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 "vedit.h"
00024 #include "vframe.h"
00025 #include "vmodule.h"
00026 #include "vrender.h"
00027 #include "vplugin.h"
00028 #include "vtrack.h"
00029 #include <string.h>
00030 #include "interlacemodes.h"
00031
00032 VModule::VModule(RenderEngine *renderengine,
00033 CommonRender *commonrender,
00034 PluginArray *plugin_array,
00035 Track *track)
00036 : Module(renderengine, commonrender, plugin_array, track)
00037 {
00038 data_type = TRACK_VIDEO;
00039 overlay_temp = 0;
00040 input_temp = 0;
00041 transition_temp = 0;
00042 }
00043
00044 VModule::~VModule()
00045 {
00046 if(overlay_temp) delete overlay_temp;
00047 if(input_temp) delete input_temp;
00048 if(transition_temp) delete transition_temp;
00049 }
00050
00051
00052 AttachmentPoint* VModule::new_attachment(Plugin *plugin)
00053 {
00054 return new VAttachmentPoint(renderengine, plugin);
00055 }
00056
00057 int VModule::get_buffer_size()
00058 {
00059 return 1;
00060 }
00061
00062 CICache* VModule::get_cache()
00063 {
00064 if(renderengine)
00065 return renderengine->get_vcache();
00066 else
00067 return cache;
00068 }
00069
00070 int VModule::import_frame(VFrame *output,
00071 VEdit *current_edit,
00072 int64_t input_position,
00073 double frame_rate,
00074 int direction)
00075 {
00076 int64_t corrected_position;
00077 int64_t corrected_position_project;
00078
00079 float in_x1;
00080 float in_y1;
00081 float in_w1;
00082 float in_h1;
00083 float out_x1;
00084 float out_y1;
00085 float out_w1;
00086 float out_h1;
00087 int result = 0;
00088 SET_TRACE
00089 double edl_rate = get_edl()->session->frame_rate;
00090 int64_t input_position_project = (int64_t)(input_position *
00091 edl_rate /
00092 frame_rate +
00093 0.001);
00094 if(!output) printf("VModule::import_frame 10 output=%p\n", output);
00095
00096 SET_TRACE
00097 corrected_position = input_position;
00098 corrected_position_project = input_position_project;
00099 if(direction == PLAY_REVERSE)
00100 {
00101 corrected_position--;
00102 input_position_project--;
00103 }
00104
00105
00106 if(current_edit &&
00107 current_edit->asset)
00108 {
00109 get_cache()->age();
00110 SET_TRACE
00111 File *source = get_cache()->check_out(current_edit->asset);
00112 SET_TRACE
00113
00114
00115 if(source)
00116 {
00117 int64_t edit_startproject = (int64_t)(current_edit->startproject *
00118 frame_rate /
00119 edl_rate);
00120 int64_t edit_startsource = (int64_t)(current_edit->startsource *
00121 frame_rate /
00122 edl_rate);
00123 uint64_t position = corrected_position -
00124 edit_startproject +
00125 edit_startsource;
00126
00127 uint64_t max_position = source->get_video_length(frame_rate) - 1;
00128 if (position > max_position) position = max_position;
00129 source->set_video_position(position,
00130 frame_rate);
00131 source->set_layer(current_edit->channel);
00132 SET_TRACE
00133
00134 ((VTrack*)track)->calculate_input_transfer(current_edit->asset,
00135 input_position_project,
00136 direction,
00137 in_x1,
00138 in_y1,
00139 in_w1,
00140 in_h1,
00141 out_x1,
00142 out_y1,
00143 out_w1,
00144 out_h1);
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int interlace_fixmethod = ilaceautofixmethod2(get_edl()->session->interlace_mode,
00155 current_edit->asset->interlace_autofixoption,
00156 current_edit->asset->interlace_mode,
00157 current_edit->asset->interlace_fixmethod);
00158
00159
00160
00161
00162
00163
00164 switch (interlace_fixmethod) {
00165 case BC_ILACE_FIXMETHOD_NONE:
00166
00167 break;
00168 case BC_ILACE_FIXMETHOD_UPONE:
00169 out_y1--;
00170 break;
00171 case BC_ILACE_FIXMETHOD_DOWNONE:
00172 out_y1++;
00173 break;
00174 default:
00175 printf("vmodule::importframe WARNING - unknown fix method for interlacing, no compensation in effect\n");
00176 }
00177 SET_TRACE
00178
00179
00180
00181 if( !EQUIV(in_x1, 0) ||
00182 !EQUIV(in_y1, 0) ||
00183 !EQUIV(in_w1, track->track_w) ||
00184 !EQUIV(in_h1, track->track_h) ||
00185 !EQUIV(out_x1, 0) ||
00186 !EQUIV(out_y1, 0) ||
00187 !EQUIV(out_w1, track->track_w) ||
00188 !EQUIV(out_h1, track->track_h) ||
00189 !EQUIV(in_w1, current_edit->asset->width) ||
00190 !EQUIV(in_h1, current_edit->asset->height))
00191 {
00192
00193
00194 VFrame **input = 0;
00195
00196 if(commonrender)
00197 {
00198 VRender *vrender = (VRender*)commonrender;
00199 input = &vrender->input_temp;
00200 }
00201 else
00202
00203 {
00204 input = &input_temp;
00205 }
00206
00207
00208 if((*input) &&
00209 ((*input)->get_w() != current_edit->asset->width ||
00210 (*input)->get_h() != current_edit->asset->height))
00211 {
00212 delete (*input);
00213 (*input) = 0;
00214 }
00215
00216
00217
00218
00219
00220 if(!(*input))
00221 {
00222 (*input) = new VFrame(0,
00223 current_edit->asset->width,
00224 current_edit->asset->height,
00225 get_edl()->session->color_model,
00226 -1);
00227 }
00228
00229
00230
00231
00232
00233 if(renderengine && renderengine->command->single_frame())
00234 source->set_cache_frames(1);
00235 SET_TRACE
00236 result = source->read_frame((*input));
00237 SET_TRACE
00238 if(renderengine && renderengine->command->single_frame())
00239 source->set_cache_frames(0);
00240
00241
00242 OverlayFrame *overlayer = 0;
00243
00244 if(commonrender)
00245 {
00246 VRender *vrender = (VRender*)commonrender;
00247 overlayer = vrender->overlayer;
00248 }
00249 else
00250
00251 {
00252 if(!plugin_array)
00253 printf("VModule::import_frame neither plugin_array nor commonrender is defined.\n");
00254 if(!overlay_temp)
00255 {
00256 overlay_temp = new OverlayFrame(plugin_array->mwindow->preferences->processors);
00257 }
00258
00259 overlayer = overlay_temp;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 output->clear_frame();
00276
00277
00278
00279
00280
00281 int mode = TRANSFER_REPLACE;
00282
00283 overlayer->overlay(output,
00284 (*input),
00285 in_x1,
00286 in_y1,
00287 in_x1 + in_w1,
00288 in_y1 + in_h1,
00289 out_x1,
00290 out_y1,
00291 out_x1 + out_w1,
00292 out_y1 + out_h1,
00293 1,
00294 mode,
00295 get_edl()->session->interpolation_type);
00296 result = 1;
00297
00298 }
00299 else
00300
00301 {
00302
00303
00304 if(renderengine && renderengine->command->single_frame())
00305 source->set_cache_frames(1);
00306 result = source->read_frame(output);
00307 if(renderengine && renderengine->command->single_frame())
00308 source->set_cache_frames(0);
00309
00310 }
00311 SET_TRACE
00312
00313 get_cache()->check_in(current_edit->asset);
00314 }
00315 else
00316 {
00317 output->clear_frame();
00318 result = 1;
00319 }
00320 }
00321 else
00322
00323 {
00324 output->clear_frame();
00325 }
00326
00327 return result;
00328 }
00329
00330
00331
00332 int VModule::render(VFrame *output,
00333 int64_t start_position,
00334 int direction,
00335 double frame_rate,
00336 int use_nudge,
00337 int debug_render)
00338 {
00339 int result = 0;
00340 double edl_rate = get_edl()->session->frame_rate;
00341
00342
00343 if(use_nudge) start_position += (int64_t)(track->nudge *
00344 frame_rate /
00345 edl_rate);
00346
00347
00348 int64_t start_position_project = (int64_t)(start_position *
00349 edl_rate /
00350 frame_rate +
00351 0.5);
00352
00353 if(debug_render)
00354 printf(" VModule::render %d %lld %s\n",
00355 use_nudge,
00356 start_position_project,
00357 track->title);
00358
00359 update_transition(start_position_project,
00360 direction);
00361 SET_TRACE
00362
00363 VEdit* current_edit = (VEdit*)track->edits->editof(start_position_project,
00364 direction,
00365 0);
00366 SET_TRACE
00367 VEdit* previous_edit = 0;
00368
00369 if(!current_edit)
00370 {
00371 output->clear_frame();
00372 return 0;
00373 }
00374
00375
00376
00377
00378
00379 if(transition)
00380 {
00381
00382
00383 VFrame **transition_input = 0;
00384 if(commonrender)
00385 {
00386 VRender *vrender = (VRender*)commonrender;
00387 transition_input = &vrender->transition_temp;
00388 }
00389 else
00390 {
00391 transition_input = &transition_temp;
00392 }
00393
00394 if((*transition_input) &&
00395 ((*transition_input)->get_w() != track->track_w ||
00396 (*transition_input)->get_h() != track->track_h))
00397 {
00398 delete (*transition_input);
00399 (*transition_input) = 0;
00400 }
00401
00402
00403 if(!(*transition_input))
00404 {
00405 (*transition_input) = new VFrame(0,
00406 track->track_w,
00407 track->track_h,
00408 get_edl()->session->color_model,
00409 -1);
00410 }
00411
00412 result = import_frame((*transition_input),
00413 current_edit,
00414 start_position,
00415 frame_rate,
00416 direction);
00417
00418
00419
00420 previous_edit = (VEdit*)current_edit->previous;
00421
00422 result |= import_frame(output,
00423 previous_edit,
00424 start_position,
00425 frame_rate,
00426 direction);
00427
00428
00429 transition_server->process_transition((*transition_input),
00430 output,
00431 (direction == PLAY_FORWARD) ?
00432 (start_position_project - current_edit->startproject) :
00433 (start_position_project - current_edit->startproject - 1),
00434 transition->length);
00435 }
00436 else
00437 {
00438
00439 SET_TRACE
00440 result = import_frame(output,
00441 current_edit,
00442 start_position,
00443 frame_rate,
00444 direction);
00445 SET_TRACE
00446 }
00447
00448
00449 return result;
00450 }
00451
00452
00453
00454
00455
00456
00457 void VModule::create_objects()
00458 {
00459 Module::create_objects();
00460 }
00461
00462
00463
00464
00465
00466