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 sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", package->path);
139 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()
323 //printf("PackageRenderer::do_video 1\n");
325 if(asset->video_data)
327 // get the absolute video position from the audio position
328 int64_t video_end = video_position + video_read_length;
330 if(video_end > package->video_end)
331 video_end = package->video_end;
333 //printf("PackageRenderer::do_video 1\n");
334 while(video_position < video_end && !result)
336 // Try to copy the compressed frame directly from the input to output files
337 //printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position);
338 if(direct_frame_copy(command->get_edl(),
343 // Direct frame copy failed.
344 // Switch back to background compression
345 if(direct_frame_copying)
347 file->start_video_thread(video_write_length,
348 command->get_edl()->session->color_model,
349 preferences->processors > 1 ? 2 : 1,
351 direct_frame_copying = 0;
354 // Try to use the rendering engine to write the frame.
355 // Get a buffer for background writing.
358 //printf("PackageRenderer::do_video 3\n");
360 if(video_write_position == 0)
361 video_output = file->get_video_buffer();
365 //printf("PackageRenderer::do_video 4\n");
368 // Construct layered output buffer
369 for(int i = 0; i < MAX_CHANNELS; i++)
370 video_output_ptr[i] =
371 (i < asset->layers) ?
372 video_output[i][video_write_position] :
374 result |= render_engine->vrender->process_buffer(
380 //printf("PackageRenderer::do_video 5\n");
382 if(mwindow && video_device->output_visible())
384 // Vector for video device
385 VFrame *preview_output[MAX_CHANNELS];
387 video_device->new_output_buffers(preview_output,
388 command->get_edl()->session->color_model);
390 for(int i = 0; i < MAX_CHANNELS; i++)
391 if(preview_output[i])
392 preview_output[i]->copy_from(video_output_ptr[i]);
393 video_device->write_buffer(preview_output,
398 //printf("PackageRenderer::do_video 6\n");
403 //printf("PackageRenderer::do_video 6.1\n");
405 // Keep the write position at 0 until ready to write real frames
406 result |= file->write_video_buffer(0);
407 //printf("PackageRenderer::do_video 6.2\n");
408 video_write_position = 0;
412 //printf("PackageRenderer::do_video 7\n");
413 // Set background rendering parameters
414 if(package->use_brender)
416 // Allow us to skip sections of the output file by setting the frame number.
417 video_output_ptr[0]->set_number(video_position);
419 video_write_position++;
420 //printf("PackageRenderer::do_video 8\n");
422 if(video_write_position >= video_write_length)
424 //printf("PackageRenderer::do_video 9\n");
425 result |= file->write_video_buffer(video_write_position);
426 //printf("PackageRenderer::do_video 10\n");
427 // Update the brender map after writing the files.
428 if(package->use_brender)
429 for(int i = 0; i < video_write_position; i++)
430 set_video_map(video_position + 1 - video_write_position + i,
432 video_write_position = 0;
434 //printf("PackageRenderer::do_video 11\n");
441 if(get_result()) result = 1;
442 if(!result && progress_cancelled()) result = 1;
447 video_position += video_read_length;
449 //printf("PackageRenderer::do_video 14 %d %d\n", video_position, result);
453 void PackageRenderer::stop_engine()
455 delete render_engine;
456 delete playable_tracks;
460 void PackageRenderer::stop_output()
462 if(asset->audio_data)
465 file->stop_audio_thread();
468 if(asset->video_data)
470 //printf("PackageRenderer::stop_output 1\n");
471 delete compressed_output;
472 //printf("PackageRenderer::stop_output 2\n");
473 if(video_write_position)
474 file->write_video_buffer(video_write_position);
475 //printf("PackageRenderer::stop_output 3\n");
476 if(package->use_brender)
477 for(int i = 0; i < video_write_position; i++)
478 set_video_map(video_position - video_write_position + i,
480 //printf("PackageRenderer::stop_output 4\n");
481 video_write_position = 0;
482 file->stop_video_thread();
483 //printf("PackageRenderer::stop_output 5\n");
486 video_device->stop_playback();
487 video_device->close_all();
494 void PackageRenderer::close_output()
497 mwindow->sighandler->pull_file(file);
503 // Aborts and returns 1 if an error is encountered.
504 int PackageRenderer::render_package(RenderPackage *package)
508 int samples_rendered = 0;
512 this->package = package;
515 // "PackageRenderer::render_package: audio s=%lld l=%lld video s=%lld l=%lld\n",
516 // package->audio_start,
517 // package->audio_end - package->audio_start,
518 // package->video_start,
519 // package->video_end - package->video_start);
524 if(!asset->video_data) video_done = 1;
525 if(!asset->audio_data) audio_done = 1;
527 // Create render engine
532 //printf("PackageRenderer::render_package 5 %d\n", result);
535 while((!audio_done || !video_done) && !result)
537 int need_audio = 0, need_video = 0;
542 // Calculate lengths to process. Audio fragment is constant.
545 if(audio_position + audio_read_length >= package->audio_end)
548 audio_read_length = package->audio_end - audio_position;
551 samples_rendered = audio_read_length;
555 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
561 video_read_length = package->video_end - video_position;
562 // Packetize video length so progress gets updated
563 video_read_length = (int)MIN(asset->frame_rate, video_read_length);
564 video_read_length = MAX(video_read_length, 30);
567 // Guide video with audio
569 video_read_length = Units::to_int64(
570 (double)(audio_position + audio_read_length) /
577 if(video_position + video_read_length >= package->video_end)
580 video_read_length = package->video_end - video_position;
583 // Calculate samples rendered for progress bar.
585 samples_rendered = Units::round((double)video_read_length /
592 //printf("PackageRenderer::render_package 1 %d %lld %lld\n", result, audio_read_length, video_read_length);
593 if(need_video && !result) do_video();
594 //printf("PackageRenderer::render_package 7 %d %d\n", result, samples_rendered);
595 if(need_audio && !result) do_audio();
598 if(!result) set_progress(samples_rendered);
604 if(!result && progress_cancelled()) result = 1;
606 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
607 // audio_read_length, video_read_length, samples_rendered, result);
611 result = get_result();
614 //printf("PackageRenderer::render_package 10\n");
616 //printf("PackageRenderer::render_package 11\n");
619 //printf("PackageRenderer::render_package 12\n");
626 //printf("PackageRenderer::render_package 13\n");
628 //printf("PackageRenderer::render_package 14\n");
632 //printf("PackageRenderer::render_package 15\n");
646 // Try to copy the compressed frame directly from the input to output files
647 // Return 1 on failure and 0 on success
648 int PackageRenderer::direct_frame_copy(EDL *edl,
649 int64_t &video_position,
653 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 // Don't background render this one
695 if(package->use_brender)
696 set_video_map(video_position, BRender::SCANNED);
698 if(!package->use_brender)
700 VFrame ***temp_output = new VFrame**[1];
701 temp_output[0] = new VFrame*[1];
702 temp_output[0][0] = compressed_output;
703 error |= file->write_frames(temp_output, 1);
704 delete temp_output[0];
714 int PackageRenderer::direct_copy_possible(EDL *edl,
715 int64_t current_position,
716 Track* playable_track, // The one track which is playable
717 Edit* &playable_edit, // The edit which is playing
718 File *file) // Output file
721 int total_playable_tracks = 0;
722 Track* current_track;
723 Patch* current_patch;
727 // Number of playable tracks must equal 1
728 for(current_track = edl->tracks->first;
729 current_track && result;
730 current_track = current_track->next)
732 if(current_track->data_type == TRACK_VIDEO)
734 if(playable_tracks->is_playable(current_track, current_position, 1))
736 playable_track = current_track;
737 total_playable_tracks++;
742 //printf("Render::direct_copy_possible 1 %d\n", result);
743 if(total_playable_tracks != 1) result = 0;
744 //printf("Render::direct_copy_possible 2 %d\n", result);
746 // Edit must have a source file
749 //printf("Render::direct_copy_possible 3 %d\n", result);
750 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
751 //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit);
756 // Source file must be able to copy to destination file.
757 // Source file must be same size as project output.
760 //printf("Render::direct_copy_possible 5 %d\n", result);
761 if(!file->can_copy_from(playable_edit,
762 current_position + playable_track->nudge,
763 edl->session->output_w,
764 edl->session->output_h))
767 //printf("Render::direct_copy_possible 6 %d\n", result);
769 // Test conditions mutual between vrender.C and this.
771 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
773 //printf("Render::direct_copy_possible 7 %d\n", result);
788 // Get result status from server
789 int PackageRenderer::get_result()
794 void PackageRenderer::set_result(int value)
798 void PackageRenderer::set_progress(int64_t value)
802 void PackageRenderer::set_video_map(int64_t position, int value)
806 int PackageRenderer::progress_cancelled()