/*
* CINELERRA
* Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
+ *
*/
#include <string>
#include <string.h>
+#include "threshold.h"
+#include "bccolors.h"
#include "clip.h"
#include "bchash.h"
#include "filexml.h"
#include "histogramengine.h"
#include "language.h"
-#include "cicolors.h"
-#include "threshold.h"
+#include "playback3d.h"
#include "thresholdwindow.h"
#include "vframe.h"
-;
using ::std::string;
void ThresholdConfig::interpolate(ThresholdConfig &prev,
ThresholdConfig &next,
- int64_t prev_frame,
- int64_t next_frame,
+ int64_t prev_frame,
+ int64_t next_frame,
int64_t current_frame)
{
- double next_scale = (double)(current_frame - prev_frame) /
+ double next_scale = (double)(current_frame - prev_frame) /
(next_frame - prev_frame);
- double prev_scale = (double)(next_frame - current_frame) /
+ double prev_scale = (double)(next_frame - current_frame) /
(next_frame - prev_frame);
min = ::interpolate(prev.min, prev_scale, next.min, next_scale);
if(!threshold_engine)
threshold_engine = new ThresholdEngine(this);
threshold_engine->process_packages(frame);
-
+
return 0;
}
int ThresholdMain::handle_opengl()
{
#ifdef HAVE_GL
- static const char *rgb_shader =
+ static const char *rgb_shader =
"uniform sampler2D tex;\n"
"uniform float min;\n"
"uniform float max;\n"
"uniform vec4 low_color;\n"
"uniform vec4 mid_color;\n"
"uniform vec4 high_color;\n"
+ "uniform vec3 rgb_to_y_vector;\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_y_vector) + yminf;\n"
" if(v < min)\n"
" pixel = low_color;\n"
" else if(v < max)\n"
" gl_FragColor = pixel;\n"
"}\n";
- static const char *yuv_shader =
+ static const char *yuv_shader =
"uniform sampler2D tex;\n"
"uniform float min;\n"
"uniform float max;\n"
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::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::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::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_Y(shader);
}
}
return v << 8 | v;
}
-static inline void rgb_to_yuv(YUV & yuv,
- unsigned char r, unsigned char g, unsigned char b,
+static inline void rgb_to_yuv(unsigned char r, unsigned char g, unsigned char b,
unsigned char & y, unsigned char & u, unsigned char & v)
{
- yuv.rgb_to_yuv_8(r, g, b, y, u, v);
+ YUV::yuv.rgb_to_yuv_8(r, g, b, y, u, v);
}
-static inline void rgb_to_yuv(YUV & yuv,
- float r, float g, float b,
+static inline void rgb_to_yuv(float r, float g, float b,
float & y, float & u, float & v)
{
- yuv.rgb_to_yuv_f(r, g, b, y, u, v);
+ YUV::yuv.rgb_to_yuv_f(r, g, b, y, u, v);
}
-static inline void rgb_to_yuv(YUV & yuv,
- uint16_t r, uint16_t g, uint16_t b,
+static inline void rgb_to_yuv(uint16_t r, uint16_t g, uint16_t b,
uint16_t & y, uint16_t & u, uint16_t & v)
{
- yuv.rgb_to_yuv_16(r, g, b, y, u, v);
+ YUV::yuv.rgb_to_yuv_16(r, g, b, y, u, v);
}
template<typename TYPE, int COMPONENTS, bool USE_YUV>
const int max = (int)(config->max * 0xffff);
const int w = data->get_w();
//const int h = data->get_h();
-
+
const TYPE r_low = scale_to_range<TYPE>(config->low_color.r);
const TYPE g_low = scale_to_range<TYPE>(config->low_color.g);
const TYPE b_low = scale_to_range<TYPE>(config->low_color.b);
const TYPE a_low = scale_to_range<TYPE>(config->low_color.a);
-
+
const TYPE r_mid = scale_to_range<TYPE>(config->mid_color.r);
const TYPE g_mid = scale_to_range<TYPE>(config->mid_color.g);
const TYPE b_mid = scale_to_range<TYPE>(config->mid_color.b);
const TYPE a_mid = scale_to_range<TYPE>(config->mid_color.a);
-
+
const TYPE r_high = scale_to_range<TYPE>(config->high_color.r);
const TYPE g_high = scale_to_range<TYPE>(config->high_color.g);
const TYPE b_high = scale_to_range<TYPE>(config->high_color.b);
if (USE_YUV)
{
- rgb_to_yuv(*server->yuv, r_low, g_low, b_low, y_low, u_low, v_low);
- rgb_to_yuv(*server->yuv, r_mid, g_mid, b_mid, y_mid, u_mid, v_mid);
- rgb_to_yuv(*server->yuv, r_high, g_high, b_high, y_high, u_high, v_high);
+ rgb_to_yuv(r_low, g_low, b_low, y_low, u_low, v_low);
+ rgb_to_yuv(r_mid, g_mid, b_mid, y_mid, u_mid, v_mid);
+ rgb_to_yuv(r_high, g_high, b_high, y_high, u_high, v_high);
}
for(int i = pkg->start; i < pkg->end; i++)
plugin->get_project_smp() + 1)
{
this->plugin = plugin;
- yuv = new YUV;
}
ThresholdEngine::~ThresholdEngine()
{
- delete yuv;
}
void ThresholdEngine::process_packages(VFrame *data)