Few changes:

1) Fixed buffer overflow occurring if JPEG quality is set to 100.
2) Changed linked monitors alarm behaviour again.
3) Fixed extremely poor blend performance on some processors such as the Intel Atom.
4) Added optional profiling code for Blend() and Delta().
pull/49/head
Kfir Itzhak 2012-02-09 12:23:45 +02:00
parent 1f072b1a62
commit 115db01f8c
4 changed files with 65 additions and 8 deletions

View File

@ -34,7 +34,7 @@ static short *g_u_table;
static short *b_u_table; static short *b_u_table;
__attribute__((aligned(16))) static const uint8_t movemask[16] = {0,4,8,12,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; __attribute__((aligned(16))) static const uint8_t movemask[16] = {0,4,8,12,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
jpeg_compress_struct *Image::jpg_ccinfo[100] = { 0 }; jpeg_compress_struct *Image::jpg_ccinfo[101] = { 0 };
jpeg_decompress_struct *Image::jpg_dcinfo = 0; jpeg_decompress_struct *Image::jpg_dcinfo = 0;
struct zm_error_mgr Image::jpg_err; struct zm_error_mgr Image::jpg_err;
@ -1421,15 +1421,40 @@ void Image::Overlay( const Image &image, int x, int y )
void Image::Blend( const Image &image, int transparency ) void Image::Blend( const Image &image, int transparency )
{ {
#ifdef ZM_IMAGE_PROFILING
struct timespec start,end,diff;
unsigned long long executetime;
unsigned long milpixels;
#endif
uint8_t* new_buffer;
if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) ) if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == 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 ); 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(transparency > 0) { if(transparency <= 0)
return;
new_buffer = AllocBuffer(size);
#ifdef ZM_IMAGE_PROFILING
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start);
#endif
/* Do the blending */ /* Do the blending */
(*fptr_blend)(buffer, image.buffer, buffer, size, transparency); (*fptr_blend)(buffer, image.buffer, new_buffer, size, transparency);
}
#ifdef ZM_IMAGE_PROFILING
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end);
timespec_diff(&start,&end,&diff);
executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec;
milpixels = (unsigned long)((long double)size)/((((long double)executetime)/1000));
Debug(5, "Blend: %u colours blended in %llu nanoseconds, %lu million colours/s\n",size,executetime,milpixels);
#endif
AssignDirect( width, height, colours, subpixelorder, new_buffer, size, ZM_BUFTYPE_ZM);
} }
Image *Image::Merge( int n_images, Image *images[] ) Image *Image::Merge( int n_images, Image *images[] )
@ -1544,6 +1569,12 @@ Image *Image::Highlight( int n_images, Image *images[], const Rgb threshold, con
/* New function to allow buffer re-using instead of allocationg memory for the delta image everytime */ /* New function to allow buffer re-using instead of allocationg memory for the delta image everytime */
void Image::Delta( const Image &image, Image* targetimage) const void Image::Delta( const Image &image, Image* targetimage) const
{ {
#ifdef ZM_IMAGE_PROFILING
struct timespec start,end,diff;
unsigned long long executetime;
unsigned long milpixels;
#endif
if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) ) if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) )
{ {
Panic( "Attempt to get delta of 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 get delta of 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);
@ -1555,6 +1586,10 @@ void Image::Delta( const Image &image, Image* targetimage) const
Panic("Failed requesting writeable buffer for storing the delta image"); Panic("Failed requesting writeable buffer for storing the delta image");
} }
#ifdef ZM_IMAGE_PROFILING
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start);
#endif
switch(colours) { switch(colours) {
case ZM_COLOUR_RGB24: case ZM_COLOUR_RGB24:
{ {
@ -1591,6 +1626,15 @@ void Image::Delta( const Image &image, Image* targetimage) const
Panic("Delta called with unexpected colours: %d",colours); Panic("Delta called with unexpected colours: %d",colours);
break; break;
} }
#ifdef ZM_IMAGE_PROFILING
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end);
timespec_diff(&start,&end,&diff);
executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec;
milpixels = (unsigned long)((long double)pixels)/((((long double)executetime)/1000));
Debug(5, "Delta: %u delta pixels generated in %llu nanoseconds, %lu million pixels/s\n",pixels,executetime,milpixels);
#endif
} }
const Coord Image::centreCoord( const char *text ) const const Coord Image::centreCoord( const char *text ) const

View File

@ -224,7 +224,7 @@ bool Monitor::MonitorLink::inAlarm()
bool Monitor::MonitorLink::hasAlarmed() bool Monitor::MonitorLink::hasAlarmed()
{ {
if ( shared_data->state == ALARM || shared_data->state == ALERT ) if ( shared_data->state == ALARM )
{ {
return( true ); return( true );
} }
@ -1278,7 +1278,7 @@ bool Monitor::Analyse()
{ {
if ( linked_monitors[i]->isConnected() ) if ( linked_monitors[i]->isConnected() )
{ {
if ( linked_monitors[i]->isAlarmed() ) if ( linked_monitors[i]->hasAlarmed() )
{ {
if ( !event ) if ( !event )
{ {

View File

@ -241,3 +241,13 @@ __attribute__((noinline,__target__("sse2"))) void* sse2_aligned_memcpy(void* des
return dest; return dest;
} }
void timespec_diff(struct timespec *start, struct timespec *end, struct timespec *diff) {
if (((end->tv_nsec)-(start->tv_nsec))<0) {
diff->tv_sec = end->tv_sec-start->tv_sec-1;
diff->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec;
} else {
diff->tv_sec = end->tv_sec-start->tv_sec;
diff->tv_nsec = end->tv_nsec-start->tv_nsec;
}
}

View File

@ -20,6 +20,8 @@
#ifndef ZM_UTILS_H #ifndef ZM_UTILS_H
#define ZM_UTILS_H #define ZM_UTILS_H
#include <time.h>
#include <sys/time.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -45,6 +47,7 @@ inline int min( int a, int b )
void ssedetect(); void ssedetect();
void* sse2_aligned_memcpy(void* dest, const void* src, size_t bytes); void* sse2_aligned_memcpy(void* dest, const void* src, size_t bytes);
void timespec_diff(struct timespec *start, struct timespec *end, struct timespec *diff);
extern unsigned int sseversion; extern unsigned int sseversion;