/*
* CINELERRA
* Copyright (C) 2009-2013 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2003-2016 Cinelerra CV contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "file.h"
#include "filexml.h"
#include "floatautos.h"
+#include "mainerror.h"
#include "maskauto.h"
#include "maskautos.h"
#include "mwindow.h"
int VModule::import_frame(VFrame *output, VEdit *current_edit,
int64_t input_position, double frame_rate, int direction, int use_opengl)
{
- int64_t direction_position;
+ int64_t direction_position=0;
// Translation of edit
- float in_x, in_y, in_w, in_h;
- float out_x, out_y, out_w, out_h;
+ float in_x=0.0, in_y=0.0, in_w=0.0, in_h=0.0;
+ float out_x=0.0, out_y=0.0, out_w=0.0, out_h=0.0;
int result = 0;
const int debug = 0;
double edl_rate = get_edl()->session->frame_rate;
nested_renderengine = 0;
}
if( !nested_command )
- nested_command = new TransportCommand;
+ nested_command = new TransportCommand(get_preferences());
nested_command->command = command;
nested_command->get_edl()->copy_all(nested_edl);
nested_command->change_type = CHANGE_ALL;
// Make positions based on requested frame rate.
int64_t position = Units::to_int64((double)pos * frame_rate / edl_rate);
- int64_t max_position;
+ int64_t video_length;
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);
+ video_length = file->get_video_length();
}
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);
+ video_length = nested_edl->tracks->total_length();
}
-// if we hit the end of stream, freeze at last frame
- CLAMP(position, 0, max_position);
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->get_direction() == PLAY_REVERSE );
+ int use_cache = renderengine->command->single_frame() ? 1 :
+ renderengine->command->get_direction() == PLAY_REVERSE ? -1 : 0;
// int use_asynchronous = !use_cache &&
// renderengine &&
// else
file->stop_video_thread();
-// 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 &&
+ if( renderengine->preferences->cache_transitions && !use_cache &&
+// cache transitions, not caching and inside transition
+ vnext && vnext->transition && vnext->transition->on &&
file->get_video_length() >= 0 && pos >= vnext->startproject &&
pos < vnext->startproject + vnext->transition->length ) {
file->set_cache_frames(0);
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();
+ if( norm_pos < 0 || video_length < 0 )
+ norm_pos = 0;
+ else if( norm_pos >= video_length )
+ norm_pos = video_length-1;
+ if( first_frame ) {
+ if( file->get_cache_frame(input, norm_pos) )
+ break; // if inside a cache run
+ first_frame = 0;
+ file->purge_cache(); // start new run
}
- else if( first_frame ) // already loaded
- break;
- first_frame = 0;
+ file->set_cache_frames(1);
+ file->set_video_position(norm_pos, 0);
+ result = file->read_frame(input);
++pos; --count;
}
use_cache = 1;
int64_t normalized_position = Units::to_int64((double)position *
current_edit->asset->frame_rate / frame_rate);
+ if( normalized_position < 0 || video_length < 0 )
+ normalized_position = 0;
+ else if( normalized_position >= video_length )
+ normalized_position = video_length-1;
//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);
__LINE__,
this,
current_edit->asset->path);
- if( use_cache ) file->set_cache_frames(1);
+ if( use_cache )
+ file->set_cache_frames(use_cache);
result = file->read_frame((*input));
- if( use_cache ) file->set_cache_frames(0);
+ if( use_cache )
+ file->set_cache_frames(0);
(*input)->set_opengl_state(VFrame::RAM);
}
else
else if( file ) {
// Cache single frames
//memset(output->get_rows()[0], 0xff, 1024);
- if( use_cache ) file->set_cache_frames(1);
+ if( use_cache )
+ file->set_cache_frames(use_cache);
result = file->read_frame(output);
- if( use_cache ) file->set_cache_frames(0);
+ if( use_cache )
+ file->set_cache_frames(0);
output->set_opengl_state(VFrame::RAM);
}
}
// (*transition_input), (*transition_input)->get_pbuffer(),
// output, output->get_pbuffer());
+ if( transition_server ) {
// Execute plugin with transition_input and output here
- if( renderengine )
- transition_server->set_use_opengl(use_opengl, renderengine->video);
- transition_server->process_transition((*transition_input), output,
- (direction == PLAY_FORWARD) ?
- (start_position_project - current_edit->startproject) :
- (start_position_project - current_edit->startproject - 1),
- transition->length);
+ if( renderengine )
+ transition_server->set_use_opengl(use_opengl, renderengine->video);
+ transition_server->process_transition((*transition_input), output,
+ (direction == PLAY_FORWARD) ?
+ (start_position_project - current_edit->startproject) :
+ (start_position_project - current_edit->startproject - 1),
+ transition->length);
+ }
+ else
+ eprintf("missing transition plugin: %s\n", transition->title);
}
else {
// Load output buffer