rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[goodguy/history.git] / cinelerra-5.1 / cinelerra / packagerenderer.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "arender.h"
23 #include "asset.h"
24 #include "auto.h"
25 #include "bctimer.h"
26 #include "brender.h"
27 #include "cache.h"
28 #include "clip.h"
29 #include "cwindow.h"
30 #include "cwindowgui.h"
31 #include "edit.h"
32 #include "edits.h"
33 #include "edl.h"
34 #include "edlsession.h"
35 #include "errorbox.h"
36 #include "file.h"
37 #include "filesystem.h"
38 #include "indexfile.h"
39 #include "language.h"
40 #include "mwindow.h"
41 #include "mwindowgui.h"
42 #include "packagerenderer.h"
43 #include "playabletracks.h"
44 #include "playbackconfig.h"
45 #include "pluginserver.h"
46 #include "preferences.h"
47 #include "render.h"
48 #include "renderengine.h"
49 #include "renderfarmfsserver.h"
50 #include "samples.h"
51 #include "sighandler.h"
52 #include "tracks.h"
53 #include "transportque.h"
54 #include "vedit.h"
55 #include "vframe.h"
56 #include "videodevice.h"
57 #include "vrender.h"
58
59
60
61
62
63
64
65 RenderPackage::RenderPackage()
66 {
67         audio_start = 0;
68         audio_end = 0;
69         video_start = 0;
70         video_end = 0;
71         audio_do = 0;
72         video_do = 0;
73         path[0] = 0;
74         done = 0;
75         use_brender = 0;
76 }
77
78 RenderPackage::~RenderPackage()
79 {
80 }
81
82
83
84
85
86
87
88
89 // Used by RenderFarm and in the future, Render, to do packages.
90 PackageRenderer::PackageRenderer()
91 {
92         command = 0;
93         audio_cache = 0;
94         video_cache = 0;
95         aconfig = 0;
96         vconfig = 0;
97         timer = new Timer;
98         frames_per_second = 0;
99 }
100
101 PackageRenderer::~PackageRenderer()
102 {
103         delete command;
104         delete audio_cache;
105         delete video_cache;
106         delete vconfig;
107         delete aconfig;
108 }
109
110 // PackageRenderer::initialize happens only once for every node when doing rendering session
111 // This is not called for each package!
112
113 int PackageRenderer::initialize(MWindow *mwindow,
114                 EDL *edl,
115                 Preferences *preferences,
116                 Asset *default_asset)
117 {
118         int result = 0;
119
120         this->mwindow = mwindow;
121         this->edl = edl;
122         this->preferences = preferences;
123         this->default_asset = default_asset;
124
125
126 //printf("PackageRenderer::initialize %d\n", preferences->processors);
127         command = new TransportCommand;
128         command->command = NORMAL_FWD;
129         command->get_edl()->copy_all(edl);
130         command->change_type = CHANGE_ALL;
131         command->set_playback_range(edl);
132
133         default_asset->frame_rate = command->get_edl()->session->frame_rate;
134         default_asset->sample_rate = command->get_edl()->session->sample_rate;
135         default_asset->aspect_ratio = (double)command->get_edl()->session->aspect_w /
136                 command->get_edl()->session->aspect_h;
137         result = Render::check_asset(edl, *default_asset);
138
139         audio_cache = new CICache(preferences);
140         video_cache = new CICache(preferences);
141
142         //PlaybackConfig *config = command->get_edl()->session->playback_config;
143         aconfig = new AudioOutConfig();
144         vconfig = new VideoOutConfig;
145
146         return result;
147 }
148
149 void PackageRenderer::create_output()
150 {
151         FileSystem fs;
152         asset = new Asset(*default_asset);
153
154         if(!get_master() && preferences->renderfarm_vfs && preferences->use_renderfarm)
155                 sprintf(asset->path, RENDERFARM_FS_PREFIX "%s", package->path);
156         else
157                 strcpy(asset->path, package->path);
158
159         file = new File;
160
161         file->set_processors(preferences->processors);
162
163 //printf("PackageRenderer::create_output %d\n", __LINE__);
164         result = file->open_file(preferences,
165                                         asset,
166                                         0,
167                                         1);
168 //printf("PackageRenderer::create_output %d %d\n", __LINE__, result);
169
170         if(result && mwindow)
171         {
172 // open failed
173                 char string[BCTEXTLEN];
174                 sprintf(string, _("Couldn't open %s"), asset->path);
175                 ErrorBox error(_(PROGRAM_NAME ": Error"),
176                         mwindow->gui->get_abs_cursor_x(1),
177                         mwindow->gui->get_abs_cursor_y(1));
178                 error.create_objects(string);
179                 error.run_window();
180         }
181         else
182         if(mwindow)
183         {
184                 mwindow->sighandler->push_file(file);
185                 IndexFile::delete_index(preferences, asset);
186         }
187 //printf("PackageRenderer::create_output %d %d\n", __LINE__, result);
188 }
189
190 void PackageRenderer::create_engine()
191 {
192 // Fix audio buffers to 1 second
193         audio_read_length = command->get_edl()->session->sample_rate;
194         command->get_edl()->session->playback_config->aconfig->fragment_size = audio_read_length;
195
196         aconfig->fragment_size = audio_read_length;
197
198
199         render_engine = new RenderEngine(0,
200                 preferences,
201                 0,
202                 0,
203                 0);
204         render_engine->set_acache(audio_cache);
205         render_engine->set_vcache(video_cache);
206         render_engine->arm_command(command);
207
208         if(package->use_brender)
209         {
210                 audio_preroll = Units::to_int64((double)preferences->brender_preroll /
211                         default_asset->frame_rate *
212                         default_asset->sample_rate);
213                 video_preroll = preferences->brender_preroll;
214         }
215         else
216         {
217                 audio_preroll = Units::to_int64(preferences->render_preroll *
218                         default_asset->sample_rate);
219                 video_preroll = Units::to_int64(preferences->render_preroll *
220                         default_asset->frame_rate);
221         }
222         audio_position = package->audio_start - audio_preroll;
223         if( audio_position < 0 )
224         {
225                 audio_preroll += audio_position;
226                 audio_position = 0;
227         }
228         video_position = package->video_start - video_preroll;
229         if( video_position < 0 )
230         {
231                 video_preroll += video_position;
232                 video_position = 0;
233         }
234
235
236 //      PRINT_TRACE
237
238 // Create output buffers
239         if(asset->audio_data)
240         {
241                 file->start_audio_thread(audio_read_length,
242                         preferences->processors > 1 ? 2 : 1);
243         }
244
245 //      PRINT_TRACE
246
247         if(asset->video_data)
248         {
249                 compressed_output = new VFrame;
250 // The write length needs to correlate with the processor count because
251 // it is passed to the file handler which usually processes frames simultaneously.
252                 video_write_length = preferences->processors;
253                 video_write_position = 0;
254                 direct_frame_copying = 0;
255
256
257 //printf("PackageRenderer::create_engine %d\n", __LINE__);
258                 file->start_video_thread(video_write_length,
259                         command->get_edl()->session->color_model,
260                         preferences->processors > 1 ? 2 : 1,
261                         0);
262 //printf("PackageRenderer::create_engine %d\n", __LINE__);
263
264
265                 if(mwindow)
266                 {
267                         video_device = new VideoDevice;
268                         video_device->open_output(vconfig,
269                                 command->get_edl()->session->frame_rate,
270                                 command->get_edl()->session->output_w,
271                                 command->get_edl()->session->output_h,
272                                 mwindow->cwindow->gui->canvas,
273                                 0);
274 //                      video_device->start_playback();
275                 }
276         }
277
278
279         playable_tracks = new PlayableTracks(render_engine->get_edl(),
280                 video_position,
281                 PLAY_FORWARD,
282                 TRACK_VIDEO,
283                 1);
284
285 }
286
287
288
289
290 void PackageRenderer::do_audio()
291 {
292 //printf("PackageRenderer::do_audio %d\n", __LINE__);
293 // Do audio data
294         if(asset->audio_data)
295         {
296                 audio_output = file->get_audio_buffer();
297 // Zero unused channels in output vector
298                 for(int i = 0; i < MAX_CHANNELS; i++)
299                 {
300                         audio_output_ptr[i] = (i < asset->channels) ?
301                                 audio_output[i] :
302                                 0;
303                 }
304
305
306
307 // Call render engine
308
309                 result = render_engine->arender->process_buffer(audio_output_ptr,
310                         audio_read_length,
311                         audio_position);
312
313
314
315 // Fix buffers for preroll
316                 int64_t output_length = audio_read_length;
317                 if(audio_preroll > 0)
318                 {
319                         if(audio_preroll >= output_length)
320                                 output_length = 0;
321                         else
322                         {
323                                 output_length -= audio_preroll;
324                                 for(int i = 0; i < MAX_CHANNELS; i++)
325                                 {
326                                         if(audio_output_ptr[i])
327                                         {
328                                                 double *data = audio_output_ptr[i]->get_data();
329                                                 for(int j = 0; j < output_length; j++)
330                                                 {
331                                                         data[j] = data[j + audio_read_length - output_length];
332                                                 }
333                                         }
334                                 }
335                         }
336 //printf("PackageRenderer::do_audio 4\n");
337
338                         audio_preroll -= audio_read_length;
339                 }
340
341 // Must perform writes even if 0 length so get_audio_buffer doesn't block
342                 result |= file->write_audio_buffer(output_length);
343         }
344
345         audio_position += audio_read_length;
346 //printf("PackageRenderer::do_audio %d\n", __LINE__);
347 }
348
349
350 void PackageRenderer::do_video()
351 {
352         const int debug = 0;
353 // Do video data
354         if(asset->video_data)
355         {
356 // get the absolute video position from the audio position
357                 int64_t video_end = video_position + video_read_length;
358
359                 if(video_end > package->video_end)
360                         video_end = package->video_end;
361
362                 while(video_position < video_end && !result)
363                 {
364 // Try to copy the compressed frame directly from the input to output files
365 //printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position);
366                         if(direct_frame_copy(command->get_edl(),
367                                 video_position,
368                                 file,
369                                 result))
370                         {
371 // Direct frame copy failed.
372 // Switch back to background compression
373                                 if(direct_frame_copying)
374                                 {
375
376                                         file->start_video_thread(video_write_length,
377                                                 command->get_edl()->session->color_model,
378                                                 preferences->processors > 1 ? 2 : 1,
379                                                 0);
380 //printf("PackageRenderer::do_video %d %d\n", __LINE__, preferences->processors);
381                                         direct_frame_copying = 0;
382                                 }
383
384 // Try to use the rendering engine to write the frame.
385 // Get a buffer for background writing.
386
387                                 if(video_write_position == 0)
388                                         video_output = file->get_video_buffer();
389
390                                 if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output);
391                                 if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output[0]);
392
393
394
395
396 // Construct layered output buffer
397                                 video_output_ptr = video_output[0][video_write_position];
398                                 if(debug)
399                                 {
400                                         printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output_ptr);
401                                         printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
402                                         video_output_ptr->dump();
403                                 }
404
405                                 if(!result)
406                                         result = render_engine->vrender->process_buffer(
407                                                 video_output_ptr,
408                                                 video_position,
409                                                 0);
410
411
412                                 if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
413
414                                 if(!result &&
415                                         mwindow &&
416                                         video_device->output_visible())
417                                 {
418 // Vector for video device
419                                         VFrame *preview_output;
420
421                                         video_device->new_output_buffer(&preview_output,
422                                                 command->get_edl()->session->color_model);
423
424                                         preview_output->copy_from(video_output_ptr);
425                                         video_device->write_buffer(preview_output,
426                                                 command->get_edl());
427                                 }
428
429                                 if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
430
431
432 // Don't write to file
433                                 if(video_preroll && !result)
434                                 {
435                                         video_preroll--;
436 // Keep the write position at 0 until ready to write real frames
437                                         result = file->write_video_buffer(0);
438                                         video_write_position = 0;
439                                 }
440                                 else
441                                 if(!result)
442                                 {
443 // Set background rendering parameters
444 // Allow us to skip sections of the output file by setting the frame number.
445 // Used by background render and render farm.
446 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
447                                         video_output_ptr->set_number(video_position);
448                                         video_write_position++;
449
450                                         if(video_write_position >= video_write_length)
451                                         {
452                                                 result = file->write_video_buffer(video_write_position);
453 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
454 // Update the brender map after writing the files.
455                                                 if(package->use_brender)
456                                                 {
457 //printf("PackageRenderer::do_video 10\n");
458                                                         for(int i = 0; i < video_write_position && !result; i++)
459                                                         {
460                                                                 result = set_video_map(video_position + 1 - video_write_position + i,
461                                                                         BRender::RENDERED);
462                                                         }
463 //printf("PackageRenderer::do_video 11 %d\n", result);
464                                                 }
465                                                 video_write_position = 0;
466                                         }
467                                 }
468 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
469
470
471                         }
472
473                         video_position++;
474                         if(!result && get_result()) result = 1;
475                         if(!result && progress_cancelled()) result = 1;
476                 }
477         }
478         else
479         {
480                 video_position += video_read_length;
481         }
482 }
483
484
485 void PackageRenderer::stop_engine()
486 {
487         delete render_engine;
488         delete playable_tracks;
489 }
490
491
492 void PackageRenderer::stop_output()
493 {
494         int error = 0;
495         if(asset->audio_data)
496         {
497 // stop file I/O
498                 file->stop_audio_thread();
499         }
500
501         if(asset->video_data)
502         {
503                 delete compressed_output;
504                 if(video_write_position)
505                         file->write_video_buffer(video_write_position);
506                 if(package->use_brender)
507                 {
508                         for(int i = 0; i < video_write_position && !error; i++)
509                         {
510                                 error = set_video_map(video_position - video_write_position + i,
511                                         BRender::RENDERED);
512                         }
513                 }
514                 video_write_position = 0;
515                 if(!error) file->stop_video_thread();
516                 if(mwindow)
517                 {
518 //                      video_device->stop_playback();
519                         video_device->close_all();
520                         delete video_device;
521                 }
522         }
523 }
524
525
526 void PackageRenderer::close_output()
527 {
528         if(mwindow)
529                 mwindow->sighandler->pull_file(file);
530         file->close_file();
531         delete file;
532         asset->Garbage::remove_user();
533 }
534
535 // Aborts and returns 1 if an error is encountered.
536 int PackageRenderer::render_package(RenderPackage *package)
537 {
538         int audio_done = 0;
539         int video_done = 0;
540         int samples_rendered = 0;
541         const int debug = 0;
542
543
544         result = 0;
545         this->package = package;
546
547 // printf(
548 // "PackageRenderer::render_package: audio s=%jd l=%jd video s=%jd l=%jd\n",
549 //      package->audio_start,
550 //      package->audio_end - package->audio_start,
551 //      package->video_start,
552 //      package->video_end - package->video_start);
553
554         if(debug) PRINT_TRACE
555
556         if( package->video_do ) default_asset->video_data = 1;
557         if( package->audio_do ) default_asset->audio_data = 1;
558         Render::check_asset(edl, *default_asset);
559
560 // FIXME: The design that we only get EDL once does not give us neccessary flexiblity to do things the way they should be donek
561         default_asset->video_data = package->video_do;
562         default_asset->audio_data = package->audio_do;
563         Render::check_asset(edl, *default_asset);
564
565         create_output();
566         if(debug) PRINT_TRACE
567
568         if(!asset->video_data) video_done = 1;
569         if(!asset->audio_data) audio_done = 1;
570
571 // Create render engine
572         if(!result)
573         {
574 if(debug) PRINT_TRACE
575                 create_engine();
576 if(debug) PRINT_TRACE
577
578
579 // Main loop
580                 timer->update();
581                 total_samples_rendered = 0;
582                 while((!audio_done || !video_done) && !result)
583                 {
584                         int need_audio = 0, need_video = 0;
585
586
587
588
589 // Calculate lengths to process.  Audio fragment is constant.
590                         if(!audio_done)
591                         {
592                                 if(audio_position + audio_read_length >= package->audio_end)
593                                 {
594                                         audio_done = 1;
595                                         audio_read_length = package->audio_end - audio_position;
596                                 }
597
598                                 samples_rendered = audio_read_length;
599                                 need_audio = 1;
600                         }
601
602 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
603
604                         if(!video_done)
605                         {
606                                 if(audio_done)
607                                 {
608 //                                      video_read_length = package->video_end - video_position;
609 // // Packetize video length so progress gets updated
610 //                                      video_read_length = (int)MIN(asset->frame_rate, video_read_length);
611 //                                      video_read_length = MAX(video_read_length, 30);
612                                         video_read_length = 1;
613                                 }
614                                 else
615 // Guide video with audio
616                                 {
617                                         video_read_length = Units::to_int64(
618                                                 (double)(audio_position + audio_read_length) /
619                                                 asset->sample_rate *
620                                                 asset->frame_rate) -
621                                                 video_position;
622                                 }
623
624 // Clamp length
625                                 if(video_position + video_read_length >= package->video_end)
626                                 {
627                                         video_done = 1;
628                                         video_read_length = package->video_end - video_position;
629                                 }
630
631 // Calculate samples rendered for progress bar.
632                                 if(audio_done)
633                                         samples_rendered = Units::round((double)video_read_length /
634                                                 asset->frame_rate *
635                                                 asset->sample_rate);
636
637                                 need_video = 1;
638                         }
639                         if(debug) PRINT_TRACE
640
641                         if(debug) printf("PackageRenderer::render_package 1 %d %jd %jd\n",
642                                         result, audio_read_length, video_read_length);
643                         if(need_video && !result) do_video();
644                         if(debug) printf("PackageRenderer::render_package %d %d %d\n",
645                                         __LINE__, result, samples_rendered);
646                         if(need_audio && !result) do_audio();
647
648
649                         if(debug) PRINT_TRACE
650                         if(!result)
651                         {
652 // Calculate frames per second for the renderfarm table.
653                                 total_samples_rendered += samples_rendered;
654                                 if(!video_done && timer->get_difference() > 30000)
655                                 {
656                                         frames_per_second = (double)total_samples_rendered *
657                                                 asset->frame_rate /
658                                                 asset->sample_rate /
659                                                 ((double)timer->get_difference() / 1000);
660                                 }
661                                 set_progress(samples_rendered);
662                         }
663                         if(debug) PRINT_TRACE
664
665
666
667
668
669                         if(!result && progress_cancelled()) result = 1;
670                         if(debug) PRINT_TRACE
671
672 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
673 // audio_read_length, video_read_length, samples_rendered, result);
674                         if(result)
675                                 set_result(result);
676                         else
677                                 result = get_result();
678                 }
679
680 // Final FPS readout
681                 frames_per_second = (double)(package->video_end - package->video_start) /
682                         ((double)timer->get_difference() / 1000);
683
684
685 //PRINT_TRACE
686                 stop_engine();
687 //PRINT_TRACE
688
689                 stop_output();
690 //PRINT_TRACE
691
692
693         }
694
695
696 //PRINT_TRACE
697
698         close_output();
699
700 //PRINT_TRACE
701
702         set_result(result);
703 //PRINT_TRACE
704
705
706
707         return result;
708 }
709
710
711
712
713
714
715
716
717 // Try to copy the compressed frame directly from the input to output files
718 // Return 1 on failure and 0 on success
719 int PackageRenderer::direct_frame_copy(EDL *edl,
720         int64_t &video_position,
721         File *file,
722         int &error)
723 {
724         Track *playable_track = 0;
725         Edit *playable_edit = 0;
726
727 //printf("Render::direct_frame_copy 1\n");
728         if(direct_copy_possible(edl,
729                 video_position,
730                 playable_track,
731                 playable_edit,
732                 file))
733         {
734 // Switch to direct copying
735                 if(!direct_frame_copying)
736                 {
737                         if(video_write_position)
738                         {
739                                 error |= file->write_video_buffer(video_write_position);
740                                 video_write_position = 0;
741                         }
742                         file->stop_video_thread();
743                         direct_frame_copying = 1;
744                 }
745 //printf("Render::direct_frame_copy 2\n");
746
747                 if(!package->use_brender)
748                         error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
749                                 video_position,
750                                 PLAY_FORWARD,
751                                 video_cache,
752                                 1,
753                                 0,
754                                 0);
755
756
757                 if(!error && video_preroll > 0)
758                 {
759                         video_preroll--;
760                 }
761                 else
762                 if(!error)
763                 {
764                         if(package->use_brender)
765                         {
766 //printf("PackageRenderer::direct_frame_copy 1\n");
767                                 error = set_video_map(video_position, BRender::SCANNED);
768 //printf("PackageRenderer::direct_frame_copy 10 %d\n", error);
769                         }
770                         else
771                         {
772                                 VFrame ***temp_output = new VFrame**[1];
773                                 temp_output[0] = new VFrame*[1];
774                                 temp_output[0][0] = compressed_output;
775                                 error = file->write_frames(temp_output, 1);
776                                 delete [] temp_output[0];
777                                 delete [] temp_output;
778                         }
779                 }
780                 return 0;
781         }
782         else
783                 return 1;
784 }
785
786 int PackageRenderer::direct_copy_possible(EDL *edl,
787                                 int64_t current_position,
788                                 Track* &playable_track,  // The one track which is playable
789                                 Edit* &playable_edit, // The edit which is playing
790                                 File *file)   // Output file
791 {
792         int result = 1;
793         int total_playable_tracks = 0;
794         Track* current_track;
795
796 // Number of playable tracks must equal 1
797         for(current_track = edl->tracks->first;
798                 current_track && result;
799                 current_track = current_track->next)
800         {
801                 if(current_track->data_type == TRACK_VIDEO)
802                 {
803                         if(playable_tracks->is_playable(current_track,
804                                 current_position,
805                                 PLAY_FORWARD,
806                                 1))
807                         {
808                                 playable_track = current_track;
809                                 total_playable_tracks++;
810                         }
811                 }
812         }
813
814 //printf("Render::direct_copy_possible 1 %d\n", result);
815         if(total_playable_tracks != 1) result = 0;
816 //printf("Render::direct_copy_possible 2 %d\n", result);
817
818 // Edit must have a source file
819 // TODO: descend into nested EDL's
820         if(result)
821         {
822 //printf("Render::direct_copy_possible 3 %d\n", result);
823                 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
824 //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit);
825                 if(!playable_edit)
826                         result = 0;
827         }
828
829 // Source file must be able to copy to destination file.
830 // Source file must be same size as project output.
831         if(result)
832         {
833                 if(!file->can_copy_from(playable_edit->asset,
834                         current_position + playable_track->nudge,
835                         edl->session->output_w,
836                         edl->session->output_h))
837                         result = 0;
838         }
839 //printf("Render::direct_copy_possible 6 %d\n", result);
840
841 // Test conditions mutual between vrender.C and this.
842         if(result &&
843                 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
844                 result = 0;
845 //printf("Render::direct_copy_possible 7 %d\n", result);
846
847         return result;
848 }
849
850
851
852
853
854
855
856
857
858 int PackageRenderer::get_master()
859 {
860         return 0;
861 }
862
863 // Get result status from server
864 int PackageRenderer::get_result()
865 {
866         return 0;
867 }
868
869 void PackageRenderer::set_result(int value)
870 {
871 }
872
873 void PackageRenderer::set_progress(int64_t value)
874 {
875 }
876
877 int PackageRenderer::set_video_map(int64_t position, int value)
878 {
879         return 0;
880 }
881
882 int PackageRenderer::progress_cancelled()
883 {
884         return 0;
885 }
886
887
888
889
890
891
892
893
894
895