/*
* 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 "clip.h"
#include "language.h"
#include "vframe.h"
-
-
-
-
-
-
-
-
#include <stdint.h>
#include <string.h>
REGISTER_PLUGIN(DeInterlaceMain)
-
-
-
DeInterlaceConfig::DeInterlaceConfig()
{
mode = DEINTERLACE_EVEN;
// threshold = that.threshold;
}
-void DeInterlaceConfig::interpolate(DeInterlaceConfig &prev,
- DeInterlaceConfig &next,
- int64_t prev_frame,
- int64_t next_frame,
+void DeInterlaceConfig::interpolate(DeInterlaceConfig &prev,
+ DeInterlaceConfig &next,
+ int64_t prev_frame,
+ int64_t next_frame,
int64_t current_frame)
{
copy_from(prev);
DeInterlaceMain::DeInterlaceMain(PluginServer *server)
: PluginVClient(server)
{
-
+
// temp = 0;
}
DeInterlaceMain::~DeInterlaceMain()
{
-
+
// if(temp) delete temp;
}
-const char* DeInterlaceMain::plugin_title() { return _("Deinterlace"); }
+const char* DeInterlaceMain::plugin_title() { return N_("Deinterlace"); }
int DeInterlaceMain::is_realtime() { return 1; }
load_configuration();
- read_frame(frame,
- 0,
- start_position,
+ read_frame(frame,
+ 0,
+ start_position,
frame_rate,
get_use_opengl());
if(get_use_opengl()) return run_opengl();
temp = frame;
// if(!temp)
-// temp = new VFrame(0,
-// frame->get_w(),
-// frame->get_h(),
-// frame->get_color_model());
+// temp = new VFrame(frame->get_w(), frame->get_h(),
+// frame->get_color_model(), 0);
switch(config.mode)
{
int DeInterlaceMain::handle_opengl()
{
#ifdef HAVE_GL
- static const char *head_frag =
+ static const char *head_frag =
"uniform sampler2D tex;\n"
"uniform float double_line_h;\n"
"uniform float line_h;\n"
"{\n"
" vec2 coord = gl_TexCoord[0].st;\n";
- static const char *line_double_frag =
+ static const char *line_double_frag =
" float line1 = floor((coord.y - y_offset) / double_line_h) * double_line_h + y_offset;\n"
" gl_FragColor = texture2D(tex, vec2(coord.x, line1));\n";
- static const char *line_avg_frag =
+ static const char *line_avg_frag =
" float line1 = floor((coord.y - 0.0) / double_line_h) * double_line_h + 0.0;\n"
" float line2 = line1 + line_h;\n"
" gl_FragColor = (texture2D(tex, vec2(coord.x, line1)) + \n"
" texture2D(tex, vec2(coord.x, line2))) / 2.0;\n";
- static const char *field_avg_frag =
+ static const char *field_avg_frag =
" float line1 = floor((coord.y - y_offset) / double_line_h) * double_line_h + y_offset;\n"
" float line2 = line1 + double_line_h;\n"
" float frac = (line2 - coord.y) / double_line_h;\n"
" gl_FragColor = mix(texture2D(tex, vec2(coord.x, line2)),\n"
" texture2D(tex, vec2(coord.x, line1)),frac);\n";
- static const char *line_swap_frag =
+ static const char *line_swap_frag =
" float line1 = floor((coord.y - y_offset) / double_line_h) * double_line_h + y_offset;\n"
// This is the input line for line2, not the denominator of the fraction
" float line2 = line1 + line_h;\n"
" gl_FragColor = mix(texture2D(tex, vec2(coord.x, line2)),\n"
" texture2D(tex, vec2(coord.x, line1)), frac);\n";
- static const char *tail_frag =
+ static const char *tail_frag =
"}\n";
get_output()->to_texture();
get_output()->enable_opengl();
get_output()->init_screen();
- const char *shader_stack[] = { 0, 0, 0 };
- shader_stack[0] = head_frag;
+ if( config.mode != DEINTERLACE_NONE ) {
+ const char *shader_stack[16];
+ memset(shader_stack,0, sizeof(shader_stack));
+ int current_shader = 0;
- float double_line_h = 2.0 / get_output()->get_texture_h();
- float line_h = 1.0 / get_output()->get_texture_h();
- float y_offset = 0.0;
- switch(config.mode)
- {
+ shader_stack[current_shader++] = head_frag;
+
+ float double_line_h = 2.0 / get_output()->get_texture_h();
+ float line_h = 1.0 / get_output()->get_texture_h();
+ float y_offset = 0.0;
+ const char *shader_frag = 0;
+
+ switch(config.mode) {
case DEINTERLACE_EVEN:
- shader_stack[1] = line_double_frag;
+ shader_frag = line_double_frag;
break;
case DEINTERLACE_ODD:
- shader_stack[1] = line_double_frag;
+ shader_frag = line_double_frag;
y_offset += 1.0;
break;
case DEINTERLACE_AVG:
- shader_stack[1] = line_avg_frag;
+ shader_frag = line_avg_frag;
break;
case DEINTERLACE_AVG_EVEN:
- shader_stack[1] = field_avg_frag;
+ shader_frag = field_avg_frag;
break;
case DEINTERLACE_AVG_ODD:
- shader_stack[1] = field_avg_frag;
+ shader_frag = field_avg_frag;
y_offset += 1.0;
break;
case DEINTERLACE_SWAP_EVEN:
- shader_stack[1] = line_swap_frag;
+ shader_frag = line_swap_frag;
break;
case DEINTERLACE_SWAP_ODD:
- shader_stack[1] = line_swap_frag;
+ shader_frag = line_swap_frag;
y_offset += 1.0;
break;
- }
-
- y_offset /= get_output()->get_texture_h();
-
- shader_stack[2] = tail_frag;
-
- if(config.mode != DEINTERLACE_NONE)
- {
- unsigned int frag = VFrame::make_shader(0,
- shader_stack[0],
- shader_stack[1],
- shader_stack[2],
- 0);
- if(frag)
- {
- glUseProgram(frag);
- glUniform1i(glGetUniformLocation(frag, "tex"), 0);
- glUniform1f(glGetUniformLocation(frag, "line_h"), line_h);
- glUniform1f(glGetUniformLocation(frag, "double_line_h"), double_line_h);
- glUniform1f(glGetUniformLocation(frag, "y_offset"), y_offset);
+ }
+ if( shader_frag )
+ shader_stack[current_shader++] = shader_frag;
+
+ shader_stack[current_shader++] = tail_frag;
+ shader_stack[current_shader] = 0;
+ unsigned int shader = VFrame::make_shader(shader_stack);
+ if( shader > 0 ) {
+ y_offset /= get_output()->get_texture_h();
+ glUseProgram(shader);
+ glUniform1i(glGetUniformLocation(shader, "tex"), 0);
+ glUniform1f(glGetUniformLocation(shader, "line_h"), line_h);
+ glUniform1f(glGetUniformLocation(shader, "double_line_h"), double_line_h);
+ glUniform1f(glGetUniformLocation(shader, "y_offset"), y_offset);
}
}
get_output()->set_opengl_state(VFrame::SCREEN);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
+
#endif
return 0;
}
void DeInterlaceMain::save_data(KeyFrame *keyframe)
{
FileXML output;
- output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+ output.set_shared_output(keyframe->xbuf);
output.tag.set_title("DEINTERLACE");
output.tag.set_property("MODE", config.mode);
// output.tag.set_property("ADAPTIVE", config.adaptive);
void DeInterlaceMain::read_data(KeyFrame *keyframe)
{
FileXML input;
- input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+ input.set_shared_input(keyframe->xbuf);
while(!input.read_tag())
{
void DeInterlaceMain::update_gui()
{
- if(thread)
+ if(thread)
{
load_configuration();
((DeInterlaceWindow*)thread->window)->lock_window();