else
// Copy to RAM
{
- command->input->enable_opengl();
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE,
- command->frame->get_rows()[0]);
- command->frame->flip_vert();
- command->frame->set_opengl_state(VFrame::RAM);
+ command->input->to_texture();
+ command->input->bind_texture(0);
+ command->frame->enable_opengl();
+ command->frame->init_screen();
+ unsigned int shader = BC_CModels::is_yuv(command->input->get_color_model()) ?
+ VFrame::make_shader(0, yuv_to_rgb_frag, 0) : 0;
+ if( shader > 0 ) {
+ glUseProgram(shader);
+ int variable = glGetUniformLocation(shader, "tex");
+ glUniform1i(variable, 0);
+ BC_GL_YUV_TO_RGB(shader);
+ }
+ else
+ glUseProgram(0);
+ command->input->draw_texture(1);
+ command->frame->screen_to_ram();
+ glUseProgram(0);
}
}
else
// Make sure OpenGL is enabled first.
window->enable_opengl();
-
//printf("Playback3D::write_buffer_sync 1 %d\n", window->get_id());
- switch(command->frame->get_opengl_state())
- {
+ int flip_y = 0, frame_state = command->frame->get_opengl_state();
+ switch( frame_state ) {
// Upload texture and composite to screen
case VFrame::RAM:
+ flip_y = 1;
+ case VFrame::SCREEN:
command->frame->to_texture();
- draw_output(command);
- break;
+ window->enable_opengl();
// Composite texture to screen and swap buffer
case VFrame::TEXTURE:
- draw_output(command);
- break;
- case VFrame::SCREEN:
-// swap buffers only
- window->flip_opengl();
+ draw_output(command, flip_y);
break;
default:
printf("Playback3D::write_buffer_sync unknown state\n");
break;
}
+ command->frame->set_opengl_state(frame_state);
window->unlock_window();
}
-void Playback3D::draw_output(Playback3DCommand *command)
+void Playback3D::draw_output(Playback3DCommand *command, int flip_y)
{
#ifdef HAVE_GL
int texture_id = command->frame->get_texture_id();
command->frame->draw_texture(
command->in_x1, command->in_y1, command->in_x2, command->in_y2,
command->out_x1, command->out_y1, command->out_x2, command->out_y2,
- 1);
+ flip_y);
-// printf("Playback3D::draw_output 2 %f,%f %f,%f -> %f,%f %f,%f\n",
+//printf("Playback3D::draw_output 2 %f,%f %f,%f -> %f,%f %f,%f\n",
// command->in_x1,
// command->in_y1,
// command->in_x2,
//printf("Playback3D::overlay_sync 1 %d\n", command->input->get_opengl_state());
- switch(command->input->get_opengl_state()) {
+ switch( command->input->get_opengl_state() ) {
// Upload texture and composite to screen
case VFrame::RAM:
command->input->to_texture();
// Convert colormodel to RGB if not nested.
// The color model setting in the output frame is ignored.
- if( command->is_nested <= 0 && // not nested
- BC_CModels::is_yuv(command->input->get_color_model()) ) {
- need_matrix = 1;
- shader_stack[total_shaders++] = yuv_to_rgb_frag;
- }
+// if( command->is_nested <= 0 && // not nested
+// BC_CModels::is_yuv(command->input->get_color_model()) ) {
+// need_matrix = 1;
+// shader_stack[total_shaders++] = yuv_to_rgb_frag;
+// }
// get the shaders
#define add_shader(s) \
}
// if to flatten alpha
- if( command->is_nested < 0 ) {
- switch(command->input->get_color_model()) {
-// yuv has already been converted to rgb
- case BC_YUVA8888:
- case BC_RGBA_FLOAT:
- case BC_RGBA8888:
- add_shader(rgba_to_rgb_flatten);
- break;
- }
- }
+// if( command->is_nested < 0 ) {
+// switch(command->input->get_color_model()) {
+//// yuv has already been converted to rgb
+// case BC_YUVA8888:
+// case BC_RGBA_FLOAT:
+// case BC_RGBA8888:
+// add_shader(rgba_to_rgb_flatten);
+// break;
+// }
+// }
// run the shaders
add_shader(0);
glUseProgram(0);
-// printf("Playback3D::overlay_sync %f %f %f %f %f %f %f %f\n",
+//printf("Playback3D::overlay_sync %f %f %f %f %f %f %f %f\n",
// command->in_x1, command->in_y1, command->in_x2, command->in_y2,
// command->out_x1, command->out_y1, command->out_x2, command->out_y2);
command->input->draw_texture(
command->in_x1, command->in_y1, command->in_x2, command->in_y2,
command->out_x1, command->out_y1, command->out_x2, command->out_y2,
-// Don't flip vertical if nested
- command->is_nested > 0 ? 0 : 1);
+ !command->is_nested);
glUseProgram(0);
// Delete temp texture
/*
* CINELERRA
* 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"
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");
output->lock_canvas("VDeviceX11::output_visible");
if( output->get_canvas()->get_hidden() ) {
output->unlock_canvas();
- return 0;
+ return 0;
}
else {
output->unlock_canvas();
}
device->mwindow->gui->unlock_window();
}
-
+
reset_parameters();
return 0;
device->mwindow->gui->unlock_window();
- capture_bitmap->capture_frame(frame,
+ capture_bitmap->capture_frame(frame,
device->input_x, device->input_y, device->do_cursor);
return 0;
}
file_colormodel == BC_RGBA_FLOAT ) {
return file_colormodel;
}
-
+
return BC_RGB888;
}
output_frame->set_opengl_state(VFrame::RAM);
}
else {
- 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,
// 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 =
+ int direct_supported =
device->out_config->use_direct_x11 &&
!output->xscroll && !output->yscroll &&
output_x1 == 0 && output_x2 == device->out_w &&
if( !bitmap ) {
int use_direct = 0;
bitmap_type = BITMAP_TEMP;
-//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n",
+//printf("VDeviceX11::new_output_buffer %d file_colormodel=%d display_colormodel=%d\n",
// __LINE__, file_colormodel, display_colormodel);
// Try hardware accelerated
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;
}
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;
// "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(),
+ bitmap = new BC_Bitmap(output->get_canvas(),
canvas_w, canvas_h, display_colormodel, 1);
bitmap_type = BITMAP_TEMP;
}
// invoked when is_nested = -1 is passed to vdevicex11->overlay(...)
// }
-// printf("VDeviceX11::write_buffer %d %d bitmap_type=%d\n",
-// __LINE__,
+// printf("VDeviceX11::write_buffer %d %d bitmap_type=%d\n",
+// __LINE__,
// output->get_canvas()->get_video_on(),
// bitmap_type);
// canvas_w = bitmap->get_w();
// canvas_h = bitmap->get_h();
// }
-//
-// 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,
// canvas_w, canvas_h);
// fflush(stdout);
// 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",
+// 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,
//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(),
+//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",
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 &&
+ 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,
+ output->get_transfers(edl,
+ output_x1, output_y1, output_x2, output_y2,
canvas_x1, canvas_y1, canvas_x2, canvas_y2,
canvas_w, canvas_h);
0);
}
else {
-//printf("VDeviceX11::write_buffer %d x=%d y=%d w=%d h=%d\n",
+//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,
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);
}
}
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,
+ this->output->mwindow->playback_3d->do_camera(this->output,
output, input,
- in_x1, in_y1, in_x2, in_y2,
+ in_x1, in_y1, in_x2, in_y2,
out_x1, out_y1, out_x2, out_y2);
}
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)
+void VDeviceX11::overlay(VFrame *output_frame, 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,
+ 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, // 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 {
- 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, // 0 - 1
- 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)