From 37cc9199b221ad5585d842e3658c5ed048493ca4 Mon Sep 17 00:00:00 2001 From: Kfir Itzhak Date: Sat, 7 May 2011 18:39:16 +0300 Subject: [PATCH] 1) Changed ZM static colours to RGB order instead of HTML(BGR) order 2) Allow ZM to compile without swscale - hopefully 3) Saved few cpu cycles during image blending 4) Fixed wrong zone colours showing up 5) Unrelated fix: Allow ZM to be compiled with the latest ffmpeg revisions --- src/zm_image.cpp | 148 +++++++++++++++++++++++----------------- src/zm_local_camera.cpp | 14 ++-- src/zm_mpeg.cpp | 2 +- src/zm_rgb.h | 16 ++--- 4 files changed, 103 insertions(+), 77 deletions(-) diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 749b4141d..af5c0133e 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -451,19 +451,22 @@ void Image::Assign( const Image &image ) { Image *Image::HighlightEdges( Rgb colour, const Box *limits ) { - if ( colours != 1 ) - { - Panic( "Attempt to highlight image edges when colours = %d", colours ); - } - Image *high_image = new Image( width, height, 3, ZM_SUBPIX_ORDER_RGB); + if ( colours != 1 ) + { + Panic( "Attempt to highlight image edges when colours = %d", colours ); + } + + Image *high_image = new Image( width, height, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB); + uint8_t* high_buff = high_image->WriteBuffer(width, height, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB); + int lo_x = limits?limits->Lo().X():0; int lo_y = limits?limits->Lo().Y():0; int hi_x = limits?limits->Hi().X():width-1; int hi_y = limits?limits->Hi().Y():height-1; for ( int y = lo_y; y <= hi_y; y++ ) { - unsigned char *p = &buffer[(y*width)+lo_x]; - unsigned char *phigh = (uint8_t*)high_image->Buffer( lo_x, y ); + uint8_t *p = &buffer[(y*width)+lo_x]; + uint8_t *phigh = high_buff + ( lo_x * y ); for ( int x = lo_x; x <= hi_x; x++, p++, phigh += 3 ) { bool edge = false; @@ -1209,10 +1212,6 @@ void Image::Blend( const Image &image, int transparency ) const Panic( "Attempt to blend different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, image.width, image.height, image.colours, image.subpixelorder ); } - if((size % 16) != 0) { - Warning("Image size is not multiples of 16"); - } - /* Do the blending */ (*fptr_blend)(buffer, image.buffer, buffer, size, transparency); } @@ -1678,6 +1677,10 @@ void Image::Fill( Rgb colour, const Box *limits ) { Panic( "Attempt to fill image with unexpected colours %d", colours ); } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + colour = rgb_convert(colour,subpixelorder); + int lo_x = limits?limits->Lo().X():0; int lo_y = limits?limits->Lo().Y():0; int hi_x = limits?limits->Hi().X():width-1; @@ -1733,6 +1736,9 @@ void Image::Fill( Rgb colour, int density, const Box *limits ) { Panic( "Attempt to fill image with unexpected colours %d", colours ); } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + colour = rgb_convert(colour,subpixelorder); int lo_x = limits?limits->Lo().X():0; int lo_y = limits?limits->Lo().Y():0; @@ -1786,9 +1792,13 @@ void Image::Fill( Rgb colour, int density, const Box *limits ) void Image::Outline( Rgb colour, const Polygon &polygon ) { if ( !(colours == 1 || colours == 3 || colours == 4 ) ) - { - Panic( "Attempt to outline image with unexpected colours %d", colours ); - } + { + Panic( "Attempt to outline image with unexpected colours %d", colours ); + } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + colour = rgb_convert(colour,subpixelorder); + int n_coords = polygon.getNumCoords(); for ( int j = 0, i = n_coords-1; j < n_coords; i = j++ ) { @@ -1894,6 +1904,9 @@ void Image::Fill( Rgb colour, int density, const Polygon &polygon ) { Panic( "Attempt to fill image with unexpected colours %d", colours ); } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + colour = rgb_convert(colour,subpixelorder); int n_coords = polygon.getNumCoords(); int n_global_edges = 0; @@ -2336,35 +2349,39 @@ void Image::Scale( unsigned int factor ) __attribute__ ((noinline)) void sse2_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) { #if (defined(__i386__) || defined(__x86_64__)) - int divider = 0; - uint32_t clearmask = 0; + static uint32_t divider = 0; + static uint32_t clearmask = 0; + static double current_blendpercent = 0.0; unsigned long i = 0; - - /* Attempt to match the blending percent to one of the possible values */ - if(blendpercent < 2.34375) { - // 1.5625% blending - divider = 6; - clearmask = 0x03030303; - } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { - // 3.125% blending - divider = 5; - clearmask = 0x07070707; - } else if(blendpercent >= 4.6875 && blendpercent < 9.375) { - // 6.25% blending - divider = 4; - clearmask = 0x0F0F0F0F; - } else if(blendpercent >= 9.375 && blendpercent < 18.75) { - // 12.5% blending - divider = 3; - clearmask = 0x1F1F1F1F; - } else if(blendpercent >= 18.75 && blendpercent < 37.5) { - // 25% blending - divider = 2; - clearmask = 0x3F3F3F3F; - } else if(blendpercent >= 37.5) { - // 50% blending - divider = 1; - clearmask = 0x7F7F7F7F; + + if(current_blendpercent != blendpercent) { + /* Attempt to match the blending percent to one of the possible values */ + if(blendpercent < 2.34375) { + // 1.5625% blending + divider = 6; + clearmask = 0x03030303; + } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { + // 3.125% blending + divider = 5; + clearmask = 0x07070707; + } else if(blendpercent >= 4.6875 && blendpercent < 9.375) { + // 6.25% blending + divider = 4; + clearmask = 0x0F0F0F0F; + } else if(blendpercent >= 9.375 && blendpercent < 18.75) { + // 12.5% blending + divider = 3; + clearmask = 0x1F1F1F1F; + } else if(blendpercent >= 18.75 && blendpercent < 37.5) { + // 25% blending + divider = 2; + clearmask = 0x3F3F3F3F; + } else if(blendpercent >= 37.5) { + // 50% blending + divider = 1; + clearmask = 0x7F7F7F7F; + } + current_blendpercent = blendpercent; } __asm__ __volatile__( @@ -2395,28 +2412,33 @@ __attribute__ ((noinline)) void sse2_fastblend(const uint8_t* col1, const uint8_ } __attribute__ ((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) { - int divider = 0; - - /* Attempt to match the blending percent to one of the possible values */ - if(blendpercent < 2.34375) { - // 1.5625% blending - divider = 6; - } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { - // 3.125% blending - divider = 5; - } else if(blendpercent >= 4.6875 && blendpercent < 9.375) { - // 6.25% blending - divider = 4; - } else if(blendpercent >= 9.375 && blendpercent < 18.75) { - // 12.5% blending - divider = 3; - } else if(blendpercent >= 18.75 && blendpercent < 37.5) { - // 25% blending - divider = 2; - } else if(blendpercent >= 37.5) { - // 50% blending - divider = 1; + static int divider = 0; + static double current_blendpercent = 0.0; + + if(current_blendpercent != blendpercent) { + /* Attempt to match the blending percent to one of the possible values */ + if(blendpercent < 2.34375) { + // 1.5625% blending + divider = 6; + } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { + // 3.125% blending + divider = 5; + } else if(blendpercent >= 4.6875 && blendpercent < 9.375) { + // 6.25% blending + divider = 4; + } else if(blendpercent >= 9.375 && blendpercent < 18.75) { + // 12.5% blending + divider = 3; + } else if(blendpercent >= 18.75 && blendpercent < 37.5) { + // 25% blending + divider = 2; + } else if(blendpercent >= 37.5) { + // 50% blending + divider = 1; + } + current_blendpercent = blendpercent; } + for(register unsigned long i=0; i < count; i += 16, col1 += 16, col2 += 16, result += 16) { result[0] = ((col2[0] - col1[0])>>divider) + col1[0]; diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 7d20053f8..63c1188d1 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -375,7 +375,8 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, subpixelorder = ZM_SUBPIX_ORDER_NONE; /* Unable to find a solution for the selected palette and target colourspace. Conversion required. Notify the user of performance penalty */ } else { - Warning("Unable to find a match for the selected palette and target colourspace. Conversion required, performance penalty expected"); + if( capture ) + Warning("Unable to find a match for the selected palette and target colourspace. Conversion required, performance penalty expected"); #if HAVE_LIBSWSCALE /* Try using swscale for the conversion */ conversion_type = 1; @@ -1011,6 +1012,7 @@ void LocalCamera::Terminate() close( vid_fd ); +#if HAVE_LIBSWSCALE /* Clean up swscale stuff */ if(conversion_type == 1) { sws_freeContext(imgConversionContext); @@ -1019,7 +1021,8 @@ void LocalCamera::Terminate() av_free(tmpPicture); tmpPicture = NULL; } - +#endif + } #define capString(test,prefix,yesString,noString,capability) \ @@ -1914,15 +1917,16 @@ int LocalCamera::Capture( Image &image ) Error("Failed requesting writeable buffer for the captured image."); return (-1); } - +#if HAVE_LIBSWSCALE if(conversion_type == 1) { /* Use swscale to convert the image directly into the shared memory */ avpicture_fill( (AVPicture *)tmpPicture, directbuffer, imagePixFormat, width, height ); sws_scale( imgConversionContext, capturePictures[capture_frame]->data, capturePictures[capture_frame]->linesize, 0, height, tmpPicture->data, tmpPicture->linesize ); - - } else if(conversion_type == 2) { + } +#endif + if(conversion_type == 2) { /* Call the image conversion function and convert directly into the shared memory */ (*conversion_fptr)(buffer, directbuffer, pixels); diff --git a/src/zm_mpeg.cpp b/src/zm_mpeg.cpp index ca06449df..ff5ba944d 100644 --- a/src/zm_mpeg.cpp +++ b/src/zm_mpeg.cpp @@ -337,7 +337,7 @@ double VideoStream::EncodeFrame( const uint8_t *buffer, int buffer_size, bool ad } sws_scale( img_convert_ctx, tmp_opicture->data, tmp_opicture->linesize, 0, c->height, opicture->data, opicture->linesize ); #else // HAVE_LIBSWSCALE - img_convert( (AVPicture *)opicture, c->pix_fmt, (AVPicture *)tmp_opicture, pf, c->width, c->height ); + Fatal("swscale is required for MPEG mode"); #endif // HAVE_LIBSWSCALE } else diff --git a/src/zm_rgb.h b/src/zm_rgb.h index 64af4b975..5694eff19 100644 --- a/src/zm_rgb.h +++ b/src/zm_rgb.h @@ -34,11 +34,11 @@ typedef uint32_t Rgb; // RGB colour type #define RGB_WHITE (0x00ffffff) #define RGB_BLACK (0x00000000) -#define RGB_RED (0x00ff0000) +#define RGB_RED (0x000000ff) #define RGB_GREEN (0x0000ff00) -#define RGB_BLUE (0x000000ff) -#define RGB_ORANGE (0x00ffa500) -#define RGB_PURPLE (0x00800080) +#define RGB_BLUE (0x00ff0000) +#define RGB_ORANGE (0x0000a5ff) +#define RGB_PURPLE (0x00800080) #define RGB_TRANSPARENT (0x01000000) #define RGB_VAL(v,c) (((v)>>(16-((c)*8)))&0xff) @@ -46,7 +46,7 @@ typedef uint32_t Rgb; // RGB colour type /* RGB or RGBA macros */ #define BLUE_VAL_RGBA(v) (((v)>>16)&0xff) #define GREEN_VAL_RGBA(v) (((v)>>8)&0xff) -#define RED_VAL_RGBA(v) ((v)&0xff) +#define RED_VAL_RGBA(v) ((v)&0xff) #define ALPHA_VAL_RGBA(v) ((v)>>24)&0xff) #define RED_PTR_RGBA(ptr) (*((uint8_t*)ptr)) #define GREEN_PTR_RGBA(ptr) (*((uint8_t*)ptr+1)) @@ -54,7 +54,7 @@ typedef uint32_t Rgb; // RGB colour type #define ALPHA_PTR_RGBA(ptr) (*((uint8_t*)ptr+3)) /* BGR or BGRA */ -#define RED_VAL_BGRA(v) (((v)>>16)&0xff) +#define RED_VAL_BGRA(v) (((v)>>16)&0xff) #define GREEN_VAL_BGRA(v) (((v)>>8)&0xff) #define BLUE_VAL_BGRA(v) ((v)&0xff) #define ALPHA_VAL_BGRA(v) ((v)>>24)&0xff) @@ -66,7 +66,7 @@ typedef uint32_t Rgb; // RGB colour type /* ARGB */ #define BLUE_VAL_ARGB(v) (((v)>>24)&0xff) #define GREEN_VAL_ARGB(v) (((v)>>16)&0xff) -#define RED_VAL_ARGB(v) (((v)>>8)&0xff) +#define RED_VAL_ARGB(v) (((v)>>8)&0xff) #define ALPHA_VAL_ARGB(v) ((v)&0xff) #define RED_PTR_ARGB(ptr) (*((uint8_t*)ptr+1)) #define GREEN_PTR_ARGB(ptr) (*((uint8_t*)ptr+2)) @@ -76,7 +76,7 @@ typedef uint32_t Rgb; // RGB colour type /* ABGR */ #define BLUE_VAL_ABGR(v) (((v)>>8)&0xff) #define GREEN_VAL_ABGR(v) (((v)>>16)&0xff) -#define RED_VAL_ABGR(v) (((v)>>24)&0xff) +#define RED_VAL_ABGR(v) (((v)>>24)&0xff) #define ALPHA_VAL_ABGR(v) ((v)&0xff) #define RED_PTR_ABGR(ptr) (*((uint8_t*)ptr+3)) #define GREEN_PTR_ABGR(ptr) (*((uint8_t*)ptr+2))