00001 #include "arender.h"
00002 #include "asset.h"
00003 #include "auto.h"
00004 #include "brender.h"
00005 #include "cache.h"
00006 #include "clip.h"
00007 #include "cwindow.h"
00008 #include "cwindowgui.h"
00009 #include "edit.h"
00010 #include "edits.h"
00011 #include "edl.h"
00012 #include "edlsession.h"
00013 #include "errorbox.h"
00014 #include "file.h"
00015 #include "filesystem.h"
00016 #include "indexfile.h"
00017 #include "language.h"
00018 #include "mwindow.h"
00019 #include "mwindowgui.h"
00020 #include "packagerenderer.h"
00021 #include "playabletracks.h"
00022 #include "playbackconfig.h"
00023 #include "pluginserver.h"
00024 #include "preferences.h"
00025 #include "render.h"
00026 #include "renderengine.h"
00027 #include "renderfarmfsserver.h"
00028 #include "sighandler.h"
00029 #include "tracks.h"
00030 #include "transportque.h"
00031 #include "vedit.h"
00032 #include "vframe.h"
00033 #include "videodevice.h"
00034 #include "vrender.h"
00035
00036
00037
00038
00039
00040
00041
00042 RenderPackage::RenderPackage()
00043 {
00044 audio_start = 0;
00045 audio_end = 0;
00046 video_start = 0;
00047 video_end = 0;
00048 path[0] = 0;
00049 done = 0;
00050 use_brender = 0;
00051 }
00052
00053 RenderPackage::~RenderPackage()
00054 {
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 PackageRenderer::PackageRenderer()
00066 {
00067 command = 0;
00068 audio_cache = 0;
00069 video_cache = 0;
00070 aconfig = 0;
00071 vconfig = 0;
00072 }
00073
00074 PackageRenderer::~PackageRenderer()
00075 {
00076 delete command;
00077 delete audio_cache;
00078 delete video_cache;
00079 delete vconfig;
00080 }
00081
00082 int PackageRenderer::initialize(MWindow *mwindow,
00083 EDL *edl,
00084 Preferences *preferences,
00085 Asset *default_asset,
00086 ArrayList<PluginServer*> *plugindb)
00087 {
00088 int result = 0;
00089
00090 this->mwindow = mwindow;
00091 this->edl = edl;
00092 this->preferences = preferences;
00093 this->default_asset = default_asset;
00094 this->plugindb = plugindb;
00095
00096
00097
00098 command = new TransportCommand;
00099 command->command = NORMAL_FWD;
00100 command->get_edl()->copy_all(edl);
00101 command->change_type = CHANGE_ALL;
00102 command->set_playback_range(edl);
00103
00104 default_asset->frame_rate = command->get_edl()->session->frame_rate;
00105 default_asset->sample_rate = command->get_edl()->session->sample_rate;
00106 default_asset->aspect_ratio = (double)command->get_edl()->session->aspect_w /
00107 command->get_edl()->session->aspect_h;
00108 result = Render::check_asset(edl, *default_asset);
00109
00110 audio_cache = new CICache(command->get_edl(), preferences, plugindb);
00111 video_cache = new CICache(command->get_edl(), preferences, plugindb);
00112
00113 PlaybackConfig *config = command->get_edl()->session->playback_config;
00114 aconfig = new AudioOutConfig(0);
00115 vconfig = new VideoOutConfig;
00116
00117 for(int i = 0; i < MAX_CHANNELS; i++)
00118 {
00119 vconfig->do_channel[i] = (i < command->get_edl()->session->video_channels);
00120 }
00121
00122
00123 return result;
00124 }
00125
00126 void PackageRenderer::create_output()
00127 {
00128 FileSystem fs;
00129 asset = new Asset(*default_asset);
00130
00131
00132
00133
00134
00135
00136
00137 if(!get_master() && preferences->renderfarm_vfs && preferences->use_renderfarm)
00138 sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", package->path);
00139 else
00140 strcpy(asset->path, package->path);
00141
00142
00143
00144
00145 file = new File;
00146
00147 file->set_processors(preferences->processors);
00148
00149 result = file->open_file(preferences,
00150 asset,
00151 0,
00152 1,
00153 command->get_edl()->session->sample_rate,
00154 command->get_edl()->session->frame_rate);
00155
00156
00157 if(result && mwindow)
00158 {
00159
00160 char string[BCTEXTLEN];
00161 sprintf(string, _("Couldn't open %s"), asset->path);
00162 ErrorBox error(PROGRAM_NAME ": Error",
00163 mwindow->gui->get_abs_cursor_x(1),
00164 mwindow->gui->get_abs_cursor_y(1));
00165 error.create_objects(string);
00166 error.run_window();
00167 }
00168 else
00169 if(mwindow)
00170 {
00171 mwindow->sighandler->push_file(file);
00172 IndexFile::delete_index(preferences, asset);
00173 }
00174
00175 }
00176
00177 void PackageRenderer::create_engine()
00178 {
00179 int current_achannel = 0, current_vchannel = 0;
00180 audio_read_length = command->get_edl()->session->sample_rate;
00181
00182 aconfig->fragment_size = audio_read_length;
00183
00184
00185 render_engine = new RenderEngine(0,
00186 preferences,
00187 command,
00188 0,
00189 plugindb,
00190 0);
00191 render_engine->set_acache(audio_cache);
00192 render_engine->set_vcache(video_cache);
00193 render_engine->arm_command(command, current_achannel, current_vchannel);
00194
00195 if(package->use_brender)
00196 {
00197 audio_preroll = Units::to_int64((double)preferences->brender_preroll /
00198 default_asset->frame_rate *
00199 default_asset->sample_rate);
00200 video_preroll = preferences->brender_preroll;
00201 }
00202 else
00203 {
00204 audio_preroll = Units::to_int64(preferences->render_preroll *
00205 default_asset->sample_rate);
00206 video_preroll = Units::to_int64(preferences->render_preroll *
00207 default_asset->frame_rate);
00208 }
00209 audio_position = package->audio_start - audio_preroll;
00210 video_position = package->video_start - video_preroll;
00211
00212
00213
00214
00215
00216 if(asset->audio_data)
00217 {
00218 file->start_audio_thread(audio_read_length,
00219 preferences->processors > 1 ? 2 : 1);
00220 }
00221
00222
00223 if(asset->video_data)
00224 {
00225 compressed_output = new VFrame;
00226
00227
00228 video_write_length = preferences->processors;
00229 video_write_position = 0;
00230 direct_frame_copying = 0;
00231
00232
00233
00234 file->start_video_thread(video_write_length,
00235 command->get_edl()->session->color_model,
00236 preferences->processors > 1 ? 2 : 1,
00237 0);
00238
00239
00240 if(mwindow)
00241 {
00242 video_device = new VideoDevice;
00243 video_device->open_output(vconfig,
00244 command->get_edl()->session->frame_rate,
00245 command->get_edl()->session->output_w,
00246 command->get_edl()->session->output_h,
00247 mwindow->cwindow->gui->canvas,
00248 0);
00249 video_device->start_playback();
00250 }
00251 }
00252
00253
00254 playable_tracks = new PlayableTracks(render_engine,
00255 video_position,
00256 TRACK_VIDEO,
00257 1);
00258
00259 }
00260
00261
00262
00263
00264 void PackageRenderer::do_audio()
00265 {
00266
00267
00268 if(asset->audio_data)
00269 {
00270 audio_output = file->get_audio_buffer();
00271
00272 for(int i = 0; i < MAX_CHANNELS; i++)
00273 audio_output_ptr[i] = (i < asset->channels) ?
00274 audio_output[i] :
00275 0;
00276
00277
00278
00279
00280
00281 result = render_engine->arender->process_buffer(audio_output_ptr,
00282 audio_read_length,
00283 audio_position,
00284 0);
00285
00286
00287
00288
00289
00290 int64_t output_length = audio_read_length;
00291 if(audio_preroll > 0)
00292 {
00293 if(audio_preroll >= output_length)
00294 output_length = 0;
00295 else
00296 {
00297 output_length -= audio_preroll;
00298 for(int i = 0; i < MAX_CHANNELS; i++)
00299 {
00300 if(audio_output_ptr[i])
00301 for(int j = 0; j < output_length; j++)
00302 {
00303 audio_output_ptr[i][j] = audio_output_ptr[i][j + audio_read_length - output_length];
00304 }
00305 }
00306 }
00307
00308
00309 audio_preroll -= audio_read_length;
00310 }
00311
00312
00313 result |= file->write_audio_buffer(output_length);
00314 }
00315
00316 audio_position += audio_read_length;
00317
00318 }
00319
00320
00321 void PackageRenderer::do_video()
00322 {
00323
00324 if(asset->video_data)
00325 {
00326
00327 int64_t video_end = video_position + video_read_length;
00328
00329 if(video_end > package->video_end)
00330 video_end = package->video_end;
00331
00332 while(video_position < video_end && !result)
00333 {
00334
00335
00336 if(direct_frame_copy(command->get_edl(),
00337 video_position,
00338 file,
00339 result))
00340 {
00341
00342
00343 if(direct_frame_copying)
00344 {
00345 file->start_video_thread(video_write_length,
00346 command->get_edl()->session->color_model,
00347 preferences->processors > 1 ? 2 : 1,
00348 0);
00349 direct_frame_copying = 0;
00350 }
00351
00352
00353
00354
00355
00356
00357 if(video_write_position == 0)
00358 video_output = file->get_video_buffer();
00359
00360
00361
00362
00363
00364
00365 for(int i = 0; i < MAX_CHANNELS; i++)
00366 video_output_ptr[i] =
00367 (i < asset->layers) ?
00368 video_output[i][video_write_position] :
00369 0;
00370
00371 if(!result)
00372 result = render_engine->vrender->process_buffer(
00373 video_output_ptr,
00374 video_position,
00375 0);
00376
00377
00378
00379 if(!result &&
00380 mwindow &&
00381 video_device->output_visible())
00382 {
00383
00384 VFrame *preview_output[MAX_CHANNELS];
00385
00386 video_device->new_output_buffers(preview_output,
00387 command->get_edl()->session->color_model);
00388
00389 for(int i = 0; i < MAX_CHANNELS; i++)
00390 if(preview_output[i])
00391 preview_output[i]->copy_from(video_output_ptr[i]);
00392 video_device->write_buffer(preview_output,
00393 command->get_edl());
00394 }
00395
00396
00397
00398
00399 if(video_preroll && !result)
00400 {
00401 video_preroll--;
00402
00403 result = file->write_video_buffer(0);
00404 video_write_position = 0;
00405 }
00406 else
00407 if(!result)
00408 {
00409
00410
00411
00412
00413
00414
00415 video_output_ptr[0]->set_number(video_position);
00416
00417
00418 video_write_position++;
00419
00420 if(video_write_position >= video_write_length)
00421 {
00422
00423 result = file->write_video_buffer(video_write_position);
00424
00425 if(package->use_brender)
00426 {
00427
00428 for(int i = 0; i < video_write_position && !result; i++)
00429 {
00430 result = set_video_map(video_position + 1 - video_write_position + i,
00431 BRender::RENDERED);
00432 }
00433
00434 }
00435 video_write_position = 0;
00436 }
00437 }
00438
00439
00440 }
00441
00442 video_position++;
00443 if(!result && get_result()) result = 1;
00444 if(!result && progress_cancelled()) result = 1;
00445 }
00446 }
00447 else
00448 {
00449 video_position += video_read_length;
00450 }
00451 }
00452
00453
00454 void PackageRenderer::stop_engine()
00455 {
00456 delete render_engine;
00457 delete playable_tracks;
00458 }
00459
00460
00461 void PackageRenderer::stop_output()
00462 {
00463 int error = 0;
00464 if(asset->audio_data)
00465 {
00466
00467 file->stop_audio_thread();
00468 }
00469
00470 if(asset->video_data)
00471 {
00472 delete compressed_output;
00473 if(video_write_position)
00474 file->write_video_buffer(video_write_position);
00475 if(package->use_brender)
00476 {
00477 for(int i = 0; i < video_write_position && !error; i++)
00478 {
00479 error = set_video_map(video_position - video_write_position + i,
00480 BRender::RENDERED);
00481 }
00482 }
00483 video_write_position = 0;
00484 if(!error) file->stop_video_thread();
00485 if(mwindow)
00486 {
00487 video_device->stop_playback();
00488 video_device->close_all();
00489 delete video_device;
00490 }
00491 }
00492 }
00493
00494
00495 void PackageRenderer::close_output()
00496 {
00497 if(mwindow)
00498 mwindow->sighandler->pull_file(file);
00499 file->close_file();
00500 delete file;
00501 delete asset;
00502 }
00503
00504
00505 int PackageRenderer::render_package(RenderPackage *package)
00506 {
00507 int audio_done = 0;
00508 int video_done = 0;
00509 int samples_rendered = 0;
00510
00511
00512 result = 0;
00513 this->package = package;
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 create_output();
00524
00525 if(!asset->video_data) video_done = 1;
00526 if(!asset->audio_data) audio_done = 1;
00527
00528
00529 if(!result)
00530 {
00531 create_engine();
00532
00533
00534
00535
00536 while((!audio_done || !video_done) && !result)
00537 {
00538 int need_audio = 0, need_video = 0;
00539
00540
00541
00542
00543
00544 if(!audio_done)
00545 {
00546 if(audio_position + audio_read_length >= package->audio_end)
00547 {
00548 audio_done = 1;
00549 audio_read_length = package->audio_end - audio_position;
00550 }
00551
00552 samples_rendered = audio_read_length;
00553 need_audio = 1;
00554 }
00555
00556
00557
00558 if(!video_done)
00559 {
00560 if(audio_done)
00561 {
00562 video_read_length = package->video_end - video_position;
00563
00564 video_read_length = (int)MIN(asset->frame_rate, video_read_length);
00565 video_read_length = MAX(video_read_length, 30);
00566 }
00567 else
00568
00569 {
00570 video_read_length = Units::to_int64(
00571 (double)(audio_position + audio_read_length) /
00572 asset->sample_rate *
00573 asset->frame_rate) -
00574 video_position;
00575 }
00576
00577
00578 if(video_position + video_read_length >= package->video_end)
00579 {
00580 video_done = 1;
00581 video_read_length = package->video_end - video_position;
00582 }
00583
00584
00585 if(audio_done)
00586 samples_rendered = Units::round((double)video_read_length /
00587 asset->frame_rate *
00588 asset->sample_rate);
00589
00590 need_video = 1;
00591 }
00592
00593
00594 if(need_video && !result) do_video();
00595
00596 if(need_audio && !result) do_audio();
00597
00598
00599 if(!result) set_progress(samples_rendered);
00600
00601
00602
00603
00604
00605 if(!result && progress_cancelled()) result = 1;
00606
00607
00608
00609 if(result)
00610 set_result(result);
00611 else
00612 result = get_result();
00613 }
00614
00615
00616 stop_engine();
00617
00618
00619 stop_output();
00620
00621
00622
00623 }
00624
00625
00626
00627
00628 close_output();
00629
00630
00631
00632 set_result(result);
00633
00634
00635
00636
00637 return result;
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 int PackageRenderer::direct_frame_copy(EDL *edl,
00650 int64_t &video_position,
00651 File *file,
00652 int &error)
00653 {
00654 Track *playable_track;
00655 Edit *playable_edit;
00656 int64_t frame_size;
00657
00658
00659 if(direct_copy_possible(edl,
00660 video_position,
00661 playable_track,
00662 playable_edit,
00663 file))
00664 {
00665
00666 if(!direct_frame_copying)
00667 {
00668 if(video_write_position)
00669 {
00670 error |= file->write_video_buffer(video_write_position);
00671 video_write_position = 0;
00672 }
00673 file->stop_video_thread();
00674 direct_frame_copying = 1;
00675 }
00676
00677
00678 if(!package->use_brender)
00679 error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
00680 video_position,
00681 PLAY_FORWARD,
00682 video_cache,
00683 1,
00684 0);
00685
00686
00687 if(!error && video_preroll > 0)
00688 {
00689 video_preroll--;
00690 }
00691 else
00692 if(!error)
00693 {
00694 if(package->use_brender)
00695 {
00696
00697 error = set_video_map(video_position, BRender::SCANNED);
00698
00699 }
00700 else
00701 {
00702 VFrame ***temp_output = new VFrame**[1];
00703 temp_output[0] = new VFrame*[1];
00704 temp_output[0][0] = compressed_output;
00705 error = file->write_frames(temp_output, 1);
00706 delete temp_output[0];
00707 delete temp_output;
00708 }
00709 }
00710 return 0;
00711 }
00712 else
00713 return 1;
00714 }
00715
00716 int PackageRenderer::direct_copy_possible(EDL *edl,
00717 int64_t current_position,
00718 Track* playable_track,
00719 Edit* &playable_edit,
00720 File *file)
00721 {
00722 int result = 1;
00723 int total_playable_tracks = 0;
00724 Track* current_track;
00725 Patch* current_patch;
00726 Auto* current_auto;
00727 int temp;
00728
00729
00730 for(current_track = edl->tracks->first;
00731 current_track && result;
00732 current_track = current_track->next)
00733 {
00734 if(current_track->data_type == TRACK_VIDEO)
00735 {
00736 if(playable_tracks->is_playable(current_track, current_position, 1))
00737 {
00738 playable_track = current_track;
00739 total_playable_tracks++;
00740 }
00741 }
00742 }
00743
00744
00745 if(total_playable_tracks != 1) result = 0;
00746
00747
00748
00749 if(result)
00750 {
00751
00752 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
00753
00754 if(!playable_edit)
00755 result = 0;
00756 }
00757
00758
00759
00760 if(result)
00761 {
00762
00763 if(!file->can_copy_from(playable_edit,
00764 current_position + playable_track->nudge,
00765 edl->session->output_w,
00766 edl->session->output_h))
00767 result = 0;
00768 }
00769
00770
00771
00772 if(result &&
00773 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
00774 result = 0;
00775
00776
00777 return result;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 int PackageRenderer::get_master()
00789 {
00790 return 0;
00791 }
00792
00793
00794 int PackageRenderer::get_result()
00795 {
00796 return 0;
00797 }
00798
00799 void PackageRenderer::set_result(int value)
00800 {
00801 }
00802
00803 void PackageRenderer::set_progress(int64_t value)
00804 {
00805 }
00806
00807 int PackageRenderer::set_video_map(int64_t position, int value)
00808 {
00809 }
00810
00811 int PackageRenderer::progress_cancelled()
00812 {
00813 return 0;
00814 }
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824