mirror of
https://github.com/game-stop/veejay.git
synced 2026-01-06 23:15:30 +01:00
luma key use alpha channel in mode 3 to blend, fix chroma key (use different algorithm), added alpha:select by chroma key, added alpha blend
This commit is contained in:
@@ -96,6 +96,7 @@ libvje_la_SOURCES = vj-effect.c vj-effman.c effects/common.c \
|
||||
effects/contourextract.c effects/maskstop.c effects/photoplay.c effects/videoplay.c effects/rgbchannel.c \
|
||||
effects/videowall.c effects/flare.c effects/radioactive.c effects/baltantv.c effects/constantblend.c effects/picinpic.c effects/bgsubtract.c effects/cali.c effects/median.c effects/average-blend.c effects/perspective.c \
|
||||
effects/toalpha.c effects/mixtoalpha.c effects/alpha2img.c effects/alphafill.c effects/alphaflatten.c \
|
||||
effects/magicalphaoverlays.c effects/travelmatte.c effects/feathermask.c effects/alphaselect.c
|
||||
effects/magicalphaoverlays.c effects/travelmatte.c effects/feathermask.c effects/alphaselect.c \
|
||||
effects/alphaselect2.c effects/alphablend.c
|
||||
|
||||
|
||||
|
||||
59
veejay-current/veejay-server/libvje/effects/alphablend.c
Normal file
59
veejay-current/veejay-server/libvje/effects/alphablend.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Linux VeeJay
|
||||
*
|
||||
* Copyright(C)2015 Niels Elburg <nelburg@gmail.com>
|
||||
*
|
||||
* 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 <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <libvjmem/vjmem.h>
|
||||
#include "alphablend.h"
|
||||
#include "common.h"
|
||||
|
||||
vj_effect *alphablend_init(int w, int h)
|
||||
{
|
||||
vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
||||
ve->num_params = 0;
|
||||
ve->description = "Alpha: Blend";
|
||||
ve->sub_format = 1;
|
||||
ve->extra_frame = 1;
|
||||
ve->parallel = 1;
|
||||
ve->has_user = 0;
|
||||
return ve;
|
||||
}
|
||||
|
||||
static inline int blend_plane( uint8_t *dst, uint8_t *A, uint8_t *B, uint8_t *aA, int size )
|
||||
{
|
||||
unsigned int i;
|
||||
for( i = 0; i < size; i ++ )
|
||||
{
|
||||
unsigned int op0 = aA[i];
|
||||
unsigned int op1 = 0xff - op0;
|
||||
dst[i] = (op1 * A[i] + op0 * B[i] ) >> 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void alphablend_apply( VJFrame *frame, VJFrame *frame2, int width,int height)
|
||||
{
|
||||
int uv_len = (frame->ssm ? frame->len : frame->uv_len );
|
||||
blend_plane( frame->data[0], frame->data[0], frame2->data[0], frame2->data[3], frame->len );
|
||||
blend_plane( frame->data[1], frame->data[1], frame2->data[1], frame2->data[3], uv_len );
|
||||
blend_plane( frame->data[2], frame->data[2], frame2->data[2], frame2->data[3], uv_len );
|
||||
}
|
||||
30
veejay-current/veejay-server/libvje/effects/alphablend.h
Normal file
30
veejay-current/veejay-server/libvje/effects/alphablend.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Linux VeeJay
|
||||
*
|
||||
* Copyright(C)2015 Niels Elburg <nwelburg@gmail.com>
|
||||
*
|
||||
* 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 ALPHABLEND_H
|
||||
#define ALPHABLEND_H
|
||||
#include <libvje/vje.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
vj_effect *alphablend_init(int w, int h);
|
||||
void alphablend_apply( VJFrame *frame, VJFrame *frame2, int width,int height);
|
||||
|
||||
#endif
|
||||
167
veejay-current/veejay-server/libvje/effects/alphaselect2.c
Normal file
167
veejay-current/veejay-server/libvje/effects/alphaselect2.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Linux VeeJay
|
||||
*
|
||||
* Copyright(C)2015 Niels Elburg <nelburg@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* originally from http://gc-films.com/chromakey.html
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <libvjmem/vjmem.h>
|
||||
#include "rgbkey.h"
|
||||
#include <math.h>
|
||||
#include "common.h"
|
||||
|
||||
vj_effect *alphaselect2_init(int w, int h)
|
||||
{
|
||||
vj_effect *ve;
|
||||
ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
||||
ve->num_params = 7;
|
||||
ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */
|
||||
ve->limits[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */
|
||||
ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */
|
||||
ve->defaults[0] = 15; /* tolerance near */
|
||||
ve->defaults[1] = 0; /* r */
|
||||
ve->defaults[2] = 255; /* g */
|
||||
ve->defaults[3] = 0; /* b */
|
||||
ve->defaults[4] = 15; /* tolerance far */
|
||||
ve->defaults[5] = 1; /* show alpha */
|
||||
ve->defaults[6] = 0; /* use existing alpha */
|
||||
|
||||
ve->limits[0][0] = 1;
|
||||
ve->limits[1][0] = 255;
|
||||
|
||||
ve->limits[0][1] = 0;
|
||||
ve->limits[1][1] = 255;
|
||||
|
||||
ve->limits[0][2] = 0;
|
||||
ve->limits[1][2] = 255;
|
||||
|
||||
ve->limits[0][3] = 0;
|
||||
ve->limits[1][3] = 255;
|
||||
|
||||
ve->limits[0][4] = 0;
|
||||
ve->limits[1][4] = 255;
|
||||
|
||||
ve->limits[0][5] = 0;
|
||||
ve->limits[1][5] = 1;
|
||||
|
||||
ve->limits[0][6] = 0;
|
||||
ve->limits[1][6] = 1;
|
||||
|
||||
ve->has_user = 0;
|
||||
ve->parallel = 1;
|
||||
ve->description = "Alpha: Select by chroma key";
|
||||
ve->extra_frame = 0;
|
||||
ve->sub_format = 1;
|
||||
ve->rgb_conv = 1;
|
||||
ve->param_description = vje_build_param_list(ve->num_params,"Tolerance Near","Red","Green","Blue", "Tolerance Far", "Show Mask", "Use Alpha-IN");
|
||||
|
||||
return ve;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static inline double color_distance( uint8_t Cb, uint8_t Cr, int Cbk, int Crk, int dA, int dB )
|
||||
{
|
||||
double tmp = 0.0;
|
||||
fast_sqrt( tmp, (Cbk - Cb) * (Cbk-Cb) + (Crk - Cr) * (Crk - Cr) );
|
||||
if( tmp < dA ) { /* near color key == bg */
|
||||
return 0.0;
|
||||
}
|
||||
if( tmp < dB ) { /* middle region */
|
||||
return (tmp - dA)/(dB - dA); /* distance to key color */
|
||||
}
|
||||
return 1.0; /* far from color key == fg */
|
||||
}
|
||||
|
||||
|
||||
void alphaselect2_apply( VJFrame *frame, int width,
|
||||
int height, int tola, int r, int g,
|
||||
int b, int tolb, int show, int alpha)
|
||||
{
|
||||
unsigned int pos;
|
||||
uint8_t *Y = frame->data[0];
|
||||
uint8_t *Cb = frame->data[1];
|
||||
uint8_t *Cr = frame->data[2];
|
||||
uint8_t *A = frame->data[3];
|
||||
int cb,cr,iy,iu,iv;
|
||||
_rgb2yuv(r,g,b,iy,iu,iv);
|
||||
|
||||
if( show ) {
|
||||
if( alpha ) {
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
if(A[pos] == 0)
|
||||
continue;
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
A[pos] = (uint8_t) (d * 255.0);
|
||||
if( A[pos] < 255 ) {
|
||||
Y[pos] = Y[pos] * d;
|
||||
Cb[pos] = 128;
|
||||
Cr[pos] = 128;
|
||||
}
|
||||
else if( A[pos] == 0) {
|
||||
Cb[pos] = 128;
|
||||
Cr[pos] = 128;
|
||||
Y[pos] = pixel_Y_lo_;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
A[pos] = (uint8_t) (d * 255.0);
|
||||
if( A[pos] < 255 ) {
|
||||
Y[pos] = Y[pos] * d;
|
||||
Cb[pos] = 128;
|
||||
Cr[pos] = 128;
|
||||
}
|
||||
else if (A[pos] == 0) {
|
||||
Cb[pos] = 128;
|
||||
Cr[pos] = 128;
|
||||
Y[pos] = pixel_Y_lo_;
|
||||
}
|
||||
/* A[pos] = (uint8_t) (d * 255.0);
|
||||
Y[pos] = (d * 255);
|
||||
Cb[pos] = 128;
|
||||
Cr[pos] = 128; */
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( alpha ) {
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
if( A[pos] == 0 )
|
||||
continue;
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
A[pos] = (uint8_t) (d * 255.0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
A[pos] = (uint8_t) (d * 255.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,18 +74,15 @@ void lumakey_simple_alpha(uint8_t *yuv1[4], uint8_t *yuv2[4], int width,
|
||||
|
||||
a1 = yuv1[0][x + y];
|
||||
a2 = yuv2[0][x + y];
|
||||
/*
|
||||
if ( a1 >= threshold && a1 <= threshold2) {
|
||||
Y = (op0 * a1 + op1 * a2 )/255;
|
||||
Cb = (op0 * yuv1[1][x+y] + op1 * yuv2[1][x+y])/255;
|
||||
Cr =(op0 * yuv1[2][x+y] + op1 * yuv2[2][x+y])/255;
|
||||
|
||||
}
|
||||
*/
|
||||
if (a1 >= threshold && a1 <= threshold2) {
|
||||
Y = ((op0 * a1) + (op1 * a2)) >> 8;
|
||||
Cb = ((op0 * yuv1[1][x + y]) + (op1 * yuv2[1][x + y])) >> 8;
|
||||
Cr = ((op0 * yuv1[2][x + y]) + (op1 * yuv2[2][x + y])) >> 8;
|
||||
|
||||
if (a1 >= threshold && a1 <= threshold2) {
|
||||
alpha = ((op0 * yuv1[3][x+y]) + (op1 * yuv2[3][x+y]) )>> 8;
|
||||
unsigned int aA = 255 - alpha;
|
||||
unsigned int aB = alpha;
|
||||
|
||||
Y = ((aA * a1) + (aB * a2)) >> 8;
|
||||
Cb = ((aA * yuv1[1][x + y]) + (aB * yuv2[1][x + y])) >> 8;
|
||||
Cr = ((aA * yuv1[2][x + y]) + (aB * yuv2[2][x + y])) >> 8;
|
||||
yuv1[0][x + y] = Y; // < 16 ? 16 : Y > 235 ? 235 : Y;
|
||||
yuv1[1][x + y] = Cb; // < 16 ? 16 : Cb > 240 ? 240 : Cb;
|
||||
yuv1[2][x + y] = Cr; // < 16 ? 16 : Cr > 240 ? 240 : Cr;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Linux VeeJay
|
||||
*
|
||||
* Copyright(C)2004 Niels Elburg <elburg@hio.hen.nl>
|
||||
* Copyright(C)2004 Niels Elburg <nwelburg@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -25,41 +25,28 @@
|
||||
#include <math.h>
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
|
||||
This effect is based on this small project:
|
||||
|
||||
http://www.cs.utah.edu/~michael/chroma/
|
||||
|
||||
The algorithm decides which pixels belong to resp. foreground
|
||||
or background. Other effects that make use of this same algorithm are
|
||||
|
||||
Complex Invert, Complex Negation, Complex Saturation, Smooth RGB Key
|
||||
Isolate by Color , Complex Threshold and Blend by Color Key,
|
||||
*/
|
||||
|
||||
/*
|
||||
(march,2005) fixed flaw (signed vs. unsigned) in algorithm
|
||||
use selectable rgb -> yuv formula,
|
||||
* originally from http://gc-films.com/chromakey.html
|
||||
*/
|
||||
|
||||
vj_effect *rgbkey_init(int w,int h)
|
||||
{
|
||||
vj_effect *ve;
|
||||
ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
||||
ve->num_params = 6;
|
||||
ve->num_params = 7;
|
||||
ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */
|
||||
ve->limits[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */
|
||||
ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */
|
||||
ve->defaults[0] = 4500; /* angle , 45 degrees*/
|
||||
ve->defaults[0] = 15; /* tolerance near */
|
||||
ve->defaults[1] = 0; /* r */
|
||||
ve->defaults[2] = 0; /* g */
|
||||
ve->defaults[3] = 255; /* b */
|
||||
ve->defaults[4] = 1; /* type */
|
||||
ve->defaults[5] = 1200; /* noise */
|
||||
ve->defaults[2] = 255; /* g */
|
||||
ve->defaults[3] = 0; /* b */
|
||||
ve->defaults[4] = 1; /* tolerance far */
|
||||
ve->defaults[5] = 1; /* show selection */
|
||||
ve->defaults[6] = 0; /* use alpha */
|
||||
|
||||
ve->limits[0][0] = 1;
|
||||
ve->limits[1][0] = 9000;
|
||||
ve->limits[1][0] = 255;
|
||||
|
||||
ve->limits[0][1] = 0;
|
||||
ve->limits[1][1] = 255;
|
||||
@@ -71,12 +58,15 @@ vj_effect *rgbkey_init(int w,int h)
|
||||
ve->limits[1][3] = 255;
|
||||
|
||||
ve->limits[0][4] = 0;
|
||||
ve->limits[1][4] = 1; /* total noise suppression off */
|
||||
ve->limits[1][4] = 255;
|
||||
|
||||
ve->limits[0][5] = 0;
|
||||
ve->limits[1][5] = 5500;
|
||||
ve->limits[1][5] = 1;
|
||||
|
||||
ve->param_description = vje_build_param_list(ve->num_params, "Angle", "Red", "Green", "Blue", "Mode", "Noise suppression");
|
||||
ve->limits[0][6] = 0;
|
||||
ve->limits[1][6] = 4; /* logical alpha operator */
|
||||
|
||||
ve->param_description = vje_build_param_list(ve->num_params, "Tolerance Near", "Red", "Green", "Blue", "Tolerance Far", "Show FG", "Alpa operator");
|
||||
ve->has_user = 0;
|
||||
ve->description = "Chroma Key (RGB)";
|
||||
ve->extra_frame = 1;
|
||||
@@ -85,250 +75,137 @@ vj_effect *rgbkey_init(int w,int h)
|
||||
ve->parallel = 1;
|
||||
return ve;
|
||||
}
|
||||
/*
|
||||
void rgbkey_scan_fg(uint8_t * src2[3], int *r, int *g, int *b)
|
||||
|
||||
static inline double color_distance( uint8_t Cb, uint8_t Cr, int Cbk, int Crk, int dA, int dB )
|
||||
{
|
||||
*r = (int) (+(1.0 * Y2[0]) + (0 * Cb2[0]) +
|
||||
(1.402 * Cr2[0]));
|
||||
*g = (int) (+(1.0 * Y2[0]) - (0.344136 * Cb2[0]) +
|
||||
(-0.714136 * Cr2[0]));
|
||||
*b = (int) (+(1.0 * Y2[0]) + (1.772 * Cb2[0]) +
|
||||
(0 * Cr2[0]));
|
||||
}
|
||||
*/
|
||||
void rgbkey_apply1(VJFrame *frame, VJFrame *frame2, int width,
|
||||
int height, int i_angle, int r, int g,
|
||||
int b, int i_noise)
|
||||
{
|
||||
|
||||
uint8_t *fg_y, *fg_cb, *fg_cr;
|
||||
uint8_t *bg_y, *bg_cb, *bg_cr;
|
||||
int accept_angle_tg, accept_angle_ctg, one_over_kc;
|
||||
int kfgy_scale, kg;
|
||||
uint8_t cb, cr;
|
||||
int kbg, x1, y1;
|
||||
float kg1, tmp, aa = 255.0f, bb = 255.0f, _y = 0;
|
||||
float angle = (float) i_angle / 100.0f;
|
||||
float noise_level = (i_noise / 100.0f);
|
||||
unsigned int pos;
|
||||
uint8_t val, tmp1;
|
||||
uint8_t *Y = frame->data[0];
|
||||
uint8_t *Cb= frame->data[1];
|
||||
uint8_t *Cr= frame->data[2];
|
||||
uint8_t *Y2 = frame2->data[0];
|
||||
uint8_t *Cb2= frame2->data[1];
|
||||
uint8_t *Cr2= frame2->data[2];
|
||||
uint8_t iy,iu,iv;
|
||||
_rgb2yuv( r,g,b, iy,iu,iv );
|
||||
_y = (float) iy;
|
||||
aa = (float) iu;
|
||||
bb = (float) iv;
|
||||
tmp = sqrt(((aa * aa) + (bb * bb)));
|
||||
cb = 0xff * (aa / tmp);
|
||||
cr = 0xff * (bb / tmp);
|
||||
kg1 = tmp;
|
||||
|
||||
/* obtain coordinate system for cb / cr */
|
||||
accept_angle_tg = (int)( 15.0f * tanf(M_PI * angle / 180.0f));
|
||||
accept_angle_ctg= (int)( 15.0f / tanf(M_PI * angle / 180.0f));
|
||||
|
||||
tmp = 1 / kg1;
|
||||
one_over_kc = 0xff * 2 * tmp - 0xff;
|
||||
kfgy_scale = 0xf * (float) (_y) / kg1;
|
||||
kg = kg1;
|
||||
|
||||
/* intialize pointers */
|
||||
fg_y = Y;
|
||||
fg_cb = Cb;
|
||||
fg_cr = Cr;
|
||||
/* 2005: swap these !! */
|
||||
bg_y = Y2;
|
||||
bg_cb = Cb2;
|
||||
bg_cr = Cr2;
|
||||
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
short xx, yy;
|
||||
/* convert foreground to xz coordinates where x direction is
|
||||
defined by key color */
|
||||
|
||||
xx = (((fg_cb[pos]) * cb) + ((fg_cr[pos]) * cr)) >> 7;
|
||||
yy = (((fg_cr[pos]) * cb) - ((fg_cb[pos]) * cr)) >> 7;
|
||||
|
||||
/* accept angle should not be > 90 degrees
|
||||
reasonable results between 10 and 80 degrees.
|
||||
*/
|
||||
|
||||
val = (xx * accept_angle_tg) >> 4;
|
||||
if (abs(yy) < val) {
|
||||
/* compute fg, suppress fg in xz according to kfg
|
||||
*/
|
||||
val = (yy * accept_angle_ctg) >> 4;
|
||||
|
||||
x1 = abs(val);
|
||||
y1 = yy;
|
||||
tmp1 = xx - x1;
|
||||
|
||||
kbg = (tmp1 * one_over_kc) >> 1;
|
||||
if (kbg < 0)
|
||||
kbg = 0;
|
||||
if (kbg > 255)
|
||||
kbg = 255;
|
||||
|
||||
val = (tmp1 * kfgy_scale) >> 4;
|
||||
if( val > 255 )
|
||||
val = 255;
|
||||
|
||||
val = fg_y[pos] - val;
|
||||
|
||||
Y[pos] = val;
|
||||
|
||||
// convert suppressed fg back to cbcr
|
||||
Cb[pos] = ((x1 * cb) - (y1 * cr)) >> 7;
|
||||
Cr[pos] = ((x1 * cr) - (y1 * cb)) >> 7;
|
||||
|
||||
// deal with noise
|
||||
val = (yy * yy) + (kg * kg);
|
||||
if (val < (noise_level * noise_level)) {
|
||||
kbg = 255;
|
||||
Y[pos] = bg_y[pos];
|
||||
Cb[pos] = bg_cb[pos];
|
||||
Cr[pos] = bg_cr[pos];
|
||||
}
|
||||
else {
|
||||
Y[pos] = (Y[pos] + (kbg * bg_y[pos])) >> 8;
|
||||
Cb[pos] = (Cb[pos] + (kbg * bg_cb[pos])) >> 8;
|
||||
Cr[pos] = (Cr[pos] + (kbg * bg_cr[pos])) >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
double tmp = 0.0;
|
||||
fast_sqrt( tmp, (Cbk - Cb) * (Cbk-Cb) + (Crk - Cr) * (Crk - Cr) );
|
||||
if( tmp < dA ) { /* near color key == bg */
|
||||
return 0.0;
|
||||
}
|
||||
if( tmp < dB ) { /* middle region */
|
||||
return (tmp - dA)/(dB - dA); /* distance to key color */
|
||||
}
|
||||
return 1.0; /* far from color key == fg */
|
||||
}
|
||||
|
||||
void rgbkey_apply2(VJFrame *frame, VJFrame *frame2, int width,
|
||||
int height, int i_angle,int r, int g,
|
||||
int b, int i_noise)
|
||||
{
|
||||
|
||||
uint8_t *fg_y, *fg_cb, *fg_cr;
|
||||
uint8_t *bg_y, *bg_cb, *bg_cr;
|
||||
int accept_angle_tg, accept_angle_ctg, one_over_kc;
|
||||
int kfgy_scale, kg;
|
||||
uint8_t cb, cr;
|
||||
int kbg, x1, y1;
|
||||
float kg1, tmp, aa = 255.0, bb = 255.0, _y = 0;
|
||||
float angle = (float) i_angle / 100.0f;
|
||||
float noise_level = (i_noise / 100.0f);
|
||||
unsigned int pos;
|
||||
uint8_t val, tmp1;
|
||||
uint8_t *Y = frame->data[0];
|
||||
uint8_t *Cb= frame->data[1];
|
||||
uint8_t *Cr= frame->data[2];
|
||||
uint8_t *Y2 = frame2->data[0];
|
||||
|
||||
void rgbkey_apply(VJFrame *frame, VJFrame *frame2, int width,int height, int tola, int r, int g,int b, int tolb, int show, int alpha)
|
||||
{
|
||||
unsigned int pos;
|
||||
uint8_t *Y = frame->data[0];
|
||||
uint8_t *Cb = frame->data[1];
|
||||
uint8_t *Cr = frame->data[2];
|
||||
uint8_t *Y2 = frame2->data[0];
|
||||
uint8_t *Cb2= frame2->data[1];
|
||||
uint8_t *Cr2= frame2->data[2];
|
||||
uint8_t iy,iu,iv;
|
||||
uint8_t *B = frame2->data[3];
|
||||
uint8_t *A = frame->data[3];
|
||||
int cb,cr,iy,iu,iv;
|
||||
_rgb2yuv(r,g,b,iy,iu,iv);
|
||||
|
||||
_rgb2yuv( r,g,b, iy,iu,iv );
|
||||
_y = (float) iy;
|
||||
aa = (float) iu;
|
||||
bb = (float) iv;
|
||||
tmp = sqrt(((aa * aa) + (bb * bb)));
|
||||
cb = 255 * (aa / tmp);
|
||||
cr = 255 * (bb / tmp);
|
||||
kg1 = tmp;
|
||||
|
||||
/* obtain coordinate system for cb / cr */
|
||||
accept_angle_tg = (int)( 15.0f * tanf(M_PI * angle / 180.0f));
|
||||
accept_angle_ctg= (int)( 15.0f / tanf(M_PI * angle / 180.0f));
|
||||
|
||||
|
||||
tmp = 1 / kg1;
|
||||
one_over_kc = 0xff * 2 * tmp - 0xff;
|
||||
kfgy_scale = 0xf * (float) (_y) / kg1;
|
||||
kg = kg1;
|
||||
|
||||
/* intialize pointers */
|
||||
fg_y = Y;
|
||||
fg_cb = Cb;
|
||||
fg_cr = Cr;
|
||||
|
||||
bg_y = Y2;
|
||||
bg_cb = Cb2;
|
||||
bg_cr = Cr2;
|
||||
|
||||
int len = frame->len;
|
||||
|
||||
for (pos = 0; pos < len; pos++) {
|
||||
short xx, yy;
|
||||
/* convert foreground to xz coordinates where x direction is
|
||||
defined by key color */
|
||||
|
||||
xx = (((fg_cb[pos]) * cb) + ((fg_cr[pos]) * cr)) >> 7;
|
||||
yy = (((fg_cr[pos]) * cb) - ((fg_cb[pos]) * cr)) >> 7;
|
||||
|
||||
/* accept angle should not be > 90 degrees
|
||||
reasonable results between 10 and 80 degrees.
|
||||
*/
|
||||
|
||||
val = (xx * accept_angle_tg) >> 4;
|
||||
if (abs(yy) < val) {
|
||||
/* compute fg, suppress fg in xz according to kfg */
|
||||
|
||||
val = (yy * accept_angle_ctg) >> 4;
|
||||
|
||||
x1 = abs(val);
|
||||
y1 = yy;
|
||||
tmp1 = xx - x1;
|
||||
|
||||
kbg = (tmp1 * one_over_kc) >> 1;
|
||||
if (kbg < 0)
|
||||
kbg = 0;
|
||||
if (kbg > 255)
|
||||
kbg = 255;
|
||||
|
||||
val = (tmp1 * kfgy_scale) >> 4;
|
||||
val = fg_y[pos] - val;
|
||||
|
||||
Y[pos] = val;
|
||||
|
||||
/* convert suppressed fg back to cbcr */
|
||||
|
||||
Cb[pos] = ((x1 * cb) - (y1 * cr)) >> 7;
|
||||
Cr[pos] = ((x1 * cr) - (y1 * cb)) >> 7;
|
||||
|
||||
/* deal with noise */
|
||||
|
||||
val = (yy * yy) + (kg * kg);
|
||||
if (val < (noise_level * noise_level)) {
|
||||
Y[pos] = 0; Cb[pos] = 128; Cr[pos] = 128;
|
||||
//kbg = 0xff;
|
||||
} else {
|
||||
|
||||
Y[pos] = (Y[pos] + (kbg * bg_y[pos])) >> 8;
|
||||
Cb[pos] = (Cb[pos] + (kbg * bg_cb[pos])) >> 8;
|
||||
Cr[pos] = (Cr[pos] + (kbg * bg_cr[pos])) >> 8;
|
||||
if( alpha == 0 ) {
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
uint8_t op1 = (d * 255);
|
||||
if( op1 == 0 ) {
|
||||
Y[pos] = Y2[pos];
|
||||
Cb[pos] = Cb2[pos];
|
||||
Cr[pos] = Cr2[pos];
|
||||
}
|
||||
else {
|
||||
uint8_t op0 = op1;
|
||||
op1 = 255 - op1;
|
||||
Y[pos] = ( (op0 * Y[pos]) + (op1 * Y2[pos])) >> 8;;
|
||||
Cb[pos] = ( (op0 * Cb[pos]) + (op1 * Cb2[pos]))>> 8;
|
||||
Cr[pos] = ( (op0 * Cr[pos]) + (op1 * Cr2[pos]))>>8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(alpha) {
|
||||
case 1:
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
if( A[pos] == 0 )
|
||||
continue;
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
uint8_t op1 = (d * 255);
|
||||
if( op1 == 0 ) {
|
||||
Y[pos] = Y2[pos];
|
||||
Cb[pos] = Cb2[pos];
|
||||
Cr[pos] = Cr2[pos];
|
||||
}
|
||||
else {
|
||||
uint8_t op0 = op1;
|
||||
op1 = 255 - op1;
|
||||
Y[pos] = ( (op0 * Y[pos]) + (op1 * Y2[pos])) >> 8;;
|
||||
Cb[pos] = ( (op0 * Cb[pos]) + (op1 * Cb2[pos]))>> 8;
|
||||
Cr[pos] = ( (op0 * Cr[pos]) + (op1 * Cr2[pos]))>>8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
if( A[pos] == 0 && B[pos] == 0)
|
||||
continue;
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
uint8_t op1 = (d * 255);
|
||||
if( op1 == 0 ) {
|
||||
Y[pos] = Y2[pos];
|
||||
Cb[pos] = Cb2[pos];
|
||||
Cr[pos] = Cr2[pos];
|
||||
}
|
||||
else {
|
||||
uint8_t op0 = op1;
|
||||
op1 = 255 - op1;
|
||||
Y[pos] = ( (op0 * Y[pos]) + (op1 * Y2[pos])) >> 8;;
|
||||
Cb[pos] = ( (op0 * Cb[pos]) + (op1 * Cb2[pos]))>> 8;
|
||||
Cr[pos] = ( (op0 * Cr[pos]) + (op1 * Cr2[pos]))>>8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
if( A[pos] == 0 || B[pos] == 0)
|
||||
continue;
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
uint8_t op1 = (d * 255);
|
||||
if( op1 == 0 ) {
|
||||
Y[pos] = Y2[pos];
|
||||
Cb[pos] = Cb2[pos];
|
||||
Cr[pos] = Cr2[pos];
|
||||
}
|
||||
else {
|
||||
uint8_t op0 = op1;
|
||||
op1 = 255 - op1;
|
||||
Y[pos] = ( (op0 * Y[pos]) + (op1 * Y2[pos])) >> 8;;
|
||||
Cb[pos] = ( (op0 * Cb[pos]) + (op1 * Cb2[pos]))>> 8;
|
||||
Cr[pos] = ( (op0 * Cr[pos]) + (op1 * Cr2[pos]))>>8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (pos = (width * height); pos != 0; pos--) {
|
||||
if( B[pos] == 0 )
|
||||
continue;
|
||||
double d = color_distance( Cb[pos],Cr[pos],iu,iv,tola,tolb );
|
||||
uint8_t op1 = (d * 255);
|
||||
if( op1 == 0 ) {
|
||||
Y[pos] = Y2[pos];
|
||||
Cb[pos] = Cb2[pos];
|
||||
Cr[pos] = Cr2[pos];
|
||||
}
|
||||
else {
|
||||
uint8_t op0 = op1;
|
||||
op1 = 255 - op1;
|
||||
Y[pos] = ( (op0 * Y[pos]) + (op1 * Y2[pos])) >> 8;;
|
||||
Cb[pos] = ( (op0 * Cb[pos]) + (op1 * Cb2[pos]))>> 8;
|
||||
Cr[pos] = ( (op0 * Cr[pos]) + (op1 * Cr2[pos]))>>8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this is the same as rgbkey_apply1, but here we have total noise suppression
|
||||
*/
|
||||
|
||||
void rgbkey_apply(VJFrame *frame, VJFrame *frame2, int width,
|
||||
int height, int i_angle, int red, int green,
|
||||
int blue, int type, int i_noise)
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
rgbkey_apply1(frame, frame2, width, height, i_angle, red,
|
||||
green, blue, i_noise);
|
||||
break;
|
||||
case 1:
|
||||
rgbkey_apply2(frame, frame2, width, height, i_angle, red,
|
||||
green, blue, i_noise);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
void rgbkey_free(){}
|
||||
|
||||
@@ -25,8 +25,5 @@
|
||||
#include <libvje/vje.h>
|
||||
vj_effect *rgbkey_init();
|
||||
void rgbkey_scan_fg(uint8_t * src2[3], int *r, int *g, int *b);
|
||||
void rgbkey_apply(VJFrame *frame, VJFrame *frame2, int width,
|
||||
int height, int i_angle, int i_noise,
|
||||
int red, int green, int blue, int type );
|
||||
void rgbkey_free();
|
||||
void rgbkey_apply(VJFrame *frame, VJFrame *frame2, int width,int height, int tola, int r, int g,int b, int tolb, int show, int alpha);
|
||||
#endif
|
||||
|
||||
@@ -123,7 +123,7 @@ enum {
|
||||
VJ_VIDEO_EFFECT_MIXTOALPHA = 248,
|
||||
VJ_VIDEO_EFFECT_MAGICALPHA = 249,
|
||||
VJ_VIDEO_EFFECT_TRAVELMATTE = 250,
|
||||
|
||||
VJ_VIDEO_EFFECT_ALPHABLEND = 251,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -226,6 +226,7 @@ enum {
|
||||
VJ_IMAGE_EFFECT_ALPHAFLATTEN = 196,
|
||||
VJ_IMAGE_EFFECT_ALPHAFEATHERMASK = 197,
|
||||
VJ_IMAGE_EFFECT_ALPHASELECT = 198,
|
||||
VJ_IMAGE_EFFECT_ALPHASELECT2 = 199,
|
||||
VJ_IMAGE_EFFECT_DUMMY=100,
|
||||
};
|
||||
|
||||
@@ -233,7 +234,7 @@ enum {
|
||||
#define VJ_IMAGE_EFFECT_MAX 199
|
||||
|
||||
#define VJ_VIDEO_EFFECT_MIN 200
|
||||
#define VJ_VIDEO_EFFECT_MAX 251
|
||||
#define VJ_VIDEO_EFFECT_MAX 252
|
||||
|
||||
#define VJ_VIDEO_COUNT (VJ_VIDEO_EFFECT_MAX - VJ_VIDEO_EFFECT_MIN)
|
||||
|
||||
@@ -378,7 +379,7 @@ extern void coloradjust_apply( VJFrame *frame, int width, int height,
|
||||
|
||||
extern void rgbkey_apply( VJFrame *frame, VJFrame *frame2, int width,
|
||||
int height, int i_angle, int i_noise,
|
||||
int r, int g, int b, int sup);
|
||||
int r, int g, int b, int sup, int alpha);
|
||||
|
||||
extern void gamma_apply( VJFrame *frame,
|
||||
int width, int height, int val);
|
||||
@@ -647,4 +648,6 @@ extern void overlayalphamagic_apply(VJFrame *frame, VJFrame *frame2, int width,i
|
||||
extern void travelmatte_apply( VJFrame *frame, VJFrame *frame2, int width,int height, int mode);
|
||||
extern void feathermask_apply( VJFrame *frame, int width, int height );
|
||||
extern void alphaselect_apply( VJFrame *frame, int width,int height, int i_angle, int r, int g,int b, int swap);
|
||||
void alphaselect2_apply( VJFrame *frame, int width,int height, int tola, int r, int g,int b, int tolb, int show, int alpha);
|
||||
void alphablend_apply( VJFrame *frame, VJFrame *frame2, int width,int height);
|
||||
#endif
|
||||
|
||||
@@ -177,6 +177,9 @@
|
||||
#include "effects/magicalphaoverlays.h"
|
||||
#include "effects/travelmatte.h"
|
||||
#include "effects/feathermask.h"
|
||||
#include "effects/alphaselect.h"
|
||||
#include "effects/alphaselect2.h"
|
||||
#include "effects/alphablend.h"
|
||||
#include <libplugger/plugload.h>
|
||||
#include <veejay/vims.h>
|
||||
|
||||
@@ -580,7 +583,8 @@ void vj_effect_initialize(int width, int height, int full_range)
|
||||
vj_effects[48] = mixtoalpha_init(width,height);
|
||||
vj_effects[49] = overlayalphamagic_init(width,height);
|
||||
vj_effects[50] = travelmatte_init(width,height);
|
||||
vj_effects[51] = dummy_init(width,height);
|
||||
vj_effects[51] = alphablend_init(width,height);
|
||||
vj_effects[52] = dummy_init(width,height);
|
||||
vj_effects[i + 1] = mirrors2_init(width,height);
|
||||
vj_effects[i + 2] = mirrors_init(width,height);
|
||||
vj_effects[i + 3] = widthmirror_init(width,height);
|
||||
@@ -679,6 +683,7 @@ void vj_effect_initialize(int width, int height, int full_range)
|
||||
vj_effects[i + 96 ] = alphaflatten_init(width,height);
|
||||
vj_effects[i + 97 ] = feathermask_init(width,height);
|
||||
vj_effects[i + 98 ] = alphaselect_init(width,height);
|
||||
vj_effects[i + 99 ] = alphaselect2_init(width,height);
|
||||
max_width = width;
|
||||
max_height = height;
|
||||
|
||||
@@ -784,7 +789,7 @@ int vj_effect_real_to_sequence(int effect_id)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (effect_id > VJ_IMAGE_EFFECT_MIN && effect_id < VJ_IMAGE_EFFECT_MAX) {
|
||||
if (effect_id > VJ_IMAGE_EFFECT_MIN && effect_id <= VJ_IMAGE_EFFECT_MAX) {
|
||||
effect_id -= VJ_IMAGE_EFFECT_MIN;
|
||||
effect_id += VJ_VIDEO_COUNT;
|
||||
return effect_id;
|
||||
@@ -1038,26 +1043,6 @@ int vj_effect_has_cb(int effect_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vj_effect_get_min_i()
|
||||
{
|
||||
return VJ_IMAGE_EFFECT_MIN;
|
||||
}
|
||||
|
||||
int vj_effect_get_max_i()
|
||||
{
|
||||
return VJ_IMAGE_EFFECT_MAX;
|
||||
}
|
||||
|
||||
int vj_effect_get_min_v()
|
||||
{
|
||||
return VJ_VIDEO_EFFECT_MIN;
|
||||
}
|
||||
|
||||
int vj_effect_get_max_v()
|
||||
{
|
||||
return VJ_VIDEO_EFFECT_MAX;
|
||||
}
|
||||
|
||||
int vj_effect_has_rgbkey(int effect_id)
|
||||
{
|
||||
int entry;
|
||||
@@ -1074,7 +1059,7 @@ int vj_effect_is_valid(int effect_id)
|
||||
{
|
||||
if( effect_id >= VJ_EXT_EFFECT && effect_id < VJ_EXT_EFFECT + n_ext_plugs_)
|
||||
return 1;
|
||||
if( effect_id > VJ_IMAGE_EFFECT_MIN && effect_id < VJ_IMAGE_EFFECT_MAX )
|
||||
if( effect_id > VJ_IMAGE_EFFECT_MIN && effect_id <= VJ_IMAGE_EFFECT_MAX )
|
||||
return 1;
|
||||
if( effect_id > VJ_VIDEO_EFFECT_MIN && effect_id < VJ_VIDEO_EFFECT_MAX )
|
||||
return 1;
|
||||
|
||||
@@ -430,6 +430,9 @@ void vj_effman_apply_image_effect(
|
||||
case VJ_IMAGE_EFFECT_ALPHASELECT:
|
||||
alphaselect_apply(frames[0],frames[0]->width,frames[0]->height,arg[0],arg[1],arg[2],arg[3],arg[4]);
|
||||
break;
|
||||
case VJ_IMAGE_EFFECT_ALPHASELECT2:
|
||||
alphaselect2_apply(frames[0],frames[0]->width,frames[0]->height,arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,7 +505,7 @@ void vj_effman_apply_video_effect( VJFrame **frames, vjp_kf *todo_info,int *arg,
|
||||
break;
|
||||
case VJ_VIDEO_EFFECT_RGBKEY:
|
||||
rgbkey_apply(frames[0], frames[1], frames[0]->width, frames[0]->height,
|
||||
arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
|
||||
arg[0], arg[1], arg[2], arg[3], arg[4], arg[5],arg[6]);
|
||||
break;
|
||||
case VJ_VIDEO_EFFECT_KEYSELECT:
|
||||
keyselect_apply(frames[0],frames[1],frames[0]->width,frames[0]->height,
|
||||
@@ -661,6 +664,9 @@ void vj_effman_apply_video_effect( VJFrame **frames, vjp_kf *todo_info,int *arg,
|
||||
case VJ_VIDEO_EFFECT_TRAVELMATTE:
|
||||
travelmatte_apply(frames[0],frames[1],frames[0]->width,frames[0]->height,arg[0]);
|
||||
break;
|
||||
case VJ_VIDEO_EFFECT_ALPHABLEND:
|
||||
alphablend_apply(frames[0],frames[1],frames[0]->width,frames[0]->height);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#define FX_LIMIT 1024
|
||||
|
||||
#define MAX_EFFECTS 150
|
||||
#define MAX_EFFECTS 152
|
||||
#define PARAM_WIDTH (1<<0x2)
|
||||
#define PARAM_HEIGHT (1<<0x3)
|
||||
#define PARAM_FADER (1<<0x1)
|
||||
@@ -46,7 +46,7 @@ typedef struct VJFrame_t
|
||||
int shift_v;
|
||||
int shift_h;
|
||||
int format;
|
||||
int width;
|
||||
int width;
|
||||
int height;
|
||||
int ssm;
|
||||
int stride[4];
|
||||
@@ -102,8 +102,8 @@ typedef struct vj_effect_instance_t {
|
||||
float *farr;
|
||||
} vj_fx_instance;
|
||||
|
||||
extern int get_pixel_range_min_Y();
|
||||
extern int get_pixel_range_min_UV();
|
||||
extern int get_pixel_range_min_Y();
|
||||
extern int get_pixel_range_min_UV();
|
||||
extern void vj_effect_initialize(int width, int height, int range);
|
||||
extern void vj_effect_shutdown();
|
||||
extern int vj_effect_max_effects();
|
||||
@@ -126,16 +126,12 @@ extern int vj_effect_get_summary_len(int entry);
|
||||
extern void *vj_effect_activate(int e, int *retcode);
|
||||
extern int vj_effect_deactivate(int e, void *ptr);
|
||||
extern int vj_effect_initialized(int e, void *ptr);
|
||||
extern int vj_effect_get_min_i();
|
||||
extern int vj_effect_get_max_i();
|
||||
extern int vj_effect_get_min_v();
|
||||
extern int vj_effect_get_max_v();
|
||||
extern int vj_effect_get_by_name(char *name);
|
||||
extern int vj_effect_apply( VJFrame **frames, VJFrameInfo *frameinfo, vjp_kf *kf, int selector, int *arguments, void *ptr);
|
||||
extern int vj_effect_prepare( VJFrame *frame, int selector);
|
||||
extern void vj_effect_dump(void);
|
||||
extern int rgb_parameter_conversion_type_;
|
||||
extern int vj_effect_is_plugin( int fx_id );
|
||||
extern int vj_effect_apply( VJFrame **frames, VJFrameInfo *frameinfo, vjp_kf *kf, int selector, int *arguments, void *ptr);
|
||||
extern int vj_effect_prepare( VJFrame *frame, int selector);
|
||||
extern void vj_effect_dump(void);
|
||||
extern int rgb_parameter_conversion_type_;
|
||||
extern int vj_effect_is_plugin( int fx_id );
|
||||
extern void *vj_effect_get_data( int seq_id );
|
||||
extern int vj_effect_is_parallel(int effect_id);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user