Move some initialisation into MOnitor() initialisation. Update UpdateAnalysisFPS to use more doubles instead of integers to get better numbers. Move capture FPS updating to UpdateCaptureFPS and use doubles there too. remove some dead code and add some debugging
This commit is contained in:
parent
3893e97e94
commit
1ffc233593
|
@ -331,6 +331,11 @@ Monitor::Monitor()
|
||||||
signal_check_colour(0),
|
signal_check_colour(0),
|
||||||
embed_exif(0),
|
embed_exif(0),
|
||||||
purpose(QUERY),
|
purpose(QUERY),
|
||||||
|
last_camera_bytes(0),
|
||||||
|
event_count(0),
|
||||||
|
image_count(0),
|
||||||
|
analysis_image_count(0),
|
||||||
|
motion_frame_count(0),
|
||||||
auto_resume_time(0),
|
auto_resume_time(0),
|
||||||
last_motion_score(0),
|
last_motion_score(0),
|
||||||
camera(nullptr),
|
camera(nullptr),
|
||||||
|
@ -352,7 +357,7 @@ Monitor::Monitor()
|
||||||
else
|
else
|
||||||
event_close_mode = CLOSE_IDLE;
|
event_close_mode = CLOSE_IDLE;
|
||||||
|
|
||||||
start_time = last_fps_time = time(0);
|
|
||||||
event = 0;
|
event = 0;
|
||||||
last_section_mod = 0;
|
last_section_mod = 0;
|
||||||
|
|
||||||
|
@ -547,10 +552,6 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
|
||||||
signal_check_colour = strtol(dbrow[col][0] == '#' ? dbrow[col]+1 : dbrow[col], 0, 16); col++;
|
signal_check_colour = strtol(dbrow[col][0] == '#' ? dbrow[col]+1 : dbrow[col], 0, 16); col++;
|
||||||
embed_exif = (*dbrow[col] != '0'); col++;
|
embed_exif = (*dbrow[col] != '0'); col++;
|
||||||
|
|
||||||
last_camera_bytes = 0;
|
|
||||||
event_count = 0;
|
|
||||||
image_count = 0;
|
|
||||||
analysis_image_count = 0;
|
|
||||||
|
|
||||||
// How many frames we need to have before we start analysing
|
// How many frames we need to have before we start analysing
|
||||||
ready_count = warmup_count;
|
ready_count = warmup_count;
|
||||||
|
@ -647,8 +648,6 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
|
||||||
shared_data->analysis_fps = 0.0;
|
shared_data->analysis_fps = 0.0;
|
||||||
} // end if purpose
|
} // end if purpose
|
||||||
|
|
||||||
start_time = last_fps_time = time(0);
|
|
||||||
|
|
||||||
//this->delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ),
|
//this->delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ),
|
||||||
//ref_image( width, height, p_camera->Colours(), p_camera->SubpixelOrder() ),
|
//ref_image( width, height, p_camera->Colours(), p_camera->SubpixelOrder() ),
|
||||||
Debug(1, "Loaded monitor %d(%s), %d zones", id, name, n_zones);
|
Debug(1, "Loaded monitor %d(%s), %d zones", id, name, n_zones);
|
||||||
|
@ -1031,6 +1030,14 @@ bool Monitor::connect() {
|
||||||
images = new Image *[pre_event_count];
|
images = new Image *[pre_event_count];
|
||||||
last_signal = shared_data->signal;
|
last_signal = shared_data->signal;
|
||||||
} // end if purpose == ANALYSIS
|
} // end if purpose == ANALYSIS
|
||||||
|
|
||||||
|
// We set these here because otherwise the first fps calc is meaningless
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
double now_double = (double)now.tv_sec + (0.000001f * now.tv_usec);
|
||||||
|
last_fps_time = now_double;
|
||||||
|
last_analysis_fps_time = now_double;
|
||||||
|
|
||||||
Debug(3, "Success connecting");
|
Debug(3, "Success connecting");
|
||||||
return true;
|
return true;
|
||||||
} // Monitor::connect
|
} // Monitor::connect
|
||||||
|
@ -1706,32 +1713,86 @@ void Monitor::CheckAction() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Monitor::UpdateAnalysisFPS() {
|
void Monitor::UpdateCaptureFPS() {
|
||||||
Debug(1, "analysis_image_count(%d) fps_report_interval(%d) mod%d", analysis_image_count, fps_report_interval,
|
if ( fps_report_interval && ( !(image_count%fps_report_interval) || image_count == 5 ) ) {
|
||||||
((analysis_image_count && fps_report_interval) ? !(analysis_image_count%fps_report_interval) : -1 ) );
|
|
||||||
if ( analysis_image_count && fps_report_interval && !(analysis_image_count%fps_report_interval) ) {
|
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, NULL);
|
||||||
double new_analysis_fps = double(fps_report_interval)/(now.tv_sec - last_analysis_fps_time);
|
double now_double = (double)now.tv_sec + (0.000001f * now.tv_usec);
|
||||||
Info("%s: %d - Analysing at %.2f fps", name, analysis_image_count, new_analysis_fps);
|
|
||||||
if ( new_analysis_fps != shared_data->analysis_fps ) {
|
|
||||||
shared_data->analysis_fps = new_analysis_fps;
|
|
||||||
|
|
||||||
char sql[ZM_SQL_SML_BUFSIZ];
|
// If we are too fast, we get div by zero. This seems to happen in the case of audio packets.
|
||||||
snprintf(sql, sizeof(sql),
|
if ( now_double != last_fps_time ) {
|
||||||
"INSERT INTO Monitor_Status (MonitorId,AnalysisFPS) VALUES (%d, %.2lf)"
|
// # of images per interval / the amount of time it took
|
||||||
" ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf",
|
double new_capture_fps = double((image_count < fps_report_interval ? image_count : fps_report_interval))/(now_double-last_fps_time);
|
||||||
id, new_analysis_fps, new_analysis_fps);
|
unsigned int new_camera_bytes = camera->Bytes();
|
||||||
|
unsigned int new_capture_bandwidth = (new_camera_bytes-last_camera_bytes)/(now_double-last_fps_time);
|
||||||
|
last_camera_bytes = new_camera_bytes;
|
||||||
|
//Info( "%d -> %d -> %d", fps_report_interval, now, last_fps_time );
|
||||||
|
//Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps );
|
||||||
|
Info("%s: images:%d - Capturing at %.2lf fps, capturing bandwidth %ubytes/sec", name, image_count, new_capture_fps, new_capture_bandwidth);
|
||||||
|
shared_data->capture_fps = new_capture_fps;
|
||||||
|
last_fps_time = now_double;
|
||||||
db_mutex.lock();
|
db_mutex.lock();
|
||||||
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
|
// The reason we update the Status as well is because if mysql restarts, the Monitor_Status table is lost,
|
||||||
|
// and nothing else will update the status until zmc restarts. Since we are successfully capturing we can
|
||||||
|
// assume that we are connected
|
||||||
|
snprintf(sql, sizeof(sql),
|
||||||
|
"INSERT INTO Monitor_Status (MonitorId,CaptureFPS,CaptureBandwidth,Status) "
|
||||||
|
"VALUES (%d, %.2lf, %u, 'Connected') ON DUPLICATE KEY UPDATE "
|
||||||
|
"CaptureFPS = %.2lf, CaptureBandwidth=%u, Status='Connected'",
|
||||||
|
id, new_capture_fps, new_capture_bandwidth, new_capture_fps, new_capture_bandwidth);
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
}
|
}
|
||||||
db_mutex.unlock();
|
db_mutex.unlock();
|
||||||
last_analysis_fps_time = now.tv_sec;
|
} // now != last_fps_time
|
||||||
}
|
} // end if report fps
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Monitor::UpdateAnalysisFPS() {
|
||||||
|
Debug(1, "analysis_image_count(%d) motion_count(%d) fps_report_interval(%d) mod%d",
|
||||||
|
analysis_image_count, motion_frame_count, fps_report_interval,
|
||||||
|
((analysis_image_count && fps_report_interval) ? !(analysis_image_count%fps_report_interval) : -1 ) );
|
||||||
|
|
||||||
|
if ( motion_frame_count && fps_report_interval && !(motion_frame_count%fps_report_interval) ) {
|
||||||
|
//if ( analysis_image_count && fps_report_interval && !(analysis_image_count%fps_report_interval) ) {
|
||||||
|
struct timeval now;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
double now_double = (double)now.tv_sec + (0.000001f * now.tv_usec);
|
||||||
|
Debug(4, "%s: %d - now:%d.%d = %lf, last %lf, diff %lf", name, analysis_image_count,
|
||||||
|
now.tv_sec, now.tv_usec, now_double, last_analysis_fps_time,
|
||||||
|
now_double - last_analysis_fps_time
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( now_double - last_analysis_fps_time > 1.0 ) {
|
||||||
|
double new_analysis_fps = double(fps_report_interval) / (now_double - last_analysis_fps_time);
|
||||||
|
Info("%s: %d - Analysing at %.2lf fps from %d / %lf - %lf",
|
||||||
|
name, analysis_image_count, new_analysis_fps,
|
||||||
|
fps_report_interval,
|
||||||
|
now_double, last_analysis_fps_time);
|
||||||
|
|
||||||
|
if ( new_analysis_fps != shared_data->analysis_fps ) {
|
||||||
|
shared_data->analysis_fps = new_analysis_fps;
|
||||||
|
|
||||||
|
char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
|
snprintf(sql, sizeof(sql),
|
||||||
|
"INSERT INTO Monitor_Status (MonitorId,AnalysisFPS) VALUES (%d, %.2lf)"
|
||||||
|
" ON DUPLICATE KEY UPDATE AnalysisFPS = %.2lf",
|
||||||
|
id, new_analysis_fps, new_analysis_fps);
|
||||||
|
db_mutex.lock();
|
||||||
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
|
}
|
||||||
|
db_mutex.unlock();
|
||||||
|
last_analysis_fps_time = now_double;
|
||||||
|
} else {
|
||||||
|
Debug(4, "No change in fps");
|
||||||
|
} // end if change in fps
|
||||||
|
} // end if at least 1 second has passed since last update
|
||||||
|
|
||||||
|
} // end if time to do an update
|
||||||
|
} // end void Monitor::UpdateAnalysisFPS
|
||||||
|
|
||||||
// Would be nice if this JUST did analysis
|
// Would be nice if this JUST did analysis
|
||||||
// This idea is that we should be analysing as close to the capture frame as possible.
|
// This idea is that we should be analysing as close to the capture frame as possible.
|
||||||
// This function should process as much as possible before returning
|
// This function should process as much as possible before returning
|
||||||
|
@ -1751,6 +1812,7 @@ bool Monitor::Analyse() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if have event, send frames until we find a video packet, at which point do analysis. Adaptive skip should only affect which frames we do analysis on.
|
// if have event, send frames until we find a video packet, at which point do analysis. Adaptive skip should only affect which frames we do analysis on.
|
||||||
|
|
||||||
int packets_processed = 0;
|
int packets_processed = 0;
|
||||||
|
@ -1840,7 +1902,15 @@ bool Monitor::Analyse() {
|
||||||
Event::StringSet zoneSet;
|
Event::StringSet zoneSet;
|
||||||
|
|
||||||
int motion_score = last_motion_score;
|
int motion_score = last_motion_score;
|
||||||
if ( !(analysis_image_count % (motion_frame_skip+1) ) ) {
|
|
||||||
|
if ( analysis_fps_limit ) {
|
||||||
|
double capture_fps = get_capture_fps();
|
||||||
|
motion_frame_skip = capture_fps / analysis_fps_limit;
|
||||||
|
Debug(1, "Recalculating motion_frame_skip (%d) = capture_fps(%f) / analysis_fps(%f)",
|
||||||
|
motion_frame_skip, capture_fps, analysis_fps_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !(analysis_image_count % (motion_frame_skip+1)) ) {
|
||||||
if ( snap->image ) {
|
if ( snap->image ) {
|
||||||
// Get new score.
|
// Get new score.
|
||||||
motion_score = DetectMotion(*(snap->image), zoneSet);
|
motion_score = DetectMotion(*(snap->image), zoneSet);
|
||||||
|
@ -1852,6 +1922,9 @@ bool Monitor::Analyse() {
|
||||||
}
|
}
|
||||||
// Why are we updating the last_motion_score too?
|
// Why are we updating the last_motion_score too?
|
||||||
last_motion_score = motion_score;
|
last_motion_score = motion_score;
|
||||||
|
motion_frame_count += 1;
|
||||||
|
} else {
|
||||||
|
Debug(1, "Skipped motion detection");
|
||||||
}
|
}
|
||||||
if ( motion_score ) {
|
if ( motion_score ) {
|
||||||
score += motion_score;
|
score += motion_score;
|
||||||
|
@ -2137,25 +2210,7 @@ bool Monitor::Analyse() {
|
||||||
} // end if ( trigger_data->trigger_state != TRIGGER_OFF )
|
} // end if ( trigger_data->trigger_state != TRIGGER_OFF )
|
||||||
|
|
||||||
if ( event ) {
|
if ( event ) {
|
||||||
int last_write = shared_data->last_write_index;
|
|
||||||
event->AddPacket(snap);
|
event->AddPacket(snap);
|
||||||
|
|
||||||
#if 0
|
|
||||||
int written = 0;
|
|
||||||
ZMPacket *queued_packet;
|
|
||||||
|
|
||||||
// since we incremented the analysis_it, this will include snap
|
|
||||||
//while ( (queued_packet = packetqueue->popPacket()) ) {
|
|
||||||
Debug(2, "adding queued packet (%d) qp last_write_index(%d), written(%d)", queued_packet->image_index, last_write, written);
|
|
||||||
event->AddPacket(queued_packet);
|
|
||||||
queued_packet->unlock();
|
|
||||||
written ++;
|
|
||||||
if ( queued_packet->image_index == -1 ) {
|
|
||||||
delete queued_packet;
|
|
||||||
}
|
|
||||||
} // end while write out queued_packets
|
|
||||||
queued_packet = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// popPacket will have placed a second lock on snap, so release it here.
|
// popPacket will have placed a second lock on snap, so release it here.
|
||||||
snap->unlock();
|
snap->unlock();
|
||||||
|
@ -2467,7 +2522,7 @@ int Monitor::Capture() {
|
||||||
packet->codec_type = camera->get_VideoStream()->codec->codec_type;
|
packet->codec_type = camera->get_VideoStream()->codec->codec_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ( packet->packet.size && !packet->in_frame ) {
|
if ( packet->packet.size and !packet->in_frame ) {
|
||||||
if (
|
if (
|
||||||
( function == RECORD or function == NODECT )
|
( function == RECORD or function == NODECT )
|
||||||
and
|
and
|
||||||
|
@ -2478,12 +2533,14 @@ int Monitor::Capture() {
|
||||||
// In this specific case we don't need to do the decode.
|
// In this specific case we don't need to do the decode.
|
||||||
Debug(1, "Not decoding");
|
Debug(1, "Not decoding");
|
||||||
} else {
|
} else {
|
||||||
//Debug(2,"About to decode");
|
Debug(2,"About to decode");
|
||||||
if ( packet->decode(camera->get_VideoCodecContext()) ) {
|
if ( packet->decode(camera->get_VideoCodecContext()) ) {
|
||||||
//Debug(2,"Getimage");
|
Debug(2,"Getimage");
|
||||||
packet->get_image(image_buffer[index].image);
|
packet->get_image(image_buffer[index].image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Error("No packet.size(%d) or packet->in_frame(%p). Not decoding", packet->packet.size, packet->in_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( packetqueue->packet_count(video_stream_id) or packet->keyframe or event ) {
|
if ( packetqueue->packet_count(video_stream_id) or packet->keyframe or event ) {
|
||||||
|
@ -2539,37 +2596,7 @@ int Monitor::Capture() {
|
||||||
image_count++;
|
image_count++;
|
||||||
Debug(2, "Unlocking packet, incrementing image_count to %d", image_count);
|
Debug(2, "Unlocking packet, incrementing image_count to %d", image_count);
|
||||||
packet->unlock();
|
packet->unlock();
|
||||||
|
UpdateCaptureFPS();
|
||||||
if ( fps_report_interval && ( !(image_count%fps_report_interval) || image_count == 5 ) ) {
|
|
||||||
time_t now = image_buffer[index].timestamp->tv_sec;
|
|
||||||
// If we are too fast, we get div by zero. This seems to happen in the case of audio packets.
|
|
||||||
if ( now != last_fps_time ) {
|
|
||||||
// # of images per interval / the amount of time it took
|
|
||||||
double new_capture_fps = double((image_count < fps_report_interval ? image_count : fps_report_interval))/(now-last_fps_time);
|
|
||||||
unsigned int new_camera_bytes = camera->Bytes();
|
|
||||||
unsigned int new_capture_bandwidth = (new_camera_bytes - last_camera_bytes)/(now-last_fps_time);
|
|
||||||
last_camera_bytes = new_camera_bytes;
|
|
||||||
//Info( "%d -> %d -> %d", fps_report_interval, now, last_fps_time );
|
|
||||||
//Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps );
|
|
||||||
Info("%s: images:%d - Capturing at %.2lf fps, capturing bandwidth %ubytes/sec", name, image_count, new_capture_fps, new_capture_bandwidth);
|
|
||||||
shared_data->capture_fps = new_capture_fps;
|
|
||||||
last_fps_time = now;
|
|
||||||
db_mutex.lock();
|
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
|
||||||
// The reason we update the Status as well is because if mysql restarts, the Monitor_Status table is lost,
|
|
||||||
// and nothing else will update the status until zmc restarts. Since we are successfully capturing we can
|
|
||||||
// assume that we are connected
|
|
||||||
snprintf(sql, sizeof(sql),
|
|
||||||
"INSERT INTO Monitor_Status (MonitorId,CaptureFPS,CaptureBandwidth,Status) "
|
|
||||||
"VALUES (%d, %.2lf, %u, 'Connected') ON DUPLICATE KEY UPDATE "
|
|
||||||
"CaptureFPS = %.2lf, CaptureBandwidth=%u, Status='Connected'",
|
|
||||||
id, new_capture_fps, new_capture_bandwidth, new_capture_fps, new_capture_bandwidth);
|
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
|
||||||
}
|
|
||||||
db_mutex.unlock();
|
|
||||||
} // now != last_fps_time
|
|
||||||
} // end if report fps
|
|
||||||
} else { // result == 0
|
} else { // result == 0
|
||||||
// Question is, do we update last_write_index etc?
|
// Question is, do we update last_write_index etc?
|
||||||
packet->unlock();
|
packet->unlock();
|
||||||
|
|
Loading…
Reference in New Issue