Skip to content

Commit 2a9b7d1

Browse files
Merge remote-tracking branch 'upstream/master' into ai_server
2 parents 5982229 + 8a5a545 commit 2a9b7d1

File tree

19 files changed

+130
-75
lines changed

19 files changed

+130
-75
lines changed

scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,11 +447,10 @@ our @options = (
447447
},
448448
{
449449
name => 'ZM_GO2RTC_PATH',
450-
default => 'http://127.0.0.1:1984/api',
450+
default => '',
451451
description => 'URL for Go2RTC API.',
452452
help => q`This value points to the location of the Go2RTC API
453-
install, including username and password. If left blank, this
454-
will default to http://127.0.0.1:1984/api
453+
install, including username and password.
455454
`,
456455
type => $types{string},
457456
category => 'system',

src/netint_network.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ void ni_cleanup_network_context(NiNetworkContext *network_ctx, bool hwframe)
133133

134134
int ni_alloc_network_context(NiNetworkContext **p_network_ctx,
135135
bool hwframe, int devid, int keep_alive_timeout, int scale_format,
136-
int scale_width, int scale_height, const char *nbg_file)
136+
unsigned int scale_width, unsigned int scale_height, const char *nbg_file)
137137
{
138138
int ret;
139139

src/netint_network.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ extern int ni_get_network_output(NiNetworkContext *network_ctx, bool hwframe,
9191
uint8_t **data);
9292
extern int ni_alloc_network_context(NiNetworkContext **p_network_ctx,
9393
bool hwframe, int devid, int keep_alive_timeout, int scale_format,
94-
int scale_width, int scale_height, const char *nbg_file);
94+
unsigned int scale_width, unsigned int scale_height, const char *nbg_file);
9595
extern void ni_cleanup_network_context(NiNetworkContext *network_ctx, bool hwframe);
9696
extern int ni_convert_to_tensor(NiNetworkContext *network_ctx, NiNetworkFrame *frame, void *data, unsigned int index);
9797
extern int ni_convert_to_tensors(NiNetworkContext *network_ctx, NiNetworkFrame *frame, void **data);

src/zm_monitor.cpp

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ Monitor::Monitor() :
175175
user(),
176176
pass(),
177177
//path
178+
onvif_event_listener(false),
179+
use_Amcrest_API(false),
178180
//device
179181
palette(0),
180182
channel(0),
@@ -1172,20 +1174,18 @@ bool Monitor::connect() {
11721174
//Janus_Manager->add_to_janus();
11731175
}
11741176

1175-
// ONVIF and Amcrest Setup
1176-
// For now, only support one event type per camera, so share some state.
1177-
if (onvif_event_listener) { //
1177+
if (use_Amcrest_API) {
1178+
Amcrest_Manager = new AmcrestAPI(this);
1179+
}
1180+
1181+
if (onvif_event_listener) { //
11781182
Debug(1, "Starting ONVIF");
11791183
if (onvif_options.find("closes_event") !=
11801184
std::string::npos) { // Option to indicate that ONVIF will send a
11811185
// close event message
11821186
Event_Poller_Closes_Event = true;
11831187
}
1184-
if (use_Amcrest_API) {
1185-
Amcrest_Manager = new AmcrestAPI(this);
1186-
} else { // using GSOAP
1187-
onvif = new ONVIF(this);
1188-
} // end if Armcrest or GSOAP
1188+
onvif = new ONVIF(this);
11891189
} else {
11901190
Debug(1, "Not Starting ONVIF");
11911191
} // End ONVIF Setup
@@ -2000,7 +2000,7 @@ int Monitor::Analyse() {
20002000

20012001
#ifdef WITH_GSOAP
20022002
if (onvif_event_listener) {
2003-
if ((onvif and onvif->isAlarmed()) or (Amcrest_Manager and Amcrest_Manager->isAlarmed())) {
2003+
if (onvif and onvif->isAlarmed()) {
20042004
score += 9;
20052005
Debug(4, "Triggered on ONVIF");
20062006
Event::StringSet noteSet;
@@ -2015,6 +2015,16 @@ int Monitor::Analyse() {
20152015
} // end if (onvif_event_listener && Event_Poller_Healthy)
20162016
#endif
20172017

2018+
if (Amcrest_Manager and Amcrest_Manager->isAlarmed()) {
2019+
score += 9;
2020+
Debug(4, "Triggered on AMCREST");
2021+
Event::StringSet noteSet;
2022+
noteSet.insert("AMCREST");
2023+
Amcrest_Manager->setNotes(noteSet);
2024+
noteSetMap[MOTION_CAUSE] = noteSet;
2025+
cause += "AMCREST";
2026+
}
2027+
20182028
// Specifically told to be on. Setting the score here is not enough to trigger the alarm. Must jump directly to ALARM
20192029
if (trigger_data->trigger_state == TriggerState::TRIGGER_ON) {
20202030
score += trigger_data->trigger_score;
@@ -2353,14 +2363,13 @@ int Monitor::Analyse() {
23532363
} else if (event_close_mode == CLOSE_TIME) {
23542364
Debug(1, "CLOSE_MODE Time");
23552365
if (std::chrono::duration_cast<Seconds>(packet->timestamp.time_since_epoch()) % section_length == Seconds(0)) {
2356-
Info("%s: %03d - Closing event %" PRIu64 ", section end forced %" PRIi64 " - %" PRIi64 " = %" PRIi64 " >= %" PRIi64,
2366+
Info("%s: %03d - Closing event %" PRIu64 ", section end forced %" PRIi64 " %% %" PRIi64 " = 0",
23572367
name.c_str(),
23582368
packet->image_index,
23592369
event->Id(),
23602370
static_cast<int64>(std::chrono::duration_cast<Seconds>(packet->timestamp.time_since_epoch()).count()),
2361-
static_cast<int64>(std::chrono::duration_cast<Seconds>(event->StartTime().time_since_epoch()).count()),
2362-
static_cast<int64>(std::chrono::duration_cast<Seconds>(packet->timestamp - event->StartTime()).count()),
2363-
static_cast<int64>(Seconds(section_length).count()));
2371+
static_cast<int64>(Seconds(section_length).count())
2372+
);
23642373
closeEvent();
23652374
}
23662375
} else if (event_close_mode == CLOSE_IDLE) {
@@ -3800,14 +3809,21 @@ Event * Monitor::openEvent(
38003809
*analysis_it,
38013810
(cause == "Continuous" ? 0 : (pre_event_count > alarm_frame_count ? pre_event_count : alarm_frame_count))
38023811
);
3803-
auto packet = *(*start_it);
3804-
auto av_packet = packet->av_packet();
3805-
3812+
auto starting_packet = *(*start_it);
3813+
auto av_packet = starting_packet->av_packet();
38063814
ZM_DUMP_PACKET(av_packet, "start packet");
38073815

3808-
auto starting_packet = *start_it;
3809-
event = new Event(this, start_it, (*starting_packet)->timestamp, cause, noteSetMap);
3810-
SetVideoWriterStartTime((*starting_packet)->timestamp);
3816+
event = new Event(this, start_it, starting_packet->timestamp, cause, noteSetMap);
3817+
SetVideoWriterStartTime(starting_packet->timestamp);
3818+
3819+
float start_duration = FPSeconds(packet_lock->packet_->timestamp - starting_packet->timestamp).count();
3820+
Debug(1, "Event duration at start: %.2f", start_duration);
3821+
if (start_duration >= Seconds(min_section_length).count()) {
3822+
Warning("Starting keyframe packet is more than %" PRId64 " seconds ago. Keyframe interval must be larger than that. "
3823+
"Either increase min_section_length or decrease keyframe interval. Automatically increasing min_section_length to %d seconds",
3824+
static_cast<int64>(Seconds(min_section_length).count()), static_cast<int>(ceil(start_duration)));
3825+
min_section_length = Seconds(static_cast<int>(ceil(start_duration)) + 1);
3826+
}
38113827

38123828
shared_data->last_event_id = event->Id();
38133829
strncpy(shared_data->alarm_cause, cause.c_str(),

src/zm_monitor.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,9 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
400400
_wsnt__RenewResponse wsnt__RenewResponse;
401401
PullPointSubscriptionBindingProxy proxyEvent;
402402
void set_credentials(struct soap *soap);
403-
std::unordered_map<std::string, std::string> alarms;
404403
#endif
405-
std::mutex alarms_mutex;
406-
404+
std::unordered_map<std::string, std::string> alarms;
405+
std::mutex alarms_mutex;
407406
public:
408407
explicit ONVIF(Monitor *parent_);
409408
~ONVIF();
@@ -419,7 +418,7 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
419418
};
420419

421420
class AmcrestAPI {
422-
protected:
421+
private:
423422
Monitor *parent;
424423
bool alarmed;
425424
bool healthy;
@@ -430,9 +429,11 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
430429
CURLM *curl_multi = nullptr;
431430
CURL *Amcrest_handle = nullptr;
432431
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp);
432+
std::unordered_map<std::string, std::string> alarms;
433433
std::mutex alarms_mutex;
434434
std::mutex response_mutex;
435435

436+
void SetNoteSet(Event::StringSet &noteSet);
436437
public:
437438
explicit AmcrestAPI(Monitor *parent_);
438439
~AmcrestAPI();
@@ -441,6 +442,7 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
441442
int start();
442443
bool isAlarmed() const { return alarmed; };
443444
bool isHealthy() const { return healthy; };
445+
void setNotes(Event::StringSet &noteSet) { SetNoteSet(noteSet); };
444446
};
445447

446448
class RTSP2WebManager {

src/zm_monitor_amcrest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,15 @@ size_t Monitor::AmcrestAPI::WriteCallback(
194194
//Debug(1, "AMCREST callback %s", (char *)contents);
195195
return size * nmemb;
196196
}
197+
198+
void Monitor::AmcrestAPI::SetNoteSet(Event::StringSet &noteSet) {
199+
std::unique_lock<std::mutex> lck(alarms_mutex);
200+
if (alarms.empty()) return;
201+
202+
std::string note = "";
203+
for (auto it = alarms.begin(); it != alarms.end(); ++it) {
204+
note = it->first + "/" + it->second;
205+
noteSet.insert(note);
206+
}
207+
}
208+

src/zm_poll_thread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#include "zm_poll_thread.h"
22

3+
#include "zm_logger.h"
34
#include "zm_monitor.h"
45
#include "zm_signal.h"
5-
#include "zm_time.h"
66

77
PollThread::PollThread(Monitor *monitor) :
88
monitor_(monitor), terminate_(false) {

src/zm_videostore.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,9 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> zm_packet)
11491149

11501150
if (zm_packet->hw_frame) {
11511151
av_frame_ref(frame.get(), zm_packet->hw_frame.get());
1152-
} else if (!zm_packet->out_frame) {
1152+
} else if (zm_packet->out_frame) {
1153+
av_frame_ref(frame.get(), zm_packet->out_frame.get());
1154+
} else {
11531155
Debug(3, "Have no out frame. codec is %s sw_pf %d %s hw_pf %d %s %dx%d",
11541156
chosen_codec_data->codec_name,
11551157
chosen_codec_data->sw_pix_fmt, av_get_pix_fmt_name(chosen_codec_data->sw_pix_fmt),
@@ -1331,16 +1333,18 @@ int VideoStore::writeVideoFramePacket(const std::shared_ptr<ZMPacket> zm_packet)
13311333
// Some hwaccel codecs may get full if we only receive one pkt for one frame
13321334

13331335
do {
1336+
zm_dump_frame(frame.get(), "sending frame");
13341337
int ret = avcodec_send_frame(video_out_ctx, frame.get());
1335-
if (ret == AVERROR(EAGAIN) and !zm_terminate) {
1336-
Debug(1, "Got EAGAIN sending frame");
1337-
continue;
1338-
}
13391338
if (ret < 0) {
1340-
Error("Could not send frame (error '%s')", av_make_error_string(ret).c_str());
1341-
return ret;
1339+
if (AVERROR(EAGAIN) != ret) {
1340+
Error("Could not send frame (error '%s')", av_make_error_string(ret).c_str());
1341+
return ret;
1342+
} else {
1343+
Debug(3, "Got EAGAIN");
1344+
}
1345+
} else {
1346+
break;
13421347
}
1343-
break;
13441348
} while(!zm_terminate);
13451349

13461350
while (!zm_terminate) {

web/ajax/modals/settings.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,17 @@
4646
<table id="contentTable" class="major">
4747
<tbody>
4848
<?php
49-
$ctls = shell_exec('v4l2-ctl -d '.$monitor->Device().' --list-ctrls');
50-
49+
if (!$monitor->Device()) {
50+
ZM\Warning("Please populate monitor Device");
51+
} else if (!file_exists($monitor->Device())) {
52+
ZM\Warning($monitor->Device() . " not found. Will not be able to get ctrls from it.");
53+
} else {
54+
$ctls = shell_exec('v4l2-ctl -d '.escapeshellarg($monitor->Device()).' --list-ctrls');
55+
ZM\Debug("CTLS $ctls");
56+
}
5157
if (!$ctls) {
52-
ZM\Warning('Guessing v4l ctrls. We need v4l2-ctl please install it');
53-
$ctls = '
58+
ZM\Warning('Guessing v4l ctrls. We need v4l2-ctl please install it');
59+
$ctls = '
5460
brightness 0x00980900 (int) : min=-10 max=10 step=1 default=0 value=8
5561
contrast 0x00980901 (int) : min=0 max=20 step=1 default=10 value=12
5662
saturation 0x00980902 (int) : min=0 max=10 step=1 default=7 value=6

web/includes/Monitor.php

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,17 +1178,9 @@ class="monitorStream imageFeed"
11781178
} else if ($player == 'zms') {
11791179
if ( $options['mode'] == 'stream' and canStream() ) {
11801180
$options['mode'] = 'jpeg';
1181-
$streamSrc = $this->getStreamSrc($options);
1182-
$html .= getImageStreamHTML('liveStream'.$this->Id(), $streamSrc, $options['width'], $options['height'], $this->Name());
1183-
} else if ( $options['mode'] == 'single' and canStream() ) {
1184-
$streamSrc = $this->getStreamSrc($options);
1185-
$html .= getImageStreamHTML('liveStream'.$this->Id(), $streamSrc, $options['width'], $options['height'], $this->Name());
1186-
} else if ( $options['mode'] == 'paused' and canStream() ) {
1187-
$streamSrc = $this->getStreamSrc($options);
1188-
$html .= getImageStreamHTML('liveStream'.$this->Id(), $streamSrc, $options['width'], $options['height'], $this->Name());
1189-
} else {
1190-
Debug("What mode or canStream? ".$options['mode']." ".canStream());
11911181
}
1182+
$streamSrc = $this->getStreamSrc($options);
1183+
$html .= getImageStreamHTML('liveStream'.$this->Id(), $streamSrc, $options['width'], $options['height'], $this->Name());
11921184
} else if ($this->JanusEnabled() or ($this->RTSP2WebEnabled() and ZM_RTSP2WEB_PATH) or ($this->Go2RTCEnabled() and ZM_GO2RTC_PATH)) {
11931185
$html .= '<video id="liveStream'.$this->Id().'" '.
11941186
((isset($options['width']) and $options['width'] and $options['width'] != '0')?'width="'.$options['width'].'"':'').

0 commit comments

Comments
 (0)