// sample_rate & frame_rate are user defined
// CLAMP(sample_rate, 1, 1000000);
// CLAMP(frame_rate, 0.001, 1000000);
- CLAMP(channels, 0, 16);
- CLAMP(width, 0, 10000);
- CLAMP(height, 0, 10000);
+ CLAMP(channels, 0, MAX_CHANNELS-1);
+ CLAMP(width, 0, 32767);
+ CLAMP(height, 0, 32767);
//printf("Asset::boundaries %d %d %f\n", __LINE__, sample_rate, frame_rate);
}
int CICache::delete_oldest()
{
int result = 0;
- total_lock->lock("CICache::delete_oldest");
CICacheItem *oldest = 0;
-// at least 2
- if( first != last ) {
- oldest = first;
- CICacheItem *current = oldest->next;
- while( current ) {
+ total_lock->lock("CICache::delete_oldest");
+ if( first != last ) { // at least 2
+ CICacheItem *current = first;
+ for( ; !oldest && current; current=current->next )
+ if( !current->checked_out ) oldest = current;
+ for( ; current; current=current->next ) {
+ if( current->checked_out ) continue;
if( current->age < oldest->age )
oldest = current;
- current = current->next;
+ }
+// delete oldest of at least 2 cache files
+ if( oldest ) {
+ remove_pointer(oldest);
+ result = 1;
}
}
// settle for just deleting one frame
- else if( first )
+ else if( first && !first->checked_out )
result = first->file->delete_oldest();
- if( oldest ) {
-// Got the oldest file. Try requesting cache purge from it.
- if( oldest->file )
- oldest->file->purge_cache();
-// Delete the file if cache already empty and not checked out.
- if( !oldest->checked_out )
- remove_pointer(oldest);
- else
- oldest = 0;
- }
total_lock->unlock();
- if( oldest ) {
+ if( oldest )
oldest->Garbage::remove_user();
- result = 1;
- }
return result;
}
{
this->mwindow = mwindow;
this->panel = panel;
- set_tooltip(_("Undo ( z )"));
+ set_tooltip(_("Undo ( z or Ctrl-z)"));
}
EditUndo::~EditUndo()
{
frm_count = 0;
nudge = AV_NOPTS_VALUE;
seek_pos = curr_pos = 0;
- seeked = 1; eof = 0;
+ seeking = 0; seeked = 1;
+ eof = 0;
reading = writing = 0;
hw_pixfmt = AV_PIX_FMT_NONE;
hw_device_ctx = 0;
}
}
if( pos == curr_pos ) return 0;
+ seeking = -1;
double secs = pos < 0 ? 0. : pos / rate;
AVRational time_base = st->time_base;
int64_t tstmp = time_base.num > 0 ? secs * time_base.den/time_base.num : 0;
int i = MAX_RETRY + pos - curr_pos;
while( ret>=0 && !flushed && curr_pos<=pos && --i>=0 ) {
ret = read_frame(frame);
- if( ret > 0 ) ++curr_pos;
+ if( ret > 0 ) {
+ if( frame->key_frame && seeking < 0 )
+ seeking = 1;
+ if( ffmpeg->file_base->get_use_cache() && seeking > 0 && curr_pos < pos ) {
+ VFrame *cache_frame = ffmpeg->file_base->new_cache_frame(vframe, curr_pos);
+ if( cache_frame ) {
+ ret = convert_cmodel(cache_frame, frame);
+ ffmpeg->file_base->put_cache_frame();
+ }
+ }
+ ++curr_pos;
+ }
}
+ seeking = 0;
if( frame->format == AV_PIX_FMT_NONE || frame->width <= 0 || frame->height <= 0 )
ret = -1;
if( ret >= 0 ) {
int64_t seek_pos, curr_pos;
int fidx;
int reading, writing;
- int seeked, eof;
+ int seeking, seeked, eof;
int hw_pixfmt;
AVBufferRef *hw_device_ctx;
return frame_cache->delete_oldest();
}
+// create cache frame using input vframe as template
+VFrame *File::new_cache_frame(VFrame *vframe, int64_t position, int first_frame)
+{
+ return frame_cache->new_cache_frame(position,
+ vframe->get_w(), vframe->get_h(), vframe->get_color_model(),
+ current_layer, asset->frame_rate, first_frame);
+}
+
+void File::put_cache_frame()
+{
+ return frame_cache->put_cache_frame();
+}
+
+int File::get_use_cache()
+{
+ return use_cache;
+}
+
+
// file driver in order of probe precidence
// can be reordered in preferences->interface
const char *File::default_probes[] = {
// Get nearest colormodel that can be decoded without a temporary frame.
// Used by read_frame.
int colormodel_supported(int colormodel);
+// create frame_cache vframe for position, use template vframe
+// clear cache if first frame is a read miss
+ VFrame *new_cache_frame(VFrame *vframe, int64_t position, int first_frame);
+ void put_cache_frame();
+ int get_use_cache();
// stubs for now
static const char *compressiontostr(const char *codec) { return codec; }
}
+VFrame *FileBase::new_cache_frame(VFrame *vframe, int64_t position)
+{
+ return file->new_cache_frame(vframe, position, 0);
+}
+void FileBase::put_cache_frame()
+{
+ return file->put_cache_frame();
+}
+int FileBase::get_use_cache()
+{
+ return file->get_use_cache();
+}
+
int channel,
int64_t len);
void allocate_history(int len);
+// create cache frames
+ VFrame *new_cache_frame(VFrame *vframe, int64_t position);
+ void put_cache_frame();
+ int get_use_cache();
// For static functions to access it
Asset *asset;
lock->unlock();
}
-
-
+VFrame *FrameCache::new_cache_frame(int64_t position, int w, int h,
+ int color_model, int layer, double frame_rate, int first_frame)
+{
+ FrameCacheItem *item = 0;
+ lock->lock("FrameCache::put_vframe");
+ if( frame_exists(position, layer, frame_rate, color_model, w, h, &item, -1) ) {
+ lock->unlock();
+ return 0;
+ }
+ if( first_frame ) {
+ while( last ) delete last;
+ total_items = 0;
+ current_item = 0;
+ }
+ item = new FrameCacheItem;
+ item->data = new VFrame(w, h, color_model);
+ item->position = position;
+ item->layer = layer;
+ item->frame_rate = frame_rate;
+ item->source_id = -1;
+ item->age = position < 0 ? INT_MAX : get_age();
+ put_item(item);
+ return item->data;
+}
+void FrameCache::put_cache_frame()
+{
+ lock->unlock();
+}
int FrameCache::frame_exists(VFrame *format, int64_t position,
int layer, double frame_rate, FrameCacheItem **item_return, int source_id)
{
FrameCacheItem *item = (FrameCacheItem*)get_item(position);
-// printf("FrameCache::frame_exists %d item=%p item->position=%jd position=%jd\n",
-// __LINE__,
-// item,
-// item ? item->position : 0,
-// position);
-
- while(item && item->position == position)
- {
-// printf("FrameCache::frame_exists %d %f,%f %d,%d %d,%d format match=%d item->data=%p\n",
-// __LINE__,
-// item->frame_rate,
-// frame_rate,
-// item->layer,
-// layer,
-// item->source_id,
-// source_id,
-// format->equivalent(item->data, 1),
-// item->data);
-// format->dump_params();
-
-// This originally tested the frame stacks because a change in the
-// interpolate plugin could cause CR2 to interpolate or not interpolate.
-// This was disabled.
- if(EQUIV(item->frame_rate, frame_rate) &&
- layer == item->layer &&
- format->equivalent(item->data, 0) &&
- (source_id == -1 || item->source_id == -1 || source_id == item->source_id))
- {
+ for( ; item && item->position == position; item = (FrameCacheItem*)item->next ) {
+ if( !EQUIV(item->frame_rate, frame_rate) ) continue;
+ if( layer != item->layer ) continue;
+ if( !format->equivalent(item->data, 0) ) continue;
+ if( source_id == -1 || item->source_id == -1 ||
+ source_id == item->source_id ) {
*item_return = item;
return 1;
}
- else
- item = (FrameCacheItem*)item->next;
}
return 0;
}
-int FrameCache::frame_exists(int64_t position,
- int layer,
- double frame_rate,
- int color_model,
- int w,
- int h,
- FrameCacheItem **item_return,
- int source_id)
+int FrameCache::frame_exists(int64_t position, int layer, double frame_rate,
+ int color_model, int w, int h, FrameCacheItem **item_return, int source_id)
{
FrameCacheItem *item = (FrameCacheItem*)get_item(position);
- while(item && item->position == position)
- {
-// printf("FrameCache::frame_exists %d %f,%f %d,%d %d,%d %d,%d\n",
-// __LINE__,
-// item->frame_rate,
-// frame_rate,
-// item->layer,
-// layer,
-// item->data->get_color_model(),
-// color_model,
-// item->data->get_w(),
-// w,
-// item->data->get_h(),
-// h);
-
- if(EQUIV(item->frame_rate, frame_rate) &&
- layer == item->layer &&
- color_model == item->data->get_color_model() &&
- w == item->data->get_w() &&
- h == item->data->get_h() &&
- (source_id == -1 || item->source_id == -1 || source_id == item->source_id))
- {
+ for( ; item && item->position == position ; item = (FrameCacheItem*)item->next ) {
+ if( !EQUIV(item->frame_rate, frame_rate) ) continue;
+ if( layer != item->layer ) continue;
+ if( color_model != item->data->get_color_model() ) continue;
+ if( w != item->data->get_w() ) continue;
+ if( h != item->data->get_h() ) continue;
+ if( source_id == -1 || item->source_id == -1 ||
+ source_id == item->source_id ) {
*item_return = item;
return 1;
}
- else
- item = (FrameCacheItem*)item->next;
}
return 0;
}
double frame_rate,
int use_copy,
Indexable *indexable);
+// create new cache vframe at position, return 0 if it already exists
+// if first_frame set, clear cache before new vframe created
+// if new vframe created, leave cache locked for frame load
+ VFrame *new_cache_frame(int64_t position, int w, int h,
+ int color_model, int layer, double frame_rate,
+ int first_frame);
+ void put_cache_frame();
void dump();
// ================================================= edit
-Undo::Undo(MWindow *mwindow) : BC_MenuItem(_("Undo"), "z", 'z')
+Undo::Undo(MWindow *mwindow) : BC_MenuItem(_("Undo"), "z or Ctrl-z", 'z')
{
this->mwindow = mwindow;
}
}
}
+ mwindow->reset_caches(1);
reset_creators();
- mwindow->reset_caches();
return 0;
}
-
int MainUndo::redo()
{
mwindow->gui->close_keyvalue_popup();
update_caption(current ? current->get_description() : "");
}
}
+ mwindow->reset_caches(1);
reset_creators();
- mwindow->reset_caches();
//dump();
return 0;
}
gui->del_keyboard_listener(
(int (BC_WindowBase::*)(BC_WindowBase *))
&MWindowGUI::keyboard_listener);
- reset_caches();
+ reset_caches(0);
#if 0
// release the hounds
if( awindow && awindow->gui ) awindow->gui->close(0);
if( prefs != preferences )
preferences->copy_from(prefs);
if( cwindow->playback_engine )
- cwindow->playback_engine->preferences->copy_from(prefs);
+ cwindow->playback_engine->update_preferences(prefs);
for(int i = 0; i < vwindows.size(); i++) {
VWindow *vwindow = vwindows[i];
if( !vwindow->is_running() ) continue;
if( vwindow->playback_engine )
- vwindow->playback_engine->preferences->copy_from(prefs);
+ vwindow->playback_engine->update_preferences(prefs);
}
for(int i = 0; i < zwindows.size(); i++) {
ZWindow *zwindow = zwindows[i];
if( !zwindow->is_running() ) continue;
if( zwindow->zgui->playback_engine )
- zwindow->zgui->playback_engine->preferences->copy_from(prefs);
+ zwindow->zgui->playback_engine->update_preferences(prefs);
}
}
return 0;
}
-void MWindow::reset_caches()
+void MWindow::reset_caches(int locked)
{
- int locked = gui->get_window_lock();
if( locked ) gui->unlock_window();
awindow->gui->stop_vicon_drawing(1);
if( cwindow->playback_engine )
void remove_indexfile(Indexable *indexable);
void rebuild_indices();
// Asset removal from caches
- void reset_caches();
+ void reset_caches(int locked);
void remove_from_caches(Indexable *idxbl);
void remove_assets_from_project(int push_undo, int redraw, int delete_indexes,
ArrayList<Indexable*> *drag_assets /* mwindow->session->drag_assets */,
// Delete current project
if( load_mode == LOADMODE_REPLACE ||
load_mode == LOADMODE_REPLACE_CONCATENATE ) {
- reset_caches();
+ reset_caches(1);
edl->save_defaults(defaults);
hide_plugins();
edl->Garbage::remove_user();
int New::create_new_project(int load_mode)
{
mwindow->stop_playback(0);
+ mwindow->reset_caches(0);
mwindow->gui->lock_window();
- mwindow->reset_caches();
memcpy(new_edl->session->achannel_positions,
&mwindow->preferences->channel_positions[new_edl->session->audio_channels - 1],
char string[BCTEXTLEN];
BC_Resources *resources = BC_WindowBase::get_resources();
BC_WindowBase *win;
- int maxw, curw;
node_list = 0;
generate_node_list();
int y0 = y;
win = add_subwindow(new BC_Title(x, y + ys5, _("Cache size (MB):"), MEDIUMFONT, resources->text_default));
- maxw = win->get_w();
- int x1 = x + xmargin4;
- win = add_subwindow(new BC_Title(x1, y + ys5, _("Use HW Device:")));
- x1 += win->get_w() + xs5;
- PrefsUseHWDev *use_hw_dev = new PrefsUseHWDev(pwindow, this, x1, y);
- use_hw_dev->create_objects();
-
+ int maxw = win->get_w();
int y1 = y += ys30;
- win = add_subwindow(new BC_Title(x, y + ys5, _("Seconds to preroll renders:")));
- if((curw = win->get_w()) > maxw)
- maxw = curw;
- maxw += x + xs5;
-
- cache_size = new CICacheSize(maxw, y0, pwindow, this);
+ win = add_subwindow(new BC_Title(x, y1 + ys5, _("Seconds to preroll renders:")));
+ maxw = bmax(win->get_w(), maxw);
+ int x2 = x + maxw + xs5;
+ int y2 = y += ys30;
+ cache_size = new CICacheSize(x2, y0, pwindow, this);
cache_size->create_objects();
-
- add_subwindow(new BC_Title(x, y + ys5, _("Seconds to preroll renders:")));
- PrefsRenderPreroll *preroll = new PrefsRenderPreroll(pwindow, this, maxw, y1);
+ PrefsRenderPreroll *preroll = new PrefsRenderPreroll(pwindow, this, x2, y1);
preroll->create_objects();
+ add_subwindow(new PrefsForceUniprocessor(pwindow, x, y2));
y += ys30;
- x1 = x + xmargin4;
- BC_Title *smp_title = new BC_Title(x1, y + ys5, _("Project SMP cpus:"));
- add_subwindow(smp_title);
- x1 += smp_title->get_w() + xs5;
- PrefsProjectSMP *proj_smp = new PrefsProjectSMP(pwindow, this, x1, y);
+ int x1 = x + xmargin4;
+ add_subwindow(cache_transitions = new CacheTransitions(x1, y0, pwindow, this));
+ win = add_subwindow(new BC_Title(x1, y1, _("Use HW Device:")));
+ maxw = win->get_w();
+ win = add_subwindow(new BC_Title(x1, y2, _("Project SMP cpus:")));
+ maxw = bmax(win->get_w(), maxw);
+ x2 = x1 + maxw + xs5;
+ PrefsUseHWDev *use_hw_dev = new PrefsUseHWDev(pwindow, this, x2, y1);
+ use_hw_dev->create_objects();
+ PrefsProjectSMP *proj_smp = new PrefsProjectSMP(pwindow, this, x2, y2);
proj_smp->create_objects();
- PrefsForceUniprocessor *force_1cpu = new PrefsForceUniprocessor(pwindow, x, y);
- add_subwindow(force_1cpu);
- y += ys30;
-
// Background rendering
add_subwindow(new BC_Bar(xs5, y, get_w() - xs10));
y += ys5;
return 0;
}
+CacheTransitions::CacheTransitions(int x, int y,
+ PreferencesWindow *pwindow, PerformancePrefs *subwindow)
+ : BC_CheckBox(x, y, pwindow->thread->preferences->cache_transitions,
+ _("Cache Transitions"))
+{
+ this->pwindow = pwindow;
+}
+
+int CacheTransitions::handle_event()
+{
+ pwindow->thread->preferences->cache_transitions = get_value();
+ return 0;
+}
+
PrefsUseHWDev::PrefsUseHWDev(PreferencesWindow *pwindow,
PerformancePrefs *subwindow, int x, int y)
int hot_node;
CICacheSize *cache_size;
+ CacheTransitions *cache_transitions;
PerfsUseHWDev *use_hw_dev;
enum
PreferencesWindow *pwindow;
};
+class CacheTransitions : public BC_CheckBox
+{
+public:
+ CacheTransitions(int x, int y,
+ PreferencesWindow *pwindow,
+ PerformancePrefs *subwindow);
+
+ int handle_event();
+
+ PreferencesWindow *pwindow;
+};
+
class PrefsUseHWDevItems : public ArrayList<BC_ListBoxItem *>
{
public:
class PrefsRenderFarmReset;
class PrefsRenderFarmWatchdog;
class CICacheSize;
+class CacheTransitions;
class PerfsUseHWDev;
#endif
return TransportCommand::get_direction(curr_command);
}
+void PlaybackEngine::update_preferences(Preferences *prefs)
+{
+ preferences->copy_from(prefs);
+ create_render_engine();
+}
+
void PlaybackEngine::send_command(int command, EDL *edl, int wait_tracking, int use_inout)
{
//printf("PlaybackEngine::send_command 1 %d\n", command);
void stop_playback(int wait);
void refresh_frame(int change_type, EDL *edl, int dir=1);
int get_direction();
+ void update_preferences(Preferences *prefs);
// Maintain caches through console changes
CICache *audio_cache, *video_cache;
if( strlen(index_directory) )
fs.complete_path(index_directory);
cache_size = 0x10000000;
+ cache_transitions = 1;
index_size = 0x400000;
index_count = 500;
use_thumbnails = 1;
for( int i=0; i<that->file_probes.size(); ++i )
this->file_probes.append(new ProbePref(*that->file_probes[i]));
cache_size = that->cache_size;
+ cache_transitions = that->cache_transitions;
project_smp = that->project_smp;
force_uniprocessor = that->force_uniprocessor;
strcpy(lv2_path, that->lv2_path);
use_brender = defaults->get("USE_BRENDER", use_brender);
brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment);
cache_size = defaults->get("CACHE_SIZE", cache_size);
+ cache_transitions = defaults->get("CACHE_TRANSITIONS", cache_transitions);
local_rate = defaults->get("LOCAL_RATE", local_rate);
use_renderfarm = defaults->get("USE_RENDERFARM", use_renderfarm);
renderfarm_port = defaults->get("RENDERFARM_PORT", renderfarm_port);
defaults->update("ANDROID_PORT", android_port);
defaults->update("CACHE_SIZE", cache_size);
+ defaults->update("CACHE_TRANSITIONS", cache_transitions);
defaults->update("INDEX_DIRECTORY", index_directory);
defaults->update("INDEX_SIZE", index_size);
defaults->update("INDEX_COUNT", index_count);
// Several caches of cache_size exist so multiply by 4.
// rendering, playback, timeline, preview
int64_t cache_size;
+ int cache_transitions;
int use_renderfarm;
int renderfarm_port;
redraw_overlays = 0;
close_assets = 0;
reload_plugins = 0;
+ reset_caches = 0;
//int need_new_indexes = 0;
rerender = 0;
File::setenv_path("LV2_PATH", preferences->lv2_path, 1);
mwindow->restart_status = -1;
}
+ if( preferences->cache_size != mwindow->preferences->cache_size ||
+ preferences->cache_transitions != mwindow->preferences->cache_transitions )
+ reset_caches = 1;
if( mwindow->preferences->perpetual_session && !preferences->perpetual_session )
mwindow->remove_undo_data();
else {
BC_Trace::disable_locks();
}
+ if( reset_caches )
+ mwindow->reset_caches(0);
mwindow->reset_android_remote();
int ffmpeg_early_probe = mwindow->preferences->get_file_probe_armed("FFMPEG_Early");
int rerender;
int close_assets;
int reload_plugins;
+ int reset_caches;
PreferencesWindow *window;
MWindow *mwindow;
// Copy of mwindow preferences
//printf("VModule::import_frame %d cache=%p\n", __LINE__, get_cache());
if( current_edit->asset ) {
get_cache()->age();
- file = get_cache()->check_out(current_edit->asset,
- get_edl());
+ file = get_cache()->check_out(current_edit->asset, get_edl());
// get_cache()->dump();
}
// File found
if( file || nested_edl ) {
-// Make all positions based on requested frame rate.
- int64_t edit_startproject = Units::to_int64(current_edit->startproject *
- frame_rate /
- edl_rate);
- int64_t edit_startsource = Units::to_int64(current_edit->startsource *
- frame_rate /
- edl_rate);
-// Source position going forward
- uint64_t position = direction_position -
- edit_startproject +
- edit_startsource;
int64_t nested_position = 0;
-
-
-
-
-
-// apply speed curve to source position so the timeline agrees with the playback
- if( track->has_speed() ) {
-// integrate position from start of edit.
- double speed_position = edit_startsource;
- FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED];
- speed_position += speed_autos->automation_integral(edit_startproject,
- direction_position-edit_startproject, PLAY_FORWARD);
-//printf("VModule::import_frame %d %jd %jd\n", __LINE__, position, (int64_t)speed_position);
- position = (int64_t)speed_position;
- }
-
-
-
-
-
- int asset_w;
- int asset_h;
- if( debug ) printf("VModule::import_frame %d\n", __LINE__);
-
-
-// maybe apply speed curve here, so timeline reflects actual playback
-
-
-
-// if we hit the end of stream, freeze at last frame
- uint64_t max_position = 0;
+// Source position going forward, in edl framerate
+ int64_t pos = Units::to_int64((double)direction_position / frame_rate * edl_rate);
+ int64_t len = pos - current_edit->startproject;
+ FloatAutos *speed_autos = !track->has_speed() ? 0 :
+ (FloatAutos*)track->automation->autos[AUTOMATION_SPEED];
+ if( speed_autos && len > 0 )
+ len = speed_autos->automation_integral(current_edit->startproject, len, PLAY_FORWARD);
+ pos = current_edit->startsource + len;
+// Make positions based on requested frame rate.
+ int64_t position = Units::to_int64((double)pos * frame_rate / edl_rate);
+
+ int64_t max_position;
+ int asset_w, asset_h;
if( file ) {
+ asset_w = current_edit->asset->width;
+ asset_h = current_edit->asset->height;
max_position = Units::to_int64((double)file->get_video_length() *
- frame_rate /
- current_edit->asset->frame_rate - 1);
+ frame_rate / current_edit->asset->frame_rate - 1);
}
else {
+ asset_w = nested_edl->session->output_w;
+ asset_h = nested_edl->session->output_h;
max_position = Units::to_int64(nested_edl->tracks->total_length() *
frame_rate - 1);
}
+// if we hit the end of stream, freeze at last frame
+ CLAMP(position, 0, max_position);
-
- if( position > max_position ) position = max_position;
- else
- if( position < 0 ) position = 0;
+ VFrame *&input = commonrender ?
+ ((VRender*)commonrender)->input_temp : // Realtime playback
+ input_temp ; // Menu effect
+ VFrame::get_temp(input, asset_w, asset_h, get_edl()->session->color_model);
int use_cache = renderengine &&
- renderengine->command->single_frame();
+ ( renderengine->command->single_frame() ||
+ renderengine->command->get_direction() == PLAY_REVERSE );
+
// int use_asynchronous = !use_cache &&
// renderengine &&
// Try to make rendering go faster.
// else
file->stop_video_thread();
- int64_t normalized_position = Units::to_int64(position *
- current_edit->asset->frame_rate /
- frame_rate);
-// printf("VModule::import_frame %d %lld %lld\n",
-// __LINE__,
-// position,
-// normalized_position);
+// cache transitions
+ VEdit *vnext = (VEdit *)current_edit->next;
+ pos = Units::to_int64((double)input_position / frame_rate * edl_rate);
+ if( renderengine && renderengine->preferences->cache_transitions &&
+ renderengine->command->get_direction() == PLAY_FORWARD &&
+ current_edit->next && current_edit->next->transition &&
+ file->get_video_length() >= 0 && pos >= vnext->startproject &&
+ pos < vnext->startproject + vnext->transition->length ) {
+ file->set_cache_frames(0);
+ file->set_layer(current_edit->channel);
+ VEdit *vnext = (VEdit *)current_edit->next;
+ Track *track = current_edit->track;
+ FloatAutos *speed_autos = (FloatAutos*)(track->has_speed() ?
+ track->automation->autos[AUTOMATION_SPEED] : 0);
+ int64_t end = vnext->startproject + vnext->transition->length;
+ int first_frame = 1;
+ int count = renderengine->preferences->cache_size /
+ input->get_data_size() / 2; // try to burn only 1/2 of cache
+ while( !result && pos < end && count > 0 ) {
+ int64_t curr_pos = pos - current_edit->startproject;
+ if( curr_pos > 0 && speed_autos )
+ curr_pos = speed_autos->automation_integral(
+ current_edit->startproject, curr_pos, PLAY_FORWARD);
+ curr_pos += current_edit->startsource;
+ int64_t norm_pos = Units::to_int64((double)curr_pos *
+ current_edit->asset->frame_rate / edl_rate);
+ VFrame *cache_frame = file->new_cache_frame(input, norm_pos, first_frame);
+ if( cache_frame ) {
+ file->set_video_position(norm_pos, 0);
+ result = file->read_frame(cache_frame);
+ file->put_cache_frame();
+ }
+ else if( first_frame ) // already loaded
+ break;
+ first_frame = 0;
+ ++pos; --count;
+ }
+ use_cache = 1;
+ }
+
+ int64_t normalized_position = Units::to_int64((double)position *
+ current_edit->asset->frame_rate / frame_rate);
+//printf("VModule::import_frame %d %lld %lld\n", __LINE__, position, normalized_position);
file->set_layer(current_edit->channel);
- file->set_video_position(normalized_position,
- 0);
- asset_w = current_edit->asset->width;
- asset_h = current_edit->asset->height;
-//printf("VModule::import_frame %d normalized_position=%lld\n", __LINE__, normalized_position);
+ file->set_video_position(normalized_position, 0);
}
else {
if( debug ) printf("VModule::import_frame %d\n", __LINE__);
- asset_w = nested_edl->session->output_w;
- asset_h = nested_edl->session->output_h;
// Get source position in nested frame rate in direction of playback.
nested_position = Units::to_int64(position *
nested_edl->session->frame_rate /
!EQUIV(in_h, asset_h)) {
//printf("VModule::import_frame %d file -> temp -> output\n", __LINE__);
// Get temporary input buffer
- VFrame **input = 0;
-// Realtime playback
- if( commonrender ) {
- VRender *vrender = (VRender*)commonrender;
-//printf("VModule::import_frame %d vrender->input_temp=%p\n", __LINE__, vrender->input_temp);
- input = &vrender->input_temp;
- }
- else {
-// Menu effect
- input = &input_temp;
- }
-
-
- if( (*input) &&
- ((*input)->get_w() != asset_w ||
- (*input)->get_h() != asset_h) ) {
- delete (*input);
- (*input) = 0;
- }
-
- if( !(*input) ) {
- (*input) =
- new VFrame(asset_w, asset_h,
- get_edl()->session->color_model);
- }
+ VFrame **input = commonrender ? // Realtime playback
+ &((VRender*)commonrender)->input_temp :
+ &input_temp ; // Menu effect
+ VFrame::get_temp(*input, asset_w, asset_h,
+ get_edl()->session->color_model);
(*input)->copy_stacks(output);
-
// file -> temp
-// Cache for single frame only
+// Cache for single frame, reverse playback
if( file ) {
if( debug ) printf("VModule::import_frame %d this=%p file=%s\n",
__LINE__,
int use_vconsole = 1;
int use_brender = 0;
int result = 0;
- int use_cache = renderengine->command->single_frame();
+ int use_cache = renderengine->command->single_frame() ||
+ renderengine->command->get_direction() == PLAY_REVERSE;
// int use_asynchronous =
// renderengine->command->realtime &&
// renderengine->get_edl()->session->video_every_frame &&
-# translation of cin.po to russian
-# translation of ru-4.po to
-# translation of ru-3.po to
-# translation of ru-2.po to
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# Translation of Cinelerra-GG Infinity to Russian
+# Copyright (C) 2006-2019 Heroine Virtual Ltd. by Adam Williams
+# Copyright (C) 2007-2020 mods for Cinelerra-GG by W.P.Morrow aka goodguy
# This file is distributed under the same license as the PACKAGE package.
#
msgid ""
msgstr ""
-"Project-Id-Version: CinelerraGG\n"
-"Report-Msgid-Bugs-To: \n"
+"Project-Id-Version: Cinelerra-GG Infinity\n"
"POT-Creation-Date: 2020-09-01 04:28+0300\n"
"PO-Revision-Date: 2020-09-06 15:06+0300\n"
"Language: ru_RU\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"