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(preferences,
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] :
372 result = render_engine->vrender->process_buffer(
381 video_device->output_visible())
383 // Vector for video device
384 VFrame *preview_output[MAX_CHANNELS];
386 video_device->new_output_buffers(preview_output,
387 command->get_edl()->session->color_model);
389 for(int i = 0; i < MAX_CHANNELS; i++)
390 if(preview_output[i])
391 preview_output[i]->copy_from(video_output_ptr[i]);
392 video_device->write_buffer(preview_output,
398 // Don't write to file
399 if(video_preroll && !result)
402 // Keep the write position at 0 until ready to write real frames
403 result = file->write_video_buffer(0);
404 video_write_position = 0;
409 //printf("PackageRenderer::do_video 7\n");
410 // Set background rendering parameters
411 // if(package->use_brender)
413 // Allow us to skip sections of the output file by setting the frame number.
414 // Used by background render and render farm.
415 video_output_ptr[0]->set_number(video_position);
416 //printf("PackageRenderer::do_video 8 %p %lld\n", video_output_ptr[0], video_position);
418 video_write_position++;
420 if(video_write_position >= video_write_length)
422 //printf("PackageRenderer::do_video 9\n");
423 result = file->write_video_buffer(video_write_position);
424 // Update the brender map after writing the files.
425 if(package->use_brender)
427 //printf("PackageRenderer::do_video 10\n");
428 for(int i = 0; i < video_write_position && !result; i++)
430 result = set_video_map(video_position + 1 - video_write_position + i,
433 //printf("PackageRenderer::do_video 11 %d\n", result);
435 video_write_position = 0;
443 if(!result && get_result()) result = 1;
444 if(!result && progress_cancelled()) result = 1;
449 video_position += video_read_length;
454 void PackageRenderer::stop_engine()
456 delete render_engine;
457 delete playable_tracks;
461 void PackageRenderer::stop_output()
464 if(asset->audio_data)
467 file->stop_audio_thread();
470 if(asset->video_data)
472 delete compressed_output;
473 if(video_write_position)
474 file->write_video_buffer(video_write_position);
475 if(package->use_brender)
477 for(int i = 0; i < video_write_position && !error; i++)
479 error = set_video_map(video_position - video_write_position + i,
483 video_write_position = 0;
484 if(!error) file->stop_video_thread();
487 video_device->stop_playback();
488 video_device->close_all();
495 void PackageRenderer::close_output()
498 mwindow->sighandler->pull_file(file);
504 // Aborts and returns 1 if an error is encountered.
505 int PackageRenderer::render_package(RenderPackage *package)
509 int samples_rendered = 0;
513 this->package = package;
516 // "PackageRenderer::render_package: audio s=%lld l=%lld video s=%lld l=%lld\n",
517 // package->audio_start,
518 // package->audio_end - package->audio_start,
519 // package->video_start,
520 // package->video_end - package->video_start);
525 if(!asset->video_data) video_done = 1;
526 if(!asset->audio_data) audio_done = 1;
528 // Create render engine
533 //printf("PackageRenderer::render_package 5 %d\n", result);
536 while((!audio_done || !video_done) && !result)
538 int need_audio = 0, need_video = 0;
543 // Calculate lengths to process. Audio fragment is constant.
546 if(audio_position + audio_read_length >= package->audio_end)
549 audio_read_length = package->audio_end - audio_position;
552 samples_rendered = audio_read_length;
556 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
562 video_read_length = package->video_end - video_position;
563 // Packetize video length so progress gets updated
564 video_read_length = (int)MIN(asset->frame_rate, video_read_length);
565 video_read_length = MAX(video_read_length, 30);
568 // Guide video with audio
570 video_read_length = Units::to_int64(
571 (double)(audio_position + audio_read_length) /
578 if(video_position + video_read_length >= package->video_end)
581 video_read_length = package->video_end - video_position;
584 // Calculate samples rendered for progress bar.
586 samples_rendered = Units::round((double)video_read_length /
593 //printf("PackageRenderer::render_package 1 %d %lld %lld\n", result, audio_read_length, video_read_length);
594 if(need_video && !result) do_video();
595 //printf("PackageRenderer::render_package 7 %d %d\n", result, samples_rendered);
596 if(need_audio && !result) do_audio();
599 if(!result) set_progress(samples_rendered);
605 if(!result && progress_cancelled()) result = 1;
607 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
608 // audio_read_length, video_read_length, samples_rendered, result);
612 result = get_result();
615 //printf("PackageRenderer::render_package 20\n");
617 //printf("PackageRenderer::render_package 30\n");
620 //printf("PackageRenderer::render_package 40\n");
627 //printf("PackageRenderer::render_package 50\n");
629 //printf("PackageRenderer::render_package 60\n");
633 //printf("PackageRenderer::render_package 70\n");
647 // Try to copy the compressed frame directly from the input to output files
648 // Return 1 on failure and 0 on success
649 int PackageRenderer::direct_frame_copy(EDL *edl,
650 int64_t &video_position,
654 Track *playable_track;
658 //printf("Render::direct_frame_copy 1\n");
659 if(direct_copy_possible(edl,
665 // Switch to direct copying
666 if(!direct_frame_copying)
668 if(video_write_position)
670 error |= file->write_video_buffer(video_write_position);
671 video_write_position = 0;
673 file->stop_video_thread();
674 direct_frame_copying = 1;
676 //printf("Render::direct_frame_copy 2\n");
678 if(!package->use_brender)
679 error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
687 if(!error && video_preroll > 0)
694 if(package->use_brender)
696 //printf("PackageRenderer::direct_frame_copy 1\n");
697 error = set_video_map(video_position, BRender::SCANNED);
698 //printf("PackageRenderer::direct_frame_copy 10 %d\n", error);
702 VFrame ***temp_output = new VFrame**[1];
703 temp_output[0] = new VFrame*[1];
704 temp_output[0][0] = compressed_output;
705 error = file->write_frames(temp_output, 1);
706 delete temp_output[0];
716 int PackageRenderer::direct_copy_possible(EDL *edl,
717 int64_t current_position,
718 Track* playable_track, // The one track which is playable
719 Edit* &playable_edit, // The edit which is playing
720 File *file) // Output file
723 int total_playable_tracks = 0;
724 Track* current_track;
725 Patch* current_patch;
729 // Number of playable tracks must equal 1
730 for(current_track = edl->tracks->first;
731 current_track && result;
732 current_track = current_track->next)
734 if(current_track->data_type == TRACK_VIDEO)
736 if(playable_tracks->is_playable(current_track, current_position, 1))
738 playable_track = current_track;
739 total_playable_tracks++;
744 //printf("Render::direct_copy_possible 1 %d\n", result);
745 if(total_playable_tracks != 1) result = 0;
746 //printf("Render::direct_copy_possible 2 %d\n", result);
748 // Edit must have a source file
751 //printf("Render::direct_copy_possible 3 %d\n", result);
752 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
753 //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit);
758 // Source file must be able to copy to destination file.
759 // Source file must be same size as project output.
762 //printf("Render::direct_copy_possible 5 %d\n", result);
763 if(!file->can_copy_from(playable_edit,
764 current_position + playable_track->nudge,
765 edl->session->output_w,
766 edl->session->output_h))
769 //printf("Render::direct_copy_possible 6 %d\n", result);
771 // Test conditions mutual between vrender.C and this.
773 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
775 //printf("Render::direct_copy_possible 7 %d\n", result);
788 int PackageRenderer::get_master()
793 // Get result status from server
794 int PackageRenderer::get_result()
799 void PackageRenderer::set_result(int value)
803 void PackageRenderer::set_progress(int64_t value)
807 int PackageRenderer::set_video_map(int64_t position, int value)
811 int PackageRenderer::progress_cancelled()