Move analysis image assignment up to where motion detection is done do remove duplication and simplify logic. Free analysis images as well as captured images after analysis. remove extra copy of image to analysis_image. Replae a packetqueue.unlock with just deleting the locked packet. No one waits for analysis. Re-introduce sleeping in the analysis thread on error to prevent spinning
This commit is contained in:
parent
ff91ac62fb
commit
c27b0aff97
|
@ -1849,12 +1849,10 @@ bool Monitor::Analyse() {
|
||||||
|
|
||||||
// Need to guard around event creation/deletion from Reload()
|
// Need to guard around event creation/deletion from Reload()
|
||||||
std::lock_guard<std::mutex> lck(event_mutex);
|
std::lock_guard<std::mutex> lck(event_mutex);
|
||||||
Debug(3, "Have event lock");
|
|
||||||
|
|
||||||
// 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));
|
||||||
int score = 0;
|
|
||||||
// Ready means that we have captured the warmup # of frames
|
// Ready means that we have captured the warmup # of frames
|
||||||
if (!Ready()) {
|
if (!Ready()) {
|
||||||
Debug(3, "Not ready?");
|
Debug(3, "Not ready?");
|
||||||
|
@ -1862,6 +1860,7 @@ bool Monitor::Analyse() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int score = 0;
|
||||||
std::string cause;
|
std::string cause;
|
||||||
Event::StringSetMap noteSetMap;
|
Event::StringSetMap noteSetMap;
|
||||||
|
|
||||||
|
@ -1886,6 +1885,8 @@ bool Monitor::Analyse() {
|
||||||
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 (!event) {
|
||||||
|
if (!cause.empty())
|
||||||
|
cause += ", ";
|
||||||
cause += trigger_data->trigger_cause;
|
cause += trigger_data->trigger_cause;
|
||||||
}
|
}
|
||||||
Event::StringSet noteSet;
|
Event::StringSet noteSet;
|
||||||
|
@ -1904,7 +1905,7 @@ bool Monitor::Analyse() {
|
||||||
}
|
}
|
||||||
} else if (function == MOCORD or function == RECORD) {
|
} else if (function == MOCORD or function == RECORD) {
|
||||||
if (!event) {
|
if (!event) {
|
||||||
if (cause.length()) cause += ", ";
|
if (!cause.empty()) cause += ", ";
|
||||||
cause += SIGNAL_CAUSE + std::string(": Reacquired");
|
cause += SIGNAL_CAUSE + std::string(": Reacquired");
|
||||||
} else {
|
} else {
|
||||||
event->addNote(SIGNAL_CAUSE, "Reacquired");
|
event->addNote(SIGNAL_CAUSE, "Reacquired");
|
||||||
|
@ -1963,7 +1964,7 @@ bool Monitor::Analyse() {
|
||||||
packetqueue.unlock(packet_lock); // This will delete packet_lock and notify_all
|
packetqueue.unlock(packet_lock); // This will delete packet_lock and notify_all
|
||||||
packetqueue.wait();
|
packetqueue.wait();
|
||||||
// Everything may have changed, just return and start again. This needs to be more RAII
|
// Everything may have changed, just return and start again. This needs to be more RAII
|
||||||
return false;
|
return true;
|
||||||
} // end while ! decoded
|
} // end while ! decoded
|
||||||
} // end if decoding enabled
|
} // end if decoding enabled
|
||||||
|
|
||||||
|
@ -1981,17 +1982,19 @@ bool Monitor::Analyse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snap->image) {
|
if (snap->image) {
|
||||||
alarm_image.Assign(*(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");
|
||||||
ref_image.Assign(*(snap->image));
|
ref_image.Assign(*(snap->image));
|
||||||
|
alarm_image.Assign(*(snap->image));
|
||||||
} else if (!(analysis_image_count % (motion_frame_skip+1))) {
|
} else if (!(analysis_image_count % (motion_frame_skip+1))) {
|
||||||
Debug(1, "Detecting motion on image %d, image %p", snap->image_index, snap->image);
|
Debug(1, "Detecting motion on image %d, image %p", snap->image_index, snap->image);
|
||||||
// Get new score.
|
// Get new score.
|
||||||
int motion_score = DetectMotion(*(snap->image), zoneSet);
|
int motion_score = DetectMotion(*(snap->image), zoneSet);
|
||||||
|
|
||||||
|
if (!snap->analysis_image)
|
||||||
|
snap->analysis_image = new Image(*(snap->image));
|
||||||
// lets construct alarm cause. It will contain cause + names of zones alarmed
|
// lets construct alarm cause. It will contain cause + names of zones alarmed
|
||||||
snap->zone_stats.reserve(zones.size());
|
snap->zone_stats.reserve(zones.size());
|
||||||
for (const Zone &zone : zones) {
|
for (const Zone &zone : zones) {
|
||||||
|
@ -2001,8 +2004,11 @@ bool Monitor::Analyse() {
|
||||||
if (zone.Alarmed()) {
|
if (zone.Alarmed()) {
|
||||||
if (!snap->alarm_cause.empty()) snap->alarm_cause += ",";
|
if (!snap->alarm_cause.empty()) snap->alarm_cause += ",";
|
||||||
snap->alarm_cause += std::string(zone.Label());
|
snap->alarm_cause += std::string(zone.Label());
|
||||||
|
if (zone.AlarmImage())
|
||||||
|
snap->analysis_image->Overlay(*(zone.AlarmImage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
alarm_image.Assign(*(snap->analysis_image));
|
||||||
Debug(3, "After motion detection, score:%d last_motion_score(%d), new motion score(%d)",
|
Debug(3, "After motion detection, score:%d last_motion_score(%d), new motion score(%d)",
|
||||||
score, last_motion_score, motion_score);
|
score, last_motion_score, motion_score);
|
||||||
motion_frame_count += 1;
|
motion_frame_count += 1;
|
||||||
|
@ -2015,13 +2021,14 @@ bool Monitor::Analyse() {
|
||||||
} // 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);
|
||||||
|
alarm_image.Assign(*(snap->image));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Debug(1, "no image so skipping motion detection");
|
Debug(1, "no image so skipping motion detection");
|
||||||
} // end if has image
|
} // end if has image
|
||||||
score += last_motion_score;
|
score += last_motion_score;
|
||||||
} else {
|
} else {
|
||||||
Debug(1, "Not Active(%d) enabled %d active %d doing motion detection: %d",
|
Debug(1, "Not Active(%d) enabled %d shared->active %d doing motion detection: %d",
|
||||||
Active(), enabled, shared_data->active,
|
Active(), enabled, shared_data->active,
|
||||||
(function == MODECT or function == MOCORD)
|
(function == MODECT or function == MOCORD)
|
||||||
);
|
);
|
||||||
|
@ -2167,34 +2174,9 @@ bool Monitor::Analyse() {
|
||||||
snap->score = score;
|
snap->score = score;
|
||||||
|
|
||||||
if (state == PREALARM) {
|
if (state == PREALARM) {
|
||||||
// Generate analysis images if necessary
|
|
||||||
if (snap->image) {
|
|
||||||
for (const Zone &zone : zones) {
|
|
||||||
if (zone.Alarmed() and zone.AlarmImage()) {
|
|
||||||
if (!snap->analysis_image)
|
|
||||||
snap->analysis_image = new Image(*(snap->image));
|
|
||||||
snap->analysis_image->Overlay(*(zone.AlarmImage()));
|
|
||||||
} // end if zone is alarmed
|
|
||||||
} // end foreach zone
|
|
||||||
if (snap->analysis_image != nullptr)
|
|
||||||
alarm_image.Assign(*(snap->analysis_image));
|
|
||||||
} // end if image.
|
|
||||||
|
|
||||||
// incremement pre alarm image count
|
// incremement pre alarm image count
|
||||||
Event::AddPreAlarmFrame(snap->image, timestamp, score, nullptr);
|
Event::AddPreAlarmFrame(snap->image, timestamp, score, nullptr);
|
||||||
} else if (state == ALARM) {
|
} else if (state == ALARM) {
|
||||||
if (snap->image) {
|
|
||||||
for (const Zone &zone : zones) {
|
|
||||||
if (zone.Alarmed() and zone.AlarmImage()) {
|
|
||||||
if (!snap->analysis_image)
|
|
||||||
snap->analysis_image = new Image(*(snap->image));
|
|
||||||
snap->analysis_image->Overlay(*(zone.AlarmImage()));
|
|
||||||
} // end if zone is alarmed
|
|
||||||
} // end foreach zone
|
|
||||||
if (snap->analysis_image != nullptr)
|
|
||||||
alarm_image.Assign(*(snap->analysis_image));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
if (noteSetMap.size() > 0)
|
if (noteSetMap.size() > 0)
|
||||||
event->updateNotes(noteSetMap);
|
event->updateNotes(noteSetMap);
|
||||||
|
@ -2246,12 +2228,19 @@ 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) and !savejpegs) {
|
if (snap->image and (videowriter == PASSTHROUGH)) {
|
||||||
|
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)) {
|
||||||
|
Debug(1, "Deleting analysis image data for %d", snap->image_index);
|
||||||
|
delete snap->analysis_image;
|
||||||
|
snap->analysis_image = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packetqueue.clearPackets(snap);
|
packetqueue.clearPackets(snap);
|
||||||
|
|
||||||
|
@ -2261,7 +2250,8 @@ bool Monitor::Analyse() {
|
||||||
analysis_image_count++;
|
analysis_image_count++;
|
||||||
}
|
}
|
||||||
packetqueue.increment_it(analysis_it);
|
packetqueue.increment_it(analysis_it);
|
||||||
packetqueue.unlock(packet_lock);
|
delete packet_lock;
|
||||||
|
//packetqueue.unlock(packet_lock);
|
||||||
shared_data->last_read_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
shared_data->last_read_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue