/*
* CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
+ *
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
*/
#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"
capture_bitmap = 0;
color_model_selected = 0;
is_cleared = 0;
+
+ for( int i = 0; i < SCREENCAP_BORDERS; i++ ) {
+ screencap_border[i] = 0;
+ }
return 0;
}
int VDeviceX11::open_input()
{
//printf("VDeviceX11::open_input 1\n");
- capture_bitmap = new BC_Capture(device->in_config->w,
+ capture_bitmap = new BC_Capture(device->in_config->w,
device->in_config->h,
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; i<SCREENCAP_BORDERS; ++i )
+ screencap_border[i]->show_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;
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;
+ return 0;
}
- else
- {
+ else {
output->unlock_canvas();
return 1;
}
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)
- {
-// 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)
+ if( output && output_frame ) {
+ output->update_refresh(device, output_frame);
+ if( device->single_frame )
output->draw_refresh();
}
+ delete bitmap; bitmap = 0;
+ delete output_frame; output_frame = 0;
+ delete capture_bitmap; capture_bitmap = 0;
-
-
- if(bitmap)
- {
- delete bitmap;
- bitmap = 0;
- }
-
- if(output_frame)
- {
- delete output_frame;
- output_frame = 0;
- }
-
- if(capture_bitmap) delete capture_bitmap;
-
- if(output)
- {
-
+ if( output ) {
// Update the status bug
- if(!device->single_frame)
- {
+ if( !device->single_frame ) {
output->stop_video();
}
- else
- {
+ else {
output->stop_single();
}
output->unlock_canvas();
}
-
+ if( device->mwindow ) {
+ device->mwindow->gui->lock_window("VDeviceX11::close_all");
+ for( int i=0; i<SCREENCAP_BORDERS; ++i ) {
+ delete screencap_border[i];
+ screencap_border[i] = 0;
+ }
+ device->mwindow->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;
}
}
}
-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 &&
output->get_canvas()->accel_available(BC_YUV422, 0) ) {
- bitmap = new BC_Bitmap(output->get_canvas(),
+ 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 )
+ 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(),
+ bitmap = new BC_Bitmap(output->get_canvas(),
device->out_w, device->out_h, BC_YUV422P, 1);
}
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();
- 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);
+// 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(),
+ 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);
}
}
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
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());
}
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(),
}
//printf("VDeviceX11::write_buffer 4 %p\n", bitmap);
-//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,
+//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 %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() ) {
+ 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);
+ (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);
+ (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);
}
-
output->get_canvas()->unlock_window();
output->unlock_canvas();
return 0;
void VDeviceX11::convert_cmodel(VFrame *output, int dst_cmodel)
{
this->output->mwindow->playback_3d->convert_cmodel(this->output,
- output,
+ output,
dst_cmodel);
}
void VDeviceX11::do_camera(VFrame *output, VFrame *input,
- float in_x1, float in_y1, float in_x2, float in_y2,
+ 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,
- in_x1, in_y1, in_x2, in_y2,
+ 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);
}
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,
+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 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)
{
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);
+// 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)
- {
+ 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(),
+ 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);
+// 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
- {
+ 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,
+ output->get_transfers(edl,
+ output_x1, output_y1, output_x2, output_y2,
canvas_x1, canvas_y1, canvas_x2, canvas_y2,
-1, -1);
float track_y2 = (float)(output_y2 - out_y2) / track_yscale + in_y2;
// Clamp canvas coords to track boundary
- if(track_x1 < 0)
- {
+ if( track_x1 < 0 ) {
float difference = -track_x1;
track_x1 += difference;
canvas_x1 += difference * track_xscale * canvas_xscale;
}
- if(track_y1 < 0)
- {
+ if( track_y1 < 0 ) {
float difference = -track_y1;
track_y1 += difference;
canvas_y1 += difference * track_yscale * canvas_yscale;
}
- if(track_x2 > input->get_w())
- {
+ 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())
- {
+ 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)
- {
+ 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);
+ track_x1, track_y1, track_x2, track_y2,
+ canvas_x1, canvas_y1, canvas_x2, canvas_y2, alpha, // 0 - 1
+ mode, interpolation_type, 0, is_nested);
}
}
}