Add keep_keyframes setting. When NOT doing passthrough we don't actually have to store all packets since last keyframe, so don't do it. SImplifies clearPackets() logic a lot and will save ram for those people.

This commit is contained in:
Isaac Connor 2021-03-22 12:04:32 -04:00
parent 6d5cbe2583
commit 3f3bc50acb
2 changed files with 31 additions and 11 deletions

View File

@ -31,7 +31,8 @@ PacketQueue::PacketQueue():
max_video_packet_count(-1), max_video_packet_count(-1),
max_stream_id(-1), max_stream_id(-1),
packet_counts(nullptr), packet_counts(nullptr),
deleting(false) deleting(false),
keep_keyframes(false)
{ {
} }
@ -120,23 +121,39 @@ void PacketQueue::clearPackets(ZMPacket *add_packet) {
// //
// So start at the beginning, counting video packets until the next keyframe. // So start at the beginning, counting video packets until the next keyframe.
// Then if deleting those packets doesn't break 1 and 2, then go ahead and delete them. // Then if deleting those packets doesn't break 1 and 2, then go ahead and delete them.
if (! ( if (keep_keyframes and ! (
add_packet->packet.stream_index == video_stream_id add_packet->packet.stream_index == video_stream_id
and and
add_packet->keyframe add_packet->keyframe
and and
(packet_counts[video_stream_id] > max_video_packet_count) (packet_counts[video_stream_id] > max_video_packet_count)
and and
*(pktQueue.begin()) != add_packet *(pktQueue.begin()) != add_packet
) )
) { ) {
Debug(3, "stream index %d ?= video_stream_id %d, keyframe %d, counts %d > max %d at begin %d", Debug(3, "stream index %d ?= video_stream_id %d, keyframe %d, keep_keyframes %d, counts %d > max %d at begin %d",
add_packet->packet.stream_index, video_stream_id, add_packet->keyframe, packet_counts[video_stream_id], max_video_packet_count, add_packet->packet.stream_index, video_stream_id, add_packet->keyframe, keep_keyframes, packet_counts[video_stream_id], max_video_packet_count,
( *(pktQueue.begin()) != add_packet ) ( *(pktQueue.begin()) != add_packet )
); );
return; return;
} }
std::unique_lock<std::mutex> lck(mutex); std::unique_lock<std::mutex> lck(mutex);
if (!keep_keyframes) {
// 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] > max_video_packet_count)) {
ZMPacket *zm_packet = *pktQueue.begin();
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);
if (!lp->trylock()) break;
delete lp;
pktQueue.pop_front();
packet_counts[zm_packet->packet.stream_index] -= 1;
Debug(1, "Deleting a packet with stream index:%d image_index:%d with keyframe:%d, video frames in queue:%d max: %d, queuesize:%d",
zm_packet->packet.stream_index, zm_packet->image_index, zm_packet->keyframe, packet_counts[video_stream_id], max_video_packet_count, pktQueue.size());
delete zm_packet;
} // end while
return;
}
// If ananlysis_it isn't at the end, we need to keep that many additional packets // If ananlysis_it isn't at the end, we need to keep that many additional packets
int tail_count = 0; int tail_count = 0;
@ -156,6 +173,7 @@ void PacketQueue::clearPackets(ZMPacket *add_packet) {
packetqueue_iterator next_front = pktQueue.begin(); packetqueue_iterator next_front = pktQueue.begin();
int video_packets_to_delete = 0; // This is a count of how many packets we will delete so we know when to stop looking int video_packets_to_delete = 0; // This is a count of how many packets we will delete so we know when to stop looking
// First packet is special because we know it is a video keyframe and only need to check for lock // First packet is special because we know it is a video keyframe and only need to check for lock
ZMPacket *zm_packet = *it; ZMPacket *zm_packet = *it;
ZMLockedPacket *lp = new ZMLockedPacket(zm_packet); ZMLockedPacket *lp = new ZMLockedPacket(zm_packet);

View File

@ -38,6 +38,7 @@ class PacketQueue {
int max_stream_id; int max_stream_id;
int *packet_counts; /* packet count for each stream_id, to keep track of how many video vs audio packets are in the queue */ int *packet_counts; /* packet count for each stream_id, to keep track of how many video vs audio packets are in the queue */
bool deleting; bool deleting;
bool keep_keyframes;
std::list<packetqueue_iterator *> iterators; std::list<packetqueue_iterator *> iterators;
std::mutex mutex; std::mutex mutex;
@ -51,6 +52,7 @@ class PacketQueue {
int addStream(); int addStream();
void setMaxVideoPackets(int p); void setMaxVideoPackets(int p);
void setKeepKeyframes(bool k) { keep_keyframes = k; };
bool queuePacket(ZMPacket* packet); bool queuePacket(ZMPacket* packet);
ZMLockedPacket * popPacket(); ZMLockedPacket * popPacket();