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 // PackageRenderer::initialize happens only once for every node when doing rendering session
83 // This is not called for each package!
85 int PackageRenderer::initialize(MWindow *mwindow,
87 Preferences *preferences,
89 ArrayList<PluginServer*> *plugindb)
93 this->mwindow = mwindow;
95 this->preferences = preferences;
96 this->default_asset = default_asset;
97 this->plugindb = plugindb;
100 //printf("PackageRenderer::initialize %d\n", preferences->processors);
101 command = new TransportCommand;
102 command->command = NORMAL_FWD;
103 command->get_edl()->copy_all(edl);
104 command->change_type = CHANGE_ALL;
105 command->set_playback_range(edl);
107 default_asset->frame_rate = command->get_edl()->session->frame_rate;
108 default_asset->sample_rate = command->get_edl()->session->sample_rate;
109 default_asset->aspect_ratio = (double)command->get_edl()->session->aspect_w /
110 command->get_edl()->session->aspect_h;
111 result = Render::check_asset(edl, *default_asset);
113 audio_cache = new CICache(preferences, plugindb);
114 video_cache = new CICache(preferences, plugindb);
116 PlaybackConfig *config = command->get_edl()->session->playback_config;
117 aconfig = new AudioOutConfig(0);
118 vconfig = new VideoOutConfig;
123 void PackageRenderer::create_output()
126 asset = new Asset(*default_asset);
132 strcpy(asset->path, package->path);
139 file->set_processors(preferences->processors);
141 result = file->open_file(preferences,
145 command->get_edl()->session->sample_rate,
146 command->get_edl()->session->frame_rate);
147 //printf("PackageRenderer::create_output 10 %d\n", result);
149 if(result && mwindow)
152 char string[BCTEXTLEN];
153 sprintf(string, _("Couldn't open %s"), asset->path);
154 ErrorBox error(PROGRAM_NAME ": Error",
155 mwindow->gui->get_abs_cursor_x(1),
156 mwindow->gui->get_abs_cursor_y(1));
157 error.create_objects(string);
163 mwindow->sighandler->push_file(file);
164 IndexFile::delete_index(preferences, asset);
166 //printf("PackageRenderer::create_output 100 %d\n", result);
169 void PackageRenderer::create_engine()
171 int current_achannel = 0, current_vchannel = 0;
172 audio_read_length = command->get_edl()->session->sample_rate;
174 aconfig->fragment_size = audio_read_length;
177 render_engine = new RenderEngine(0,
183 render_engine->set_acache(audio_cache);
184 render_engine->set_vcache(video_cache);
185 render_engine->arm_command(command, current_achannel, current_vchannel);
187 if(package->use_brender)
189 audio_preroll = Units::to_int64((double)preferences->brender_preroll /
190 default_asset->frame_rate *
191 default_asset->sample_rate);
192 video_preroll = preferences->brender_preroll;
196 audio_preroll = Units::to_int64(preferences->render_preroll *
197 default_asset->sample_rate);
198 video_preroll = Units::to_int64(preferences->render_preroll *
199 default_asset->frame_rate);
201 audio_position = package->audio_start - audio_preroll;
202 video_position = package->video_start - video_preroll;
207 // Create output buffers
208 if(asset->audio_data)
210 file->start_audio_thread(audio_read_length,
211 preferences->processors > 1 ? 2 : 1);
215 if(asset->video_data)
217 compressed_output = new VFrame;
218 // The write length needs to correlate with the processor count because
219 // it is passed to the file handler which usually processes frames simultaneously.
220 video_write_length = preferences->processors;
221 video_write_position = 0;
222 direct_frame_copying = 0;
225 //printf("PackageRenderer::create_engine 1\n");
226 file->start_video_thread(video_write_length,
227 command->get_edl()->session->color_model,
228 preferences->processors > 1 ? 2 : 1,
234 video_device = new VideoDevice;
235 video_device->open_output(vconfig,
236 command->get_edl()->session->frame_rate,
237 command->get_edl()->session->output_w,
238 command->get_edl()->session->output_h,
239 mwindow->cwindow->gui->canvas,
241 video_device->start_playback();
246 playable_tracks = new PlayableTracks(render_engine,
256 void PackageRenderer::do_audio()
258 //printf("PackageRenderer::do_audio 1\n");
260 if(asset->audio_data)
262 audio_output = file->get_audio_buffer();
263 // Zero unused channels in output vector
264 for(int i = 0; i < MAX_CHANNELS; i++)
265 audio_output_ptr[i] = (i < asset->channels) ?
272 // Call render engine
273 result = render_engine->arender->process_buffer(audio_output_ptr,
278 //printf("PackageRenderer::do_audio 3\n");
281 // Fix buffers for preroll
282 int64_t output_length = audio_read_length;
283 if(audio_preroll > 0)
285 if(audio_preroll >= output_length)
289 output_length -= audio_preroll;
290 for(int i = 0; i < MAX_CHANNELS; i++)
292 if(audio_output_ptr[i])
293 for(int j = 0; j < output_length; j++)
295 audio_output_ptr[i][j] = audio_output_ptr[i][j + audio_read_length - output_length];
299 //printf("PackageRenderer::do_audio 4\n");
301 audio_preroll -= audio_read_length;
304 // Must perform writes even if 0 length so get_audio_buffer doesn't block
305 result |= file->write_audio_buffer(output_length);
308 audio_position += audio_read_length;
309 //printf("PackageRenderer::do_audio 5\n");
313 void PackageRenderer::do_video()
316 if(asset->video_data)
318 // get the absolute video position from the audio position
319 int64_t video_end = video_position + video_read_length;
321 if(video_end > package->video_end)
322 video_end = package->video_end;
324 while(video_position < video_end && !result)
326 // Try to copy the compressed frame directly from the input to output files
327 //printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position);
328 if(direct_frame_copy(command->get_edl(),
333 // Direct frame copy failed.
334 // Switch back to background compression
335 if(direct_frame_copying)
337 file->start_video_thread(video_write_length,
338 command->get_edl()->session->color_model,
339 preferences->processors > 1 ? 2 : 1,
341 direct_frame_copying = 0;
344 // Try to use the rendering engine to write the frame.
345 // Get a buffer for background writing.
349 if(video_write_position == 0)
350 video_output = file->get_video_buffer();
356 // Construct layered output buffer
357 video_output_ptr = video_output[0][video_write_position];
360 result = render_engine->vrender->process_buffer(
369 video_device->output_visible())
371 // Vector for video device
372 VFrame *preview_output;
374 video_device->new_output_buffer(&preview_output,
375 command->get_edl()->session->color_model);
377 preview_output->copy_from(video_output_ptr);
378 video_device->write_buffer(preview_output,
384 // Don't write to file
385 if(video_preroll && !result)
388 // Keep the write position at 0 until ready to write real frames
389 result = file->write_video_buffer(0);
390 video_write_position = 0;
395 // Set background rendering parameters
396 // Allow us to skip sections of the output file by setting the frame number.
397 // Used by background render and render farm.
398 video_output_ptr->set_number(video_position);
399 video_write_position++;
401 if(video_write_position >= video_write_length)
403 //printf("PackageRenderer::do_video 9\n");
404 result = file->write_video_buffer(video_write_position);
405 // Update the brender map after writing the files.
406 if(package->use_brender)
408 //printf("PackageRenderer::do_video 10\n");
409 for(int i = 0; i < video_write_position && !result; i++)
411 result = set_video_map(video_position + 1 - video_write_position + i,
414 //printf("PackageRenderer::do_video 11 %d\n", result);
416 video_write_position = 0;
424 if(!result && get_result()) result = 1;
425 if(!result && progress_cancelled()) result = 1;
430 video_position += video_read_length;
435 void PackageRenderer::stop_engine()
437 delete render_engine;
438 delete playable_tracks;
442 void PackageRenderer::stop_output()
445 if(asset->audio_data)
448 file->stop_audio_thread();
451 if(asset->video_data)
453 delete compressed_output;
454 if(video_write_position)
455 file->write_video_buffer(video_write_position);
456 if(package->use_brender)
458 for(int i = 0; i < video_write_position && !error; i++)
460 error = set_video_map(video_position - video_write_position + i,
464 video_write_position = 0;
465 if(!error) file->stop_video_thread();
468 video_device->stop_playback();
469 video_device->close_all();
476 void PackageRenderer::close_output()
479 mwindow->sighandler->pull_file(file);
482 Garbage::delete_object(asset);
485 // Aborts and returns 1 if an error is encountered.
486 int PackageRenderer::render_package(RenderPackage *package)
490 int samples_rendered = 0;
494 this->package = package;
497 // "PackageRenderer::render_package: audio s=%lld l=%lld video s=%lld l=%lld\n",
498 // package->audio_start,
499 // package->audio_end - package->audio_start,
500 // package->video_start,
501 // package->video_end - package->video_start);
504 // FIXME: The design that we only get EDL once does not give us neccessary flexiblity to do things the way they should be donek
505 default_asset->video_data = package->video_do;
506 default_asset->audio_data = package->audio_do;
507 Render::check_asset(edl, *default_asset);
511 if(!asset->video_data) video_done = 1;
512 if(!asset->audio_data) audio_done = 1;
514 // Create render engine
519 //printf("PackageRenderer::render_package 5 %d\n", result);
522 while((!audio_done || !video_done) && !result)
524 int need_audio = 0, need_video = 0;
529 // Calculate lengths to process. Audio fragment is constant.
532 if(audio_position + audio_read_length >= package->audio_end)
535 audio_read_length = package->audio_end - audio_position;
538 samples_rendered = audio_read_length;
542 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
548 video_read_length = package->video_end - video_position;
549 // Packetize video length so progress gets updated
550 video_read_length = (int)MIN(asset->frame_rate, video_read_length);
551 video_read_length = MAX(video_read_length, 30);
554 // Guide video with audio
556 video_read_length = Units::to_int64(
557 (double)(audio_position + audio_read_length) /
564 if(video_position + video_read_length >= package->video_end)
567 video_read_length = package->video_end - video_position;
570 // Calculate samples rendered for progress bar.
572 samples_rendered = Units::round((double)video_read_length /
579 //printf("PackageRenderer::render_package 1 %d %lld %lld\n", result, audio_read_length, video_read_length);
580 if(need_video && !result) do_video();
581 //printf("PackageRenderer::render_package 7 %d %d\n", result, samples_rendered);
582 if(need_audio && !result) do_audio();
585 if(!result) set_progress(samples_rendered);
591 if(!result && progress_cancelled()) result = 1;
593 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
594 // audio_read_length, video_read_length, samples_rendered, result);
598 result = get_result();
601 //printf("PackageRenderer::render_package 20\n");
603 //printf("PackageRenderer::render_package 30\n");
606 //printf("PackageRenderer::render_package 40\n");
613 //printf("PackageRenderer::render_package 50\n");
615 //printf("PackageRenderer::render_package 60\n");
619 //printf("PackageRenderer::render_package 70\n");
633 // Try to copy the compressed frame directly from the input to output files
634 // Return 1 on failure and 0 on success
635 int PackageRenderer::direct_frame_copy(EDL *edl,
636 int64_t &video_position,
640 Track *playable_track;
644 //printf("Render::direct_frame_copy 1\n");
645 if(direct_copy_possible(edl,
651 // Switch to direct copying
652 if(!direct_frame_copying)
654 if(video_write_position)
656 error |= file->write_video_buffer(video_write_position);
657 video_write_position = 0;
659 file->stop_video_thread();
660 direct_frame_copying = 1;
662 //printf("Render::direct_frame_copy 2\n");
664 if(!package->use_brender)
665 error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
674 if(!error && video_preroll > 0)
681 if(package->use_brender)
683 //printf("PackageRenderer::direct_frame_copy 1\n");
684 error = set_video_map(video_position, BRender::SCANNED);
685 //printf("PackageRenderer::direct_frame_copy 10 %d\n", error);
689 VFrame ***temp_output = new VFrame**[1];
690 temp_output[0] = new VFrame*[1];
691 temp_output[0][0] = compressed_output;
692 error = file->write_frames(temp_output, 1);
693 delete [] temp_output[0];
703 int PackageRenderer::direct_copy_possible(EDL *edl,
704 int64_t current_position,
705 Track* playable_track, // The one track which is playable
706 Edit* &playable_edit, // The edit which is playing
707 File *file) // Output file
710 int total_playable_tracks = 0;
711 Track* current_track;
712 Patch* current_patch;
716 // Number of playable tracks must equal 1
717 for(current_track = edl->tracks->first;
718 current_track && result;
719 current_track = current_track->next)
721 if(current_track->data_type == TRACK_VIDEO)
723 if(playable_tracks->is_playable(current_track, current_position, 1))
725 playable_track = current_track;
726 total_playable_tracks++;
731 //printf("Render::direct_copy_possible 1 %d\n", result);
732 if(total_playable_tracks != 1) result = 0;
733 //printf("Render::direct_copy_possible 2 %d\n", result);
735 // Edit must have a source file
738 //printf("Render::direct_copy_possible 3 %d\n", result);
739 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
740 //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit);
745 // Source file must be able to copy to destination file.
746 // Source file must be same size as project output.
749 //printf("Render::direct_copy_possible 5 %d\n", result);
750 if(!file->can_copy_from(playable_edit,
751 current_position + playable_track->nudge,
752 edl->session->output_w,
753 edl->session->output_h))
756 //printf("Render::direct_copy_possible 6 %d\n", result);
758 // Test conditions mutual between vrender.C and this.
760 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
762 //printf("Render::direct_copy_possible 7 %d\n", result);
775 int PackageRenderer::get_master()
780 // Get result status from server
781 int PackageRenderer::get_result()
786 void PackageRenderer::set_result(int value)
790 void PackageRenderer::set_progress(int64_t value)
794 int PackageRenderer::set_video_map(int64_t position, int value)
798 int PackageRenderer::progress_cancelled()