add livido fx background subtraction

This commit is contained in:
c0ntrol
2016-03-20 19:34:15 +01:00
parent d26ff24761
commit b38f8e84c4
2 changed files with 244 additions and 3 deletions

View File

@@ -1,17 +1,19 @@
lividoplugin_LTLIBRARIES = lvd_solid.la \
lividoplugin_LTLIBRARIES = lvd_bgsubtract.la \
lvd_solid.la \
lvd_colortone.la \
lvd_displaywall.la \
lvd_stroboscope.la \
lvd_colorexchange.la
lvd_bgsubtract_la_SOURCES = lvd_bgsubtract.c
lvd_solid_la_SOURCES = lvd_solid.c
lvd_colortone_la_SOURCES = lvd_colortone.c
lvd_displaywall_la_SOURCES = lvd_displaywall.c
lvd_stroboscope_la_SOURCES = lvd_stroboscope.c
lvd_colorexchange_la_SOURCES = lvd_colorexchange.c
AM_CPPFLAGS = $(FFMPEG_CFLAGS)
AM_CFLAGS = -I@top_srcdir@/include $(OP_CFLAGS)
AM_CPPFLAGS = $(FFMPEG_CFLAGS) $(VJE_CFLAGS)
AM_CFLAGS = -I@top_srcdir@/include $(VJE_CFLAGS)
AM_LDFLAGS = -module -avoid-version -lm -export-dynamic
AM_LIBTOOLFLAGS = --tag=disable-static

View File

@@ -0,0 +1,239 @@
/*
* LIBVJE - veejay fx library
*
* Copyright(C)2016 Niels Elburg <nwelburg@gmail.com>
* See COPYING for software license and distribution details
*/
#ifndef IS_LIVIDO_PLUGIN
#define IS_LIVIDO_PLUGIN
#endif
#include "../libplugger/specs/livido.h"
LIVIDO_PLUGIN
#include "utils.h"
#include "livido-utils.c"
#include "lvd_common.h"
#define RUP8(num)(((num)+8)&~8)
typedef struct
{
uint8_t *bg;
int frame_no;
} bgsubtract_t;
livido_init_f init_instance( livido_port_t *my_instance )
{
int w = 0, h = 0;
lvd_extract_dimensions( my_instance, "out_channels", &w, &h );
bgsubtract_t *b = (bgsubtract_t*) livido_malloc(sizeof(bgsubtract_t));
b->bg = (uint8_t*) livido_malloc( sizeof(uint8_t) * RUP8(w * h) );
livido_property_set( my_instance, "PLUGIN_private", LIVIDO_ATOM_TYPE_VOIDPTR,1, &b);
livido_memset( b->bg, 0, w * h );
return LIVIDO_NO_ERROR;
}
livido_deinit_f deinit_instance( livido_port_t *my_instance )
{
void *ptr = NULL;
if ( livido_property_get( my_instance, "PLUGIN_private", 0, &ptr ) == LIVIDO_NO_ERROR )
{
bgsubtract_t *b = (bgsubtract_t*) ptr;
if( b->bg ) {
livido_free( b->bg );
}
livido_free(b);
}
return LIVIDO_NO_ERROR;
}
void lvd_vje_diff_plane( uint8_t *__restrict__ A, uint8_t *__restrict__ B, uint8_t *__restrict__ O, int threshold, const int len )
{
unsigned int i;
for( i = 0; i < len; i ++ ) {
O[i] = abs( A[i] - B[i] );
if( O[i] < threshold )
O[i] = 0;
else
O[i] = 0xff;
}
}
void lvd_avg_frame( uint8_t *__restrict__ A, uint8_t *__restrict__ O, const int len )
{
unsigned int i;
for( i = 0; i < len; i ++ )
{
O[i] = (O[i] + A[i]) >> 1;
}
}
int process_instance( livido_port_t *my_instance, double timecode )
{
int len =0;
uint8_t *A[4] = {NULL,NULL,NULL,NULL};
uint8_t *O[4]= {NULL,NULL,NULL,NULL};
int palette;
int w;
int h;
bgsubtract_t *ptr = NULL;
int error = lvd_extract_channel_values( my_instance, "out_channels", 0, &w,&h, O,&palette );
if( error != LIVIDO_NO_ERROR )
return LIVIDO_ERROR_NO_OUTPUT_CHANNELS;
error = lvd_extract_channel_values( my_instance, "in_channels" , 0, &w, &h, A, &palette );
if( error != LIVIDO_NO_ERROR )
return LIVIDO_ERROR_NO_INPUT_CHANNELS;
error = livido_property_get( my_instance, "PLUGIN_private", 0, &ptr );
if( error != LIVIDO_NO_ERROR )
return LIVIDO_ERROR_INTERNAL;
int uv_len = lvd_uv_plane_len( palette,w,h );
len = w * h;
int snap_bg = lvd_extract_param_index( my_instance,"in_parameters", 0 );
int threshold = lvd_extract_param_index( my_instance,"in_parameters", 1 );
int mode = lvd_extract_param_index( my_instance,"in_parameters", 2 );
if( snap_bg ) {
if( ptr->frame_no == 0 ) {
livido_memcpy( ptr->bg, A[0], len );
}
else {
/* average frames (assumes that background is static) */
lvd_avg_frame( A[0], ptr->bg, len );
}
ptr->frame_no ++;
/* while snapping, show bg frame */
livido_memcpy( O[0], ptr->bg, len );
livido_memset( O[1], 128, uv_len );
livido_memset( O[2], 128, uv_len );
}
else {
if( mode == 0 ) {
lvd_vje_diff_plane( ptr->bg, A[0], O[0], threshold, len );
livido_memset( O[1], 128, uv_len );
livido_memset( O[2], 128, uv_len );
}
else {
lvd_vje_diff_plane( ptr->bg, A[0], O[3], threshold, len );
}
ptr->frame_no = 0;
}
return LIVIDO_NO_ERROR;
}
livido_port_t *livido_setup(livido_setup_t list[], int version)
{
LIVIDO_IMPORT(list);
livido_port_t *port = NULL;
livido_port_t *in_params[3];
livido_port_t *in_chans[3];
livido_port_t *out_chans[1];
livido_port_t *info = NULL;
livido_port_t *filter = NULL;
//@ setup root node, plugin info
info = livido_port_new( LIVIDO_PORT_TYPE_PLUGIN_INFO );
port = info;
livido_set_string_value( port, "maintainer", "Niels");
livido_set_string_value( port, "version","1");
filter = livido_port_new( LIVIDO_PORT_TYPE_FILTER_CLASS );
livido_set_int_value( filter, "api_version", LIVIDO_API_VERSION );
//@ setup function pointers
livido_set_voidptr_value( filter, "deinit_func", &deinit_instance );
livido_set_voidptr_value( filter, "init_func", &init_instance );
livido_set_voidptr_value( filter, "process_func", &process_instance );
port = filter;
//@ meta information
livido_set_string_value( port, "name", "Background Subtraction");
livido_set_string_value( port, "description", "Subtract the background");
livido_set_string_value( port, "author", "Niels Elburg"); //ported to livido
livido_set_int_value( port, "flags", 0);
livido_set_string_value( port, "license", "GPL2");
livido_set_int_value( port, "version", 1);
//@ some palettes veejay-classic uses
int palettes0[] = {
LIVIDO_PALETTE_YUV422P,
LIVIDO_PALETTE_YUV444P,
0,
};
//@ setup output channel
out_chans[0] = livido_port_new( LIVIDO_PORT_TYPE_CHANNEL_TEMPLATE );
port = out_chans[0];
livido_set_string_value( port, "name", "Output Channel");
livido_set_int_array( port, "palette_list", 3, palettes0);
livido_set_int_value( port, "flags", 0);
in_chans[0] = livido_port_new( LIVIDO_PORT_TYPE_CHANNEL_TEMPLATE );
port = in_chans[0];
livido_set_string_value( port, "name", "Input Channel");
livido_set_int_array( port, "palette_list", 3, palettes0);
livido_set_int_value( port, "flags", 0);
//@ setup parameters (INDEX type, 0-255)
in_params[0] = livido_port_new( LIVIDO_PORT_TYPE_PARAMETER_TEMPLATE );
port = in_params[0];
livido_set_string_value(port, "name", "Background" );
livido_set_string_value(port, "kind", "INDEX" );
livido_set_int_value( port, "min", 0 );
livido_set_int_value( port, "max", 1 );
livido_set_int_value( port, "default", 0 );
livido_set_string_value( port, "description" ,"Set to snap current frame as a background frame");
in_params[1] = livido_port_new( LIVIDO_PORT_TYPE_PARAMETER_TEMPLATE );
port = in_params[1];
livido_set_string_value(port, "name", "Threshold" );
livido_set_string_value(port, "kind", "INDEX" );
livido_set_int_value( port, "min", 0 );
livido_set_int_value( port, "max", 255 );
livido_set_int_value( port, "default", 40 );
livido_set_string_value( port, "description" ,"Difference Threshold");
in_params[2] = livido_port_new( LIVIDO_PORT_TYPE_PARAMETER_TEMPLATE );
port = in_params[2];
livido_set_string_value(port, "name", "Alpha" );
livido_set_string_value(port, "kind", "INDEX" );
livido_set_int_value( port, "min", 0);
livido_set_int_value( port, "max", 1 );
livido_set_int_value( port, "default", 0 );
livido_set_string_value( port, "description" ,"Set difference frame as Alpha Channel");
//@ setup the nodes
livido_set_portptr_array( filter, "in_parameter_templates",3, in_params );
livido_set_portptr_array( filter, "out_channel_templates", 1, out_chans );
livido_set_portptr_array( filter, "in_channel_templates",1, in_chans );
livido_set_portptr_value(info, "filters", filter);
return info;
}