From: Good Guy Date: Thu, 7 Dec 2017 02:28:46 +0000 (-0700) Subject: opengl colorspace + BT2020 X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=af44bff549c39ac8bb6e42a791e7a211e1013526;p=goodguy%2Fhistory.git opengl colorspace + BT2020 ffmpeg default file color model vframe params framecache fix make_shader rework fix segv if open mixer window with no tracks selected dmp upgrade for open files/pos + user memory status colorspace in plugins, timefront fix, yuv clamps diffkey improvements, needs more attention --- diff --git a/cinelerra-5.1/cinelerra/affine.C b/cinelerra-5.1/cinelerra/affine.C index b1af491d..ff9c4709 100644 --- a/cinelerra-5.1/cinelerra/affine.C +++ b/cinelerra-5.1/cinelerra/affine.C @@ -491,9 +491,7 @@ void AffineUnit::process_package(LoadPackage *package) server->output->to_texture(); server->output->enable_opengl(); - unsigned int frag_shader = VFrame::make_shader(0, - affine_frag, - 0); + unsigned int frag_shader = VFrame::make_shader(0, affine_frag, 0); if( frag_shader > 0 ) { glUseProgram(frag_shader); glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); diff --git a/cinelerra-5.1/cinelerra/appearanceprefs.C b/cinelerra-5.1/cinelerra/appearanceprefs.C index 90b39c00..7342e3ea 100644 --- a/cinelerra-5.1/cinelerra/appearanceprefs.C +++ b/cinelerra-5.1/cinelerra/appearanceprefs.C @@ -539,6 +539,7 @@ int HighlightInverseColor::handle_event() const char *YuvColorSpace::color_space[] = { N_("BT601"), N_("BT709"), + N_("BT2020"), }; YuvColorSpace::YuvColorSpace(int x, int y, PreferencesWindow *pwindow) diff --git a/cinelerra-5.1/cinelerra/appearanceprefs.h b/cinelerra-5.1/cinelerra/appearanceprefs.h index e93563a5..600b8270 100644 --- a/cinelerra-5.1/cinelerra/appearanceprefs.h +++ b/cinelerra-5.1/cinelerra/appearanceprefs.h @@ -255,7 +255,7 @@ public: class YuvColorSpace : public BC_PopupMenu { - static const char *color_space[2]; + static const char *color_space[3]; public: YuvColorSpace(int x, int y, PreferencesWindow *pwindow); ~YuvColorSpace(); diff --git a/cinelerra-5.1/cinelerra/fileffmpeg.C b/cinelerra-5.1/cinelerra/fileffmpeg.C index 4d797431..82a810d6 100644 --- a/cinelerra-5.1/cinelerra/fileffmpeg.C +++ b/cinelerra-5.1/cinelerra/fileffmpeg.C @@ -342,9 +342,9 @@ int FileFFMPEG::get_best_colormodel(int driver, int vstream) int is_mpeg = !ff ? 0 : ff->ff_video_mpeg_color_range(vstream); switch(driver) { - case PLAYBACK_X11: return is_mpeg ? BC_YUV888 : BC_RGB888; + case PLAYBACK_X11: + case PLAYBACK_X11_GL: return is_mpeg ? BC_YUV888 : BC_RGB888; case PLAYBACK_X11_XV: return BC_YUV420P; - case PLAYBACK_X11_GL: return BC_RGB_FLOAT; } return BC_RGB888; @@ -354,9 +354,9 @@ int FileFFMPEG::get_best_colormodel(Asset *asset, int driver) { switch(driver) { // the direct X11 color model requires scaling in the codec - case PLAYBACK_X11: return BC_RGB888; + case PLAYBACK_X11: + case PLAYBACK_X11_GL: return BC_RGB888; case PLAYBACK_X11_XV: return BC_YUV420P; - case PLAYBACK_X11_GL: return BC_RGB_FLOAT; } return BC_YUV420P; diff --git a/cinelerra-5.1/cinelerra/framecache.C b/cinelerra-5.1/cinelerra/framecache.C index 6e9fc4d6..fdf7ef35 100644 --- a/cinelerra-5.1/cinelerra/framecache.C +++ b/cinelerra-5.1/cinelerra/framecache.C @@ -123,14 +123,8 @@ int FrameCache::get_frame(VFrame *frame, // result->data->get_w(), // frame->get_w()); - +// no context data since keyframe updates may vary input frame->copy_from(result->data); - - -// This would have copied the color matrix for interpolate, but -// required the same plugin stack as the reader. -// frame->copy_stacks(result->data); - frame->copy_params(result->data); } result->age = get_age(); } diff --git a/cinelerra-5.1/cinelerra/playback3d.C b/cinelerra-5.1/cinelerra/playback3d.C index 835d8a22..04c668be 100644 --- a/cinelerra-5.1/cinelerra/playback3d.C +++ b/cinelerra-5.1/cinelerra/playback3d.C @@ -21,6 +21,7 @@ #define GL_GLEXT_PROTOTYPES +#include "bccolors.h" #include "bcsignals.h" #include "bcwindowbase.h" #include "canvas.h" @@ -59,14 +60,12 @@ #ifdef HAVE_GL static const char *yuv_to_rgb_frag = "uniform sampler2D tex;\n" + "uniform mat3 yuv_to_rgb_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 yuva = texture2D(tex, gl_TexCoord[0].st);\n" - " yuva.rgb -= vec3(0, 0.5, 0.5);\n" - " const mat3 yuv_to_rgb_matrix = mat3(\n" - " 1, 1, 1, \n" - " 0, -0.34414, 1.77200, \n" - " 1.40200, -0.71414, 0);\n" + " yuva.rgb -= vec3(yminf, 0.5, 0.5);\n" " gl_FragColor = vec4(yuv_to_rgb_matrix * yuva.rgb, yuva.a);\n" "}\n"; @@ -86,14 +85,12 @@ static const char *yuva_to_yuv_frag = static const char *yuva_to_rgb_frag = "uniform sampler2D tex;\n" + "uniform mat3 yuv_to_rgb_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 yuva = texture2D(tex, gl_TexCoord[0].st);\n" - " yuva.rgb -= vec3(0, 0.5, 0.5);\n" - " const mat3 yuv_to_rgb_matrix = mat3(\n" - " 1, 1, 1, \n" - " 0, -0.34414, 1.77200, \n" - " 1.40200, -0.71414, 0);\n" + " yuva.rgb -= vec3(yminf, 0.5, 0.5);\n" " yuva.rgb = yuv_to_rgb_matrix * yuva.rgb;\n" " yuva.rgb *= yuva.a;\n" " yuva.a = 1.0;\n" @@ -102,15 +99,13 @@ static const char *yuva_to_rgb_frag = static const char *rgb_to_yuv_frag = "uniform sampler2D tex;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 rgba = texture2D(tex, gl_TexCoord[0].st);\n" - " const mat3 rgb_to_yuv_matrix = mat3(\n" - " 0.29900, -0.16874, 0.50000, \n" - " 0.58700, -0.33126, -0.41869, \n" - " 0.11400, 0.50000, -0.08131);\n" " rgba.rgb = rgb_to_yuv_matrix * rgba.rgb;\n" - " rgba.rgb += vec3(0, 0.5, 0.5);\n" + " rgba.rgb += vec3(yminf, 0.5, 0.5);\n" " gl_FragColor = rgba;\n" "}\n"; @@ -127,17 +122,15 @@ static const char *rgba_to_rgb_frag = static const char *rgba_to_yuv_frag = "uniform sampler2D tex;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 rgba = texture2D(tex, gl_TexCoord[0].st);\n" - " const mat3 rgb_to_yuv_matrix = mat3(\n" - " 0.29900, -0.16874, 0.50000, \n" - " 0.58700, -0.33126, -0.41869, \n" - " 0.11400, 0.50000, -0.08131);\n" " rgba.rgb *= rgba.a;\n" " rgba.a = 1.0;\n" " rgba.rgb = rgb_to_yuv_matrix * rgba.rgb;\n" - " rgba.rgb += vec3(0, 0.5, 0.5);\n" + " rgba.rgb += vec3(yminf, 0.5, 0.5);\n" " gl_FragColor = rgba;\n" "}\n"; @@ -701,28 +694,15 @@ void Playback3D::draw_output(Playback3DCommand *command) // Undo any previous shader settings command->frame->bind_texture(0); - - - // Convert colormodel - unsigned int frag_shader = 0; - switch(command->frame->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - frag_shader = VFrame::make_shader(0, - yuv_to_rgb_frag, - 0); - break; - } - - - if(frag_shader > 0) - { - glUseProgram(frag_shader); - int variable = glGetUniformLocation(frag_shader, "tex"); + unsigned int shader = !BC_CModels::is_yuv(command->frame->get_color_model()) ? 0 : + VFrame::make_shader(0, yuv_to_rgb_frag, 0); + if( shader > 0 ) { + glUseProgram(shader); // Set texture unit of the texture + int variable = glGetUniformLocation(shader, "tex"); glUniform1i(variable, 0); + BC_GL_YUV_TO_RGB(shader); } if(BC_CModels::components(command->frame->get_color_model()) == 4) @@ -1006,8 +986,9 @@ void Playback3D::overlay_sync(Playback3DCommand *command) } - const char *shader_stack[4] = { 0, 0, 0, 0, }; - int total_shaders = 0; + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int total_shaders = 0, need_matrix = 0; VFrame::init_screen(canvas_w, canvas_h); @@ -1016,13 +997,10 @@ void Playback3D::overlay_sync(Playback3DCommand *command) // Convert colormodel to RGB if not nested. // The color model setting in the output frame is ignored. - if( command->is_nested <= 0 ) { // not nested - switch(command->input->get_color_model()) { - case BC_YUV888: - case BC_YUVA8888: - shader_stack[total_shaders++] = yuv_to_rgb_frag; - break; - } + 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 @@ -1055,24 +1033,22 @@ void Playback3D::overlay_sync(Playback3DCommand *command) } // run the shaders - unsigned int frag_shader = 0; - if(shader_stack[0]) { - frag_shader = VFrame::make_shader(0, - shader_stack[0], shader_stack[1], - shader_stack[2], shader_stack[3], 0); - - glUseProgram(frag_shader); - + add_shader(0); + unsigned int shader = !shader_stack[0] ? 0 : + VFrame::make_shader(shader_stack); + if( shader > 0 ) { + glUseProgram(shader); + if( need_matrix ) BC_GL_YUV_TO_RGB(shader); // Set texture unit of the texture - glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); // Set texture unit of the temp texture - glUniform1i(glGetUniformLocation(frag_shader, "tex2"), 1); + glUniform1i(glGetUniformLocation(shader, "tex2"), 1); // Set alpha - int variable = glGetUniformLocation(frag_shader, "alpha"); + int variable = glGetUniformLocation(shader, "alpha"); glUniform1f(variable, command->alpha); // Set dimensions of the temp texture if(temp_texture) - glUniform2f(glGetUniformLocation(frag_shader, "tex2_dimensions"), + glUniform2f(glGetUniformLocation(shader, "tex2_dimensions"), (float)temp_texture->get_texture_w(), (float)temp_texture->get_texture_h()); } @@ -1399,27 +1375,19 @@ void Playback3D::do_mask_sync(Playback3DCommand *command) // For unfeathered masks, we could use a stencil buffer // for further optimization but we also need a YUV algorithm. unsigned int frag_shader = 0; - switch(temp_texture->get_texture_components()) - { - case 3: - if(command->frame->get_color_model() == BC_YUV888) - frag_shader = VFrame::make_shader(0, - multiply_yuvmask3_frag, - 0); - else - frag_shader = VFrame::make_shader(0, - multiply_mask3_frag, - 0); - break; - case 4: - frag_shader = VFrame::make_shader(0, - multiply_mask4_frag, - 0); - break; + switch(temp_texture->get_texture_components()) { + case 3: + frag_shader = VFrame::make_shader(0, + command->frame->get_color_model() == BC_YUV888 ? + multiply_yuvmask3_frag : multiply_mask3_frag, + 0); + break; + case 4: + frag_shader = VFrame::make_shader(0, multiply_mask4_frag, 0); + break; } - if(frag_shader) - { + if( frag_shader ) { int variable; glUseProgram(frag_shader); if((variable = glGetUniformLocation(frag_shader, "tex")) >= 0) @@ -1502,8 +1470,7 @@ void Playback3D::convert_cmodel_sync(Playback3DCommand *command) #ifdef HAVE_GL command->canvas->lock_canvas("Playback3D::convert_cmodel_sync"); - if(command->canvas->get_canvas()) - { + if( command->canvas->get_canvas() ) { BC_WindowBase *window = command->canvas->get_canvas(); window->lock_window("Playback3D::convert_cmodel_sync"); window->enable_opengl(); @@ -1514,47 +1481,45 @@ void Playback3D::convert_cmodel_sync(Playback3DCommand *command) command->frame->to_texture(); // Colormodel permutation - const char *shader = 0; int src_cmodel = command->frame->get_color_model(); int dst_cmodel = command->dst_cmodel; - typedef struct - { - int src; - int dst; + typedef struct { + int src, dst, typ; const char *shader; } cmodel_shader_table_t; - static cmodel_shader_table_t cmodel_shader_table[] = - { - { BC_RGB888, BC_YUV888, rgb_to_yuv_frag }, - { BC_RGB888, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_RGBA8888, BC_RGB888, rgba_to_rgb_frag }, - { BC_RGBA8888, BC_RGB_FLOAT, rgba_to_rgb_frag }, - { BC_RGBA8888, BC_YUV888, rgba_to_yuv_frag }, - { BC_RGBA8888, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_RGB_FLOAT, BC_YUV888, rgb_to_yuv_frag }, - { BC_RGB_FLOAT, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_RGBA_FLOAT, BC_RGB888, rgba_to_rgb_frag }, - { BC_RGBA_FLOAT, BC_RGB_FLOAT, rgba_to_rgb_frag }, - { BC_RGBA_FLOAT, BC_YUV888, rgba_to_yuv_frag }, - { BC_RGBA_FLOAT, BC_YUVA8888, rgb_to_yuv_frag }, - { BC_YUV888, BC_RGB888, yuv_to_rgb_frag }, - { BC_YUV888, BC_RGBA8888, yuv_to_rgb_frag }, - { BC_YUV888, BC_RGB_FLOAT, yuv_to_rgb_frag }, - { BC_YUV888, BC_RGBA_FLOAT, yuv_to_rgb_frag }, - { BC_YUVA8888, BC_RGB888, yuva_to_rgb_frag }, - { BC_YUVA8888, BC_RGBA8888, yuv_to_rgb_frag }, - { BC_YUVA8888, BC_RGB_FLOAT, yuva_to_rgb_frag }, - { BC_YUVA8888, BC_RGBA_FLOAT, yuv_to_rgb_frag }, - { BC_YUVA8888, BC_YUV888, yuva_to_yuv_frag }, + enum { rgb_to_rgb, rgb_to_yuv, yuv_to_rgb, yuv_to_yuv, }; + int type = -1; + static cmodel_shader_table_t cmodel_shader_table[] = { + { BC_RGB888, BC_YUV888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGB888, BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGBA8888, BC_RGB888, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA8888, BC_RGB_FLOAT, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA8888, BC_YUV888, rgb_to_yuv, rgba_to_yuv_frag }, + { BC_RGBA8888, BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGB_FLOAT, BC_YUV888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGB_FLOAT, BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_RGBA_FLOAT,BC_RGB888, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA_FLOAT,BC_RGB_FLOAT, rgb_to_rgb, rgba_to_rgb_frag }, + { BC_RGBA_FLOAT,BC_YUV888, rgb_to_yuv, rgba_to_yuv_frag }, + { BC_RGBA_FLOAT,BC_YUVA8888, rgb_to_yuv, rgb_to_yuv_frag }, + { BC_YUV888, BC_RGB888, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUV888, BC_RGBA8888, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUV888, BC_RGB_FLOAT, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUV888, BC_RGBA_FLOAT, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUVA8888, BC_RGB888, yuv_to_rgb, yuva_to_rgb_frag }, + { BC_YUVA8888, BC_RGBA8888, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUVA8888, BC_RGB_FLOAT, yuv_to_rgb, yuva_to_rgb_frag }, + { BC_YUVA8888, BC_RGBA_FLOAT, yuv_to_rgb, yuv_to_rgb_frag }, + { BC_YUVA8888, BC_YUV888, yuv_to_yuv, yuva_to_yuv_frag }, }; + const char *shader = 0; int table_size = sizeof(cmodel_shader_table) / sizeof(cmodel_shader_table_t); - for(int i = 0; i < table_size; i++) - { - if(cmodel_shader_table[i].src == src_cmodel && - cmodel_shader_table[i].dst == dst_cmodel) - { + for( int i=0; idst_cmodel, // shader); - if(shader) - { + const char *shader_stack[9]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + if( shader ) { //printf("Playback3D::convert_cmodel_sync %d\n", __LINE__); + shader_stack[current_shader++] = shader; + shader_stack[current_shader] = 0; + unsigned int shader_id = VFrame::make_shader(shader_stack); + command->frame->bind_texture(0); - unsigned int shader_id = -1; - if(shader) - { - shader_id = VFrame::make_shader(0, - shader, - 0); - glUseProgram(shader_id); - glUniform1i(glGetUniformLocation(shader_id, "tex"), 0); + glUseProgram(shader_id); + + glUniform1i(glGetUniformLocation(shader_id, "tex"), 0); + switch( type ) { + case rgb_to_yuv: + BC_GL_RGB_TO_YUV(shader_id); + break; + case yuv_to_rgb: + BC_GL_YUV_TO_RGB(shader_id); + break; } command->frame->draw_texture(); - if(shader) glUseProgram(0); - command->frame->set_opengl_state(VFrame::SCREEN); } @@ -1659,8 +1631,7 @@ void Playback3D::do_fade_sync(Playback3DCommand *command) } - if(frag_shader) - { + if( frag_shader ) { glUseProgram(frag_shader); int variable; if((variable = glGetUniformLocation(frag_shader, "tex")) >= 0) diff --git a/cinelerra-5.1/cinelerra/playback3d.h b/cinelerra-5.1/cinelerra/playback3d.h index ccba7d8d..314f392a 100644 --- a/cinelerra-5.1/cinelerra/playback3d.h +++ b/cinelerra-5.1/cinelerra/playback3d.h @@ -23,6 +23,7 @@ #define PLAYBACK3D_H #include "arraylist.h" +#include "bccolors.h" #include "bcpixmap.inc" #include "bcsynchronous.h" #include "bcwindowbase.inc" @@ -39,21 +40,43 @@ +// use static presets YUV in bccolors.h +#define BC_GL_MATRIX(shader, mat) \ + glUniformMatrix3fv(glGetUniformLocation(shader, #mat), 1, 0, YUV::mat) + +#define BC_GL_YMINF(shader,mat) \ + glUniform1f(glGetUniformLocation(shader, "yminf"), YUV::mat[9]) + +#define BC_GL_RGB_TO_YUV(shader) do { \ + BC_GL_MATRIX(shader, rgb_to_yuv_matrix); \ + BC_GL_YMINF(shader, rgb_to_yuv_matrix); \ +} while(0) + +#define BC_GL_YUV_TO_RGB(shader) do { \ + BC_GL_MATRIX(shader, yuv_to_rgb_matrix); \ + BC_GL_YMINF(shader, yuv_to_rgb_matrix); \ +} while(0) + +#define BC_GL_COLORS(shader) do { \ + BC_GL_MATRIX(shader, yuv_to_rgb_matrix); \ + BC_GL_MATRIX(shader, rgb_to_yuv_matrix); \ + BC_GL_YMINF(shader, rgb_to_yuv_matrix); \ +} while(0) + + +#define bc_gl_yuv_to_rgb "uniform mat3 yuv_to_rgb_matrix;\n" +#define bc_gl_rgb_to_yuv "uniform mat3 rgb_to_yuv_matrix;\n" +#define bc_gl_yminf "uniform float yminf;\n" +#define bc_gl_colors bc_gl_yuv_to_rgb bc_gl_rgb_to_yuv bc_gl_yminf // Macros for useful fragment shaders #define YUV_TO_RGB_FRAG(PIXEL) \ - PIXEL ".gb -= vec2(0.5, 0.5);\n" \ - PIXEL ".rgb = mat3(\n" \ - " 1, 1, 1, \n" \ - " 0, -0.34414, 1.77200, \n" \ - " 1.40200, -0.71414, 0) * " PIXEL ".rgb;\n" + PIXEL ".rgb -= vec3(yminf, 0.5, 0.5);\n" \ + PIXEL ".rgb = yuv_to_rgb_matrix * " PIXEL ".rgb;\n" #define RGB_TO_YUV_FRAG(PIXEL) \ - PIXEL ".rgb = mat3(\n" \ - " 0.29900, -0.16874, 0.50000, \n" \ - " 0.58700, -0.33126, -0.41869, \n" \ - " 0.11400, 0.50000, -0.08131) * " PIXEL ".rgb;\n" \ - PIXEL ".gb += vec2(0.5, 0.5);\n" + PIXEL ".rgb = rgb_to_yuv_matrix * " PIXEL ".rgb;\n" \ + PIXEL ".rgb += vec3(yminf, 0.5, 0.5);\n" #define RGB_TO_HSV_FRAG(PIXEL) \ "{\n" \ @@ -163,8 +186,6 @@ "" PIXEL ".b = b;\n" \ "}\n" - - class Playback3DCommand : public BC_SynchronousCommand { public: diff --git a/cinelerra-5.1/cinelerra/zwindow.C b/cinelerra-5.1/cinelerra/zwindow.C index c970f22f..80234ca0 100644 --- a/cinelerra-5.1/cinelerra/zwindow.C +++ b/cinelerra-5.1/cinelerra/zwindow.C @@ -73,7 +73,7 @@ void Mixers::del_mixer(int idx) void Mixer::set_title(const char *tp) { if( tp == title ) return; - strncpy(title, tp, sizeof(title)); + strncpy(title, !tp ? "" : tp, sizeof(title)); title[sizeof(title)-1] = 0; } diff --git a/cinelerra-5.1/guicast/bccolors.C b/cinelerra-5.1/guicast/bccolors.C index a287fb78..78aaf64f 100644 --- a/cinelerra-5.1/guicast/bccolors.C +++ b/cinelerra-5.1/guicast/bccolors.C @@ -126,6 +126,8 @@ int HSV::hsv_to_yuv(int &y, int &u, int &v, float h, float s, float va, int max) YUV YUV::yuv; +float YUV::rgb_to_yuv_matrix[10]; +float YUV::yuv_to_rgb_matrix[10]; YUV::YUV() { @@ -140,13 +142,14 @@ void YUV::yuv_set_colors(int color_space, int color_range) int mpeg; switch( color_space ) { default: - case 0: kr = BT601_Kr; kb = BT601_Kb; break; - case 1: kr = BT709_Kr; kb = BT709_Kb; break; + case BC_COLORS_BT601: kr = BT601_Kr; kb = BT601_Kb; break; + case BC_COLORS_BT709: kr = BT709_Kr; kb = BT709_Kb; break; + case BC_COLORS_BT2020: kr = BT2020_Kr; kb = BT2020_Kb; break; } switch( color_range ) { default: - case 0: mpeg = 0; break; - case 1: mpeg = 1; break; + case BC_COLORS_JPEG: mpeg = 0; break; + case BC_COLORS_MPEG: mpeg = 1; break; } init(kr, kb, mpeg); } @@ -219,6 +222,29 @@ void YUV::init(double Kr, double Kb, int mpeg) vtor8f, vtog8f, utog8f, utob8f); init_tables(0x10000, vtor16f, vtog16f, utog16f, utob16f); + + rgb_to_yuv_matrix[0] = r_to_y; + rgb_to_yuv_matrix[1] = r_to_u; + rgb_to_yuv_matrix[2] = r_to_v; + rgb_to_yuv_matrix[3] = g_to_y; + rgb_to_yuv_matrix[4] = g_to_u; + rgb_to_yuv_matrix[5] = g_to_v; + rgb_to_yuv_matrix[6] = b_to_y; + rgb_to_yuv_matrix[7] = b_to_u; + rgb_to_yuv_matrix[8] = b_to_v; + rgb_to_yuv_matrix[9] = yminf; + + float yscale = 1.f / yrangef; + yuv_to_rgb_matrix[0] = yscale; + yuv_to_rgb_matrix[1] = yscale; + yuv_to_rgb_matrix[2] = yscale; + yuv_to_rgb_matrix[3] = 0; + yuv_to_rgb_matrix[4] = u_to_g; + yuv_to_rgb_matrix[5] = u_to_b; + yuv_to_rgb_matrix[6] = v_to_r; + yuv_to_rgb_matrix[7] = v_to_g; + yuv_to_rgb_matrix[8] = 0; + yuv_to_rgb_matrix[9] = yminf; } void YUV::init_tables(int len, diff --git a/cinelerra-5.1/guicast/bccolors.h b/cinelerra-5.1/guicast/bccolors.h index ed3b6fe1..720735ce 100644 --- a/cinelerra-5.1/guicast/bccolors.h +++ b/cinelerra-5.1/guicast/bccolors.h @@ -24,31 +24,12 @@ // Duplicate filename in guicast +#include "bccolors.inc" #include "clip.h" #include "vframe.inc" #include -// bt601 coefs originaly used -// Compression coefficients straight out of jpeglib -#define R_TO_Y 0.29900 -#define G_TO_Y 0.58700 -#define B_TO_Y 0.11400 - -#define R_TO_U -0.16874 -#define G_TO_U -0.33126 -#define B_TO_U 0.50000 - -#define R_TO_V 0.50000 -#define G_TO_V -0.41869 -#define B_TO_V -0.08131 - -// Decompression coefficients straight out of jpeglib -#define V_TO_R 1.40200 -#define V_TO_G -0.71414 - -#define U_TO_G -0.34414 -#define U_TO_B 1.77200 /* Digital YCbCr is derived from analog RGB as follows: @@ -198,8 +179,6 @@ class YUV #define utog8f (tabf+0x40200) #define utob8f (tabf+0x40300) -#define bc_always_inline __attribute__ ((__always_inline__)) inline - public: YUV(); ~YUV(); @@ -207,11 +186,13 @@ public: inline int is_mpeg() { return mpeg; } static YUV yuv; + static float rgb_to_yuv_matrix[10]; + static float yuv_to_rgb_matrix[10]; #define YUV_rgb_to_yuv_8(r,g,b, y,u,v) \ - y = (rtoy8[r] + gtoy8[g] + btoy8[b] + yzero) >> 16; \ - u = (rtou8[r] + gtou8[g] + btou8[b] + uvzero) >> 16; \ - v = (rtov8[r] + gtov8[g] + btov8[b] + uvzero) >> 16 + y = iclip((rtoy8[r] + gtoy8[g] + btoy8[b] + yzero) >> 16, ymin8, ymax8); \ + u = iclip((rtou8[r] + gtou8[g] + btou8[b] + uvzero) >> 16, uvmin8, uvmax8); \ + v = iclip((rtov8[r] + gtov8[g] + btov8[b] + uvzero) >> 16, uvmin8, uvmax8) bc_always_inline void rgb_to_yuv_8(int r, int g, int b, int &y, int &u, int &v) { YUV_rgb_to_yuv_8(r,g,b, y,u,v); @@ -224,9 +205,9 @@ public: } #define YUV_rgb_to_yuv_16(r,g,b, y,u,v) \ - y = (rtoy16[r] + gtoy16[g] + btoy16[b] + yzero) >> 8; \ - u = (rtou16[r] + gtou16[g] + btou16[b] + uvzero) >> 8; \ - v = (rtov16[r] + gtov16[g] + btov16[b] + uvzero) >> 8 + y = iclip((rtoy16[r] + gtoy16[g] + btoy16[b] + yzero) >> 8, ymin16, ymax16); \ + u = iclip((rtou16[r] + gtou16[g] + btou16[b] + uvzero) >> 8, uvmin16, uvmax16); \ + v = iclip((rtov16[r] + gtov16[g] + btov16[b] + uvzero) >> 8, uvmin16, uvmax16) bc_always_inline void rgb_to_yuv_16(int r, int g, int b, int &y, int &u, int &v) { YUV_rgb_to_yuv_16(r,g,b, y,u,v); @@ -244,58 +225,51 @@ public: u = r * r_to_u + g * g_to_u + b * b_to_u; v = r * r_to_v + g * g_to_v + b * b_to_v; } - bc_always_inline void rgb_to_yuv_8(float r, float g, float b, int &y, int &u, int &v) { - float fy, fu, fv; rgb_to_yuv_f(r, g, b, fy, fu, fv); - int iy = fy * 0x100, iu = fu * 0x100, iv = fv * 0x100; - CLAMP(iy, ymin8, ymax8); - CLAMP(iu, uvmin8, uvmax8); CLAMP(iv, uvmin8, uvmax8); - y = iy; u = iu; v = iv; + bc_always_inline void rgb_to_yuv_f(float r, float g, float b, uint8_t &y, uint8_t &u, uint8_t &v) { + int ir = iclip(r*0x100, 0, 0xff); + int ig = iclip(g*0x100, 0, 0xff); + int ib = iclip(b*0x100, 0, 0xff); + rgb_to_yuv_8(ir,ig,ib, y,u,v); } - bc_always_inline void rgb_to_yuv_16(float r, float g, float b, - int &y, int &u, int &v) { - float fy, fu, fv; rgb_to_yuv_f(r, g, b, fy, fu, fv); - int iy = fy * 0x10000, iu = fu * 0x10000, iv = fv * 0x10000; - CLAMP(iy, ymin16, ymax16); - CLAMP(iu, uvmin16, uvmax16); CLAMP(iv, uvmin16, uvmax16); - y = iy; u = iu; v = iv; + bc_always_inline void rgb_to_yuv_f(float r, float g, float b, uint16_t &y, uint16_t &u, uint16_t &v) { + int ir = iclip(r*0x10000, 0, 0xffff); + int ig = iclip(g*0x10000, 0, 0xffff); + int ib = iclip(b*0x10000, 0, 0xffff); + rgb_to_yuv_16(ir,ig,ib, y,u,v); } #define YUV_yuv_to_rgb_8(r,g,b, y,u,v) \ - r = (ytab8[y] + vtor8[v]) >> 16; \ - g = (ytab8[y] + utog8[u] + vtog8[v]) >> 16; \ - b = (ytab8[y] + utob8[u]) >> 16 + r = iclip((ytab8[y] + vtor8[v]) >> 16, 0, 0xff); \ + g = iclip((ytab8[y] + utog8[u] + vtog8[v]) >> 16, 0, 0xff); \ + b = iclip((ytab8[y] + utob8[u]) >> 16, 0, 0xff) bc_always_inline void yuv_to_rgb_8(int &r, int &g, int &b, int y, int u, int v) { YUV_yuv_to_rgb_8(r,g,b, y,u,v); - CLAMP(r, 0, 0xff); CLAMP(g, 0, 0xff); CLAMP(b, 0, 0xff); } bc_always_inline void yuv_to_rgb_8(uint8_t &r, uint8_t &g, uint8_t &b, int y, int u, int v) { YUV_yuv_to_rgb_8(r,g,b, y,u,v); } bc_always_inline void yuv_to_rgb_8(int &r, int &g, int &b) { int y = r, u = g, v = b; YUV_yuv_to_rgb_8(r,g,b, y,u,v); - CLAMP(r, 0, 0xff); CLAMP(g, 0, 0xff); CLAMP(b, 0, 0xff); } bc_always_inline void yuv_to_rgb_8(float &r, float &g, float &b, int y, int u, int v) { - int ir, ig, ib; YUV_yuv_to_rgb_8(ir,ig,ib, y,u,v); + int ir, ig, ib; yuv_to_rgb_8(ir,ig,ib, y,u,v); float s = 1/255.f; r = s*ir; g = s*ig; b = s*ib; } #define YUV_yuv_to_rgb_16(r,g,b, y,u,v) \ - r = (ytab16[y] + vtor16[v]) >> 8; \ - g = (ytab16[y] + utog16[u] + vtog16[v]) >> 8; \ - b = (ytab16[y] + utob16[u]) >> 8 + r = iclip((ytab16[y] + vtor16[v]) >> 8, 0, 0xffff); \ + g = iclip((ytab16[y] + utog16[u] + vtog16[v]) >> 8, 0, 0xffff); \ + b = iclip((ytab16[y] + utob16[u]) >> 8, 0, 0xffff) bc_always_inline void yuv_to_rgb_16(int &r, int &g, int &b, int y, int u, int v) { YUV_yuv_to_rgb_16(r,g,b, y,u,v); - CLAMP(r, 0, 0xffff); CLAMP(g, 0, 0xffff); CLAMP(b, 0, 0xffff); } bc_always_inline void yuv_to_rgb_16(uint16_t &r, uint16_t &g, uint16_t &b, int y, int u, int v) { YUV_yuv_to_rgb_16(r,g,b, y,u,v); } bc_always_inline void yuv_to_rgb_16(int &r, int &g, int &b) { int y = r, u = g, v = b; YUV_yuv_to_rgb_16(r,g,b, y,u,v); - CLAMP(r, 0, 0xffff); CLAMP(g, 0, 0xffff); CLAMP(b, 0, 0xffff); } bc_always_inline void yuv_to_rgb_16(float &r, float &g, float &b, int y, int u, int v) { int ir, ig, ib; YUV_yuv_to_rgb_16(ir,ig,ib, y,u,v); @@ -308,19 +282,36 @@ public: g = y + u_to_g * u + v_to_g * v; b = y + u_to_b * u; } + bc_always_inline void yuv_to_rgb_f(float &r, float &g, float &b, uint8_t &y, uint8_t &u, uint8_t &v) { + yuv_to_rgb_8(r,g,b, y,u,v); + } + bc_always_inline void yuv_to_rgb_f(float &r, float &g, float &b, uint16_t &y, uint16_t &u, uint16_t &v) { + yuv_to_rgb_16(r,g,b, y,u,v); + } + + bc_always_inline int rgb_to_y_8(int r, int g, int b) { + return (rtoy8[r] + gtoy8[g] + btoy8[b] + yzero) >> 16; + } + bc_always_inline int rgb_to_y_16(int r, int g, int b) { + return (rtoy16[r] + gtoy16[g] + btoy16[b] + yzero) >> 8; + } + bc_always_inline float rgb_to_y_f(float r, float g, float b) { + return r * r_to_y + g * g_to_y + b * b_to_y + yminf; + } // For easier programming. Doesn't do anything. // unused cases in macro expansions, mismatched argument types inline void yuv_to_rgb_8(float &r, float &g, float &b, float y, float u, float v) {} inline void yuv_to_rgb_16(float &r, float &g, float &b, float y, float u, float v) {} inline void yuv_to_rgb_f(int &r, int &g, int &b, int y, int u, int v) {} - inline void yuv_to_rgb_f(uint8_t &r, uint8_t &g, uint8_t &b, int y, int u, int v) {} + inline void yuv_to_rgb_f(uint8_t &r, uint8_t &g, uint8_t &b, int&y, int u, int v) {} inline void yuv_to_rgb_f(uint16_t &r, uint16_t &g, uint16_t &b, int y, int u, int v) {} + inline void rgb_to_yuv_8(float r, float g, float b, float &y, float &u, float &v) {} inline void rgb_to_yuv_16(float r, float g, float b, float &y, float &u, float &v) {} - inline void rgb_to_yuv_f(int &r, int &g, int &b, int y, int u, int v) {} - inline void rgb_to_yuv_f(uint8_t &r, uint8_t &g, uint8_t &b, int y, int u, int v) {} - inline void rgb_to_yuv_f(uint16_t &r, uint16_t &g, uint16_t &b, int y, int u, int v) {} + inline void rgb_to_yuv_f(int r, int g, int b, int &y, int &u, int &v) {} + inline void rgb_to_yuv_f(uint8_t r, uint8_t g, uint8_t b, int &y, int &u, int &v) {} + inline void rgb_to_yuv_f(uint16_t r, uint16_t g, uint16_t b, int &y, int &u, int &v) {} }; diff --git a/cinelerra-5.1/guicast/bccolors.inc b/cinelerra-5.1/guicast/bccolors.inc index 32f9fc04..010faca5 100644 --- a/cinelerra-5.1/guicast/bccolors.inc +++ b/cinelerra-5.1/guicast/bccolors.inc @@ -25,5 +25,11 @@ class YUV; +#define BC_COLORS_BT601 0 +#define BC_COLORS_BT709 1 +#define BC_COLORS_BT2020 2 + +#define BC_COLORS_JPEG 0 +#define BC_COLORS_MPEG 1 #endif diff --git a/cinelerra-5.1/guicast/bcsignals.C b/cinelerra-5.1/guicast/bcsignals.C index 6847fa5c..ec08b6fa 100644 --- a/cinelerra-5.1/guicast/bcsignals.C +++ b/cinelerra-5.1/guicast/bcsignals.C @@ -109,6 +109,53 @@ static void bc_copy_textfile(int lines, FILE *ofp, const char *fmt,...) fclose(ifp); } +static void bc_list_openfiles(int lines, FILE *ofp, const char *fmt,...) +{ + va_list ap; va_start(ap, fmt); + char bfr[BCTEXTLEN]; vsnprintf(bfr, sizeof(bfr), fmt, ap); + va_end(ap); + DIR *dir = opendir(bfr); + if( !dir ) return; + struct dirent64 *dent; + while( --lines >= 0 && (dent = readdir64(dir)) ) { + const char *fn = dent->d_name; + fprintf(ofp, "%s", fn); + char path[BCTEXTLEN], link[BCTEXTLEN]; + struct stat st; + snprintf(path, sizeof(path), "%s/%s", bfr, fn); + if( !stat(path,&st) ) { + int typ = 0; + if( S_ISREG(st.st_mode) ) typ = ' '; + else if( S_ISDIR(st.st_mode) ) typ = 'd'; + else if( S_ISBLK(st.st_mode) ) typ = 'b'; + else if( S_ISCHR(st.st_mode) ) typ = 'c'; + else if( S_ISFIFO(st.st_mode) ) typ = 'f'; + else if( S_ISLNK(st.st_mode) ) typ = 'l'; + else if( S_ISSOCK(st.st_mode) ) typ = 's'; + if( typ ) fprintf(ofp, "\t%c", typ); + fprintf(ofp, "\tsize %jd", st.st_size); + int len = readlink(path, link, sizeof(link)-1); + if( len > 0 ) { + link[len] = 0; + fprintf(ofp, "\t-> %s", link); + } + } + snprintf(path, sizeof(path), "%sinfo/%s", bfr, fn); + FILE *fp = fopen(path,"r"); int64_t pos; + if( fp ) { + while( fgets(link, sizeof(link), fp) ) { + if( sscanf(link, "pos:%jd", &pos) == 1 ) { + fprintf(ofp, "\tpos: %jd", pos); + break; + } + } + fclose(fp); + } + fprintf(ofp, "\n"); + } + closedir(dir); +} + // Can't use Mutex because it would be recursive static pthread_mutex_t *handler_lock = 0; @@ -401,6 +448,8 @@ static void handle_dump(int n, siginfo_t * info, void *sc) } fprintf(fp,"\nVERSION:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/version"); fprintf(fp,"\nMEMINFO:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/meminfo"); + fprintf(fp,"\nSTATUS:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/%d/status",pid); + fprintf(fp,"\nFD:\n"); bc_list_openfiles(INT_MAX, fp,"/proc/%d/fd", pid); fprintf(fp,"\nMAPS:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/%d/maps",pid); char proc_mem[64]; if( tid > 0 && tid != pid ) diff --git a/cinelerra-5.1/guicast/clip.h b/cinelerra-5.1/guicast/clip.h index 00337442..45a4a2c1 100644 --- a/cinelerra-5.1/guicast/clip.h +++ b/cinelerra-5.1/guicast/clip.h @@ -43,59 +43,36 @@ #define TO_RAD(x) ((x) * 2 * M_PI / 360) #define TO_DEG(x) ((x) * 360 / 2 / M_PI) -static inline int bmin(int a, int b) { return a < b ? a : b; } -static inline float bmin(float a, float b) { return a < b ? a : b; } -static inline double bmin(double a, double b) { return a < b ? a : b; } -static inline int bmax(int a, int b) { return a > b ? a : b; } -static inline float bmax(float a, float b) { return a > b ? a : b; } -static inline double bmax(double a, double b) { return a > b ? a : b; } +#define bc_always_inline __attribute__ ((__always_inline__)) inline -static inline int bclip(int &iv, int imn, int imx) { +static bc_always_inline int bmin(int a, int b) { return a < b ? a : b; } +static bc_always_inline float bmin(float a, float b) { return a < b ? a : b; } +static bc_always_inline double bmin(double a, double b) { return a < b ? a : b; } +static bc_always_inline int bmax(int a, int b) { return a > b ? a : b; } +static bc_always_inline float bmax(float a, float b) { return a > b ? a : b; } +static bc_always_inline double bmax(double a, double b) { return a > b ? a : b; } + +static bc_always_inline int iclip(int iv, int imn, int imx) { + return iv < imn ? imn : iv > imx ? imx : iv; +} +static bc_always_inline int bclip(int &iv, int imn, int imx) { return iv < imn ? imn : iv > imx ? imx : iv; } -static inline float bclip(float &fv, float fmn, float fmx) { +static bc_always_inline float bclip(float &fv, float fmn, float fmx) { return fv < fmn ? fmn : fv > fmx ? fmx : fv; } -static inline double bclip(double &dv, double dmn, double dmx) { +static bc_always_inline double bclip(double &dv, double dmn, double dmx) { return dv < dmn ? dmn : dv > dmx ? dmx : dv; } -static inline void bclamp(int &iv, int imn, int imx) { + +static bc_always_inline void bclamp(int &iv, int imn, int imx) { if( iv < imn ) iv = imn; else if( iv > imx ) iv = imx; } -static inline void bclamp(float &fv, float fmn, float fmx) { +static bc_always_inline void bclamp(float &fv, float fmn, float fmx) { if( fv < fmn ) fv = fmn; else if( fv > fmx ) fv = fmx; } -static inline void bclamp(double &dv, double dmn, double dmx) { +static bc_always_inline void bclamp(double &dv, double dmn, double dmx) { if( dv < dmn ) dv = dmn; else if( dv > dmx ) dv = dmx; } -static inline void bc_rgb2yuv(float r, float g, float b, float &y, float &u, float &v) -{ //bt601, jpeg, unclipped - y = 0.29900*r + 0.58700*g + 0.11400*b; - u = -0.16874*r - 0.33126*g + 0.50000*b + 0.5; - v = 0.50000*r - 0.41869*g - 0.08131*b + 0.5; -} -static inline void bc_rgb2yuv(int r, int g, int b, int &y, int &u, int &v, int max=255) -{ // clipped - float mx = max, fr = r/mx, fg = g/mx, fb = b/mx, fy, fu, fv; - bc_rgb2yuv(fr,fg,fb, fy,fu,fv); - y = (int)(fy * mx + 0.5); bclamp(y,0,max); - u = (int)(fu * mx + 0.5); bclamp(u,0,max); - v = (int)(fv * mx + 0.5); bclamp(v,0,max); -} -static inline void bc_yuv2rgb(float y, float u, float v, float &r, float &g, float &b) -{ //bt601, jpeg, unclipped - r = y + 1.40200*v; - g = y - 0.34414*u - 0.71414*v; - b = y + 1.77200*u; -} -static inline void bc_yuv2rgb(int y, int u, int v, int &r, int &g, int &b, int max=255) -{ // clipped - int ofs = (max + 1) / 2; - float mx = max, fy = y/mx, fu = (u-ofs)/mx, fv = (v-ofs)/mx, fr, fg, fb; - bc_yuv2rgb(fy,fu,fv, fr,fg,fb); - r = (int)(fr * mx + 0.5); bclamp(r,0,max); - g = (int)(fg * mx + 0.5); bclamp(g,0,max); - b = (int)(fb * mx + 0.5); bclamp(b,0,max); -} #endif diff --git a/cinelerra-5.1/guicast/test5.C b/cinelerra-5.1/guicast/test5.C new file mode 100644 index 00000000..81fa6dd5 --- /dev/null +++ b/cinelerra-5.1/guicast/test5.C @@ -0,0 +1,58 @@ +#include +#include +#include "bccolors.C" + +//c++ -g -I../guicast test5.C ../guicast/x86_64/libguicast.a \ +// -DHAVE_GL -DHAVE_XFT -I/usr/include/freetype2 -lGL -lX11 -lXext \ +// -lXinerama -lXv -lpng -lfontconfig -lfreetype -lXft -pthread + +int main(int ac, char **av) +{ + int rgb2yuv = atoi(av[1]); + int color = atoi(av[2]); + int range = atoi(av[3]); + + YUV::yuv.yuv_set_colors(color, range); + if( !rgb2yuv ) { + for( int y=0; y<0x100; ++y ) { + for( int u=0; u<0x100; ++u ) { + for( int v=0; v<0x100; ++v ) { + float fy = y/255.f, fu = u/255.f - 0.5f, fv = v/255.f - 0.5f; + float fr, fg, fb; YUV::yuv.yuv_to_rgb_f(fr,fg,fb, fy,fu,fv); + if( fr<0 || fr>1 || fg<0 || fg>1 || fb<0 || fb>1 ) + continue; + float yy, uu, vv; YUV::yuv.rgb_to_yuv_f(fr,fg,fb, yy,uu,vv); + float d = fabsf(fy-yy) + fabsf(fu-uu) + fabsf(fv-vv); + int rr = fr*256, gg = fg*256, bb = fb*256; + CLAMP(rr,0,255); CLAMP(gg,0,255); CLAMP(bb,0,255); + printf("yuv 0x%02x 0x%02x 0x%02x =%f,%f,%f, " + "rgb 0x%02x 0x%02x 0x%02x =%f,%f,%f, " + " %f,%f,%f, %f\n", + y,u,v, fy,fu,fv, rr,gg,bb, fr,fg,fb, yy,uu,vv, d); + } + } + } + } + else { + for( int r=0; r<0x100; ++r ) { + for( int g=0; g<0x100; ++g ) { + for( int b=0; b<0x100; ++b ) { + float fr = r/255.f, fg = g/255.f, fb = b/255.f; + float fy, fu, fv; YUV::yuv.rgb_to_yuv_f(fr,fg,fb, fy,fu,fv); + if( fy<0 || fy>1 || fu<0 || fu>1 || fv<0 || fv>1 ) + continue; + float rr, gg, bb; YUV::yuv.yuv_to_rgb_f(rr,gg,bb, fy,fu,fv); + float d = fabsf(fr-rr) + fabsf(fg-gg) + fabsf(fb-bb); + int yy = fy*256, uu = fu*256, vv = fv*256; + CLAMP(yy,0,255); CLAMP(uu,0,255); CLAMP(vv,0,255); + printf("rgb 0x%02x 0x%02x 0x%02x =%f,%f,%f, " + "yuv 0x%02x 0x%02x 0x%02x =%f,%f,%f, " + " %f,%f,%f, %f\n", + r,g,b, fr,fg,fb, yy,uu,vv, fy,fu,fv, rr,gg,bb, d); + } + } + } + } + return 0; +} + diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index eaa1f078..e8dad7ea 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -134,9 +134,10 @@ VFrame::VFrame(VFrame &frame) use_shm = frame.use_shm; allocate_data(0, -1, 0, 0, 0, frame.w, frame.h, frame.color_model, frame.bytes_per_line); - copy_from(&frame); + copy_vframe(&frame); } + VFrame::VFrame(int w, int h, int color_model, long bytes_per_line) { reset_parameters(1); @@ -1027,14 +1028,12 @@ void VFrame::rotate270() void VFrame::flip_vert() { - unsigned char *temp = new unsigned char[bytes_per_line]; - for(int i = 0, j = h - 1; i < j; i++, j--) - { + unsigned char temp[bytes_per_line]; + for( int i=0, j=h; --j>i; ++i ) { memcpy(temp, rows[j], bytes_per_line); memcpy(rows[j], rows[i], bytes_per_line); memcpy(rows[i], temp, bytes_per_line); } - delete [] temp; } void VFrame::flip_horiz() @@ -1118,18 +1117,19 @@ int VFrame::copy_from(VFrame *frame) break; } - params->copy_from(frame->params); return 0; } int VFrame::transfer_from(VFrame *that, int bg_color, int in_x, int in_y, int in_w, int in_h) { + timestamp = that->timestamp; + copy_params(that); + if( this->get_color_model() == that->get_color_model() && this->get_w() == that->get_w() && this->get_h() == that->get_h() && this->get_bytes_per_line() == that->get_bytes_per_line() ) return this->copy_from(that); - timestamp = that->timestamp; #if 0 BC_CModels::transfer( this->get_rows(), that->get_rows(), // Packed data out/in @@ -1170,7 +1170,6 @@ int VFrame::transfer_from(VFrame *that, int bg_color, int in_x, int in_y, int in that->get_bytes_per_line(), bg_color); #endif - params->copy_from(that->params); return 0; } @@ -1269,22 +1268,20 @@ void VFrame::copy_stacks(VFrame *src) { clear_stacks(); - for(int i = 0; i < src->next_effects.total; i++) - { - char *ptr; - next_effects.append(ptr = new char[strlen(src->next_effects.values[i]) + 1]); - strcpy(ptr, src->next_effects.values[i]); - } - for(int i = 0; i < src->prev_effects.total; i++) - { - char *ptr; - prev_effects.append(ptr = new char[strlen(src->prev_effects.values[i]) + 1]); - strcpy(ptr, src->prev_effects.values[i]); - } + for( int i=0; i < src->next_effects.total; ++i ) + next_effects.append(cstrdup(src->next_effects[i])); + for( int i=0; i < src->prev_effects.total; ++i ) + prev_effects.append(cstrdup(src->prev_effects[i])); copy_params(src); } +int VFrame::copy_vframe(VFrame *frame) +{ + copy_stacks(frame); + return copy_from(frame); +} + int VFrame::equal_stacks(VFrame *src) { for(int i = 0; i < src->next_effects.total && i < next_effects.total; i++) @@ -1337,7 +1334,7 @@ void VFrame::set_pixel_color(int rgb) int ir = 0xff & (pixel_rgb >> 16); int ig = 0xff & (pixel_rgb >> 8); int ib = 0xff & (pixel_rgb >> 0); - bc_rgb2yuv(ir,ig,ib, ir,ig,ib); + YUV::yuv.rgb_to_yuv_8(ir, ig, ib); pixel_yuv = (ir<<16) | (ig<<8) | (ib<<0); } diff --git a/cinelerra-5.1/guicast/vframe.h b/cinelerra-5.1/guicast/vframe.h index 45dbe11f..f9a05aef 100644 --- a/cinelerra-5.1/guicast/vframe.h +++ b/cinelerra-5.1/guicast/vframe.h @@ -130,6 +130,7 @@ public: // direct copy with no alpha int copy_from(VFrame *frame); + int copy_vframe(VFrame *src); // BC_CModels::transfer int transfer_from(VFrame *frame, int bg_color, int in_x, int in_y, int in_w, int in_h); int transfer_from(VFrame *frame, int bg_color=0) { @@ -296,11 +297,12 @@ public: // Adds the program with put_shader. // Returns the program handle. // Requires a null terminated argument list of shaders to link together. +// if fragments is not NULL, it is a a zero terminated list of frags +// if fragments is NULL, then a zero terminated list of va_args frags // At least one shader argument must have a main() function. make_shader // replaces all the main() functions with unique functions and calls them in // sequence, so multiple independant shaders can be linked. -// x is a placeholder for va_arg and should be 0. - static unsigned int make_shader(int x, ...); + static unsigned int make_shader(const char **fragments, ...); static void dump_shader(int shader_id); // Because OpenGL is faster if multiple effects are combined, we need diff --git a/cinelerra-5.1/guicast/vframe3d.C b/cinelerra-5.1/guicast/vframe3d.C index 9f09f638..8d5f88e8 100644 --- a/cinelerra-5.1/guicast/vframe3d.C +++ b/cinelerra-5.1/guicast/vframe3d.C @@ -336,127 +336,83 @@ static int print_error(char *source, unsigned int object, int is_program) +// call as: +// make_shader(0, frag1, .., fragn, 0); +// or make_shader(fragments); - -unsigned int VFrame::make_shader(int x, ...) +unsigned int VFrame::make_shader(const char **fragments, ...) { unsigned int result = 0; #ifdef HAVE_GL // Construct single source file out of arguments - char *complete_program = 0; - int complete_size = 0; - int current_shader = 0; - - va_list list; - va_start(list, x); - - while(1) - { - char *text = va_arg(list, char*); - if(!text) break; - -// Replace one occurrance in each source of main() with a unique id. - char main_replacement[BCTEXTLEN]; - sprintf(main_replacement, "main%03d()", current_shader); -//printf("VFrame::make_shader %s %s\n", text, main_replacement); - char *source_replacement = new char[strlen(text) + strlen(main_replacement) + 1]; - char *ptr = strstr(text, "main()"); - - if(ptr) - { - memcpy(source_replacement, text, ptr - text); - source_replacement[ptr - text] = 0; - strcat(source_replacement, main_replacement); - ptr += strlen("main()"); - strcat(source_replacement, ptr); - current_shader++; - } - else - { - memcpy(source_replacement, text, strlen(text)); - source_replacement[strlen(text)] = 0; - } - - if(!complete_program) - { - complete_size = strlen(source_replacement) + 1; - complete_program = (char*)malloc(complete_size); - strcpy(complete_program, source_replacement); - } - else - { - complete_size += strlen(source_replacement); - complete_program = (char*)realloc(complete_program, complete_size); - strcat(complete_program, source_replacement); - } - - delete [] source_replacement; + char *program = 0; + int nb_mains = 0; + + int nb_frags = 1; + if( !fragments ) { + va_list list; va_start(list, fragments); + while( va_arg(list, char*) != 0 ) ++nb_frags; + va_end(list); } - va_end(list); - -// Add main() function which calls all the unique main replacements in order - char main_function[BCTEXTLEN]; - sprintf(main_function, - "\n" - "void main()\n" - "{\n"); - - for(int i = 0; i < current_shader; i++) - { - char main_replacement[BCTEXTLEN]; - sprintf(main_replacement, "\tmain%03d();\n", i); - strcat(main_function, main_replacement); + const char *frags[nb_frags], *text = 0; + if( !fragments ) { + va_list list; va_start(list, fragments); + for( int i=0; iget_shader(complete_program, - &got_it); - - if(!got_it) - { + result = BC_WindowBase::get_synchronous()->get_shader(program, &got_it); + if( !got_it ) { result = glCreateProgram(); - - unsigned int shader; - shader = glCreateShader(GL_FRAGMENT_SHADER); - const GLchar *text_ptr = complete_program; + unsigned int shader = glCreateShader(GL_FRAGMENT_SHADER); + const GLchar *text_ptr = program; glShaderSource(shader, 1, &text_ptr, NULL); glCompileShader(shader); - int error = print_error(complete_program, shader, 0); + int error = print_error(program, shader, 0); glAttachShader(result, shader); glDeleteShader(shader); - glLinkProgram(result); - if(!error) error = print_error(complete_program, result, 1); - - -// printf("BC_WindowBase::make_shader: shader=%d window_id=%d\n", -// result, + if( !error ) + error = print_error(program, result, 1); +//printf("BC_WindowBase::make_shader: shader=%d window_id=%d\n", result, // BC_WindowBase::get_synchronous()->current_window->get_id()); - BC_WindowBase::get_synchronous()->put_shader(result, complete_program); + BC_WindowBase::get_synchronous()->put_shader(result, program); } -//printf("VFrame::make_shader\n%s\n", complete_program); - free(complete_program); - complete_program = NULL; - +//printf("VFrame::make_shader\n%s\n", program); #endif return result; } diff --git a/cinelerra-5.1/plugins/bluebanana/bluebananacolor.c b/cinelerra-5.1/plugins/bluebanana/bluebananacolor.c index e4321b3a..cb64f979 100644 --- a/cinelerra-5.1/plugins/bluebanana/bluebananacolor.c +++ b/cinelerra-5.1/plugins/bluebanana/bluebananacolor.c @@ -398,6 +398,10 @@ static inline void HSpV_to_RGB(float H, float Sp, float V, float &R, float &G, f static inline void HSpV_correct_RGB(float H, float Sp, float &V, float &R, float &G, float &B){ float vp = Sp<0.f?0.f:(fabs(V)+HSpV_SATURATION_BIAS)*Sp*HSpV_SATURATION_ISCALE; +#define R_TO_Y (Kr) +#define G_TO_Y (Kg) +#define B_TO_Y (Kb) + int i = (int)H; switch(i){ default: diff --git a/cinelerra-5.1/plugins/brightness/brightness.C b/cinelerra-5.1/plugins/brightness/brightness.C index 5c37b20b..9eaf9a30 100644 --- a/cinelerra-5.1/plugins/brightness/brightness.C +++ b/cinelerra-5.1/plugins/brightness/brightness.C @@ -19,11 +19,13 @@ * */ -#include "clip.h" -#include "filexml.h" #include "brightness.h" +#include "bccolors.h" #include "bchash.h" +#include "clip.h" +#include "filexml.h" #include "language.h" +#include "playback3d.h" #include #include @@ -182,16 +184,11 @@ int BrightnessMain::handle_opengl() "uniform float brightness;\n" "uniform float contrast;\n" "uniform float offset;\n" + "uniform mat3 yuv_to_rgb_matrix;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "void main()\n" "{\n" - " const mat3 yuv_to_rgb_matrix = mat3(\n" - " 1, 1, 1, \n" - " 0, -0.34414, 1.77200, \n" - " 1.40200, -0.71414, 0);\n" - " const mat3 rgb_to_yuv_matrix = mat3(\n" - " 0.29900, -0.16874, 0.50000, \n" - " 0.58700, -0.33126, -0.41869, \n" - " 0.11400, 0.50000, -0.08131);\n" " vec4 rgba = texture2D(tex, gl_TexCoord[0].st);\n" " rgba.rgb = rgb_to_yuv_matrix * rgba.rgb;\n" " rgba.r += brightness;\n" @@ -202,36 +199,13 @@ int BrightnessMain::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); + int need_matrix = 0; + const char *brightness_frag = BC_CModels::is_yuv(get_output()->get_color_model()) ? + (config.luma ? (need_matrix = 0, brightness_yuvluma_frag) : brightness_yuv_frag) : + (config.luma ? (need_matrix = 1, brightness_rgbluma_frag) : brightness_rgb_frag) ; - unsigned int shader_id = 0; - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - if(config.luma) - shader_id = VFrame::make_shader(0, - brightness_yuvluma_frag, - 0); - else - shader_id = VFrame::make_shader(0, - brightness_yuv_frag, - 0); - break; - default: - if(config.luma) - shader_id = VFrame::make_shader(0, - brightness_rgbluma_frag, - 0); - else - shader_id = VFrame::make_shader(0, - brightness_rgb_frag, - 0); - break; - } - - - if(shader_id > 0) - { + unsigned int shader_id = VFrame::make_shader(0, brightness_frag, 0); + if( shader_id > 0 ) { glUseProgram(shader_id); glUniform1i(glGetUniformLocation(shader_id, "tex"), 0); glUniform1f(glGetUniformLocation(shader_id, "brightness"), config.brightness / 100); @@ -241,6 +215,10 @@ int BrightnessMain::handle_opengl() glUniform1f(glGetUniformLocation(shader_id, "contrast"), contrast); float offset = 0.5 - contrast / 2; glUniform1f(glGetUniformLocation(shader_id, "offset"), offset); + if( need_matrix ) { + BC_GL_MATRIX(shader_id, yuv_to_rgb_matrix); + BC_GL_MATRIX(shader_id, rgb_to_yuv_matrix); + } } get_output()->init_screen(); diff --git a/cinelerra-5.1/plugins/chromakey/chromakey.C b/cinelerra-5.1/plugins/chromakey/chromakey.C index 9bae8312..73140371 100644 --- a/cinelerra-5.1/plugins/chromakey/chromakey.C +++ b/cinelerra-5.1/plugins/chromakey/chromakey.C @@ -19,6 +19,7 @@ * */ +#include "bccolors.h" #include "bcdisplayinfo.h" #include "bcsignals.h" #include "chromakey.h" @@ -384,9 +385,7 @@ void ChromaKeyUnit::process_package(LoadPackage *package) //float max_hue = h + plugin->config.threshold * 360 / 100; -#define RGB_TO_VALUE(r, g, b) \ -((r) * R_TO_Y + (g) * G_TO_Y + (b) * B_TO_Y) - +#define RGB_TO_VALUE(r, g, b) YUV::yuv.rgb_to_y_f((r),(g),(b)) #define OUTER_VARIABLES(plugin) \ float value = RGB_TO_VALUE(plugin->config.red, \ @@ -688,9 +687,11 @@ int ChromaKey::handle_opengl() "}\n"; static const char *get_rgbvalue_frag = + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "float get_value(vec4 color)\n" "{\n" - " return dot(color.rgb, vec3(0.29900, 0.58700, 0.11400));\n" + " return dot(color.rgb, rgb_to_yuv_matrix[0]) + yminf;\n" "}\n"; static const char *value_frag = @@ -734,64 +735,56 @@ int ChromaKey::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); get_output()->init_screen(); - const char *shader_stack[] = { 0, 0, 0, 0, 0 }; - int current_shader = 0; + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; shader_stack[current_shader++] = uniform_frag; - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - if(config.use_value) - { - shader_stack[current_shader++] = get_yuvvalue_frag; - shader_stack[current_shader++] = value_frag; - } - else - { - shader_stack[current_shader++] = cube_frag; - } - break; - default: - if(config.use_value) - { - shader_stack[current_shader++] = get_rgbvalue_frag; - shader_stack[current_shader++] = value_frag; - } - else - { - shader_stack[current_shader++] = cube_frag; - } - break; + switch(get_output()->get_color_model()) { + case BC_YUV888: + case BC_YUVA8888: + if( config.use_value ) { + shader_stack[current_shader++] = get_yuvvalue_frag; + shader_stack[current_shader++] = value_frag; + } + else { + shader_stack[current_shader++] = cube_frag; + } + break; + + default: + if(config.use_value) { + shader_stack[current_shader++] = get_rgbvalue_frag; + shader_stack[current_shader++] = value_frag; + } + else { + shader_stack[current_shader++] = cube_frag; + } + break; } SET_TRACE - unsigned int frag = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - 0); - get_output()->bind_texture(0); - - if(frag) - { - glUseProgram(frag); - glUniform1i(glGetUniformLocation(frag, "tex"), 0); - glUniform1f(glGetUniformLocation(frag, "min_v"), min_v); - glUniform1f(glGetUniformLocation(frag, "max_v"), max_v); - glUniform1f(glGetUniformLocation(frag, "run"), run); - glUniform1f(glGetUniformLocation(frag, "threshold"), threshold); - glUniform1f(glGetUniformLocation(frag, "threshold_run"), threshold_run); + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); + if( shader > 0 ) { + get_output()->bind_texture(0); + glUseProgram(shader); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + glUniform1f(glGetUniformLocation(shader, "min_v"), min_v); + glUniform1f(glGetUniformLocation(shader, "max_v"), max_v); + glUniform1f(glGetUniformLocation(shader, "run"), run); + glUniform1f(glGetUniformLocation(shader, "threshold"), threshold); + glUniform1f(glGetUniformLocation(shader, "threshold_run"), threshold_run); if(get_output()->get_color_model() != BC_YUV888 && get_output()->get_color_model() != BC_YUVA8888) - glUniform3f(glGetUniformLocation(frag, "key"), + glUniform3f(glGetUniformLocation(shader, "key"), r_key, g_key, b_key); else - glUniform3f(glGetUniformLocation(frag, "key"), + glUniform3f(glGetUniformLocation(shader, "key"), (float)y_key / 0xff, (float)u_key / 0xff, (float)v_key / 0xff); - + if(config.use_value) + BC_GL_RGB_TO_YUV(shader); } SET_TRACE diff --git a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C index a56cff1e..b96b172a 100644 --- a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C +++ b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.C @@ -686,36 +686,30 @@ void ChromaKeyUnit::process_chromakey(int components, for (int j = 0; j < w; j++) { - float a = 1; - - float r = (float) row[0] / max; - float g = (float) row[1] / max; - float b = (float) row[2] / max; + float r, g, b, a = 1; + if (!use_yuv) { + r = (float) row[0] / max; + g = (float) row[1] / max; + b = (float) row[2] / max; + } + else + YUV::yuv.yuv_to_rgb_f (r, g, b, row[0], row[1], row[2]); float h, s, v; float av = 1, ah = 1, as = 1, avm = 1; bool has_match = true; - if (use_yuv) - { -/* Convert pixel to RGB float */ - float y = r; - float u = g; - float v = b; - YUV::yuv.yuv_to_rgb_f (r, g, b, y, u - 0.5, v - 0.5); - } - HSV::rgb_to_hsv (r, g, b, h, s, v); // First, test if the hue is in range /* Hue wrap */ if(h <= hue_key - tolerance_in * 180.0) - h += 360; + h += 360.0; else if(h >= hue_key + tolerance_in * 180.0) - h -= 360; + h -= 360.0; if (tolerance == 0) @@ -792,29 +786,14 @@ void ChromaKeyUnit::process_chromakey(int components, HSV::hsv_to_rgb (r, g, b, h, s, v); - if (use_yuv) - { - float y; - float u; - float v; - YUV::yuv.rgb_to_yuv_f (r, g, b, y, u, v); - CLAMP (y, 0, 1.0); - CLAMP (u, 0, 1.0); - CLAMP (v, 0, 1.0); - row[0] = (component_type) ((float) y * max); - row[1] = (component_type) ((float) (u + 0.5) * max); - row[2] = (component_type) ((float) (v + 0.5) * max); + if (!use_yuv) { + row[0] = (component_type) ((float) r * max); + row[1] = (component_type) ((float) g * max); + row[2] = (component_type) ((float) b * max); } - else - { - CLAMP (r, 0, 1.0); - CLAMP (g, 0, 1.0); - CLAMP (b, 0, 1.0); - row[0] = (component_type) ((float) r * max); - row[1] = (component_type) ((float) g * max); - row[2] = (component_type) ((float) b * max); - } - } + else + YUV::yuv.rgb_to_yuv_f(r, g, b, row[0], row[1], row[2]); + } a += alpha_offset; CLAMP (a, 0.0, 1.0); @@ -1059,16 +1038,21 @@ int ChromaKeyHSV::handle_opengl() static const char *yuv_shader = "const vec3 black = vec3(0.0, 0.5, 0.5);\n" + "uniform mat3 yuv_to_rgb_matrix;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "\n" "vec4 yuv_to_rgb(vec4 color)\n" "{\n" - YUV_TO_RGB_FRAG("color") + " color.rgb -= vec3(yminf, 0.5, 0.5);\n" + " color.rgb = yuv_to_rgb_matrix * color.rgb;\n" " return color;\n" "}\n" "\n" "vec4 rgb_to_yuv(vec4 color)\n" "{\n" - RGB_TO_YUV_FRAG("color") + " color.rgb = rgb_to_yuv_matrix * color.rgb;\n" + " color.rgb += vec3(yminf, 0.5, 0.5);\n" " return color;\n" "}\n"; @@ -1116,78 +1100,58 @@ int ChromaKeyHSV::handle_opengl() " return vec4(color.rgb, min(color.a, color2.a));" "}\n"; - extern unsigned char _binary_chromakey_sl_start[]; - static const char *shader = (char*)_binary_chromakey_sl_start; - get_output()->to_texture(); get_output()->enable_opengl(); get_output()->init_screen(); - const char* shader_stack[] = { 0, 0, 0, 0, 0 }; - - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - shader_stack[0] = yuv_shader; - shader_stack[1] = hsv_shader; - if(config.show_mask) - shader_stack[2] = show_yuvmask_shader; - else - shader_stack[2] = nomask_shader; - shader_stack[3] = shader; - break; - - default: - shader_stack[0] = rgb_shader; - shader_stack[1] = hsv_shader; - if(config.show_mask) - shader_stack[2] = show_rgbmask_shader; - else - shader_stack[2] = nomask_shader; - shader_stack[3] = shader; - break; - } - - - unsigned int frag = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - 0); - - if(frag) - { - glUseProgram(frag); - glUniform1i(glGetUniformLocation(frag, "tex"), 0); - glUniform1f(glGetUniformLocation(frag, "red"), red); - glUniform1f(glGetUniformLocation(frag, "green"), green); - glUniform1f(glGetUniformLocation(frag, "blue"), blue); - glUniform1f(glGetUniformLocation(frag, "in_slope"), in_slope); - glUniform1f(glGetUniformLocation(frag, "out_slope"), out_slope); - glUniform1f(glGetUniformLocation(frag, "tolerance"), tolerance); - glUniform1f(glGetUniformLocation(frag, "tolerance_in"), tolerance_in); - glUniform1f(glGetUniformLocation(frag, "tolerance_out"), tolerance_out); - glUniform1f(glGetUniformLocation(frag, "sat"), sat); - glUniform1f(glGetUniformLocation(frag, "min_s"), min_s); - glUniform1f(glGetUniformLocation(frag, "min_s_in"), min_s_in); - glUniform1f(glGetUniformLocation(frag, "min_s_out"), min_s_out); - glUniform1f(glGetUniformLocation(frag, "min_v"), min_v); - glUniform1f(glGetUniformLocation(frag, "min_v_in"), min_v_in); - glUniform1f(glGetUniformLocation(frag, "min_v_out"), min_v_out); - glUniform1f(glGetUniformLocation(frag, "max_v"), max_v); - glUniform1f(glGetUniformLocation(frag, "max_v_in"), max_v_in); - glUniform1f(glGetUniformLocation(frag, "max_v_out"), max_v_out); - glUniform1f(glGetUniformLocation(frag, "spill_threshold"), spill_threshold); - glUniform1f(glGetUniformLocation(frag, "spill_amount"), spill_amount); - glUniform1f(glGetUniformLocation(frag, "alpha_offset"), alpha_offset); - glUniform1f(glGetUniformLocation(frag, "hue_key"), hue_key); - glUniform1f(glGetUniformLocation(frag, "saturation_key"), saturation_key); - glUniform1f(glGetUniformLocation(frag, "value_key"), value_key); + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + shader_stack[current_shader++] = \ + !BC_CModels::is_yuv(get_output()->get_color_model()) ? + rgb_shader : yuv_shader; + shader_stack[current_shader++] = hsv_shader; + shader_stack[current_shader++] = !config.show_mask ? nomask_shader : + !BC_CModels::is_yuv(get_output()->get_color_model()) ? + show_rgbmask_shader : show_yuvmask_shader ; + extern unsigned char _binary_chromakey_sl_start[]; + static const char *shader_frag = (char*)_binary_chromakey_sl_start; + shader_stack[current_shader++] = shader_frag; + + 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, "red"), red); + glUniform1f(glGetUniformLocation(shader, "green"), green); + glUniform1f(glGetUniformLocation(shader, "blue"), blue); + glUniform1f(glGetUniformLocation(shader, "in_slope"), in_slope); + glUniform1f(glGetUniformLocation(shader, "out_slope"), out_slope); + glUniform1f(glGetUniformLocation(shader, "tolerance"), tolerance); + glUniform1f(glGetUniformLocation(shader, "tolerance_in"), tolerance_in); + glUniform1f(glGetUniformLocation(shader, "tolerance_out"), tolerance_out); + glUniform1f(glGetUniformLocation(shader, "sat"), sat); + glUniform1f(glGetUniformLocation(shader, "min_s"), min_s); + glUniform1f(glGetUniformLocation(shader, "min_s_in"), min_s_in); + glUniform1f(glGetUniformLocation(shader, "min_s_out"), min_s_out); + glUniform1f(glGetUniformLocation(shader, "min_v"), min_v); + glUniform1f(glGetUniformLocation(shader, "min_v_in"), min_v_in); + glUniform1f(glGetUniformLocation(shader, "min_v_out"), min_v_out); + glUniform1f(glGetUniformLocation(shader, "max_v"), max_v); + glUniform1f(glGetUniformLocation(shader, "max_v_in"), max_v_in); + glUniform1f(glGetUniformLocation(shader, "max_v_out"), max_v_out); + glUniform1f(glGetUniformLocation(shader, "spill_threshold"), spill_threshold); + glUniform1f(glGetUniformLocation(shader, "spill_amount"), spill_amount); + glUniform1f(glGetUniformLocation(shader, "alpha_offset"), alpha_offset); + glUniform1f(glGetUniformLocation(shader, "hue_key"), hue_key); + glUniform1f(glGetUniformLocation(shader, "saturation_key"), saturation_key); + glUniform1f(glGetUniformLocation(shader, "value_key"), value_key); + if( BC_CModels::is_yuv(get_output()->get_color_model()) ) + BC_GL_COLORS(shader); } - get_output()->bind_texture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); diff --git a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.sl b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.sl index 25ca2d04..51cd1f34 100644 --- a/cinelerra-5.1/plugins/chromakeyhsv/chromakey.sl +++ b/cinelerra-5.1/plugins/chromakeyhsv/chromakey.sl @@ -41,10 +41,10 @@ void main() /* Hue wrap */ if(color2.r <= hue_key - tolerance_in * 180.0) - color2.r += 360; + color2.r += 360.0; else if(color2.r >= hue_key + tolerance_in * 180.0) - color2.r -= 360; + color2.r -= 360.0; /* Hue is completely out of range */ if (tolerance == 0.0) diff --git a/cinelerra-5.1/plugins/color3way/aggregated.h b/cinelerra-5.1/plugins/color3way/aggregated.h deleted file mode 100644 index a6934e54..00000000 --- a/cinelerra-5.1/plugins/color3way/aggregated.h +++ /dev/null @@ -1,93 +0,0 @@ - -/* - * CINELERRA - * Copyright (C) 2008 Adam Williams - * - * 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 - * - */ - -#ifndef COLORBALANCE_AGGREGATED -#define COLORBALANCE_AGGREGATED - -static const char *colorbalance_get_pixel1 = - "vec4 colorbalance_get_pixel()\n" - "{\n" - " return gl_FragColor;\n" - "}\n"; - -static const char *colorbalance_get_pixel2 = - "uniform sampler2D tex;\n" - "vec4 colorbalance_get_pixel()\n" - "{\n" - " return texture2D(tex, gl_TexCoord[0].st);\n" - "}\n"; - - -static const char *colorbalance_rgb_shader = - "uniform vec3 colorbalance_scale;\n" - "void main()\n" - "{\n" - " gl_FragColor = colorbalance_get_pixel();\n" - " gl_FragColor.rgb *= colorbalance_scale;\n" - "}\n"; - -static const char *colorbalance_yuv_shader = - "uniform vec3 colorbalance_scale;\n" - "void main()\n" - "{\n" - " gl_FragColor = colorbalance_get_pixel();\n" - YUV_TO_RGB_FRAG("gl_FragColor") - " gl_FragColor.rgb *= colorbalance_scale;\n" - RGB_TO_YUV_FRAG("gl_FragColor") - "}\n"; - -static const char *colorbalance_yuv_preserve_shader = - "uniform vec3 colorbalance_scale;\n" - "void main()\n" - "{\n" - " gl_FragColor = colorbalance_get_pixel();\n" - " float y = gl_FragColor.r;\n" - YUV_TO_RGB_FRAG("gl_FragColor") - " gl_FragColor.rgb *= colorbalance_scale.rgb;\n" - RGB_TO_YUV_FRAG("gl_FragColor") - " gl_FragColor.r = y;\n" - "}\n"; - -#define COLORBALANCE_COMPILE(shader_stack, current_shader, aggregate_prev) \ -{ \ - if(aggregate_prev) \ - shader_stack[current_shader++] = colorbalance_get_pixel1; \ - else \ - shader_stack[current_shader++] = colorbalance_get_pixel2; \ - if(BC_CModels::is_yuv(get_output()->get_color_model())) \ - {\ - if(get_output()->get_params()->get("COLORBALANCE_PRESERVE", (int)0)) \ - shader_stack[current_shader++] = colorbalance_yuv_preserve_shader; \ - else \ - shader_stack[current_shader++] = colorbalance_yuv_shader; \ - } \ - else \ - shader_stack[current_shader++] = colorbalance_rgb_shader; \ -} - -#define COLORBALANCE_UNIFORMS(shader) \ - glUniform3f(glGetUniformLocation(shader, "colorbalance_scale"), \ - get_output()->get_params()->get("COLORBALANCE_CYAN", (float)1), \ - get_output()->get_params()->get("COLORBALANCE_MAGENTA", (float)1), \ - get_output()->get_params()->get("COLORBALANCE_YELLOW", (float)1)); - -#endif - diff --git a/cinelerra-5.1/plugins/color3way/color3way.C b/cinelerra-5.1/plugins/color3way/color3way.C index 5704ded3..8cc288ee 100644 --- a/cinelerra-5.1/plugins/color3way/color3way.C +++ b/cinelerra-5.1/plugins/color3way/color3way.C @@ -27,10 +27,6 @@ #include "language.h" #include "playback3d.h" -#include "aggregated.h" -#include "../interpolate/aggregated.h" -#include "../gamma/aggregated.h" - #include #include @@ -183,12 +179,13 @@ Color3WayUnit::Color3WayUnit(Color3WayMain *plugin, r = r + TOTAL_TRANSFER(r, r_factor); \ g = g + TOTAL_TRANSFER(g, g_factor); \ b = b + TOTAL_TRANSFER(b, b_factor); \ + r = CLAMP(r,0,1); g = CLAMP(g,0,1); b = CLAMP(b,0,1); \ /* Apply saturation/value */ \ float h, s, v; \ HSV::rgb_to_hsv(r, g, b, h, s, v); \ v += TOTAL_TRANSFER(v, v_factor); \ s += TOTAL_TRANSFER(s, s_factor); \ - s = MAX(s, 0); \ + s = CLAMP(s,0,1); v = CLAMP(v,0,1); \ HSV::hsv_to_rgb(r, g, b, h, s, v); @@ -196,52 +193,35 @@ Color3WayUnit::Color3WayUnit(Color3WayMain *plugin, { \ type *in = (type*)plugin->get_input()->get_rows()[i]; \ type *out = (type*)plugin->get_input()->get_rows()[i]; \ - for(int j = 0; j < w; j++) \ - { \ + for(int j = 0; j < w; j++) { \ /* Convert to RGB float */ \ - float r; \ - float g; \ - float b; \ - if(is_yuv) \ - { \ - YUV::yuv.yuv_to_rgb_f(r, g, b, \ - (float)in[0] / max, \ - (float)in[1] / max - 0.5, \ - (float)in[2] / max - 0.5); \ - in += 3; \ + float r, g, b; \ + if( !is_yuv ) { \ + r = (float)in[0] / max; \ + g = (float)in[1] / max; \ + b = (float)in[2] / max; \ } \ else \ - { \ - r = (float)*in++ / max; \ - g = (float)*in++ / max; \ - b = (float)*in++ / max; \ - } \ + YUV::yuv.yuv_to_rgb_f(r, g, b, in[0], in[1], in[2]); \ \ PROCESS_PIXEL(r, g, b) \ \ + if( !is_yuv ) { \ /* Convert to project colormodel */ \ - if(is_yuv) \ - { \ - float y, u, v; \ - YUV::yuv.rgb_to_yuv_f(r, g, b, y, u, v); \ - r = y; \ - g = u + 0.5; \ - b = v + 0.5; \ - } \ - if(max == 0xff) \ - { \ - CLAMP(r, 0, 1); \ - CLAMP(g, 0, 1); \ - CLAMP(b, 0, 1); \ - } \ - *out++ = (type)(r * max); \ - *out++ = (type)(g * max); \ - *out++ = (type)(b * max); \ - if(components == 4) \ - { \ - in++; \ - out++; \ + if(max == 0xff) { \ + CLAMP(r, 0, 1); \ + CLAMP(g, 0, 1); \ + CLAMP(b, 0, 1); \ + } \ + out[0] = (type)(r * max); \ + out[1] = (type)(g * max); \ + out[2] = (type)(b * max); \ } \ + else \ + YUV::yuv.rgb_to_yuv_f(r, g, b, out[0], out[1], out[2]); \ + \ + in += components; \ + out += components; \ } \ } @@ -493,11 +473,8 @@ int Color3WayMain::process_buffer(VFrame *frame, get_aggregation(&aggregate_interpolate, &aggregate_gamma); - - engine->process_packages(); - return 0; } @@ -620,68 +597,4 @@ void Color3WayMain::get_aggregation(int *aggregate_interpolate, } } -int Color3WayMain::handle_opengl() -{ -#ifdef HAVE_GL - - get_output()->to_texture(); - get_output()->enable_opengl(); - - unsigned int shader = 0; - const char *shader_stack[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int current_shader = 0; - int aggregate_interpolate = 0; - int aggregate_gamma = 0; - - get_aggregation(&aggregate_interpolate, - &aggregate_gamma); - -printf("Color3WayMain::handle_opengl %d %d\n", aggregate_interpolate, aggregate_gamma); - if(aggregate_interpolate) - INTERPOLATE_COMPILE(shader_stack, current_shader) - - if(aggregate_gamma) - GAMMA_COMPILE(shader_stack, current_shader, aggregate_interpolate) - - COLORBALANCE_COMPILE(shader_stack, - current_shader, - aggregate_gamma || aggregate_interpolate) - - shader = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - shader_stack[4], - shader_stack[5], - shader_stack[6], - shader_stack[7], - 0); - - if(shader > 0) - { - glUseProgram(shader); - glUniform1i(glGetUniformLocation(shader, "tex"), 0); - - if(aggregate_interpolate) INTERPOLATE_UNIFORMS(shader); - if(aggregate_gamma) GAMMA_UNIFORMS(shader); - - COLORBALANCE_UNIFORMS(shader); - - } - - get_output()->init_screen(); - get_output()->bind_texture(0); - get_output()->draw_texture(); - glUseProgram(0); - get_output()->set_opengl_state(VFrame::SCREEN); -#endif - return 0; -} - - - - - - diff --git a/cinelerra-5.1/plugins/color3way/color3way.h b/cinelerra-5.1/plugins/color3way/color3way.h index a70ac8d7..17f1a08f 100644 --- a/cinelerra-5.1/plugins/color3way/color3way.h +++ b/cinelerra-5.1/plugins/color3way/color3way.h @@ -111,7 +111,6 @@ public: void update_gui(); void save_data(KeyFrame *keyframe); void read_data(KeyFrame *keyframe); - int handle_opengl(); void get_aggregation(int *aggregate_interpolate, int *aggregate_gamma); diff --git a/cinelerra-5.1/plugins/colorbalance/aggregated.h b/cinelerra-5.1/plugins/colorbalance/aggregated.h index a6934e54..6c8d78f4 100644 --- a/cinelerra-5.1/plugins/colorbalance/aggregated.h +++ b/cinelerra-5.1/plugins/colorbalance/aggregated.h @@ -49,9 +49,9 @@ static const char *colorbalance_yuv_shader = "void main()\n" "{\n" " gl_FragColor = colorbalance_get_pixel();\n" - YUV_TO_RGB_FRAG("gl_FragColor") + YUV_TO_RGB_FRAG("gl_FragColor") " gl_FragColor.rgb *= colorbalance_scale;\n" - RGB_TO_YUV_FRAG("gl_FragColor") + RGB_TO_YUV_FRAG("gl_FragColor") "}\n"; static const char *colorbalance_yuv_preserve_shader = @@ -60,34 +60,27 @@ static const char *colorbalance_yuv_preserve_shader = "{\n" " gl_FragColor = colorbalance_get_pixel();\n" " float y = gl_FragColor.r;\n" - YUV_TO_RGB_FRAG("gl_FragColor") + YUV_TO_RGB_FRAG("gl_FragColor") " gl_FragColor.rgb *= colorbalance_scale.rgb;\n" - RGB_TO_YUV_FRAG("gl_FragColor") + RGB_TO_YUV_FRAG("gl_FragColor") " gl_FragColor.r = y;\n" "}\n"; -#define COLORBALANCE_COMPILE(shader_stack, current_shader, aggregate_prev) \ -{ \ - if(aggregate_prev) \ - shader_stack[current_shader++] = colorbalance_get_pixel1; \ - else \ - shader_stack[current_shader++] = colorbalance_get_pixel2; \ - if(BC_CModels::is_yuv(get_output()->get_color_model())) \ - {\ - if(get_output()->get_params()->get("COLORBALANCE_PRESERVE", (int)0)) \ - shader_stack[current_shader++] = colorbalance_yuv_preserve_shader; \ - else \ - shader_stack[current_shader++] = colorbalance_yuv_shader; \ - } \ - else \ - shader_stack[current_shader++] = colorbalance_rgb_shader; \ -} +#define COLORBALANCE_COMPILE(shader_stack, current_shader, aggregate_prev) do { \ + shader_stack[current_shader++] = \ + aggregate_prev ? colorbalance_get_pixel1 : colorbalance_get_pixel2; \ + shader_stack[current_shader++] = \ + !BC_CModels::is_yuv(get_output()->get_color_model()) ? colorbalance_rgb_shader : \ + get_output()->get_params()->get("COLORBALANCE_PRESERVE", (int)0) ? \ + colorbalance_yuv_preserve_shader : colorbalance_yuv_shader ; \ +} while(0) -#define COLORBALANCE_UNIFORMS(shader) \ +#define COLORBALANCE_UNIFORMS(shader) do { \ glUniform3f(glGetUniformLocation(shader, "colorbalance_scale"), \ get_output()->get_params()->get("COLORBALANCE_CYAN", (float)1), \ get_output()->get_params()->get("COLORBALANCE_MAGENTA", (float)1), \ - get_output()->get_params()->get("COLORBALANCE_YELLOW", (float)1)); + get_output()->get_params()->get("COLORBALANCE_YELLOW", (float)1)); \ +} while(0) #endif diff --git a/cinelerra-5.1/plugins/colorbalance/colorbalance.C b/cinelerra-5.1/plugins/colorbalance/colorbalance.C index c5e4db0c..16d26ef9 100644 --- a/cinelerra-5.1/plugins/colorbalance/colorbalance.C +++ b/cinelerra-5.1/plugins/colorbalance/colorbalance.C @@ -403,27 +403,23 @@ int ColorBalanceMain::test_boundary(float &value) int ColorBalanceMain::synchronize_params(ColorBalanceSlider *slider, float difference) { - if(thread && config.lock_params) - { - if(slider != ((ColorBalanceWindow*)thread->window)->cyan) - { - config.cyan += difference; - test_boundary(config.cyan); - ((ColorBalanceWindow*)thread->window)->cyan->update((int64_t)config.cyan); - } - if(slider != ((ColorBalanceWindow*)thread->window)->magenta) - { - config.magenta += difference; - test_boundary(config.magenta); - ((ColorBalanceWindow*)thread->window)->magenta->update((int64_t)config.magenta); - } - if(slider != ((ColorBalanceWindow*)thread->window)->yellow) - { - config.yellow += difference; - test_boundary(config.yellow); - ((ColorBalanceWindow*)thread->window)->yellow->update((int64_t)config.yellow); - } - } + if(thread && config.lock_params) { + if(slider != ((ColorBalanceWindow*)thread->window)->cyan) { + config.cyan += difference; + test_boundary(config.cyan); + ((ColorBalanceWindow*)thread->window)->cyan->update((int64_t)config.cyan); + } + if(slider != ((ColorBalanceWindow*)thread->window)->magenta) { + config.magenta += difference; + test_boundary(config.magenta); + ((ColorBalanceWindow*)thread->window)->magenta->update((int64_t)config.magenta); + } + if(slider != ((ColorBalanceWindow*)thread->window)->yellow) { + config.yellow += difference; + test_boundary(config.yellow); + ((ColorBalanceWindow*)thread->window)->yellow->update((int64_t)config.yellow); + } + } return 0; } @@ -605,9 +601,14 @@ int ColorBalanceMain::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); - unsigned int shader = 0; - const char *shader_stack[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int current_shader = 0; + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + int need_color_matrix = BC_CModels::is_yuv(get_output()->get_color_model()) ? 1 : 0; + if( need_color_matrix ) + shader_stack[current_shader++] = bc_gl_colors; + int aggregate_interpolate = 0; int aggregate_gamma = 0; @@ -616,28 +617,18 @@ int ColorBalanceMain::handle_opengl() //printf("ColorBalanceMain::handle_opengl %d %d\n", aggregate_interpolate, aggregate_gamma); if(aggregate_interpolate) - INTERPOLATE_COMPILE(shader_stack, current_shader) + INTERPOLATE_COMPILE(shader_stack, current_shader); if(aggregate_gamma) - GAMMA_COMPILE(shader_stack, current_shader, aggregate_interpolate) - - COLORBALANCE_COMPILE(shader_stack, - current_shader, - aggregate_gamma || aggregate_interpolate) - - shader = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - shader_stack[4], - shader_stack[5], - shader_stack[6], - shader_stack[7], - 0); - - if(shader > 0) - { + GAMMA_COMPILE(shader_stack, current_shader, + aggregate_interpolate); + + COLORBALANCE_COMPILE(shader_stack, current_shader, + aggregate_gamma || aggregate_interpolate); + + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); + if( shader > 0 ) { glUseProgram(shader); glUniform1i(glGetUniformLocation(shader, "tex"), 0); @@ -645,7 +636,7 @@ int ColorBalanceMain::handle_opengl() if(aggregate_gamma) GAMMA_UNIFORMS(shader); COLORBALANCE_UNIFORMS(shader); - + if( need_color_matrix ) BC_GL_COLORS(shader); } get_output()->init_screen(); diff --git a/cinelerra-5.1/plugins/colorbalance/colorbalancewindow.C b/cinelerra-5.1/plugins/colorbalance/colorbalancewindow.C index 66f7914c..263f15ea 100644 --- a/cinelerra-5.1/plugins/colorbalance/colorbalancewindow.C +++ b/cinelerra-5.1/plugins/colorbalance/colorbalancewindow.C @@ -87,18 +87,11 @@ void ColorBalanceWindow::update() ColorBalanceSlider::ColorBalanceSlider(ColorBalanceMain *client, float *output, int x, int y) - : BC_ISlider(x, - y, - 0, - 200, - 200, - -1000, - 1000, - (int)*output) + : BC_ISlider(x, y, 0, 200, 200, -1000, 1000, (int)*output) { this->client = client; this->output = output; - old_value = *output; + old_value = *output; } ColorBalanceSlider::~ColorBalanceSlider() @@ -109,7 +102,7 @@ int ColorBalanceSlider::handle_event() { float difference = get_value() - *output; *output = get_value(); - client->synchronize_params(this, difference); + client->synchronize_params(this, difference); client->send_configure_change(); return 1; } diff --git a/cinelerra-5.1/plugins/deinterlace/deinterlace.C b/cinelerra-5.1/plugins/deinterlace/deinterlace.C index 850959e3..028d90db 100644 --- a/cinelerra-5.1/plugins/deinterlace/deinterlace.C +++ b/cinelerra-5.1/plugins/deinterlace/deinterlace.C @@ -28,23 +28,12 @@ #include "language.h" #include "vframe.h" - - - - - - - - #include #include REGISTER_PLUGIN(DeInterlaceMain) - - - DeInterlaceConfig::DeInterlaceConfig() { mode = DEINTERLACE_EVEN; @@ -456,63 +445,62 @@ int DeInterlaceMain::handle_opengl() 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); } } diff --git a/cinelerra-5.1/plugins/diffkey/diffkey.C b/cinelerra-5.1/plugins/diffkey/diffkey.C index 118b7f38..9ce891ea 100644 --- a/cinelerra-5.1/plugins/diffkey/diffkey.C +++ b/cinelerra-5.1/plugins/diffkey/diffkey.C @@ -22,6 +22,7 @@ #ifndef DIFFKEY_H #define DIFFKEY_H +#include "bccolors.h" #include "bcdisplayinfo.h" #include "clip.h" #include "bchash.h" @@ -31,7 +32,7 @@ #include "loadbalance.h" #include "bccolors.h" #include "pluginvclient.h" - +#include "playback3d.h" #include @@ -450,8 +451,9 @@ int DiffKey::handle_opengl() " float difference = abs(foreground.r - background.r);\n"; static const char *rgb_value = - " float difference = abs(dot(foreground.rgb, vec3(0.29900, 0.58700, 0.11400)) - \n" - " dot(background.rgb, vec3(0.29900, 0.58700, 0.11400)));\n"; + " float difference = abs(" + " dot(foreground.rgb, rgb_to_yuv_matrix[0]) - " + " dot(background.rgb, rgb_to_yuv_matrix[0]));\n"; static const char *diffkey_tail = " vec4 result;\n" @@ -466,10 +468,6 @@ int DiffKey::handle_opengl() " gl_FragColor = result;\n" "}\n"; - - - - top_frame->enable_opengl(); top_frame->init_screen(); @@ -479,46 +477,27 @@ int DiffKey::handle_opengl() top_frame->enable_opengl(); top_frame->init_screen(); - unsigned int shader_id = 0; - if(config.do_value) - { - if(BC_CModels::is_yuv(top_frame->get_color_model())) - shader_id = VFrame::make_shader(0, - diffkey_head, - yuv_value, - diffkey_tail, - 0); - else - shader_id = VFrame::make_shader(0, - diffkey_head, - rgb_value, - diffkey_tail, - 0); - } - else - { - shader_id = VFrame::make_shader(0, - diffkey_head, - colorcube, - diffkey_tail, - 0); - } - - + int need_color_matrix = 0; + const char *shader_frag = !config.do_value ? colorcube : + BC_CModels::is_yuv(top_frame->get_color_model()) ? + yuv_value : (need_color_matrix = 1, rgb_value); + unsigned int shader = VFrame::make_shader(0, + diffkey_head, shader_frag, diffkey_tail, 0); DIFFKEY_VARS(this) bottom_frame->bind_texture(1); top_frame->bind_texture(0); - if(shader_id > 0) - { - glUseProgram(shader_id); - glUniform1i(glGetUniformLocation(shader_id, "tex_fg"), 0); - glUniform1i(glGetUniformLocation(shader_id, "tex_bg"), 1); - glUniform1f(glGetUniformLocation(shader_id, "threshold"), threshold); - glUniform1f(glGetUniformLocation(shader_id, "pad"), pad); - glUniform1f(glGetUniformLocation(shader_id, "threshold_pad"), threshold_pad); + if( shader > 0 ) { + glUseProgram(shader); + glUniform1i(glGetUniformLocation(shader, "tex_fg"), 0); + glUniform1i(glGetUniformLocation(shader, "tex_bg"), 1); + glUniform1f(glGetUniformLocation(shader, "threshold"), threshold); + glUniform1f(glGetUniformLocation(shader, "pad"), pad); + glUniform1f(glGetUniformLocation(shader, "threshold_pad"), threshold_pad); + if( need_color_matrix ) + BC_GL_MATRIX(shader, rgb_to_yuv_matrix); } if(BC_CModels::components(get_output()->get_color_model()) == 3) @@ -531,11 +510,14 @@ int DiffKey::handle_opengl() top_frame->draw_texture(); glUseProgram(0); top_frame->set_opengl_state(VFrame::SCREEN); -// Fastest way to discard output - bottom_frame->set_opengl_state(VFrame::TEXTURE); glDisable(GL_BLEND); +// does not work, fails in playback3d +// Fastest way to discard output +// bottom_frame->set_opengl_state(VFrame::TEXTURE); +// kludge ahead + top_frame->screen_to_ram(); #endif return 0; } @@ -598,8 +580,7 @@ void DiffKeyClient::process_package(LoadPackage *ptr) DiffKey *plugin = engine->plugin; int w = plugin->top_frame->get_w(); -#define RGB_TO_VALUE(r, g, b) \ -((r) * R_TO_Y + (g) * G_TO_Y + (b) * B_TO_Y) +#define RGB_TO_VALUE(r, g, b) YUV::yuv.rgb_to_y_f((r),(g),(b)) #define DIFFKEY_MACRO(type, components, max, chroma_offset) \ diff --git a/cinelerra-5.1/plugins/dissolve/dissolve.C b/cinelerra-5.1/plugins/dissolve/dissolve.C index e2e0d532..6c04fa07 100644 --- a/cinelerra-5.1/plugins/dissolve/dissolve.C +++ b/cinelerra-5.1/plugins/dissolve/dissolve.C @@ -108,25 +108,20 @@ int DissolveMain::handle_opengl() src->bind_texture(0); dst->bind_texture(1); - const char *shader_stack[] = { 0, 0, 0 }; - int current_shader = 0; - shader_stack[current_shader++] = blend_dissolve; - - unsigned int shader_id = VFrame::make_shader(0, - shader_stack[0], shader_stack[1], shader_stack[2], 0); - - glUseProgram(shader_id); - glUniform1f(glGetUniformLocation(shader_id, "fade"), fade); - glUniform1i(glGetUniformLocation(shader_id, "src_tex"), 0); - glUniform1i(glGetUniformLocation(shader_id, "dst_tex"), 1); - if(BC_CModels::is_yuv(dst->get_color_model())) - glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"), 0.0, 0.5, 0.5); - else - glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"), 0.0, 0.0, 0.0); - glUniform2f(glGetUniformLocation(shader_id, "dst_tex_dimensions"), - (float)dst->get_texture_w(), - (float)dst->get_texture_h()); - + unsigned int shader = VFrame::make_shader(0, blend_dissolve, 0); + if( shader > 0 ) { + glUseProgram(shader); + glUniform1f(glGetUniformLocation(shader, "fade"), fade); + glUniform1i(glGetUniformLocation(shader, "src_tex"), 0); + glUniform1i(glGetUniformLocation(shader, "dst_tex"), 1); + if(BC_CModels::is_yuv(dst->get_color_model())) + glUniform3f(glGetUniformLocation(shader, "chroma_offset"), 0.0, 0.5, 0.5); + else + glUniform3f(glGetUniformLocation(shader, "chroma_offset"), 0.0, 0.0, 0.0); + glUniform2f(glGetUniformLocation(shader, "dst_tex_dimensions"), + (float)dst->get_texture_w(), + (float)dst->get_texture_h()); + } glDisable(GL_BLEND); src->draw_texture(); glUseProgram(0); diff --git a/cinelerra-5.1/plugins/framefield/framefield.C b/cinelerra-5.1/plugins/framefield/framefield.C index 68312aea..f4ff5487 100644 --- a/cinelerra-5.1/plugins/framefield/framefield.C +++ b/cinelerra-5.1/plugins/framefield/framefield.C @@ -718,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,49 +737,40 @@ int FrameField::handle_opengl() 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(); diff --git a/cinelerra-5.1/plugins/gamma/aggregated.h b/cinelerra-5.1/plugins/gamma/aggregated.h index 592ce80b..695497d6 100644 --- a/cinelerra-5.1/plugins/gamma/aggregated.h +++ b/cinelerra-5.1/plugins/gamma/aggregated.h @@ -72,29 +72,16 @@ static const char *gamma_yuv_frag = " gl_FragColor = pixel;\n" "}\n"; -#define GAMMA_COMPILE(shader_stack, current_shader, aggregate_interpolation) \ -{ \ - if(aggregate_interpolation) \ - shader_stack[current_shader++] = gamma_get_pixel1; \ - else \ - shader_stack[current_shader++] = gamma_get_pixel2; \ - \ - switch(get_output()->get_color_model()) \ - { \ - case BC_YUV888: \ - case BC_YUVA8888: \ - shader_stack[current_shader++] = gamma_pow_frag; \ - shader_stack[current_shader++] = gamma_yuv_frag; \ - break; \ - default: \ - shader_stack[current_shader++] = gamma_pow_frag; \ - shader_stack[current_shader++] = gamma_rgb_frag; \ - break; \ - } \ -} +#define GAMMA_COMPILE(shader_stack, current_shader, aggregate_interpolation) do { \ + shader_stack[current_shader++] = \ + (aggregate_interpolation) ? gamma_get_pixel1 : gamma_get_pixel2; \ + shader_stack[current_shader++] = gamma_pow_frag; \ + shader_stack[current_shader++] = \ + !BC_CModels::is_yuv(get_output()->get_color_model()) ? \ + gamma_rgb_frag : gamma_yuv_frag; \ +} while(0) -#define GAMMA_UNIFORMS(frag) \ -{ \ +#define GAMMA_UNIFORMS(frag) do { \ float gamma = get_output()->get_params()->get("GAMMA_GAMMA", (float)1); \ float max = get_output()->get_params()->get("GAMMA_MAX", (float)1) * gamma; \ gamma -= 1.0; \ @@ -102,11 +89,6 @@ static const char *gamma_yuv_frag = glUniform1f(glGetUniformLocation(frag, "gamma_scale"), scale); \ glUniform1f(glGetUniformLocation(frag, "gamma_gamma"), gamma); \ glUniform1f(glGetUniformLocation(frag, "gamma_max"), max); \ -printf("GAMMA_UNIFORMS %f %f\n", max, gamma); \ -} - - - - +} while(0) #endif diff --git a/cinelerra-5.1/plugins/gamma/gamma.C b/cinelerra-5.1/plugins/gamma/gamma.C index 1307d8cd..a462b062 100644 --- a/cinelerra-5.1/plugins/gamma/gamma.C +++ b/cinelerra-5.1/plugins/gamma/gamma.C @@ -573,43 +573,30 @@ int GammaMain::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; - const char *shader_stack[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int current_shader = 0; - + int need_color_matrix = BC_CModels::is_yuv(get_output()->get_color_model()) ? 1 : 0; + if( need_color_matrix ) + shader_stack[current_shader++] = bc_gl_colors; // Aggregate with interpolate - int aggregate = 0; - if(prev_effect_is(_("Interpolate Pixels"))) - { - aggregate = 1; - INTERPOLATE_COMPILE(shader_stack, current_shader) - } + int aggregate = prev_effect_is(_("Interpolate Pixels")) ? 1 : 0; + if( aggregate ) + INTERPOLATE_COMPILE(shader_stack, current_shader); GAMMA_COMPILE(shader_stack, current_shader, aggregate); - unsigned int shader = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - shader_stack[4], - shader_stack[5], - shader_stack[6], - shader_stack[7], - 0); - - - if(shader > 0) - { + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); + if( shader > 0 ) { glUseProgram(shader); glUniform1i(glGetUniformLocation(shader, "tex"), 0); - if(aggregate) - { - INTERPOLATE_UNIFORMS(shader) - } - GAMMA_UNIFORMS(shader) + INTERPOLATE_UNIFORMS(shader); + GAMMA_UNIFORMS(shader); + if( need_color_matrix ) BC_GL_COLORS(shader); } get_output()->init_screen(); diff --git a/cinelerra-5.1/plugins/gradient/gradient.C b/cinelerra-5.1/plugins/gradient/gradient.C index 9cf1c152..2378aec9 100644 --- a/cinelerra-5.1/plugins/gradient/gradient.C +++ b/cinelerra-5.1/plugins/gradient/gradient.C @@ -895,132 +895,125 @@ int GradientMain::handle_opengl() "}\n"; - const char *shader_stack[5] = { 0, 0, 0, 0, 0 }; - shader_stack[0] = head_frag; - - switch(config.shape) - { - case GradientConfig::LINEAR: - shader_stack[1] = linear_shape; - break; - - default: - shader_stack[1] = radial_shape; - break; + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + shader_stack[current_shader++] = head_frag; + + const char *shape_frag = 0; + switch( config.shape ) { + case GradientConfig::LINEAR: + shape_frag = linear_shape; + break; + default: + shape_frag = radial_shape; + break; } - - switch(config.rate) - { - case GradientConfig::LINEAR: - shader_stack[2] = linear_rate; - break; - case GradientConfig::LOG: - shader_stack[2] = log_rate; - break; - case GradientConfig::SQUARE: - shader_stack[2] = square_rate; - break; + if( shape_frag ) + shader_stack[current_shader++] = shape_frag; + + const char *rate_frag = 0; + switch(config.rate) { + case GradientConfig::LINEAR: + rate_frag = linear_rate; + break; + case GradientConfig::LOG: + rate_frag = log_rate; + break; + case GradientConfig::SQUARE: + rate_frag = square_rate; + break; } + if( rate_frag ) + shader_stack[current_shader++] = rate_frag; + + shader_stack[current_shader++] = tail_frag; - shader_stack[3] = tail_frag; // Force frame to create texture without copying to it if full alpha. - if(config.in_a >= 0xff && - config.out_a >= 0xff) + if( config.in_a >= 0xff && config.out_a >= 0xff ) get_output()->set_opengl_state(VFrame::TEXTURE); get_output()->to_texture(); get_output()->enable_opengl(); get_output()->init_screen(); get_output()->bind_texture(0); - unsigned int frag = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - 0); - - if(frag) - { - glUseProgram(frag); + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); + if( shader > 0 ) { + glUseProgram(shader); float w = get_output()->get_w(); float h = get_output()->get_h(); float texture_w = get_output()->get_texture_w(); float texture_h = get_output()->get_texture_h(); - glUniform1i(glGetUniformLocation(frag, "tex"), 0); - glUniform1f(glGetUniformLocation(frag, "half_w"), w / 2 / texture_w); - glUniform1f(glGetUniformLocation(frag, "half_h"), h / 2 / texture_h); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + glUniform1f(glGetUniformLocation(shader, "half_w"), w / 2 / texture_w); + glUniform1f(glGetUniformLocation(shader, "half_h"), h / 2 / texture_h); if(config.shape == GradientConfig::LINEAR) { - glUniform1f(glGetUniformLocation(frag, "center_x"), + glUniform1f(glGetUniformLocation(shader, "center_x"), w / 2 / texture_w); - glUniform1f(glGetUniformLocation(frag, "center_y"), + glUniform1f(glGetUniformLocation(shader, "center_y"), h / 2 / texture_h); } else { - glUniform1f(glGetUniformLocation(frag, "center_x"), + glUniform1f(glGetUniformLocation(shader, "center_x"), (float)config.center_x * w / 100 / texture_w); - glUniform1f(glGetUniformLocation(frag, "center_y"), + glUniform1f(glGetUniformLocation(shader, "center_y"), (float)config.center_y * h / 100 / texture_h); } float gradient_size = hypotf(w / texture_w, h / texture_h); - glUniform1f(glGetUniformLocation(frag, "half_gradient_size"), + glUniform1f(glGetUniformLocation(shader, "half_gradient_size"), gradient_size / 2); - glUniform1f(glGetUniformLocation(frag, "sin_angle"), + glUniform1f(glGetUniformLocation(shader, "sin_angle"), sin(config.angle * (M_PI / 180))); - glUniform1f(glGetUniformLocation(frag, "cos_angle"), + glUniform1f(glGetUniformLocation(shader, "cos_angle"), cos(config.angle * (M_PI / 180))); float in_radius = (float)config.in_radius / 100 * gradient_size; - glUniform1f(glGetUniformLocation(frag, "in_radius"), in_radius); + glUniform1f(glGetUniformLocation(shader, "in_radius"), in_radius); float out_radius = (float)config.out_radius / 100 * gradient_size; - glUniform1f(glGetUniformLocation(frag, "out_radius"), out_radius); - glUniform1f(glGetUniformLocation(frag, "radius_diff"), + glUniform1f(glGetUniformLocation(shader, "out_radius"), out_radius); + glUniform1f(glGetUniformLocation(shader, "radius_diff"), out_radius - in_radius); - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - { - float in1, in2, in3, in4; - float out1, out2, out3, out4; - YUV::yuv.rgb_to_yuv_f((float)config.in_r / 0xff, - (float)config.in_g / 0xff, - (float)config.in_b / 0xff, - in1, - in2, - in3); + switch(get_output()->get_color_model()) { + case BC_YUV888: + case BC_YUVA8888: { + float in1, in2, in3, in4; + float out1, out2, out3, out4; + YUV::yuv.rgb_to_yuv_f( + (float)config.in_r / 0xff, + (float)config.in_g / 0xff, + (float)config.in_b / 0xff, + in1, in2, in3); in4 = (float)config.in_a / 0xff; - YUV::yuv.rgb_to_yuv_f((float)config.out_r / 0xff, - (float)config.out_g / 0xff, - (float)config.out_b / 0xff, - out1, - out2, - out3); - in2 += 0.5; - in3 += 0.5; - out2 += 0.5; - out3 += 0.5; - out4 = (float)config.out_a / 0xff; - glUniform4f(glGetUniformLocation(frag, "out_color"), - out1, out2, out3, out4); - glUniform4f(glGetUniformLocation(frag, "in_color"), - in1, in2, in3, in4); - break; - } + YUV::yuv.rgb_to_yuv_f( + (float)config.out_r / 0xff, + (float)config.out_g / 0xff, + (float)config.out_b / 0xff, + out1, out2, out3); + in2 += 0.5; in3 += 0.5; + out2 += 0.5; out3 += 0.5; + out4 = (float)config.out_a / 0xff; + glUniform4f(glGetUniformLocation(shader, "out_color"), + out1, out2, out3, out4); + glUniform4f(glGetUniformLocation(shader, "in_color"), + in1, in2, in3, in4); + break; } - default: - glUniform4f(glGetUniformLocation(frag, "out_color"), - (float)config.out_r / 0xff, - (float)config.out_g / 0xff, - (float)config.out_b / 0xff, - (float)config.out_a / 0xff); - glUniform4f(glGetUniformLocation(frag, "in_color"), - (float)config.in_r / 0xff, - (float)config.in_g / 0xff, - (float)config.in_b / 0xff, - (float)config.in_a / 0xff); - break; + default: + glUniform4f(glGetUniformLocation(shader, "out_color"), + (float)config.out_r / 0xff, + (float)config.out_g / 0xff, + (float)config.out_b / 0xff, + (float)config.out_a / 0xff); + glUniform4f(glGetUniformLocation(shader, "in_color"), + (float)config.in_r / 0xff, + (float)config.in_g / 0xff, + (float)config.in_b / 0xff, + (float)config.in_a / 0xff); + break; } } @@ -1033,23 +1026,11 @@ int GradientMain::handle_opengl() } - - - - - - - - - GradientPackage::GradientPackage() : LoadPackage() { } - - - GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin) : LoadClient(server) { @@ -1058,8 +1039,6 @@ GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin) } - - static float calculate_opacity(float mag, float in_radius, float out_radius, int rate) { diff --git a/cinelerra-5.1/plugins/histogram/histogram.C b/cinelerra-5.1/plugins/histogram/histogram.C index a31f2fec..996edac9 100644 --- a/cinelerra-5.1/plugins/histogram/histogram.C +++ b/cinelerra-5.1/plugins/histogram/histogram.C @@ -625,8 +625,14 @@ int HistogramMain::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); - const char *shader_stack[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int current_shader = 0; + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + int need_color_matrix = BC_CModels::is_yuv(get_output()->get_color_model()) ? 1 : 0; + if( need_color_matrix ) + shader_stack[current_shader++] = bc_gl_colors; + int aggregate_interpolation = 0; int aggregate_gamma = 0; int aggregate_colorbalance = 0; @@ -671,64 +677,34 @@ int HistogramMain::handle_opengl() if(!strcmp(get_output()->get_prev_effect(0), _("Color Balance"))) aggregate_colorbalance = 1; + if( BC_CModels::is_yuv(get_output()->get_color_model()) ) + shader_stack[current_shader++] = bc_gl_colors; // The order of processing is fixed by this sequence if(aggregate_interpolation) - INTERPOLATE_COMPILE(shader_stack, - current_shader) + INTERPOLATE_COMPILE(shader_stack, current_shader); if(aggregate_gamma) - GAMMA_COMPILE(shader_stack, - current_shader, - aggregate_interpolation) + GAMMA_COMPILE(shader_stack, current_shader, + aggregate_interpolation); if(aggregate_colorbalance) - COLORBALANCE_COMPILE(shader_stack, - current_shader, - aggregate_interpolation || aggregate_gamma) + COLORBALANCE_COMPILE(shader_stack, current_shader, + aggregate_interpolation || aggregate_gamma); + shader_stack[current_shader++] = + aggregate_interpolation || aggregate_gamma || aggregate_colorbalance ? + histogram_get_pixel1 : histogram_get_pixel2; - if(aggregate_interpolation || aggregate_gamma || aggregate_colorbalance) - shader_stack[current_shader++] = histogram_get_pixel1; - else - shader_stack[current_shader++] = histogram_get_pixel2; - - unsigned int shader = 0; - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - shader_stack[current_shader++] = head_frag; - shader_stack[current_shader++] = get_yuv_frag; - shader_stack[current_shader++] = apply_histogram_frag; - shader_stack[current_shader++] = put_yuv_frag; - break; - default: - shader_stack[current_shader++] = head_frag; - shader_stack[current_shader++] = get_rgb_frag; - shader_stack[current_shader++] = apply_histogram_frag; - shader_stack[current_shader++] = put_rgb_frag; - break; - } + shader_stack[current_shader++] = head_frag; + shader_stack[current_shader++] = BC_CModels::is_yuv(get_output()->get_color_model()) ? + get_yuv_frag : get_rgb_frag; + shader_stack[current_shader++] = apply_histogram_frag; + shader_stack[current_shader++] = BC_CModels::is_yuv(get_output()->get_color_model()) ? + put_yuv_frag : put_rgb_frag; - shader = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - shader_stack[3], - shader_stack[4], - shader_stack[5], - shader_stack[6], - shader_stack[7], - shader_stack[8], - shader_stack[9], - shader_stack[10], - shader_stack[11], - shader_stack[12], - shader_stack[13], - shader_stack[14], - shader_stack[15], - 0); + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); // printf("HistogramMain::handle_opengl %d %d %d %d shader=%d\n", // aggregate_interpolation, @@ -763,14 +739,15 @@ int HistogramMain::handle_opengl() { glUseProgram(shader); glUniform1i(glGetUniformLocation(shader, "tex"), 0); - if(aggregate_gamma) GAMMA_UNIFORMS(shader) - if(aggregate_interpolation) INTERPOLATE_UNIFORMS(shader) - if(aggregate_colorbalance) COLORBALANCE_UNIFORMS(shader) + if(aggregate_gamma) GAMMA_UNIFORMS(shader); + if(aggregate_interpolation) INTERPOLATE_UNIFORMS(shader); + if(aggregate_colorbalance) COLORBALANCE_UNIFORMS(shader); glUniform4fv(glGetUniformLocation(shader, "low_input"), 1, low_input); glUniform4fv(glGetUniformLocation(shader, "high_input"), 1, high_input); glUniform4fv(glGetUniformLocation(shader, "gamma"), 1, gamma); glUniform4fv(glGetUniformLocation(shader, "low_output"), 1, low_output); glUniform4fv(glGetUniformLocation(shader, "output_scale"), 1, output_scale); + if( need_color_matrix ) BC_GL_COLORS(shader); } get_output()->init_screen(); diff --git a/cinelerra-5.1/plugins/huesaturation/huesaturation.C b/cinelerra-5.1/plugins/huesaturation/huesaturation.C index 4ecb1d61..db76fa23 100644 --- a/cinelerra-5.1/plugins/huesaturation/huesaturation.C +++ b/cinelerra-5.1/plugins/huesaturation/huesaturation.C @@ -677,38 +677,26 @@ int HueEffect::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); - unsigned int frag_shader = 0; - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: -// This is a lousy approximation but good enough for the masker. - if(EQUIV(config.hue, 0)) - frag_shader = VFrame::make_shader(0, - yuv_saturation_frag, - 0); - else - frag_shader = VFrame::make_shader(0, - yuv_frag, - 0); - break; - default: - frag_shader = VFrame::make_shader(0, - rgb_frag, - 0); - break; - } - - - if(frag_shader > 0) - { - glUseProgram(frag_shader); - glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); - glUniform1f(glGetUniformLocation(frag_shader, "h_offset"), config.hue); - glUniform1f(glGetUniformLocation(frag_shader, "s_offset"), + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + int need_color_matrix = BC_CModels::is_yuv(get_output()->get_color_model()) ? 1 : 0; + if( need_color_matrix ) shader_stack[current_shader++] = bc_gl_colors; + shader_stack[current_shader++] = !need_color_matrix ? rgb_frag : + EQUIV(config.hue, 0) ? yuv_saturation_frag: yuv_frag ; + + 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, "h_offset"), config.hue); + glUniform1f(glGetUniformLocation(shader, "s_offset"), ((float)config.saturation - MINSATURATION) / MAXSATURATION); - glUniform1f(glGetUniformLocation(frag_shader, "v_offset"), + glUniform1f(glGetUniformLocation(shader, "v_offset"), ((float)config.value - MINVALUE) / MAXVALUE); + if( need_color_matrix ) BC_GL_COLORS(shader); } get_output()->init_screen(); diff --git a/cinelerra-5.1/plugins/interpolate/aggregated.h b/cinelerra-5.1/plugins/interpolate/aggregated.h index 23904320..383a436e 100644 --- a/cinelerra-5.1/plugins/interpolate/aggregated.h +++ b/cinelerra-5.1/plugins/interpolate/aggregated.h @@ -38,10 +38,8 @@ static const char *interpolate_shader = " vec3 result;\n" " pattern_coord -= pattern_offset;\n" " pattern_coord = fract(pattern_coord / pattern_size);\n" -" if(pattern_coord.x >= 0.5)\n" -" {\n" -" if(pattern_coord.y >= 0.5)\n" -" {\n" +" if(pattern_coord.x >= 0.5) {\n" +" if(pattern_coord.y >= 0.5) {\n" /* Bottom right of pattern */ /* Bottom right pixels are: */ /* 2 */ @@ -52,13 +50,12 @@ static const char *interpolate_shader = " vec2 pixel3 = pixel_coord + vec2(pixel_size.x, 0.0);\n" " vec2 pixel4 = pixel_coord + vec2(0.0, pixel_size.y);\n" " result = vec3((texture2D(tex, pixel1).r + \n" -" texture2D(tex, pixel3).r) / 2.0, \n" -" texture2D(tex, pixel_coord).g, \n" -" (texture2D(tex, pixel2).b + \n" -" texture2D(tex, pixel4).b) / 2.0);\n" +" texture2D(tex, pixel3).r) / 2.0, \n" +" texture2D(tex, pixel_coord).g, \n" +" (texture2D(tex, pixel2).b + \n" +" texture2D(tex, pixel4).b) / 2.0);\n" " }\n" -" else\n" -" {\n" +" else {\n" /* Top right of pattern */ /* Top right pixels are: */ /* 123 */ @@ -73,20 +70,18 @@ static const char *interpolate_shader = " vec2 pixel7 = pixel_coord + vec2(0.0, pixel_size.y);\n" " vec2 pixel8 = pixel_coord + pixel_size;\n" " result = vec3((texture2D(tex, pixel1).r + \n" -" texture2D(tex, pixel3).r + \n" -" texture2D(tex, pixel6).r + \n" -" texture2D(tex, pixel8).r) / 4.0, \n" -" (texture2D(tex, pixel4).g + \n" -" texture2D(tex, pixel2).g + \n" -" texture2D(tex, pixel5).g + \n" -" texture2D(tex, pixel7).g) / 4.0, \n" -" texture2D(tex, pixel_coord).b);\n" +" texture2D(tex, pixel3).r + \n" +" texture2D(tex, pixel6).r + \n" +" texture2D(tex, pixel8).r) / 4.0, \n" +" (texture2D(tex, pixel4).g + \n" +" texture2D(tex, pixel2).g + \n" +" texture2D(tex, pixel5).g + \n" +" texture2D(tex, pixel7).g) / 4.0, \n" +" texture2D(tex, pixel_coord).b);\n" " }\n" " }\n" -" else\n" -" {\n" -" if(pattern_coord.y >= 0.5)\n" -" {\n" +" else {\n" +" if(pattern_coord.y >= 0.5) {\n" /* Bottom left of pattern */ /* Bottom left pixels are: */ /* 123 */ @@ -100,19 +95,17 @@ static const char *interpolate_shader = " vec2 pixel6 = pixel_coord + vec2(-pixel_size.x, pixel_size.y);\n" " vec2 pixel7 = pixel_coord + vec2(0.0, pixel_size.y);\n" " vec2 pixel8 = pixel_coord + pixel_size;\n" -" result = vec3(\n" -" texture2D(tex, pixel_coord).r, \n" -" (texture2D(tex, pixel4).g + \n" -" texture2D(tex, pixel2).g + \n" -" texture2D(tex, pixel5).g + \n" -" texture2D(tex, pixel7).g) / 4.0, \n" -" (texture2D(tex, pixel1).b + \n" -" texture2D(tex, pixel3).b + \n" -" texture2D(tex, pixel6).b + \n" -" texture2D(tex, pixel8).b) / 4.0);\n" +" result = vec3(texture2D(tex, pixel_coord).r, \n" +" (texture2D(tex, pixel4).g + \n" +" texture2D(tex, pixel2).g + \n" +" texture2D(tex, pixel5).g + \n" +" texture2D(tex, pixel7).g) / 4.0, \n" +" (texture2D(tex, pixel1).b + \n" +" texture2D(tex, pixel3).b + \n" +" texture2D(tex, pixel6).b + \n" +" texture2D(tex, pixel8).b) / 4.0);\n" " }\n" -" else\n" -" {\n" +" else {\n" /* Top left of pattern */ /* Top left pixels are: */ /* 2 */ @@ -122,27 +115,23 @@ static const char *interpolate_shader = " vec2 pixel2 = pixel_coord - vec2(0.0, pixel_size.y);\n" " vec2 pixel3 = pixel_coord + vec2(pixel_size.x, 0.0);\n" " vec2 pixel4 = pixel_coord + vec2(0.0, pixel_size.y);\n" -" result = vec3(\n" -" (texture2D(tex, pixel2).r + \n" -" texture2D(tex, pixel4).r) / 2.0, \n" -" texture2D(tex, pixel_coord).g, \n" -" (texture2D(tex, pixel1).b + \n" -" texture2D(tex, pixel3).b) / 2.0);\n" +" result = vec3((texture2D(tex, pixel2).r + \n" +" texture2D(tex, pixel4).r) / 2.0, \n" +" texture2D(tex, pixel_coord).g, \n" +" (texture2D(tex, pixel1).b + \n" +" texture2D(tex, pixel3).b) / 2.0);\n" " }\n" " }\n" "\n" -"\n" " gl_FragColor = vec4(result * color_matrix, 1.0);\n" "}\n"; -#define INTERPOLATE_COMPILE(shader_stack, current_shader) \ -{ \ +#define INTERPOLATE_COMPILE(shader_stack, current_shader) do { \ shader_stack[current_shader++] = interpolate_shader; \ -} +} while(0) -#define INTERPOLATE_UNIFORMS(frag) \ -{ \ +#define INTERPOLATE_UNIFORMS(frag) do { \ int x_offset = get_output()->get_params()->get("INTERPOLATEPIXELS_X", (int)0); \ int y_offset = get_output()->get_params()->get("INTERPOLATEPIXELS_Y", (int)0); \ float color_matrix[9]; \ @@ -151,21 +140,12 @@ static const char *interpolate_shader = char string[BCTEXTLEN]; \ string[0] = 0; \ get_output()->get_params()->get("DCRAW_MATRIX", string); \ - sscanf(string, \ - "%f %f %f %f %f %f %f %f %f", \ - &color_matrix[0], \ - &color_matrix[1], \ - &color_matrix[2], \ - &color_matrix[3], \ - &color_matrix[4], \ - &color_matrix[5], \ - &color_matrix[6], \ - &color_matrix[7], \ - &color_matrix[8]); \ + sscanf(string, "%f %f %f %f %f %f %f %f %f", \ + &color_matrix[0], &color_matrix[1], &color_matrix[2], \ + &color_matrix[3], &color_matrix[4], &color_matrix[5], \ + &color_matrix[6], &color_matrix[7], &color_matrix[8]); \ glUniformMatrix3fv(glGetUniformLocation(frag, "color_matrix"), \ - 1, \ - 0, \ - color_matrix); \ + 1, 0, color_matrix); \ glUniform2f(glGetUniformLocation(frag, "pattern_offset"), \ (float)x_offset / get_output()->get_texture_w(), \ (float)y_offset / get_output()->get_texture_h()); \ @@ -175,7 +155,7 @@ static const char *interpolate_shader = glUniform2f(glGetUniformLocation(frag, "pixel_size"), \ 1.0 / get_output()->get_texture_w(), \ 1.0 / get_output()->get_texture_h()); \ -} +} while(0) #endif diff --git a/cinelerra-5.1/plugins/interpolate/interpolate.C b/cinelerra-5.1/plugins/interpolate/interpolate.C index cbb8fa7c..84f1bfc6 100644 --- a/cinelerra-5.1/plugins/interpolate/interpolate.C +++ b/cinelerra-5.1/plugins/interpolate/interpolate.C @@ -327,20 +327,20 @@ int InterpolatePixelsMain::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); - const char *shader_stack[] = { 0, 0, 0 }; - int current_shader = 0; - INTERPOLATE_COMPILE(shader_stack, current_shader) - unsigned int frag = VFrame::make_shader(0, - shader_stack[0], - 0); - if(frag > 0) - { - glUseProgram(frag); - glUniform1i(glGetUniformLocation(frag, "tex"), 0); - INTERPOLATE_UNIFORMS(frag) + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); + int current_shader = 0; + + INTERPOLATE_COMPILE(shader_stack, current_shader); + + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); + if( shader > 0 ) { + glUseProgram(shader); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + INTERPOLATE_UNIFORMS(shader); } - get_output()->init_screen(); get_output()->bind_texture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); diff --git a/cinelerra-5.1/plugins/invertvideo/invert.C b/cinelerra-5.1/plugins/invertvideo/invert.C index 078f48f8..fed3f3ef 100644 --- a/cinelerra-5.1/plugins/invertvideo/invert.C +++ b/cinelerra-5.1/plugins/invertvideo/invert.C @@ -349,10 +349,7 @@ int InvertVideoEffect::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); - unsigned int frag_shader = 0; - frag_shader = VFrame::make_shader(0, - invert_frag, - 0); + unsigned int frag_shader = VFrame::make_shader(0, invert_frag, 0); glUseProgram(frag_shader); glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); glUniform1i(glGetUniformLocation(frag_shader, "do_r"), config.r); diff --git a/cinelerra-5.1/plugins/lens/lens.C b/cinelerra-5.1/plugins/lens/lens.C index 00411de9..c5b4648c 100644 --- a/cinelerra-5.1/plugins/lens/lens.C +++ b/cinelerra-5.1/plugins/lens/lens.C @@ -947,15 +947,14 @@ int LensMain::handle_opengl() "uniform vec2 center_coord;\n" "uniform vec4 border_color;\n" "uniform vec4 r;\n" - "uniform float radius;\n" "void main()\n" "{\n" " vec2 outcoord = gl_TexCoord[0].st * texture_extents;\n" " vec2 coord_diff = outcoord - center_coord;\n" " float z = sqrt(coord_diff.x * coord_diff.x +\n" " coord_diff.y * coord_diff.y);\n" - " vec4 radius1 = (vec4(z, z, z, z) / r) * 2.0 * radius;\n" - " vec4 z_in = r * atan(radius1) / (3.14159 / 2.0);\n" + " vec4 radius1 = vec4(z, z, z, z) / r;\n" + " vec4 z_in = r * tan(radius1) / (3.14159 / 2.0);\n" "\n" " float angle;\n" " if( coord_diff.x == 0.0 )\n" @@ -992,29 +991,29 @@ int LensMain::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); - unsigned int frag_shader = 0; - switch( config.mode ) - { + unsigned int shader = 0; + const char *shader_frag = 0; + switch( config.mode ) { case LensConfig::SPHERICAL_SHRINK: - frag_shader = VFrame::make_shader(0, shrink_frag, 0); + shader_frag = shrink_frag; break; case LensConfig::SPHERICAL_STRETCH: - frag_shader = VFrame::make_shader(0, stretch_frag, 0); + shader_frag = stretch_frag; break; case LensConfig::RECTILINEAR_STRETCH: - frag_shader = VFrame::make_shader(0, rectilinear_stretch_frag, 0); + shader_frag = rectilinear_stretch_frag; break; case LensConfig::RECTILINEAR_SHRINK: - frag_shader = VFrame::make_shader(0, rectilinear_shrink_frag, 0); + shader_frag = rectilinear_shrink_frag; break; } - - if( frag_shader > 0 ) { + if( shader_frag ) + shader = VFrame::make_shader(0, shader_frag, 0); + if( shader > 0 ) { float border_color[] = { 0, 0, 0, 0 }; if( BC_CModels::is_yuv(get_output()->get_color_model()) ) { - border_color[1] = 0.5; - border_color[2] = 0.5; + border_color[1] = border_color[2] = 0.5; } double x_factor = config.aspect; @@ -1022,18 +1021,18 @@ int LensMain::handle_opengl() if( x_factor < 1 ) x_factor = 1; if( y_factor < 1 ) y_factor = 1; - glUseProgram(frag_shader); - glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); - glUniform2f(glGetUniformLocation(frag_shader, "aspect"), + glUseProgram(shader); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + glUniform2f(glGetUniformLocation(shader, "aspect"), x_factor, y_factor); - glUniform2f(glGetUniformLocation(frag_shader, "center_coord"), + glUniform2f(glGetUniformLocation(shader, "center_coord"), (GLfloat)get_input()->get_w() * config.center_x / 100.0, (GLfloat)get_input()->get_h() * config.center_y / 100.0); - glUniform2f(glGetUniformLocation(frag_shader, "texture_extents"), + glUniform2f(glGetUniformLocation(shader, "texture_extents"), (GLfloat)get_input()->get_texture_w(), (GLfloat)get_input()->get_texture_h()); - glUniform2f(glGetUniformLocation(frag_shader, "image_extents"), + glUniform2f(glGetUniformLocation(shader, "image_extents"), (GLfloat)get_input()->get_w(), (GLfloat)get_input()->get_h()); @@ -1042,60 +1041,55 @@ int LensMain::handle_opengl() float *fov = config.fov; float dim; float max_z; - switch( config.mode ) - { - case LensConfig::SPHERICAL_SHRINK: - dim = MAX(width, height) * config.radius; - max_z = dim * sqrt(2.0) / 2; - glUniform4fv(glGetUniformLocation(frag_shader, "border_color"), - 1, - (GLfloat*)border_color); - glUniform4f(glGetUniformLocation(frag_shader, "max_z"), + switch( config.mode ) { + case LensConfig::SPHERICAL_SHRINK: + dim = MAX(width, height) * config.radius; + max_z = dim * sqrt(2.0) / 2; + glUniform4fv(glGetUniformLocation(shader, "border_color"), + 1, (GLfloat*)border_color); + glUniform4f(glGetUniformLocation(shader, "max_z"), max_z / fov[0], max_z / fov[1], max_z / fov[2], max_z / fov[3]); - glUniform4f(glGetUniformLocation(frag_shader, "r"), + glUniform4f(glGetUniformLocation(shader, "r"), (max_z / fov[0]) * 2 / M_PI, (max_z / fov[1]) * 2 / M_PI, (max_z / fov[2]) * 2 / M_PI, (max_z / fov[3]) * 2 / M_PI); - break; + break; - case LensConfig::SPHERICAL_STRETCH: - dim = MAX(width, height) * config.radius; - max_z = dim * sqrt(2.0) / 2; - glUniform4f(glGetUniformLocation(frag_shader, "r"), + case LensConfig::SPHERICAL_STRETCH: + dim = MAX(width, height) * config.radius; + max_z = dim * sqrt(2.0) / 2; + glUniform4f(glGetUniformLocation(shader, "r"), max_z / M_PI / (fov[0] / 2.0), max_z / M_PI / (fov[1] / 2.0), max_z / M_PI / (fov[2] / 2.0), max_z / M_PI / (fov[3] / 2.0)); - break; + break; - case LensConfig::RECTILINEAR_STRETCH: - max_z = sqrt(SQR(width) + SQR(height)) / 2; - glUniform4f(glGetUniformLocation(frag_shader, "r"), + case LensConfig::RECTILINEAR_STRETCH: + max_z = sqrt(SQR(width) + SQR(height)) / 2; + glUniform4f(glGetUniformLocation(shader, "r"), max_z / M_PI / (fov[0] / 2.0), max_z / M_PI / (fov[1] / 2.0), max_z / M_PI / (fov[2] / 2.0), max_z / M_PI / (fov[3] / 2.0)); - glUniform1f(glGetUniformLocation(frag_shader, "radius"), + glUniform1f(glGetUniformLocation(shader, "radius"), config.radius); - break; + break; - case LensConfig::RECTILINEAR_SHRINK: - max_z = sqrt(SQR(width) + SQR(height)) / 2; - glUniform4f(glGetUniformLocation(frag_shader, "r"), - max_z / M_PI / (fov[0] / 2.0), - max_z / M_PI / (fov[1] / 2.0), - max_z / M_PI / (fov[2] / 2.0), - max_z / M_PI / (fov[3] / 2.0)); - glUniform1f(glGetUniformLocation(frag_shader, "radius"), - config.radius); - break; + case LensConfig::RECTILINEAR_SHRINK: + max_z = MAX(width, height) / 2 * config.radius; + glUniform4f(glGetUniformLocation(shader, "r"), + max_z / fov[0], + max_z / fov[1], + max_z / fov[2], + max_z / fov[3]); + break; } - get_output()->init_screen(); get_output()->bind_texture(0); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); @@ -1104,7 +1098,6 @@ int LensMain::handle_opengl() get_output()->draw_texture(); glUseProgram(0); - if( config.draw_guides ) { int w = get_output()->get_w(); int h = get_output()->get_h(); diff --git a/cinelerra-5.1/plugins/overlay/overlay.C b/cinelerra-5.1/plugins/overlay/overlay.C index 5f0ea80f..fd423d75 100644 --- a/cinelerra-5.1/plugins/overlay/overlay.C +++ b/cinelerra-5.1/plugins/overlay/overlay.C @@ -593,29 +593,26 @@ static const char * const overlay_shaders[TRANSFER_TYPES] = { dst->init_screen(); src->bind_texture(0); dst->bind_texture(1); - const char *shader_stack[] = { 0, 0, 0 }; + + const char *shader_stack[16]; + memset(shader_stack,0, sizeof(shader_stack)); int current_shader = 0; shader_stack[current_shader++] = get_pixels_frag; shader_stack[current_shader++] = overlay_shaders[config.mode]; shader_stack[current_shader++] = put_pixels_frag; - - unsigned int shader_id = 0; - shader_id = VFrame::make_shader(0, - shader_stack[0], - shader_stack[1], - shader_stack[2], - 0); - - glUseProgram(shader_id); - glUniform1i(glGetUniformLocation(shader_id, "src_tex"), 0); - glUniform1i(glGetUniformLocation(shader_id, "dst_tex"), 1); - glUniform2f(glGetUniformLocation(shader_id, "dst_tex_dimensions"), - (float)dst->get_texture_w(), (float)dst->get_texture_h()); - float chroma_offset = BC_CModels::is_yuv(dst->get_color_model()) ? 0.5 : 0.0; - glUniform3f(glGetUniformLocation(shader_id, "chroma_offset"), - 0.0, chroma_offset, chroma_offset); - + shader_stack[current_shader] = 0; + unsigned int shader = VFrame::make_shader(shader_stack); + if( shader > 0 ) { + glUseProgram(shader); + glUniform1i(glGetUniformLocation(shader, "src_tex"), 0); + glUniform1i(glGetUniformLocation(shader, "dst_tex"), 1); + glUniform2f(glGetUniformLocation(shader, "dst_tex_dimensions"), + (float)dst->get_texture_w(), (float)dst->get_texture_h()); + float chroma_offset = BC_CModels::is_yuv(dst->get_color_model()) ? 0.5 : 0.0; + glUniform3f(glGetUniformLocation(shader, "chroma_offset"), + 0.0, chroma_offset, chroma_offset); + } src->draw_texture(); glUseProgram(0); diff --git a/cinelerra-5.1/plugins/rgb601/rgb601.C b/cinelerra-5.1/plugins/rgb601/rgb601.C index c67de4af..e04e0f41 100644 --- a/cinelerra-5.1/plugins/rgb601/rgb601.C +++ b/cinelerra-5.1/plugins/rgb601/rgb601.C @@ -353,24 +353,22 @@ int RGB601Main::handle_opengl() get_output()->bind_texture(0); unsigned int frag_shader = 0; - switch(get_output()->get_color_model()) - { - case BC_YUV888: - case BC_YUVA8888: - frag_shader = VFrame::make_shader(0, - config.direction == 1 ? yuv_fwd_frag : yuv_rev_frag, - 0); + switch( get_output()->get_color_model() ) { + case BC_YUV888: + case BC_YUVA8888: + frag_shader = VFrame::make_shader(0, + config.direction == 1 ? yuv_fwd_frag : yuv_rev_frag, + 0); break; - default: - frag_shader = VFrame::make_shader(0, - config.direction == 1 ? rgb_fwd_frag : rgb_rev_frag, - 0); + default: + frag_shader = VFrame::make_shader(0, + config.direction == 1 ? rgb_fwd_frag : rgb_rev_frag, + 0); break; } - if(frag_shader) - { + if( frag_shader > 0 ) { glUseProgram(frag_shader); glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0); } diff --git a/cinelerra-5.1/plugins/swapchannels/swapchannels.C b/cinelerra-5.1/plugins/swapchannels/swapchannels.C index 99e36b74..3ea0f900 100644 --- a/cinelerra-5.1/plugins/swapchannels/swapchannels.C +++ b/cinelerra-5.1/plugins/swapchannels/swapchannels.C @@ -497,13 +497,13 @@ int SwapMain::handle_opengl() get_output()->clear_pbuffer(); get_output()->bind_texture(0); - unsigned int shader_id = VFrame::make_shader(0, - output_frag, - 0); - glUseProgram(shader_id); - glUniform1i(glGetUniformLocation(shader_id, "tex"), 0); - glUniform1f(glGetUniformLocation(shader_id, "chroma_offset"), - BC_CModels::is_yuv(get_output()->get_color_model()) ? 0.5 : 0.0); + unsigned int shader = VFrame::make_shader(0, output_frag, 0); + if( shader > 0 ) { + glUseProgram(shader); + glUniform1i(glGetUniformLocation(shader, "tex"), 0); + glUniform1f(glGetUniformLocation(shader, "chroma_offset"), + BC_CModels::is_yuv(get_output()->get_color_model()) ? 0.5 : 0.0); + } get_output()->draw_texture(); glUseProgram(0); diff --git a/cinelerra-5.1/plugins/swapframes/swapframes.C b/cinelerra-5.1/plugins/swapframes/swapframes.C index e9c24ea7..b1f87f5e 100644 --- a/cinelerra-5.1/plugins/swapframes/swapframes.C +++ b/cinelerra-5.1/plugins/swapframes/swapframes.C @@ -333,8 +333,3 @@ int SwapFrames::process_buffer(VFrame *frame, return 0; } -int SwapFrames::handle_opengl() -{ - return 0; -} - diff --git a/cinelerra-5.1/plugins/swapframes/swapframes.h b/cinelerra-5.1/plugins/swapframes/swapframes.h index ffa4107c..6b547289 100644 --- a/cinelerra-5.1/plugins/swapframes/swapframes.h +++ b/cinelerra-5.1/plugins/swapframes/swapframes.h @@ -106,7 +106,6 @@ public: void update_gui(); void save_data(KeyFrame *keyframe); void read_data(KeyFrame *keyframe); - int handle_opengl(); PLUGIN_CLASS_MEMBERS(SwapFramesConfig) diff --git a/cinelerra-5.1/plugins/threshold/threshold.C b/cinelerra-5.1/plugins/threshold/threshold.C index fdcd5af6..09a3680b 100644 --- a/cinelerra-5.1/plugins/threshold/threshold.C +++ b/cinelerra-5.1/plugins/threshold/threshold.C @@ -22,17 +22,17 @@ #include #include +#include "threshold.h" +#include "bccolors.h" #include "clip.h" #include "bchash.h" #include "filexml.h" #include "histogramengine.h" #include "language.h" -#include "bccolors.h" -#include "threshold.h" +#include "playback3d.h" #include "thresholdwindow.h" #include "vframe.h" -; using ::std::string; @@ -259,10 +259,12 @@ int ThresholdMain::handle_opengl() "uniform vec4 low_color;\n" "uniform vec4 mid_color;\n" "uniform vec4 high_color;\n" + "uniform mat3 rgb_to_yuv_matrix;\n" + "uniform float yminf;\n" "void main()\n" "{\n" " vec4 pixel = texture2D(tex, gl_TexCoord[0].st);\n" - " float v = dot(pixel.rgb, vec3(0.299, 0.587, 0.114));\n" + " float v = dot(pixel.rgb, rgb_to_yuv_matrix[0]) + yminf;\n" " if(v < min)\n" " pixel = low_color;\n" " else if(v < max)\n" @@ -294,78 +296,67 @@ int ThresholdMain::handle_opengl() get_output()->to_texture(); get_output()->enable_opengl(); - unsigned int shader = 0; int color_model = get_output()->get_color_model(); bool is_yuv = BC_CModels::is_yuv(color_model); bool has_alpha = BC_CModels::has_alpha(color_model); - if(is_yuv) - shader = VFrame::make_shader(0, yuv_shader, 0); - else - shader = VFrame::make_shader(0, rgb_shader, 0); - - if(shader > 0) - { + unsigned int shader = VFrame::make_shader(0, is_yuv ? yuv_shader : rgb_shader, 0); + if( shader > 0 ) { glUseProgram(shader); glUniform1i(glGetUniformLocation(shader, "tex"), 0); glUniform1f(glGetUniformLocation(shader, "min"), config.min); glUniform1f(glGetUniformLocation(shader, "max"), config.max); - if (is_yuv) - { + if (is_yuv) { float y_low, u_low, v_low; float y_mid, u_mid, v_mid; float y_high, u_high, v_high; - YUV::yuv.rgb_to_yuv_f((float)config.low_color.r / 0xff, - (float)config.low_color.g / 0xff, - (float)config.low_color.b / 0xff, - y_low, - u_low, - v_low); - u_low += 0.5; - v_low += 0.5; - YUV::yuv.rgb_to_yuv_f((float)config.mid_color.r / 0xff, - (float)config.mid_color.g / 0xff, - (float)config.mid_color.b / 0xff, - y_mid, - u_mid, - v_mid); - u_mid += 0.5; - v_mid += 0.5; - YUV::yuv.rgb_to_yuv_f((float)config.high_color.r / 0xff, - (float)config.high_color.g / 0xff, - (float)config.high_color.b / 0xff, - y_high, - u_high, - v_high); - u_high += 0.5; - v_high += 0.5; + YUV::yuv.rgb_to_yuv_f( + (float)config.low_color.r / 0xff, + (float)config.low_color.g / 0xff, + (float)config.low_color.b / 0xff, + y_low, u_low, v_low); + u_low += 0.5; v_low += 0.5; + YUV::yuv.rgb_to_yuv_f( + (float)config.mid_color.r / 0xff, + (float)config.mid_color.g / 0xff, + (float)config.mid_color.b / 0xff, + y_mid, u_mid, v_mid); + u_mid += 0.5; v_mid += 0.5; + YUV::yuv.rgb_to_yuv_f( + (float)config.high_color.r / 0xff, + (float)config.high_color.g / 0xff, + (float)config.high_color.b / 0xff, + y_high, u_high, v_high); + u_high += 0.5; v_high += 0.5; glUniform4f(glGetUniformLocation(shader, "low_color"), - y_low, u_low, v_low, - has_alpha ? (float)config.low_color.a / 0xff : 1.0); + y_low, u_low, v_low, + has_alpha ? (float)config.low_color.a / 0xff : 1.0); glUniform4f(glGetUniformLocation(shader, "mid_color"), - y_mid, u_mid, v_mid, - has_alpha ? (float)config.mid_color.a / 0xff : 1.0); + y_mid, u_mid, v_mid, + has_alpha ? (float)config.mid_color.a / 0xff : 1.0); glUniform4f(glGetUniformLocation(shader, "high_color"), - y_high, u_high, v_high, - has_alpha ? (float)config.high_color.a / 0xff : 1.0); - } else { + y_high, u_high, v_high, + has_alpha ? (float)config.high_color.a / 0xff : 1.0); + } + else { glUniform4f(glGetUniformLocation(shader, "low_color"), - (float)config.low_color.r / 0xff, - (float)config.low_color.g / 0xff, - (float)config.low_color.b / 0xff, - has_alpha ? (float)config.low_color.a / 0xff : 1.0); + (float)config.low_color.r / 0xff, + (float)config.low_color.g / 0xff, + (float)config.low_color.b / 0xff, + has_alpha ? (float)config.low_color.a / 0xff : 1.0); glUniform4f(glGetUniformLocation(shader, "mid_color"), - (float)config.mid_color.r / 0xff, - (float)config.mid_color.g / 0xff, - (float)config.mid_color.b / 0xff, - has_alpha ? (float)config.mid_color.a / 0xff : 1.0); + (float)config.mid_color.r / 0xff, + (float)config.mid_color.g / 0xff, + (float)config.mid_color.b / 0xff, + has_alpha ? (float)config.mid_color.a / 0xff : 1.0); glUniform4f(glGetUniformLocation(shader, "high_color"), - (float)config.high_color.r / 0xff, - (float)config.high_color.g / 0xff, - (float)config.high_color.b / 0xff, - has_alpha ? (float)config.high_color.a / 0xff : 1.0); + (float)config.high_color.r / 0xff, + (float)config.high_color.g / 0xff, + (float)config.high_color.b / 0xff, + has_alpha ? (float)config.high_color.a / 0xff : 1.0); + BC_GL_RGB_TO_YUV(shader); } } diff --git a/cinelerra-5.1/plugins/timeavg/timeavg.C b/cinelerra-5.1/plugins/timeavg/timeavg.C index 02ce4f5d..0de40c2d 100644 --- a/cinelerra-5.1/plugins/timeavg/timeavg.C +++ b/cinelerra-5.1/plugins/timeavg/timeavg.C @@ -19,8 +19,9 @@ * */ -#include "clip.h" +#include "bccolors.h" #include "bchash.h" +#include "clip.h" #include "filexml.h" #include "keyframe.h" #include "language.h" @@ -498,8 +499,7 @@ void TimeAvgMain::reset_accum(int w, int h, int color_model) } } -#define RGB_TO_VALUE(r, g, b) \ -((r) * R_TO_Y + (g) * G_TO_Y + (b) * B_TO_Y) +#define RGB_TO_VALUE(r, g, b) YUV::yuv.rgb_to_y_f((r),(g),(b)) // Only AVERAGE and ACCUMULATE use this #define SUBTRACT_ACCUM(type, \ diff --git a/cinelerra-5.1/plugins/timefront/timefront.C b/cinelerra-5.1/plugins/timefront/timefront.C index 82dbd59a..2fdfab31 100644 --- a/cinelerra-5.1/plugins/timefront/timefront.C +++ b/cinelerra-5.1/plugins/timefront/timefront.C @@ -746,11 +746,12 @@ int TimeFrontMain::is_synthesis() { \ unsigned int choice = invertion gradient_row[j]; \ { \ - out_row[0] = framelist[choice]->get_rows()[i][j * components + 0]; \ - out_row[1] = framelist[choice]->get_rows()[i][j * components + 1]; \ - out_row[2] = framelist[choice]->get_rows()[i][j * components + 2]; \ + type *in_row = (type *)framelist[choice]->get_rows()[i]; \ + out_row[0] = in_row[j * components + 0]; \ + out_row[1] = in_row[j * components + 1]; \ + out_row[2] = in_row[j * components + 2]; \ if (components == 4) \ - out_row[3] = framelist[choice]->get_rows()[i][j * components + 3]; \ + out_row[3] = in_row[j * components + 3]; \ } \ out_row += components; \ } \ diff --git a/cinelerra-5.1/plugins/titler/titler.C b/cinelerra-5.1/plugins/titler/titler.C index 060e3eb9..27ed9a1f 100644 --- a/cinelerra-5.1/plugins/titler/titler.C +++ b/cinelerra-5.1/plugins/titler/titler.C @@ -543,7 +543,7 @@ TitleUnit::TitleUnit(TitleMain *plugin, TitleEngine *server) static void get_mask_colors(int rgb, int color_model, int &rr, int &gg, int &bb) { int r = 0xff & (rgb>>16), g = 0xff & (rgb>>8), b = 0xff & (rgb>>0); - if( BC_CModels::is_yuv(color_model) ) bc_rgb2yuv(r,g,b, r,g,b); + if( BC_CModels::is_yuv(color_model) ) YUV::yuv.rgb_to_yuv_8(r,g,b); rr = r; gg = g; bb = b; } diff --git a/cinelerra-5.1/plugins/yuv/yuv.C b/cinelerra-5.1/plugins/yuv/yuv.C index 18846756..83f7f03c 100644 --- a/cinelerra-5.1/plugins/yuv/yuv.C +++ b/cinelerra-5.1/plugins/yuv/yuv.C @@ -302,6 +302,10 @@ void YUVEffect::read_data(KeyFrame *keyframe) y = temp_type((float)y * y_scale + round); \ u = temp_type((float)(u - (max / 2 + 1)) * u_scale + round) + (max / 2 + 1); \ v = temp_type((float)(v - (max / 2 + 1)) * v_scale + round) + (max / 2 + 1); \ + \ + CLAMP(y, 0, max); \ + CLAMP(u, 0, max); \ + CLAMP(v, 0, max); \ } \ else \ { \