Merge branch 'release-1.36' of github.com:ZoneMinder/zoneminder into release-1.36
commit
af4f8fd761
|
@ -1824,13 +1824,13 @@ bool Monitor::Analyse() {
|
|||
|
||||
/* try to stay behind the decoder. */
|
||||
if (decoding_enabled) {
|
||||
while (!snap->decoded and !zm_terminate and !analysis_thread->Stopped()) {
|
||||
while (!snap->decoded and !zm_terminate and !analysis_thread->Stopped() and !packetqueue.stopping()) {
|
||||
// Need to wait for the decoder thread.
|
||||
packetqueue.notify_all();
|
||||
Debug(1, "Waiting for decode");
|
||||
packet_lock->wait();
|
||||
} // end while ! decoded
|
||||
if (zm_terminate or analysis_thread->Stopped()) {
|
||||
if (zm_terminate or analysis_thread->Stopped() or packetqueue.stopping()) {
|
||||
delete packet_lock;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@ PacketQueue::PacketQueue():
|
|||
packet_counts(nullptr),
|
||||
deleting(false),
|
||||
keep_keyframes(false),
|
||||
warned_count(0)
|
||||
warned_count(0),
|
||||
has_out_of_order_packets_(false),
|
||||
max_keyframe_interval_(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -86,6 +88,24 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
|
|||
}
|
||||
{
|
||||
std::unique_lock<std::mutex> lck(mutex);
|
||||
if (deleting or zm_terminate) return false;
|
||||
|
||||
if (!has_out_of_order_packets_ and (add_packet->packet.dts != AV_NOPTS_VALUE)) {
|
||||
auto rit = pktQueue.rbegin();
|
||||
// Find the previous packet for the stream, and check dts
|
||||
while (rit != pktQueue.rend()) {
|
||||
if ((*rit)->packet.stream_index == add_packet->packet.stream_index) {
|
||||
if ((*rit)->packet.dts >= add_packet->packet.dts) {
|
||||
Debug(1, "Have out of order packets");
|
||||
ZM_DUMP_PACKET((*rit)->packet, "queued_packet");
|
||||
ZM_DUMP_PACKET(add_packet->packet, "add_packet");
|
||||
has_out_of_order_packets_ = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
rit++;
|
||||
} // end while
|
||||
}
|
||||
|
||||
pktQueue.push_back(add_packet);
|
||||
packet_counts[add_packet->packet.stream_index] += 1;
|
||||
|
@ -115,8 +135,8 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
|
|||
warned_count++;
|
||||
Warning("You have set the max video packets in the queue to %u."
|
||||
" The queue is full. Either Analysis is not keeping up or"
|
||||
" your camera's keyframe interval is larger than this setting."
|
||||
, max_video_packet_count);
|
||||
" your camera's keyframe interval %d is larger than this setting."
|
||||
, max_video_packet_count, max_keyframe_interval_);
|
||||
}
|
||||
|
||||
for (
|
||||
|
@ -152,6 +172,9 @@ bool PacketQueue::queuePacket(std::shared_ptr<ZMPacket> add_packet) {
|
|||
}
|
||||
} // end foreach iterator
|
||||
|
||||
zm_packet->decoded = true; // Have to in case analysis is waiting on it
|
||||
zm_packet->notify_all();
|
||||
|
||||
it = pktQueue.erase(it);
|
||||
packet_counts[zm_packet->packet.stream_index] -= 1;
|
||||
Debug(1,
|
||||
|
@ -226,12 +249,8 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
|
|||
// If not doing passthrough, we don't care about starting with a keyframe so logic is simpler
|
||||
while ((*pktQueue.begin() != add_packet) and (packet_counts[video_stream_id] > pre_event_video_packet_count + tail_count)) {
|
||||
std::shared_ptr<ZMPacket> zm_packet = *pktQueue.begin();
|
||||
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
|
||||
if (!lp->trylock()) {
|
||||
delete lp;
|
||||
break;
|
||||
}
|
||||
delete lp;
|
||||
ZMLockedPacket lp(zm_packet);
|
||||
if (!lp.trylock()) break;
|
||||
|
||||
if (is_there_an_iterator_pointing_to_packet(zm_packet)) {
|
||||
Warning("Found iterator at beginning of queue. Some thread isn't keeping up");
|
||||
|
@ -297,12 +316,12 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (zm_packet->packet->stream_index == video_stream_id) {
|
||||
if (zm_packet->packet.stream_index == video_stream_id) {
|
||||
keyframe_interval_count++;
|
||||
if (zm_packet->keyframe) {
|
||||
Debug(4, "Have a video keyframe so setting next front to it. Keyframe interval so far is %d", keyframe_interval_count);
|
||||
|
||||
if (max_keyframe_interval < keyframe_interval_count) max_keyframe_interval = keyframe_interval_count;
|
||||
Debug(3, "Have a video keyframe so setting next front to it. Keyframe interval so far is %d", keyframe_interval_count);
|
||||
if (keyframe_interval_count > max_keyframe_interval_)
|
||||
max_keyframe_interval_ = keyframe_interval_count;
|
||||
keyframe_interval_count = 1;
|
||||
next_front = it;
|
||||
}
|
||||
|
@ -353,11 +372,14 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
|
|||
void PacketQueue::stop() {
|
||||
deleting = true;
|
||||
condition.notify_all();
|
||||
for (const auto &p : pktQueue) p->notify_all();
|
||||
for (const auto &p : pktQueue) {
|
||||
p->notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
void PacketQueue::clear() {
|
||||
deleting = true;
|
||||
// Why are we notifying?
|
||||
condition.notify_all();
|
||||
if (!packet_counts) // special case, not initialised
|
||||
return;
|
||||
|
|
|
@ -47,6 +47,8 @@ class PacketQueue {
|
|||
std::mutex mutex;
|
||||
std::condition_variable condition;
|
||||
int warned_count;
|
||||
bool has_out_of_order_packets_;
|
||||
int max_keyframe_interval_;
|
||||
|
||||
public:
|
||||
PacketQueue();
|
||||
|
@ -61,10 +63,13 @@ class PacketQueue {
|
|||
|
||||
bool queuePacket(std::shared_ptr<ZMPacket> packet);
|
||||
void stop();
|
||||
bool stopping() const { return deleting; };
|
||||
void clear();
|
||||
void dumpQueue();
|
||||
unsigned int size();
|
||||
unsigned int get_packet_count(int stream_id) const { return packet_counts[stream_id]; };
|
||||
bool has_out_of_order_packets() const { return has_out_of_order_packets_; };
|
||||
int get_max_keyframe_interval() const { return max_keyframe_interval_; };
|
||||
|
||||
void clearPackets(const std::shared_ptr<ZMPacket> &packet);
|
||||
int packet_count(int stream_id);
|
||||
|
|
Loading…
Reference in New Issue