00001 #include "asset.h"
00002 #include "bcsignals.h"
00003 #include "cache.h"
00004 #include "clip.h"
00005 #include "commonrender.h"
00006 #include "edits.h"
00007 #include "edl.h"
00008 #include "edlsession.h"
00009 #include "file.h"
00010 #include "filexml.h"
00011 #include "floatautos.h"
00012 #include "mwindow.h"
00013 #include "overlayframe.h"
00014 #include "patch.h"
00015 #include "pluginarray.h"
00016 #include "preferences.h"
00017 #include "renderengine.h"
00018 #include "sharedlocation.h"
00019 #include "transition.h"
00020 #include "transportque.h"
00021 #include "units.h"
00022 #include "vattachmentpoint.h"
00023 #include "vdevicex11.h"
00024 #include "vedit.h"
00025 #include "vframe.h"
00026 #include "videodevice.h"
00027 #include "vmodule.h"
00028 #include "vrender.h"
00029 #include "vplugin.h"
00030 #include "vtrack.h"
00031 #include <string.h>
00032 #include "interlacemodes.h"
00033 #include "maskengine.h"
00034 #include "automation.h"
00035
00036 VModule::VModule(RenderEngine *renderengine,
00037 CommonRender *commonrender,
00038 PluginArray *plugin_array,
00039 Track *track)
00040 : Module(renderengine, commonrender, plugin_array, track)
00041 {
00042 data_type = TRACK_VIDEO;
00043 overlay_temp = 0;
00044 input_temp = 0;
00045 transition_temp = 0;
00046 if (renderengine)
00047 masker = new MaskEngine(renderengine->preferences->processors);
00048 else
00049 masker = new MaskEngine(plugin_array->mwindow->preferences->processors);
00050
00051 }
00052
00053 VModule::~VModule()
00054 {
00055 if(overlay_temp) delete overlay_temp;
00056 if(input_temp) delete input_temp;
00057 if(transition_temp) delete transition_temp;
00058 delete masker;
00059 }
00060
00061
00062 AttachmentPoint* VModule::new_attachment(Plugin *plugin)
00063 {
00064 return new VAttachmentPoint(renderengine, plugin);
00065 }
00066
00067 int VModule::get_buffer_size()
00068 {
00069 return 1;
00070 }
00071
00072 CICache* VModule::get_cache()
00073 {
00074 if(renderengine)
00075 return renderengine->get_vcache();
00076 else
00077 return cache;
00078 }
00079
00080 int VModule::import_frame(VFrame *output,
00081 VEdit *current_edit,
00082 int64_t input_position,
00083 double frame_rate,
00084 int direction,
00085 int use_opengl)
00086 {
00087 int64_t corrected_position;
00088 int64_t corrected_position_project;
00089
00090 float in_x1;
00091 float in_y1;
00092 float in_w1;
00093 float in_h1;
00094 float out_x1;
00095 float out_y1;
00096 float out_w1;
00097 float out_h1;
00098 int result = 0;
00099 double edl_rate = get_edl()->session->frame_rate;
00100 int64_t input_position_project = (int64_t)(input_position *
00101 edl_rate /
00102 frame_rate +
00103 0.001);
00104 if(!output) printf("VModule::import_frame 10 output=%p\n", output);
00105
00106 corrected_position = input_position;
00107 corrected_position_project = input_position_project;
00108 if(direction == PLAY_REVERSE)
00109 {
00110 corrected_position--;
00111 input_position_project--;
00112 }
00113
00114 VDeviceX11 *x11_device = 0;
00115 if(use_opengl)
00116 {
00117 if(renderengine && renderengine->video)
00118 {
00119 x11_device = (VDeviceX11*)renderengine->video->get_output_base();
00120 output->set_opengl_state(VFrame::RAM);
00121 }
00122 }
00123
00124
00125
00126 if(current_edit &&
00127 current_edit->asset)
00128 {
00129 get_cache()->age();
00130 File *source = get_cache()->check_out(current_edit->asset,
00131 get_edl());
00132
00133
00134 if(source)
00135 {
00136 int64_t edit_startproject = (int64_t)(current_edit->startproject *
00137 frame_rate /
00138 edl_rate);
00139 int64_t edit_startsource = (int64_t)(current_edit->startsource *
00140 frame_rate /
00141 edl_rate);
00142 uint64_t position = corrected_position -
00143 edit_startproject +
00144 edit_startsource;
00145
00146 uint64_t max_position = source->get_video_length(frame_rate) - 1;
00147 if (position > max_position) position = max_position;
00148 int use_cache = renderengine &&
00149 renderengine->command->single_frame();
00150 int use_asynchronous = !use_cache && renderengine &&
00151 renderengine->command->realtime &&
00152 renderengine->edl->session->video_asynchronous;
00153
00154 if(use_asynchronous)
00155 source->start_video_decode_thread();
00156 else
00157 source->stop_video_thread();
00158
00159 source->set_video_position(position, frame_rate);
00160 source->set_layer(current_edit->channel);
00161
00162 ((VTrack*)track)->calculate_input_transfer(current_edit->asset,
00163 input_position_project,
00164 direction,
00165 in_x1,
00166 in_y1,
00167 in_w1,
00168 in_h1,
00169 out_x1,
00170 out_y1,
00171 out_w1,
00172 out_h1);
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 int interlace_fixmethod = ilaceautofixmethod2(get_edl()->session->interlace_mode,
00183 current_edit->asset->interlace_autofixoption,
00184 current_edit->asset->interlace_mode,
00185 current_edit->asset->interlace_fixmethod);
00186
00187
00188
00189
00190
00191
00192 switch (interlace_fixmethod) {
00193 case BC_ILACE_FIXMETHOD_NONE:
00194
00195 break;
00196 case BC_ILACE_FIXMETHOD_UPONE:
00197 out_y1--;
00198 break;
00199 case BC_ILACE_FIXMETHOD_DOWNONE:
00200 out_y1++;
00201 break;
00202 default:
00203 printf("vmodule::importframe WARNING - unknown fix method for interlacing, no compensation in effect\n");
00204 }
00205
00206
00207
00208 if( !EQUIV(in_x1, 0) ||
00209 !EQUIV(in_y1, 0) ||
00210 !EQUIV(in_w1, track->track_w) ||
00211 !EQUIV(in_h1, track->track_h) ||
00212 !EQUIV(out_x1, 0) ||
00213 !EQUIV(out_y1, 0) ||
00214 !EQUIV(out_w1, track->track_w) ||
00215 !EQUIV(out_h1, track->track_h) ||
00216 !EQUIV(in_w1, current_edit->asset->width) ||
00217 !EQUIV(in_h1, current_edit->asset->height))
00218 {
00219
00220
00221
00222
00223
00224 VFrame **input = 0;
00225
00226 if(commonrender)
00227 {
00228 VRender *vrender = (VRender*)commonrender;
00229 input = &vrender->input_temp;
00230 }
00231 else
00232
00233 {
00234 input = &input_temp;
00235 }
00236
00237
00238 if((*input) &&
00239 ((*input)->get_w() != current_edit->asset->width ||
00240 (*input)->get_h() != current_edit->asset->height))
00241 {
00242 delete (*input);
00243 (*input) = 0;
00244 }
00245
00246
00247
00248
00249
00250 if(!(*input))
00251 {
00252 (*input) = new VFrame(0,
00253 current_edit->asset->width,
00254 current_edit->asset->height,
00255 get_edl()->session->color_model,
00256 -1);
00257 }
00258
00259
00260
00261 (*input)->copy_stacks(output);
00262
00263
00264
00265 if(use_cache) source->set_cache_frames(1);
00266 result = source->read_frame((*input));
00267 if(use_cache) source->set_cache_frames(0);
00268 (*input)->set_opengl_state(VFrame::RAM);
00269
00270
00271
00272
00273 OverlayFrame *overlayer = 0;
00274
00275
00276 if(use_opengl)
00277 {
00278 }
00279 else
00280
00281 if(commonrender)
00282 {
00283 VRender *vrender = (VRender*)commonrender;
00284 overlayer = vrender->overlayer;
00285 }
00286 else
00287
00288 {
00289 if(!plugin_array)
00290 printf("VModule::import_frame neither plugin_array nor commonrender is defined.\n");
00291 if(!overlay_temp)
00292 {
00293 overlay_temp = new OverlayFrame(plugin_array->mwindow->preferences->processors);
00294 }
00295
00296 overlayer = overlay_temp;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 if(use_opengl)
00313 {
00314 x11_device->do_camera(output,
00315 (*input),
00316 in_x1,
00317 in_y1,
00318 in_x1 + in_w1,
00319 in_y1 + in_h1,
00320 out_x1,
00321 out_y1,
00322 out_x1 + out_w1,
00323 out_y1 + out_h1);
00324 }
00325 else
00326 {
00327 output->clear_frame();
00328
00329
00330
00331
00332
00333
00334
00335 int mode = TRANSFER_REPLACE;
00336 if(get_edl()->session->interpolation_type != NEAREST_NEIGHBOR &&
00337 cmodel_is_yuv(output->get_color_model()))
00338 mode = TRANSFER_NORMAL;
00339
00340 overlayer->overlay(output,
00341 (*input),
00342 in_x1,
00343 in_y1,
00344 in_x1 + in_w1,
00345 in_y1 + in_h1,
00346 out_x1,
00347 out_y1,
00348 out_x1 + out_w1,
00349 out_y1 + out_h1,
00350 1,
00351 mode,
00352 get_edl()->session->interpolation_type);
00353 }
00354 result = 1;
00355 output->copy_stacks((*input));
00356 }
00357 else
00358
00359 {
00360
00361 if(use_cache) source->set_cache_frames(1);
00362 result = source->read_frame(output);
00363 if(use_cache) source->set_cache_frames(0);
00364 output->set_opengl_state(VFrame::RAM);
00365 }
00366
00367 get_cache()->check_in(current_edit->asset);
00368 }
00369 else
00370 {
00371 if(use_opengl)
00372 {
00373 x11_device->clear_input(output);
00374 }
00375 else
00376 {
00377 output->clear_frame();
00378 }
00379 result = 1;
00380 }
00381 }
00382 else
00383
00384 {
00385 if(use_opengl)
00386 {
00387 x11_device->clear_input(output);
00388 }
00389 else
00390 {
00391 output->clear_frame();
00392 }
00393 }
00394
00395
00396 return result;
00397 }
00398
00399
00400
00401 int VModule::render(VFrame *output,
00402 int64_t start_position,
00403 int direction,
00404 double frame_rate,
00405 int use_nudge,
00406 int debug_render,
00407 int use_opengl)
00408 {
00409 int result = 0;
00410 double edl_rate = get_edl()->session->frame_rate;
00411
00412 if(use_nudge) start_position += (int64_t)(track->nudge *
00413 frame_rate /
00414 edl_rate);
00415
00416 int64_t start_position_project = (int64_t)(start_position *
00417 edl_rate /
00418 frame_rate +
00419 0.5);
00420
00421 update_transition(start_position_project,
00422 direction);
00423
00424 VEdit* current_edit = (VEdit*)track->edits->editof(start_position_project,
00425 direction,
00426 0);
00427 VEdit* previous_edit = 0;
00428
00429 if(debug_render)
00430 printf(" VModule::render %d %lld %s transition=%p opengl=%d current_edit=%p output=%p\n",
00431 use_nudge,
00432 start_position_project,
00433 track->title,
00434 transition,
00435 use_opengl,
00436 current_edit,
00437 output);
00438
00439 if(!current_edit)
00440 {
00441 output->clear_frame();
00442
00443
00444
00445 return 0;
00446 }
00447
00448
00449
00450
00451
00452 if(transition && transition->on)
00453 {
00454
00455
00456 VFrame **transition_input = 0;
00457 if(commonrender)
00458 {
00459 VRender *vrender = (VRender*)commonrender;
00460 transition_input = &vrender->transition_temp;
00461 }
00462 else
00463 {
00464 transition_input = &transition_temp;
00465 }
00466
00467 if((*transition_input) &&
00468 ((*transition_input)->get_w() != track->track_w ||
00469 (*transition_input)->get_h() != track->track_h))
00470 {
00471 delete (*transition_input);
00472 (*transition_input) = 0;
00473 }
00474
00475
00476 if(!(*transition_input))
00477 {
00478 (*transition_input) = new VFrame(0,
00479 track->track_w,
00480 track->track_h,
00481 get_edl()->session->color_model,
00482 -1);
00483 }
00484
00485 result = import_frame((*transition_input),
00486 current_edit,
00487 start_position,
00488 frame_rate,
00489 direction,
00490 use_opengl);
00491
00492
00493
00494 previous_edit = (VEdit*)current_edit->previous;
00495
00496 result |= import_frame(output,
00497 previous_edit,
00498 start_position,
00499 frame_rate,
00500 direction,
00501 use_opengl);
00502
00503
00504 if(renderengine)
00505 transition_server->set_use_opengl(use_opengl, renderengine->video);
00506 transition_server->process_transition((*transition_input),
00507 output,
00508 (direction == PLAY_FORWARD) ?
00509 (start_position_project - current_edit->startproject) :
00510 (start_position_project - current_edit->startproject - 1),
00511 transition->length);
00512 }
00513 else
00514 {
00515
00516 result = import_frame(output,
00517 current_edit,
00518 start_position,
00519 frame_rate,
00520 direction,
00521 use_opengl);
00522 }
00523
00524 int64_t mask_position;
00525 if (renderengine)
00526 mask_position = renderengine->vrender->current_position;
00527 else
00528 mask_position = start_position;
00529 masker->do_mask(output,
00530 mask_position,
00531 edl_rate,
00532 edl_rate,
00533 (MaskAutos*)track->automation->autos[AUTOMATION_MASK],
00534 direction,
00535 1);
00536
00537
00538 return result;
00539 }
00540
00541
00542
00543
00544
00545
00546 void VModule::create_objects()
00547 {
00548 Module::create_objects();
00549 }
00550
00551
00552
00553
00554
00555