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:
parent
f2aaeb78e0
commit
37cc9199b2
144
src/zm_image.cpp
144
src/zm_image.cpp
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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++ )
|
||||||
{
|
{
|
||||||
|
@ -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,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,29 +2412,34 @@ __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(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
|
||||||
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
|
divider = 6;
|
||||||
// 3.125% blending
|
} else if(blendpercent >= 2.34375 && blendpercent < 4.6875) {
|
||||||
divider = 5;
|
// 3.125% blending
|
||||||
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
|
divider = 5;
|
||||||
// 6.25% blending
|
} else if(blendpercent >= 4.6875 && blendpercent < 9.375) {
|
||||||
divider = 4;
|
// 6.25% blending
|
||||||
} else if(blendpercent >= 9.375 && blendpercent < 18.75) {
|
divider = 4;
|
||||||
// 12.5% blending
|
} else if(blendpercent >= 9.375 && blendpercent < 18.75) {
|
||||||
divider = 3;
|
// 12.5% blending
|
||||||
} else if(blendpercent >= 18.75 && blendpercent < 37.5) {
|
divider = 3;
|
||||||
// 25% blending
|
} else if(blendpercent >= 18.75 && blendpercent < 37.5) {
|
||||||
divider = 2;
|
// 25% blending
|
||||||
} else if(blendpercent >= 37.5) {
|
divider = 2;
|
||||||
// 50% blending
|
} else if(blendpercent >= 37.5) {
|
||||||
divider = 1;
|
// 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];
|
||||||
result[1] = ((col2[1] - col1[1])>>divider) + col1[1];
|
result[1] = ((col2[1] - col1[1])>>divider) + col1[1];
|
||||||
|
|
|
@ -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,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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
16
src/zm_rgb.h
16
src/zm_rgb.h
|
@ -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))
|
||||||
|
|
Loading…
Reference in New Issue