add threads param to ffmpeg plugins, spec fix, added m2t ext
[goodguy/history.git] / cinelerra-5.1 / cinelerra / vdevicex11.C
index e1b5c2a91dbc0112ce2f1a714be9b8816a265517..31873e6a4c1b79d7687cc8231f27798baf5e64c5 100644 (file)
  */
 
 #include "assets.h"
+#include "auto.h"
 #include "bccapture.h"
 #include "bcsignals.h"
 #include "canvas.h"
 #include "bccmodels.h"
 #include "edl.h"
 #include "edlsession.h"
+#include "maskautos.h"
+#include "maskauto.h"
 #include "mwindow.h"
 #include "playback3d.h"
 #include "playbackconfig.h"
@@ -134,64 +137,8 @@ int VDeviceX11::close_all()
 
        if(output && output_frame)
        {
-// Copy our output frame buffer to the canvas's permanent frame buffer.
-// They must be different buffers because the output frame is being written
-// while the user is redrawing the canvas frame buffer over and over.
-
-               int use_opengl = device->out_config->driver == PLAYBACK_X11_GL &&
-                       output_frame->get_opengl_state() == VFrame::SCREEN;
-               int best_color_model = output_frame->get_color_model();
-
-// OpenGL does YUV->RGB in the compositing step
-               if(use_opengl)
-                       best_color_model = BC_RGB888;
-
-               if(output->refresh_frame &&
-                       (output->refresh_frame->get_w() != device->out_w ||
-                       output->refresh_frame->get_h() != device->out_h ||
-                       output->refresh_frame->get_color_model() != best_color_model))
-               {
-                       delete output->refresh_frame;
-                       output->refresh_frame = 0;
-               }
-
-               if(!output->refresh_frame)
-               {
-                       output->refresh_frame = new VFrame(0, -1,
-                               device->out_w, device->out_h,
-                               best_color_model, -1);
-               }
-
-               if(use_opengl)
-               {
-                       output->get_canvas()->unlock_window();
-                       output->unlock_canvas();
-
-                       output->mwindow->playback_3d->copy_from(output,
-                               output->refresh_frame, output_frame, 0);
-                       output->lock_canvas("VDeviceX11::close_all 2");
-                       output->get_canvas()->lock_window("VDeviceX11::close_all 2");
-               }
-               else
-                       output->refresh_frame->copy_from(output_frame);
-
-// // Update the status bug
-//             if(!device->single_frame)
-//             {
-//                     output->stop_video();
-//             }
-//             else
-//             {
-//                     output->stop_single();
-//             }
-
-// Draw the first refresh with new frame.
-// Doesn't work if video and openGL because OpenGL doesn't have
-// the output buffer for video.
-// Not necessary for any case if we mandate a frame advance after
-// every stop.
-               if(/* device->out_config->driver != PLAYBACK_X11_GL ||
-                       */ device->single_frame)
+               output->update_refresh(device, output_frame);
+               if( device->single_frame )
                        output->draw_refresh();
        }
 
@@ -318,153 +265,102 @@ void VDeviceX11::new_output_buffer(VFrame **result, int colormodel)
        int best_colormodel = get_best_colormodel(colormodel);
 
 // Only create OpenGL Pbuffer and texture.
-       if(device->out_config->driver == PLAYBACK_X11_GL)
-       {
+       if( device->out_config->driver == PLAYBACK_X11_GL ) {
 // Create bitmap for initial load into texture.
 // Not necessary to do through Playback3D.....yet
-               if(!output_frame)
-               {
+               if( !output_frame ) {
                        output_frame = new VFrame(0, -1,
-                               device->out_w, device->out_h,
-                               colormodel, -1);
+                               device->out_w, device->out_h, colormodel, -1);
 //BUFFER2(output_frame->get_rows()[0], "VDeviceX11::new_output_buffer 1");
                }
 
                window_id = output->get_canvas()->get_id();
                output_frame->set_opengl_state(VFrame::RAM);
        }
-       else
-       {
+       else {
 // Conform existing bitmap to new colormodel and output size
-               if(bitmap)
-               {
+               if( bitmap ) {
 // Restart if output size changed or output colormodel changed.
 // May have to recreate if transferring between windowed and fullscreen.
-                       if(!color_model_selected ||
-                               (!bitmap->hardware_scaling() &&
-                                       (bitmap->get_w() != output->get_canvas()->get_w() ||
-                                       bitmap->get_h() != output->get_canvas()->get_h())) ||
-                               colormodel != output_frame->get_color_model())
-                       {
-                               int size_change = (bitmap->get_w() != output->get_canvas()->get_w() ||
-                                       bitmap->get_h() != output->get_canvas()->get_h());
+                       if( !color_model_selected || ( !bitmap->hardware_scaling() &&
+                               (bitmap->get_w() != output->get_canvas()->get_w() ||
+                                bitmap->get_h() != output->get_canvas()->get_h()) ) ||
+                           colormodel != output_frame->get_color_model() ) {
+                               int size_change =
+                                       bitmap->get_w() != output->get_canvas()->get_w() ||
+                                       bitmap->get_h() != output->get_canvas()->get_h();
 //printf("VDeviceX11::new_output_buffer %d\n", __LINE__);
-                               delete bitmap;
-                               delete output_frame;
-                               bitmap = 0;
-                               output_frame = 0;
+                               delete bitmap;        bitmap = 0;
+                               delete output_frame;  output_frame = 0;
 
 // Blank only if size changed
-                               if(size_change)
-                               {
+                               if( size_change ) {
                                        output->get_canvas()->set_color(BLACK);
                                        output->get_canvas()->draw_box(0, 0, output->w, output->h);
                                        output->get_canvas()->flash();
                                }
                        }
-                       else
-// Update the ring buffer
-                       if(bitmap_type == BITMAP_PRIMARY)
-                       {
-//printf("VDeviceX11::new_output_buffer %d\n", __LINE__);
-                               output_frame->set_memory(bitmap);
-                       }
                }
 
 // Create new bitmap
-               if(!bitmap)
-               {
+               if( !bitmap ) {
 // Try hardware accelerated
-                       switch(best_colormodel)
-                       {
-                               case BC_YUV420P:
-                                       if(device->out_config->driver == PLAYBACK_X11_XV &&
-                                               output->get_canvas()->accel_available(best_colormodel, 0) &&
-                                               !output->use_scrollbars)
-                                       {
-                                               bitmap = new BC_Bitmap(output->get_canvas(),
-                                                       device->out_w, device->out_h,
-                                                       best_colormodel, 1);
-                                               output_frame = new VFrame(bitmap,
-                                                       device->out_w, device->out_h,
-                                                       best_colormodel, -1);
-                                               bitmap_type = BITMAP_PRIMARY;
-                                       }
-                                       break;
-
-                               case BC_YUV422P:
-                                       if(device->out_config->driver == PLAYBACK_X11_XV &&
-                                               output->get_canvas()->accel_available(best_colormodel, 0) &&
-                                               !output->use_scrollbars)
-                                       {
-                                               bitmap = new BC_Bitmap(output->get_canvas(),
-                                                       device->out_w, device->out_h,
-                                                       best_colormodel, 1);
-                                               output_frame = new VFrame(bitmap,
-                                                       device->out_w, device->out_h,
-                                                       best_colormodel, -1);
-                                               bitmap_type = BITMAP_PRIMARY;
-                                       }
-                                       else
-                                       if(device->out_config->driver == PLAYBACK_X11_XV &&
-                                               output->get_canvas()->accel_available(BC_YUV422, 0))
-                                       {
-                                               bitmap = new BC_Bitmap(output->get_canvas(),
-                                                       device->out_w,
-                                                       device->out_h,
-                                                       BC_YUV422,
-                                                       1);
-                                               bitmap_type = BITMAP_TEMP;
-                                       }
-                                       break;
-
-                               case BC_YUV422:
-                                       if(device->out_config->driver == PLAYBACK_X11_XV &&
-                                               output->get_canvas()->accel_available(best_colormodel, 0) &&
-                                               !output->use_scrollbars)
-                                       {
-                                               bitmap = new BC_Bitmap(output->get_canvas(),
-                                                       device->out_w, device->out_h,
-                                                       best_colormodel, 1);
-                                               output_frame = new VFrame(bitmap,
-                                                       device->out_w, device->out_h,
-                                                       best_colormodel, -1);
-                                               bitmap_type = BITMAP_PRIMARY;
-                                       }
-                                       else
-                                       if(device->out_config->driver == PLAYBACK_X11_XV &&
-                                               output->get_canvas()->accel_available(BC_YUV422P, 0))
-                                       {
-                                               bitmap = new BC_Bitmap(output->get_canvas(),
-                                                       device->out_w, device->out_h,
-                                                       BC_YUV422P, 1);
-                                               bitmap_type = BITMAP_TEMP;
-                                       }
-                                       break;
-                       }
+                       bitmap_type = BITMAP_TEMP;
+                       switch( best_colormodel ) {
+                       case BC_YUV420P:
+                               if( device->out_config->driver == PLAYBACK_X11_XV &&
+                                   output->get_canvas()->accel_available(best_colormodel, 0) &&
+                                   !output->use_scrollbars )
+                                       bitmap_type = BITMAP_PRIMARY;
+                               break;
 
+                       case BC_YUV422P:
+                               if( device->out_config->driver == PLAYBACK_X11_XV &&
+                                   output->get_canvas()->accel_available(best_colormodel, 0) &&
+                                   !output->use_scrollbars )
+                                       bitmap_type = BITMAP_PRIMARY;
+                               else if( device->out_config->driver == PLAYBACK_X11_XV &&
+                                   output->get_canvas()->accel_available(BC_YUV422, 0) ) {
+                                       bitmap = new BC_Bitmap(output->get_canvas(),
+                                               device->out_w, device->out_h, BC_YUV422, 1);
+                               }
+                               break;
+
+                       case BC_YUV422:
+                               if( device->out_config->driver == PLAYBACK_X11_XV &&
+                                   output->get_canvas()->accel_available(best_colormodel, 0) &&
+                                   !output->use_scrollbars )
+                                       bitmap_type = BITMAP_PRIMARY;
+                               else if( device->out_config->driver == PLAYBACK_X11_XV &&
+                                   output->get_canvas()->accel_available(BC_YUV422P, 0) ) {
+                                       bitmap = new BC_Bitmap(output->get_canvas(),
+                                               device->out_w, device->out_h, BC_YUV422P, 1);
+                               }
+                               break;
+                       }
+                       if( bitmap_type == BITMAP_PRIMARY ) {
+                               bitmap = new BC_Bitmap(output->get_canvas(),
+                                       device->out_w, device->out_h, best_colormodel, 1);
+                               output_frame = new VFrame(bitmap,
+                                       device->out_w, device->out_h, best_colormodel, -1);
+                       }
+                       else {
 // Try default colormodel
-                       if(!bitmap)
-                       {
                                best_colormodel = output->get_canvas()->get_color_model();
                                bitmap = new BC_Bitmap(output->get_canvas(),
-                                       output->get_canvas()->get_w(),
-                                       output->get_canvas()->get_h(),
+                                       output->get_canvas()->get_w(), output->get_canvas()->get_h(),
                                        best_colormodel, 1);
-                               bitmap_type = BITMAP_TEMP;
-                       }
-
-                       if(bitmap_type == BITMAP_TEMP)
-                       {
 // Intermediate frame
                                output_frame = new VFrame(0, -1,
-                                       device->out_w, device->out_h,
-                                       colormodel, -1);
-//BUFFER2(output_frame->get_rows()[0], "VDeviceX11::new_output_buffer 2");
-                               bitmap_type = BITMAP_TEMP;
+                                       device->out_w, device->out_h, colormodel, -1);
                        }
+
                        color_model_selected = 1;
                }
+               else if( bitmap_type == BITMAP_PRIMARY ) {
+// Update the ring buffer
+                       output_frame->set_memory(bitmap);
+               }
        }
 
        *result = output_frame;
@@ -496,7 +392,7 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)
 {
 // The reason for not drawing single frame is that it is _always_ drawn
 // when drawing draw_refresh in cwindowgui and vwindowgui
-       if (device->single_frame)
+       if( device->single_frame )
                return 0;
 
        output->lock_canvas("VDeviceX11::write_buffer");
@@ -531,51 +427,26 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)
        }
        else
 #endif
-       if(bitmap_type == BITMAP_TEMP) {
+       if( bitmap_type == BITMAP_TEMP ) {
 // printf("VDeviceX11::write_buffer 1 %d %d, %d %d %d %d -> %d %d %d %d\n",
 //  output->w, output->h, in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h );
 // fflush(stdout);
 //printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels);
-
-
-               if(bitmap->hardware_scaling())
-               {
-                       BC_CModels::transfer(bitmap->get_row_pointers(),
-                               output_channels->get_rows(), 0, 0, 0,
-                               output_channels->get_y(),
-                               output_channels->get_u(),
-                               output_channels->get_v(),
-                               0, 0,
-                               output_channels->get_w(),
-                               output_channels->get_h(),
-                               0, 0,
-                               bitmap->get_w(),
-                               bitmap->get_h(),
-                               output_channels->get_color_model(),
-                               bitmap->get_color_model(),
-                               0,
-                               output_channels->get_w(),
-                               bitmap->get_w());
+               if( bitmap->hardware_scaling() ) {
+                       BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(),
+                               0, 0, 0, output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
+                               0, 0, output_channels->get_w(), output_channels->get_h(),
+                               0, 0, bitmap->get_w(), bitmap->get_h(),
+                               output_channels->get_color_model(), bitmap->get_color_model(),
+                               0, output_channels->get_w(), bitmap->get_w());
                }
-               else
-               {
-                       BC_CModels::transfer(bitmap->get_row_pointers(),
-                               output_channels->get_rows(), 0, 0, 0,
-                               output_channels->get_y(),
-                               output_channels->get_u(),
-                               output_channels->get_v(),
-                               (int)output_x1,
-                               (int)output_y1,
-                               (int)(output_x2 - output_x1),
-                               (int)(output_y2 - output_y1),
-                               0, 0,
-                               (int)(canvas_x2 - canvas_x1),
-                               (int)(canvas_y2 - canvas_y1),
-                               output_channels->get_color_model(),
-                               bitmap->get_color_model(),
-                               0,
-                               output_channels->get_w(),
-                               bitmap->get_w());
+               else {
+                       BC_CModels::transfer(bitmap->get_row_pointers(), output_channels->get_rows(),
+                               0, 0, 0, output_channels->get_y(), output_channels->get_u(), output_channels->get_v(),
+                               (int)output_x1, (int)output_y1, (int)(output_x2 - output_x1), (int)(output_y2 - output_y1),
+                               0, 0, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
+                               output_channels->get_color_model(), bitmap->get_color_model(),
+                               0, output_channels->get_w(), bitmap->get_w());
                }
        }
 
@@ -589,11 +460,9 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)
 // canvas_x1, canvas_y1, canvas_x2, canvas_y2);
 
 // Cause X server to display it
-       if(device->out_config->driver == PLAYBACK_X11_GL)
-       {
+       if( device->out_config->driver == PLAYBACK_X11_GL ) {
 // Output is drawn in close_all if no video.
-               if(output->get_canvas()->get_video_on())
-               {
+               if( output->get_canvas()->get_video_on() ) {
 // Draw output frame directly.  Not used for compositing.
                        output->get_canvas()->unlock_window();
                        output->unlock_canvas();
@@ -605,32 +474,18 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl)
                        output->get_canvas()->lock_window("VDeviceX11::write_buffer 2");
                }
        }
-       else
-       if(bitmap->hardware_scaling())
-       {
-               output->get_canvas()->draw_bitmap(bitmap,
-                       !device->single_frame,
+       else if( bitmap->hardware_scaling() ) {
+               output->get_canvas()->draw_bitmap(bitmap, !device->single_frame,
                        (int)canvas_x1, (int)canvas_y1,
-                       (int)(canvas_x2 - canvas_x1),
-                       (int)(canvas_y2 - canvas_y1),
+                       (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1),
                        (int)output_x1, (int)output_y1,
-                       (int)(output_x2 - output_x1),
-                       (int)(output_y2 - output_y1),
-                       0);
+                       (int)(output_x2 - output_x1), (int)(output_y2 - output_y1), 0);
        }
-       else
-       {
-//printf("VDeviceX11::write_buffer %d bitmap=%p\n", __LINE__, bitmap);
-               output->get_canvas()->draw_bitmap(bitmap,
-                       !device->single_frame,
+       else {
+               output->get_canvas()->draw_bitmap(bitmap, !device->single_frame,
                        (int)canvas_x1, (int)canvas_y1,
-                       (int)(canvas_x2 - canvas_x1),
-                       (int)(canvas_y2 - canvas_y1),
-                       0, 0,
-                       (int)(canvas_x2 - canvas_x1),
-                       (int)(canvas_y2 - canvas_y1),
-                       0);
-//printf("VDeviceX11::write_buffer %d bitmap=%p\n", __LINE__, bitmap);
+                       (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), 0, 0,
+                       (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), 0);
        }
 
 
@@ -678,9 +533,17 @@ void VDeviceX11::do_fade(VFrame *output_temp, float fade)
        this->output->mwindow->playback_3d->do_fade(this->output, output_temp, fade);
 }
 
-void VDeviceX11::do_mask(VFrame *output_temp, int64_t start_position_project,
-               MaskAutos *keyframe_set, MaskAuto *keyframe,
-               MaskAuto *default_auto)
+bool VDeviceX11::can_mask(int64_t start_position_project, MaskAutos *keyframe_set)
+{
+       Auto *current = 0;
+       MaskAuto *keyframe = (MaskAuto*)keyframe_set->
+               get_prev_auto(start_position_project, PLAY_FORWARD, current);
+       return keyframe->disable_opengl_masking ? 0 : 1;
+}
+
+void VDeviceX11::do_mask(VFrame *output_temp,
+       int64_t start_position_project, MaskAutos *keyframe_set,
+       MaskAuto *keyframe, MaskAuto *default_auto)
 {
        this->output->mwindow->playback_3d->do_mask(output,
                output_temp, start_position_project,