X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fvdevicex11.C;h=ea8720dbf2f777eea591644eba51bd3a1c13d4ae;hp=31873e6a4c1b79d7687cc8231f27798baf5e64c5;hb=HEAD;hpb=e9a3c57c8d3bb4d79e76a4c3942f86a66d3c267e diff --git a/cinelerra-5.1/cinelerra/vdevicex11.C b/cinelerra-5.1/cinelerra/vdevicex11.C index 31873e6a..ea8720db 100644 --- a/cinelerra-5.1/cinelerra/vdevicex11.C +++ b/cinelerra-5.1/cinelerra/vdevicex11.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 2008 Adam Williams + * Copyright (C) 2008-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,16 +20,18 @@ */ #include "assets.h" -#include "auto.h" +#include "autos.h" #include "bccapture.h" +#include "bccmodels.h" #include "bcsignals.h" #include "canvas.h" -#include "bccmodels.h" #include "edl.h" #include "edlsession.h" -#include "maskautos.h" +#include "file.h" #include "maskauto.h" +#include "maskautos.h" #include "mwindow.h" +#include "mwindowgui.h" #include "playback3d.h" #include "playbackconfig.h" #include "preferences.h" @@ -75,6 +77,10 @@ int VDeviceX11::reset_parameters() capture_bitmap = 0; color_model_selected = 0; is_cleared = 0; + + for( int i = 0; i < SCREENCAP_BORDERS; i++ ) { + screencap_border[i] = 0; + } return 0; } @@ -86,23 +92,48 @@ int VDeviceX11::open_input() device->in_config->screencapture_display); //printf("VDeviceX11::open_input 2\n"); +// create overlay + device->mwindow->gui->lock_window("VDeviceX11::close_all"); + + screencap_border[0] = new BC_Popup(device->mwindow->gui, + device->input_x - SCREENCAP_PIXELS, device->input_y - SCREENCAP_PIXELS, + device->in_config->w + SCREENCAP_PIXELS * 2, SCREENCAP_PIXELS, + SCREENCAP_COLOR, 1); + screencap_border[1] = new BC_Popup(device->mwindow->gui, + device->input_x - SCREENCAP_PIXELS, device->input_y, + SCREENCAP_PIXELS, device->in_config->h, + SCREENCAP_COLOR, 1); + screencap_border[2] = new BC_Popup(device->mwindow->gui, + device->input_x - SCREENCAP_PIXELS, device->input_y + device->in_config->h, + device->in_config->w + SCREENCAP_PIXELS * 2, SCREENCAP_PIXELS, + SCREENCAP_COLOR, 1); + screencap_border[3] = new BC_Popup(device->mwindow->gui, + device->input_x + device->in_config->w, device->input_y, + SCREENCAP_PIXELS, device->in_config->h, + SCREENCAP_COLOR, 1); +usleep(500000); // avoids a bug in gnome-shell 2017/10/19 + + for( int i=0; ishow_window(0); + + device->mwindow->gui->flush(); + device->mwindow->gui->unlock_window(); + return 0; } int VDeviceX11::open_output() { - if(output) - { + if( output ) { output->lock_canvas("VDeviceX11::open_output"); output->get_canvas()->lock_window("VDeviceX11::open_output"); - if(!device->single_frame) + if( !device->single_frame ) output->start_video(); else output->start_single(); output->get_canvas()->unlock_window(); // Enable opengl in the first routine that needs it, to reduce the complexity. - output->unlock_canvas(); } return 0; @@ -111,16 +142,14 @@ int VDeviceX11::open_output() int VDeviceX11::output_visible() { - if(!output) return 0; + if( !output ) return 0; output->lock_canvas("VDeviceX11::output_visible"); - if(output->get_canvas()->get_hidden()) - { + if( output->get_canvas()->get_hidden() ) { output->unlock_canvas(); return 0; } - else - { + else { output->unlock_canvas(); return 1; } @@ -129,125 +158,121 @@ int VDeviceX11::output_visible() int VDeviceX11::close_all() { - if(output) - { + if( output ) { output->lock_canvas("VDeviceX11::close_all 1"); output->get_canvas()->lock_window("VDeviceX11::close_all 1"); - } - - if(output && output_frame) - { - output->update_refresh(device, output_frame); - if( device->single_frame ) - output->draw_refresh(); - } - - - - - if(bitmap) - { - delete bitmap; - bitmap = 0; - } - - if(output_frame) - { - delete output_frame; - output_frame = 0; - } - - if(capture_bitmap) delete capture_bitmap; - - if(output) - { - + int video_on = output->get_canvas()->get_video_on(); // Update the status bug - if(!device->single_frame) - { + if( !device->single_frame ) { output->stop_video(); } - else - { + else { output->stop_single(); } + if( output_frame ) { + output->update_refresh(device, output_frame); +// if the last frame is good, don't draw over it + if( !video_on || output->need_overlays() ) + output->draw_refresh(1); + } + } + + delete bitmap; bitmap = 0; + delete output_frame; output_frame = 0; + delete capture_bitmap; capture_bitmap = 0; + if( output ) { output->get_canvas()->unlock_window(); output->unlock_canvas(); } + if( device->mwindow ) { + device->mwindow->gui->lock_window("VDeviceX11::close_all"); + for( int i=0; imwindow->gui->unlock_window(); + } reset_parameters(); + return 0; } int VDeviceX11::read_buffer(VFrame *frame) { - capture_bitmap->capture_frame(frame, device->input_x, device->input_y); +//printf("VDeviceX11::read_buffer %d colormodel=%d\n", __LINE__, frame->get_color_model()); + device->mwindow->gui->lock_window("VDeviceX11::close_all"); + + screencap_border[0]->reposition_window(device->input_x - SCREENCAP_PIXELS, + device->input_y - SCREENCAP_PIXELS); + screencap_border[1]->reposition_window(device->input_x - SCREENCAP_PIXELS, + device->input_y); + screencap_border[2]->reposition_window(device->input_x - SCREENCAP_PIXELS, + device->input_y + device->in_config->h); + screencap_border[3]->reposition_window(device->input_x + device->in_config->w, + device->input_y); + device->mwindow->gui->flush(); + device->mwindow->gui->unlock_window(); + + + capture_bitmap->capture_frame(frame, + device->input_x, device->input_y, device->do_cursor); return 0; } int VDeviceX11::get_best_colormodel(Asset *asset) { - return BC_RGB888; + return File::get_best_colormodel(asset, SCREENCAPTURE); +// return BC_RGB888; } -int VDeviceX11::get_best_colormodel(int colormodel) +int VDeviceX11::get_display_colormodel(int file_colormodel) { int result = -1; - if(device->out_config->driver == PLAYBACK_X11_GL) - { - if(colormodel == BC_RGB888 || - colormodel == BC_RGBA8888 || - colormodel == BC_YUV888 || - colormodel == BC_YUVA8888 || - colormodel == BC_RGB_FLOAT || - colormodel == BC_RGBA_FLOAT) - { - return colormodel; + if( device->out_config->driver == PLAYBACK_X11_GL ) { + if( file_colormodel == BC_RGB888 || + file_colormodel == BC_RGBA8888 || + file_colormodel == BC_YUV888 || + file_colormodel == BC_YUVA8888 || + file_colormodel == BC_RGB_FLOAT || + file_colormodel == BC_RGBA_FLOAT ) { + return file_colormodel; } + return BC_RGB888; } - if(!device->single_frame) - { - switch(colormodel) - { - case BC_YUV420P: - case BC_YUV422P: - case BC_YUV422: - result = colormodel; - break; + if( !device->single_frame ) { + switch( file_colormodel ) { + case BC_YUV420P: + case BC_YUV422P: + case BC_YUV422: + result = file_colormodel; + break; } } -// 2 more colormodels are supported by OpenGL - if(device->out_config->driver == PLAYBACK_X11_GL) - { - if(colormodel == BC_RGB_FLOAT || - colormodel == BC_RGBA_FLOAT) - result = colormodel; - } - - if(result < 0) - { - switch(colormodel) - { - case BC_RGB888: - case BC_RGBA8888: - case BC_YUV888: - case BC_YUVA8888: - result = colormodel; - break; - - default: - output->lock_canvas("VDeviceX11::get_best_colormodel"); - result = output->get_canvas()->get_color_model(); - output->unlock_canvas(); - break; + if( result < 0 ) { + switch( file_colormodel ) { + case BC_RGB888: + case BC_RGBA8888: + case BC_YUV888: + case BC_YUVA8888: + case BC_RGB_FLOAT: + case BC_RGBA_FLOAT: + result = file_colormodel; + break; + + default: + output->lock_canvas("VDeviceX11::get_display_colormodel"); + result = output->get_canvas()->get_color_model(); + output->unlock_canvas(); + break; } } @@ -255,68 +280,127 @@ int VDeviceX11::get_best_colormodel(int colormodel) } -void VDeviceX11::new_output_buffer(VFrame **result, int colormodel) +void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *edl) { -//printf("VDeviceX11::new_output_buffer 1\n"); +// printf("VDeviceX11::new_output_buffer %d hardware_scaling=%d\n", +// __LINE__, bitmap ? bitmap->hardware_scaling() : 0); output->lock_canvas("VDeviceX11::new_output_buffer"); output->get_canvas()->lock_window("VDeviceX11::new_output_buffer 1"); // Get the best colormodel the display can handle. - int best_colormodel = get_best_colormodel(colormodel); + int display_colormodel = get_display_colormodel(file_colormodel); +//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n", +// __LINE__, file_colormodel, display_colormodel); // Only create OpenGL Pbuffer and texture. 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 ) { - output_frame = new VFrame(0, -1, - device->out_w, device->out_h, colormodel, -1); -//BUFFER2(output_frame->get_rows()[0], "VDeviceX11::new_output_buffer 1"); + output_frame = new VFrame(device->out_w, device->out_h, file_colormodel); } window_id = output->get_canvas()->get_id(); output_frame->set_opengl_state(VFrame::RAM); } else { + output->get_transfers(edl, + output_x1, output_y1, output_x2, output_y2, + canvas_x1, canvas_y1, canvas_x2, canvas_y2, +// Canvas may be a different size than the temporary bitmap for pure software + -1, -1); + canvas_w = canvas_x2 - canvas_x1; + canvas_h = canvas_y2 - canvas_y1; +// can the direct frame be used? + int direct_supported = + device->out_config->use_direct_x11 && + !output->xscroll && !output->yscroll && + output_x1 == 0 && output_x2 == device->out_w && + output_y1 == 0 && output_y2 == device->out_h; + +// file wants direct frame but we need a temp + if( !direct_supported && file_colormodel == BC_BGR8888 ) + file_colormodel = BC_RGB888; + // Conform existing bitmap to new colormodel and output size if( bitmap ) { +// printf("VDeviceX11::new_output_buffer %d bitmap=%dx%d canvas=%dx%d canvas=%dx%d\n", +// __LINE__, bitmap->get_w(), bitmap->get_h(), canvas_w, canvas_h,); + int size_change = ( + bitmap->get_w() != canvas_w || + bitmap->get_h() != canvas_h ); + // 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(); -//printf("VDeviceX11::new_output_buffer %d\n", __LINE__); + if( !color_model_selected || + file_colormodel != output_frame->get_color_model() || + (!bitmap->hardware_scaling() && size_change) ) { +//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d prev " +// "file_colormodel=%d bitmap=%p output_frame=%p\n", __LINE__, +// file_colormodel, output_frame->get_color_model(), bitmap, output_frame); delete bitmap; bitmap = 0; delete output_frame; output_frame = 0; - -// Blank only if size changed +// Clear borders if size changed if( size_change ) { +//printf("VDeviceX11::new_output_buffer %d w=%d h=%d " +// "canvas_x1=%d canvas_y1=%d canvas_x2=%d canvas_y2=%d\n", +// __LINE__, // (int)output->w, (int)output->h, +// (int)canvas_x1, (int)canvas_y1, (int)canvas_x2, (int)canvas_y2); output->get_canvas()->set_color(BLACK); - output->get_canvas()->draw_box(0, 0, output->w, output->h); - output->get_canvas()->flash(); + + if( canvas_y1 > 0 ) { + output->get_canvas()->draw_box(0, 0, output->w, canvas_y1); + output->get_canvas()->flash(0, 0, output->w, canvas_y1); + } + + if( canvas_y2 < output->h ) { + output->get_canvas()->draw_box(0, canvas_y2, output->w, output->h - canvas_y2); + output->get_canvas()->flash(0, canvas_y2, output->w, output->h - canvas_y2); + } + + if( canvas_x1 > 0 ) { + output->get_canvas()->draw_box(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); + output->get_canvas()->flash(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); + } + + if( canvas_x2 < output->w ) { + output->get_canvas()->draw_box(canvas_x2, canvas_y1, + output->w - canvas_x2, canvas_y2 - canvas_y1); + output->get_canvas()->flash(canvas_x2, canvas_y1, + output->w - canvas_x2, canvas_y2 - canvas_y1); + } } } } // Create new bitmap if( !bitmap ) { -// Try hardware accelerated + int use_direct = 0; bitmap_type = BITMAP_TEMP; - switch( best_colormodel ) { +//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n", +// __LINE__, file_colormodel, display_colormodel); + +// Try hardware accelerated + switch( display_colormodel ) { +// blit from the codec directly to the window, using the standard X11 color model. +// Must scale in the codec. No cropping + case BC_BGR8888: + if( direct_supported ) { + bitmap_type = BITMAP_PRIMARY; + use_direct = 1; + } + break; + case BC_YUV420P: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(best_colormodel, 0) && + output->get_canvas()->accel_available(display_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->get_canvas()->accel_available(display_colormodel, 0) && !output->use_scrollbars ) bitmap_type = BITMAP_PRIMARY; else if( device->out_config->driver == PLAYBACK_X11_XV && @@ -328,9 +412,10 @@ void VDeviceX11::new_output_buffer(VFrame **result, int colormodel) case BC_YUV422: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(best_colormodel, 0) && - !output->use_scrollbars ) + output->get_canvas()->accel_available(display_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(), @@ -339,26 +424,33 @@ void VDeviceX11::new_output_buffer(VFrame **result, int colormodel) break; } if( bitmap_type == BITMAP_PRIMARY ) { + int bitmap_w = use_direct ? canvas_w : device->out_w; + int bitmap_h = use_direct ? canvas_h : device->out_h; bitmap = new BC_Bitmap(output->get_canvas(), - device->out_w, device->out_h, best_colormodel, 1); + bitmap_w, bitmap_h, display_colormodel, -1); output_frame = new VFrame(bitmap, - device->out_w, device->out_h, best_colormodel, -1); + bitmap_w, bitmap_h, display_colormodel, -1); } - else { -// Try default colormodel - best_colormodel = output->get_canvas()->get_color_model(); +// Make an intermediate frame + if( !bitmap ) { + display_colormodel = output->get_canvas()->get_color_model(); +// printf("VDeviceX11::new_output_buffer %d creating temp display_colormodel=%d " +// "file_colormodel=%d %dx%d %dx%d %dx%d\n", __LINE__, +// display_colormodel, file_colormodel, device->out_w, device->out_h, +// output->get_canvas()->get_w(), output->get_canvas()->get_h(), canvas_w, canvas_h); bitmap = new BC_Bitmap(output->get_canvas(), - output->get_canvas()->get_w(), output->get_canvas()->get_h(), - best_colormodel, 1); -// Intermediate frame - output_frame = new VFrame(0, -1, - device->out_w, device->out_h, colormodel, -1); + canvas_w, canvas_h, display_colormodel, 1); + bitmap_type = BITMAP_TEMP; } + if( bitmap_type == BITMAP_TEMP ) { +// Intermediate frame +//printf("VDeviceX11::new_output_buffer %d creating output_frame\n", __LINE__); + output_frame = new VFrame(device->out_w, device->out_h, file_colormodel); + } color_model_selected = 1; } else if( bitmap_type == BITMAP_PRIMARY ) { -// Update the ring buffer output_frame->set_memory(bitmap); } } @@ -374,14 +466,14 @@ void VDeviceX11::new_output_buffer(VFrame **result, int colormodel) int VDeviceX11::start_playback() { // Record window is initialized when its monitor starts. - if(!device->single_frame) + if( !device->single_frame ) output->start_video(); return 0; } int VDeviceX11::stop_playback() { - if(!device->single_frame) + if( !device->single_frame ) output->stop_video(); // Record window goes back to monitoring // get the last frame played and store it in the video_out @@ -390,105 +482,125 @@ int VDeviceX11::stop_playback() 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 ) - return 0; - output->lock_canvas("VDeviceX11::write_buffer"); output->get_canvas()->lock_window("VDeviceX11::write_buffer 1"); - -// Canvas may be a different size than the temporary bitmap for pure software - int xfr_w, xfr_h; - if(bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling()) { - xfr_w = bitmap->get_w(); - xfr_h = bitmap->get_h(); - } - else - xfr_w = xfr_h = -1; - -//printf("VDeviceX11::write_buffer %d %d\n", __LINE__, output->get_canvas()->get_video_on()); - output->get_transfers(edl, output_x1, output_y1, output_x2, output_y2, - canvas_x1, canvas_y1, canvas_x2, canvas_y2, xfr_w, xfr_h); - -// Convert colormodel -#if 0 +// if( device->out_config->driver == PLAYBACK_X11_GL && +// output_frame->get_color_model() != BC_RGB888 ) { // this is handled by overlay call in virtualvnode, using flatten alpha // invoked when is_nested = -1 is passed to vdevicex11->overlay(...) - if(device->out_config->driver == PLAYBACK_X11_GL && - output_frame->get_color_model() != BC_RGB888) { - int cmodel = BC_RGB888; - output->get_canvas()->unlock_window(); - output->unlock_canvas(); - output->mwindow->playback_3d->convert_cmodel(output, output_frame, cmodel); - output_frame->reallocate(0,-1,0,0,0,output_frame->get_w(),output_frame->get_h(),cmodel,-1); - output->lock_canvas("VDeviceX11::write_buffer 3"); - output->get_canvas()->lock_window("VDeviceX11::write_buffer 3"); - } - else -#endif +// } + +// printf("VDeviceX11::write_buffer %d %d bitmap_type=%d\n", +// __LINE__, +// output->get_canvas()->get_video_on(), +// bitmap_type); + +// int use_bitmap_extents = 0; +// canvas_w = -1; canvas_h = -1; +// // Canvas may be a different size than the temporary bitmap for pure software +// if( bitmap_type == BITMAP_TEMP && !bitmap->hardware_scaling() ) { +// canvas_w = bitmap->get_w(); +// canvas_h = bitmap->get_h(); +// } +// +// output->get_transfers(edl, +// output_x1, output_y1, output_x2, output_y2, +// canvas_x1, canvas_y1, canvas_x2, canvas_y2, +// canvas_w, canvas_h); + +// Convert colormodel 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 ); +// 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); + +// printf("VDeviceX11::write_buffer %d output_channels=%p\n", __LINE__, output_channels); +// printf("VDeviceX11::write_buffer %d input color_model=%d output color_model=%d\n", +// __LINE__, output_channels->get_color_model(), bitmap->get_color_model()); 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(), + 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()); + -1, 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(), + 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()); + -1, output_channels->get_w(), bitmap->get_w()); } } //printf("VDeviceX11::write_buffer 4 %p\n", bitmap); -//for(i = 0; i < 1000; i += 4) bitmap->get_data()[i] = 128; +//for( i = 0; i < 1000; i += 4 ) bitmap->get_data()[i] = 128; //printf("VDeviceX11::write_buffer 2 %d %d %d\n", bitmap_type, -// bitmap->get_color_model(), output->get_color_model()); -//fflush(stdout); -//printf("VDeviceX11::write_buffer 2 %d %d, %f %f %f %f -> %f %f %f %f\n", -// output->w, output->h, output_x1, output_y1, output_x2, output_y2, +// bitmap->get_color_model(), +// output->get_color_model());fflush(stdout); + +// printf("VDeviceX11::write_buffer %d %dx%d %f %f %f %f -> %f %f %f %f\n", +// __LINE__, // output->w, output->h, +// output_x1, output_y1, output_x2, output_y2, // canvas_x1, canvas_y1, canvas_x2, canvas_y2); // Cause X server to display it if( device->out_config->driver == PLAYBACK_X11_GL ) { // Output is drawn in close_all if no video. if( output->get_canvas()->get_video_on() ) { + canvas_w = -1; canvas_h = -1; +// Canvas may be a different size than the temporary bitmap for pure software + if( bitmap_type == BITMAP_TEMP && + !bitmap->hardware_scaling() ) { + canvas_w = bitmap->get_w(); + canvas_h = bitmap->get_h(); + } + + output->get_transfers(edl, + output_x1, output_y1, output_x2, output_y2, + canvas_x1, canvas_y1, canvas_x2, canvas_y2, + canvas_w, canvas_h); + +//printf("VDeviceX11::write_buffer %d\n", __LINE__); // Draw output frame directly. Not used for compositing. output->get_canvas()->unlock_window(); output->unlock_canvas(); - output->mwindow->playback_3d->write_buffer(output, - output_frame, output_x1, output_y1, output_x2, output_y2, - canvas_x1, canvas_y1, canvas_x2, canvas_y2, is_cleared); + output->mwindow->playback_3d->write_buffer(output, output_frame, + output_x1, output_y1, output_x2, output_y2, + canvas_x1, canvas_y1, canvas_x2, canvas_y2, + is_cleared); is_cleared = 0; output->lock_canvas("VDeviceX11::write_buffer 2"); output->get_canvas()->lock_window("VDeviceX11::write_buffer 2"); } } - 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)output_x1, (int)output_y1, - (int)(output_x2 - output_x1), (int)(output_y2 - output_y1), 0); - } 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); + 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)output_x1, (int)output_y1, + (int)(output_x2 - output_x1), (int)(output_y2 - output_y1), + 0); + } + else { +//printf("VDeviceX11::write_buffer %d x=%d y=%d w=%d h=%d\n", +// __LINE__, (int)canvas_x1, (int)canvas_y1, +// output->get_canvas()->get_w(), output->get_canvas()->get_h()); + 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); + } + if( !output->get_canvas()->get_video_on() ) + output->get_canvas()->flash(0); } - output->get_canvas()->unlock_window(); output->unlock_canvas(); return 0; @@ -498,10 +610,8 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) void VDeviceX11::clear_output() { is_cleared = 1; - - output->mwindow->playback_3d->clear_output(output, - output->get_canvas()->get_video_on() ? 0 : output_frame); - + output->mwindow->playback_3d->clear_output(output, 0); + output->mwindow->playback_3d->clear_output(output, output_frame); } @@ -513,7 +623,7 @@ void VDeviceX11::clear_input(VFrame *frame) void VDeviceX11::convert_cmodel(VFrame *output, int dst_cmodel) { this->output->mwindow->playback_3d->convert_cmodel(this->output, - output, + output, dst_cmodel); } @@ -521,8 +631,8 @@ void VDeviceX11::do_camera(VFrame *output, VFrame *input, float in_x1, float in_y1, float in_x2, float in_y2, float out_x1, float out_y1, float out_x2, float out_y2) { - this->output->mwindow->playback_3d->do_camera( - this->output, output, input, + this->output->mwindow->playback_3d->do_camera(this->output, + output, input, in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2); } @@ -541,109 +651,23 @@ bool VDeviceX11::can_mask(int64_t start_position_project, MaskAutos *keyframe_se 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) +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, - keyframe_set, keyframe, default_auto); + this->output->mwindow->playback_3d->do_mask(output, output_temp, + start_position_project, keyframe_set, keyframe, default_auto); } void VDeviceX11::overlay(VFrame *output_frame, VFrame *input, -// This is the transfer from track to output frame float in_x1, float in_y1, float in_x2, float in_y2, float out_x1, float out_y1, float out_x2, float out_y2, - float alpha /*0-1*/, int mode, EDL *edl, int is_nested) + float alpha, int mode, EDL *edl, int is_nested) { int interpolation_type = edl->session->interpolation_type; - -// printf("VDeviceX11::overlay 1:\n" -// "in_x1=%f in_y1=%f in_x2=%f in_y2=%f\n" -// "out_x1=%f out_y1=%f out_x2=%f out_y2=%f\n", -// in_x1, in_y1, in_x2, in_y2, -// out_x1, out_y1, out_x2, out_y2); -// Convert node coords to canvas coords in here - -// If single frame playback or nested EDL, use full sized PBuffer as output. - if(device->single_frame || is_nested > 0) - { - output->mwindow->playback_3d->overlay(output, input, - in_x1, in_y1, in_x2, in_y2, - out_x1, out_y1, out_x2, out_y2, - alpha, mode, interpolation_type, - output_frame, is_nested); -// printf("VDeviceX11::overlay 1 %p %d %d %d\n", -// output_frame, -// output_frame->get_w(), -// output_frame->get_h(), -// output_frame->get_opengl_state()); - } - else - { - output->lock_canvas("VDeviceX11::overlay"); - output->get_canvas()->lock_window("VDeviceX11::overlay"); - -// This is the transfer from output frame to canvas - output->get_transfers(edl, - output_x1, output_y1, output_x2, output_y2, - canvas_x1, canvas_y1, canvas_x2, canvas_y2, - -1, -1); - - output->get_canvas()->unlock_window(); - output->unlock_canvas(); - - -// Get transfer from track to canvas - float track_xscale = (out_x2 - out_x1) / (in_x2 - in_x1); - float track_yscale = (out_y2 - out_y1) / (in_y2 - in_y1); - float canvas_xscale = (float)(canvas_x2 - canvas_x1) / (output_x2 - output_x1); - float canvas_yscale = (float)(canvas_y2 - canvas_y1) / (output_y2 - output_y1); - - -// Get coordinates of canvas relative to track frame - float track_x1 = (float)(output_x1 - out_x1) / track_xscale + in_x1; - float track_y1 = (float)(output_y1 - out_y1) / track_yscale + in_y1; - float track_x2 = (float)(output_x2 - out_x2) / track_xscale + in_x2; - float track_y2 = (float)(output_y2 - out_y2) / track_yscale + in_y2; - -// Clamp canvas coords to track boundary - if(track_x1 < 0) - { - float difference = -track_x1; - track_x1 += difference; - canvas_x1 += difference * track_xscale * canvas_xscale; - } - if(track_y1 < 0) - { - float difference = -track_y1; - track_y1 += difference; - canvas_y1 += difference * track_yscale * canvas_yscale; - } - - if(track_x2 > input->get_w()) - { - float difference = track_x2 - input->get_w(); - track_x2 -= difference; - canvas_x2 -= difference * track_xscale * canvas_xscale; - } - if(track_y2 > input->get_h()) - { - float difference = track_y2 - input->get_h(); - track_y2 -= difference; - canvas_y2 -= difference * track_yscale * canvas_yscale; - } - -// Overlay directly from track buffer to canvas, skipping output buffer - if(track_x2 > track_x1 && track_y2 > track_y1 && - canvas_x2 > canvas_x1 && canvas_y2 > canvas_y1) - { - output->mwindow->playback_3d->overlay(output, input, - track_x1, track_y1, track_x2, track_y2, - canvas_x1, canvas_y1, canvas_x2, canvas_y2, - alpha, mode, interpolation_type, 0, is_nested); - } - } + output->mwindow->playback_3d->overlay(output, input, + in_x1, in_y1, in_x2, in_y2, + out_x1, out_y1, out_x2, out_y2, alpha, // 0 - 1 + mode, interpolation_type, output_frame, is_nested); } void VDeviceX11::run_plugin(PluginClient *client)