8cd64fe67f9ce485e7fe6b704c5c593daac2c5da
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / vdevicex11.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008-2017 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 "assets.h"
23 #include "autos.h"
24 #include "bccapture.h"
25 #include "bccmodels.h"
26 #include "bcsignals.h"
27 #include "canvas.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "file.h"
31 #include "maskauto.h"
32 #include "maskautos.h"
33 #include "mwindow.h"
34 #include "mwindowgui.h"
35 #include "playback3d.h"
36 #include "playbackconfig.h"
37 #include "preferences.h"
38 #include "recordconfig.h"
39 #include "strategies.inc"
40 #include "vdevicex11.h"
41 #include "vframe.h"
42 #include "videodevice.h"
43 #include "videowindow.h"
44 #include "videowindowgui.h"
45
46 #include <string.h>
47 #include <unistd.h>
48
49 VDeviceX11::VDeviceX11(VideoDevice *device, Canvas *output)
50  : VDeviceBase(device)
51 {
52         reset_parameters();
53         this->output = output;
54 }
55
56 VDeviceX11::~VDeviceX11()
57 {
58         close_all();
59 }
60
61 int VDeviceX11::reset_parameters()
62 {
63         output_frame = 0;
64         window_id = 0;
65         bitmap = 0;
66         bitmap_type = 0;
67         bitmap_w = 0;
68         bitmap_h = 0;
69         output_x1 = 0;
70         output_y1 = 0;
71         output_x2 = 0;
72         output_y2 = 0;
73         canvas_x1 = 0;
74         canvas_y1 = 0;
75         canvas_x2 = 0;
76         canvas_y2 = 0;
77         capture_bitmap = 0;
78         color_model_selected = 0;
79         is_cleared = 0;
80         return 0;
81 }
82
83 int VDeviceX11::open_input()
84 {
85 //printf("VDeviceX11::open_input 1\n");
86         capture_bitmap = new BC_Capture(device->in_config->w,
87                 device->in_config->h,
88                 device->in_config->screencapture_display);
89 //printf("VDeviceX11::open_input 2\n");
90         capture_bitmap->bars_on(SCREENCAP_PIXELS, SCREENCAP_COLOR,
91                 device->input_x, device->input_y,
92                 device->in_config->w, device->in_config->h);
93
94         return 0;
95 }
96
97 int VDeviceX11::open_output()
98 {
99         if( output ) {
100                 output->lock_canvas("VDeviceX11::open_output");
101                 output->get_canvas()->lock_window("VDeviceX11::open_output");
102                 if( !device->single_frame )
103                         output->start_video();
104                 else
105                         output->start_single();
106                 output->get_canvas()->unlock_window();
107
108 // Enable opengl in the first routine that needs it, to reduce the complexity.
109                 output->unlock_canvas();
110         }
111         return 0;
112 }
113
114
115 int VDeviceX11::output_visible()
116 {
117         if( !output ) return 0;
118
119         output->lock_canvas("VDeviceX11::output_visible");
120         if( output->get_canvas()->get_hidden() ) {
121                 output->unlock_canvas();
122                 return 0;
123         }
124         else {
125                 output->unlock_canvas();
126                 return 1;
127         }
128 }
129
130
131 int VDeviceX11::close_all()
132 {
133         if( output ) {
134                 output->lock_canvas("VDeviceX11::close_all 1");
135                 output->get_canvas()->lock_window("VDeviceX11::close_all 1");
136                 int video_on = output->get_canvas()->get_video_on();
137 // Update the status bug
138                 if( !device->single_frame ) {
139                         output->stop_video();
140                 }
141                 else {
142                         output->stop_single();
143                 }
144                 if( output_frame ) {
145                         output->update_refresh(device, output_frame);
146 // if the last frame is good, don't draw over it
147                         if( !video_on || output->need_overlays() ) {
148                                 output->unlock_canvas();
149                                 output->draw_refresh(1);
150                                 output->lock_canvas("VDeviceX11::close_all 2");
151                         }
152                 }
153         }
154
155         delete bitmap;          bitmap = 0;
156         delete output_frame;    output_frame = 0;
157         delete capture_bitmap;  capture_bitmap = 0;
158
159         if( output ) {
160                 output->get_canvas()->unlock_window();
161                 output->unlock_canvas();
162         }
163
164         reset_parameters();
165
166         return 0;
167 }
168
169 int VDeviceX11::read_buffer(VFrame *frame)
170 {
171         capture_bitmap->bars_reposition(
172                 device->input_x, device->input_y,
173                 device->in_config->w, device->in_config->h);
174
175         capture_bitmap->capture_frame(frame,
176                 device->input_x, device->input_y, device->do_cursor);
177         return 0;
178 }
179
180
181 int VDeviceX11::get_best_colormodel(Asset *asset)
182 {
183         return File::get_best_colormodel(asset, SCREENCAPTURE);
184 //      return BC_RGB888;
185 }
186
187
188 int VDeviceX11::get_display_colormodel(int file_colormodel)
189 {
190         int result = -1;
191
192         if( device->out_config->driver == PLAYBACK_X11_GL ) {
193                 if( file_colormodel == BC_RGB888 ||
194                     file_colormodel == BC_RGBA8888 ||
195                     file_colormodel == BC_YUV888 ||
196                     file_colormodel == BC_YUVA8888 ||
197                     file_colormodel == BC_RGB_FLOAT ||
198                     file_colormodel == BC_RGBA_FLOAT ) {
199                         return file_colormodel;
200                 }
201
202                 return BC_RGB888;
203         }
204
205         if( !device->single_frame ) {
206                 switch( file_colormodel ) {
207                 case BC_YUV420P:
208                 case BC_YUV422P:
209                 case BC_YUV422:
210                         result = file_colormodel;
211                         break;
212                 }
213         }
214
215         if( result < 0 ) {
216                 switch( file_colormodel ) {
217                 case BC_RGB888:
218                 case BC_RGBA8888:
219                 case BC_YUV888:
220                 case BC_YUVA8888:
221                 case BC_RGB_FLOAT:
222                 case BC_RGBA_FLOAT:
223                         result = file_colormodel;
224                         break;
225
226                 default:
227                         output->lock_canvas("VDeviceX11::get_display_colormodel");
228                         result = output->get_canvas()->get_color_model();
229                         output->unlock_canvas();
230                         break;
231                 }
232         }
233
234         return result;
235 }
236
237
238 void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *edl)
239 {
240 // printf("VDeviceX11::new_output_buffer %d hardware_scaling=%d\n",
241 // __LINE__, bitmap ? bitmap->hardware_scaling() : 0);
242         output->lock_canvas("VDeviceX11::new_output_buffer");
243         output->get_canvas()->lock_window("VDeviceX11::new_output_buffer 1");
244
245 // Get the best colormodel the display can handle.
246         int display_colormodel = get_display_colormodel(file_colormodel);
247
248 //printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n",
249 // __LINE__, file_colormodel, display_colormodel);
250 // Only create OpenGL Pbuffer and texture.
251         if( device->out_config->driver == PLAYBACK_X11_GL ) {
252 // Create bitmap for initial load into texture.
253 // Not necessary to do through Playback3D.....yet
254                 if( !output_frame ) {
255                         output_frame = new VFrame(device->out_w, device->out_h, file_colormodel);
256                 }
257
258                 window_id = output->get_canvas()->get_id();
259                 output_frame->set_opengl_state(VFrame::RAM);
260         }
261         else {
262                 output->get_transfers(edl,
263                         output_x1, output_y1, output_x2, output_y2,
264                         canvas_x1, canvas_y1, canvas_x2, canvas_y2,
265 // Canvas may be a different size than the temporary bitmap for pure software
266                         -1, -1);
267                 canvas_w = canvas_x2 - canvas_x1;
268                 canvas_h = canvas_y2 - canvas_y1;
269 // can the direct frame be used?
270                 int direct_supported =
271                         device->out_config->use_direct_x11 &&
272                         !output->xscroll && !output->yscroll &&
273                         output_x1 == 0 && output_x2 == device->out_w &&
274                         output_y1 == 0 && output_y2 == device->out_h;
275
276 // file wants direct frame but we need a temp
277                 if( !direct_supported && file_colormodel == BC_BGR8888 )
278                         file_colormodel = BC_RGB888;
279
280 // Conform existing bitmap to new colormodel and output size
281                 if( bitmap ) {
282 // printf("VDeviceX11::new_output_buffer %d bitmap=%dx%d canvas=%dx%d canvas=%dx%d\n",
283 // __LINE__, bitmap->get_w(), bitmap->get_h(), canvas_w, canvas_h,);
284                         int size_change = (
285                                 bitmap->get_w() != canvas_w ||
286                                 bitmap->get_h() != canvas_h );
287
288 // Restart if output size changed or output colormodel changed.
289 // May have to recreate if transferring between windowed and fullscreen.
290                         if( !color_model_selected ||
291                             file_colormodel != output_frame->get_color_model() ||
292                             (!bitmap->hardware_scaling() && size_change) ) {
293 //printf("VDeviceX11::new_output_buffer %d file_colormodel=%d prev "
294 // "file_colormodel=%d bitmap=%p output_frame=%p\n", __LINE__,
295 // file_colormodel, output_frame->get_color_model(), bitmap, output_frame);
296                                 delete bitmap;        bitmap = 0;
297                                 delete output_frame;  output_frame = 0;
298 // Clear borders if size changed
299                                 if( size_change ) {
300 //printf("VDeviceX11::new_output_buffer %d w=%d h=%d "
301 // "canvas_x1=%d canvas_y1=%d canvas_x2=%d canvas_y2=%d\n",
302 // __LINE__, // (int)output->w, (int)output->h,
303 // (int)canvas_x1, (int)canvas_y1, (int)canvas_x2, (int)canvas_y2);
304                                         output->get_canvas()->set_color(BLACK);
305
306                                         if( canvas_y1 > 0 ) {
307                                                 output->get_canvas()->draw_box(0, 0, output->w, canvas_y1);
308                                                 output->get_canvas()->flash(0, 0, output->w, canvas_y1);
309                                         }
310
311                                         if( canvas_y2 < output->h ) {
312                                                 output->get_canvas()->draw_box(0, canvas_y2, output->w, output->h - canvas_y2);
313                                                 output->get_canvas()->flash(0, canvas_y2, output->w, output->h - canvas_y2);
314                                         }
315
316                                         if( canvas_x1 > 0 ) {
317                                                 output->get_canvas()->draw_box(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1);
318                                                 output->get_canvas()->flash(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1);
319                                         }
320
321                                         if( canvas_x2 < output->w ) {
322                                                 output->get_canvas()->draw_box(canvas_x2, canvas_y1,
323                                                         output->w - canvas_x2, canvas_y2 - canvas_y1);
324                                                 output->get_canvas()->flash(canvas_x2, canvas_y1,
325                                                         output->w - canvas_x2, canvas_y2 - canvas_y1);
326                                         }
327                                 }
328                         }
329                 }
330
331 // Create new bitmap
332                 if( !bitmap ) {
333                         int use_direct = 0;
334                         bitmap_type = BITMAP_TEMP;
335 //printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n",
336 // __LINE__, file_colormodel, display_colormodel);
337
338 // Try hardware accelerated
339                         switch( display_colormodel ) {
340 // blit from the codec directly to the window, using the standard X11 color model.
341 // Must scale in the codec.  No cropping
342                         case BC_BGR8888:
343                                 if( direct_supported ) {
344                                         bitmap_type = BITMAP_PRIMARY;
345                                         use_direct = 1;
346                                 }
347                                 break;
348
349                         case BC_YUV420P:
350                                 if( device->out_config->driver == PLAYBACK_X11_XV &&
351                                     output->get_canvas()->accel_available(display_colormodel, 0) &&
352                                     !output->use_scrollbars )
353                                         bitmap_type = BITMAP_PRIMARY;
354                                 break;
355
356                         case BC_YUV422P:
357                                 if( device->out_config->driver == PLAYBACK_X11_XV &&
358                                     output->get_canvas()->accel_available(display_colormodel, 0) &&
359                                     !output->use_scrollbars )
360                                         bitmap_type = BITMAP_PRIMARY;
361                                 else if( device->out_config->driver == PLAYBACK_X11_XV &&
362                                     output->get_canvas()->accel_available(BC_YUV422, 0) ) {
363                                         bitmap = new BC_Bitmap(output->get_canvas(),
364                                                 device->out_w, device->out_h, BC_YUV422, 1);
365                                 }
366                                 break;
367
368                         case BC_YUV422:
369                                 if( device->out_config->driver == PLAYBACK_X11_XV &&
370                                     output->get_canvas()->accel_available(display_colormodel, 0) &&
371                                     !output->use_scrollbars ) {
372                                         bitmap_type = BITMAP_PRIMARY;
373                                 }
374                                 else if( device->out_config->driver == PLAYBACK_X11_XV &&
375                                     output->get_canvas()->accel_available(BC_YUV422P, 0) ) {
376                                         bitmap = new BC_Bitmap(output->get_canvas(),
377                                                 device->out_w, device->out_h, BC_YUV422P, 1);
378                                 }
379                                 break;
380                         }
381                         if( bitmap_type == BITMAP_PRIMARY ) {
382                                 int bitmap_w = use_direct ? canvas_w : device->out_w;
383                                 int bitmap_h = use_direct ? canvas_h : device->out_h;
384                                 bitmap = new BC_Bitmap(output->get_canvas(),
385                                         bitmap_w, bitmap_h,  display_colormodel, -1);
386                                 output_frame = new VFrame(bitmap,
387                                         bitmap_w, bitmap_h, display_colormodel, -1);
388                         }
389 // Make an intermediate frame
390                         if( !bitmap ) {
391                                 display_colormodel = output->get_canvas()->get_color_model();
392 // printf("VDeviceX11::new_output_buffer %d creating temp display_colormodel=%d "
393 // "file_colormodel=%d %dx%d %dx%d %dx%d\n", __LINE__,
394 // display_colormodel, file_colormodel, device->out_w, device->out_h,
395 // output->get_canvas()->get_w(), output->get_canvas()->get_h(), canvas_w, canvas_h);
396                                 bitmap = new BC_Bitmap(output->get_canvas(),
397                                         canvas_w, canvas_h, display_colormodel, 1);
398                                 bitmap_type = BITMAP_TEMP;
399                         }
400
401                         if( bitmap_type == BITMAP_TEMP ) {
402 // Intermediate frame
403 //printf("VDeviceX11::new_output_buffer %d creating output_frame\n", __LINE__);
404                                 output_frame = new VFrame(device->out_w, device->out_h, file_colormodel);
405                         }
406                         color_model_selected = 1;
407                 }
408                 else if( bitmap_type == BITMAP_PRIMARY ) {
409                         output_frame->set_memory(bitmap);
410                 }
411         }
412
413         *result = output_frame;
414 //printf("VDeviceX11::new_output_buffer 10 %d\n", output->get_canvas()->get_window_lock());
415
416         output->get_canvas()->unlock_window();
417         output->unlock_canvas();
418 }
419
420
421 int VDeviceX11::start_playback()
422 {
423 // Record window is initialized when its monitor starts.
424         if( !device->single_frame )
425                 output->start_video();
426         return 0;
427 }
428
429 int VDeviceX11::stop_playback()
430 {
431         if( !device->single_frame )
432                 output->stop_video();
433 // Record window goes back to monitoring
434 // get the last frame played and store it in the video_out
435         return 0;
436 }
437
438 int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)
439 {
440         output->lock_canvas("VDeviceX11::write_buffer");
441         output->get_canvas()->lock_window("VDeviceX11::write_buffer 1");
442 //      if( device->out_config->driver == PLAYBACK_X11_GL &&
443 //          output_frame->get_color_model() != BC_RGB888 ) {
444 // this is handled by overlay call in virtualvnode, using flatten alpha
445 // invoked when is_nested = -1 is passed to vdevicex11->overlay(...)
446 //      }
447
448 // printf("VDeviceX11::write_buffer %d %d bitmap_type=%d\n",
449 // __LINE__,
450 // output->get_canvas()->get_video_on(),
451 // bitmap_type);
452
453 //      int use_bitmap_extents = 0;
454 //      canvas_w = -1;  canvas_h = -1;
455 // // Canvas may be a different size than the temporary bitmap for pure software
456 //      if( bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling() ) {
457 //              canvas_w = bitmap->get_w();
458 //              canvas_h = bitmap->get_h();
459 //      }
460 //
461 //      output->get_transfers(edl,
462 //              output_x1, output_y1, output_x2, output_y2,
463 //              canvas_x1, canvas_y1, canvas_x2, canvas_y2,
464 //              canvas_w, canvas_h);
465
466 // Convert colormodel
467         if( bitmap_type == BITMAP_TEMP ) {
468 // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n",
469 //   output->w, output->h, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h);
470 // fflush(stdout);
471
472 // printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels);
473 // printf("VDeviceX11::write_buffer %d input color_model=%d output color_model=%d\n",
474 // __LINE__, output_channels->get_color_model(), bitmap->get_color_model());
475                 if( bitmap->hardware_scaling() ) {
476                         BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0,
477                                 output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
478                                 0, 0, output_channels->get_w(), output_channels->get_h(),
479                                 0, 0, bitmap->get_w(), bitmap->get_h(),
480                                 output_channels->get_color_model(), bitmap->get_color_model(),
481                                 -1, output_channels->get_w(), bitmap->get_w());
482                 }
483                 else {
484                         BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(), 0, 0, 0,
485                                 output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
486                                 (int)output_x1, (int)output_y1, (int)(output_x2 - output_x1), (int)(output_y2 - output_y1),
487                                 0, 0, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
488                                 output_channels->get_color_model(), bitmap->get_color_model(),
489                                 -1, output_channels->get_w(), bitmap->get_w());
490                 }
491         }
492
493 //printf("VDeviceX11::write_buffer 4 %p\n", bitmap);
494 //for( i = 0; i < 1000; i += 4 ) bitmap->get_data()[i] = 128;
495 //printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type,
496 //      bitmap->get_color_model(),
497 //      output->get_color_model());fflush(stdout);
498
499 // printf("VDeviceX11::write_buffer %d %dx%d %f %f %f %f -> %f %f %f %f\n",
500 // __LINE__, // output->w, output->h,
501 // output_x1, output_y1, output_x2, output_y2,
502 // canvas_x1, canvas_y1, canvas_x2, canvas_y2);
503
504 // Cause X server to display it
505         if( device->out_config->driver == PLAYBACK_X11_GL ) {
506 // Output is drawn in close_all if no video.
507                 if( output->get_canvas()->get_video_on() ) {
508                         canvas_w = -1;  canvas_h = -1;
509 // Canvas may be a different size than the temporary bitmap for pure software
510                         if( bitmap_type == BITMAP_TEMP &&
511                                 !bitmap->hardware_scaling() ) {
512                                 canvas_w = bitmap->get_w();
513                                 canvas_h = bitmap->get_h();
514                         }
515
516                         output->get_transfers(edl,
517                                 output_x1, output_y1, output_x2, output_y2,
518                                 canvas_x1, canvas_y1, canvas_x2, canvas_y2,
519                                 canvas_w, canvas_h);
520
521 //printf("VDeviceX11::write_buffer %d\n", __LINE__);
522 // Draw output frame directly.  Not used for compositing.
523                         output->get_canvas()->unlock_window();
524                         output->unlock_canvas();
525                         output->mwindow->playback_3d->write_buffer(output, output_frame,
526                                 output_x1, output_y1, output_x2, output_y2,
527                                 canvas_x1, canvas_y1, canvas_x2, canvas_y2,
528                                 is_cleared);
529                         is_cleared = 0;
530                         output->lock_canvas("VDeviceX11::write_buffer 2");
531                         output->get_canvas()->lock_window("VDeviceX11::write_buffer 2");
532                 }
533         }
534         else {
535                 if( bitmap->hardware_scaling() ) {
536                         output->get_canvas()->draw_bitmap(bitmap, !device->single_frame,
537                                 (int)canvas_x1, (int)canvas_y1,
538                                 (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
539                                 (int)output_x1, (int)output_y1,
540                                 (int)(output_x2 - output_x1), (int)(output_y2 - output_y1),
541                                 0);
542                 }
543                 else {
544 //printf("VDeviceX11::write_buffer %d x=%d y=%d w=%d h=%d\n",
545 // __LINE__, (int)canvas_x1, (int)canvas_y1,
546 // output->get_canvas()->get_w(), output->get_canvas()->get_h());
547                         output->get_canvas()->draw_bitmap(bitmap, !device->single_frame,
548                                 (int)canvas_x1, (int)canvas_y1,
549                                 (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
550                                 0, 0,
551                                 (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
552                                 0);
553 //printf("VDeviceX11::write_buffer %d bitmap=%p\n", __LINE__, bitmap);
554                 }
555         }
556
557         output->get_canvas()->unlock_window();
558         output->unlock_canvas();
559         return 0;
560 }
561
562
563 void VDeviceX11::clear_output()
564 {
565         is_cleared = 1;
566         output->mwindow->playback_3d->clear_output(output, 0);
567         output->mwindow->playback_3d->clear_output(output, output_frame);
568 }
569
570
571 void VDeviceX11::clear_input(VFrame *frame)
572 {
573         this->output->mwindow->playback_3d->clear_input(this->output, frame);
574 }
575
576 void VDeviceX11::convert_cmodel(VFrame *output, int dst_cmodel)
577 {
578         this->output->mwindow->playback_3d->convert_cmodel(this->output,
579                 output, 
580                 dst_cmodel);
581 }
582
583 void VDeviceX11::do_camera(VFrame *output, VFrame *input,
584         float in_x1, float in_y1, float in_x2, float in_y2,
585         float out_x1, float out_y1, float out_x2, float out_y2)
586 {
587         this->output->mwindow->playback_3d->do_camera(this->output,
588                 output, input,
589                 in_x1, in_y1, in_x2, in_y2,
590                 out_x1, out_y1, out_x2, out_y2);
591 }
592
593
594 void VDeviceX11::do_fade(VFrame *output_temp, float fade)
595 {
596         this->output->mwindow->playback_3d->do_fade(this->output, output_temp, fade);
597 }
598
599 bool VDeviceX11::can_mask(int64_t start_position_project, MaskAutos *keyframe_set)
600 {
601         Auto *current = 0;
602         MaskAuto *keyframe = (MaskAuto*)keyframe_set->
603                 get_prev_auto(start_position_project, PLAY_FORWARD, current);
604         return keyframe->disable_opengl_masking ? 0 : 1;
605 }
606
607 void VDeviceX11::do_mask(VFrame *output_temp, int64_t start_position_project,
608                 MaskAutos *keyframe_set, MaskAuto *keyframe, MaskAuto *default_auto)
609 {
610         this->output->mwindow->playback_3d->do_mask(output, output_temp,
611                 start_position_project, keyframe_set, keyframe, default_auto);
612 }
613
614 void VDeviceX11::overlay(VFrame *output_frame, VFrame *input,
615                 float in_x1, float in_y1, float in_x2, float in_y2,
616                 float out_x1, float out_y1, float out_x2, float out_y2,
617                 float alpha, int mode, EDL *edl, int is_nested)
618 {
619         int interpolation_type = edl->session->interpolation_type;
620         output->mwindow->playback_3d->overlay(output, input,
621                 in_x1, in_y1, in_x2, in_y2,
622                 out_x1, out_y1, out_x2, out_y2, alpha, // 0 - 1
623                 mode, interpolation_type, output_frame, is_nested);
624 }
625
626 void VDeviceX11::run_plugin(PluginClient *client)
627 {
628         output->mwindow->playback_3d->run_plugin(output, client);
629 }
630
631 void VDeviceX11::copy_frame(VFrame *dst, VFrame *src)
632 {
633         output->mwindow->playback_3d->copy_from(output, dst, src, 1);
634 }
635