Revert my idea of having ONVIF and TRIGGER code start/end events. Move code to tst for Ready() up above ONVIF and TRIGGER code. When waiting for decode, junk the idea of locking in the packetqueue. Since waiting releases the lock, we should be ok waiting and notifying in the packet. (I know there was a time when I felt this was necessary and I think it had to do with the deinterlacing case, but I've simplified that code too).
This commit is contained in:
parent
274ffd7da0
commit
9240a93ef5
|
@ -1839,6 +1839,12 @@ bool Monitor::Analyse() {
|
||||||
packetqueue.increment_it(analysis_it);
|
packetqueue.increment_it(analysis_it);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Ready means that we have captured the warmup # of frames
|
||||||
|
if (!Ready()) {
|
||||||
|
Debug(3, "Not ready?");
|
||||||
|
delete packet_lock;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// signal is set by capture
|
// signal is set by capture
|
||||||
bool signal = shared_data->signal;
|
bool signal = shared_data->signal;
|
||||||
|
@ -1853,54 +1859,36 @@ bool Monitor::Analyse() {
|
||||||
// if we have been told to be OFF, then we are off and don't do any processing.
|
// if we have been told to be OFF, then we are off and don't do any processing.
|
||||||
if (trigger_data->trigger_state != TriggerState::TRIGGER_OFF) {
|
if (trigger_data->trigger_state != TriggerState::TRIGGER_OFF) {
|
||||||
Debug(4, "Trigger not OFF state is (%d)", int(trigger_data->trigger_state));
|
Debug(4, "Trigger not OFF state is (%d)", int(trigger_data->trigger_state));
|
||||||
// Ready means that we have captured the warmup # of frames
|
|
||||||
if (!Ready()) {
|
|
||||||
Debug(3, "Not ready?");
|
|
||||||
delete packet_lock;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int score = 0;
|
int score = 0;
|
||||||
std::string cause;
|
std::string cause;
|
||||||
Event::StringSetMap noteSetMap;
|
Event::StringSetMap noteSetMap;
|
||||||
|
|
||||||
#ifdef WITH_GSOAP
|
#ifdef WITH_GSOAP
|
||||||
if (ONVIF_Trigger_State) {
|
if (onvif_event_listener && ONVIF_Healthy) {
|
||||||
score += 9;
|
if (ONVIF_Trigger_State) {
|
||||||
Debug(1, "Triggered on ONVIF");
|
score += 9;
|
||||||
if (!event) {
|
Debug(1, "Triggered on ONVIF");
|
||||||
Event::StringSet noteSet;
|
Event::StringSet noteSet;
|
||||||
noteSet.insert("ONVIF2");
|
noteSet.insert("ONVIF2");
|
||||||
noteSetMap[MOTION_CAUSE] = noteSet;
|
noteSetMap[MOTION_CAUSE] = noteSet;
|
||||||
|
|
||||||
event = openEvent(snap, "ONVIF", noteSetMap);
|
|
||||||
cause += "ONVIF";
|
cause += "ONVIF";
|
||||||
} else {
|
//If the camera isn't going to send an event close, we need to close it here, but only after it has actually triggered an alarm.
|
||||||
event->addNote(MOTION_CAUSE, "ONVIF2");
|
if (!ONVIF_Closes_Event && state == ALARM)
|
||||||
// Add to cause
|
ONVIF_Trigger_State = FALSE;
|
||||||
}
|
} // end ONVIF_Trigger
|
||||||
// Regardless of previous state, we go to ALARM
|
} // end if (onvif_event_listener && ONVIF_Healthy)
|
||||||
shared_data->state = state = ALARM;
|
|
||||||
//If the camera isn't going to send an event close, we need to close it here, but only after it has actually triggered an alarm.
|
|
||||||
if (!ONVIF_Closes_Event && state == ALARM)
|
|
||||||
ONVIF_Trigger_State = FALSE;
|
|
||||||
} // end ONVIF_Trigger
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Specifically told to be on. Setting the score here will trigger the alarm.
|
// Specifically told to be on. Setting the score here is not enough to trigger the alarm. Must jump directly to ALARM
|
||||||
if (trigger_data->trigger_state == TriggerState::TRIGGER_ON) {
|
if (trigger_data->trigger_state == TriggerState::TRIGGER_ON) {
|
||||||
score += trigger_data->trigger_score;
|
score += trigger_data->trigger_score;
|
||||||
Debug(1, "Triggered on score += %d => %d", trigger_data->trigger_score, score);
|
Debug(1, "Triggered on score += %d => %d", trigger_data->trigger_score, score);
|
||||||
if (!event) {
|
if (!cause.empty()) cause += ", ";
|
||||||
Event::StringSet noteSet;
|
cause += trigger_data->trigger_cause;
|
||||||
noteSet.insert(trigger_data->trigger_text);
|
Event::StringSet noteSet;
|
||||||
noteSetMap[trigger_data->trigger_cause] = noteSet;
|
noteSet.insert(trigger_data->trigger_text);
|
||||||
event = openEvent(snap, trigger_data->trigger_cause, noteSetMap);
|
noteSetMap[trigger_data->trigger_cause] = noteSet;
|
||||||
Info("%s: %03d - Opening new event %" PRIu64 ", alarm start", name.c_str(), analysis_image_count, event->Id());
|
|
||||||
} else {
|
|
||||||
event->addNote(trigger_data->trigger_cause, trigger_data->trigger_text);
|
|
||||||
// Need to know if we should end the previous and start a new one, or just add the data
|
|
||||||
}
|
|
||||||
shared_data->state = state = ALARM;
|
shared_data->state = state = ALARM;
|
||||||
} // end if trigger_on
|
} // end if trigger_on
|
||||||
|
|
||||||
|
@ -1968,14 +1956,21 @@ bool Monitor::Analyse() {
|
||||||
|
|
||||||
/* try to stay behind the decoder. */
|
/* try to stay behind the decoder. */
|
||||||
if (decoding_enabled) {
|
if (decoding_enabled) {
|
||||||
if (!snap->decoded and !zm_terminate and !analysis_thread->Stopped()) {
|
while (!snap->decoded and !zm_terminate and !analysis_thread->Stopped()) {
|
||||||
// Need to wait for the decoder thread.
|
// Need to wait for the decoder thread.
|
||||||
|
// decoder thread might be waiting on the lock for this packet.
|
||||||
|
// So we need to relinquish the lock and wait. Waiting automatically relinquishes the lock
|
||||||
|
// So...
|
||||||
Debug(1, "Waiting for decode");
|
Debug(1, "Waiting for decode");
|
||||||
packetqueue.unlock(packet_lock); // This will delete packet_lock and notify_all
|
packet_lock->wait();
|
||||||
packetqueue.wait();
|
//packetqueue.unlock(packet_lock); // This will delete packet_lock and notify_all
|
||||||
// Everything may have changed, just return and start again. This needs to be more RAII
|
//packetqueue.wait();
|
||||||
return true;
|
////packet_lock->lock();
|
||||||
} // end while ! decoded
|
} // end while ! decoded
|
||||||
|
if (zm_terminate or analysis_thread->Stopped()) {
|
||||||
|
delete packet_lock;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} // end if decoding enabled
|
} // end if decoding enabled
|
||||||
|
|
||||||
if (Active() and (function == MODECT or function == MOCORD)) {
|
if (Active() and (function == MODECT or function == MOCORD)) {
|
||||||
|
@ -1990,7 +1985,6 @@ bool Monitor::Analyse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snap->image) {
|
if (snap->image) {
|
||||||
|
|
||||||
// decoder may not have been able to provide an image
|
// decoder may not have been able to provide an image
|
||||||
if (!ref_image.Buffer()) {
|
if (!ref_image.Buffer()) {
|
||||||
Debug(1, "Assigning instead of Detecting");
|
Debug(1, "Assigning instead of Detecting");
|
||||||
|
@ -2024,8 +2018,9 @@ bool Monitor::Analyse() {
|
||||||
|
|
||||||
if (snap->score) {
|
if (snap->score) {
|
||||||
if (cause.length()) cause += ", ";
|
if (cause.length()) cause += ", ";
|
||||||
cause += MOTION_CAUSE+std::string(":")+snap->alarm_cause;
|
cause += MOTION_CAUSE + std::string(":") + snap->alarm_cause;
|
||||||
noteSetMap[MOTION_CAUSE] = zoneSet;
|
noteSetMap[MOTION_CAUSE] = zoneSet;
|
||||||
|
score += snap->score;
|
||||||
} // end if motion_score
|
} // end if motion_score
|
||||||
} else {
|
} else {
|
||||||
Debug(1, "Skipped motion detection last motion score was %d", last_motion_score);
|
Debug(1, "Skipped motion detection last motion score was %d", last_motion_score);
|
||||||
|
@ -2069,13 +2064,15 @@ bool Monitor::Analyse() {
|
||||||
Info("%s: %03d - Opened new event %" PRIu64 ", continuous section start",
|
Info("%s: %03d - Opened new event %" PRIu64 ", continuous section start",
|
||||||
name.c_str(), analysis_image_count, event->Id());
|
name.c_str(), analysis_image_count, event->Id());
|
||||||
/* To prevent cancelling out an existing alert\prealarm\alarm state */
|
/* To prevent cancelling out an existing alert\prealarm\alarm state */
|
||||||
|
// This ignores current score status. This should all come after the state machine calculations
|
||||||
if (state == IDLE) {
|
if (state == IDLE) {
|
||||||
shared_data->state = state = TAPE;
|
shared_data->state = state = TAPE;
|
||||||
}
|
}
|
||||||
} // end if ! event
|
} // end if ! event
|
||||||
} // end if RECORDING
|
} // end if RECORDING
|
||||||
|
|
||||||
if ((snap->score > 0) and (function != MONITOR)) {
|
// If motion detecting, score will be > 0 on motion, but if skipping frames, might not be. So also test snap->score
|
||||||
|
if ((score > 0) or ((snap->score > 0) and (function != MONITOR))) {
|
||||||
if ((state == IDLE) || (state == TAPE) || (state == PREALARM)) {
|
if ((state == IDLE) || (state == TAPE) || (state == PREALARM)) {
|
||||||
// If we should end then previous continuous event and start a new non-continuous event
|
// If we should end then previous continuous event and start a new non-continuous event
|
||||||
if (event && event->Frames()
|
if (event && event->Frames()
|
||||||
|
@ -2133,8 +2130,8 @@ bool Monitor::Analyse() {
|
||||||
if (state == ALARM) {
|
if (state == ALARM) {
|
||||||
last_alarm_count = analysis_image_count;
|
last_alarm_count = analysis_image_count;
|
||||||
} // This is needed so post_event_count counts after last alarmed frames while in ALARM not single alarmed frames while ALERT
|
} // This is needed so post_event_count counts after last alarmed frames while in ALARM not single alarmed frames while ALERT
|
||||||
} else if (!score and snap->score == 0) { // snap->score means -1 which means didn't do motion detection so don't do state transition
|
} else if (!score and (snap->score == 0)) { // snap->score means -1 which means didn't do motion detection so don't do state transition
|
||||||
Debug(1, "!score");
|
Debug(1, "!score %s", State_Strings[state].c_str());
|
||||||
alert_to_alarm_frame_count = alarm_frame_count; // load same value configured for alarm_frame_count
|
alert_to_alarm_frame_count = alarm_frame_count; // load same value configured for alarm_frame_count
|
||||||
|
|
||||||
if (state == ALARM) {
|
if (state == ALARM) {
|
||||||
|
@ -2238,17 +2235,17 @@ bool Monitor::Analyse() {
|
||||||
// In the case where people have pre-alarm frames, the web ui will generate the frame images
|
// In the case where people have pre-alarm frames, the web ui will generate the frame images
|
||||||
// from the mp4. So no one will notice anyways.
|
// from the mp4. So no one will notice anyways.
|
||||||
if (snap->image and (videowriter == PASSTHROUGH)) {
|
if (snap->image and (videowriter == PASSTHROUGH)) {
|
||||||
if (!savejpegs) {
|
if (!savejpegs) {
|
||||||
Debug(1, "Deleting image data for %d", snap->image_index);
|
Debug(1, "Deleting image data for %d", snap->image_index);
|
||||||
// Don't need raw images anymore
|
// Don't need raw images anymore
|
||||||
delete snap->image;
|
delete snap->image;
|
||||||
snap->image = nullptr;
|
snap->image = nullptr;
|
||||||
}
|
}
|
||||||
if (snap->analysis_image and !(savejpegs & 2)) {
|
if (snap->analysis_image and !(savejpegs & 2)) {
|
||||||
Debug(1, "Deleting analysis image data for %d", snap->image_index);
|
Debug(1, "Deleting analysis image data for %d", snap->image_index);
|
||||||
delete snap->analysis_image;
|
delete snap->analysis_image;
|
||||||
snap->analysis_image = nullptr;
|
snap->analysis_image = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packetqueue.clearPackets(snap);
|
packetqueue.clearPackets(snap);
|
||||||
|
@ -2571,7 +2568,8 @@ bool Monitor::Decode() {
|
||||||
std::shared_ptr<ZMPacket> packet = packet_lock->packet_;
|
std::shared_ptr<ZMPacket> packet = packet_lock->packet_;
|
||||||
if (packet->codec_type != AVMEDIA_TYPE_VIDEO) {
|
if (packet->codec_type != AVMEDIA_TYPE_VIDEO) {
|
||||||
Debug(4, "Not video");
|
Debug(4, "Not video");
|
||||||
packetqueue.unlock(packet_lock);
|
//packetqueue.unlock(packet_lock);
|
||||||
|
delete packet_lock;
|
||||||
return true; // Don't need decode
|
return true; // Don't need decode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2677,24 +2675,31 @@ bool Monitor::Decode() {
|
||||||
capture_image->Deinterlace_Blend();
|
capture_image->Deinterlace_Blend();
|
||||||
} else if (deinterlacing_value == 4) {
|
} else if (deinterlacing_value == 4) {
|
||||||
while (!zm_terminate) {
|
while (!zm_terminate) {
|
||||||
|
// ICON FIXME SHould we not clone decoder_it?
|
||||||
ZMLockedPacket *deinterlace_packet_lock = packetqueue.get_packet(decoder_it);
|
ZMLockedPacket *deinterlace_packet_lock = packetqueue.get_packet(decoder_it);
|
||||||
if (!deinterlace_packet_lock) {
|
if (!deinterlace_packet_lock) {
|
||||||
packetqueue.unlock(packet_lock);
|
delete packet_lock;
|
||||||
|
//packetqueue.unlock(packet_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deinterlace_packet_lock->packet_->codec_type == packet->codec_type) {
|
if (deinterlace_packet_lock->packet_->codec_type == packet->codec_type) {
|
||||||
capture_image->Deinterlace_4Field(deinterlace_packet_lock->packet_->image, (deinterlacing>>8)&0xff);
|
capture_image->Deinterlace_4Field(deinterlace_packet_lock->packet_->image, (deinterlacing>>8)&0xff);
|
||||||
packetqueue.unlock(deinterlace_packet_lock);
|
delete deinterlace_packet_lock;
|
||||||
|
//packetqueue.unlock(deinterlace_packet_lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
packetqueue.unlock(deinterlace_packet_lock);
|
delete deinterlace_packet_lock;
|
||||||
|
//packetqueue.unlock(deinterlace_packet_lock);
|
||||||
packetqueue.increment_it(decoder_it);
|
packetqueue.increment_it(decoder_it);
|
||||||
}
|
}
|
||||||
if (zm_terminate) return false;
|
if (zm_terminate) {
|
||||||
|
delete packet_lock;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (deinterlacing_value == 5) {
|
} else if (deinterlacing_value == 5) {
|
||||||
capture_image->Deinterlace_Blend_CustomRatio((deinterlacing>>8)&0xff);
|
capture_image->Deinterlace_Blend_CustomRatio((deinterlacing>>8)&0xff);
|
||||||
}
|
}
|
||||||
}
|
} // end if deinterlacing_value
|
||||||
|
|
||||||
if (orientation != ROTATE_0) {
|
if (orientation != ROTATE_0) {
|
||||||
Debug(3, "Doing rotation");
|
Debug(3, "Doing rotation");
|
||||||
|
@ -2731,7 +2736,8 @@ bool Monitor::Decode() {
|
||||||
shared_data->signal = (capture_image and signal_check_points) ? CheckSignal(capture_image) : true;
|
shared_data->signal = (capture_image and signal_check_points) ? CheckSignal(capture_image) : true;
|
||||||
shared_data->last_write_index = index;
|
shared_data->last_write_index = index;
|
||||||
shared_data->last_write_time = std::chrono::system_clock::to_time_t(packet->timestamp);
|
shared_data->last_write_time = std::chrono::system_clock::to_time_t(packet->timestamp);
|
||||||
packetqueue.unlock(packet_lock);
|
delete packet_lock;
|
||||||
|
//packetqueue.unlock(packet_lock);
|
||||||
return true;
|
return true;
|
||||||
} // end bool Monitor::Decode()
|
} // end bool Monitor::Decode()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue