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()
83 // PackageRenderer::initialize happens only once for every node when doing rendering session
84 // This is not called for each package!
86 int PackageRenderer::initialize(MWindow *mwindow,
88 Preferences *preferences,
90 ArrayList<PluginServer*> *plugindb)
94 this->mwindow = mwindow;
96 this->preferences = preferences;
97 this->default_asset = default_asset;
98 this->plugindb = plugindb;
101 //printf("PackageRenderer::initialize %d\n", preferences->processors);
102 command = new TransportCommand;
103 command->command = NORMAL_FWD;
104 command->get_edl()->copy_all(edl);
105 command->change_type = CHANGE_ALL;
106 command->set_playback_range(edl);
108 default_asset->frame_rate = command->get_edl()->session->frame_rate;
109 default_asset->sample_rate = command->get_edl()->session->sample_rate;
110 default_asset->aspect_ratio = (double)command->get_edl()->session->aspect_w /
111 command->get_edl()->session->aspect_h;
112 result = Render::check_asset(edl, *default_asset);
114 audio_cache = new CICache(preferences, plugindb);
115 video_cache = new CICache(preferences, plugindb);
117 PlaybackConfig *config = command->get_edl()->session->playback_config;
118 aconfig = new AudioOutConfig(0);
119 vconfig = new VideoOutConfig;
124 void PackageRenderer::create_output()
127 asset = new Asset(*default_asset);
133 strcpy(asset->path, package->path);
140 file->set_processors(preferences->processors);
142 result = file->open_file(preferences,
146 command->get_edl()->session->sample_rate,
147 command->get_edl()->session->frame_rate);
148 //printf("PackageRenderer::create_output 10 %d\n", result);
150 if(result && mwindow)
153 char string[BCTEXTLEN];
154 sprintf(string, _("Couldn't open %s"), asset->path);
155 ErrorBox error(PROGRAM_NAME ": Error",
156 mwindow->gui->get_abs_cursor_x(1),
157 mwindow->gui->get_abs_cursor_y(1));
158 error.create_objects(string);
164 mwindow->sighandler->push_file(file);
165 IndexFile::delete_index(preferences, asset);
167 //printf("PackageRenderer::create_output 100 %d\n", result);
170 void PackageRenderer::create_engine()
172 int current_achannel = 0, current_vchannel = 0;
173 audio_read_length = command->get_edl()->session->sample_rate;
175 aconfig->fragment_size = audio_read_length;
178 render_engine = new RenderEngine(0,
184 render_engine->set_acache(audio_cache);
185 render_engine->set_vcache(video_cache);
186 render_engine->arm_command(command, current_achannel, current_vchannel);
188 if(package->use_brender)
190 audio_preroll = Units::to_int64((double)preferences->brender_preroll /
191 default_asset->frame_rate *
192 default_asset->sample_rate);
193 video_preroll = preferences->brender_preroll;
197 audio_preroll = Units::to_int64(preferences->render_preroll *
198 default_asset->sample_rate);
199 video_preroll = Units::to_int64(preferences->render_preroll *
200 default_asset->frame_rate);
202 audio_position = package->audio_start - audio_preroll;
203 video_position = package->video_start - video_preroll;
208 // Create output buffers
209 if(asset->audio_data)
211 file->start_audio_thread(audio_read_length,
212 preferences->processors > 1 ? 2 : 1);
216 if(asset->video_data)
218 compressed_output = new VFrame;
219 // The write length needs to correlate with the processor count because
220 // it is passed to the file handler which usually processes frames simultaneously.
221 video_write_length = preferences->processors;
222 video_write_position = 0;
223 direct_frame_copying = 0;
226 //printf("PackageRenderer::create_engine 1\n");
227 file->start_video_thread(video_write_length,
228 command->get_edl()->session->color_model,
229 preferences->processors > 1 ? 2 : 1,
235 video_device = new VideoDevice;
236 video_device->open_output(vconfig,
237 command->get_edl()->session->frame_rate,
238 command->get_edl()->session->output_w,
239 command->get_edl()->session->output_h,
240 mwindow->cwindow->gui->canvas,
242 video_device->start_playback();
247 playable_tracks = new PlayableTracks(render_engine,
257 void PackageRenderer::do_audio()
259 //printf("PackageRenderer::do_audio 1\n");
261 if(asset->audio_data)
263 audio_output = file->get_audio_buffer();
264 // Zero unused channels in output vector
265 for(int i = 0; i < MAX_CHANNELS; i++)
266 audio_output_ptr[i] = (i < asset->channels) ?
273 // Call render engine
274 result = render_engine->arender->process_buffer(audio_output_ptr,
279 //printf("PackageRenderer::do_audio 3\n");
282 // Fix buffers for preroll
283 int64_t output_length = audio_read_length;
284 if(audio_preroll > 0)
286 if(audio_preroll >= output_length)
290 output_length -= audio_preroll;
291 for(int i = 0; i < MAX_CHANNELS; i++)
293 if(audio_output_ptr[i])
294 for(int j = 0; j < output_length; j++)
296 audio_output_ptr[i][j] = audio_output_ptr[i][j + audio_read_length - output_length];
300 //printf("PackageRenderer::do_audio 4\n");
302 audio_preroll -= audio_read_length;
305 // Must perform writes even if 0 length so get_audio_buffer doesn't block
306 result |= file->write_audio_buffer(output_length);
309 audio_position += audio_read_length;
310 //printf("PackageRenderer::do_audio 5\n");
314 void PackageRenderer::do_video()
317 if(asset->video_data)
319 // get the absolute video position from the audio position
320 int64_t video_end = video_position + video_read_length;
322 if(video_end > package->video_end)
323 video_end = package->video_end;
325 while(video_position < video_end && !result)
327 // Try to copy the compressed frame directly from the input to output files
328 //printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position);
329 if(direct_frame_copy(command->get_edl(),
334 // Direct frame copy failed.
335 // Switch back to background compression
336 if(direct_frame_copying)
338 file->start_video_thread(video_write_length,
339 command->get_edl()->session->color_model,
340 preferences->processors > 1 ? 2 : 1,
342 direct_frame_copying = 0;
345 // Try to use the rendering engine to write the frame.
346 // Get a buffer for background writing.
350 if(video_write_position == 0)
351 video_output = file->get_video_buffer();
357 // Construct layered output buffer
358 video_output_ptr = video_output[0][video_write_position];
361 result = render_engine->vrender->process_buffer(
370 video_device->output_visible())
372 // Vector for video device
373 VFrame *preview_output;
375 video_device->new_output_buffer(&preview_output,
376 command->get_edl()->session->color_model);
378 preview_output->copy_from(video_output_ptr);
379 video_device->write_buffer(preview_output,
385 // Don't write to file
386 if(video_preroll && !result)
389 // Keep the write position at 0 until ready to write real frames
390 result = file->write_video_buffer(0);
391 video_write_position = 0;
396 // Set background rendering parameters
397 // Allow us to skip sections of the output file by setting the frame number.
398 // Used by background render and render farm.
399 video_output_ptr->set_number(video_position);
400 video_write_position++;
402 if(video_write_position >= video_write_length)
404 //printf("PackageRenderer::do_video 9\n");
405 result = file->write_video_buffer(video_write_position);
406 // Update the brender map after writing the files.
407 if(package->use_brender)
409 //printf("PackageRenderer::do_video 10\n");
410 for(int i = 0; i < video_write_position && !result; i++)
412 result = set_video_map(video_position + 1 - video_write_position + i,
415 //printf("PackageRenderer::do_video 11 %d\n", result);
417 video_write_position = 0;
425 if(!result && get_result()) result = 1;
426 if(!result && progress_cancelled()) result = 1;
431 video_position += video_read_length;
436 void PackageRenderer::stop_engine()
438 delete render_engine;
439 delete playable_tracks;
443 void PackageRenderer::stop_output()
446 if(asset->audio_data)
449 file->stop_audio_thread();
452 if(asset->video_data)
454 delete compressed_output;
455 if(video_write_position)
456 file->write_video_buffer(video_write_position);
457 if(package->use_brender)
459 for(int i = 0; i < video_write_position && !error; i++)
461 error = set_video_map(video_position - video_write_position + i,
465 video_write_position = 0;
466 if(!error) file->stop_video_thread();
469 video_device->stop_playback();
470 video_device->close_all();
477 void PackageRenderer::close_output()
480 mwindow->sighandler->pull_file(file);
483 Garbage::delete_object(asset);
486 // Aborts and returns 1 if an error is encountered.
487 int PackageRenderer::render_package(RenderPackage *package)
491 int samples_rendered = 0;
495 this->package = package;
498 // "PackageRenderer::render_package: audio s=%lld l=%lld video s=%lld l=%lld\n",
499 // package->audio_start,
500 // package->audio_end - package->audio_start,
501 // package->video_start,
502 // package->video_end - package->video_start);
505 // FIXME: The design that we only get EDL once does not give us neccessary flexiblity to do things the way they should be donek
506 default_asset->video_data = package->video_do;
507 default_asset->audio_data = package->audio_do;
508 Render::check_asset(edl, *default_asset);
512 if(!asset->video_data) video_done = 1;
513 if(!asset->audio_data) audio_done = 1;
515 // Create render engine
520 //printf("PackageRenderer::render_package 5 %d\n", result);
523 while((!audio_done || !video_done) && !result)
525 int need_audio = 0, need_video = 0;
530 // Calculate lengths to process. Audio fragment is constant.
533 if(audio_position + audio_read_length >= package->audio_end)
536 audio_read_length = package->audio_end - audio_position;
539 samples_rendered = audio_read_length;
543 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
549 video_read_length = package->video_end - video_position;
550 // Packetize video length so progress gets updated
551 video_read_length = (int)MIN(asset->frame_rate, video_read_length);
552 video_read_length = MAX(video_read_length, 30);
555 // Guide video with audio
557 video_read_length = Units::to_int64(
558 (double)(audio_position + audio_read_length) /
565 if(video_position + video_read_length >= package->video_end)
568 video_read_length = package->video_end - video_position;
571 // Calculate samples rendered for progress bar.
573 samples_rendered = Units::round((double)video_read_length /
580 //printf("PackageRenderer::render_package 1 %d %lld %lld\n", result, audio_read_length, video_read_length);
581 if(need_video && !result) do_video();
582 //printf("PackageRenderer::render_package 7 %d %d\n", result, samples_rendered);
583 if(need_audio && !result) do_audio();
586 if(!result) set_progress(samples_rendered);
592 if(!result && progress_cancelled()) result = 1;
594 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
595 // audio_read_length, video_read_length, samples_rendered, result);
599 result = get_result();
602 //printf("PackageRenderer::render_package 20\n");
604 //printf("PackageRenderer::render_package 30\n");
607 //printf("PackageRenderer::render_package 40\n");
614 //printf("PackageRenderer::render_package 50\n");
616 //printf("PackageRenderer::render_package 60\n");
620 //printf("PackageRenderer::render_package 70\n");
634 // Try to copy the compressed frame directly from the input to output files
635 // Return 1 on failure and 0 on success
636 int PackageRenderer::direct_frame_copy(EDL *edl,
637 int64_t &video_position,
641 Track *playable_track;
645 //printf("Render::direct_frame_copy 1\n");
646 if(direct_copy_possible(edl,
652 // Switch to direct copying
653 if(!direct_frame_copying)
655 if(video_write_position)
657 error |= file->write_video_buffer(video_write_position);
658 video_write_position = 0;
660 file->stop_video_thread();
661 direct_frame_copying = 1;
663 //printf("Render::direct_frame_copy 2\n");
665 if(!package->use_brender)
666 error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
675 if(!error && video_preroll > 0)
682 if(package->use_brender)
684 //printf("PackageRenderer::direct_frame_copy 1\n");
685 error = set_video_map(video_position, BRender::SCANNED);
686 //printf("PackageRenderer::direct_frame_copy 10 %d\n", error);
690 VFrame ***temp_output = new VFrame**[1];
691 temp_output[0] = new VFrame*[1];
692 temp_output[0][0] = compressed_output;
693 error = file->write_frames(temp_output, 1);
694 delete [] temp_output[0];
704 int PackageRenderer::direct_copy_possible(EDL *edl,
705 int64_t current_position,
706 Track* playable_track, // The one track which is playable
707 Edit* &playable_edit, // The edit which is playing
708 File *file) // Output file
711 int total_playable_tracks = 0;
712 Track* current_track;
713 Patch* current_patch;
717 // Number of playable tracks must equal 1
718 for(current_track = edl->tracks->first;
719 current_track && result;
720 current_track = current_track->next)
722 if(current_track->data_type == TRACK_VIDEO)
724 if(playable_tracks->is_playable(current_track, current_position, 1))
726 playable_track = current_track;
727 total_playable_tracks++;
732 //printf("Render::direct_copy_possible 1 %d\n", result);
733 if(total_playable_tracks != 1) result = 0;
734 //printf("Render::direct_copy_possible 2 %d\n", result);
736 // Edit must have a source file
739 //printf("Render::direct_copy_possible 3 %d\n", result);
740 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
741 //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit);
746 // Source file must be able to copy to destination file.
747 // Source file must be same size as project output.
750 //printf("Render::direct_copy_possible 5 %d\n", result);
751 if(!file->can_copy_from(playable_edit,
752 current_position + playable_track->nudge,
753 edl->session->output_w,
754 edl->session->output_h))
757 //printf("Render::direct_copy_possible 6 %d\n", result);
759 // Test conditions mutual between vrender.C and this.
761 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
763 //printf("Render::direct_copy_possible 7 %d\n", result);
776 int PackageRenderer::get_master()
781 // Get result status from server
782 int PackageRenderer::get_result()
787 void PackageRenderer::set_result(int value)
791 void PackageRenderer::set_progress(int64_t value)
795 int PackageRenderer::set_video_map(int64_t position, int value)
799 int PackageRenderer::progress_cancelled()