prevent popup deactivation while button_down
[goodguy/history.git] / cinelerra-5.0 / cinelerra / vmodule.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2009-2013 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 "asset.h"
23 #include "bchash.h"
24 #include "bcpbuffer.h"
25 #include "bcsignals.h"
26 #include "cache.h"
27 #include "clip.h"
28 #include "commonrender.h"
29 #include "edits.h"
30 #include "edl.h"
31 #include "edlsession.h"
32 #include "file.h"
33 #include "filexml.h"
34 #include "floatautos.h"
35 #include "mwindow.h"
36 #include "overlayframe.h"
37 #include "patch.h"
38 #include "pluginarray.h"
39 #include "preferences.h"
40 #include "renderengine.h"
41 #include "sharedlocation.h"
42 #include "tracks.h"
43 #include "transition.h"
44 #include "transportque.h"
45 #include "units.h"
46 #include "vattachmentpoint.h"
47 #include "vdevicex11.h"
48 #include "vedit.h"
49 #include "vframe.h"
50 #include "videodevice.h"
51 #include "vmodule.h"
52 #include "vrender.h"
53 #include "vplugin.h"
54 #include "vtrack.h"
55 #include <string.h>
56
57 VModule::VModule(RenderEngine *renderengine, 
58         CommonRender *commonrender, 
59         PluginArray *plugin_array,
60         Track *track)
61  : Module(renderengine, commonrender, plugin_array, track)
62 {
63         data_type = TRACK_VIDEO;
64         overlay_temp = 0;
65         input_temp = 0;
66         transition_temp = 0;
67 }
68
69 VModule::~VModule()
70 {
71         if(overlay_temp) delete overlay_temp;
72         if(input_temp) delete input_temp;
73         if(transition_temp) delete transition_temp;
74 }
75
76
77 AttachmentPoint* VModule::new_attachment(Plugin *plugin)
78 {
79         return new VAttachmentPoint(renderengine, plugin);
80 }
81
82 int VModule::get_buffer_size()
83 {
84         return 1;
85 }
86
87 CICache* VModule::get_cache()
88 {
89         if(renderengine) 
90                 return renderengine->get_vcache();
91         else
92                 return cache;
93 }
94
95
96
97
98
99
100 int VModule::import_frame(VFrame *output,
101         VEdit *current_edit,
102         int64_t input_position,
103         double frame_rate,
104         int direction,
105         int use_opengl)
106 {
107         int64_t direction_position;
108 // Translation of edit
109         float in_x;
110         float in_y;
111         float in_w;
112         float in_h;
113         float out_x;
114         float out_y;
115         float out_w;
116         float out_h;
117         int result = 0;
118         const int debug = 0;
119         double edl_rate = get_edl()->session->frame_rate;
120
121         int64_t input_position_project = Units::to_int64(input_position * 
122                 edl_rate / 
123                 frame_rate + 
124                 0.001);
125
126
127
128
129
130
131
132         if(!output) printf("VModule::import_frame %d output=%p\n", __LINE__, output);
133         //output->dump_params();
134
135
136         if(debug) printf("VModule::import_frame %d this=%p input_position=%lld direction=%d\n", 
137                 __LINE__,
138                 this,
139                 (long long)input_position,
140                 direction);
141
142 // Convert to position corrected for direction
143         direction_position = input_position;
144         if(direction == PLAY_REVERSE)
145         {
146                 direction_position--;
147                 input_position_project--;
148         }
149         if(!output) printf("VModule::import_frame %d output=%p\n", __LINE__, output);
150
151         VDeviceX11 *x11_device = 0;
152         if(use_opengl)
153         {
154                 if(renderengine && renderengine->video)
155                 {
156                         x11_device = (VDeviceX11*)renderengine->video->get_output_base();
157                         output->set_opengl_state(VFrame::RAM);
158                         if(!x11_device) use_opengl = 0;
159                 }
160         }
161
162         if(!output) printf("VModule::import_frame %d output=%p x11_device=%p nested_edl=%p\n", 
163                 __LINE__,
164                 output,
165                 x11_device,
166                 nested_edl);
167
168
169         if(debug) printf("VModule::import_frame %d current_edit=%p\n", 
170                 __LINE__,
171                 current_edit);
172
173
174 // Load frame into output
175
176 // Create objects for nested EDL
177         if(current_edit &&
178                 current_edit->nested_edl)
179         {
180                 int command;
181                 if(debug) printf("VModule::import_frame %d nested_edl=%p current_edit->nested_edl=%p\n", 
182                         __LINE__,
183                         nested_edl,
184                         current_edit->nested_edl);
185
186 // Convert requested direction to command
187                 if(renderengine->command->command == CURRENT_FRAME)
188                 {
189                         command = CURRENT_FRAME;
190                 }
191                 else
192                 if(direction == PLAY_REVERSE)
193                 {
194                         if(renderengine->command->single_frame())
195                                 command = SINGLE_FRAME_REWIND;
196                         else
197                                 command = NORMAL_REWIND;
198                 }
199                 else
200                 {
201                         if(renderengine->command->single_frame())
202                                 command = SINGLE_FRAME_FWD;
203                         else
204                                 command = NORMAL_FWD;
205                 }
206
207                 if(!nested_edl || nested_edl->id != current_edit->nested_edl->id)
208                 {
209                         nested_edl = current_edit->nested_edl;
210                         if(nested_renderengine)
211                         {
212                                 delete nested_renderengine;
213                                 nested_renderengine = 0;
214                         }
215
216                         if(!nested_command)
217                         {
218                                 nested_command = new TransportCommand;
219                         }
220
221
222                         if(!nested_renderengine)
223                         {
224                                 nested_command->command = command;
225                                 nested_command->get_edl()->copy_all(nested_edl);
226                                 nested_command->change_type = CHANGE_ALL;
227                                 nested_command->realtime = renderengine->command->realtime;
228                                 nested_renderengine = new RenderEngine(0,
229                                         get_preferences(), 
230                                         0,
231                                         renderengine ? renderengine->channeldb : 0,
232                                         1);
233                                 nested_renderengine->set_vcache(get_cache());
234                                 nested_renderengine->arm_command(nested_command);
235                         }
236                 }
237                 else
238                 {
239
240 // Update nested command
241                         nested_renderengine->command->command = command;
242                         nested_command->realtime = renderengine->command->realtime;
243                 }
244
245 // Update nested video driver for opengl
246                 nested_renderengine->video = renderengine->video;
247         }
248         else
249         {
250                 nested_edl = 0;
251         }
252         if(debug) printf("VModule::import_frame %d\n", __LINE__);
253
254         if(!output) printf("VModule::import_frame %d output=%p\n", __LINE__, output);
255
256         if(current_edit &&
257                 (current_edit->asset ||
258                 (current_edit->nested_edl && nested_renderengine->vrender)))
259         {
260                 File *file = 0;
261
262                 if(debug) printf("VModule::import_frame %d cache=%p\n", 
263                         __LINE__,
264                         get_cache());
265                 if(current_edit->asset)
266                 {
267                         get_cache()->age();
268                         file = get_cache()->check_out(current_edit->asset,
269                                 get_edl());
270 //                      get_cache()->dump();
271                 }
272
273 // File found
274                 if(file || nested_edl)
275                 {
276 // Make all positions based on requested frame rate.
277                         int64_t edit_startproject = Units::to_int64(current_edit->startproject * 
278                                 frame_rate / 
279                                 edl_rate);
280                         int64_t edit_startsource = Units::to_int64(current_edit->startsource *
281                                 frame_rate /
282                                 edl_rate);
283 // Source position going forward
284                         uint64_t position = direction_position - 
285                                 edit_startproject + 
286                                 edit_startsource;
287                         int64_t nested_position = 0;
288
289
290                         
291
292
293 // apply speed curve to source position so the timeline agrees with the playback
294                         if(track->has_speed())
295                         {
296 // integrate position from start of edit.
297                                 double speed_position = edit_startsource;
298                                 FloatAuto *previous = 0;
299                                 FloatAuto *next = 0;
300                                 FloatAutos *speed_autos = (FloatAutos*)track->automation->autos[AUTOMATION_SPEED];
301                                 for(int64_t i = edit_startproject; i < direction_position; i++)
302                                 {
303                                         double speed = speed_autos->get_value(i, 
304                                                 PLAY_FORWARD,
305                                                 previous,
306                                                 next);
307                                         speed_position += speed;
308                                 }
309 //printf("VModule::import_frame %d %lld %lld\n", __LINE__, position, (int64_t)speed_position);
310                                 position = (int64_t)speed_position;
311                         }
312
313
314
315
316
317                         int asset_w;
318                         int asset_h;
319                         if(debug) printf("VModule::import_frame %d\n", __LINE__);
320
321
322 // maybe apply speed curve here, so timeline reflects actual playback
323
324
325
326 // if we hit the end of stream, freeze at last frame
327                         uint64_t max_position = 0;
328                         if(file)
329                         {
330                                 max_position = Units::to_int64((double)file->get_video_length() *
331                                         frame_rate / 
332                                         current_edit->asset->frame_rate - 1);
333                         }
334                         else
335                         {
336                                 max_position = Units::to_int64(nested_edl->tracks->total_playable_length() *
337                                         frame_rate - 1);
338                         }
339
340
341                         if(position > max_position) position = max_position;
342                         else
343                         if(position < 0) position = 0;
344
345                         int use_cache = renderengine && 
346                                 renderengine->command->single_frame();
347                         int use_asynchronous = !use_cache && 
348                                 renderengine &&
349 // Try to make rendering go faster.
350 // But converts some formats to YUV420, which may degrade input format.
351 //                              renderengine->command->realtime &&
352                                 renderengine->get_edl()->session->video_asynchronous;
353
354                         if(file)
355                         {
356                                 if(debug) printf("VModule::import_frame %d\n", __LINE__);
357                                 if(use_asynchronous)
358                                         file->start_video_decode_thread();
359                                 else
360                                         file->stop_video_thread();
361
362                                 int64_t normalized_position = Units::to_int64(position *
363                                         current_edit->asset->frame_rate /
364                                         frame_rate);
365 // printf("VModule::import_frame %d %lld %lld\n", 
366 // __LINE__, 
367 // position, 
368 // normalized_position);
369                                 file->set_layer(current_edit->channel);
370                                 file->set_video_position(normalized_position,
371                                         0);
372                                 asset_w = current_edit->asset->width;
373                                 asset_h = current_edit->asset->height;
374 //printf("VModule::import_frame %d normalized_position=%lld\n", __LINE__, normalized_position);
375                         }
376                         else
377                         {
378                                 if(debug) printf("VModule::import_frame %d\n", __LINE__);
379                                 asset_w = nested_edl->session->output_w;
380                                 asset_h = nested_edl->session->output_h;
381 // Get source position in nested frame rate in direction of playback.
382                                 nested_position = Units::to_int64(position * 
383                                         nested_edl->session->frame_rate / 
384                                         frame_rate);
385                                 if(direction == PLAY_REVERSE)
386                                         nested_position++;
387                         }
388                         
389
390 // Auto scale if required
391                         if(output->get_params()->get("AUTOSCALE", 0))
392                         {
393                                 float autoscale_w = output->get_params()->get("AUTOSCALE_W", 1024);
394                                 float autoscale_h = output->get_params()->get("AUTOSCALE_H", 1024);
395                                 float x_scale = autoscale_w / asset_w;
396                                 float y_scale = autoscale_h / asset_h;
397
398 // Overriding camera
399                                 in_x = 0;
400                                 in_y = 0;
401                                 in_w = asset_w;
402                                 in_h = asset_h;
403
404                                 if(x_scale < y_scale)
405                                 {
406                                         out_w = in_w * x_scale;
407                                         out_h = in_h * x_scale;
408                                 }
409                                 else
410                                 {
411                                         out_w = in_w * y_scale;
412                                         out_h = in_h * y_scale;
413                                 }
414
415                                 out_x = track->track_w / 2 - out_w / 2;
416                                 out_y = track->track_h / 2 - out_h / 2;
417                         }
418                         else
419 // Apply camera
420                         {
421                                 ((VTrack*)track)->calculate_input_transfer(asset_w, 
422                                         asset_h,
423                                         input_position_project, 
424                                         direction, 
425                                         in_x, 
426                                         in_y, 
427                                         in_w, 
428                                         in_h,
429                                         out_x, 
430                                         out_y, 
431                                         out_w, 
432                                         out_h);
433                         }
434
435 // printf("VModule::import_frame %d %f %d %f %d\n", 
436 // __LINE__,
437 // in_w, 
438 // asset_w,
439 // in_h,
440 // asset_h);
441
442 // file -> temp -> output
443                         if( !EQUIV(in_x, 0) || 
444                                 !EQUIV(in_y, 0) || 
445                                 !EQUIV(in_w, track->track_w) || 
446                                 !EQUIV(in_h, track->track_h) || 
447                                 !EQUIV(out_x, 0) ||
448                                 !EQUIV(out_y, 0) ||
449                                 !EQUIV(out_w, track->track_w) ||
450                                 !EQUIV(out_h, track->track_h) ||
451                                 !EQUIV(in_w, asset_w) ||
452                                 !EQUIV(in_h, asset_h))
453                         {
454                                 if(debug) printf("VModule::import_frame %d file -> temp -> output\n", __LINE__);
455
456
457
458
459 // Get temporary input buffer
460                                 VFrame **input = 0;
461 // Realtime playback
462                                 if(commonrender)
463                                 {
464                                         VRender *vrender = (VRender*)commonrender;
465 //printf("VModule::import_frame %d vrender->input_temp=%p\n", __LINE__, vrender->input_temp);
466                                         input = &vrender->input_temp;
467                                 }
468                                 else
469 // Menu effect
470                                 {
471                                         input = &input_temp;
472                                 }
473
474
475                                 if((*input) && 
476                                         ((*input)->get_w() != asset_w ||
477                                         (*input)->get_h() != asset_h))
478                                 {
479                                         delete (*input);
480                                         (*input) = 0;
481                                 }
482
483
484
485
486
487                                 if(!(*input))
488                                 {
489                                         (*input) = new VFrame(0,
490                                                 -1,
491                                                 asset_w,
492                                                 asset_h,
493                                                 get_edl()->session->color_model,
494                                                 -1);
495                                 }
496
497
498
499                                 (*input)->copy_stacks(output);
500
501 // file -> temp
502 // Cache for single frame only
503                                 if(file)
504                                 {
505                                         if(debug) printf("VModule::import_frame %d this=%p file=%s\n", 
506                                                 __LINE__, 
507                                                 this,
508                                                 current_edit->asset->path);
509                                         if(use_cache) file->set_cache_frames(1);
510                                         result = file->read_frame((*input));
511                                         if(use_cache) file->set_cache_frames(0);
512                                         (*input)->set_opengl_state(VFrame::RAM);
513                                 }
514                                 else
515                                 if(nested_edl)
516                                 {
517 // If the colormodels differ, change input to nested colormodel
518                                         int nested_cmodel = nested_renderengine->get_edl()->session->color_model;
519                                         int current_cmodel = output->get_color_model();
520                                         int output_w = output->get_w();
521                                         int output_h = output->get_h();
522                                         VFrame *input2 = (*input);
523
524                                         if(nested_cmodel != current_cmodel)
525                                         {
526 // If opengl, input -> input -> output
527                                                 if(use_opengl)
528                                                 {
529                                                 }
530                                                 else
531                                                 {
532 // If software, input2 -> input -> output
533 // Use output as a temporary.
534                                                         input2 = output;
535                                                 }
536
537                                                 if(debug) printf("VModule::import_frame %d this=%p nested_cmodel=%d\n", 
538                                                         __LINE__,
539                                                         this,
540                                                         nested_cmodel);
541                                                 input2->dump();
542                                                 input2->reallocate(0, 
543                                                         -1,
544                                                         0,
545                                                         0,
546                                                         0,
547                                                         (*input)->get_w(), 
548                                                         (*input)->get_h(), 
549                                                         nested_cmodel, 
550                                                         -1);
551                                                 input2->dump();
552                                         }
553
554
555                                         if(debug) printf("VModule::import_frame %d this=%p nested_edl=%s input2=%p\n", 
556                                                 __LINE__,
557                                                 this,
558                                                 nested_edl->path,
559                                                 input2);
560
561                                         result = nested_renderengine->vrender->process_buffer(
562                                                 input2, 
563                                                 nested_position,
564                                                 use_opengl);
565
566                                         if(debug) printf("VModule::import_frame %d this=%p nested_edl=%s\n", 
567                                                 __LINE__,
568                                                 this,
569                                                 nested_edl->path);
570
571                                         if(nested_cmodel != current_cmodel)
572                                         {
573                                                 if(debug) printf("VModule::import_frame %d\n", __LINE__);
574                                                 if(use_opengl)
575                                                 {
576 // Change colormodel in hardware.
577                                                         if(debug) printf("VModule::import_frame %d\n", __LINE__);
578                                                         x11_device->convert_cmodel(input2, 
579                                                                 current_cmodel);
580
581 // The converted color model is now in hardware, so return the input2 buffer
582 // to the expected color model.
583                                                         input2->reallocate(0, 
584                                                                 -1,
585                                                                 0,
586                                                                 0,
587                                                                 0,
588                                                                 (*input)->get_w(), 
589                                                                 (*input)->get_h(), 
590                                                                 current_cmodel, 
591                                                                 -1);
592                                                 }
593                                                 else
594                                                 {
595 // Transfer from input2 to input
596 if(debug) printf("VModule::import_frame %d nested_cmodel=%d current_cmodel=%d input2=%p input=%p output=%p\n", 
597 __LINE__, 
598 nested_cmodel,
599 current_cmodel,
600 input2, 
601 (*input),
602 output);
603                                                         BC_CModels::transfer((*input)->get_rows(),
604                                                                 input2->get_rows(),
605                                                                 0,
606                                                                 0,
607                                                                 0,
608                                                                 0,
609                                                                 0,
610                                                                 0,
611                                                                 0,
612                                                                 0,
613                                                             input2->get_w(),
614                                                             input2->get_h(),
615                                                                 0,
616                                                                 0,
617                                                                 (*input)->get_w(),
618                                                                 (*input)->get_h(),
619                                                                 nested_cmodel,
620                                                                 current_cmodel,
621                                                                 0,
622                                                                 input2->get_w(),
623                                                                 (*input)->get_w());
624 //printf("VModule::import_frame %d\n", __LINE__);
625
626 // input2 was the output buffer, so it must be restored
627                                                 input2->reallocate(0, 
628                                                         -1,
629                                                         0,
630                                                         0,
631                                                         0,
632                                                         output_w, 
633                                                         output_h, 
634                                                         current_cmodel, 
635                                                         -1);
636 //printf("VModule::import_frame %d\n", __LINE__);
637                                                 }
638                                         }
639
640                                 }
641
642 // Find an overlayer object to perform the camera transformation
643                                 OverlayFrame *overlayer = 0;
644
645 // OpenGL playback uses hardware
646                                 if(use_opengl)
647                                 {
648 //printf("VModule::import_frame %d\n", __LINE__);
649                                 }
650                                 else
651 // Realtime playback
652                                 if(commonrender)
653                                 {
654                                         VRender *vrender = (VRender*)commonrender;
655                                         overlayer = vrender->overlayer;
656                                 }
657                                 else
658 // Menu effect
659                                 {
660                                         if(!plugin_array)
661                                                 printf("VModule::import_frame neither plugin_array nor commonrender is defined.\n");
662                                         if(!overlay_temp)
663                                         {
664                                                 overlay_temp = new OverlayFrame(plugin_array->mwindow->preferences->processors);
665                                         }
666
667                                         overlayer = overlay_temp;
668                                 }
669 // printf("VModule::import_frame 1 %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", 
670 //      in_x, 
671 //      in_y, 
672 //      in_w, 
673 //      in_h, 
674 //      out_x, 
675 //      out_y, 
676 //      out_w, 
677 //      out_h);
678
679 // temp -> output
680 // for(int j = 0; j < output->get_w() * 3 * 5; j++)
681 //      output->get_rows()[0][j] = 255;
682
683                                 if(use_opengl)
684                                 {
685                                         x11_device->do_camera(output,
686                                                 (*input), 
687                                                 in_x,
688                                                 in_y,
689                                                 in_x + in_w,
690                                                 in_y + in_h,
691                                                 out_x,
692                                                 out_y,
693                                                 out_x + out_w,
694                                                 out_y + out_h);
695 if(debug) printf("VModule::import_frame %d %d %d\n", 
696 __LINE__, 
697 output->get_opengl_state(),
698 (*input)->get_opengl_state());
699                                 }
700                                 else
701                                 {
702
703
704
705                                         output->clear_frame();
706
707
708 // get_cache()->check_in(current_edit->asset);
709 // return;
710
711 // TRANSFER_REPLACE is the fastest transfer mode but it has the disadvantage
712 // of producing green borders in floating point translation of YUV
713                                         int mode = TRANSFER_REPLACE;
714                                         if(get_edl()->session->interpolation_type != NEAREST_NEIGHBOR &&
715                                                 BC_CModels::is_yuv(output->get_color_model()))
716                                                 mode = TRANSFER_NORMAL;
717
718                                         if(debug) printf("VModule::import_frame %d temp -> output\n", __LINE__);
719                                         overlayer->overlay(output,
720                                                 (*input), 
721                                                 in_x,
722                                                 in_y,
723                                                 in_x + in_w,
724                                                 in_y + in_h,
725                                                 out_x,
726                                                 out_y,
727                                                 out_x + out_w,
728                                                 out_y + out_h,
729                                                 1,
730                                                 mode,
731                                                 get_edl()->session->interpolation_type);
732                                 }
733                                 result = 1;
734                                 output->copy_stacks((*input));
735                         }
736                         else
737 // file -> output
738                         {
739                                 if(debug) printf("VModule::import_frame %d file -> output nested_edl=%p file=%p\n", 
740                                         __LINE__,
741                                         nested_edl,
742                                         file);
743                                 if(nested_edl)
744                                 {
745                                         VFrame **input = &output;
746 // If colormodels differ, reallocate output in nested colormodel.
747                                         int nested_cmodel = nested_renderengine->get_edl()->session->color_model;
748                                         int current_cmodel = output->get_color_model();
749
750 if(debug) printf("VModule::import_frame %d nested_cmodel=%d current_cmodel=%d\n", 
751 __LINE__, 
752 nested_cmodel, 
753 current_cmodel);
754
755                                         if(nested_cmodel != current_cmodel)
756                                         {
757                                                 if(use_opengl)
758                                                 {
759                                                 }
760                                                 else
761                                                 {
762                                                         if(commonrender)
763                                                         {
764                                                                 input = &((VRender*)commonrender)->input_temp;
765                                                         }
766                                                         else
767                                                         {
768                                                                 input = &input_temp;
769                                                         }
770
771                                                         if(!(*input)) (*input) = new VFrame;
772                                                 }
773
774                                                 (*input)->reallocate(0,
775                                                         -1,
776                                                         0,
777                                                         0,
778                                                         0,
779                                                         output->get_w(),
780                                                         output->get_h(),
781                                                         nested_cmodel,
782                                                         -1);
783 if(debug) printf("VModule::import_frame %d\n", 
784 __LINE__);
785 //(*input)->dump();
786 //(*input)->clear_frame();
787                                         }
788
789 if(debug) printf("VModule::import_frame %d %p %p\n", 
790 __LINE__,
791 (*input)->get_rows(),
792 (*input));
793                                         result = nested_renderengine->vrender->process_buffer(
794                                                 (*input), 
795                                                 nested_position,
796                                                 use_opengl);
797 if(debug) printf("VModule::import_frame %d\n", 
798 __LINE__);
799
800 // If colormodels differ, change colormodels in opengl if possible.
801 // Swap output for temp if not possible.
802                                         if(nested_cmodel != current_cmodel)
803                                         {
804                                                 if(use_opengl)
805                                                 {
806                                                         x11_device->convert_cmodel(output, 
807                                                                 current_cmodel);
808
809 // The color model was changed in place, so return output buffer
810                                                         output->reallocate(0, 
811                                                                 -1,
812                                                                 0,
813                                                                 0,
814                                                                 0,
815                                                                 output->get_w(), 
816                                                                 output->get_h(), 
817                                                                 current_cmodel, 
818                                                                 -1);
819                                                 }
820                                                 else
821                                                 {
822 // Transfer from temporary to output
823 if(debug) printf("VModule::import_frame %d %d %d %d %d %d %d\n", 
824 __LINE__,
825 (*input)->get_w(),
826 (*input)->get_h(),
827 output->get_w(),
828 output->get_h(),
829 nested_cmodel,
830 current_cmodel);
831                                                         BC_CModels::transfer(output->get_rows(),
832                                                                 (*input)->get_rows(),
833                                                                 0,
834                                                                 0,
835                                                                 0,
836                                                                 0,
837                                                                 0,
838                                                                 0,
839                                                                 0,
840                                                                 0,
841                                                                 (*input)->get_w(),
842                                                                 (*input)->get_h(),
843                                                                 0,
844                                                                 0,
845                                                                 output->get_w(),
846                                                                 output->get_h(),
847                                                                 nested_cmodel,
848                                                                 current_cmodel,
849                                                                 0,
850                                                                 (*input)->get_w(),
851                                                                 output->get_w());
852                                                 }
853
854                                         }
855                                         
856                                 }
857                                 else
858                                 if(file)
859                                 {
860 // Cache single frames
861 //memset(output->get_rows()[0], 0xff, 1024);
862                                         if(use_cache) file->set_cache_frames(1);
863                                         result = file->read_frame(output);
864                                         if(use_cache) file->set_cache_frames(0);
865                                         output->set_opengl_state(VFrame::RAM);
866                                 }
867                         }
868
869                         if(file)
870                         {
871                                 get_cache()->check_in(current_edit->asset);
872                                 file = 0;
873                         }
874                 }
875                 else
876 // Source not found
877                 {
878                         if(debug) printf("VModule::import_frame %d\n", __LINE__);
879                         if(use_opengl)
880                         {
881                                 x11_device->clear_input(output);
882                         }
883                         else
884                         {
885                                 output->clear_frame();
886                         }
887                         result = 1;
888                 }
889         }
890         else
891 // Source is silence
892         {
893                 if(debug) printf("VModule::import_frame %d\n", __LINE__);
894                 if(use_opengl)
895                 {
896                         x11_device->clear_input(output);
897                 }
898                 else
899                 {
900                         output->clear_frame();
901                 }
902         }
903
904         if(debug) printf("VModule::import_frame %d done\n", __LINE__);
905
906         return result;
907 }
908
909
910
911 int VModule::render(VFrame *output,
912         int64_t start_position,
913         int direction,
914         double frame_rate,
915         int use_nudge,
916         int debug_render,
917         int use_opengl)
918 {
919         int result = 0;
920         double edl_rate = get_edl()->session->frame_rate;
921
922 //printf("VModule::render %d %ld\n", __LINE__, start_position);
923
924         if(use_nudge) start_position += Units::to_int64(track->nudge * 
925                 frame_rate / 
926                 edl_rate);
927
928         int64_t start_position_project = Units::to_int64(start_position *
929                 edl_rate /
930                 frame_rate + 
931                 0.5);
932
933         update_transition(start_position_project, 
934                 direction);
935
936         VEdit* current_edit = (VEdit*)track->edits->editof(start_position_project, 
937                 direction,
938                 0);
939         VEdit* previous_edit = 0;
940 //printf("VModule::render %d %p %ld %d\n", __LINE__, current_edit, start_position_project, direction);
941
942         if(debug_render)
943                 printf("    VModule::render %d %d %ld %s transition=%p opengl=%d current_edit=%p output=%p\n", 
944                         __LINE__, 
945                         use_nudge, 
946                         start_position_project,
947                         track->title,
948                         transition,
949                         use_opengl,
950                         current_edit,
951                         output);
952
953         if(!current_edit)
954         {
955                 output->clear_frame();
956                 return 0;
957         }
958
959
960
961
962 // Process transition
963         if(transition && transition->on)
964         {
965
966 // Get temporary buffer
967                 VFrame **transition_input = 0;
968                 if(commonrender)
969                 {
970                         VRender *vrender = (VRender*)commonrender;
971                         transition_input = &vrender->transition_temp;
972                 }
973                 else
974                 {
975                         transition_input = &transition_temp;
976                 }
977
978                 if((*transition_input) &&
979                         ((*transition_input)->get_w() != track->track_w ||
980                         (*transition_input)->get_h() != track->track_h))
981                 {
982                         delete (*transition_input);
983                         (*transition_input) = 0;
984                 }
985
986 // Load incoming frame
987                 if(!(*transition_input))
988                 {
989                         (*transition_input) = new VFrame(0,
990                                 -1,
991                                 track->track_w,
992                                 track->track_h,
993                                 get_edl()->session->color_model,
994                                 -1);
995                 }
996                 
997                 (*transition_input)->copy_stacks(output);
998
999 //printf("VModule::render %d\n", __LINE__);
1000                 result = import_frame((*transition_input), 
1001                         current_edit, 
1002                         start_position,
1003                         frame_rate,
1004                         direction,
1005                         use_opengl);
1006
1007
1008 // Load transition buffer
1009                 previous_edit = (VEdit*)current_edit->previous;
1010
1011                 result |= import_frame(output, 
1012                         previous_edit, 
1013                         start_position,
1014                         frame_rate,
1015                         direction,
1016                         use_opengl);
1017 //printf("VModule::render %d\n", __LINE__);
1018
1019 // printf("VModule::render %d %p %p %p %p\n", 
1020 // __LINE__,
1021 // (*transition_input),
1022 // (*transition_input)->get_pbuffer(),
1023 // output,
1024 // output->get_pbuffer());
1025
1026
1027 // Execute plugin with transition_input and output here
1028                 if(renderengine) 
1029                         transition_server->set_use_opengl(use_opengl, renderengine->video);
1030                 transition_server->process_transition((*transition_input), 
1031                         output,
1032                         (direction == PLAY_FORWARD) ? 
1033                                 (start_position_project - current_edit->startproject) :
1034                                 (start_position_project - current_edit->startproject - 1),
1035                         transition->length);
1036         }
1037         else
1038         {
1039 // Load output buffer
1040                 result = import_frame(output, 
1041                         current_edit, 
1042                         start_position,
1043                         frame_rate,
1044                         direction,
1045                         use_opengl);
1046         }
1047
1048
1049         return result;
1050 }
1051
1052
1053
1054
1055
1056
1057 void VModule::create_objects()
1058 {
1059         Module::create_objects();
1060 }
1061
1062
1063
1064
1065
1066