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