5 #include "commonrender.h"
8 #include "edlsession.h"
11 #include "floatautos.h"
13 #include "overlayframe.h"
15 #include "pluginarray.h"
16 #include "preferences.h"
17 #include "renderengine.h"
18 #include "sharedlocation.h"
19 #include "transition.h"
20 #include "transportque.h"
22 #include "vattachmentpoint.h"
23 #include "vdevicex11.h"
26 #include "videodevice.h"
32 #include "interlacemodes.h"
33 #include "maskengine.h"
34 #include "automation.h"
36 VModule::VModule(RenderEngine *renderengine,
37 CommonRender *commonrender,
38 PluginArray *plugin_array,
40 : Module(renderengine, commonrender, plugin_array, track)
42 data_type = TRACK_VIDEO;
47 masker = new MaskEngine(renderengine->preferences->processors);
49 masker = new MaskEngine(plugin_array->mwindow->preferences->processors);
55 if(overlay_temp) delete overlay_temp;
56 if(input_temp) delete input_temp;
57 if(transition_temp) delete transition_temp;
62 AttachmentPoint* VModule::new_attachment(Plugin *plugin)
64 return new VAttachmentPoint(renderengine, plugin);
67 int VModule::get_buffer_size()
72 CICache* VModule::get_cache()
75 return renderengine->get_vcache();
80 int VModule::import_frame(VFrame *output,
82 int64_t input_position,
87 int64_t corrected_position;
88 int64_t corrected_position_project;
89 // Translation of edit
99 double edl_rate = get_edl()->session->frame_rate;
100 int64_t input_position_project = (int64_t)(input_position *
104 if(!output) printf("VModule::import_frame 10 output=%p\n", output);
106 corrected_position = input_position;
107 corrected_position_project = input_position_project;
108 if(direction == PLAY_REVERSE)
110 corrected_position--;
111 input_position_project--;
114 VDeviceX11 *x11_device = 0;
117 if(renderengine && renderengine->video)
119 x11_device = (VDeviceX11*)renderengine->video->get_output_base();
120 output->set_opengl_state(VFrame::RAM);
125 // Load frame into output
130 File *source = get_cache()->check_out(current_edit->asset,
132 // get_cache()->dump();
136 int64_t edit_startproject = (int64_t)(current_edit->startproject *
139 int64_t edit_startsource = (int64_t)(current_edit->startsource *
142 uint64_t position = corrected_position -
145 // if we hit the end of stream, freeze at last frame
146 uint64_t max_position = source->get_video_length(frame_rate) - 1;
147 if (position > max_position) position = max_position;
148 int use_cache = renderengine &&
149 renderengine->command->single_frame();
150 int use_asynchronous = !use_cache && renderengine &&
151 renderengine->command->realtime &&
152 renderengine->edl->session->video_asynchronous;
155 source->start_video_decode_thread();
157 source->stop_video_thread();
159 source->set_video_position(position, frame_rate);
160 source->set_layer(current_edit->channel);
162 ((VTrack*)track)->calculate_input_transfer(current_edit->asset,
163 input_position_project,
175 // printf("VModule::import_frame 1 [ilace] Project: mode (%d) Asset: autofixoption (%d), mode (%d), method (%d)\n",
176 // get_edl()->session->interlace_mode,
177 // current_edit->asset->interlace_autofixoption,
178 // current_edit->asset->interlace_mode,
179 // current_edit->asset->interlace_fixmethod);
181 // Determine the interlacing method to use.
182 int interlace_fixmethod = ilaceautofixmethod2(get_edl()->session->interlace_mode,
183 current_edit->asset->interlace_autofixoption,
184 current_edit->asset->interlace_mode,
185 current_edit->asset->interlace_fixmethod);
187 // char string[BCTEXTLEN];
188 // ilacefixmethod_to_text(string,interlace_fixmethod);
189 // printf("VModule::import_frame 1 [ilace] Compensating by using: '%s'\n",string);
191 // Compensate for the said interlacing...
192 switch (interlace_fixmethod) {
193 case BC_ILACE_FIXMETHOD_NONE:
196 case BC_ILACE_FIXMETHOD_UPONE:
199 case BC_ILACE_FIXMETHOD_DOWNONE:
203 printf("vmodule::importframe WARNING - unknown fix method for interlacing, no compensation in effect\n");
207 // file -> temp -> output
208 if( !EQUIV(in_x1, 0) ||
210 !EQUIV(in_w1, track->track_w) ||
211 !EQUIV(in_h1, track->track_h) ||
214 !EQUIV(out_w1, track->track_w) ||
215 !EQUIV(out_h1, track->track_h) ||
216 !EQUIV(in_w1, current_edit->asset->width) ||
217 !EQUIV(in_h1, current_edit->asset->height))
223 // Get temporary input buffer
228 VRender *vrender = (VRender*)commonrender;
229 input = &vrender->input_temp;
239 ((*input)->get_w() != current_edit->asset->width ||
240 (*input)->get_h() != current_edit->asset->height))
252 (*input) = new VFrame(0,
253 current_edit->asset->width,
254 current_edit->asset->height,
255 get_edl()->session->color_model,
261 (*input)->copy_stacks(output);
264 // Cache for single frame only
265 if(use_cache) source->set_cache_frames(1);
266 result = source->read_frame((*input));
267 if(use_cache) source->set_cache_frames(0);
268 (*input)->set_opengl_state(VFrame::RAM);
270 //printf("VModule::import_frame 1 %lld %f\n", input_position, frame_rate);
272 // Find an overlayer object to perform the camera transformation
273 OverlayFrame *overlayer = 0;
275 // OpenGL playback uses hardware
283 VRender *vrender = (VRender*)commonrender;
284 overlayer = vrender->overlayer;
290 printf("VModule::import_frame neither plugin_array nor commonrender is defined.\n");
293 overlay_temp = new OverlayFrame(plugin_array->mwindow->preferences->processors);
296 overlayer = overlay_temp;
298 // printf("VModule::import_frame 1 %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n",
309 // for(int j = 0; j < output->get_w() * 3 * 5; j++)
310 // output->get_rows()[0][j] = 255;
314 x11_device->do_camera(output,
327 output->clear_frame();
330 // get_cache()->check_in(current_edit->asset);
333 // TRANSFER_REPLACE is the fastest transfer mode but it has the disadvantage
334 // of producing green borders in floating point translation of YUV
335 int mode = TRANSFER_REPLACE;
336 if(get_edl()->session->interpolation_type != NEAREST_NEIGHBOR &&
337 cmodel_is_yuv(output->get_color_model()))
338 mode = TRANSFER_NORMAL;
340 overlayer->overlay(output,
352 get_edl()->session->interpolation_type);
355 output->copy_stacks((*input));
360 // Cache single frames only
361 if(use_cache) source->set_cache_frames(1);
362 result = source->read_frame(output);
363 if(use_cache) source->set_cache_frames(0);
364 output->set_opengl_state(VFrame::RAM);
367 get_cache()->check_in(current_edit->asset);
373 x11_device->clear_input(output);
377 output->clear_frame();
387 x11_device->clear_input(output);
391 output->clear_frame();
401 int VModule::render(VFrame *output,
402 int64_t start_position,
410 double edl_rate = get_edl()->session->frame_rate;
412 if(use_nudge) start_position += (int64_t)(track->nudge *
416 int64_t start_position_project = (int64_t)(start_position *
421 update_transition(start_position_project,
424 VEdit* current_edit = (VEdit*)track->edits->editof(start_position_project,
427 VEdit* previous_edit = 0;
430 printf(" VModule::render %d %lld %s transition=%p opengl=%d current_edit=%p output=%p\n",
432 start_position_project,
441 output->clear_frame();
442 // We do not apply mask here, since alpha is 0, and neither substracting nor multypling changes it
443 // Another mask mode - "addition" should be added to be able to create mask from empty frames
444 // in this case we would call masking here too...
451 // Process transition
452 if(transition && transition->on)
455 // Get temporary buffer
456 VFrame **transition_input = 0;
459 VRender *vrender = (VRender*)commonrender;
460 transition_input = &vrender->transition_temp;
464 transition_input = &transition_temp;
467 if((*transition_input) &&
468 ((*transition_input)->get_w() != track->track_w ||
469 (*transition_input)->get_h() != track->track_h))
471 delete (*transition_input);
472 (*transition_input) = 0;
475 // Load incoming frame
476 if(!(*transition_input))
478 (*transition_input) = new VFrame(0,
481 get_edl()->session->color_model,
485 result = import_frame((*transition_input),
493 // Load transition buffer
494 previous_edit = (VEdit*)current_edit->previous;
496 result |= import_frame(output,
503 // Execute plugin with transition_input and output here
505 transition_server->set_use_opengl(use_opengl, renderengine->video);
506 transition_server->process_transition((*transition_input),
508 (direction == PLAY_FORWARD) ?
509 (start_position_project - current_edit->startproject) :
510 (start_position_project - current_edit->startproject - 1),
515 // Load output buffer
516 result = import_frame(output,
524 int64_t mask_position;
526 mask_position = renderengine->vrender->current_position;
528 mask_position = start_position;
529 masker->do_mask(output,
533 (MaskAutos*)track->automation->autos[AUTOMATION_MASK],
535 1); // we are calling before plugins
546 void VModule::create_objects()
548 Module::create_objects();