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

@ -455,15 +455,18 @@ Image *Image::HighlightEdges( Rgb colour, const Box *limits )
{ {
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;
@ -1734,6 +1737,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;
int hi_x = limits?limits->Hi().X():width-1; int hi_x = limits?limits->Hi().X():width-1;
@ -1789,6 +1795,10 @@ void Image::Outline( Rgb colour, const Polygon &polygon )
{ {
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++ )
{ {
@ -1895,6 +1905,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;
Edge global_edges[n_coords]; Edge global_edges[n_coords];
@ -2336,10 +2349,12 @@ 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;
if(current_blendpercent != blendpercent) {
/* Attempt to match the blending percent to one of the possible values */ /* Attempt to match the blending percent to one of the possible values */
if(blendpercent < 2.34375) { if(blendpercent < 2.34375) {
// 1.5625% blending // 1.5625% blending
@ -2366,6 +2381,8 @@ __attribute__ ((noinline)) void sse2_fastblend(const uint8_t* col1, const uint8_
divider = 1; divider = 1;
clearmask = 0x7F7F7F7F; clearmask = 0x7F7F7F7F;
} }
current_blendpercent = blendpercent;
}
__asm__ __volatile__( __asm__ __volatile__(
"movd %5, %%xmm3\n\t" "movd %5, %%xmm3\n\t"
@ -2395,8 +2412,10 @@ __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;
if(current_blendpercent != blendpercent) {
/* Attempt to match the blending percent to one of the possible values */ /* Attempt to match the blending percent to one of the possible values */
if(blendpercent < 2.34375) { if(blendpercent < 2.34375) {
// 1.5625% blending // 1.5625% blending
@ -2417,6 +2436,9 @@ __attribute__ ((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t
// 50% blending // 50% blending
divider = 1; 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,6 +375,7 @@ 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 {
if( capture )
Warning("Unable to find a match for the selected palette and target colourspace. Conversion required, performance penalty expected"); 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 */
@ -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,6 +1021,7 @@ void LocalCamera::Terminate()
av_free(tmpPicture); av_free(tmpPicture);
tmpPicture = NULL; tmpPicture = NULL;
} }
#endif
} }
@ -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,10 +34,10 @@ 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)