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
This commit is contained in:
Kfir Itzhak 2011-05-07 18:39:16 +03:00
parent f2aaeb78e0
commit 37cc9199b2
4 changed files with 103 additions and 77 deletions

View File

@ -451,19 +451,22 @@ void Image::Assign( const Image &image ) {
Image *Image::HighlightEdges( Rgb colour, const Box *limits ) Image *Image::HighlightEdges( Rgb colour, const Box *limits )
{ {
if ( colours != 1 ) if ( colours != 1 )
{ {
Panic( "Attempt to highlight image edges when colours = %d", colours ); Panic( "Attempt to highlight image edges when colours = %d", colours );
} }
Image *high_image = new Image( width, height, 3, ZM_SUBPIX_ORDER_RGB);
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_x = limits?limits->Lo().X():0;
int lo_y = limits?limits->Lo().Y():0; int lo_y = limits?limits->Lo().Y():0;
int hi_x = limits?limits->Hi().X():width-1; int hi_x = limits?limits->Hi().X():width-1;
int hi_y = limits?limits->Hi().Y():height-1; int hi_y = limits?limits->Hi().Y():height-1;
for ( int y = lo_y; y <= hi_y; y++ ) for ( int y = lo_y; y <= hi_y; y++ )
{ {
unsigned char *p = &buffer[(y*width)+lo_x]; uint8_t *p = &buffer[(y*width)+lo_x];
unsigned char *phigh = (uint8_t*)high_image->Buffer( lo_x, y ); uint8_t *phigh = high_buff + ( lo_x * y );
for ( int x = lo_x; x <= hi_x; x++, p++, phigh += 3 ) for ( int x = lo_x; x <= hi_x; x++, p++, phigh += 3 )
{ {
bool edge = false; 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 ); 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 */ /* Do the blending */
(*fptr_blend)(buffer, image.buffer, buffer, size, transparency); (*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 ); 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_x = limits?limits->Lo().X():0;
int lo_y = limits?limits->Lo().Y():0; int lo_y = limits?limits->Lo().Y():0;
int hi_x = limits?limits->Hi().X():width-1; 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 ); 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_x = limits?limits->Lo().X():0;
int lo_y = limits?limits->Lo().Y():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 ) void Image::Outline( Rgb colour, const Polygon &polygon )
{ {
if ( !(colours == 1 || colours == 3 || colours == 4 ) ) 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(); int n_coords = polygon.getNumCoords();
for ( int j = 0, i = n_coords-1; j < n_coords; i = j++ ) 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 ); 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_coords = polygon.getNumCoords();
int n_global_edges = 0; 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) { __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__)) #if (defined(__i386__) || defined(__x86_64__))
int divider = 0; static uint32_t divider = 0;
uint32_t clearmask = 0; static uint32_t clearmask = 0;
static double current_blendpercent = 0.0;
unsigned long i = 0; unsigned long i = 0;
/* Attempt to match the blending percent to one of the possible values */ if(current_blendpercent != blendpercent) {
if(blendpercent < 2.34375) { /* Attempt to match the blending percent to one of the possible values */
// 1.5625% blending if(blendpercent < 2.34375) {
divider = 6; // 1.5625% blending
clearmask = 0x03030303; divider = 6;
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { clearmask = 0x03030303;
// 3.125% blending } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
divider = 5; // 3.125% blending
clearmask = 0x07070707; divider = 5;
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) { clearmask = 0x07070707;
// 6.25% blending } else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
divider = 4; // 6.25% blending
clearmask = 0x0F0F0F0F; divider = 4;
} else if(blendpercent >= 9.375 && blendpercent < 18.75) { clearmask = 0x0F0F0F0F;
// 12.5% blending } else if(blendpercent >= 9.375 && blendpercent < 18.75) {
divider = 3; // 12.5% blending
clearmask = 0x1F1F1F1F; divider = 3;
} else if(blendpercent >= 18.75 && blendpercent < 37.5) { clearmask = 0x1F1F1F1F;
// 25% blending } else if(blendpercent >= 18.75 && blendpercent < 37.5) {
divider = 2; // 25% blending
clearmask = 0x3F3F3F3F; divider = 2;
} else if(blendpercent >= 37.5) { clearmask = 0x3F3F3F3F;
// 50% blending } else if(blendpercent >= 37.5) {
divider = 1; // 50% blending
clearmask = 0x7F7F7F7F; divider = 1;
clearmask = 0x7F7F7F7F;
}
current_blendpercent = blendpercent;
} }
__asm__ __volatile__( __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) { __attribute__ ((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) {
int divider = 0; static int divider = 0;
static double current_blendpercent = 0.0;
/* Attempt to match the blending percent to one of the possible values */
if(blendpercent < 2.34375) { if(current_blendpercent != blendpercent) {
// 1.5625% blending /* Attempt to match the blending percent to one of the possible values */
divider = 6; if(blendpercent < 2.34375) {
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) { // 1.5625% blending
// 3.125% blending divider = 6;
divider = 5; } else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) { // 3.125% blending
// 6.25% blending divider = 5;
divider = 4; } else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
} else if(blendpercent >= 9.375 && blendpercent < 18.75) { // 6.25% blending
// 12.5% blending divider = 4;
divider = 3; } else if(blendpercent >= 9.375 && blendpercent < 18.75) {
} else if(blendpercent >= 18.75 && blendpercent < 37.5) { // 12.5% blending
// 25% blending divider = 3;
divider = 2; } else if(blendpercent >= 18.75 && blendpercent < 37.5) {
} else if(blendpercent >= 37.5) { // 25% blending
// 50% blending divider = 2;
divider = 1; } 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) { 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]; result[0] = ((col2[0] - col1[0])>>divider) + col1[0];

View File

@ -375,7 +375,8 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel,
subpixelorder = ZM_SUBPIX_ORDER_NONE; 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 */ /* Unable to find a solution for the selected palette and target colourspace. Conversion required. Notify the user of performance penalty */
} else { } 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 #if HAVE_LIBSWSCALE
/* Try using swscale for the conversion */ /* Try using swscale for the conversion */
conversion_type = 1; conversion_type = 1;
@ -1011,6 +1012,7 @@ void LocalCamera::Terminate()
close( vid_fd ); close( vid_fd );
#if HAVE_LIBSWSCALE
/* Clean up swscale stuff */ /* Clean up swscale stuff */
if(conversion_type == 1) { if(conversion_type == 1) {
sws_freeContext(imgConversionContext); sws_freeContext(imgConversionContext);
@ -1019,7 +1021,8 @@ void LocalCamera::Terminate()
av_free(tmpPicture); av_free(tmpPicture);
tmpPicture = NULL; tmpPicture = NULL;
} }
#endif
} }
#define capString(test,prefix,yesString,noString,capability) \ #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."); Error("Failed requesting writeable buffer for the captured image.");
return (-1); return (-1);
} }
#if HAVE_LIBSWSCALE
if(conversion_type == 1) { if(conversion_type == 1) {
/* Use swscale to convert the image directly into the shared memory */ /* Use swscale to convert the image directly into the shared memory */
avpicture_fill( (AVPicture *)tmpPicture, directbuffer, imagePixFormat, width, height ); 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 ); 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 */ /* Call the image conversion function and convert directly into the shared memory */
(*conversion_fptr)(buffer, directbuffer, pixels); (*conversion_fptr)(buffer, directbuffer, pixels);

View File

@ -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 ); sws_scale( img_convert_ctx, tmp_opicture->data, tmp_opicture->linesize, 0, c->height, opicture->data, opicture->linesize );
#else // HAVE_LIBSWSCALE #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 #endif // HAVE_LIBSWSCALE
} }
else else

View File

@ -34,11 +34,11 @@ typedef uint32_t Rgb; // RGB colour type
#define RGB_WHITE (0x00ffffff) #define RGB_WHITE (0x00ffffff)
#define RGB_BLACK (0x00000000) #define RGB_BLACK (0x00000000)
#define RGB_RED (0x00ff0000) #define RGB_RED (0x000000ff)
#define RGB_GREEN (0x0000ff00) #define RGB_GREEN (0x0000ff00)
#define RGB_BLUE (0x000000ff) #define RGB_BLUE (0x00ff0000)
#define RGB_ORANGE (0x00ffa500) #define RGB_ORANGE (0x0000a5ff)
#define RGB_PURPLE (0x00800080) #define RGB_PURPLE (0x00800080)
#define RGB_TRANSPARENT (0x01000000) #define RGB_TRANSPARENT (0x01000000)
#define RGB_VAL(v,c) (((v)>>(16-((c)*8)))&0xff) #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 */ /* RGB or RGBA macros */
#define BLUE_VAL_RGBA(v) (((v)>>16)&0xff) #define BLUE_VAL_RGBA(v) (((v)>>16)&0xff)
#define GREEN_VAL_RGBA(v) (((v)>>8)&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 ALPHA_VAL_RGBA(v) ((v)>>24)&0xff)
#define RED_PTR_RGBA(ptr) (*((uint8_t*)ptr)) #define RED_PTR_RGBA(ptr) (*((uint8_t*)ptr))
#define GREEN_PTR_RGBA(ptr) (*((uint8_t*)ptr+1)) #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)) #define ALPHA_PTR_RGBA(ptr) (*((uint8_t*)ptr+3))
/* BGR or BGRA */ /* 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 GREEN_VAL_BGRA(v) (((v)>>8)&0xff)
#define BLUE_VAL_BGRA(v) ((v)&0xff) #define BLUE_VAL_BGRA(v) ((v)&0xff)
#define ALPHA_VAL_BGRA(v) ((v)>>24)&0xff) #define ALPHA_VAL_BGRA(v) ((v)>>24)&0xff)
@ -66,7 +66,7 @@ typedef uint32_t Rgb; // RGB colour type
/* ARGB */ /* ARGB */
#define BLUE_VAL_ARGB(v) (((v)>>24)&0xff) #define BLUE_VAL_ARGB(v) (((v)>>24)&0xff)
#define GREEN_VAL_ARGB(v) (((v)>>16)&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 ALPHA_VAL_ARGB(v) ((v)&0xff)
#define RED_PTR_ARGB(ptr) (*((uint8_t*)ptr+1)) #define RED_PTR_ARGB(ptr) (*((uint8_t*)ptr+1))
#define GREEN_PTR_ARGB(ptr) (*((uint8_t*)ptr+2)) #define GREEN_PTR_ARGB(ptr) (*((uint8_t*)ptr+2))
@ -76,7 +76,7 @@ typedef uint32_t Rgb; // RGB colour type
/* ABGR */ /* ABGR */
#define BLUE_VAL_ABGR(v) (((v)>>8)&0xff) #define BLUE_VAL_ABGR(v) (((v)>>8)&0xff)
#define GREEN_VAL_ABGR(v) (((v)>>16)&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 ALPHA_VAL_ABGR(v) ((v)&0xff)
#define RED_PTR_ABGR(ptr) (*((uint8_t*)ptr+3)) #define RED_PTR_ABGR(ptr) (*((uint8_t*)ptr+3))
#define GREEN_PTR_ABGR(ptr) (*((uint8_t*)ptr+2)) #define GREEN_PTR_ABGR(ptr) (*((uint8_t*)ptr+2))