mirror of
https://github.com/game-stop/veejay.git
synced 2025-12-16 12:50:00 +01:00
fix bg subtract, add extra mode to magic mirror, fix snap bg, added special mode to magic mirror that depends on bg subtraction
This commit is contained in:
@@ -26,110 +26,125 @@
|
|||||||
#include <libyuv/yuvconv.h>
|
#include <libyuv/yuvconv.h>
|
||||||
#include <libvjmsg/vj-msg.h>
|
#include <libvjmsg/vj-msg.h>
|
||||||
#include "softblur.h"
|
#include "softblur.h"
|
||||||
static uint8_t *static_bg = NULL;
|
#include <libsubsample/subsample.h>
|
||||||
|
|
||||||
|
static uint8_t *static_bg__ = NULL;
|
||||||
|
static uint8_t *bg_frame__[4] = { NULL,NULL,NULL,NULL };
|
||||||
|
static int bg_ssm = 0;
|
||||||
|
|
||||||
vj_effect *bgsubtract_init(int width, int height)
|
vj_effect *bgsubtract_init(int width, int height)
|
||||||
{
|
{
|
||||||
vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
||||||
ve->num_params = 3;
|
ve->num_params = 3;
|
||||||
ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */
|
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[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */
|
||||||
ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */
|
ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */
|
||||||
ve->limits[0][0] = 0; /* threshold */
|
ve->limits[0][0] = 0; /* threshold */
|
||||||
ve->limits[1][0] = 255;
|
ve->limits[1][0] = 255;
|
||||||
ve->limits[0][1] = 0; /* mode */
|
ve->limits[0][1] = 0; /* mode */
|
||||||
ve->limits[1][1] = 1;
|
ve->limits[1][1] = 1;
|
||||||
ve->limits[0][2] = 0; /* alpha */
|
ve->limits[0][2] = 0; /* alpha */
|
||||||
ve->limits[1][2] = 1;
|
ve->limits[1][2] = 1;
|
||||||
|
|
||||||
ve->defaults[0] = 45;
|
ve->defaults[0] = 45;
|
||||||
ve->defaults[1] = 0;
|
ve->defaults[1] = 1;
|
||||||
ve->defaults[2] = 0;
|
ve->defaults[2] = 0;
|
||||||
|
|
||||||
ve->description = "Substract background (static, requires bg mask)";
|
ve->description = "Subtract background";
|
||||||
ve->extra_frame = 0;
|
ve->extra_frame = 0;
|
||||||
ve->sub_format = -1;
|
ve->sub_format = -1;
|
||||||
ve->has_user = 1;
|
ve->has_user = 1;
|
||||||
ve->user_data = NULL;
|
ve->user_data = NULL;
|
||||||
ve->param_description = vje_build_param_list( ve->num_params, "Threshold", "Mode", "To Alpha");
|
ve->param_description = vje_build_param_list( ve->num_params, "Threshold", "Mode", "To Alpha");
|
||||||
|
|
||||||
ve->hints = vje_init_value_hint_list( ve->num_params );
|
ve->hints = vje_init_value_hint_list( ve->num_params );
|
||||||
|
|
||||||
vje_build_value_hint_list( ve->hints, ve->limits[1][1], 1,"Preview", "Inverted preview", "Normal" );
|
vje_build_value_hint_list( ve->hints, ve->limits[1][1], 1,"Show Difference", "Show Static BG" );
|
||||||
|
|
||||||
ve->alpha = FLAG_ALPHA_OUT | FLAG_ALPHA_OPTIONAL;
|
ve->alpha = FLAG_ALPHA_OUT | FLAG_ALPHA_OPTIONAL;
|
||||||
|
|
||||||
return ve;
|
return ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define rup8(num)(((num)+8)&~8)
|
|
||||||
int bgsubtract_malloc(int width, int height)
|
int bgsubtract_malloc(int width, int height)
|
||||||
{
|
{
|
||||||
if(static_bg == NULL)
|
if(static_bg__ == NULL){
|
||||||
static_bg = (uint8_t*) vj_calloc( rup8( width + width * height * sizeof(uint8_t)) );
|
static_bg__ = (uint8_t*) vj_malloc( RUP8(width*height)*4);
|
||||||
|
bg_frame__[0] = static_bg__;
|
||||||
|
bg_frame__[1] = bg_frame__[0] + RUP8(width*height);
|
||||||
|
bg_frame__[2] = bg_frame__[1] + RUP8(width*height);
|
||||||
|
bg_frame__[3] = bg_frame__[2] + RUP8(width*height);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bgsubtract_free()
|
void bgsubtract_free()
|
||||||
{
|
{
|
||||||
if( static_bg )
|
if( static_bg__ ) {
|
||||||
free(static_bg );
|
free(static_bg__ );
|
||||||
static_bg = NULL;
|
|
||||||
|
bg_frame__[0] = NULL;
|
||||||
|
bg_frame__[1] = NULL;
|
||||||
|
bg_frame__[2] = NULL;
|
||||||
|
bg_frame__[3] = NULL;
|
||||||
|
static_bg__ = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int bgsubtract_prepare(uint8_t *map[4], int width, int height)
|
int bgsubtract_prepare(VJFrame *frame)
|
||||||
{
|
{
|
||||||
if(!static_bg )
|
if(!static_bg__ )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ copy the iamge
|
//@ copy the iamge
|
||||||
veejay_memcpy( static_bg, map[0], (width*height));
|
veejay_memcpy( bg_frame__[0], frame->data[0], frame->len );
|
||||||
|
if( frame->ssm ) {
|
||||||
|
veejay_memcpy( bg_frame__[1], frame->data[1], frame->len );
|
||||||
|
veejay_memcpy( bg_frame__[2], frame->data[2], frame->len );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// if data is subsampled, super sample it now
|
||||||
|
veejay_memcpy( bg_frame__[1], frame->data[1], frame->uv_len );
|
||||||
|
veejay_memcpy( bg_frame__[2], frame->data[2], frame->uv_len );
|
||||||
|
chroma_supersample( SSM_422_444, frame, bg_frame__ );
|
||||||
|
}
|
||||||
|
|
||||||
|
bg_ssm = 1;
|
||||||
|
|
||||||
VJFrame tmp;
|
veejay_msg(2, "Subtract background: Snapped background frame");
|
||||||
veejay_memset( &tmp, 0, sizeof(VJFrame));
|
|
||||||
tmp.data[0] = static_bg;
|
|
||||||
tmp.width = width;
|
|
||||||
tmp.height = height;
|
|
||||||
|
|
||||||
//@ 3x3 blur
|
|
||||||
softblur_apply( &tmp, width,height,0);
|
|
||||||
|
|
||||||
veejay_msg(2, "Substract background: Snapped background frame");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t* bgsubtract_get_bg_frame(unsigned int plane)
|
||||||
|
{
|
||||||
|
return bg_frame__[ plane ];
|
||||||
|
}
|
||||||
|
|
||||||
void bgsubtract_apply(VJFrame *frame,int width, int height, int threshold, int mode, int alpha )
|
void bgsubtract_apply(VJFrame *frame,int width, int height, int threshold, int mode, int alpha )
|
||||||
{
|
{
|
||||||
VJFrame tmp;
|
const int uv_len = (frame->ssm ? frame->len : frame->uv_len );
|
||||||
veejay_memset( &tmp, 0, sizeof(VJFrame));
|
|
||||||
tmp.data[0] = frame->data[0];
|
|
||||||
tmp.width = width;
|
|
||||||
tmp.height = height;
|
|
||||||
|
|
||||||
//@ 3x3 blur
|
if( mode ) {
|
||||||
softblur_apply( &tmp, width,height,0);
|
veejay_memcpy( frame->data[0], bg_frame__[0], frame->len );
|
||||||
|
if( frame->ssm ) {
|
||||||
|
veejay_memcpy( frame->data[1], bg_frame__[1], frame->len );
|
||||||
|
veejay_memcpy( frame->data[2], bg_frame__[2], frame->len );
|
||||||
|
} else { /* if chain is still subsampled, copy only greyscale image */
|
||||||
|
veejay_memset( frame->data[1], 128, frame->uv_len );
|
||||||
|
veejay_memset( frame->data[2], 128, frame->uv_len );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( alpha == 0 ) {
|
if( alpha == 0 ) {
|
||||||
if ( mode == 0 ) {
|
veejay_memset( frame->data[1], 128, uv_len );
|
||||||
binarify( frame->data[0], static_bg,frame->data[0], threshold, 0, width*height );
|
veejay_memset( frame->data[2], 128, uv_len );
|
||||||
} else if ( mode == 1 ) {
|
vje_diff_plane( bg_frame__[0], frame->data[0], frame->data[0], threshold, frame->len );
|
||||||
binarify( frame->data[0], static_bg, frame->data[0], threshold, 1,width*height );
|
|
||||||
}
|
|
||||||
|
|
||||||
veejay_memset( frame->data[1], 128, frame->uv_len );
|
|
||||||
veejay_memset( frame->data[2], 128, frame->uv_len );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( mode == 0 ) {
|
vje_diff_plane( bg_frame__[0], frame->data[0], frame->data[3], threshold, frame->len );
|
||||||
binarify( frame->data[0], static_bg,frame->data[3], threshold, 0, width*height );
|
|
||||||
} else if ( mode == 1 ) {
|
|
||||||
binarify( frame->data[0], static_bg, frame->data[3], threshold, 1,width*height );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
vj_effect *bgsubtract_init(int width, int height);
|
vj_effect *bgsubtract_init(int width, int height);
|
||||||
void bgsubtract_free();
|
void bgsubtract_free();
|
||||||
int bgsubtract_malloc(int w, int h);
|
int bgsubtract_malloc(int w, int h);
|
||||||
int bgsubtract_prepare(uint8_t *map[4], int w, int h);
|
int bgsubtract_prepare(VJFrame *frame);
|
||||||
void bgsubtract_apply(VJFrame *frame,int width,int height,int mode, int threshold, int to_alpha);
|
void bgsubtract_apply(VJFrame *frame,int width,int height,int mode, int threshold, int to_alpha);
|
||||||
|
uint8_t *bgsubtract_get_bg_frame(unsigned int plane);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1490,7 +1490,11 @@ void vje_diff_plane( uint8_t *A, uint8_t *B, uint8_t *O, int threshold, int len
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for( i = 0; i < len; i ++ ) {
|
for( i = 0; i < len; i ++ ) {
|
||||||
O[i] = ( abs( B[i] - A[i] ) > threshold ? 0xff : 0 );
|
O[i] = abs( A[i] - B[i] );
|
||||||
|
if( O[i] < threshold )
|
||||||
|
O[i] = 0;
|
||||||
|
else
|
||||||
|
O[i] = 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Linux VeeJay
|
* Linux VeeJay
|
||||||
*
|
*
|
||||||
* Copyright(C)2004 Niels Elburg <elburg@hio.hen.nl>
|
* Copyright(C)2004-2016 Niels Elburg <nwelburg@gmail.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "magicmirror.h"
|
#include "magicmirror.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "motionmap.h"
|
||||||
|
#include <libvje/internal.h>
|
||||||
|
|
||||||
// if d or n changes, tables need to be calculated
|
// if d or n changes, tables need to be calculated
|
||||||
static uint8_t *magicmirrorbuf[4] = { NULL,NULL,NULL,NULL };
|
static uint8_t *magicmirrorbuf[4] = { NULL,NULL,NULL,NULL };
|
||||||
@@ -31,47 +33,60 @@ static double *funhouse_y = NULL;
|
|||||||
static unsigned int *cache_x = NULL;
|
static unsigned int *cache_x = NULL;
|
||||||
static unsigned int *cache_y = NULL;
|
static unsigned int *cache_y = NULL;
|
||||||
static unsigned int last[4] = {0,0,20,20};
|
static unsigned int last[4] = {0,0,20,20};
|
||||||
|
static int cx1 = 0;
|
||||||
|
static int cx2 = 0;
|
||||||
static int n__ = 0;
|
static int n__ = 0;
|
||||||
static int N__ = 0;
|
static int N__ = 0;
|
||||||
|
|
||||||
vj_effect *magicmirror_init(int w, int h)
|
vj_effect *magicmirror_init(int w, int h)
|
||||||
{
|
{
|
||||||
vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
||||||
ve->num_params = 4;
|
ve->num_params = 5;
|
||||||
ve->defaults = (int *) vj_calloc(sizeof(int) * ve->num_params); /* default values */
|
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[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */
|
||||||
ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */
|
ve->limits[1] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* max */
|
||||||
|
|
||||||
ve->defaults[0] = w/4;
|
ve->defaults[0] = w/4;
|
||||||
ve->defaults[1] = h/4;
|
ve->defaults[1] = h/4;
|
||||||
ve->defaults[2] = 20;
|
ve->defaults[2] = 20;
|
||||||
ve->defaults[3] = 20;
|
ve->defaults[3] = 20;
|
||||||
|
ve->defaults[4] = 0;
|
||||||
|
|
||||||
|
ve->limits[0][0] = 0;
|
||||||
|
ve->limits[1][0] = w/2;
|
||||||
|
ve->limits[0][1] = 0;
|
||||||
|
ve->limits[1][1] = h/2;
|
||||||
|
ve->limits[0][2] = 0;
|
||||||
|
ve->limits[1][2] = 100;
|
||||||
|
ve->limits[0][3] = 0;
|
||||||
|
ve->limits[1][3] = 100;
|
||||||
|
ve->limits[0][4] = 0;
|
||||||
|
ve->limits[1][4] = 2;
|
||||||
|
|
||||||
ve->limits[0][0] = 0;
|
|
||||||
ve->limits[1][0] = w/2;
|
|
||||||
ve->limits[0][1] = 0;
|
|
||||||
ve->limits[1][1] = h/2;
|
|
||||||
ve->limits[0][2] = 0;
|
|
||||||
ve->limits[1][2] = 100;
|
|
||||||
ve->limits[0][3] = 0;
|
|
||||||
ve->limits[1][3] = 100;
|
|
||||||
ve->motion = 1;
|
ve->motion = 1;
|
||||||
ve->sub_format = 1;
|
ve->sub_format = 1;
|
||||||
ve->description = "Magic Mirror Surface";
|
ve->description = "Magic Mirror Surface";
|
||||||
ve->has_user =0;
|
ve->has_user =0;
|
||||||
ve->extra_frame = 0;
|
ve->extra_frame = 0;
|
||||||
ve->param_description = vje_build_param_list(ve->num_params, "X", "Y", "X","Y" );
|
ve->alpha = FLAG_ALPHA_SRC_A | FLAG_ALPHA_OUT | FLAG_ALPHA_OPTIONAL;
|
||||||
return ve;
|
ve->param_description = vje_build_param_list(ve->num_params, "X", "Y", "X","Y", "Alpha" );
|
||||||
|
|
||||||
|
ve->hints = vje_init_value_hint_list( ve->num_params );
|
||||||
|
|
||||||
|
vje_build_value_hint_list( ve->hints, ve->limits[1][4], 4, "Normal", "Alpha Mirror Mask", "Alpha Mirror Mask Only" );
|
||||||
|
|
||||||
|
return ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
int magicmirror_malloc(int w, int h)
|
int magicmirror_malloc(int w, int h)
|
||||||
{
|
{
|
||||||
magicmirrorbuf[0] = (uint8_t*) vj_malloc(sizeof(uint8_t)*RUP8(w*h*3));
|
magicmirrorbuf[0] = (uint8_t*) vj_malloc(sizeof(uint8_t)*RUP8(w*h*4));
|
||||||
if(!magicmirrorbuf[0])
|
if(!magicmirrorbuf[0])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
magicmirrorbuf[1] = magicmirrorbuf[0] + RUP8(w*h);
|
magicmirrorbuf[1] = magicmirrorbuf[0] + RUP8(w*h);
|
||||||
magicmirrorbuf[2] = magicmirrorbuf[1] + RUP8(w*h);
|
magicmirrorbuf[2] = magicmirrorbuf[1] + RUP8(w*h);
|
||||||
|
magicmirrorbuf[3] = magicmirrorbuf[2] + RUP8(w*h);
|
||||||
|
|
||||||
funhouse_x = (double*)vj_calloc(sizeof(double) * w );
|
funhouse_x = (double*)vj_calloc(sizeof(double) * w );
|
||||||
if(!funhouse_x) return 0;
|
if(!funhouse_x) return 0;
|
||||||
@@ -101,13 +116,14 @@ void magicmirror_free()
|
|||||||
magicmirrorbuf[0] = NULL;
|
magicmirrorbuf[0] = NULL;
|
||||||
magicmirrorbuf[1] = NULL;
|
magicmirrorbuf[1] = NULL;
|
||||||
magicmirrorbuf[2] = NULL;
|
magicmirrorbuf[2] = NULL;
|
||||||
|
magicmirrorbuf[3] = NULL;
|
||||||
cache_x = NULL;
|
cache_x = NULL;
|
||||||
cache_y = NULL;
|
cache_y = NULL;
|
||||||
funhouse_x = NULL;
|
funhouse_x = NULL;
|
||||||
funhouse_y = NULL;
|
funhouse_y = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void magicmirror_apply( VJFrame *frame, int w, int h, int vx, int vy, int d, int n )
|
void magicmirror_apply( VJFrame *frame, int w, int h, int vx, int vy, int d, int n, int alpha )
|
||||||
{
|
{
|
||||||
double c1 = (double)vx;
|
double c1 = (double)vx;
|
||||||
double c2 = (double)vy;
|
double c2 = (double)vy;
|
||||||
@@ -115,7 +131,14 @@ void magicmirror_apply( VJFrame *frame, int w, int h, int vx, int vy, int d, int
|
|||||||
int interpolate = 1;
|
int interpolate = 1;
|
||||||
if( motionmap_active())
|
if( motionmap_active())
|
||||||
{
|
{
|
||||||
motionmap_scale_to( 100,100,0,0, &d, &n, &n__, &N__ );
|
if( motionmap_is_locked() ) {
|
||||||
|
d = cx1;
|
||||||
|
n = cx2;
|
||||||
|
} else {
|
||||||
|
motionmap_scale_to( 100,100,0,0, &d, &n, &n__, &N__ );
|
||||||
|
cx1 = d;
|
||||||
|
cx2 = n;
|
||||||
|
}
|
||||||
motion = 1;
|
motion = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -134,6 +157,7 @@ void magicmirror_apply( VJFrame *frame, int w, int h, int vx, int vy, int d, int
|
|||||||
uint8_t *Y = frame->data[0];
|
uint8_t *Y = frame->data[0];
|
||||||
uint8_t *Cb= frame->data[1];
|
uint8_t *Cb= frame->data[1];
|
||||||
uint8_t *Cr= frame->data[2];
|
uint8_t *Cr= frame->data[2];
|
||||||
|
uint8_t *A = frame->data[3];
|
||||||
|
|
||||||
if( d != last[1] ) {
|
if( d != last[1] ) {
|
||||||
changed = 1; last[1] =d;
|
changed = 1; last[1] =d;
|
||||||
@@ -165,14 +189,6 @@ void magicmirror_apply( VJFrame *frame, int w, int h, int vx, int vy, int d, int
|
|||||||
funhouse_y[y] = res;
|
funhouse_y[y] = res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// int strides[4] = { len,len,len, 0 };
|
|
||||||
// vj_frame_copy( frame->data, magicmirrorbuf, strides );
|
|
||||||
|
|
||||||
veejay_memcpy( magicmirrorbuf[0], frame->data[0], len );
|
|
||||||
veejay_memcpy( magicmirrorbuf[1], frame->data[1], len );
|
|
||||||
veejay_memcpy( magicmirrorbuf[2], frame->data[2], len );
|
|
||||||
|
|
||||||
for(x=0; x < w; x++)
|
for(x=0; x < w; x++)
|
||||||
{
|
{
|
||||||
dx = x + funhouse_x[x] * c1;
|
dx = x + funhouse_x[x] * c1;
|
||||||
@@ -188,17 +204,91 @@ void magicmirror_apply( VJFrame *frame, int w, int h, int vx, int vy, int d, int
|
|||||||
cache_y[y] = dy;
|
cache_y[y] = dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(y=1; y < h-1; y++)
|
veejay_memcpy( magicmirrorbuf[0], frame->data[0], len );
|
||||||
{
|
veejay_memcpy( magicmirrorbuf[1], frame->data[1], len );
|
||||||
for(x=1; x < w-1; x++)
|
veejay_memcpy( magicmirrorbuf[2], frame->data[2], len );
|
||||||
|
|
||||||
|
if( alpha ) {
|
||||||
|
veejay_memcpy( magicmirrorbuf[3], frame->data[3], len );
|
||||||
|
/* apply on alpha first */
|
||||||
|
for(y=1; y < h-1; y++)
|
||||||
{
|
{
|
||||||
p = cache_y[y] * w + cache_x[x];
|
for(x=1; x < w-1; x++)
|
||||||
q = y * w + x;
|
{
|
||||||
Y[q] = magicmirrorbuf[0][p];
|
q = y * w + x;
|
||||||
Cb[q] = magicmirrorbuf[1][p];
|
p = cache_y[y] * w + cache_x[x];
|
||||||
Cr[q] = magicmirrorbuf[2][p];
|
A[q] = magicmirrorbuf[3][p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *Am = magicmirrorbuf[3];
|
||||||
|
|
||||||
|
switch(alpha) {
|
||||||
|
case 1:
|
||||||
|
for(y=1; y < h-1; y++)
|
||||||
|
{
|
||||||
|
for(x=1; x < w-1; x++)
|
||||||
|
{
|
||||||
|
q = y * w + x;
|
||||||
|
p = cache_y[y] * w + cache_x[x];
|
||||||
|
if( Am[p] || A[q] ) {
|
||||||
|
Y[q] = magicmirrorbuf[0][p];
|
||||||
|
Cb[q] = magicmirrorbuf[1][p];
|
||||||
|
Cr[q] = magicmirrorbuf[2][p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
//@ try get a bg from somwhere
|
||||||
|
uint8_t *bgY = vj_effect_get_bg( VJ_IMAGE_EFFECT_BGSUBTRACT, 0 );
|
||||||
|
uint8_t *bgCb= vj_effect_get_bg( VJ_IMAGE_EFFECT_BGSUBTRACT, 1 );
|
||||||
|
uint8_t *bgCr= vj_effect_get_bg( VJ_IMAGE_EFFECT_BGSUBTRACT, 2 );
|
||||||
|
|
||||||
|
if( bgY == NULL || bgCb == NULL || bgCr == NULL ) {
|
||||||
|
veejay_msg(0,"This mode requires 'Subtract background' FX");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(y=1; y < h-1; y++)
|
||||||
|
{
|
||||||
|
for(x=1; x < w-1; x++)
|
||||||
|
{
|
||||||
|
q = y * w + x;
|
||||||
|
p = cache_y[y] * w + cache_x[x];
|
||||||
|
|
||||||
|
if( A[q] ) {
|
||||||
|
Y[q] = magicmirrorbuf[0][p];
|
||||||
|
Cb[q] = magicmirrorbuf[1][p];
|
||||||
|
Cr[q] = magicmirrorbuf[2][p];
|
||||||
|
} else if ( Am[q] ) {
|
||||||
|
//@ put in pixels from static bg
|
||||||
|
Y[q] = bgY[q];
|
||||||
|
Cb[q] = bgCb[q];
|
||||||
|
Cr[q] = bgCr[q];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
for(y=1; y < h-1; y++)
|
||||||
|
{
|
||||||
|
for(x=1; x < w-1; x++)
|
||||||
|
{
|
||||||
|
q = y * w + x;
|
||||||
|
p = cache_y[y] * w + cache_x[x];
|
||||||
|
|
||||||
|
Y[q] = magicmirrorbuf[0][p];
|
||||||
|
Cb[q] = magicmirrorbuf[1][p];
|
||||||
|
Cr[q] = magicmirrorbuf[2][p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if( interpolate )
|
if( interpolate )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
vj_effect *magicmirror_init(int w, int h);
|
vj_effect *magicmirror_init(int w, int h);
|
||||||
int magicmirror_malloc(int w, int h);
|
int magicmirror_malloc(int w, int h);
|
||||||
void magicmirror_apply( VJFrame *frame, int width, int height, int a, int b,
|
void magicmirror_apply( VJFrame *frame, int width, int height, int a, int b, int na, int nb, int alpha);
|
||||||
int na, int nb);
|
|
||||||
void magicmirror_free();
|
void magicmirror_free();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,6 +32,16 @@
|
|||||||
* To use the plain C version, define NO_AUTOVECTORIZATION
|
* To use the plain C version, define NO_AUTOVECTORIZATION
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* create mask of foreground object (aproximate IR)
|
||||||
|
* put mask into alpha-channel
|
||||||
|
* apply secundary effect on alpha-channel
|
||||||
|
* apply secundary effect on whole frame, using alpha channel
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -49,7 +59,7 @@
|
|||||||
vj_effect *motionmap_init(int w, int h)
|
vj_effect *motionmap_init(int w, int h)
|
||||||
{
|
{
|
||||||
vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect));
|
vj_effect *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->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[0] = (int *) vj_calloc(sizeof(int) * ve->num_params); /* min */
|
||||||
@@ -66,19 +76,28 @@ vj_effect *motionmap_init(int w, int h)
|
|||||||
ve->limits[1][3] = HIS_LEN;
|
ve->limits[1][3] = HIS_LEN;
|
||||||
ve->limits[0][5] = 0;
|
ve->limits[0][5] = 0;
|
||||||
ve->limits[1][5] = 1;
|
ve->limits[1][5] = 1;
|
||||||
|
ve->limits[0][6] = 0;
|
||||||
|
ve->limits[1][6] = 3;
|
||||||
ve->defaults[0] = 40;
|
ve->defaults[0] = 40;
|
||||||
ve->defaults[1] = 1000;
|
ve->defaults[1] = 1000;
|
||||||
ve->defaults[2] = 1;
|
ve->defaults[2] = 1;
|
||||||
ve->defaults[3] = HIS_DEFAULT;
|
ve->defaults[3] = HIS_DEFAULT;
|
||||||
ve->defaults[4] = HIS_DEFAULT;
|
ve->defaults[4] = HIS_DEFAULT;
|
||||||
ve->defaults[5] = 0;
|
ve->defaults[5] = 0;
|
||||||
|
ve->defaults[6] = 0;
|
||||||
ve->description = "Motion Mapping";
|
ve->description = "Motion Mapping";
|
||||||
ve->sub_format = 1;
|
ve->sub_format = 1;
|
||||||
ve->extra_frame = 0;
|
ve->extra_frame = 0;
|
||||||
ve->has_user = 0;
|
ve->has_user = 0;
|
||||||
ve->n_out = 2;
|
ve->n_out = 2;
|
||||||
ve->param_description = vje_build_param_list( ve->num_params,
|
// ve->alpha = FLAG_ALPHA_OUT | FLAG_ALPHA_SRC_A;
|
||||||
"Difference Threshold", "Maximum Motion Energy","Draw Motion Map","History in frames" ,"Decay", "Interpolate frames");
|
ve->param_description = vje_build_param_list( ve->num_params,
|
||||||
|
"Difference Threshold", "Maximum Motion Energy","Draw Motion Map","History in frames" ,"Decay", "Interpolate frames", "Activity Mode");
|
||||||
|
|
||||||
|
ve->hints = vje_init_value_hint_list( ve->num_params );
|
||||||
|
|
||||||
|
vje_build_value_hint_list( ve->hints, ve->limits[1][6], 6, "Normal", "Local Max", "Global Max", "Hold Last" );
|
||||||
|
|
||||||
return ve;
|
return ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +110,7 @@ static uint8_t *prev_img = NULL;
|
|||||||
static uint8_t *interpolate_buf = NULL;
|
static uint8_t *interpolate_buf = NULL;
|
||||||
|
|
||||||
static int32_t max = 0;
|
static int32_t max = 0;
|
||||||
|
static int32_t global_max = 0;
|
||||||
static uint32_t nframe_ =0;
|
static uint32_t nframe_ =0;
|
||||||
static int current_his_len = HIS_DEFAULT;
|
static int current_his_len = HIS_DEFAULT;
|
||||||
static int current_decay = HIS_DEFAULT;
|
static int current_decay = HIS_DEFAULT;
|
||||||
@@ -100,6 +120,7 @@ static int running = 0;
|
|||||||
static int is_initialized = 0;
|
static int is_initialized = 0;
|
||||||
static int do_interpolation = 0;
|
static int do_interpolation = 0;
|
||||||
static int stored_frame = 0;
|
static int stored_frame = 0;
|
||||||
|
static int scale_lock = 0;
|
||||||
|
|
||||||
int motionmap_malloc(int w, int h )
|
int motionmap_malloc(int w, int h )
|
||||||
{
|
{
|
||||||
@@ -148,6 +169,9 @@ void motionmap_free(void)
|
|||||||
do_interpolation = 0;
|
do_interpolation = 0;
|
||||||
keyv_ = 0;
|
keyv_ = 0;
|
||||||
keyp_ = 0;
|
keyp_ = 0;
|
||||||
|
scale_lock = 0;
|
||||||
|
global_max = 0;
|
||||||
|
stored_frame = 0;
|
||||||
binary_img = NULL;
|
binary_img = NULL;
|
||||||
prev_img = NULL;
|
prev_img = NULL;
|
||||||
}
|
}
|
||||||
@@ -167,6 +191,11 @@ int motionmap_active()
|
|||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int motionmap_is_locked()
|
||||||
|
{
|
||||||
|
return scale_lock;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t motionmap_activity()
|
uint32_t motionmap_activity()
|
||||||
{
|
{
|
||||||
return keyv_;
|
return keyv_;
|
||||||
@@ -174,24 +203,24 @@ uint32_t motionmap_activity()
|
|||||||
|
|
||||||
void motionmap_scale_to( int p1max, int p2max, int p1min, int p2min, int *p1val, int *p2val, int *pos, int *len )
|
void motionmap_scale_to( int p1max, int p2max, int p1min, int p2min, int *p1val, int *p2val, int *pos, int *len )
|
||||||
{
|
{
|
||||||
if( max == 0 )
|
if( global_max == 0 || scale_lock )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( keyv_ > max )
|
if( keyv_ > global_max )
|
||||||
{
|
{
|
||||||
keyv_ = max;
|
keyv_ = global_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = (nframe_ % current_decay) + 1;
|
int n = (nframe_ % current_decay) + 1;
|
||||||
float q = 1.0f / (float) current_decay * n;
|
float q = 1.0f / (float) current_decay * n;
|
||||||
float diff = (float) keyv_ - (float) keyp_ ;
|
float diff = (float) keyv_ - (float) keyp_ ;
|
||||||
float pu = keyp_ + (q * diff);
|
float pu = keyp_ + (q * diff);
|
||||||
float m = (float) max;
|
float m = (float) global_max;
|
||||||
|
|
||||||
if( pu > m )
|
if( pu > m )
|
||||||
pu = m;
|
pu = m;
|
||||||
|
|
||||||
float w = 1.0 / max;
|
float w = 1.0 / global_max;
|
||||||
float pw = w * pu;
|
float pw = w * pu;
|
||||||
|
|
||||||
*p1val = p1min + (int) ((p1max-p1min) * pw);
|
*p1val = p1min + (int) ((p1max-p1min) * pw);
|
||||||
@@ -290,7 +319,6 @@ void motionmap_calc_diff( const uint8_t *bg, uint8_t *prev_img, const uint8_t *i
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint8_t p1,p2;
|
uint8_t p1,p2;
|
||||||
|
|
||||||
#ifndef NO_AUTOVECTORIZATION
|
|
||||||
uint8_t *I1 = pI1;
|
uint8_t *I1 = pI1;
|
||||||
uint8_t *I2 = pI2;
|
uint8_t *I2 = pI2;
|
||||||
|
|
||||||
@@ -308,6 +336,7 @@ void motionmap_calc_diff( const uint8_t *bg, uint8_t *prev_img, const uint8_t *i
|
|||||||
else
|
else
|
||||||
I2[i] = 0xff;
|
I2[i] = 0xff;
|
||||||
|
|
||||||
|
// A[i] = I1[i];
|
||||||
I1[i] = abs( I1[i] - I2[i] );
|
I1[i] = abs( I1[i] - I2[i] );
|
||||||
I2[i] = bDst[i] >> 1;
|
I2[i] = bDst[i] >> 1;
|
||||||
}
|
}
|
||||||
@@ -317,30 +346,6 @@ void motionmap_calc_diff( const uint8_t *bg, uint8_t *prev_img, const uint8_t *i
|
|||||||
bDst[i] = I1[i] + I2[i];
|
bDst[i] = I1[i] + I2[i];
|
||||||
prev_img[i] = img[i];
|
prev_img[i] = img[i];
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
for( i = 0; i < len; i ++ )
|
|
||||||
{
|
|
||||||
uint8_t q1 = 0, q2 = 0;
|
|
||||||
p1 = abs( bg[i] - img[i] );
|
|
||||||
if( p1 > threshold ) {
|
|
||||||
q1 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
p2 = abs( bg[i] - prev_img[i] );
|
|
||||||
if( p2 > threshold ) {
|
|
||||||
q2 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( (!q1 && q2) || (!q2 && q1) ) {
|
|
||||||
bDst[i] = 0xff;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bDst[i] = (bDst[i] >> 1); //@ decay
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_img[i] = img[i];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void motionmap_find_diff_job( void *arg )
|
void motionmap_find_diff_job( void *arg )
|
||||||
@@ -350,6 +355,7 @@ void motionmap_find_diff_job( void *arg )
|
|||||||
const uint8_t *t_bg = t->input[0];
|
const uint8_t *t_bg = t->input[0];
|
||||||
const uint8_t *t_img = t->input[1];
|
const uint8_t *t_img = t->input[1];
|
||||||
uint8_t *t_prev_img = t->input[2];
|
uint8_t *t_prev_img = t->input[2];
|
||||||
|
// uint8_t *t_alpha = t->input[3];
|
||||||
uint8_t *t_binary_img = t->output[0];
|
uint8_t *t_binary_img = t->output[0];
|
||||||
uint8_t *t_diff1 = t->output[1];
|
uint8_t *t_diff1 = t->output[1];
|
||||||
uint8_t *t_diff2 = t->output[2];
|
uint8_t *t_diff2 = t->output[2];
|
||||||
@@ -357,7 +363,8 @@ void motionmap_find_diff_job( void *arg )
|
|||||||
const int len = t->strides[0];
|
const int len = t->strides[0];
|
||||||
const int threshold = t->iparams[0];
|
const int threshold = t->iparams[0];
|
||||||
|
|
||||||
motionmap_calc_diff( t_bg, t_prev_img, t_img,t_diff1,t_diff2, t_binary_img, len, threshold );
|
// motionmap_calc_diff( t_bg, t_prev_img, t_img,t_diff1,t_diff2, t_binary_img,t_alpha, len, threshold );
|
||||||
|
motionmap_calc_diff( t_bg, t_prev_img, t_img,t_diff1,t_diff2, t_binary_img,len, threshold );
|
||||||
}
|
}
|
||||||
|
|
||||||
int motionmap_prepare( uint8_t *map[4], int width, int height )
|
int motionmap_prepare( uint8_t *map[4], int width, int height )
|
||||||
@@ -374,16 +381,20 @@ int motionmap_prepare( uint8_t *map[4], int width, int height )
|
|||||||
running = 0;
|
running = 0;
|
||||||
stored_frame = 0;
|
stored_frame = 0;
|
||||||
do_interpolation = 0;
|
do_interpolation = 0;
|
||||||
|
scale_lock = 0;
|
||||||
veejay_msg(2, "Motion Mapping: Snapped background frame");
|
veejay_msg(2, "Motion Mapping: Snapped background frame");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
static int32_t global_act = 0;
|
||||||
|
|
||||||
void motionmap_apply( VJFrame *frame, int width, int height, int threshold, int limit, int draw, int history, int decay, int interpol )
|
void motionmap_apply( VJFrame *frame, int width, int height, int threshold, int limit, int draw, int history, int decay, int interpol, int last_act_level )
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const unsigned int len = (width * height);
|
const unsigned int len = (width * height);
|
||||||
uint8_t *Cb = frame->data[1];
|
uint8_t *Cb = frame->data[1];
|
||||||
uint8_t *Cr = frame->data[2];
|
uint8_t *Cr = frame->data[2];
|
||||||
|
// uint8_t *alpha = frame->data[3];
|
||||||
|
|
||||||
if(!have_bg) {
|
if(!have_bg) {
|
||||||
veejay_msg(VEEJAY_MSG_ERROR,"Motion Mapping: Snap the background frame with VIMS 339 or mask button in reloaded");
|
veejay_msg(VEEJAY_MSG_ERROR,"Motion Mapping: Snap the background frame with VIMS 339 or mask button in reloaded");
|
||||||
return;
|
return;
|
||||||
@@ -395,10 +406,12 @@ void motionmap_apply( VJFrame *frame, int width, int height, int threshold, int
|
|||||||
task.stride[0] = len; // plane length
|
task.stride[0] = len; // plane length
|
||||||
task.stride[1] = len;
|
task.stride[1] = len;
|
||||||
task.stride[2] = len;
|
task.stride[2] = len;
|
||||||
|
// task.stride[3] = len;
|
||||||
task.stride[3] = 0;
|
task.stride[3] = 0;
|
||||||
task.data[0] = bg_image; // plane 0 = background image
|
task.data[0] = bg_image; // plane 0 = background image
|
||||||
task.data[1] = frame->data[0]; // plane 1 = luminance channel
|
task.data[1] = frame->data[0]; // plane 1 = luminance channel
|
||||||
task.data[2] = prev_img; // plane 2 = luminance channel of previous frame
|
task.data[2] = prev_img; // plane 2 = luminance channel of previous frame
|
||||||
|
// task.data[3] = alpha;
|
||||||
task.data[3] = NULL;
|
task.data[3] = NULL;
|
||||||
task.ssm = 1; // all planes are the same size
|
task.ssm = 1; // all planes are the same size
|
||||||
task.format = frame->format; // not important, but cannot be 0
|
task.format = frame->format; // not important, but cannot be 0
|
||||||
@@ -409,15 +422,19 @@ void motionmap_apply( VJFrame *frame, int width, int height, int threshold, int
|
|||||||
task.width = width; // dimensions
|
task.width = width; // dimensions
|
||||||
task.height = height;
|
task.height = height;
|
||||||
|
|
||||||
|
// uint8_t *dst[4] = { binary_img, diff_img, diff_img + RUP8(len), alpha };
|
||||||
uint8_t *dst[4] = { binary_img, diff_img, diff_img + RUP8(len), NULL };
|
uint8_t *dst[4] = { binary_img, diff_img, diff_img + RUP8(len), NULL };
|
||||||
|
|
||||||
|
|
||||||
vj_task_set_from_frame( &task );
|
vj_task_set_from_frame( &task );
|
||||||
vj_task_set_param( threshold, 0 );
|
vj_task_set_param( threshold, 0 );
|
||||||
|
|
||||||
vj_task_run( task.data, dst, NULL,NULL,3, (performer_job_routine) &motionmap_find_diff_job );
|
vj_task_run( task.data, dst, NULL,NULL,4, (performer_job_routine) &motionmap_find_diff_job );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// motionmap_calc_diff( (const uint8_t*) bg_image, prev_img, (const uint8_t*) frame->data[0], diff_img, diff_img + RUP8(len), binary_img, alpha, len, threshold );
|
||||||
motionmap_calc_diff( (const uint8_t*) bg_image, prev_img, (const uint8_t*) frame->data[0], diff_img, diff_img + RUP8(len), binary_img, len, threshold );
|
motionmap_calc_diff( (const uint8_t*) bg_image, prev_img, (const uint8_t*) frame->data[0], diff_img, diff_img + RUP8(len), binary_img, len, threshold );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( draw )
|
if( draw )
|
||||||
@@ -427,12 +444,15 @@ void motionmap_apply( VJFrame *frame, int width, int height, int threshold, int
|
|||||||
vj_frame_copy1( binary_img, frame->data[0], len );
|
vj_frame_copy1( binary_img, frame->data[0], len );
|
||||||
running = 0;
|
running = 0;
|
||||||
stored_frame = 0;
|
stored_frame = 0;
|
||||||
|
scale_lock = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t activity_level = motionmap_activity_level( binary_img, width, height );
|
int32_t activity_level = motionmap_activity_level( binary_img, width, height );
|
||||||
int32_t avg_actlvl = 0;
|
int32_t avg_actlvl = 0;
|
||||||
int32_t min = INT_MAX;
|
int32_t min = INT_MAX;
|
||||||
|
int32_t local_max = 0;
|
||||||
|
|
||||||
|
|
||||||
current_his_len = history;
|
current_his_len = history;
|
||||||
current_decay = decay;
|
current_decay = decay;
|
||||||
@@ -444,21 +464,55 @@ void motionmap_apply( VJFrame *frame, int width, int height, int threshold, int
|
|||||||
avg_actlvl += histogram_[i];
|
avg_actlvl += histogram_[i];
|
||||||
if(histogram_[i] > max ) max = histogram_[i];
|
if(histogram_[i] > max ) max = histogram_[i];
|
||||||
if(histogram_[i] < min ) min = histogram_[i];
|
if(histogram_[i] < min ) min = histogram_[i];
|
||||||
|
if(histogram_[i] > local_max) local_max = histogram_[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
avg_actlvl = avg_actlvl / current_his_len;
|
avg_actlvl = avg_actlvl / current_his_len;
|
||||||
|
if( avg_actlvl < limit ) {
|
||||||
if( avg_actlvl < limit )
|
|
||||||
avg_actlvl = 0;
|
avg_actlvl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
nframe_ ++;
|
nframe_ ++;
|
||||||
|
|
||||||
if( (nframe_ % current_his_len)==0 )
|
switch( last_act_level ) {
|
||||||
{
|
case 0:
|
||||||
key1_ = min;
|
if( (nframe_ % current_his_len)==0 )
|
||||||
key2_ = max;
|
{
|
||||||
keyp_ = keyv_;
|
key1_ = min;
|
||||||
keyv_ = avg_actlvl;
|
key2_ = max;
|
||||||
|
keyp_ = keyv_;
|
||||||
|
keyv_ = avg_actlvl;
|
||||||
|
global_max = max;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
key1_ = min;
|
||||||
|
key2_ = max;
|
||||||
|
keyv_ = local_max;
|
||||||
|
global_max = local_max;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
key1_ = min;
|
||||||
|
key2_ = max;
|
||||||
|
keyp_ = keyv_;
|
||||||
|
keyv_ = avg_actlvl;
|
||||||
|
global_max = max;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if( (nframe_ % current_his_len)==0 )
|
||||||
|
{
|
||||||
|
key1_ = min;
|
||||||
|
key2_ = max;
|
||||||
|
keyp_ = keyv_;
|
||||||
|
keyv_ = avg_actlvl;
|
||||||
|
global_max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( avg_actlvl == 0 )
|
||||||
|
scale_lock = 1;
|
||||||
|
else
|
||||||
|
scale_lock = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
running = 1;
|
running = 1;
|
||||||
|
|||||||
@@ -25,8 +25,14 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
vj_effect *motionmap_init(int w, int h);
|
vj_effect *motionmap_init(int w, int h);
|
||||||
void motionmap_apply( VJFrame *frame, int width, int height, int t, int n, int draw, int histo, int op, int ip);
|
void motionmap_apply( VJFrame *frame, int width, int height, int t, int n, int draw, int histo, int op, int ip, int la);
|
||||||
int motionmap_malloc(int w,int h);
|
int motionmap_malloc(int w,int h);
|
||||||
void motionmap_free(void);
|
void motionmap_free(void);
|
||||||
int motionmap_prepare( uint8_t *map[4], int w, int h );
|
int motionmap_prepare( uint8_t *map[4], int w, int h );
|
||||||
|
int motionmap_active();
|
||||||
|
int motionmap_is_locked();
|
||||||
|
uint8_t *motionmap_interpolate_buffer();
|
||||||
|
uint8_t *motionmap_bgmap();
|
||||||
|
void motionmap_store_frame( VJFrame *fx );
|
||||||
|
void motionmap_interpolate_frame( VJFrame *fx, int N, int n );
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ extern void pencilsketch_apply(VJFrame *frame, int w, int h, int type, int thres
|
|||||||
|
|
||||||
extern void pixelate_apply(VJFrame *frame, int w, int h, int v );
|
extern void pixelate_apply(VJFrame *frame, int w, int h, int v );
|
||||||
|
|
||||||
extern void magicmirror_apply(VJFrame *frame, int w, int h, int x, int y, int d, int n );
|
extern void magicmirror_apply(VJFrame *frame, int w, int h, int x, int y, int d, int n, int alpha );
|
||||||
|
|
||||||
extern void lumamask_apply(VJFrame *frame,VJFrame *frame2, int w, int h, int n, int m, int border, int alpha);
|
extern void lumamask_apply(VJFrame *frame,VJFrame *frame2, int w, int h, int n, int m, int border, int alpha);
|
||||||
|
|
||||||
@@ -539,7 +539,9 @@ extern void dissolve_apply(VJFrame *frame,VJFrame *frame2, int w, int h, int opa
|
|||||||
|
|
||||||
extern void overclock_apply(VJFrame *frame, int w, int h, int val, int r);
|
extern void overclock_apply(VJFrame *frame, int w, int h, int val, int r);
|
||||||
|
|
||||||
extern int bgsubtract_prepare(uint8_t *map[4], int w, int h);
|
uint8_t *bgsubtract_get_bg_frame(unsigned int plane);
|
||||||
|
|
||||||
|
extern int bgsubtract_prepare(VJFrame *frame);
|
||||||
|
|
||||||
extern void bgsubtract_apply(VJFrame *frame,int width, int height, int mode, int threshold, int alpha );
|
extern void bgsubtract_apply(VJFrame *frame,int width, int height, int mode, int threshold, int alpha );
|
||||||
|
|
||||||
@@ -585,7 +587,7 @@ extern void picinpic_apply( void *user_data, VJFrame *frame, VJFrame *frame2,
|
|||||||
|
|
||||||
extern void threshold_apply( VJFrame *frame, VJFrame *frame2,int width, int height, int threshold, int reverse );
|
extern void threshold_apply( VJFrame *frame, VJFrame *frame2,int width, int height, int threshold, int reverse );
|
||||||
|
|
||||||
extern void motionmap_apply( VJFrame *frame, int w, int h, int threshold, int reverse, int draw, int his, int op, int ip );
|
extern void motionmap_apply( VJFrame *frame, int w, int h, int threshold, int reverse, int draw, int his, int op, int ip, int la );
|
||||||
|
|
||||||
extern void rgbchannel_apply( VJFrame *frame, int width, int height, int chr, int chg , int chb);
|
extern void rgbchannel_apply( VJFrame *frame, int width, int height, int chr, int chg , int chb);
|
||||||
|
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ void vj_effman_apply_image_effect(
|
|||||||
arg[1]);
|
arg[1]);
|
||||||
break;
|
break;
|
||||||
case VJ_IMAGE_EFFECT_MAGICMIRROR:
|
case VJ_IMAGE_EFFECT_MAGICMIRROR:
|
||||||
magicmirror_apply(frames[0],frames[0]->width,frames[0]->height,arg[0],arg[1],arg[2],arg[3]);
|
magicmirror_apply(frames[0],frames[0]->width,frames[0]->height,arg[0],arg[1],arg[2],arg[3],arg[4]);
|
||||||
break;
|
break;
|
||||||
case VJ_IMAGE_EFFECT_RASTER:
|
case VJ_IMAGE_EFFECT_RASTER:
|
||||||
raster_apply(frames[0],frames[0]->width,frames[0]->height,arg[0],arg[1]);
|
raster_apply(frames[0],frames[0]->width,frames[0]->height,arg[0],arg[1]);
|
||||||
@@ -391,7 +391,7 @@ void vj_effman_apply_image_effect(
|
|||||||
deinterlace_apply( frames[0], frames[0]->width, frames[0]->height, arg[0]);
|
deinterlace_apply( frames[0], frames[0]->width, frames[0]->height, arg[0]);
|
||||||
break;
|
break;
|
||||||
case VJ_IMAGE_EFFECT_MOTIONMAP:
|
case VJ_IMAGE_EFFECT_MOTIONMAP:
|
||||||
motionmap_apply( frames[0], frames[0]->width,frames[0]->height,arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
|
motionmap_apply( frames[0], frames[0]->width,frames[0]->height,arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
|
||||||
break;
|
break;
|
||||||
case VJ_IMAGE_EFFECT_CONTOUR:
|
case VJ_IMAGE_EFFECT_CONTOUR:
|
||||||
contourextract_apply( vj_effects[entry]->user_data, frames[0],
|
contourextract_apply( vj_effects[entry]->user_data, frames[0],
|
||||||
@@ -708,6 +708,18 @@ void vj_effman_apply_video_effect( VJFrame **frames, vjp_kf *todo_info,int *arg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t* vj_effect_get_bg( int selector, unsigned int plane )
|
||||||
|
{
|
||||||
|
switch( selector ) {
|
||||||
|
case VJ_IMAGE_EFFECT_BGSUBTRACT:
|
||||||
|
return bgsubtract_get_bg_frame( plane );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int vj_effect_prepare( VJFrame *frame, int selector)
|
int vj_effect_prepare( VJFrame *frame, int selector)
|
||||||
{
|
{
|
||||||
int fx_id = vj_effect_real_to_sequence( selector );
|
int fx_id = vj_effect_real_to_sequence( selector );
|
||||||
@@ -716,7 +728,7 @@ int vj_effect_prepare( VJFrame *frame, int selector)
|
|||||||
|
|
||||||
switch( selector ) {
|
switch( selector ) {
|
||||||
case VJ_IMAGE_EFFECT_BGSUBTRACT:
|
case VJ_IMAGE_EFFECT_BGSUBTRACT:
|
||||||
return bgsubtract_prepare( frame->data, frame->width,frame->height );
|
return bgsubtract_prepare( frame );
|
||||||
break;
|
break;
|
||||||
case VJ_IMAGE_EFFECT_CONTOUR:
|
case VJ_IMAGE_EFFECT_CONTOUR:
|
||||||
return contourextract_prepare(frame->data,frame->width,frame->height );
|
return contourextract_prepare(frame->data,frame->width,frame->height );
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ extern int vj_effect_initialized(int e, void *ptr);
|
|||||||
extern int vj_effect_get_by_name(char *name);
|
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_apply( VJFrame **frames, VJFrameInfo *frameinfo, vjp_kf *kf, int selector, int *arguments, void *ptr);
|
||||||
extern int vj_effect_prepare( VJFrame *frame, int selector);
|
extern int vj_effect_prepare( VJFrame *frame, int selector);
|
||||||
|
extern uint8_t *vj_effect_get_bg( int selector, unsigned int plane );
|
||||||
extern void vj_effect_dump(void);
|
extern void vj_effect_dump(void);
|
||||||
extern int rgb_parameter_conversion_type_;
|
extern int rgb_parameter_conversion_type_;
|
||||||
extern int vj_effect_is_plugin( int fx_id );
|
extern int vj_effect_is_plugin( int fx_id );
|
||||||
|
|||||||
@@ -219,44 +219,17 @@ filelist_t *find_media_files( veejay_t *info )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int vj_perform_take_bg(veejay_t *info, VJFrame *frame, int pass)
|
int vj_perform_take_bg(veejay_t *info, VJFrame *frame)
|
||||||
{
|
{
|
||||||
int n = 0;
|
vj_effect_prepare( frame, VJ_VIDEO_EFFECT_CHAMBLEND );
|
||||||
if( pass == 0 ) {
|
vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CHAMELEON );
|
||||||
if(frame->ssm == 1 ) {
|
vj_effect_prepare( frame, VJ_IMAGE_EFFECT_BGSUBTRACT );
|
||||||
n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_CHAMBLEND );
|
vj_effect_prepare( frame, VJ_VIDEO_EFFECT_DIFF );
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CHAMELEON );
|
vj_effect_prepare( frame, VJ_IMAGE_EFFECT_MOTIONMAP );
|
||||||
if(n > 0 )
|
vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CONTOUR );
|
||||||
return 1;
|
vj_effect_prepare( frame, VJ_IMAGE_EFFECT_BGSUBTRACT );
|
||||||
}
|
vj_effect_prepare( frame, VJ_VIDEO_EFFECT_DIFF );
|
||||||
if(frame->ssm == 0) {
|
vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CONTOUR );
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_BGSUBTRACT );
|
|
||||||
n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_DIFF );
|
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_MOTIONMAP );
|
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CONTOUR );
|
|
||||||
if( n > 0 )
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( frame->ssm == 0 )
|
|
||||||
{
|
|
||||||
chroma_supersample( info->settings->sample_mode,frame,frame->data );
|
|
||||||
n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_CHAMBLEND );
|
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CHAMELEON );
|
|
||||||
frame->ssm = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (n > 0 ? 0: 1 );
|
|
||||||
} else {
|
|
||||||
if(frame->ssm == 0) {
|
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_BGSUBTRACT );
|
|
||||||
n += vj_effect_prepare( frame, VJ_VIDEO_EFFECT_DIFF );
|
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_MOTIONMAP );
|
|
||||||
n += vj_effect_prepare( frame, VJ_IMAGE_EFFECT_CONTOUR );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ long vj_get_relative_time(void);
|
|||||||
void vj_stamp_clear();
|
void vj_stamp_clear();
|
||||||
unsigned int vj_stamp();
|
unsigned int vj_stamp();
|
||||||
|
|
||||||
int vj_perform_take_bg( veejay_t *info, VJFrame *src, int pass);
|
int vj_perform_take_bg( veejay_t *info, VJFrame *src);
|
||||||
|
|
||||||
int veejay_create_temp_file(const char *prefix, char *dst);
|
int veejay_create_temp_file(const char *prefix, char *dst);
|
||||||
|
|
||||||
|
|||||||
@@ -2645,8 +2645,13 @@ static void vj_perform_plain_fill_buffer(veejay_t * info, int *ret)
|
|||||||
*ret = vj_perform_get_frame_(info, info->uc->sample_id, settings->current_frame_num,&frame,&frame, p0_buffer,p1_buffer,0 );
|
*ret = vj_perform_get_frame_(info, info->uc->sample_id, settings->current_frame_num,&frame,&frame, p0_buffer,p1_buffer,0 );
|
||||||
} else if ( info->uc->playback_mode == VJ_PLAYBACK_MODE_PLAIN ) {
|
} else if ( info->uc->playback_mode == VJ_PLAYBACK_MODE_PLAIN ) {
|
||||||
*ret = vj_perform_get_frame_(info, 0, settings->current_frame_num,&frame,&frame, p0_buffer, p1_buffer,0 );
|
*ret = vj_perform_get_frame_(info, 0, settings->current_frame_num,&frame,&frame, p0_buffer, p1_buffer,0 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(info->uc->take_bg==1 )
|
||||||
|
{
|
||||||
|
info->uc->take_bg = vj_perform_take_bg(info,&frame);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
static int rec_audio_sample_ = 0;
|
static int rec_audio_sample_ = 0;
|
||||||
static int vj_perform_render_sample_frame(veejay_t *info, uint8_t *frame[4], int sample)
|
static int vj_perform_render_sample_frame(veejay_t *info, uint8_t *frame[4], int sample)
|
||||||
@@ -2958,19 +2963,17 @@ static int vj_perform_tag_fill_buffer(veejay_t * info)
|
|||||||
|
|
||||||
if(!active)
|
if(!active)
|
||||||
{
|
{
|
||||||
if (type == VJ_TAG_TYPE_V4L || type == VJ_TAG_TYPE_NET || type == VJ_TAG_TYPE_MCAST || type == VJ_TAG_TYPE_PICTURE )
|
if (type == VJ_TAG_TYPE_V4L || type == VJ_TAG_TYPE_NET || type == VJ_TAG_TYPE_MCAST || type == VJ_TAG_TYPE_PICTURE )
|
||||||
vj_tag_enable( info->uc->sample_id );
|
vj_tag_enable( info->uc->sample_id );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (vj_tag_get_frame(info->uc->sample_id, info->effect_frame1,NULL))
|
||||||
if (vj_tag_get_frame(info->uc->sample_id, info->effect_frame1,NULL))
|
{
|
||||||
{
|
error = 0;
|
||||||
error = 0;
|
cached_tag_frames[0] = info->uc->sample_id;
|
||||||
cached_tag_frames[0] = info->uc->sample_id;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error == 1)
|
if (error == 1)
|
||||||
{
|
{
|
||||||
@@ -2983,7 +2986,13 @@ static int vj_perform_tag_fill_buffer(veejay_t * info)
|
|||||||
dumb.data[3] = frame[3];
|
dumb.data[3] = frame[3];
|
||||||
dummy_apply(&dumb,info->video_output_width,info->video_output_height,VJ_EFFECT_COLOR_BLACK );
|
dummy_apply(&dumb,info->video_output_width,info->video_output_height,VJ_EFFECT_COLOR_BLACK );
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
|
if(info->uc->take_bg==1 )
|
||||||
|
{
|
||||||
|
info->uc->take_bg = vj_perform_take_bg(info,info->effect_frame1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vj_perform_pre_chain(veejay_t *info, VJFrame *frame)
|
static void vj_perform_pre_chain(veejay_t *info, VJFrame *frame)
|
||||||
@@ -3531,11 +3540,6 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett
|
|||||||
free(more_text);
|
free(more_text);
|
||||||
|
|
||||||
|
|
||||||
if (info->uc->take_bg==1)
|
|
||||||
{
|
|
||||||
info->uc->take_bg = vj_perform_take_bg(info,frame,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!settings->composite && info->uc->mouse[0] > 0 && info->uc->mouse[1] > 0)
|
if(!settings->composite && info->uc->mouse[0] > 0 && info->uc->mouse[1] > 0)
|
||||||
{
|
{
|
||||||
if( info->uc->mouse[2] == 1 ) {
|
if( info->uc->mouse[2] == 1 ) {
|
||||||
@@ -3609,7 +3613,6 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( frame->ssm == 1 )
|
if( frame->ssm == 1 )
|
||||||
{
|
{
|
||||||
chroma_subsample(settings->sample_mode,frame,pri);
|
chroma_subsample(settings->sample_mode,frame,pri);
|
||||||
@@ -3621,12 +3624,6 @@ static void vj_perform_finish_render( veejay_t *info, video_playback_setup *sett
|
|||||||
frame2->ssm=0;
|
frame2->ssm=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->uc->take_bg==1)
|
|
||||||
{
|
|
||||||
vj_perform_take_bg(info,frame,1);
|
|
||||||
info->uc->take_bg = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( frame2->data[0] == frame->data[0] )
|
if( frame2->data[0] == frame->data[0] )
|
||||||
frame->ssm = 0;
|
frame->ssm = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user