8 #include "cwindowgui.h"
12 #include "edlsession.h"
15 #include "filesystem.h"
16 #include "indexfile.h"
19 #include "mwindowgui.h"
20 #include "packagerenderer.h"
21 #include "playabletracks.h"
22 #include "playbackconfig.h"
23 #include "pluginserver.h"
24 #include "preferences.h"
26 #include "renderengine.h"
27 #include "renderfarmfsserver.h"
28 #include "sighandler.h"
30 #include "transportque.h"
33 #include "videodevice.h"
42 RenderPackage::RenderPackage()
53 RenderPackage::~RenderPackage()
64 // Used by RenderFarm and in the future, Render, to do packages.
65 PackageRenderer::PackageRenderer()
74 PackageRenderer::~PackageRenderer()
82 int PackageRenderer::initialize(MWindow *mwindow,
84 Preferences *preferences,
86 ArrayList<PluginServer*> *plugindb)
90 this->mwindow = mwindow;
92 this->preferences = preferences;
93 this->default_asset = default_asset;
94 this->plugindb = plugindb;
97 //printf("PackageRenderer::initialize %d\n", preferences->processors);
98 command = new TransportCommand;
99 command->command = NORMAL_FWD;
100 command->get_edl()->copy_all(edl);
101 command->change_type = CHANGE_ALL;
102 command->set_playback_range(edl);
104 default_asset->frame_rate = command->get_edl()->session->frame_rate;
105 default_asset->sample_rate = command->get_edl()->session->sample_rate;
106 default_asset->aspect_ratio = (double)command->get_edl()->session->aspect_w /
107 command->get_edl()->session->aspect_h;
108 result = Render::check_asset(edl, *default_asset);
110 audio_cache = new CICache(command->get_edl(), preferences, plugindb);
111 video_cache = new CICache(command->get_edl(), preferences, plugindb);
113 PlaybackConfig *config = command->get_edl()->session->playback_config;
114 aconfig = new AudioOutConfig(0);
115 vconfig = new VideoOutConfig;
116 // playback_config = new PlaybackConfig(PLAYBACK_LOCALHOST, 0);
117 for(int i = 0; i < MAX_CHANNELS; i++)
119 vconfig->do_channel[i] = (i < command->get_edl()->session->video_channels);
126 void PackageRenderer::create_output()
129 asset = new Asset(*default_asset);
135 // Tag output paths for VFS here.
136 // if(!mwindow && preferences->renderfarm_vfs && preferences->use_renderfarm)
137 if(!get_master() && preferences->renderfarm_vfs && preferences->use_renderfarm)
138 sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", package->path);
140 strcpy(asset->path, package->path);
147 file->set_processors(preferences->processors);
149 result = file->open_file(plugindb,
153 command->get_edl()->session->sample_rate,
154 command->get_edl()->session->frame_rate);
155 //printf("PackageRenderer::create_output 10 %d\n", result);
157 if(result && mwindow)
160 char string[BCTEXTLEN];
161 sprintf(string, _("Couldn't open %s"), asset->path);
162 ErrorBox error(PROGRAM_NAME ": Error",
163 mwindow->gui->get_abs_cursor_x(1),
164 mwindow->gui->get_abs_cursor_y(1));
165 error.create_objects(string);
171 mwindow->sighandler->push_file(file);
172 IndexFile::delete_index(preferences, asset);
174 //printf("PackageRenderer::create_output 100 %d\n", result);
177 void PackageRenderer::create_engine()
179 int current_achannel = 0, current_vchannel = 0;
180 audio_read_length = command->get_edl()->session->sample_rate;
182 aconfig->fragment_size = audio_read_length;
185 render_engine = new RenderEngine(0,
191 render_engine->set_acache(audio_cache);
192 render_engine->set_vcache(video_cache);
193 render_engine->arm_command(command, current_achannel, current_vchannel);
195 if(package->use_brender)
197 audio_preroll = Units::to_int64((double)preferences->brender_preroll /
198 default_asset->frame_rate *
199 default_asset->sample_rate);
200 video_preroll = preferences->brender_preroll;
204 audio_preroll = Units::to_int64(preferences->render_preroll *
205 default_asset->sample_rate);
206 video_preroll = Units::to_int64(preferences->render_preroll *
207 default_asset->frame_rate);
209 audio_position = package->audio_start - audio_preroll;
210 video_position = package->video_start - video_preroll;
215 // Create output buffers
216 if(asset->audio_data)
218 file->start_audio_thread(audio_read_length,
219 preferences->processors > 1 ? 2 : 1);
223 if(asset->video_data)
225 compressed_output = new VFrame;
226 // The write length needs to correlate with the processor count because
227 // it is passed to the file handler which usually processes frames simultaneously.
228 video_write_length = preferences->processors;
229 video_write_position = 0;
230 direct_frame_copying = 0;
233 //printf("PackageRenderer::create_engine 1\n");
234 file->start_video_thread(video_write_length,
235 command->get_edl()->session->color_model,
236 preferences->processors > 1 ? 2 : 1,
242 video_device = new VideoDevice;
243 video_device->open_output(vconfig,
244 command->get_edl()->session->frame_rate,
245 command->get_edl()->session->output_w,
246 command->get_edl()->session->output_h,
247 mwindow->cwindow->gui->canvas,
249 video_device->start_playback();
254 playable_tracks = new PlayableTracks(render_engine,
264 void PackageRenderer::do_audio()
266 //printf("PackageRenderer::do_audio 1\n");
268 if(asset->audio_data)
270 audio_output = file->get_audio_buffer();
271 // Zero unused channels in output vector
272 for(int i = 0; i < MAX_CHANNELS; i++)
273 audio_output_ptr[i] = (i < asset->channels) ?
280 // Call render engine
281 result = render_engine->arender->process_buffer(audio_output_ptr,
286 //printf("PackageRenderer::do_audio 3\n");
289 // Fix buffers for preroll
290 int64_t output_length = audio_read_length;
291 if(audio_preroll > 0)
293 if(audio_preroll >= output_length)
297 output_length -= audio_preroll;
298 for(int i = 0; i < MAX_CHANNELS; i++)
300 if(audio_output_ptr[i])
301 for(int j = 0; j < output_length; j++)
303 audio_output_ptr[i][j] = audio_output_ptr[i][j + audio_read_length - output_length];
307 //printf("PackageRenderer::do_audio 4\n");
309 audio_preroll -= audio_read_length;
312 // Must perform writes even if 0 length so get_audio_buffer doesn't block
313 result |= file->write_audio_buffer(output_length);
316 audio_position += audio_read_length;
317 //printf("PackageRenderer::do_audio 5\n");
321 void PackageRenderer::do_video()
324 if(asset->video_data)
326 // get the absolute video position from the audio position
327 int64_t video_end = video_position + video_read_length;
329 if(video_end > package->video_end)
330 video_end = package->video_end;
332 while(video_position < video_end && !result)
334 // Try to copy the compressed frame directly from the input to output files
335 //printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position);
336 if(direct_frame_copy(command->get_edl(),
341 // Direct frame copy failed.
342 // Switch back to background compression
343 if(direct_frame_copying)
345 file->start_video_thread(video_write_length,
346 command->get_edl()->session->color_model,
347 preferences->processors > 1 ? 2 : 1,
349 direct_frame_copying = 0;
352 // Try to use the rendering engine to write the frame.
353 // Get a buffer for background writing.
357 if(video_write_position == 0)
358 video_output = file->get_video_buffer();
364 // Construct layered output buffer
365 for(int i = 0; i < MAX_CHANNELS; i++)
366 video_output_ptr[i] =
367 (i < asset->layers) ?
368 video_output[i][video_write_position] :
370 result |= render_engine->vrender->process_buffer(
377 if(mwindow && video_device->output_visible())
379 // Vector for video device
380 VFrame *preview_output[MAX_CHANNELS];
382 video_device->new_output_buffers(preview_output,
383 command->get_edl()->session->color_model);
385 for(int i = 0; i < MAX_CHANNELS; i++)
386 if(preview_output[i])
387 preview_output[i]->copy_from(video_output_ptr[i]);
388 video_device->write_buffer(preview_output,
393 //printf("PackageRenderer::do_video 6\n");
398 //printf("PackageRenderer::do_video 6.1\n");
400 // Keep the write position at 0 until ready to write real frames
401 result |= file->write_video_buffer(0);
402 //printf("PackageRenderer::do_video 6.2\n");
403 video_write_position = 0;
407 //printf("PackageRenderer::do_video 7\n");
408 // Set background rendering parameters
409 // if(package->use_brender)
411 // Allow us to skip sections of the output file by setting the frame number.
412 // Used by background render and render farm.
413 video_output_ptr[0]->set_number(video_position);
414 //printf("PackageRenderer::do_video 8 %p %lld\n", video_output_ptr[0], video_position);
416 video_write_position++;
418 if(video_write_position >= video_write_length)
420 //printf("PackageRenderer::do_video 9\n");
421 result |= file->write_video_buffer(video_write_position);
422 //printf("PackageRenderer::do_video 10\n");
423 // Update the brender map after writing the files.
424 if(package->use_brender)
425 for(int i = 0; i < video_write_position; i++)
426 set_video_map(video_position + 1 - video_write_position + i,
428 video_write_position = 0;
430 //printf("PackageRenderer::do_video 11\n");
437 if(get_result()) result = 1;
438 if(!result && progress_cancelled()) result = 1;
443 video_position += video_read_length;
445 //printf("PackageRenderer::do_video 14 %d %d\n", video_position, result);
449 void PackageRenderer::stop_engine()
451 delete render_engine;
452 delete playable_tracks;
456 void PackageRenderer::stop_output()
458 if(asset->audio_data)
461 file->stop_audio_thread();
464 if(asset->video_data)
466 delete compressed_output;
467 if(video_write_position)
468 file->write_video_buffer(video_write_position);
469 if(package->use_brender)
470 for(int i = 0; i < video_write_position; i++)
471 set_video_map(video_position - video_write_position + i,
473 video_write_position = 0;
474 file->stop_video_thread();
477 video_device->stop_playback();
478 video_device->close_all();
485 void PackageRenderer::close_output()
488 mwindow->sighandler->pull_file(file);
494 // Aborts and returns 1 if an error is encountered.
495 int PackageRenderer::render_package(RenderPackage *package)
499 int samples_rendered = 0;
503 this->package = package;
506 // "PackageRenderer::render_package: audio s=%lld l=%lld video s=%lld l=%lld\n",
507 // package->audio_start,
508 // package->audio_end - package->audio_start,
509 // package->video_start,
510 // package->video_end - package->video_start);
515 if(!asset->video_data) video_done = 1;
516 if(!asset->audio_data) audio_done = 1;
518 // Create render engine
523 //printf("PackageRenderer::render_package 5 %d\n", result);
526 while((!audio_done || !video_done) && !result)
528 int need_audio = 0, need_video = 0;
533 // Calculate lengths to process. Audio fragment is constant.
536 if(audio_position + audio_read_length >= package->audio_end)
539 audio_read_length = package->audio_end - audio_position;
542 samples_rendered = audio_read_length;
546 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
552 video_read_length = package->video_end - video_position;
553 // Packetize video length so progress gets updated
554 video_read_length = (int)MIN(asset->frame_rate, video_read_length);
555 video_read_length = MAX(video_read_length, 30);
558 // Guide video with audio
560 video_read_length = Units::to_int64(
561 (double)(audio_position + audio_read_length) /
568 if(video_position + video_read_length >= package->video_end)
571 video_read_length = package->video_end - video_position;
574 // Calculate samples rendered for progress bar.
576 samples_rendered = Units::round((double)video_read_length /
583 //printf("PackageRenderer::render_package 1 %d %lld %lld\n", result, audio_read_length, video_read_length);
584 if(need_video && !result) do_video();
585 //printf("PackageRenderer::render_package 7 %d %d\n", result, samples_rendered);
586 if(need_audio && !result) do_audio();
589 if(!result) set_progress(samples_rendered);
595 if(!result && progress_cancelled()) result = 1;
597 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
598 // audio_read_length, video_read_length, samples_rendered, result);
602 result = get_result();
605 //printf("PackageRenderer::render_package 10\n");
607 //printf("PackageRenderer::render_package 11\n");
610 //printf("PackageRenderer::render_package 12\n");
617 //printf("PackageRenderer::render_package 13\n");
619 //printf("PackageRenderer::render_package 14\n");
623 //printf("PackageRenderer::render_package 15\n");
637 // Try to copy the compressed frame directly from the input to output files
638 // Return 1 on failure and 0 on success
639 int PackageRenderer::direct_frame_copy(EDL *edl,
640 int64_t &video_position,
644 Track *playable_track;
649 //printf("Render::direct_frame_copy 1\n");
650 if(direct_copy_possible(edl,
656 // Switch to direct copying
657 if(!direct_frame_copying)
659 if(video_write_position)
661 error |= file->write_video_buffer(video_write_position);
662 video_write_position = 0;
664 file->stop_video_thread();
665 direct_frame_copying = 1;
667 //printf("Render::direct_frame_copy 2\n");
669 if(!package->use_brender)
670 error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
678 if(!error && video_preroll > 0)
685 // Don't background render this one
686 if(package->use_brender)
687 set_video_map(video_position, BRender::SCANNED);
689 if(!package->use_brender)
691 VFrame ***temp_output = new VFrame**[1];
692 temp_output[0] = new VFrame*[1];
693 temp_output[0][0] = compressed_output;
694 error |= file->write_frames(temp_output, 1);
695 delete temp_output[0];
705 int PackageRenderer::direct_copy_possible(EDL *edl,
706 int64_t current_position,
707 Track* playable_track, // The one track which is playable
708 Edit* &playable_edit, // The edit which is playing
709 File *file) // Output file
712 int total_playable_tracks = 0;
713 Track* current_track;
714 Patch* current_patch;
718 // Number of playable tracks must equal 1
719 for(current_track = edl->tracks->first;
720 current_track && result;
721 current_track = current_track->next)
723 if(current_track->data_type == TRACK_VIDEO)
725 if(playable_tracks->is_playable(current_track, current_position, 1))
727 playable_track = current_track;
728 total_playable_tracks++;
733 //printf("Render::direct_copy_possible 1 %d\n", result);
734 if(total_playable_tracks != 1) result = 0;
735 //printf("Render::direct_copy_possible 2 %d\n", result);
737 // Edit must have a source file
740 //printf("Render::direct_copy_possible 3 %d\n", result);
741 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
742 //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit);
747 // Source file must be able to copy to destination file.
748 // Source file must be same size as project output.
751 //printf("Render::direct_copy_possible 5 %d\n", result);
752 if(!file->can_copy_from(playable_edit,
753 current_position + playable_track->nudge,
754 edl->session->output_w,
755 edl->session->output_h))
758 //printf("Render::direct_copy_possible 6 %d\n", result);
760 // Test conditions mutual between vrender.C and this.
762 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
764 //printf("Render::direct_copy_possible 7 %d\n", result);
777 int PackageRenderer::get_master()
782 // Get result status from server
783 int PackageRenderer::get_result()
788 void PackageRenderer::set_result(int value)
792 void PackageRenderer::set_progress(int64_t value)
796 void PackageRenderer::set_video_map(int64_t position, int value)
800 int PackageRenderer::progress_cancelled()