update shuttlerc, fix vwdw lock update_position
[goodguy/cinelerra.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         delete timer;
109 }
110
111 // PackageRenderer::initialize happens only once for every node when doing rendering session
112 // This is not called for each package!
113
114 int PackageRenderer::initialize(MWindow *mwindow,
115                 EDL *edl,
116                 Preferences *preferences,
117                 Asset *default_asset)
118 {
119         int result = 0;
120
121         this->mwindow = mwindow;
122         this->edl = edl;
123         this->preferences = preferences;
124         this->default_asset = default_asset;
125
126
127 //printf("PackageRenderer::initialize %d\n", preferences->processors);
128         command = new TransportCommand;
129         command->command = NORMAL_FWD;
130         command->get_edl()->copy_all(edl);
131         command->change_type = CHANGE_ALL;
132         command->set_playback_range();
133
134         default_asset->frame_rate = command->get_edl()->session->frame_rate;
135         default_asset->sample_rate = command->get_edl()->session->sample_rate;
136         default_asset->aspect_ratio = (double)command->get_edl()->session->aspect_w /
137                 command->get_edl()->session->aspect_h;
138         result = Render::check_asset(edl, *default_asset);
139
140         audio_cache = new CICache(preferences);
141         video_cache = new CICache(preferences);
142
143         //PlaybackConfig *config = command->get_edl()->session->playback_config;
144         aconfig = new AudioOutConfig();
145         vconfig = new VideoOutConfig;
146
147         return result;
148 }
149
150 void PackageRenderer::create_output()
151 {
152         FileSystem fs;
153         asset = new Asset(*default_asset);
154
155         if(!get_master() && preferences->renderfarm_vfs && preferences->use_renderfarm)
156                 snprintf(asset->path, sizeof(asset->path),
157                         RENDERFARM_FS_PREFIX "%s", package->path);
158         else
159                 strncpy(asset->path, package->path, sizeof(asset->path));
160
161         file = new File;
162         file->set_processors(preferences->processors);
163         result = file->open_file(preferences, asset, 0, 1);
164
165         if(result && mwindow)
166         {
167 // open failed
168                 char string[BCTEXTLEN];
169                 snprintf(string, sizeof(string), _("Couldn't open %s"), asset->path);
170                 ErrorBox error(_(PROGRAM_NAME ": Error"),
171                         mwindow->gui->get_abs_cursor_x(1),
172                         mwindow->gui->get_abs_cursor_y(1));
173                 error.create_objects(string);
174                 error.run_window();
175         }
176         else
177         if(mwindow)
178         {
179                 mwindow->sighandler->push_file(file);
180                 IndexFile::delete_index(preferences, asset);
181         }
182 //printf("PackageRenderer::create_output %d %d\n", __LINE__, result);
183 }
184
185 void PackageRenderer::create_engine()
186 {
187 // Fix audio buffers to 1 second
188         audio_read_length = command->get_edl()->session->sample_rate;
189         command->get_edl()->session->playback_config->aconfig->fragment_size = audio_read_length;
190
191         aconfig->fragment_size = audio_read_length;
192
193
194         render_engine = new RenderEngine(0, preferences, 0, 0);
195         render_engine->set_acache(audio_cache);
196         render_engine->set_vcache(video_cache);
197         render_engine->arm_command(command);
198
199         if(package->use_brender)
200         {
201                 audio_preroll = Units::to_int64((double)preferences->brender_preroll /
202                         default_asset->frame_rate *
203                         default_asset->sample_rate);
204                 video_preroll = preferences->brender_preroll;
205         }
206         else
207         {
208                 audio_preroll = Units::to_int64(preferences->render_preroll *
209                         default_asset->sample_rate);
210                 video_preroll = Units::to_int64(preferences->render_preroll *
211                         default_asset->frame_rate);
212         }
213         audio_position = package->audio_start - audio_preroll;
214         if( audio_position < 0 )
215         {
216                 audio_preroll += audio_position;
217                 audio_position = 0;
218         }
219         video_position = package->video_start - video_preroll;
220         if( video_position < 0 )
221         {
222                 video_preroll += video_position;
223                 video_position = 0;
224         }
225
226
227 //      PRINT_TRACE
228
229 // Create output buffers
230         if(asset->audio_data)
231         {
232                 file->start_audio_thread(audio_read_length,
233                         preferences->processors > 1 ? 2 : 1);
234         }
235
236 //      PRINT_TRACE
237
238         if(asset->video_data)
239         {
240                 compressed_output = new VFrame;
241 // The write length needs to correlate with the processor count because
242 // it is passed to the file handler which usually processes frames simultaneously.
243                 video_write_length = preferences->processors;
244                 video_write_position = 0;
245                 direct_frame_copying = 0;
246
247
248 //printf("PackageRenderer::create_engine %d video_write_length=%d\n", __LINE__, video_write_length);
249 // starting frames are corrupted if video_write_length > 2.  Work around it, for now.
250                 if(video_write_length > 2)
251                 {
252                         video_write_length = 2;
253                 }
254                 file->start_video_thread(video_write_length,
255                         command->get_edl()->session->color_model,
256                         preferences->processors > 1 ? 2 : 1,
257                         0);
258 //printf("PackageRenderer::create_engine %d\n", __LINE__);
259
260
261                 if(mwindow)
262                 {
263                         video_device = new VideoDevice;
264                         video_device->open_output(vconfig,
265                                 command->get_edl()->session->frame_rate,
266                                 command->get_edl()->session->output_w,
267                                 command->get_edl()->session->output_h,
268                                 mwindow->cwindow->gui->canvas,
269                                 0);
270 //                      video_device->start_playback();
271                 }
272         }
273
274
275         playable_tracks = new PlayableTracks(render_engine->get_edl(),
276                 video_position,
277                 PLAY_FORWARD,
278                 TRACK_VIDEO,
279                 1);
280
281 }
282
283
284
285
286 void PackageRenderer::do_audio()
287 {
288 //printf("PackageRenderer::do_audio %d\n", __LINE__);
289 // Do audio data
290         if(asset->audio_data)
291         {
292                 audio_output = file->get_audio_buffer();
293 // Zero unused channels in output vector
294                 for(int i = 0; i < MAX_CHANNELS; i++)
295                 {
296                         audio_output_ptr[i] = (i < asset->channels) ?
297                                 audio_output[i] :
298                                 0;
299                 }
300
301
302
303 // Call render engine
304
305                 result = render_engine->arender->process_buffer(audio_output_ptr,
306                         audio_read_length,
307                         audio_position);
308
309
310
311 // Fix buffers for preroll
312                 int64_t output_length = audio_read_length;
313                 if(audio_preroll > 0)
314                 {
315                         if(audio_preroll >= output_length)
316                                 output_length = 0;
317                         else
318                         {
319                                 output_length -= audio_preroll;
320                                 for(int i = 0; i < MAX_CHANNELS; i++)
321                                 {
322                                         if(audio_output_ptr[i])
323                                         {
324                                                 double *data = audio_output_ptr[i]->get_data();
325                                                 for(int j = 0; j < output_length; j++)
326                                                 {
327                                                         data[j] = data[j + audio_read_length - output_length];
328                                                 }
329                                         }
330                                 }
331                         }
332 //printf("PackageRenderer::do_audio 4\n");
333
334                         audio_preroll -= audio_read_length;
335                 }
336
337 // Must perform writes even if 0 length so get_audio_buffer doesn't block
338                 result |= file->write_audio_buffer(output_length);
339         }
340
341         audio_position += audio_read_length;
342 //printf("PackageRenderer::do_audio %d\n", __LINE__);
343 }
344
345
346 void PackageRenderer::do_video()
347 {
348         const int debug = 0;
349 // Do video data
350         if(asset->video_data)
351         {
352 // get the absolute video position from the audio position
353                 int64_t video_end = video_position + video_read_length;
354
355                 if(video_end > package->video_end)
356                         video_end = package->video_end;
357
358                 while(video_position < video_end && !result)
359                 {
360 // Try to copy the compressed frame directly from the input to output files
361 //printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position);
362                         if(direct_frame_copy(command->get_edl(),
363                                 video_position,
364                                 file,
365                                 result))
366                         {
367 // Direct frame copy failed.
368 // Switch back to background compression
369                                 if(direct_frame_copying)
370                                 {
371
372                                         file->start_video_thread(video_write_length,
373                                                 command->get_edl()->session->color_model,
374                                                 preferences->processors > 1 ? 2 : 1,
375                                                 0);
376 //printf("PackageRenderer::do_video %d %d\n", __LINE__, preferences->processors);
377                                         direct_frame_copying = 0;
378                                 }
379
380 // Try to use the rendering engine to write the frame.
381 // Get a buffer for background writing.
382
383                                 if(video_write_position == 0)
384                                         video_output = file->get_video_buffer();
385
386                                 if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output);
387                                 if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output[0]);
388
389
390
391
392 // Construct layered output buffer
393                                 video_output_ptr = video_output[0][video_write_position];
394                                 if(debug)
395                                 {
396                                         printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output_ptr);
397                                         printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
398                                         video_output_ptr->dump();
399                                 }
400
401                                 if(!result)
402                                         result = render_engine->vrender->process_buffer(
403                                                 video_output_ptr,
404                                                 video_position,
405                                                 0);
406
407
408                                 if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
409
410                                 if(!result &&
411                                         mwindow &&
412                                         video_device->output_visible())
413                                 {
414 // Vector for video device
415                                         VFrame *preview_output;
416
417                                         video_device->new_output_buffer(&preview_output,
418                                                 command->get_edl()->session->color_model,
419                                                 command->get_edl());
420
421                                         preview_output->copy_from(video_output_ptr);
422                                         video_device->write_buffer(preview_output,
423                                                 command->get_edl());
424                                 }
425
426                                 if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
427
428
429 // Don't write to file
430                                 if(video_preroll && !result)
431                                 {
432                                         video_preroll--;
433 // Keep the write position at 0 until ready to write real frames
434                                         result = file->write_video_buffer(0);
435                                         video_write_position = 0;
436                                 }
437                                 else
438                                 if(!result)
439                                 {
440 // Set background rendering parameters
441 // Allow us to skip sections of the output file by setting the frame number.
442 // Used by background render and render farm.
443 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
444                                         video_output_ptr->set_number(video_position);
445                                         video_write_position++;
446
447                                         if(video_write_position >= video_write_length)
448                                         {
449                                                 result = file->write_video_buffer(video_write_position);
450 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
451 // Update the brender map after writing the files.
452                                                 if(package->use_brender)
453                                                 {
454 //printf("PackageRenderer::do_video 10\n");
455                                                         for(int i = 0; i < video_write_position && !result; i++)
456                                                         {
457                                                                 result = set_video_map(video_position + 1 - video_write_position + i,
458                                                                         BRender::RENDERED);
459                                                         }
460 //printf("PackageRenderer::do_video 11 %d\n", result);
461                                                 }
462                                                 video_write_position = 0;
463                                         }
464                                 }
465 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
466
467
468                         }
469
470                         video_position++;
471                         if(!result && get_result()) result = 1;
472                         if(!result && progress_cancelled()) result = 1;
473                 }
474         }
475         else
476         {
477                 video_position += video_read_length;
478         }
479 }
480
481
482 void PackageRenderer::stop_engine()
483 {
484         delete render_engine;
485         delete playable_tracks;
486 }
487
488
489 void PackageRenderer::stop_output()
490 {
491         int error = 0;
492         if(asset->audio_data)
493         {
494 // stop file I/O
495                 file->stop_audio_thread();
496         }
497
498         if(asset->video_data)
499         {
500                 delete compressed_output;
501                 if(video_write_position)
502                         file->write_video_buffer(video_write_position);
503                 if(package->use_brender)
504                 {
505                         for(int i = 0; i < video_write_position && !error; i++)
506                         {
507                                 error = set_video_map(video_position - video_write_position + i,
508                                         BRender::RENDERED);
509                         }
510                 }
511                 video_write_position = 0;
512                 if(!error) file->stop_video_thread();
513                 if(mwindow)
514                 {
515 //                      video_device->stop_playback();
516                         video_device->close_all();
517                         delete video_device;
518                 }
519         }
520 }
521
522
523 void PackageRenderer::close_output()
524 {
525         if(mwindow)
526                 mwindow->sighandler->pull_file(file);
527         file->close_file();
528         delete file;
529         asset->Garbage::remove_user();
530 }
531
532 // Aborts and returns 1 if an error is encountered.
533 int PackageRenderer::render_package(RenderPackage *package)
534 {
535         int audio_done = 0;
536         int video_done = 0;
537         int samples_rendered = 0;
538         const int debug = 0;
539
540
541         result = 0;
542         this->package = package;
543
544 // printf(
545 // "PackageRenderer::render_package: audio s=%jd l=%jd video s=%jd l=%jd\n",
546 //      package->audio_start,
547 //      package->audio_end - package->audio_start,
548 //      package->video_start,
549 //      package->video_end - package->video_start);
550
551         if(debug) PRINT_TRACE
552
553         if( package->video_do ) default_asset->video_data = 1;
554         if( package->audio_do ) default_asset->audio_data = 1;
555         Render::check_asset(edl, *default_asset);
556
557 // FIXME: The design that we only get EDL once does not give us neccessary flexiblity to do things the way they should be donek
558         default_asset->video_data = package->video_do;
559         default_asset->audio_data = package->audio_do;
560         Render::check_asset(edl, *default_asset);
561
562         create_output();
563         if(debug) PRINT_TRACE
564
565         if(!asset->video_data) video_done = 1;
566         if(!asset->audio_data) audio_done = 1;
567
568 // Create render engine
569         if(!result)
570         {
571 if(debug) PRINT_TRACE
572                 create_engine();
573 if(debug) PRINT_TRACE
574
575
576 // Main loop
577                 timer->update();
578                 total_samples_rendered = 0;
579                 while((!audio_done || !video_done) && !result)
580                 {
581                         int need_audio = 0, need_video = 0;
582
583
584
585
586 // Calculate lengths to process.  Audio fragment is constant.
587                         if(!audio_done)
588                         {
589                                 if(audio_position + audio_read_length >= package->audio_end)
590                                 {
591                                         audio_done = 1;
592                                         audio_read_length = package->audio_end - audio_position;
593                                 }
594
595                                 samples_rendered = audio_read_length;
596                                 need_audio = 1;
597                         }
598
599 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
600
601                         if(!video_done)
602                         {
603                                 if(audio_done)
604                                 {
605 //                                      video_read_length = package->video_end - video_position;
606 // // Packetize video length so progress gets updated
607 //                                      video_read_length = (int)MIN(asset->frame_rate, video_read_length);
608 //                                      video_read_length = MAX(video_read_length, 30);
609                                         video_read_length = 1;
610                                 }
611                                 else
612 // Guide video with audio
613                                 {
614                                         video_read_length = Units::to_int64(
615                                                 (double)(audio_position + audio_read_length) /
616                                                 asset->sample_rate *
617                                                 asset->frame_rate) -
618                                                 video_position;
619                                 }
620
621 // Clamp length
622                                 if(video_position + video_read_length >= package->video_end)
623                                 {
624                                         video_done = 1;
625                                         video_read_length = package->video_end - video_position;
626                                 }
627
628 // Calculate samples rendered for progress bar.
629                                 if(audio_done)
630                                         samples_rendered = Units::round((double)video_read_length /
631                                                 asset->frame_rate *
632                                                 asset->sample_rate);
633
634                                 need_video = 1;
635                         }
636                         if(debug) PRINT_TRACE
637
638                         if(debug) printf("PackageRenderer::render_package 1 %d %jd %jd\n",
639                                         result, audio_read_length, video_read_length);
640                         if(need_video && !result) do_video();
641                         if(debug) printf("PackageRenderer::render_package %d %d %d\n",
642                                         __LINE__, result, samples_rendered);
643                         if(need_audio && !result) do_audio();
644
645
646                         if(debug) PRINT_TRACE
647                         if(!result)
648                         {
649 // Calculate frames per second for the renderfarm table.
650                                 total_samples_rendered += samples_rendered;
651                                 if(!video_done && timer->get_difference() > 30000)
652                                 {
653                                         frames_per_second = (double)total_samples_rendered *
654                                                 asset->frame_rate /
655                                                 asset->sample_rate /
656                                                 ((double)timer->get_difference() / 1000);
657                                 }
658                                 set_progress(samples_rendered);
659                         }
660                         if(debug) PRINT_TRACE
661
662
663
664
665
666                         if(!result && progress_cancelled()) result = 1;
667                         if(debug) PRINT_TRACE
668
669 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
670 // audio_read_length, video_read_length, samples_rendered, result);
671                         if(result)
672                                 set_result(result);
673                         else
674                                 result = get_result();
675                 }
676
677 // Final FPS readout
678                 frames_per_second = (double)(package->video_end - package->video_start) /
679                         ((double)timer->get_difference() / 1000);
680
681
682 //PRINT_TRACE
683                 stop_engine();
684 //PRINT_TRACE
685
686                 stop_output();
687 //PRINT_TRACE
688
689
690         }
691
692
693 //PRINT_TRACE
694
695         close_output();
696
697 //PRINT_TRACE
698
699         set_result(result);
700 //PRINT_TRACE
701
702
703
704         return result;
705 }
706
707
708
709
710
711
712
713
714 // Try to copy the compressed frame directly from the input to output files
715 // Return 1 on failure and 0 on success
716 int PackageRenderer::direct_frame_copy(EDL *edl,
717         int64_t &video_position,
718         File *file,
719         int &error)
720 {
721         Track *playable_track = 0;
722         Edit *playable_edit = 0;
723
724 //printf("Render::direct_frame_copy 1\n");
725         if(direct_copy_possible(edl,
726                 video_position,
727                 playable_track,
728                 playable_edit,
729                 file))
730         {
731 // Switch to direct copying
732                 if(!direct_frame_copying)
733                 {
734                         if(video_write_position)
735                         {
736                                 error |= file->write_video_buffer(video_write_position);
737                                 video_write_position = 0;
738                         }
739                         file->stop_video_thread();
740                         direct_frame_copying = 1;
741                 }
742 //printf("Render::direct_frame_copy 2\n");
743
744                 if(!package->use_brender)
745                 {
746                         error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
747                                 video_position,
748                                 PLAY_FORWARD,
749                                 video_cache,
750                                 1,
751                                 0,
752                                 0);
753 //printf("Render::direct_frame_copy %d %d\n", __LINE__, compressed_output->get_compressed_size());
754                 }
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