diff --git a/veejay-current/veejay-server/libvje/Makefile.am b/veejay-current/veejay-server/libvje/Makefile.am index 5bd9a2fe..91c01527 100644 --- a/veejay-current/veejay-server/libvje/Makefile.am +++ b/veejay-current/veejay-server/libvje/Makefile.am @@ -11,7 +11,7 @@ noinst_LTLIBRARIES = $(VJE_LIB_FILE) libvje_la_SOURCES = plugload.c vj-effect.c vj-effman.c effects/common.c \ effects/diff.c effects/fibdownscale.c effects/killchroma.c \ effects/lumamagick.c effects/autoeq.c effects/colorhis.c \ - effects/mirrors.c effects/goom.c effects/colormap.c effects/negation.c \ + effects/mirrors.c effects/goom.c effects/colormap.c effects/negatechannel.c effects/negation.c \ effects/overclock.c effects/dissolve.c effects/opacity.c effects/posterize.c \ effects/dither.c effects/dices.c effects/emboss.c effects/flip.c \ effects/revtv.c effects/softblur.c effects/zoom.c effects/split.c effects/widthmirror.c \ diff --git a/veejay-current/veejay-server/libvje/effects/negatechannel.c b/veejay-current/veejay-server/libvje/effects/negatechannel.c new file mode 100644 index 00000000..243a84fa --- /dev/null +++ b/veejay-current/veejay-server/libvje/effects/negatechannel.c @@ -0,0 +1,184 @@ +/* + * Linux VeeJay + * + * Copyright(C)2008 Niels Elburg + * + * 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 +#include +#include "negatechannel.h" + +vj_effect *negatechannel_init(int w, int h) +{ + vj_effect *ve = (vj_effect *) vj_calloc(sizeof(vj_effect)); + ve->num_params = 2; + + 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->limits[0][0] = 0; + ve->limits[1][0] = 2; + ve->limits[0][1] = 0; + ve->limits[1][2] = 0xff; + ve->defaults[0] = 0; + ve->defaults[1] = 0xff; + ve->description = "Negate a channel"; + ve->sub_format = 0; + ve->extra_frame = 0; + ve->has_user = 0; + ve->param_description = vje_build_param_list( ve->num_params, "Y=0, Cb=1, Cr=2", "Value" ); + return ve; +} + +#ifdef HAVE_ASM_MMX +#undef HAVE_K6_2PLUS +#if !defined( HAVE_ASM_MMX2) && defined( HAVE_ASM_3DNOW ) +#define HAVE_K6_2PLUS +#endif + +#undef _EMMS + +#ifdef HAVE_K6_2PLUS +/* On K6 femms is faster of emms. On K7 femms is directly mapped on emms. */ +#define _EMMS "femms" +#else +#define _EMMS "emms" +#endif +static inline void negate_mask(uint8_t val) +{ + uint8_t mask[8] = { val,val,val,val, val,val,val,val }; +// uint64_t mask = 0xffffffffffffffffLL; + uint8_t *m = (uint8_t*)&mask; + + __asm __volatile( + "movq (%0), %%mm4\n\t" + :: "r" (m) ); +} + +static inline void mmx_negate( uint8_t *dst, uint8_t *in ) +{ + __asm __volatile( + "movq (%0), %%mm0\n\t" + "movq %%mm4, %%mm1\n\t" + "psubb %%mm0, %%mm1\n\t" + "movq %%mm1, (%1)\n\t" + :: "r" (in) , "r" (dst) + ); +} + +#endif + +void negatechannel_apply( VJFrame *frame, int width, int height, int chan, int val) +{ + int i; + int len = (width * height); + int uv_len = frame->uv_len; + + uint8_t *Y = frame->data[0]; + uint8_t *Cb = frame->data[1]; + uint8_t *Cr = frame->data[2]; + +#ifndef HAVE_ASM_MMX + switch( chan ) { + case 0: + for (i = 0; i < len; i++) { + *(Y) = val - *(Y); + *(Y)++; + } + break; + case 1: + + for (i = 0; i < uv_len; i++) { + *(Cb) = val - *(Cb); + *(Cb)++; + } + break; + case 2: + for (i = 0; i < uv_len; i++) { + *(Cr) = val - *(Cr); + *(Cr)++; + } + break; + } + +#else + + int left = len % 8; + int work= len >> 3; + + negate_mask(val); + + switch( chan ) { + case 0: + for( i = 0; i < work ; i ++ ) + { + mmx_negate( Y, Y ); + Y += 8; + } + + if (left ) + { + for( i = 0; i < left; i ++ ) + { + *(Y) = val - *(Y); + *(Y)++; + } + } + break; + case 1: + + work = uv_len >> 3; + left = uv_len % 8; + for( i = 0; i < work ; i ++ ) + { + mmx_negate( Cb, Cb ); + Cr += 8; + } + + if(left ) + { + for( i = 0; i < left; i ++ ) + { + *(Cb) = val - *(Cb); + *(Cb)++; + } + } + break; + case 2: + work = uv_len >> 3; + left = uv_len % 8; + for( i = 0; i < work ; i ++ ) + { + mmx_negate( Cr, Cr ); + Cr += 8; + } + + if(left ) + { + for( i = 0; i < left; i ++ ) + { + *(Cr) = val - *(Cr); + *(Cr)++; + } + } + break; + } + + __asm__ __volatile__ ( _EMMS:::"memory"); + +#endif +} diff --git a/veejay-current/veejay-server/libvje/effects/negatechannel.h b/veejay-current/veejay-server/libvje/effects/negatechannel.h new file mode 100644 index 00000000..d0446dd9 --- /dev/null +++ b/veejay-current/veejay-server/libvje/effects/negatechannel.h @@ -0,0 +1,29 @@ +/* + * Linux VeeJay + * + * Copyright(C)2008 Niels Elburg + * + * 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 CHANNELNEGATION_H +#define CHANNELNEGATION_H +#include +#include +#include + +vj_effect *negatechannel_init(int w, int h); +void negatechannel_apply( VJFrame *frame, int width, int height,int chan, int val); +#endif diff --git a/veejay-current/veejay-server/libvje/internal.h b/veejay-current/veejay-server/libvje/internal.h index c18da3e1..06ca85e6 100644 --- a/veejay-current/veejay-server/libvje/internal.h +++ b/veejay-current/veejay-server/libvje/internal.h @@ -212,11 +212,12 @@ enum { VJ_IMAGE_EFFECT_CONTOUR = 188, VJ_IMAGE_EFFECT_LENSCORRECTION = 189, VJ_IMAGE_EFFECT_BGSUBTRACT = 190, + VJ_IMAGE_EFFECT_NEGATECHANNEL = 191, VJ_IMAGE_EFFECT_DUMMY=100, }; #define VJ_IMAGE_EFFECT_MIN 100 -#define VJ_IMAGE_EFFECT_MAX 191 +#define VJ_IMAGE_EFFECT_MAX 192 #define VJ_VIDEO_EFFECT_MIN 200 #define VJ_VIDEO_EFFECT_MAX 246 @@ -288,6 +289,9 @@ extern void mirrors2_apply( VJFrame *frame, int width, int height, int type); extern void negation_apply( VJFrame *frame, int width, int height, int val); +extern void negatechannel_apply( VJFrame *frame, int width, int height, + int chan, int val); + extern void colormap_apply( VJFrame *frame, int width, int height, int r, int g, int b); extern void opacity_apply(VJFrame *frame, VJFrame *frame2, int width, diff --git a/veejay-current/veejay-server/libvje/vj-effect.c b/veejay-current/veejay-server/libvje/vj-effect.c index 47c7a123..59816f7c 100644 --- a/veejay-current/veejay-server/libvje/vj-effect.c +++ b/veejay-current/veejay-server/libvje/vj-effect.c @@ -28,6 +28,7 @@ #include "effects/fibdownscale.h" #include "effects/magicoverlays.h" #include "effects/negation.h" +#include "effects/negatechannel.h" #include "effects/radcor.h" #include "effects/opacity.h" #include "effects/posterize.h" @@ -597,6 +598,8 @@ void vj_effect_initialize(int width, int height, int full_range) vj_effects[i + 49] = waterrippletv_init(width,height); vj_effects[i + 89 ]= radcor_init(width,height); vj_effects[i + 90 ]= bgsubtract_init(width,height); + vj_effects[i + 91 ]= negatechannel_init(width,height); + max_width = width; max_height = height; diff --git a/veejay-current/veejay-server/libvje/vj-effman.c b/veejay-current/veejay-server/libvje/vj-effman.c index bddf099e..563f879f 100644 --- a/veejay-current/veejay-server/libvje/vj-effman.c +++ b/veejay-current/veejay-server/libvje/vj-effman.c @@ -257,6 +257,10 @@ void vj_effman_apply_image_effect( case VJ_IMAGE_EFFECT_NEGATION: negation_apply(frames[0], frameinfo->width, frameinfo->height, arg[0]); break; + case VJ_IMAGE_EFFECT_NEGATECHANNEL: + negatechannel_apply(frames[0], frameinfo->width, frameinfo->height, arg[0],arg[1]); + break; + case VJ_IMAGE_EFFECT_COLFLASH: colflash_apply(frames[0], frameinfo->width,frameinfo->height,arg[0], arg[1],arg[2],arg[3],arg[4] ); diff --git a/veejay-current/veejay-server/libvje/vje.h b/veejay-current/veejay-server/libvje/vje.h index 7c85095d..84bb2f35 100644 --- a/veejay-current/veejay-server/libvje/vje.h +++ b/veejay-current/veejay-server/libvje/vje.h @@ -22,7 +22,7 @@ #define FX_LIMIT 1024 -#define MAX_EFFECTS 137 +#define MAX_EFFECTS 138 #define PARAM_WIDTH (1<<0x2) #define PARAM_HEIGHT (1<<0x3) #define PARAM_FADER (1<<0x1)