From 575b3138de49a8750f9a7babaa747fd10bf46492 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 12 Apr 2017 13:39:47 -0400 Subject: [PATCH] change it from a queue to a list. Implement a clearQueue that keeps some frames, and a function clear out unwanted frames --- src/zm_packetqueue.cpp | 89 +++++++++++++++++++++++++++++++++++++++--- src/zm_packetqueue.h | 6 ++- 2 files changed, 88 insertions(+), 7 deletions(-) diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index c38f74c52..f60b11df5 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -34,7 +34,7 @@ zm_packetqueue::~zm_packetqueue() { } bool zm_packetqueue::queuePacket( ZMPacket* zm_packet ) { - pktQueue.push( zm_packet ); + pktQueue.push_back( zm_packet ); return true; } @@ -42,7 +42,7 @@ bool zm_packetqueue::queuePacket( AVPacket* av_packet ) { ZMPacket *zm_packet = new ZMPacket( av_packet ); - pktQueue.push( zm_packet ); + pktQueue.push_back( zm_packet ); return true; } @@ -53,17 +53,57 @@ ZMPacket* zm_packetqueue::popPacket( ) { } ZMPacket *packet = pktQueue.front(); - pktQueue.pop(); + pktQueue.pop_front(); return packet; } +unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id ) { + + Debug(3, "Clearing all but %d frames", frames_to_keep ); + frames_to_keep += 1; + + if ( pktQueue.empty() ) { + Debug(3, "Queue is empty"); + return 0; + } else { + Debug(3, "Queue has (%d)", pktQueue.size() ); + } + + list::reverse_iterator it; + ZMPacket *packet = NULL; + + for ( it = pktQueue.rbegin(); it != pktQueue.rend() && frames_to_keep; ++it ) { + ZMPacket *zm_packet = *it; + AVPacket *av_packet = &(zm_packet->packet); + + Debug(3, "Looking at packet with stream index (%d) with keyframe (%d), frames_to_keep is (%d)", av_packet->stream_index, ( av_packet->flags & AV_PKT_FLAG_KEY ), frames_to_keep ); + + // Want frames_to_keep video keyframes. Otherwise, we may not have enough + if ( ( av_packet->stream_index == stream_id) && ( av_packet->flags & AV_PKT_FLAG_KEY ) ) { + if (!frames_to_keep) + break; + frames_to_keep --; + } + } + unsigned int delete_count = 0; + while ( it != pktQueue.rend() ) { + Debug(3, "Deleting a packet from the front, count is (%d)", delete_count ); + + packet = pktQueue.front(); + pktQueue.pop_front(); + delete packet; + + delete_count += 1; + } + return delete_count; +} // end unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id ) + void zm_packetqueue::clearQueue() { ZMPacket *packet = NULL; while(!pktQueue.empty()) { - packet = pktQueue.front(); - pktQueue.pop(); + pktQueue.pop_front(); delete packet; } } @@ -71,3 +111,42 @@ void zm_packetqueue::clearQueue() { unsigned int zm_packetqueue::size() { return pktQueue.size(); } + + +void zm_packetqueue::clear_unwanted_packets( timeval *recording_started, int mVideoStreamId ) { + // Need to find the keyframe <= recording_started. Can get rid of audio packets. + if ( pktQueue.empty() ) { + return; + } + + // Step 1 - find keyframe < recording_started. + // Step 2 - pop packets until we get to the packet in step 2 + list::reverse_iterator it; + + for ( it = pktQueue.rbegin(); it != pktQueue.rend(); ++ it ) { + ZMPacket *zm_packet = *it; + AVPacket *av_packet = &(zm_packet->packet); +Debug(1, "Looking for keyframe after start" ); + if ( + ( av_packet->flags & AV_PKT_FLAG_KEY ) + && + ( av_packet->stream_index == mVideoStreamId ) + && + timercmp( &(zm_packet->timestamp), recording_started, < ) + ) { +Debug(1, "Found keyframe before start" ); + break; + } + } + if ( it == pktQueue.rend() ) { + Debug(1, "Didn't find a keyframe packet keeping all" ); + return; + } + + ZMPacket *packet = NULL; + while ( pktQueue.rend() != it ) { + packet = pktQueue.front(); + pktQueue.pop_front(); + delete packet; + } +} diff --git a/src/zm_packetqueue.h b/src/zm_packetqueue.h index 730487312..39160ddfd 100644 --- a/src/zm_packetqueue.h +++ b/src/zm_packetqueue.h @@ -23,7 +23,7 @@ //#include //#include //#include -#include +#include #include "zm_packet.h" extern "C" { @@ -40,10 +40,12 @@ public: ZMPacket * popPacket( ); bool popVideoPacket(ZMPacket* packet); bool popAudioPacket(ZMPacket* packet); + unsigned int clearQueue( unsigned int video_frames_to_keep, int stream_id ); void clearQueue( ); unsigned int size(); + void clear_unwanted_packets( timeval *recording, int mVideoStreamId ); private: - std::queue pktQueue; + std::list pktQueue; };