From fb4c972912353a229e357356c8883eba3b9c37d0 Mon Sep 17 00:00:00 2001 From: ddennedy Date: Sun, 10 Jun 2007 21:34:57 +0000 Subject: [PATCH] added effectv module with BurningTV filter provided by Stephane Fillod git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@987 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/modules/effectv/Makefile | 35 +++++ src/modules/effectv/configure | 19 +++ src/modules/effectv/factory.c | 44 ++++++ src/modules/effectv/filter_burn.c | 214 ++++++++++++++++++++++++++ src/modules/effectv/filter_burn.h | 27 ++++ src/modules/effectv/image.c | 307 +++++++++++++++++++++++++++++++++++++ src/modules/effectv/utils.c | 55 +++++++ src/modules/effectv/utils.h | 46 ++++++ 8 files changed, 747 insertions(+), 0 deletions(-) create mode 100644 src/modules/effectv/Makefile create mode 100755 src/modules/effectv/configure create mode 100644 src/modules/effectv/factory.c create mode 100644 src/modules/effectv/filter_burn.c create mode 100644 src/modules/effectv/filter_burn.h create mode 100644 src/modules/effectv/gpl create mode 100644 src/modules/effectv/image.c create mode 100644 src/modules/effectv/utils.c create mode 100644 src/modules/effectv/utils.h diff --git a/src/modules/effectv/Makefile b/src/modules/effectv/Makefile new file mode 100644 index 0000000..a3ca6bc --- /dev/null +++ b/src/modules/effectv/Makefile @@ -0,0 +1,35 @@ +include ../../../config.mak + +TARGET = ../libmlteffectv$(LIBSUF) + +OBJS = factory.o \ + filter_burn.o \ + image.o \ + utils.o + +CFLAGS += -I../.. + +LDFLAGS+=-L../../framework -lmlt + +SRCS := $(OBJS:.o=.c) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) + +depend: $(SRCS) + $(CC) -MM $(CFLAGS) $^ 1>.depend + +distclean: clean + rm -f .depend + +clean: + rm -f $(OBJS) $(TARGET) + +install: all + install -m 755 $(TARGET) "$(DESTDIR)$(prefix)/share/mlt/modules" + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/src/modules/effectv/configure b/src/modules/effectv/configure new file mode 100755 index 0000000..25f1d82 --- /dev/null +++ b/src/modules/effectv/configure @@ -0,0 +1,19 @@ +#!/bin/sh + +if [ "$help" != "1" ] +then + +cat << EOF >> ../producers.dat +EOF + +cat << EOF >> ../filters.dat +BurningTV libmlteffectv$LIBSUF +EOF + +cat << EOF >> ../transitions.dat +EOF + +cat << EOF >> ../consumers.dat +EOF + +fi diff --git a/src/modules/effectv/factory.c b/src/modules/effectv/factory.c new file mode 100644 index 0000000..06320d8 --- /dev/null +++ b/src/modules/effectv/factory.c @@ -0,0 +1,44 @@ +/* + * factory.c -- the factory method interfaces + * Copyright (C) 2007 Stephane Fillod + * + * 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 + +#include "filter_burn.h" + +void *mlt_create_producer( char *id, void *arg ) +{ + return NULL; +} + +void *mlt_create_filter( char *id, void *arg ) +{ + if ( !strcmp( id, "BurningTV" ) ) + return filter_burn_init( arg ); + return NULL; +} + +void *mlt_create_transition( char *id, void *arg ) +{ + return NULL; +} + +void *mlt_create_consumer( char *id, void *arg ) +{ + return NULL; +} diff --git a/src/modules/effectv/filter_burn.c b/src/modules/effectv/filter_burn.c new file mode 100644 index 0000000..d5a579b --- /dev/null +++ b/src/modules/effectv/filter_burn.c @@ -0,0 +1,214 @@ +/* + * filter_burn.c -- burning filter + * Copyright (C) 2007 Stephane Fillod + * + * Filter taken from EffecTV - Realtime Digital Video Effector + * Copyright (C) 2001-2006 FUKUCHI Kentaro + * + * BurningTV - burns incoming objects. + * Copyright (C) 2001-2002 FUKUCHI Kentaro + * + * Fire routine is taken from Frank Jan Sorensen's demo program. + * + * + * 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 "filter_burn.h" + +#include + +#include +#include +#include +#include +#include "utils.h" + + +#define MaxColor 120 +#define Decay 15 +#define MAGIC_THRESHOLD "50" + +static RGB32 palette[256]; + +/* FIXME: endianess? */ +static void makePalette(void) +{ + int i, r, g, b; + + for(i=0; i> 8)); + i++; + } + i += 2; + } + + mlt_convert_rgb24a_to_yuv422((uint8_t *)dest, *width, *height, *width * sizeof(RGB32), + *image, NULL ); + + mlt_pool_release(dest); + } + + return error; +} + +/** Filter processing. +*/ + +static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) +{ + // Push the frame filter + mlt_frame_push_service( frame, this ); + mlt_frame_push_get_image( frame, filter_get_image ); + + return frame; +} + +/** Constructor for the filter. +*/ + +mlt_filter filter_burn_init( char *arg ) +{ + mlt_filter this = mlt_filter_new( ); + if ( this != NULL ) + { + this->process = filter_process; + mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "foreground", "0" ); + mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "threshold", MAGIC_THRESHOLD ); + } + if (!palette[128]) + { + makePalette(); + } + return this; +} + diff --git a/src/modules/effectv/filter_burn.h b/src/modules/effectv/filter_burn.h new file mode 100644 index 0000000..8c8e731 --- /dev/null +++ b/src/modules/effectv/filter_burn.h @@ -0,0 +1,27 @@ +/* + * filter_brun.h -- burning filter + * Copyright (C) 2007 Stephane Fillod + * + * 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 _FILTER_BURN_H_ +#define _FILTER_BURN_H_ + +#include + +extern mlt_filter filter_burn_init( char *arg ); + +#endif diff --git a/src/modules/effectv/gpl b/src/modules/effectv/gpl new file mode 100644 index 0000000..e69de29 diff --git a/src/modules/effectv/image.c b/src/modules/effectv/image.c new file mode 100644 index 0000000..dbd848f --- /dev/null +++ b/src/modules/effectv/image.c @@ -0,0 +1,307 @@ +/* + * EffecTV - Realtime Digital Video Effector + * Copyright (C) 2001-2006 FUKUCHI Kentaro + * + * image.c: utilities for image processing. + * + */ + +#include +#include +#include "utils.h" + + +/* + * Collection of background subtraction functions + */ + +/* checks only fake-Y value */ +/* In these function Y value is treated as R*2+G*4+B. */ + +int image_set_threshold_y(int threshold) +{ + int y_threshold = threshold * 7; /* fake-Y value is timed by 7 */ + + return y_threshold; +} + +void image_bgset_y(RGB32 *background, const RGB32 *src, int video_area, int y_threshold) +{ + int i; + int R, G, B; + const RGB32 *p; + short *q; + + p = src; + q = (short *)background; + for(i=0; i>(16-1); + G = ((*p)&0xff00)>>(8-2); + B = (*p)&0xff; + *q = (short)(R + G + B); + p++; + q++; + } +} + +void image_bgsubtract_y(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, int y_threshold) +{ + int i; + int R, G, B; + const RGB32 *p; + short *q; + unsigned char *r; + int v; + + p = src; + q = (short *)background; + r = diff; + for(i=0; i>(16-1); + G = ((*p)&0xff00)>>(8-2); + B = (*p)&0xff; + v = (R + G + B) - (int)(*q); + *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24); + + p++; + q++; + r++; + } + +/* The origin of subtraction function is; + * diff(src, dest) = (abs(src - dest) > threshold) ? 0xff : 0; + * + * This functions is transformed to; + * (threshold > (src - dest) > -threshold) ? 0 : 0xff; + * + * (v + threshold)>>24 is 0xff when v is less than -threshold. + * (v - threshold)>>24 is 0xff when v is less than threshold. + * So, ((v + threshold)>>24) | ((threshold - v)>>24) will become 0xff when + * abs(src - dest) > threshold. + */ +} + +/* Background image is refreshed every frame */ +void image_bgsubtract_update_y(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, int y_threshold) +{ + int i; + int R, G, B; + const RGB32 *p; + short *q; + unsigned char *r; + int v; + + p = src; + q = (short *)background; + r = diff; + for(i=0; i>(16-1); + G = ((*p)&0xff00)>>(8-2); + B = (*p)&0xff; + v = (R + G + B) - (int)(*q); + *q = (short)(R + G + B); + *r = ((v + y_threshold)>>24) | ((y_threshold - v)>>24); + + p++; + q++; + r++; + } +} + +/* checks each RGB value */ + +/* The range of r, g, b are [0..7] */ +RGB32 image_set_threshold_RGB(int r, int g, int b) +{ + unsigned char R, G, B; + RGB32 rgb_threshold; + + R = G = B = 0xff; + R = R<>8); + b = b ^ 0xffffff; + a = a ^ b; + a = a & rgb_threshold; + *r++ = (0 - a)>>24; + } +} + +void image_bgsubtract_update_RGB(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold) +{ + int i; + const RGB32 *p; + RGB32 *q; + unsigned a, b; + unsigned char *r; + + p = src; + q = background; + r = diff; + for(i=0; i>8); + b = b ^ 0xffffff; + a = a ^ b; + a = a & rgb_threshold; + *r++ = (0 - a)>>24; + } +} + +/* noise filter for subtracted image. */ +void image_diff_filter(unsigned char *diff2, const unsigned char *diff, int width, int height) +{ + int x, y; + const unsigned char *src; + unsigned char *dest; + unsigned int count; + unsigned int sum1, sum2, sum3; + + src = diff; + dest = diff2 + width +1; + for(y=1; y>24; + src++; + } + dest += 2; + } +} + +/* Y value filters */ +void image_y_over(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold) +{ + int i; + int R, G, B, v; + unsigned char *p = diff; + + for(i = video_area; i>0; i--) { + R = ((*src)&0xff0000)>>(16-1); + G = ((*src)&0xff00)>>(8-2); + B = (*src)&0xff; + v = y_threshold - (R + G + B); + *p = (unsigned char)(v>>24); + src++; + p++; + } +} + +void image_y_under(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold) +{ + int i; + int R, G, B, v; + unsigned char *p = diff; + + for(i = video_area; i>0; i--) { + R = ((*src)&0xff0000)>>(16-1); + G = ((*src)&0xff00)>>(8-2); + B = (*src)&0xff; + v = (R + G + B) - y_threshold; + *p = (unsigned char)(v>>24); + src++; + p++; + } +} + +/* tiny edge detection */ +void image_edge(unsigned char *diff2, const RGB32 *src, int width, int height, int y_threshold) +{ + int x, y; + unsigned char *p, *q; + int r, g, b; + int ar, ag, ab; + int w; + + p = (unsigned char *)src; + q = diff2; + w = width * sizeof(RGB32); + + for(y=0; y y_threshold) { + *q = 255; + } else { + *q = 0; + } + q++; + p += 4; + } + p += 4; + *q++ = 0; + } + memset(q, 0, width); +} + +/* horizontal flipping */ +void image_hflip(const RGB32 *src, RGB32 *dest, int width, int height) +{ + int x, y; + + src += width - 1; + for(y=0; y +#include "utils.h" + +/* + * HSI color system utilities + */ +static int itrunc(double f) +{ + int i; + + i=(int)f; + if(i<0)i=0; + if(i>255)i=255; + return i; +} + +void HSItoRGB(double H, double S, double I, int *r, int *g, int *b) +{ + double T,Rv,Gv,Bv; + + Rv=1+S*sin(H-2*M_PI/3); + Gv=1+S*sin(H); + Bv=1+S*sin(H+2*M_PI/3); + T=255.999*I/2; + *r=itrunc(Rv*T); + *g=itrunc(Gv*T); + *b=itrunc(Bv*T); +} + +/* + * fastrand - fast fake random number generator + * Warning: The low-order bits of numbers generated by fastrand() + * are bad as random numbers. For example, fastrand()%4 + * generates 1,2,3,0,1,2,3,0... + * You should use high-order bits. + */ +unsigned int fastrand_val; + +unsigned int fastrand(void) +{ + return (fastrand_val=fastrand_val*1103515245+12345); +} + +void fastsrand(unsigned int seed) +{ + fastrand_val = seed; +} diff --git a/src/modules/effectv/utils.h b/src/modules/effectv/utils.h new file mode 100644 index 0000000..284db0f --- /dev/null +++ b/src/modules/effectv/utils.h @@ -0,0 +1,46 @@ +/* + * EffecTV - Realtime Digital Video Effector + * Copyright (C) 2001-2006 FUKUCHI Kentaro + * + * utils.h: header file for utils + * + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include + +typedef uint32_t RGB32; + +/* DEFINE's by nullset@dookie.net */ +#define RED(n) ((n>>16) & 0x000000FF) +#define GREEN(n) ((n>>8) & 0x000000FF) +#define BLUE(n) ((n>>0) & 0x000000FF) +#define RGB(r,g,b) ((0<<24) + (r<<16) + (g <<8) + (b)) +#define INTENSITY(n) ( ( (RED(n)+GREEN(n)+BLUE(n))/3)) + +/* utils.c */ +void HSItoRGB(double H, double S, double I, int *r, int *g, int *b); + +extern unsigned int fastrand_val; +unsigned int fastrand(void); +void fastsrand(unsigned int); +#define inline_fastrand() (fastrand_val=fastrand_val*1103515245+12345) + +/* image.c */ +int image_set_threshold_y(int threshold); +void image_bgset_y(RGB32 *background, const RGB32 *src, int video_area, int y_threshold); +void image_bgsubtract_y(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, int y_threshold); +void image_bgsubtract_update_y(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, int y_threshold); +RGB32 image_set_threshold_RGB(int r, int g, int b); +void image_bgset_RGB(RGB32 *background, const RGB32 *src, int video_area); +void image_bgsubtract_RGB(unsigned char *diff, const RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold); +void image_bgsubtract_update_RGB(unsigned char *diff, RGB32 *background, const RGB32 *src, int video_area, RGB32 rgb_threshold); +void image_diff_filter(unsigned char *diff2, const unsigned char *diff, int width, int height); +void image_y_over(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold); +void image_y_under(unsigned char *diff, const RGB32 *src, int video_area, int y_threshold); +void image_edge(unsigned char *diff2, const RGB32 *src, int width, int height, int y_threshold); +void image_hflip(const RGB32 *src, RGB32 *dest, int width, int height); + +#endif /* __UTILS_H__ */ -- 1.7.4.4