00001 #include "asset.h"
00002 #include "automation.h"
00003 #include "bcsignals.h"
00004 #include "clip.h"
00005 #include "edits.h"
00006 #include "edl.h"
00007 #include "edlsession.h"
00008 #include "fadeengine.h"
00009 #include "floatauto.h"
00010 #include "floatautos.h"
00011 #include "intauto.h"
00012 #include "intautos.h"
00013 #include "maskauto.h"
00014 #include "maskautos.h"
00015 #include "maskengine.h"
00016 #include "mwindow.h"
00017 #include "module.h"
00018 #include "overlayframe.h"
00019 #include "playabletracks.h"
00020 #include "plugin.h"
00021 #include "preferences.h"
00022 #include "renderengine.h"
00023 #include "transition.h"
00024 #include "transportque.h"
00025 #include "vattachmentpoint.h"
00026 #include "vdevicex11.h"
00027 #include "vframe.h"
00028 #include "videodevice.h"
00029 #include "virtualvconsole.h"
00030 #include "virtualvnode.h"
00031 #include "vmodule.h"
00032 #include "vrender.h"
00033 #include "vtrack.h"
00034
00035 #include <string.h>
00036
00037
00038 VirtualVNode::VirtualVNode(RenderEngine *renderengine,
00039 VirtualConsole *vconsole,
00040 Module *real_module,
00041 Plugin *real_plugin,
00042 Track *track,
00043 VirtualNode *parent_node)
00044 : VirtualNode(renderengine,
00045 vconsole,
00046 real_module,
00047 real_plugin,
00048 track,
00049 parent_node)
00050 {
00051 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
00052 fader = new FadeEngine(renderengine->preferences->processors);
00053 masker = new MaskEngine(renderengine->preferences->processors);
00054 }
00055
00056 VirtualVNode::~VirtualVNode()
00057 {
00058 delete fader;
00059 delete masker;
00060 }
00061
00062 VirtualNode* VirtualVNode::create_module(Plugin *real_plugin,
00063 Module *real_module,
00064 Track *track)
00065 {
00066 return new VirtualVNode(renderengine,
00067 vconsole,
00068 real_module,
00069 0,
00070 track,
00071 this);
00072 }
00073
00074
00075 VirtualNode* VirtualVNode::create_plugin(Plugin *real_plugin)
00076 {
00077 return new VirtualVNode(renderengine,
00078 vconsole,
00079 0,
00080 real_plugin,
00081 track,
00082 this);
00083 }
00084
00085 int VirtualVNode::read_data(VFrame *output_temp,
00086 int64_t start_position,
00087 double frame_rate,
00088 int use_opengl)
00089 {
00090 VirtualNode *previous_plugin = 0;
00091 int result = 0;
00092
00093 if(!output_temp)
00094 printf("VirtualVNode::read_data output_temp=%p\n", output_temp);
00095
00096 if(vconsole->debug_tree)
00097 printf(" VirtualVNode::read_data position=%lld rate=%f title=%s opengl=%d\n",
00098 start_position,
00099 frame_rate,
00100 track->title,
00101 use_opengl);
00102
00103
00104
00105
00106 VEdit *parent_edit = 0;
00107 if(parent_node && parent_node->track && renderengine)
00108 {
00109 double edl_rate = renderengine->edl->session->frame_rate;
00110 int64_t start_position_project = (int64_t)(start_position *
00111 edl_rate /
00112 frame_rate +
00113 0.5);
00114 parent_edit = (VEdit*)parent_node->track->edits->editof(start_position_project,
00115 renderengine->command->get_direction(),
00116 0);
00117 }
00118
00119
00120
00121
00122 if(parent_node && (previous_plugin = parent_node->get_previous_plugin(this)))
00123 {
00124 result = ((VirtualVNode*)previous_plugin)->render(output_temp,
00125 start_position,
00126 frame_rate,
00127 use_opengl);
00128 }
00129 else
00130
00131
00132
00133
00134 if(parent_node && (parent_edit || !real_module))
00135 {
00136 result = ((VirtualVNode*)parent_node)->read_data(output_temp,
00137 start_position,
00138 frame_rate,
00139 use_opengl);
00140 }
00141 else
00142 if(real_module)
00143 {
00144
00145 result = ((VModule*)real_module)->render(output_temp,
00146 start_position,
00147 renderengine->command->get_direction(),
00148 frame_rate,
00149 0,
00150 vconsole->debug_tree,
00151 use_opengl);
00152 }
00153
00154 return result;
00155 }
00156
00157
00158 int VirtualVNode::render(VFrame *output_temp,
00159 int64_t start_position,
00160 double frame_rate,
00161 int use_opengl)
00162 {
00163 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
00164 if(real_module)
00165 {
00166 render_as_module(vrender->video_out,
00167 output_temp,
00168 start_position,
00169 frame_rate,
00170 use_opengl);
00171 }
00172 else
00173 if(real_plugin)
00174 {
00175 render_as_plugin(output_temp,
00176 start_position,
00177 frame_rate,
00178 use_opengl);
00179 }
00180 return 0;
00181 }
00182
00183 void VirtualVNode::render_as_plugin(VFrame *output_temp,
00184 int64_t start_position,
00185 double frame_rate,
00186 int use_opengl)
00187 {
00188 if(!attachment ||
00189 !real_plugin ||
00190 !real_plugin->on) return;
00191
00192
00193 if(vconsole->debug_tree)
00194 printf(" VirtualVNode::render_as_plugin title=%s use_opengl=%d\n",
00195 track->title,
00196 use_opengl);
00197
00198 ((VAttachmentPoint*)attachment)->render(
00199 output_temp,
00200 plugin_buffer_number,
00201 start_position,
00202 frame_rate,
00203 vconsole->debug_tree,
00204 use_opengl);
00205 }
00206
00207
00208 int VirtualVNode::render_as_module(VFrame *video_out,
00209 VFrame *output_temp,
00210 int64_t start_position,
00211 double frame_rate,
00212 int use_opengl)
00213 {
00214
00215 int direction = renderengine->command->get_direction();
00216 double edl_rate = renderengine->edl->session->frame_rate;
00217
00218 int64_t start_position_project = (int64_t)(start_position *
00219 edl_rate /
00220 frame_rate);
00221 if(direction == PLAY_REVERSE) start_position_project--;
00222
00223 if(vconsole->debug_tree)
00224 printf(" VirtualVNode::render_as_module title=%s use_opengl=%d video_out=%p output_temp=%p\n",
00225 track->title,
00226 use_opengl,
00227 video_out,
00228 output_temp);
00229
00230 output_temp->push_next_effect("VirtualVNode::render_as_module");
00231
00232
00233
00234 if(subnodes.total)
00235 {
00236 VirtualVNode *node = (VirtualVNode*)subnodes.values[subnodes.total - 1];
00237 node->render(output_temp,
00238 start_position,
00239 frame_rate,
00240 use_opengl);
00241 }
00242 else
00243
00244 {
00245 read_data(output_temp,
00246 start_position,
00247 frame_rate,
00248 use_opengl);
00249 }
00250
00251 output_temp->pop_next_effect();
00252
00253 render_fade(output_temp,
00254 start_position,
00255 frame_rate,
00256 track->automation->autos[AUTOMATION_FADE],
00257 direction);
00258
00259 render_mask(output_temp, start_position_project, frame_rate, use_opengl);
00260
00261
00262
00263
00264 int mute_constant;
00265 int mute_fragment = 1;
00266 int64_t mute_position = 0;
00267
00268
00269
00270 get_mute_fragment(start_position,
00271 mute_constant,
00272 mute_fragment,
00273 (Autos*)((VTrack*)track)->automation->autos[AUTOMATION_MUTE],
00274 direction,
00275 0);
00276
00277 if(!mute_constant)
00278 {
00279
00280 render_projector(output_temp,
00281 video_out,
00282 start_position,
00283 frame_rate);
00284 }
00285
00286 output_temp->push_prev_effect("VirtualVNode::render_as_module");
00287
00288
00289
00290 Edit *edit = 0;
00291 if(renderengine->show_tc)
00292 renderengine->vrender->insert_timecode(edit,
00293 start_position,
00294 output_temp);
00295
00296 return 0;
00297 }
00298
00299 int VirtualVNode::render_fade(VFrame *output,
00300
00301
00302 int64_t start_position,
00303 double frame_rate,
00304 Autos *autos,
00305 int direction)
00306 {
00307 double slope, intercept;
00308 int64_t slope_len = 1;
00309 FloatAuto *previous = 0;
00310 FloatAuto *next = 0;
00311 double edl_rate = renderengine->edl->session->frame_rate;
00312 int64_t start_position_project = (int64_t)(start_position *
00313 edl_rate /
00314 frame_rate);
00315
00316 if(vconsole->debug_tree)
00317 printf(" VirtualVNode::render_fade title=%s\n", track->title);
00318
00319 intercept = ((FloatAutos*)autos)->get_value(start_position_project,
00320 direction,
00321 previous,
00322 next);
00323
00324
00325 CLAMP(intercept, 0, 100);
00326
00327
00328
00329
00330
00331 if(!EQUIV(intercept / 100, 1))
00332 {
00333 if(((VirtualVConsole*)vconsole)->use_opengl)
00334 ((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->do_fade(
00335 output,
00336 intercept / 100);
00337 else
00338 fader->do_fade(output, output, intercept / 100);
00339 }
00340
00341 return 0;
00342 }
00343
00344
00345
00346 void VirtualVNode::render_mask(VFrame *output_temp,
00347 int64_t start_position_project,
00348 double frame_rate,
00349 int use_opengl)
00350 {
00351 MaskAutos *keyframe_set =
00352 (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
00353
00354 Auto *current = 0;
00355 MaskAuto *default_auto = (MaskAuto*)keyframe_set->default_auto;
00356 MaskAuto *keyframe = (MaskAuto*)keyframe_set->get_prev_auto(start_position_project,
00357 PLAY_FORWARD,
00358 current);
00359
00360 int total_points = 0;
00361 for(int i = 0; i < keyframe->masks.total; i++)
00362 {
00363 SubMask *mask = keyframe->get_submask(i);
00364 int submask_points = mask->points.total;
00365 if(submask_points > 1) total_points += submask_points;
00366 }
00367
00368
00369
00370 if(total_points <= 2 ||
00371 (keyframe->value == 0 && default_auto->mode == MASK_SUBTRACT_ALPHA))
00372 {
00373 return;
00374 }
00375
00376
00377 if(keyframe->value == 0 && default_auto->mode == MASK_MULTIPLY_ALPHA)
00378 {
00379 output_temp->clear_frame();
00380 return;
00381 }
00382
00383 if(((VirtualVConsole*)vconsole)->use_opengl)
00384 {
00385 ((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->do_mask(
00386 output_temp,
00387 start_position_project,
00388 keyframe_set,
00389 keyframe,
00390 default_auto);
00391 }
00392 else
00393 {
00394
00395 int direction = renderengine->command->get_direction();
00396 double edl_rate = renderengine->edl->session->frame_rate;
00397 masker->do_mask(output_temp,
00398 start_position_project,
00399 frame_rate,
00400 edl_rate,
00401 keyframe_set,
00402 direction,
00403 0);
00404 }
00405 }
00406
00407
00408
00409 int VirtualVNode::render_projector(VFrame *input,
00410 VFrame *output,
00411 int64_t start_position,
00412 double frame_rate)
00413 {
00414 float in_x1, in_y1, in_x2, in_y2;
00415 float out_x1, out_y1, out_x2, out_y2;
00416 double edl_rate = renderengine->edl->session->frame_rate;
00417 int64_t start_position_project = (int64_t)(start_position *
00418 edl_rate /
00419 frame_rate);
00420 VRender *vrender = ((VirtualVConsole*)vconsole)->vrender;
00421 if(vconsole->debug_tree)
00422 printf(" VirtualVNode::render_projector input=%p output=%p title=%s\n",
00423 input, output, track->title);
00424
00425 if(output)
00426 {
00427 ((VTrack*)track)->calculate_output_transfer(start_position_project,
00428 renderengine->command->get_direction(),
00429 in_x1,
00430 in_y1,
00431 in_x2,
00432 in_y2,
00433 out_x1,
00434 out_y1,
00435 out_x2,
00436 out_y2);
00437
00438 in_x2 += in_x1;
00439 in_y2 += in_y1;
00440 out_x2 += out_x1;
00441 out_y2 += out_y1;
00442
00443
00444
00445
00446 if(out_x2 > out_x1 &&
00447 out_y2 > out_y1 &&
00448 in_x2 > in_x1 &&
00449 in_y2 > in_y1)
00450 {
00451 int direction = renderengine->command->get_direction();
00452 IntAuto *mode_keyframe = 0;
00453 mode_keyframe =
00454 (IntAuto*)track->automation->autos[AUTOMATION_MODE]->get_prev_auto(
00455 start_position_project,
00456 direction,
00457 (Auto* &)mode_keyframe);
00458
00459 int mode = mode_keyframe->value;
00460
00461
00462
00463
00464
00465
00466
00467
00468 if(mode == TRANSFER_NORMAL &&
00469 vconsole->current_exit_node == vconsole->total_exit_nodes - 1)
00470 mode = TRANSFER_REPLACE;
00471
00472 if(((VirtualVConsole*)vconsole)->use_opengl)
00473 {
00474 ((VDeviceX11*)((VirtualVConsole*)vconsole)->get_vdriver())->overlay(
00475 output,
00476 input,
00477 in_x1,
00478 in_y1,
00479 in_x2,
00480 in_y2,
00481 out_x1,
00482 out_y1,
00483 out_x2,
00484 out_y2,
00485 1,
00486 mode,
00487 renderengine->edl);
00488 }
00489 else
00490 {
00491 vrender->overlayer->overlay(output,
00492 input,
00493 in_x1,
00494 in_y1,
00495 in_x2,
00496 in_y2,
00497 out_x1,
00498 out_y1,
00499 out_x2,
00500 out_y2,
00501 1,
00502 mode,
00503 renderengine->edl->session->interpolation_type);
00504 }
00505 }
00506 }
00507 return 0;
00508 }
00509