Make clearPackets return false if it can't remove any packets. So that we try again even if we aren't looking at a keyframe.

pull/4623/head
Isaac Connor 2026-02-11 22:35:50 -05:00
parent f90c4a4d35
commit 56588939e7
2 changed files with 24 additions and 12 deletions

View File

@ -40,6 +40,7 @@ PacketQueue::PacketQueue():
has_out_of_order_packets_(false),
max_keyframe_interval_(0),
frames_since_last_keyframe_(0),
clear_packets_pending_(false),
next_queue_index_(0)
{
}
@ -215,7 +216,7 @@ packetqueue_iterator PacketQueue::deletePacket(packetqueue_iterator it) {
return pktQueue.erase(it);
}
void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
bool PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
// Packets removed from the queue are collected here and destroyed after the
// mutex is released, so that expensive ZMPacket destructors (freeing images,
// av packets) don't run while the queue is locked.
@ -233,23 +234,27 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
// Then if deleting those packets doesn't break 1 and 2, then go ahead and delete them.
//
// One assumption that we can make is that there will be packets in the queue. Because we call it while holding a locked packet
if (deleting) return;
if (deleting) return false;
// When keep_keyframes, normally only attempt clearing on video keyframes.
// If a previous clear attempt failed (clear_packets_pending_), retry on
// any video packet regardless of keyframe status.
if (keep_keyframes and ! (
add_packet->packet->stream_index == video_stream_id
and
add_packet->keyframe
(add_packet->keyframe or clear_packets_pending_)
and
(packet_counts[video_stream_id] > pre_event_video_packet_count)
and
*(pktQueue.begin()) != add_packet
)
) {
Debug(3, "stream index %d ?= video_stream_id %d, keyframe %d, keep_keyframes %d, counts %d > pre_event_count %d at begin %d",
add_packet->packet->stream_index, video_stream_id, add_packet->keyframe, keep_keyframes, packet_counts[video_stream_id], pre_event_video_packet_count,
Debug(3, "stream index %d ?= video_stream_id %d, keyframe %d, keep_keyframes %d, pending %d, counts %d > pre_event_count %d at begin %d",
add_packet->packet->stream_index, video_stream_id, add_packet->keyframe, keep_keyframes, clear_packets_pending_,
packet_counts[video_stream_id], pre_event_video_packet_count,
( *(pktQueue.begin()) != add_packet )
);
return;
return false;
}
// If analysis_it isn't at the end, we need to keep that many additional packets
@ -303,8 +308,9 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
} // end while
Debug(3, "Done removing %d packets from queue. packet_counts %d >? pre_event %d + tail %d = %d",
packets_removed, packet_counts[video_stream_id], pre_event_video_packet_count, tail_count, pre_event_video_packet_count + tail_count);
clear_packets_pending_ = (packets_removed == 0);
// mutex released here at end of scope, packets destroyed after
return;
return (packets_removed > 0);
}
auto it = pktQueue.begin();
@ -314,7 +320,7 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
std::shared_ptr<ZMPacket> zm_packet = *it;
if (zm_packet == add_packet) {
Debug(1, "First packet in queue is the analysis packet.");
return;
return false;
}
int keyframe_interval_count = 0;
@ -323,7 +329,8 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
if (zm_packet->queue_index >= min_iterator_queue_index) {
Debug(3, "Found iterator Counted %d video packets. Which would leave %d in packetqueue tail count is %d",
video_packets_to_delete, packet_counts[video_stream_id]-video_packets_to_delete, tail_count);
return;
clear_packets_pending_ = true;
return false;
}
++it;
@ -382,11 +389,15 @@ void PacketQueue::clearPackets(const std::shared_ptr<ZMPacket> &add_packet) {
packet_counts[zm_packet->packet->stream_index] -= 1;
packets_to_destroy.push_back(std::move(zm_packet));
}
} // end if have at least max_video_packet_count video packets remaining
clear_packets_pending_ = false;
} else {
clear_packets_pending_ = true;
}
} // end scope for unique_lock — mutex released here
// packets_to_destroy goes out of scope here, destroying packets without holding the mutex
} // end void PacketQueue::clearPackets(ZMPacket* zm_packet)
return !clear_packets_pending_;
} // end bool PacketQueue::clearPackets(ZMPacket* zm_packet)
void PacketQueue::stop() {
std::lock_guard<std::mutex> lck(mutex);

View File

@ -53,6 +53,7 @@ class PacketQueue {
bool has_out_of_order_packets_;
int max_keyframe_interval_;
int frames_since_last_keyframe_;
bool clear_packets_pending_;
uint64_t next_queue_index_;
Monitor *monitor_;
@ -80,7 +81,7 @@ class PacketQueue {
return has_out_of_order_packets_; };
int get_max_keyframe_interval() const { return max_keyframe_interval_; };
void clearPackets(const std::shared_ptr<ZMPacket> &packet);
bool clearPackets(const std::shared_ptr<ZMPacket> &packet);
int packet_count(int stream_id);
bool increment_it(packetqueue_iterator *it, bool wait);