dynamic keyframes, textbox rework, andrea ffmpeg.opts, perpetual chkpt undo, lv2...
[goodguy/history.git] / cinelerra-5.1 / plugins / framefield / framefield.C
index fabe7e0b48432ae36eefc7688c511968caf0c62d..314ab2b2bb6e8fb02018e133a9e84291d39108a3 100644 (file)
@@ -2,21 +2,21 @@
 /*
  * 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"
@@ -186,11 +186,11 @@ int FrameFieldConfig::equivalent(FrameFieldConfig &src)
 
 
 FrameFieldWindow::FrameFieldWindow(FrameField *plugin)
- : PluginClientWindow(plugin, 
-       210, 
-       160, 
-       200, 
-       160, 
+ : PluginClientWindow(plugin,
+       210,
+       160,
+       200,
+       160,
        0)
 {
        this->plugin = plugin;
@@ -218,12 +218,12 @@ void FrameFieldWindow::create_objects()
 
 
 
-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"))
 {
@@ -243,12 +243,12 @@ int FrameFieldTop::handle_event()
 
 
 
-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"))
 {
@@ -289,7 +289,7 @@ int FrameFieldBottom::handle_event()
 FrameField::FrameField(PluginServer *server)
  : PluginVClient(server)
 {
-       
+
        field_number = 0;
        src_frame = 0;
        src_frame_number = -1;
@@ -302,7 +302,7 @@ FrameField::FrameField(PluginServer *server)
 
 FrameField::~FrameField()
 {
-       
+
 
        if(src_frame) delete src_frame;
        if(src_texture) delete src_texture;
@@ -351,12 +351,8 @@ int FrameField::process_buffer(VFrame *frame,
 
                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;
        }
@@ -367,9 +363,9 @@ int FrameField::process_buffer(VFrame *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;
@@ -383,7 +379,7 @@ int FrameField::process_buffer(VFrame *frame,
                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();
@@ -393,13 +389,13 @@ int FrameField::process_buffer(VFrame *frame,
 // 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);
                        }
 
@@ -411,8 +407,8 @@ int FrameField::process_buffer(VFrame *frame,
                        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);
                        }
 
@@ -428,8 +424,8 @@ int FrameField::process_buffer(VFrame *frame,
                        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);
                        }
 
@@ -441,8 +437,8 @@ int FrameField::process_buffer(VFrame *frame,
                        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);
                        }
 
@@ -563,7 +559,7 @@ void FrameField::average_rows(int offset, VFrame *frame)
 
 
 
-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)
@@ -585,7 +581,7 @@ void FrameField::save_data(KeyFrame *keyframe)
        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();
@@ -599,7 +595,7 @@ void FrameField::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())
        {
@@ -627,7 +623,7 @@ void FrameField::update_gui()
 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"
@@ -647,25 +643,25 @@ int FrameField::handle_opengl()
                "               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"
@@ -692,8 +688,8 @@ int FrameField::handle_opengl()
                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,
@@ -722,7 +718,6 @@ int FrameField::handle_opengl()
                get_output()->enable_opengl();
        }
 
-       unsigned int frag = 0;
        float y_offset = 0.0;
        if(field_number == 0)
        {
@@ -738,53 +733,44 @@ int FrameField::handle_opengl()
        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();