merged hv7 mod
[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                 snprintf(asset->path, sizeof(asset->path),
156                         RENDERFARM_FS_PREFIX "%s", package->path);
157         else
158                 strncpy(asset->path, package->path, sizeof(asset->path));
159
160         file = new File;
161         file->set_processors(preferences->processors);
162         result = file->open_file(preferences, asset, 0, 1);
163
164         if(result && mwindow)
165         {
166 // open failed
167                 char string[BCTEXTLEN];
168                 snprintf(string, sizeof(string), _("Couldn't open %s"), asset->path);
169                 ErrorBox error(_(PROGRAM_NAME ": Error"),
170                         mwindow->gui->get_abs_cursor_x(1),
171                         mwindow->gui->get_abs_cursor_y(1));
172                 error.create_objects(string);
173                 error.run_window();
174         }
175         else
176         if(mwindow)
177         {
178                 mwindow->sighandler->push_file(file);
179                 IndexFile::delete_index(preferences, asset);
180         }
181 //printf("PackageRenderer::create_output %d %d\n", __LINE__, result);
182 }
183
184 void PackageRenderer::create_engine()
185 {
186 // Fix audio buffers to 1 second
187         audio_read_length = command->get_edl()->session->sample_rate;
188         command->get_edl()->session->playback_config->aconfig->fragment_size = audio_read_length;
189
190         aconfig->fragment_size = audio_read_length;
191
192
193         render_engine = new RenderEngine(0, preferences, 0, 0);
194         render_engine->set_acache(audio_cache);
195         render_engine->set_vcache(video_cache);
196         render_engine->arm_command(command);
197
198         if(package->use_brender)
199         {
200                 audio_preroll = Units::to_int64((double)preferences->brender_preroll /
201                         default_asset->frame_rate *
202                         default_asset->sample_rate);
203                 video_preroll = preferences->brender_preroll;
204         }
205         else
206         {
207                 audio_preroll = Units::to_int64(preferences->render_preroll *
208                         default_asset->sample_rate);
209                 video_preroll = Units::to_int64(preferences->render_preroll *
210                         default_asset->frame_rate);
211         }
212         audio_position = package->audio_start - audio_preroll;
213         if( audio_position < 0 )
214         {
215                 audio_preroll += audio_position;
216                 audio_position = 0;
217         }
218         video_position = package->video_start - video_preroll;
219         if( video_position < 0 )
220         {
221                 video_preroll += video_position;
222                 video_position = 0;
223         }
224
225
226 //      PRINT_TRACE
227
228 // Create output buffers
229         if(asset->audio_data)
230         {
231                 file->start_audio_thread(audio_read_length,
232                         preferences->processors > 1 ? 2 : 1);
233         }
234
235 //      PRINT_TRACE
236
237         if(asset->video_data)
238         {
239                 compressed_output = new VFrame;
240 // The write length needs to correlate with the processor count because
241 // it is passed to the file handler which usually processes frames simultaneously.
242                 video_write_length = preferences->processors;
243                 video_write_position = 0;
244                 direct_frame_copying = 0;
245
246
247 //printf("PackageRenderer::create_engine %d video_write_length=%d\n", __LINE__, video_write_length);
248 // starting frames are corrupted if video_write_length > 2.  Work around it, for now.
249                 if(video_write_length > 2)
250                 {
251                         video_write_length = 2;
252                 }
253                 file->start_video_thread(video_write_length,
254                         command->get_edl()->session->color_model,
255                         preferences->processors > 1 ? 2 : 1,
256                         0);
257 //printf("PackageRenderer::create_engine %d\n", __LINE__);
258
259
260                 if(mwindow)
261                 {
262                         video_device = new VideoDevice;
263                         video_device->open_output(vconfig,
264                                 command->get_edl()->session->frame_rate,
265                                 command->get_edl()->session->output_w,
266                                 command->get_edl()->session->output_h,
267                                 mwindow->cwindow->gui->canvas,
268                                 0);
269 //                      video_device->start_playback();
270                 }
271         }
272
273
274         playable_tracks = new PlayableTracks(render_engine->get_edl(),
275                 video_position,
276                 PLAY_FORWARD,
277                 TRACK_VIDEO,
278                 1);
279
280 }
281
282
283
284
285 void PackageRenderer::do_audio()
286 {
287 //printf("PackageRenderer::do_audio %d\n", __LINE__);
288 // Do audio data
289         if(asset->audio_data)
290         {
291                 audio_output = file->get_audio_buffer();
292 // Zero unused channels in output vector
293                 for(int i = 0; i < MAX_CHANNELS; i++)
294                 {
295                         audio_output_ptr[i] = (i < asset->channels) ?
296                                 audio_output[i] :
297                                 0;
298                 }
299
300
301
302 // Call render engine
303
304                 result = render_engine->arender->process_buffer(audio_output_ptr,
305                         audio_read_length,
306                         audio_position);
307
308
309
310 // Fix buffers for preroll
311                 int64_t output_length = audio_read_length;
312                 if(audio_preroll > 0)
313                 {
314                         if(audio_preroll >= output_length)
315                                 output_length = 0;
316                         else
317                         {
318                                 output_length -= audio_preroll;
319                                 for(int i = 0; i < MAX_CHANNELS; i++)
320                                 {
321                                         if(audio_output_ptr[i])
322                                         {
323                                                 double *data = audio_output_ptr[i]->get_data();
324                                                 for(int j = 0; j < output_length; j++)
325                                                 {
326                                                         data[j] = data[j + audio_read_length - output_length];
327                                                 }
328                                         }
329                                 }
330                         }
331 //printf("PackageRenderer::do_audio 4\n");
332
333                         audio_preroll -= audio_read_length;
334                 }
335
336 // Must perform writes even if 0 length so get_audio_buffer doesn't block
337                 result |= file->write_audio_buffer(output_length);
338         }
339
340         audio_position += audio_read_length;
341 //printf("PackageRenderer::do_audio %d\n", __LINE__);
342 }
343
344
345 void PackageRenderer::do_video()
346 {
347         const int debug = 0;
348 // Do video data
349         if(asset->video_data)
350         {
351 // get the absolute video position from the audio position
352                 int64_t video_end = video_position + video_read_length;
353
354                 if(video_end > package->video_end)
355                         video_end = package->video_end;
356
357                 while(video_position < video_end && !result)
358                 {
359 // Try to copy the compressed frame directly from the input to output files
360 //printf("PackageRenderer::do_video 2 video_position=%ld\n", video_position);
361                         if(direct_frame_copy(command->get_edl(),
362                                 video_position,
363                                 file,
364                                 result))
365                         {
366 // Direct frame copy failed.
367 // Switch back to background compression
368                                 if(direct_frame_copying)
369                                 {
370
371                                         file->start_video_thread(video_write_length,
372                                                 command->get_edl()->session->color_model,
373                                                 preferences->processors > 1 ? 2 : 1,
374                                                 0);
375 //printf("PackageRenderer::do_video %d %d\n", __LINE__, preferences->processors);
376                                         direct_frame_copying = 0;
377                                 }
378
379 // Try to use the rendering engine to write the frame.
380 // Get a buffer for background writing.
381
382                                 if(video_write_position == 0)
383                                         video_output = file->get_video_buffer();
384
385                                 if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output);
386                                 if(debug) printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output[0]);
387
388
389
390
391 // Construct layered output buffer
392                                 video_output_ptr = video_output[0][video_write_position];
393                                 if(debug)
394                                 {
395                                         printf("PackageRenderer::do_video %d %p\n", __LINE__, video_output_ptr);
396                                         printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
397                                         video_output_ptr->dump();
398                                 }
399
400                                 if(!result)
401                                         result = render_engine->vrender->process_buffer(
402                                                 video_output_ptr,
403                                                 video_position,
404                                                 0);
405
406
407                                 if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
408
409                                 if(!result &&
410                                         mwindow &&
411                                         video_device->output_visible())
412                                 {
413 // Vector for video device
414                                         VFrame *preview_output;
415
416                                         video_device->new_output_buffer(&preview_output,
417                                                 command->get_edl()->session->color_model,
418                                                 command->get_edl());
419
420                                         preview_output->copy_from(video_output_ptr);
421                                         video_device->write_buffer(preview_output,
422                                                 command->get_edl());
423                                 }
424
425                                 if(debug) printf("PackageRenderer::do_video %d %d\n", __LINE__, result);
426
427
428 // Don't write to file
429                                 if(video_preroll && !result)
430                                 {
431                                         video_preroll--;
432 // Keep the write position at 0 until ready to write real frames
433                                         result = file->write_video_buffer(0);
434                                         video_write_position = 0;
435                                 }
436                                 else
437                                 if(!result)
438                                 {
439 // Set background rendering parameters
440 // Allow us to skip sections of the output file by setting the frame number.
441 // Used by background render and render farm.
442 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
443                                         video_output_ptr->set_number(video_position);
444                                         video_write_position++;
445
446                                         if(video_write_position >= video_write_length)
447                                         {
448                                                 result = file->write_video_buffer(video_write_position);
449 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
450 // Update the brender map after writing the files.
451                                                 if(package->use_brender)
452                                                 {
453 //printf("PackageRenderer::do_video 10\n");
454                                                         for(int i = 0; i < video_write_position && !result; i++)
455                                                         {
456                                                                 result = set_video_map(video_position + 1 - video_write_position + i,
457                                                                         BRender::RENDERED);
458                                                         }
459 //printf("PackageRenderer::do_video 11 %d\n", result);
460                                                 }
461                                                 video_write_position = 0;
462                                         }
463                                 }
464 //printf("PackageRenderer::do_video %d %jd\n", __LINE__, video_position);
465
466
467                         }
468
469                         video_position++;
470                         if(!result && get_result()) result = 1;
471                         if(!result && progress_cancelled()) result = 1;
472                 }
473         }
474         else
475         {
476                 video_position += video_read_length;
477         }
478 }
479
480
481 void PackageRenderer::stop_engine()
482 {
483         delete render_engine;
484         delete playable_tracks;
485 }
486
487
488 void PackageRenderer::stop_output()
489 {
490         int error = 0;
491         if(asset->audio_data)
492         {
493 // stop file I/O
494                 file->stop_audio_thread();
495         }
496
497         if(asset->video_data)
498         {
499                 delete compressed_output;
500                 if(video_write_position)
501                         file->write_video_buffer(video_write_position);
502                 if(package->use_brender)
503                 {
504                         for(int i = 0; i < video_write_position && !error; i++)
505                         {
506                                 error = set_video_map(video_position - video_write_position + i,
507                                         BRender::RENDERED);
508                         }
509                 }
510                 video_write_position = 0;
511                 if(!error) file->stop_video_thread();
512                 if(mwindow)
513                 {
514 //                      video_device->stop_playback();
515                         video_device->close_all();
516                         delete video_device;
517                 }
518         }
519 }
520
521
522 void PackageRenderer::close_output()
523 {
524         if(mwindow)
525                 mwindow->sighandler->pull_file(file);
526         file->close_file();
527         delete file;
528         asset->Garbage::remove_user();
529 }
530
531 // Aborts and returns 1 if an error is encountered.
532 int PackageRenderer::render_package(RenderPackage *package)
533 {
534         int audio_done = 0;
535         int video_done = 0;
536         int samples_rendered = 0;
537         const int debug = 0;
538
539
540         result = 0;
541         this->package = package;
542
543 // printf(
544 // "PackageRenderer::render_package: audio s=%jd l=%jd video s=%jd l=%jd\n",
545 //      package->audio_start,
546 //      package->audio_end - package->audio_start,
547 //      package->video_start,
548 //      package->video_end - package->video_start);
549
550         if(debug) PRINT_TRACE
551
552         if( package->video_do ) default_asset->video_data = 1;
553         if( package->audio_do ) default_asset->audio_data = 1;
554         Render::check_asset(edl, *default_asset);
555
556 // FIXME: The design that we only get EDL once does not give us neccessary flexiblity to do things the way they should be donek
557         default_asset->video_data = package->video_do;
558         default_asset->audio_data = package->audio_do;
559         Render::check_asset(edl, *default_asset);
560
561         create_output();
562         if(debug) PRINT_TRACE
563
564         if(!asset->video_data) video_done = 1;
565         if(!asset->audio_data) audio_done = 1;
566
567 // Create render engine
568         if(!result)
569         {
570 if(debug) PRINT_TRACE
571                 create_engine();
572 if(debug) PRINT_TRACE
573
574
575 // Main loop
576                 timer->update();
577                 total_samples_rendered = 0;
578                 while((!audio_done || !video_done) && !result)
579                 {
580                         int need_audio = 0, need_video = 0;
581
582
583
584
585 // Calculate lengths to process.  Audio fragment is constant.
586                         if(!audio_done)
587                         {
588                                 if(audio_position + audio_read_length >= package->audio_end)
589                                 {
590                                         audio_done = 1;
591                                         audio_read_length = package->audio_end - audio_position;
592                                 }
593
594                                 samples_rendered = audio_read_length;
595                                 need_audio = 1;
596                         }
597
598 //printf("PackageRenderer::render_package 6 %d\n", samples_rendered);
599
600                         if(!video_done)
601                         {
602                                 if(audio_done)
603                                 {
604 //                                      video_read_length = package->video_end - video_position;
605 // // Packetize video length so progress gets updated
606 //                                      video_read_length = (int)MIN(asset->frame_rate, video_read_length);
607 //                                      video_read_length = MAX(video_read_length, 30);
608                                         video_read_length = 1;
609                                 }
610                                 else
611 // Guide video with audio
612                                 {
613                                         video_read_length = Units::to_int64(
614                                                 (double)(audio_position + audio_read_length) /
615                                                 asset->sample_rate *
616                                                 asset->frame_rate) -
617                                                 video_position;
618                                 }
619
620 // Clamp length
621                                 if(video_position + video_read_length >= package->video_end)
622                                 {
623                                         video_done = 1;
624                                         video_read_length = package->video_end - video_position;
625                                 }
626
627 // Calculate samples rendered for progress bar.
628                                 if(audio_done)
629                                         samples_rendered = Units::round((double)video_read_length /
630                                                 asset->frame_rate *
631                                                 asset->sample_rate);
632
633                                 need_video = 1;
634                         }
635                         if(debug) PRINT_TRACE
636
637                         if(debug) printf("PackageRenderer::render_package 1 %d %jd %jd\n",
638                                         result, audio_read_length, video_read_length);
639                         if(need_video && !result) do_video();
640                         if(debug) printf("PackageRenderer::render_package %d %d %d\n",
641                                         __LINE__, result, samples_rendered);
642                         if(need_audio && !result) do_audio();
643
644
645                         if(debug) PRINT_TRACE
646                         if(!result)
647                         {
648 // Calculate frames per second for the renderfarm table.
649                                 total_samples_rendered += samples_rendered;
650                                 if(!video_done && timer->get_difference() > 30000)
651                                 {
652                                         frames_per_second = (double)total_samples_rendered *
653                                                 asset->frame_rate /
654                                                 asset->sample_rate /
655                                                 ((double)timer->get_difference() / 1000);
656                                 }
657                                 set_progress(samples_rendered);
658                         }
659                         if(debug) PRINT_TRACE
660
661
662
663
664
665                         if(!result && progress_cancelled()) result = 1;
666                         if(debug) PRINT_TRACE
667
668 // printf("PackageRenderer::render_package 10 %d %d %d %d\n",
669 // audio_read_length, video_read_length, samples_rendered, result);
670                         if(result)
671                                 set_result(result);
672                         else
673                                 result = get_result();
674                 }
675
676 // Final FPS readout
677                 frames_per_second = (double)(package->video_end - package->video_start) /
678                         ((double)timer->get_difference() / 1000);
679
680
681 //PRINT_TRACE
682                 stop_engine();
683 //PRINT_TRACE
684
685                 stop_output();
686 //PRINT_TRACE
687
688
689         }
690
691
692 //PRINT_TRACE
693
694         close_output();
695
696 //PRINT_TRACE
697
698         set_result(result);
699 //PRINT_TRACE
700
701
702
703         return result;
704 }
705
706
707
708
709
710
711
712
713 // Try to copy the compressed frame directly from the input to output files
714 // Return 1 on failure and 0 on success
715 int PackageRenderer::direct_frame_copy(EDL *edl,
716         int64_t &video_position,
717         File *file,
718         int &error)
719 {
720         Track *playable_track = 0;
721         Edit *playable_edit = 0;
722
723 //printf("Render::direct_frame_copy 1\n");
724         if(direct_copy_possible(edl,
725                 video_position,
726                 playable_track,
727                 playable_edit,
728                 file))
729         {
730 // Switch to direct copying
731                 if(!direct_frame_copying)
732                 {
733                         if(video_write_position)
734                         {
735                                 error |= file->write_video_buffer(video_write_position);
736                                 video_write_position = 0;
737                         }
738                         file->stop_video_thread();
739                         direct_frame_copying = 1;
740                 }
741 //printf("Render::direct_frame_copy 2\n");
742
743                 if(!package->use_brender)
744                 {
745                         error |= ((VEdit*)playable_edit)->read_frame(compressed_output,
746                                 video_position,
747                                 PLAY_FORWARD,
748                                 video_cache,
749                                 1,
750                                 0,
751                                 0);
752 //printf("Render::direct_frame_copy %d %d\n", __LINE__, compressed_output->get_compressed_size());
753                 }
754                 
755
756                 if(!error && video_preroll > 0)
757                 {
758                         video_preroll--;
759                 }
760                 else
761                 if(!error)
762                 {
763                         if(package->use_brender)
764                         {
765 //printf("PackageRenderer::direct_frame_copy 1\n");
766                                 error = set_video_map(video_position, BRender::SCANNED);
767 //printf("PackageRenderer::direct_frame_copy 10 %d\n", error);
768                         }
769                         else
770                         {
771                                 VFrame ***temp_output = new VFrame**[1];
772                                 temp_output[0] = new VFrame*[1];
773                                 temp_output[0][0] = compressed_output;
774                                 error = file->write_frames(temp_output, 1);
775                                 delete [] temp_output[0];
776                                 delete [] temp_output;
777                         }
778                 }
779                 return 0;
780         }
781         else
782                 return 1;
783 }
784
785 int PackageRenderer::direct_copy_possible(EDL *edl,
786                                 int64_t current_position,
787                                 Track* &playable_track,  // The one track which is playable
788                                 Edit* &playable_edit, // The edit which is playing
789                                 File *file)   // Output file
790 {
791         int result = 1;
792         int total_playable_tracks = 0;
793         Track* current_track;
794
795 // Number of playable tracks must equal 1
796         for(current_track = edl->tracks->first;
797                 current_track && result;
798                 current_track = current_track->next)
799         {
800                 if(current_track->data_type == TRACK_VIDEO)
801                 {
802                         if(playable_tracks->is_playable(current_track,
803                                 current_position,
804                                 PLAY_FORWARD,
805                                 1))
806                         {
807                                 playable_track = current_track;
808                                 total_playable_tracks++;
809                         }
810                 }
811         }
812
813 //printf("Render::direct_copy_possible 1 %d\n", result);
814         if(total_playable_tracks != 1) result = 0;
815 //printf("Render::direct_copy_possible 2 %d\n", result);
816
817 // Edit must have a source file
818 // TODO: descend into nested EDL's
819         if(result)
820         {
821 //printf("Render::direct_copy_possible 3 %d\n", result);
822                 playable_edit = playable_track->edits->get_playable_edit(current_position, 1);
823 //printf("Render::direct_copy_possible 4 %d %p\n", result, playable_edit);
824                 if(!playable_edit)
825                         result = 0;
826         }
827
828 // Source file must be able to copy to destination file.
829 // Source file must be same size as project output.
830         if(result)
831         {
832                 if(!file->can_copy_from(playable_edit->asset,
833                         current_position + playable_track->nudge,
834                         edl->session->output_w,
835                         edl->session->output_h))
836                         result = 0;
837         }
838 //printf("Render::direct_copy_possible 6 %d\n", result);
839
840 // Test conditions mutual between vrender.C and this.
841         if(result &&
842                 !playable_track->direct_copy_possible(current_position, PLAY_FORWARD, 1))
843                 result = 0;
844 //printf("Render::direct_copy_possible 7 %d\n", result);
845
846         return result;
847 }
848
849
850
851
852
853
854
855
856
857 int PackageRenderer::get_master()
858 {
859         return 0;
860 }
861
862 // Get result status from server
863 int PackageRenderer::get_result()
864 {
865         return 0;
866 }
867
868 void PackageRenderer::set_result(int value)
869 {
870 }
871
872 void PackageRenderer::set_progress(int64_t value)
873 {
874 }
875
876 int PackageRenderer::set_video_map(int64_t position, int value)
877 {
878         return 0;
879 }
880
881 int PackageRenderer::progress_cancelled()
882 {
883         return 0;
884 }
885
886
887
888
889
890
891
892
893
894