Rename H264PASSTHROUGH to just PASSTHROUGH. Start with last_signal set to true so that we don't have a signal change event on startup. Use new generic packetqueue functions

pull/3122/head
Isaac Connor 2021-01-06 11:31:31 -05:00
parent d6c217c1ec
commit e93a895f28
1 changed files with 64 additions and 37 deletions

View File

@ -303,7 +303,10 @@ Monitor::Monitor()
videowriter(DISABLED),
encoderparams(""),
output_codec(0),
encoder(""),
output_container(""),
imagePixFormat(AV_PIX_FMT_NONE),
subpixelorder(0),
record_audio(0),
//event_prefix
//label_format
@ -316,6 +319,7 @@ Monitor::Monitor()
stream_replay_buffer(0),
section_length(0),
min_section_length(0),
adaptive_skip(false),
frame_skip(0),
motion_frame_skip(0),
analysis_fps_limit(0),
@ -330,12 +334,23 @@ Monitor::Monitor()
signal_check_points(0),
signal_check_colour(0),
embed_exif(0),
capture_max_fps(0),
purpose(QUERY),
last_camera_bytes(0),
event_count(0),
image_count(0),
analysis_image_count(0),
motion_frame_count(0),
ready_count(0),
first_alarm_count(0),
last_alarm_count(0),
last_signal(false),
last_section_mod(0),
buffer_count(0),
state(IDLE),
start_time(0),
last_fps_time(0),
last_analysis_fps_time(0),
auto_resume_time(0),
last_motion_score(0),
camera(nullptr),
@ -558,7 +573,8 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
last_alarm_count = 0;
state = IDLE;
last_signal = false;
last_signal = true; // Defaulting to having signal so that we don't get a signal change on the first frame.
// Instead initial failure to capture will cause a loss of signal change which I think makes more sense.
camera = NULL;
uint64_t image_size = width * height * colours;
@ -606,7 +622,7 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
and
( savejpegs == 0 )
and
( videowriter == H264PASSTHROUGH )
( videowriter == PASSTHROUGH )
and
!decoding_enabled
);
@ -954,7 +970,8 @@ bool Monitor::connect() {
shared_timestamps = (struct timeval *)((char *)video_store_data + sizeof(VideoStoreData));
shared_images = (unsigned char *)((char *)shared_timestamps + (image_buffer_count*sizeof(struct timeval)));
packetqueue = NULL;
packetqueue = nullptr;
analysis_it = nullptr;
if ( ((unsigned long)shared_images % 64) != 0 ) {
/* Align images buffer to nearest 64 byte boundary */
@ -1144,6 +1161,7 @@ Monitor::~Monitor() {
delete packetqueue;
packetqueue = nullptr;
analysis_it = nullptr; // deleted by packetqueue
for ( int i = 0; i < n_zones; i++ ) {
delete zones[i];
@ -1812,7 +1830,8 @@ bool Monitor::Analyse() {
Debug(1, "Waiting for PrimeCapture");
return false;
}
if ( !analysis_it )
analysis_it = packetqueue->get_video_it(true);
// 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.
@ -1820,19 +1839,19 @@ bool Monitor::Analyse() {
ZMPacket *snap;
// get_analysis_packet will lock the packet
while ( (!zm_terminate) and (snap = packetqueue->get_analysis_packet()) ) {
while ( (!zm_terminate) and (snap = packetqueue->get_packet(analysis_it)) ) {
// Is it possible for snap->score to be ! -1 ? Not if everything is working correctly
if ( snap->score != -1 ) {
snap->unlock();
packetqueue->increment_analysis_it();
packetqueue->increment_it(analysis_it);
Error("skipping because score was %d", snap->score);
return false;
}
packets_processed += 1;
std::list<ZMPacket *>::iterator snap_it = packetqueue->get_analysis_it();
packetqueue->increment_analysis_it();
packetqueue_iterator snap_it = *analysis_it;
//packetqueue->get_analysis_it();
packetqueue->increment_it(analysis_it);
// signal is set by capture
bool signal = shared_data->signal;
@ -2052,8 +2071,7 @@ bool Monitor::Analyse() {
name, image_count, Event::PreAlarmCount(), alarm_frame_count, shared_data->alarm_cause);
if ( !event ) {
std::list<ZMPacket *>::iterator start_it = packetqueue->get_event_start_packet_it(
packetqueue_iterator start_it = packetqueue->get_event_start_packet_it(
snap_it,
(pre_event_count > alarm_frame_count ? pre_event_count : alarm_frame_count)
);
@ -2073,7 +2091,7 @@ bool Monitor::Analyse() {
shared_data->state = state = ALARM;
Info("%s: %03d - Opening new event %" PRIu64 ", alarm start", name, image_count, event->Id());
}
} // end if no event, so start it
if ( alarm_frame_count ) {
Debug(1, "alarm frame count so SavePreAlarmFrames");
event->SavePreAlarmFrames();
@ -2107,9 +2125,9 @@ bool Monitor::Analyse() {
}
} else if ( state == PREALARM ) {
// Back to IDLE
shared_data->state = state = function != MOCORD ? IDLE : TAPE;
shared_data->state = state = ((function != MOCORD) ? IDLE : TAPE);
} else {
Debug(1, "State %d ALERT beacuse image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%d) - recording.tv_src(%d) >= min_section_length(%d)",
Debug(1, "State %d beacuse image_count(%d)-last_alarm_count(%d) > post_event_count(%d) and timestamp.tv_sec(%d) - recording.tv_src(%d) >= min_section_length(%d)",
state, analysis_image_count, last_alarm_count, post_event_count,
timestamp->tv_sec, video_store_data->recording.tv_sec, min_section_length);
}
@ -2442,10 +2460,12 @@ int Monitor::Capture() {
ZMPacket *packet = new ZMPacket();
packet->timestamp = new struct timeval;
packet->image_index = image_count;
gettimeofday(packet->timestamp, nullptr);
// Still need to lock it. When we add it to queue other threads can pounce on it
packet->lock();
// Not so convinced. We hold the packetqueue lock while adding it.
//packet->lock();
Image* capture_image = image_buffer[index].image;
//Debug(1, "capture image: %d x %d linesize: %d", capture_image->Width(), capture_image->Height(), capture_image->LineSize());
int captureResult = 0;
@ -2462,7 +2482,7 @@ int Monitor::Capture() {
gettimeofday(packet->timestamp, NULL);
if ( FirstCapture ) {
packet->unlock();
//packet->unlock();
FirstCapture = 0;
return 0;
}
@ -2483,23 +2503,26 @@ int Monitor::Capture() {
shared_data->last_write_index = index;
shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
image_count++;
packet->unlock();
//packet->unlock();
delete packet;
// What about timestamping it?
// Don't want to do analysis on it, but we won't due to signal
return -1;
} else if ( captureResult > 0 ) {
Debug(2, "Have packet stream_index:%d ?= videostream_id:(%d) q.vpktcount(%d) event?(%d) ",
packet->packet.stream_index, video_stream_id, packetqueue->packet_count(video_stream_id), ( event ? 1 : 0 ) );
//packet->unlock();
if ( packet->packet.stream_index != video_stream_id ) {
// Only queue if we have some video packets in there. Should push this logic into packetqueue
if ( packetqueue->packet_count(video_stream_id) or event ) {
Debug(2, "Queueing audio packet");
packetqueue->queuePacket(packet);
} else {
delete packet;
}
// Don't update last_write_index because that is used for live streaming
//shared_data->last_write_time = image_buffer[index].timestamp->tv_sec;
packet->unlock();
return 1;
} // end if audio
@ -2574,25 +2597,27 @@ int Monitor::Capture() {
} // end if have image
// FIXME Copy to shmem
if ( packetqueue->packet_count(video_stream_id) or packet->keyframe or event ) {
Debug(2, "Have video packet for index (%d), adding to queue", index);
packetqueue->queuePacket(packet);
} else {
Debug(2, "Not queuing video packet for index (%d) packet count %d", index, packetqueue->packet_count(video_stream_id));
}
Debug(2, "Queuedideo packet for index (%d), adding to queue", index);
shared_data->signal = signal_check_points ? CheckSignal(capture_image) : true;
shared_data->last_write_index = index;
shared_data->last_write_time = packet->timestamp->tv_sec;
//image_buffer[index].timestamp->tv_sec;
image_count++;
Debug(2, "Unlocking packet, incrementing image_count to %d", image_count);
packet->unlock();
// We can get away with unlocking the packet early because no one will know about it until
// we unlock the packetqueue and signal them
//packet->unlock();
if ( packetqueue->packet_count(video_stream_id) or packet->keyframe or event ) {
Debug(2, "Have video packet for image index (%d), adding to queue", index);
packetqueue->queuePacket(packet);
} else {
Debug(2, "Not queuing video packet for index (%d) packet count %d", index, packetqueue->packet_count(video_stream_id));
delete packet;
}
UpdateCaptureFPS();
} else { // result == 0
// Question is, do we update last_write_index etc?
packet->unlock();
//packet->unlock();
delete packet;
return 0;
} // end if result
} // end if deinterlacing
@ -2894,7 +2919,7 @@ int Monitor::PrimeCapture() {
Debug(2, "Failed to prime %d", ret);
}
return ret;
}
} // end int Monitor::PrimeCapture()
int Monitor::PreCapture() const { return camera->PreCapture(); }
int Monitor::PostCapture() const { return camera->PostCapture(); }
@ -2902,6 +2927,7 @@ int Monitor::Close() {
if ( packetqueue ) {
delete packetqueue;
packetqueue = nullptr;
analysis_it = nullptr; // deleted by packetqueue
}
Debug(1, "Closing camera");
return camera->Close();
@ -2914,7 +2940,7 @@ void Monitor::get_ref_image() {
ZMPacket *snap;
while (
(
!( snap = packetqueue->get_analysis_packet())
!( snap = packetqueue->get_packet(analysis_it))
or
( snap->packet.stream_index != video_stream_id )
or
@ -2926,7 +2952,7 @@ void Monitor::get_ref_image() {
if ( ! snap->image ) {
snap->unlock();
// can't analyse it anyways, incremement
packetqueue->increment_analysis_it();
packetqueue->increment_it(analysis_it);
}
//usleep(10000);
}
@ -2937,7 +2963,8 @@ void Monitor::get_ref_image() {
snap->packet.stream_index, video_stream_id, snap->image_index, snap->image );
// Might not have been decoded yet FIXME
if ( snap->image ) {
ref_image.Assign(width, height, camera->Colours(), camera->SubpixelOrder(), snap->image->Buffer(), camera->ImageSize());
ref_image.Assign(width, height, camera->Colours(),
camera->SubpixelOrder(), snap->image->Buffer(), camera->ImageSize());
Debug(2, "Have ref image about to unlock");
} else {
Debug(2, "Have no ref image about to unlock");