Skip to content

Commit

Permalink
Merge branch 'master' into patch-474778
Browse files Browse the repository at this point in the history
  • Loading branch information
IgorA100 authored Nov 4, 2024
2 parents 61d07af + 6a2b1b0 commit 0cf4692
Show file tree
Hide file tree
Showing 32 changed files with 1,121 additions and 146 deletions.
2 changes: 1 addition & 1 deletion distros/redhat/zoneminder.spec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
%global zmtargetdistro %{?rhel:el%{rhel}}%{!?rhel:fc%{fedora}}

Name: zoneminder
Version: 1.37.64
Version: 1.37.65
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
Expand Down
5 changes: 0 additions & 5 deletions scripts/zmupdate.pl.in
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,6 @@ if ( $version ) {
my ( $detaint_version ) = $version =~ /^([\w.]+)$/;
$version = $detaint_version;

if ( ZM_VERSION eq $version ) {
print("\nDatabase already at version $version, update skipped.\n\n");
exit(0);
}

my $start_zm = 0;
print("\nInitiating database upgrade to version ".ZM_VERSION." from version $version\n");
if ( $interactive ) {
Expand Down
3 changes: 3 additions & 0 deletions src/zm_analysis_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ AnalysisThread::AnalysisThread(Monitor *monitor) :

AnalysisThread::~AnalysisThread() {
Stop();
if (thread_.joinable()) thread_.join();
}

void AnalysisThread::Start() {
Expand All @@ -22,6 +23,8 @@ void AnalysisThread::Start() {

void AnalysisThread::Stop() {
terminate_ = true;
}
void AnalysisThread::Join() {
if (thread_.joinable()) thread_.join();
}

Expand Down
1 change: 1 addition & 0 deletions src/zm_analysis_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class AnalysisThread {

void Start();
void Stop();
void Join();
bool Stopped() const { return terminate_; }

private:
Expand Down
4 changes: 4 additions & 0 deletions src/zm_decoder_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ DecoderThread::DecoderThread(Monitor *monitor) :

DecoderThread::~DecoderThread() {
Stop();
if (thread_.joinable()) thread_.join();
}

void DecoderThread::Start() {
Expand All @@ -20,6 +21,9 @@ void DecoderThread::Start() {

void DecoderThread::Stop() {
terminate_ = true;
}

void DecoderThread::Join() {
if (thread_.joinable()) thread_.join();
}

Expand Down
1 change: 1 addition & 0 deletions src/zm_decoder_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class DecoderThread {

void Start();
void Stop();
void Join();

private:
void Run();
Expand Down
15 changes: 14 additions & 1 deletion src/zm_eventstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,13 +642,13 @@ void EventStream::processCommand(const CmdMsg *msg) {
break;
}


struct {
uint64_t event_id;
//Microseconds duration;
double duration;
//Microseconds progress;
double progress;
double fps;
int rate;
int zoom;
int scale;
Expand All @@ -667,6 +667,18 @@ void EventStream::processCommand(const CmdMsg *msg) {
status_data.zoom = zoom;
status_data.scale = scale;
status_data.paused = paused;

FPSeconds elapsed = now - last_fps_update;
if (elapsed.count() > 0) {
actual_fps = (actual_fps + (frame_count - last_frame_count) / elapsed.count())/2;
Debug(1, "actual_fps %f = old + frame_count %d - last %d / elapsed %.2f from %.2f - %.2f", actual_fps, frame_count, last_frame_count,
elapsed.count(), FPSeconds(now.time_since_epoch()).count(), FPSeconds(last_fps_update.time_since_epoch()).count());
last_frame_count = frame_count;
last_fps_update = now;
}

status_data.fps = actual_fps;

Debug(2, "Event:%" PRIu64 ", Duration %f, Paused:%d, progress:%f Rate:%d, Zoom:%d Scale:%d",
status_data.event_id,
FPSeconds(status_data.duration).count(),
Expand Down Expand Up @@ -1026,6 +1038,7 @@ void EventStream::runStream() {
zm_terminate = true;
break;
}
frame_count++;
}

{
Expand Down
13 changes: 8 additions & 5 deletions src/zm_ffmpeg_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,13 @@ int FfmpegCamera::Capture(std::shared_ptr<ZMPacket> &zm_packet) {
Info("Suspected 32bit wraparound in input pts. %" PRId64, packet->pts);
return -1;
} else if (packet->pts - lastPTS < -10*stream->time_base.den) {
// -10 is for 10 seconds. Avigilon cameras seem to jump around by about 36 constantly
double pts_time = static_cast<double>(av_rescale_q(packet->pts, stream->time_base, AV_TIME_BASE_Q)) / AV_TIME_BASE;
double last_pts_time = static_cast<double>(av_rescale_q(lastPTS, stream->time_base, AV_TIME_BASE_Q)) / AV_TIME_BASE;
logPrintf(Logger::WARNING + monitor->Importance(), "Stream pts jumped back in time too far. pts %.2f - last pts %.2f = %.2f > 10seconds",
pts_time, last_pts_time, pts_time - last_pts_time);
if (!monitor->WallClockTimestamps()) {
// -10 is for 10 seconds. Avigilon cameras seem to jump around by about 36 constantly
double pts_time = static_cast<double>(av_rescale_q(packet->pts, stream->time_base, AV_TIME_BASE_Q)) / AV_TIME_BASE;
double last_pts_time = static_cast<double>(av_rescale_q(lastPTS, stream->time_base, AV_TIME_BASE_Q)) / AV_TIME_BASE;
logPrintf(Logger::WARNING + monitor->Importance(), "Stream pts jumped back in time too far. pts %.2f - last pts %.2f = %.2f > 10seconds",
pts_time, last_pts_time, pts_time - last_pts_time);
}
if (error_count > 5)
return -1;
error_count += 1;
Expand Down Expand Up @@ -543,6 +545,7 @@ int FfmpegCamera::OpenFfmpeg() {
ret = av_dict_parse_string(&opts, mOptions.c_str(), "=", ",", 0);
// reorder_queue is for avformat not codec
av_dict_set(&opts, "reorder_queue_size", nullptr, AV_DICT_MATCH_CASE);
av_dict_set(&opts, "probesize", nullptr, AV_DICT_MATCH_CASE);
}
ret = avcodec_open2(mVideoCodecContext, mVideoCodec, &opts);

Expand Down
44 changes: 26 additions & 18 deletions src/zm_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
std::string mqtt_subscriptions_string = std::string(dbrow[col] ? dbrow[col] : "");
mqtt_subscriptions = Split(mqtt_subscriptions_string, ',');
col++;
Error("MQTT enabled ? %d, subs %s", mqtt_enabled, mqtt_subscriptions_string.c_str());
Debug(1, "MQTT enabled ? %d, subs %s", mqtt_enabled, mqtt_subscriptions_string.c_str());
#else
Debug(1, "Not compiled with MQTT");
#endif
Expand Down Expand Up @@ -1378,11 +1378,11 @@ SystemTimePoint Monitor::GetTimestamp(int index) const {
return {};
}

unsigned int Monitor::GetLastReadIndex() const {
int Monitor::GetLastReadIndex() const {
return ( shared_data->last_read_index != image_buffer_count ? shared_data->last_read_index : -1 );
}

unsigned int Monitor::GetLastWriteIndex() const {
int Monitor::GetLastWriteIndex() const {
return ( shared_data->last_write_index != image_buffer_count ? shared_data->last_write_index : -1 );
}

Expand Down Expand Up @@ -2595,7 +2595,9 @@ int Monitor::Capture() {
packet->timestamp = std::chrono::system_clock::now();
shared_data->heartbeat_time = std::chrono::system_clock::to_time_t(packet->timestamp);
int captureResult = camera->Capture(packet);
Debug(4, "Back from capture result=%d image count %d", captureResult, shared_data->image_count);
Debug(4, "Back from capture result=%d image count %d timestamp %" PRId64, captureResult, shared_data->image_count,
static_cast<int64>(std::chrono::duration_cast<Microseconds>(packet->timestamp.time_since_epoch()).count())
);

if (captureResult < 0) {
// Unable to capture image
Expand Down Expand Up @@ -2749,19 +2751,19 @@ bool Monitor::setupConvertContext(const AVFrame *input_frame, const Image *image
bool Monitor::Decode() {
ZMLockedPacket *packet_lock = packetqueue.get_packet_and_increment_it(decoder_it);
if (!packet_lock) return false;

std::shared_ptr<ZMPacket> packet = packet_lock->packet_;
if (packet->codec_type != AVMEDIA_TYPE_VIDEO) {
packet->decoded = true;
Debug(4, "Not video");
//packetqueue.unlock(packet_lock);
delete packet_lock;
return true; // Don't need decode
}

if ((!packet->image) and packet->packet->size and !packet->in_frame) {
if ((decoding == DECODING_ALWAYS)
or
((decoding == DECODING_ONDEMAND) and this->hasViewers() )
((decoding == DECODING_ONDEMAND) and (this->hasViewers() or (shared_data->last_write_index == image_buffer_count)))
or
((decoding == DECODING_KEYFRAMES) and packet->keyframe)
or
Expand Down Expand Up @@ -2792,7 +2794,7 @@ bool Monitor::Decode() {
Debug(1, "Ret from decode %d, zm_terminate %d", ret, zm_terminate);
}
} else {
Debug(1, "Not Decoding ? %s", Decoding_Strings[decoding].c_str());
Debug(1, "Not Decoding frame %d? %s", packet->image_index, Decoding_Strings[decoding].c_str());
} // end if doing decoding
} else {
Debug(1, "No packet.size(%d) or packet->in_frame(%p). Not decoding", packet->packet->size, packet->in_frame.get());
Expand Down Expand Up @@ -3373,25 +3375,31 @@ int Monitor::PreCapture() const { return camera->PreCapture(); }
int Monitor::PostCapture() const { return camera->PostCapture(); }

int Monitor::Pause() {

// Because the stream indexes may change we have to clear out the packetqueue
if (decoder) decoder->Stop();

if (analysis_thread) {
analysis_thread->Stop();
Debug(1, "Analysis stopped");
}

Debug(1, "Stopping packetqueue");
// Wake everyone up
packetqueue.stop();

// Because the stream indexes may change we have to clear out the packetqueue
if (decoder) {
Debug(1, "Decoder stopping");
decoder->Stop();
Debug(1, "Decoder stopped");
}
Debug(1, "Joining decode");
decoder->Join();

if (convert_context) {
sws_freeContext(convert_context);
convert_context = nullptr;
if (convert_context) {
sws_freeContext(convert_context);
convert_context = nullptr;
}
}

if (analysis_thread) {
analysis_thread->Stop();
Debug(1, "Analysis stopped");
Debug(1, "Joining analysis");
analysis_thread->Join();
}

// Must close event before closing camera because it uses in_streams
Expand Down
21 changes: 6 additions & 15 deletions src/zm_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
}
return false;
}

inline unsigned int Id() const { return id; }
inline const char *Name() const { return name.c_str(); }
inline bool Deleted() const { return deleted; }
Expand Down Expand Up @@ -738,7 +737,7 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
inline const char *EventPrefix() const { return event_prefix.c_str(); }
inline bool Ready() const {
if (!packetqueue.get_max_keyframe_interval()) {
Debug(4, "No keyframe interval.");
Debug(4, "Not ready because no keyframe interval.");
return false;
}
if (decoding_image_count >= ready_count) {
Expand Down Expand Up @@ -767,17 +766,9 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
bool hasViewers() {
if (shared_data && shared_data->valid) {
SystemTimePoint now = std::chrono::system_clock::now();
Debug(3, "Last viewed %" PRId64 " seconds ago",
static_cast<int64>(std::chrono::duration_cast<Seconds>(now.time_since_epoch()).count())
-
shared_data->last_viewed_time
);
return (
(
static_cast<int64>(std::chrono::duration_cast<Seconds>(now.time_since_epoch()).count())
-
shared_data->last_viewed_time
) > 10 ? false : true);
int64 intNow = static_cast<int64>(std::chrono::duration_cast<Seconds>(now.time_since_epoch()).count());
Debug(3, "Last viewed %" PRId64 " seconds ago", intNow - shared_data->last_viewed_time);
return (((!shared_data->last_viewed_time) or ((intNow - shared_data->last_viewed_time)) > 10)) ? false : true;
}
return false;
}
Expand Down Expand Up @@ -849,8 +840,8 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
unsigned int GetCaptureMaxFPS() const { return capture_max_fps; }
Microseconds GetCaptureDelay() const { return capture_delay; }
Microseconds GetAlarmCaptureDelay() const { return alarm_capture_delay; }
unsigned int GetLastReadIndex() const;
unsigned int GetLastWriteIndex() const;
int GetLastReadIndex() const;
int GetLastWriteIndex() const;
uint64_t GetLastEventId() const;
double GetFPS() const;
void UpdateFPS();
Expand Down
4 changes: 2 additions & 2 deletions src/zm_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ void MQTT::on_subscribe(int mid, int qos_count, const int *granted_qos) {
Debug(1, "MQTT: Subscribed to topic ");
}

void MQTT::on_publish() {
Debug(1, "MQTT: on_publish ");
void MQTT::on_publish(int mid) {
Debug(1, "MQTT: on_publish %d", mid);
}

void MQTT::send(const std::string &message) {
Expand Down
2 changes: 1 addition & 1 deletion src/zm_mqtt.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MQTT : public mosqpp::mosquittopp {
void on_connect(int rc);
void on_message(const struct mosquitto_message *message);
void on_subscribe(int mid, int qos_count, const int *granted_qos);
void on_publish();
void on_publish(int mid);
enum sensorTypes {
NUMERIC = 0,
DIGITAL
Expand Down
5 changes: 3 additions & 2 deletions src/zm_packetqueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
while (rit != pktQueue.rend()) {
std::shared_ptr<ZMPacket> prev_packet = *rit;
if (prev_packet->packet->stream_index == add_packet->packet->stream_index) {
if (prev_packet->keyframe) break;
packet_count ++;
if (prev_packet->keyframe) break;
}
++rit;
}
Expand Down Expand Up @@ -295,7 +295,7 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
return;
}

int keyframe_interval_count = 1;
int keyframe_interval_count = 0;
int video_packets_to_delete = 0; // This is a count of how many packets we will delete so we know when to stop looking

ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
Expand Down Expand Up @@ -428,6 +428,7 @@ void PacketQueue::clear() {
delete[] packet_counts;
packet_counts = nullptr;
max_stream_id = -1;
max_keyframe_interval_ = 0;

Debug(1, "Packetqueue is clear, notifying");
condition.notify_all();
Expand Down
1 change: 1 addition & 0 deletions src/zm_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ class StreamBase {
memset(&rem_sock_path, 0, sizeof(rem_sock_path));
memset(&rem_addr, 0, sizeof(rem_addr));
memset(&sock_path_lock, 0, sizeof(sock_path_lock));
last_fps_update = std::chrono::steady_clock::now();

vid_stream = nullptr;
msg = { 0, { 0 } };
Expand Down
6 changes: 3 additions & 3 deletions src/zm_videostore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1329,8 +1329,8 @@ int VideoStore::writeAudioFramePacket(const std::shared_ptr<ZMPacket> zm_packet)
int64_t ts = static_cast<int64>(std::chrono::duration_cast<Microseconds>(zm_packet->timestamp.time_since_epoch()).count());
ipkt->pts = ipkt->dts = av_rescale_q(ts, AV_TIME_BASE_Q, audio_in_stream->time_base);

Debug(2, "dts from timestamp, set to (%" PRId64 ") secs(%.2f)",
ts, FPSeconds(zm_packet->timestamp.time_since_epoch()).count());
Debug(2, "dts %" PRId64 " from timestamp %" PRId64 " secs(%.2f)",
ipkt->dts, ts, FPSeconds(zm_packet->timestamp.time_since_epoch()).count());
}

if (audio_first_dts == AV_NOPTS_VALUE) {
Expand Down Expand Up @@ -1397,7 +1397,7 @@ int VideoStore::writeAudioFramePacket(const std::shared_ptr<ZMPacket> zm_packet)
opkt->dts = ipkt->dts;
}

ZM_DUMP_STREAM_PACKET(audio_in_stream, ipkt, "after pts adjustment");
ZM_DUMP_STREAM_PACKET(audio_in_stream, opkt, "after pts adjustment");
av_packet_rescale_ts(opkt.get(), audio_in_stream->time_base, audio_out_stream->time_base);
ZM_DUMP_STREAM_PACKET(audio_out_stream, opkt, "after stream pts adjustment");
write_packet(opkt.get(), audio_out_stream);
Expand Down
Loading

0 comments on commit 0cf4692

Please sign in to comment.