Author: Janne Liljeblad <janne.liljeblad@gmail.com>
Last-Update: 2013-03-05
Forwarded: yes
Origin: upstream, http://git.dyne.org/frei0r/commit/?id=852a4ac
Description: Add transparent background option to vectorscope
---
src/filter/vectorscope/vectorscope.c | 105 ++++++++++++++++++++++++++++-------
1 file changed, 84 insertions(+), 21 deletions(-)
diff --git a/src/filter/vectorscope/vectorscope.c b/src/filter/vectorscope/vectorscope.c
index fd28313..e984534 100644
--- a/src/filter/vectorscope/vectorscope.c
+++ b/src/filter/vectorscope/vectorscope.c
@@ -57,6 +57,8 @@ typedef struct vectorscope_instance {
gavl_video_scaler_t* scope_scaler;
gavl_video_frame_t* scope_frame_src;
gavl_video_frame_t* scope_frame_dst;
+ double mix;
+ double overlay_sides;
} vectorscope_instance_t;
int f0r_init()
@@ -74,14 +76,26 @@ void f0r_get_plugin_info( f0r_plugin_info_t* info )
info->color_model = F0R_COLOR_MODEL_RGBA8888;
info->frei0r_version = FREI0R_MAJOR_VERSION;
info->major_version = 0;
- info->minor_version = 1;
- info->num_params = 0;
+ info->minor_version = 2;
+ info->num_params = 2;
info->explanation = "Displays the vectorscope of the video-data";
}
void f0r_get_param_info( f0r_param_info_t* info, int param_index )
{
- /* empty */
+ switch(param_index)
+ {
+ case 0:
+ info->name = "mix";
+ info->type = F0R_PARAM_DOUBLE;
+ info->explanation = "The amount of source image mixed into background of display";
+ break;
+ case 1:
+ info->name = "overlay sides";
+ info->type = F0R_PARAM_BOOL;
+ info->explanation = "If false, the sides of image are shown without overlay";
+ break;
+ }
}
f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
@@ -94,6 +108,9 @@ f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
return NULL;
}
+ inst->mix = 0.0;
+ inst->overlay_sides = 1.0;
+
inst->scala = (unsigned char*)malloc( width * height * 4 );
gavl_video_scaler_t* video_scaler;
@@ -232,13 +249,35 @@ void f0r_destruct(f0r_instance_t instance)
}
void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_index)
-{
- /* empty */
+{
+ assert(instance);
+ vectorscope_instance_t* inst = (vectorscope_instance_t*)instance;
+
+ switch(param_index)
+ {
+ case 0:
+ *((double *)param) = inst->mix;
+ break;
+ case 1:
+ *((double *)param) = inst->overlay_sides;
+ break;
+ }
}
void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index)
-{
- /* empty */
+{
+ assert(instance);
+ vectorscope_instance_t* inst = (vectorscope_instance_t*)instance;
+
+ switch(param_index)
+ {
+ case 0:
+ inst->mix = *((double *)param);
+ break;
+ case 1:
+ inst->overlay_sides = *((double *)param);
+ break;
+ }
}
/* RGB to YCbCr range 0-255 */
@@ -257,7 +296,8 @@ void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, u
vectorscope_instance_t* inst = (vectorscope_instance_t*)instance;
int width = inst->w;
- int height = inst->h;
+ int height = inst->h;
+ double mix = inst->mix;
int len = inst->w * inst->h;
int scope_len = SCOPE_WIDTH * SCOPE_HEIGHT;
@@ -276,9 +316,17 @@ void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, u
src_end = src + len;
scope_end = scope + scope_len;
- while ( dst < dst_end ) {
- *(dst++) = 0xFF000000;
- }
+ if ( inst->overlay_sides > 0.5) {
+ while ( dst < dst_end ) {
+ *(dst++) = 0xFF000000;
+ }
+ } else {
+ while ( dst < dst_end ) {
+ *(dst++) = *(src++);
+ }
+ src -= len;
+ }
+
dst = outframe;
while ( scope < scope_end ) {
*(scope++) = 0xFF000000;
@@ -293,7 +341,6 @@ void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, u
YCbCr = rgb_to_YCbCr(rgb);
x = YCbCr.Cb;
y = 255-YCbCr.Cr;
- //printf ("Cb: %d, Cr: %d\n", x, y );
if ( x >= 0 && x < SCOPE_WIDTH && y >= 0 && y < SCOPE_HEIGHT ) {
pixel = (uint8_t*)&scope[x+SCOPE_WIDTH*y];
if ( pixel[0] < 255 ) {
@@ -301,7 +348,6 @@ void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, u
pixel[1]++;
pixel[2]++;
}
- //dst[x+width*y] += 1;//0xFFFFFFFF;
}
}
@@ -310,17 +356,34 @@ void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, u
gavl_video_scaler_scale( inst->scope_scaler, inst->scope_frame_src, inst->scope_frame_dst );
- unsigned char *scala8, *dst8, *dst8_end;
+ unsigned char *scala8, *dst8, *dst8_end, *src8;
scala8 = inst->scala;
+ src8 = (unsigned char*)inframe;
dst8 = (unsigned char*)outframe;
dst8_end = dst8 + ( len * 4 );
- while ( dst8 < dst8_end ) {
- dst8[0] = ( ( ( scala8[0] - dst8[0] ) * 255 * scala8[3] ) >> 16 ) + dst8[0];
- dst8[1] = ( ( ( scala8[1] - dst8[1] ) * 255 * scala8[3] ) >> 16 ) + dst8[1];
- dst8[2] = ( ( ( scala8[2] - dst8[2] ) * 255 * scala8[3] ) >> 16 ) + dst8[2];
- scala8 += 4;
- dst8 += 4;
- }
+ if (mix > 0.001 ) { // to not lose performance for non-mixing users
+ while ( dst8 < dst8_end ) {
+ dst8[0] = ( ( ( scala8[0] - dst8[0] ) * 255 * scala8[3] ) >> 16 ) + dst8[0];
+ dst8[1] = ( ( ( scala8[1] - dst8[1] ) * 255 * scala8[3] ) >> 16 ) + dst8[1];
+ dst8[2] = ( ( ( scala8[2] - dst8[2] ) * 255 * scala8[3] ) >> 16 ) + dst8[2];
+ if (dst8[0] == 0) {
+ dst8[0] = src8[0] * mix;
+ dst8[1] = src8[1] * mix;
+ dst8[2] = src8[2] * mix;
+ }
+ scala8 += 4;
+ dst8 += 4;
+ src8 += 4;
+ }
+ } else {
+ while ( dst8 < dst8_end ) {
+ dst8[0] = ( ( ( scala8[0] - dst8[0] ) * 255 * scala8[3] ) >> 16 ) + dst8[0];
+ dst8[1] = ( ( ( scala8[1] - dst8[1] ) * 255 * scala8[3] ) >> 16 ) + dst8[1];
+ dst8[2] = ( ( ( scala8[2] - dst8[2] ) * 255 * scala8[3] ) >> 16 ) + dst8[2];
+ scala8 += 4;
+ dst8 += 4;
+ }
+ }
}
--
2.0.0.rc2