/*
* CINELERRA
* Copyright (C) 2008 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 "bcdisplayinfo.h"
FrameFieldWindow::FrameFieldWindow(FrameField *plugin)
- : PluginClientWindow(plugin,
- 210,
- 160,
- 200,
- 160,
+ : PluginClientWindow(plugin,
+ 210,
+ 160,
+ 200,
+ 160,
0)
{
this->plugin = plugin;
-FrameFieldTop::FrameFieldTop(FrameField *plugin,
- FrameFieldWindow *gui,
- int x,
+FrameFieldTop::FrameFieldTop(FrameField *plugin,
+ FrameFieldWindow *gui,
+ int x,
int y)
- : BC_Radial(x,
- y,
+ : BC_Radial(x,
+ y,
plugin->config.field_dominance == TOP_FIELD_FIRST,
_("Top field first"))
{
-FrameFieldBottom::FrameFieldBottom(FrameField *plugin,
- FrameFieldWindow *gui,
- int x,
+FrameFieldBottom::FrameFieldBottom(FrameField *plugin,
+ FrameFieldWindow *gui,
+ int x,
int y)
- : BC_Radial(x,
- y,
+ : BC_Radial(x,
+ y,
plugin->config.field_dominance == BOTTOM_FIELD_FIRST,
_("Bottom field first"))
{
FrameField::FrameField(PluginServer *server)
: PluginVClient(server)
{
-
+
field_number = 0;
src_frame = 0;
src_frame_number = -1;
FrameField::~FrameField()
{
-
+
if(src_frame) delete src_frame;
if(src_texture) delete src_texture;
if(!src_frame)
{
- src_frame = new VFrame(0,
- -1,
- frame->get_w(),
- frame->get_h(),
- frame->get_color_model(),
- -1);
+ src_frame = new VFrame(frame->get_w(), frame->get_h(),
+ frame->get_color_model(), 0);
}
ptr = src_frame;
}
// If same frame was requested, assume it was a configuration change and reprocess.
start_position == last_frame)
{
- read_frame(ptr,
- 0,
- current_frame_number,
+ read_frame(ptr,
+ 0,
+ current_frame_number,
frame_rate / 2,
get_use_opengl());
src_frame_number = current_frame_number;
return 0;
}
- int row_size = VFrame::calculate_bytes_per_pixel(frame->get_color_model()) *
+ int row_size = VFrame::calculate_bytes_per_pixel(frame->get_color_model()) *
frame->get_w();
unsigned char **src_rows = src_frame->get_rows();
// Even field
if(field_number == 0)
{
- if(config.field_dominance == TOP_FIELD_FIRST)
+ if(config.field_dominance == TOP_FIELD_FIRST)
{
for(int i = 0; i < frame->get_h() - 1; i += 2)
{
// Copy even lines of src to both lines of output
- memcpy(output_rows[i],
- src_rows[i],
+ memcpy(output_rows[i],
+ src_rows[i],
row_size);
}
for(int i = 0; i < frame->get_h() - 1; i += 2)
{
// Copy odd lines of current to both lines of output with shift up.
- memcpy(output_rows[i + 1],
- src_rows[i + 1],
+ memcpy(output_rows[i + 1],
+ src_rows[i + 1],
row_size);
}
for(int i = 0; i < frame->get_h() - 1; i += 2)
{
// Copy odd lines of src to both lines of output
- memcpy(output_rows[i + 1],
- src_rows[i + 1],
+ memcpy(output_rows[i + 1],
+ src_rows[i + 1],
row_size);
}
for(int i = 0; i < frame->get_h() - 1; i += 2)
{
// Copy even lines of src to both lines of output.
- memcpy(output_rows[i],
- src_rows[i],
+ memcpy(output_rows[i],
+ src_rows[i],
row_size);
}
-const char* FrameField::plugin_title() { return _("Frames to fields"); }
+const char* FrameField::plugin_title() { return N_("Frames to fields"); }
int FrameField::is_realtime() { return 1; }
NEW_WINDOW_MACRO(FrameField, FrameFieldWindow)
FileXML output;
// cause data to be stored directly in text
- output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+ output.set_shared_output(keyframe->xbuf);
output.tag.set_title("FRAME_FIELD");
output.tag.set_property("DOMINANCE", config.field_dominance);
output.append_tag();
{
FileXML input;
- input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+ input.set_shared_input(keyframe->xbuf);
while(!input.read_tag())
{
int FrameField::handle_opengl()
{
#ifdef HAVE_GL
- static const char *field_frag =
+ static const char *field_frag =
"uniform sampler2D tex;\n"
"uniform float double_line_h;\n"
"uniform float y_offset;\n"
" frac);\n"
"}\n";
- static const char *_601_to_rgb_frag =
+ static const char *_601_to_rgb_frag =
"void main()\n"
"{\n"
" gl_FragColor.rgb = gl_FragColor.rgb * vec3(1.1644, 1.1644, 1.1644) - vec3(0.0627, 0.0627, 0.0627);\n"
"}\n";
- static const char *_601_to_yuv_frag =
+ static const char *_601_to_yuv_frag =
"void main()\n"
"{\n"
" gl_FragColor.r = gl_FragColor.r * 1.1644 - 0.0627;\n"
"}\n";
- static const char *rgb_to_601_frag =
+ static const char *rgb_to_601_frag =
"void main()\n"
"{\n"
" gl_FragColor.rgb = gl_FragColor.rgb * vec3(0.8588, 0.8588, 0.8588) + vec3(0.0627, 0.0627, 0.0627);\n"
"}\n";
- static const char *yuv_to_601_frag =
+ static const char *yuv_to_601_frag =
"void main()\n"
"{\n"
" gl_FragColor.r = gl_FragColor.r * 0.8588 + 0.0627;\n"
VFrame::init_screen(get_output()->get_w(), get_output()->get_h());
glActiveTexture(GL_TEXTURE0);
BC_Texture::new_texture(&src_texture,
- get_output()->get_w(),
- get_output()->get_h(),
+ get_output()->get_w(),
+ get_output()->get_h(),
get_output()->get_color_model());
src_texture->bind(0);
glCopyTexSubImage2D(GL_TEXTURE_2D,
get_output()->enable_opengl();
}
- unsigned int frag = 0;
float y_offset = 0.0;
if(field_number == 0)
{
VFrame::init_screen(get_output()->get_w(), get_output()->get_h());
glActiveTexture(GL_TEXTURE0);
BC_Texture::new_texture(&src_texture,
- get_output()->get_w(),
- get_output()->get_h(),
+ get_output()->get_w(),
+ get_output()->get_h(),
get_output()->get_color_model());
+ const char *shader_stack[16];
+ memset(shader_stack,0, sizeof(shader_stack));
+ int current_shader = 0;
- const char *shaders[3] = { 0, 0, 0 };
- shaders[0] = field_frag;
-
+ shader_stack[current_shader++] = field_frag;
// Aggregate with other effect
//printf("FrameField::handle_opengl %s\n", get_output()->get_next_effect());
- if(aggregate_rgb601)
- {
- if(rgb601_direction == 1)
- {
- if(BC_CModels::is_yuv(get_output()->get_color_model()))
- shaders[1] = yuv_to_601_frag;
- else
- shaders[1] = rgb_to_601_frag;
- }
- else
- if(rgb601_direction == 2)
- {
- if(BC_CModels::is_yuv(get_output()->get_color_model()))
- shaders[1] = _601_to_yuv_frag;
- else
- shaders[1] = _601_to_rgb_frag;
+ if( aggregate_rgb601 ) {
+ switch( rgb601_direction ) {
+ case 1:
+ shader_stack[current_shader++] =
+ BC_CModels::is_yuv(get_output()->get_color_model()) ?
+ yuv_to_601_frag : rgb_to_601_frag;
+ break;
+ case 2:
+ shader_stack[current_shader++] =
+ BC_CModels::is_yuv(get_output()->get_color_model()) ?
+ _601_to_yuv_frag : _601_to_rgb_frag;
+ break;
}
}
-
-
- frag = VFrame::make_shader(0, shaders[0], shaders[1], shaders[2], 0);
-
-
- if(frag)
- {
- glUseProgram(frag);
- glUniform1i(glGetUniformLocation(frag, "tex"), 0);
- glUniform1f(glGetUniformLocation(frag, "double_line_h"),
+ shader_stack[current_shader] = 0;
+ unsigned int shader = VFrame::make_shader(shader_stack);
+ if( shader > 0 ) {
+ glUseProgram(shader);
+ glUniform1i(glGetUniformLocation(shader, "tex"), 0);
+ glUniform1f(glGetUniformLocation(shader, "double_line_h"),
2.0 / src_texture->get_texture_h());
- glUniform1f(glGetUniformLocation(frag, "y_offset"),
+ glUniform1f(glGetUniformLocation(shader, "y_offset"),
y_offset / src_texture->get_texture_h());
}
-
-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
get_output()->draw_texture();