|
|
|
@ -398,11 +398,11 @@ Monitor::Monitor(
|
|
|
|
|
+ 64; /* Padding used to permit aligning the images buffer to 16 byte boundary */
|
|
|
|
|
|
|
|
|
|
Debug( 1, "mem.size=%d", mem_size );
|
|
|
|
|
mem_ptr = NULL;
|
|
|
|
|
mem_ptr = NULL;
|
|
|
|
|
|
|
|
|
|
if ( purpose == CAPTURE ) {
|
|
|
|
|
this->connect();
|
|
|
|
|
if ( ! mem_ptr ) exit(-1);
|
|
|
|
|
this->connect();
|
|
|
|
|
if ( ! mem_ptr ) exit(-1);
|
|
|
|
|
memset( mem_ptr, 0, mem_size );
|
|
|
|
|
shared_data->size = sizeof(SharedData);
|
|
|
|
|
shared_data->active = enabled;
|
|
|
|
@ -429,8 +429,8 @@ Monitor::Monitor(
|
|
|
|
|
trigger_data->trigger_showtext[0] = 0;
|
|
|
|
|
shared_data->valid = true;
|
|
|
|
|
} else if ( purpose == ANALYSIS ) {
|
|
|
|
|
this->connect();
|
|
|
|
|
if ( ! mem_ptr ) exit(-1);
|
|
|
|
|
this->connect();
|
|
|
|
|
if ( ! mem_ptr ) exit(-1);
|
|
|
|
|
shared_data->state = IDLE;
|
|
|
|
|
shared_data->last_read_time = 0;
|
|
|
|
|
shared_data->alarm_x = -1;
|
|
|
|
@ -446,9 +446,9 @@ Monitor::Monitor(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Will this not happen every time a monitor is instantiated? Seems like all the calls to the Monitor constructor pass a zero for n_zones, then load zones after..
|
|
|
|
|
// Will this not happen every time a monitor is instantiated? Seems like all the calls to the Monitor constructor pass a zero for n_zones, then load zones after..
|
|
|
|
|
if ( !n_zones ) {
|
|
|
|
|
Debug( 1, "Monitor %s has no zones, adding one.", name );
|
|
|
|
|
Debug( 1, "Monitor %s has no zones, adding one.", name );
|
|
|
|
|
n_zones = 1;
|
|
|
|
|
zones = new Zone *[1];
|
|
|
|
|
Coord coords[4] = { Coord( 0, 0 ), Coord( width-1, 0 ), Coord( width-1, height-1 ), Coord( 0, height-1 ) };
|
|
|
|
@ -533,28 +533,28 @@ bool Monitor::connect() {
|
|
|
|
|
// Allocate the size
|
|
|
|
|
if ( ftruncate( map_fd, mem_size ) < 0 ) {
|
|
|
|
|
Fatal( "Can't extend memory map file %s to %d bytes: %s", mem_file, mem_size, strerror(errno) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if ( map_stat.st_size == 0 ) {
|
|
|
|
|
Error( "Got empty memory map file size %ld, is the zmc process for this monitor running?", map_stat.st_size, mem_size );
|
|
|
|
|
return false;
|
|
|
|
|
return false;
|
|
|
|
|
} else if ( map_stat.st_size != mem_size ) {
|
|
|
|
|
Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size );
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
#ifdef MAP_LOCKED
|
|
|
|
|
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0 );
|
|
|
|
|
if ( mem_ptr == MAP_FAILED ) {
|
|
|
|
|
if ( errno == EAGAIN ) {
|
|
|
|
|
Debug( 1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size );
|
|
|
|
|
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0 );
|
|
|
|
|
if ( mem_ptr == MAP_FAILED ) {
|
|
|
|
|
if ( errno == EAGAIN ) {
|
|
|
|
|
Debug( 1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size );
|
|
|
|
|
#endif
|
|
|
|
|
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 );
|
|
|
|
|
Debug( 1, "Mapped file %s (%d bytes) to locked memory, unlocked", mem_file, mem_size );
|
|
|
|
|
mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 );
|
|
|
|
|
Debug( 1, "Mapped file %s (%d bytes) to locked memory, unlocked", mem_file, mem_size );
|
|
|
|
|
#ifdef MAP_LOCKED
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if ( mem_ptr == MAP_FAILED )
|
|
|
|
|
Fatal( "Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno );
|
|
|
|
|
if ( mem_ptr == MAP_FAILED )
|
|
|
|
|
Fatal( "Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno );
|
|
|
|
|
}
|
|
|
|
|
#else // ZM_MEM_MAPPED
|
|
|
|
|
shm_id = shmget( (config.shm_key&0xffff0000)|id, mem_size, IPC_CREAT|0700 );
|
|
|
|
@ -575,9 +575,9 @@ bool Monitor::connect() {
|
|
|
|
|
unsigned char *shared_images = (unsigned char *)((char *)shared_timestamps + (image_buffer_count*sizeof(struct timeval)));
|
|
|
|
|
|
|
|
|
|
if(((unsigned long)shared_images % 16) != 0) {
|
|
|
|
|
/* Align images buffer to nearest 16 byte boundary */
|
|
|
|
|
Debug(3,"Aligning shared memory images to the next 16 byte boundary");
|
|
|
|
|
shared_images = (uint8_t*)((unsigned long)shared_images + (16 - ((unsigned long)shared_images % 16)));
|
|
|
|
|
/* Align images buffer to nearest 16 byte boundary */
|
|
|
|
|
Debug(3,"Aligning shared memory images to the next 16 byte boundary");
|
|
|
|
|
shared_images = (uint8_t*)((unsigned long)shared_images + (16 - ((unsigned long)shared_images % 16)));
|
|
|
|
|
}
|
|
|
|
|
image_buffer = new Snapshot[image_buffer_count];
|
|
|
|
|
for ( int i = 0; i < image_buffer_count; i++ )
|
|
|
|
@ -608,39 +608,39 @@ bool Monitor::connect() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Monitor::~Monitor()
|
|
|
|
|
{
|
|
|
|
|
if ( timestamps ) {
|
|
|
|
|
delete[] timestamps;
|
|
|
|
|
timestamps = 0;
|
|
|
|
|
}
|
|
|
|
|
if ( images ) {
|
|
|
|
|
delete[] images;
|
|
|
|
|
images = 0;
|
|
|
|
|
}
|
|
|
|
|
if ( timestamps ) {
|
|
|
|
|
delete[] timestamps;
|
|
|
|
|
timestamps = 0;
|
|
|
|
|
}
|
|
|
|
|
if ( images ) {
|
|
|
|
|
delete[] images;
|
|
|
|
|
images = 0;
|
|
|
|
|
}
|
|
|
|
|
if ( privacy_bitmask ) {
|
|
|
|
|
delete[] privacy_bitmask;
|
|
|
|
|
privacy_bitmask = NULL;
|
|
|
|
|
}
|
|
|
|
|
if ( mem_ptr ) {
|
|
|
|
|
if ( event )
|
|
|
|
|
Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() );
|
|
|
|
|
closeEvent();
|
|
|
|
|
if ( mem_ptr ) {
|
|
|
|
|
if ( event )
|
|
|
|
|
Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() );
|
|
|
|
|
closeEvent();
|
|
|
|
|
|
|
|
|
|
if ( (deinterlacing & 0xff) == 4)
|
|
|
|
|
{
|
|
|
|
|
delete next_buffer.image;
|
|
|
|
|
delete next_buffer.timestamp;
|
|
|
|
|
}
|
|
|
|
|
for ( int i = 0; i < image_buffer_count; i++ )
|
|
|
|
|
{
|
|
|
|
|
delete image_buffer[i].image;
|
|
|
|
|
}
|
|
|
|
|
delete[] image_buffer;
|
|
|
|
|
} // end if mem_ptr
|
|
|
|
|
if ( (deinterlacing & 0xff) == 4)
|
|
|
|
|
{
|
|
|
|
|
delete next_buffer.image;
|
|
|
|
|
delete next_buffer.timestamp;
|
|
|
|
|
}
|
|
|
|
|
for ( int i = 0; i < image_buffer_count; i++ )
|
|
|
|
|
{
|
|
|
|
|
delete image_buffer[i].image;
|
|
|
|
|
}
|
|
|
|
|
delete[] image_buffer;
|
|
|
|
|
} // end if mem_ptr
|
|
|
|
|
|
|
|
|
|
for ( int i = 0; i < n_zones; i++ )
|
|
|
|
|
{
|
|
|
|
@ -651,49 +651,49 @@ Monitor::~Monitor()
|
|
|
|
|
delete camera;
|
|
|
|
|
delete storage;
|
|
|
|
|
|
|
|
|
|
if ( mem_ptr ) {
|
|
|
|
|
if ( purpose == ANALYSIS )
|
|
|
|
|
{
|
|
|
|
|
shared_data->state = state = IDLE;
|
|
|
|
|
shared_data->last_read_index = image_buffer_count;
|
|
|
|
|
shared_data->last_read_time = 0;
|
|
|
|
|
if ( mem_ptr ) {
|
|
|
|
|
if ( purpose == ANALYSIS )
|
|
|
|
|
{
|
|
|
|
|
shared_data->state = state = IDLE;
|
|
|
|
|
shared_data->last_read_index = image_buffer_count;
|
|
|
|
|
shared_data->last_read_time = 0;
|
|
|
|
|
|
|
|
|
|
if ( analysis_fps )
|
|
|
|
|
{
|
|
|
|
|
for ( int i = 0; i < pre_event_buffer_count; i++ )
|
|
|
|
|
{
|
|
|
|
|
delete pre_event_buffer[i].image;
|
|
|
|
|
delete pre_event_buffer[i].timestamp;
|
|
|
|
|
}
|
|
|
|
|
delete[] pre_event_buffer;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ( purpose == CAPTURE )
|
|
|
|
|
{
|
|
|
|
|
shared_data->valid = false;
|
|
|
|
|
memset( mem_ptr, 0, mem_size );
|
|
|
|
|
}
|
|
|
|
|
if ( analysis_fps )
|
|
|
|
|
{
|
|
|
|
|
for ( int i = 0; i < pre_event_buffer_count; i++ )
|
|
|
|
|
{
|
|
|
|
|
delete pre_event_buffer[i].image;
|
|
|
|
|
delete pre_event_buffer[i].timestamp;
|
|
|
|
|
}
|
|
|
|
|
delete[] pre_event_buffer;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ( purpose == CAPTURE )
|
|
|
|
|
{
|
|
|
|
|
shared_data->valid = false;
|
|
|
|
|
memset( mem_ptr, 0, mem_size );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if ZM_MEM_MAPPED
|
|
|
|
|
if ( msync( mem_ptr, mem_size, MS_SYNC ) < 0 )
|
|
|
|
|
Error( "Can't msync: %s", strerror(errno) );
|
|
|
|
|
if ( munmap( mem_ptr, mem_size ) < 0 )
|
|
|
|
|
Fatal( "Can't munmap: %s", strerror(errno) );
|
|
|
|
|
close( map_fd );
|
|
|
|
|
if ( msync( mem_ptr, mem_size, MS_SYNC ) < 0 )
|
|
|
|
|
Error( "Can't msync: %s", strerror(errno) );
|
|
|
|
|
if ( munmap( mem_ptr, mem_size ) < 0 )
|
|
|
|
|
Fatal( "Can't munmap: %s", strerror(errno) );
|
|
|
|
|
close( map_fd );
|
|
|
|
|
#else // ZM_MEM_MAPPED
|
|
|
|
|
struct shmid_ds shm_data;
|
|
|
|
|
if ( shmctl( shm_id, IPC_STAT, &shm_data ) < 0 ) {
|
|
|
|
|
Error( "Can't shmctl: %s", strerror(errno) );
|
|
|
|
|
exit( -1 );
|
|
|
|
|
}
|
|
|
|
|
if ( shm_data.shm_nattch <= 1 ) {
|
|
|
|
|
if ( shmctl( shm_id, IPC_RMID, 0 ) < 0 ) {
|
|
|
|
|
Error( "Can't shmctl: %s", strerror(errno) );
|
|
|
|
|
exit( -1 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
struct shmid_ds shm_data;
|
|
|
|
|
if ( shmctl( shm_id, IPC_STAT, &shm_data ) < 0 ) {
|
|
|
|
|
Error( "Can't shmctl: %s", strerror(errno) );
|
|
|
|
|
exit( -1 );
|
|
|
|
|
}
|
|
|
|
|
if ( shm_data.shm_nattch <= 1 ) {
|
|
|
|
|
if ( shmctl( shm_id, IPC_RMID, 0 ) < 0 ) {
|
|
|
|
|
Error( "Can't shmctl: %s", strerror(errno) );
|
|
|
|
|
exit( -1 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif // ZM_MEM_MAPPED
|
|
|
|
|
} // end if mem_ptr
|
|
|
|
|
} // end if mem_ptr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Monitor::AddZones( int p_n_zones, Zone *p_zones[] )
|
|
|
|
@ -744,7 +744,7 @@ int Monitor::GetImage( int index, int scale )
|
|
|
|
|
if ( index != image_buffer_count )
|
|
|
|
|
{
|
|
|
|
|
Image *image;
|
|
|
|
|
// If we are going to be modifying the snapshot before writing, then we need to copy it
|
|
|
|
|
// If we are going to be modifying the snapshot before writing, then we need to copy it
|
|
|
|
|
if ( ( scale != ZM_SCALE_BASE ) || ( !config.timestamp_on_capture ) ) {
|
|
|
|
|
Snapshot *snap = &image_buffer[index];
|
|
|
|
|
Image *snap_image = snap->image;
|
|
|
|
@ -1244,32 +1244,32 @@ bool Monitor::CheckSignal( const Image *image )
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(colours == ZM_COLOUR_GRAY8) {
|
|
|
|
|
if ( *(buffer+index) != grayscale_val )
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
} else if(colours == ZM_COLOUR_RGB24) {
|
|
|
|
|
const uint8_t *ptr = buffer+(index*colours);
|
|
|
|
|
|
|
|
|
|
if ( usedsubpixorder == ZM_SUBPIX_ORDER_BGR) {
|
|
|
|
|
if ( (RED_PTR_BGRA(ptr) != red_val) || (GREEN_PTR_BGRA(ptr) != green_val) || (BLUE_PTR_BGRA(ptr) != blue_val) )
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
/* Assume RGB */
|
|
|
|
|
if ( (RED_PTR_RGBA(ptr) != red_val) || (GREEN_PTR_RGBA(ptr) != green_val) || (BLUE_PTR_RGBA(ptr) != blue_val) )
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if(colours == ZM_COLOUR_RGB32) {
|
|
|
|
|
if ( usedsubpixorder == ZM_SUBPIX_ORDER_ARGB || usedsubpixorder == ZM_SUBPIX_ORDER_ABGR) {
|
|
|
|
|
if ( ARGB_ABGR_ZEROALPHA(*(((const Rgb*)buffer)+index)) != ARGB_ABGR_ZEROALPHA(colour_val) )
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
/* Assume RGBA or BGRA */
|
|
|
|
|
if ( RGBA_BGRA_ZEROALPHA(*(((const Rgb*)buffer)+index)) != RGBA_BGRA_ZEROALPHA(colour_val) )
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(colours == ZM_COLOUR_GRAY8) {
|
|
|
|
|
if ( *(buffer+index) != grayscale_val )
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
} else if(colours == ZM_COLOUR_RGB24) {
|
|
|
|
|
const uint8_t *ptr = buffer+(index*colours);
|
|
|
|
|
|
|
|
|
|
if ( usedsubpixorder == ZM_SUBPIX_ORDER_BGR) {
|
|
|
|
|
if ( (RED_PTR_BGRA(ptr) != red_val) || (GREEN_PTR_BGRA(ptr) != green_val) || (BLUE_PTR_BGRA(ptr) != blue_val) )
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
/* Assume RGB */
|
|
|
|
|
if ( (RED_PTR_RGBA(ptr) != red_val) || (GREEN_PTR_RGBA(ptr) != green_val) || (BLUE_PTR_RGBA(ptr) != blue_val) )
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if(colours == ZM_COLOUR_RGB32) {
|
|
|
|
|
if ( usedsubpixorder == ZM_SUBPIX_ORDER_ARGB || usedsubpixorder == ZM_SUBPIX_ORDER_ABGR) {
|
|
|
|
|
if ( ARGB_ABGR_ZEROALPHA(*(((const Rgb*)buffer)+index)) != ARGB_ABGR_ZEROALPHA(colour_val) )
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
/* Assume RGBA or BGRA */
|
|
|
|
|
if ( RGBA_BGRA_ZEROALPHA(*(((const Rgb*)buffer)+index)) != RGBA_BGRA_ZEROALPHA(colour_val) )
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return( false );
|
|
|
|
@ -1740,7 +1740,7 @@ bool Monitor::Analyse()
|
|
|
|
|
if ( config.create_analysis_images )
|
|
|
|
|
{
|
|
|
|
|
bool got_anal_image = false;
|
|
|
|
|
alarm_image.Assign( *snap_image );
|
|
|
|
|
alarm_image.Assign( *snap_image );
|
|
|
|
|
for( int i = 0; i < n_zones; i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( zones[i]->Alarmed() )
|
|
|
|
@ -2090,24 +2090,24 @@ Debug( 1, "Server ID %d", staticConfig.SERVER_ID );
|
|
|
|
|
const char *device = dbrow[col]; col++;
|
|
|
|
|
int channel = atoi(dbrow[col]); col++;
|
|
|
|
|
int format = atoi(dbrow[col]); col++;
|
|
|
|
|
bool v4l_multi_buffer = config.v4l_multi_buffer;
|
|
|
|
|
if ( dbrow[col] ) {
|
|
|
|
|
if (*dbrow[col] == '0' ) {
|
|
|
|
|
v4l_multi_buffer = false;
|
|
|
|
|
} else if ( *dbrow[col] == '1' ) {
|
|
|
|
|
v4l_multi_buffer = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
col++;
|
|
|
|
|
|
|
|
|
|
int v4l_captures_per_frame = 0;
|
|
|
|
|
if ( dbrow[col] ) {
|
|
|
|
|
v4l_captures_per_frame = atoi(dbrow[col]);
|
|
|
|
|
} else {
|
|
|
|
|
v4l_captures_per_frame = config.captures_per_frame;
|
|
|
|
|
}
|
|
|
|
|
bool v4l_multi_buffer = config.v4l_multi_buffer;
|
|
|
|
|
if ( dbrow[col] ) {
|
|
|
|
|
if (*dbrow[col] == '0' ) {
|
|
|
|
|
v4l_multi_buffer = false;
|
|
|
|
|
} else if ( *dbrow[col] == '1' ) {
|
|
|
|
|
v4l_multi_buffer = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
col++;
|
|
|
|
|
|
|
|
|
|
int v4l_captures_per_frame = 0;
|
|
|
|
|
if ( dbrow[col] ) {
|
|
|
|
|
v4l_captures_per_frame = atoi(dbrow[col]);
|
|
|
|
|
} else {
|
|
|
|
|
v4l_captures_per_frame = config.captures_per_frame;
|
|
|
|
|
}
|
|
|
|
|
Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
|
|
|
|
col++;
|
|
|
|
|
col++;
|
|
|
|
|
const char *method = dbrow[col]; col++;
|
|
|
|
|
|
|
|
|
|
int width = atoi(dbrow[col]); col++;
|
|
|
|
@ -2164,8 +2164,8 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
|
|
|
|
device,
|
|
|
|
|
channel,
|
|
|
|
|
format,
|
|
|
|
|
v4l_multi_buffer,
|
|
|
|
|
v4l_captures_per_frame,
|
|
|
|
|
v4l_multi_buffer,
|
|
|
|
|
v4l_captures_per_frame,
|
|
|
|
|
method,
|
|
|
|
|
cam_width,
|
|
|
|
|
cam_height,
|
|
|
|
@ -3019,30 +3019,30 @@ Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame );
|
|
|
|
|
|
|
|
|
|
int Monitor::Capture()
|
|
|
|
|
{
|
|
|
|
|
static int FirstCapture = 1;
|
|
|
|
|
int captureResult;
|
|
|
|
|
|
|
|
|
|
int index = image_count%image_buffer_count;
|
|
|
|
|
Image* capture_image = image_buffer[index].image;
|
|
|
|
|
|
|
|
|
|
if ( (deinterlacing & 0xff) == 4) {
|
|
|
|
|
if ( FirstCapture != 1 ) {
|
|
|
|
|
/* Copy the next image into the shared memory */
|
|
|
|
|
capture_image->CopyBuffer(*(next_buffer.image));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Capture a new next image */
|
|
|
|
|
captureResult = camera->Capture(*(next_buffer.image));
|
|
|
|
|
|
|
|
|
|
if ( FirstCapture ) {
|
|
|
|
|
FirstCapture = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
/* Capture directly into image buffer, avoiding the need to memcpy() */
|
|
|
|
|
captureResult = camera->Capture(*capture_image);
|
|
|
|
|
}
|
|
|
|
|
static int FirstCapture = 1;
|
|
|
|
|
int captureResult;
|
|
|
|
|
|
|
|
|
|
int index = image_count%image_buffer_count;
|
|
|
|
|
Image* capture_image = image_buffer[index].image;
|
|
|
|
|
|
|
|
|
|
if ( (deinterlacing & 0xff) == 4) {
|
|
|
|
|
if ( FirstCapture != 1 ) {
|
|
|
|
|
/* Copy the next image into the shared memory */
|
|
|
|
|
capture_image->CopyBuffer(*(next_buffer.image));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Capture a new next image */
|
|
|
|
|
captureResult = camera->Capture(*(next_buffer.image));
|
|
|
|
|
|
|
|
|
|
if ( FirstCapture ) {
|
|
|
|
|
FirstCapture = 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
/* Capture directly into image buffer, avoiding the need to memcpy() */
|
|
|
|
|
captureResult = camera->Capture(*capture_image);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( captureResult != 0 )
|
|
|
|
|
{
|
|
|
|
@ -3059,18 +3059,18 @@ int Monitor::Capture()
|
|
|
|
|
if ( captureResult == 1 )
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/* Deinterlacing */
|
|
|
|
|
if ( (deinterlacing & 0xff) == 1 ) {
|
|
|
|
|
capture_image->Deinterlace_Discard();
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 2 ) {
|
|
|
|
|
capture_image->Deinterlace_Linear();
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 3 ) {
|
|
|
|
|
capture_image->Deinterlace_Blend();
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 4 ) {
|
|
|
|
|
capture_image->Deinterlace_4Field( next_buffer.image, (deinterlacing>>8)&0xff );
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 5 ) {
|
|
|
|
|
capture_image->Deinterlace_Blend_CustomRatio( (deinterlacing>>8)&0xff );
|
|
|
|
|
}
|
|
|
|
|
/* Deinterlacing */
|
|
|
|
|
if ( (deinterlacing & 0xff) == 1 ) {
|
|
|
|
|
capture_image->Deinterlace_Discard();
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 2 ) {
|
|
|
|
|
capture_image->Deinterlace_Linear();
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 3 ) {
|
|
|
|
|
capture_image->Deinterlace_Blend();
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 4 ) {
|
|
|
|
|
capture_image->Deinterlace_4Field( next_buffer.image, (deinterlacing>>8)&0xff );
|
|
|
|
|
} else if ( (deinterlacing & 0xff) == 5 ) {
|
|
|
|
|
capture_image->Deinterlace_Blend_CustomRatio( (deinterlacing>>8)&0xff );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( orientation != ROTATE_0 )
|
|
|
|
|