From 6bc526b74d7c939d6ebc1e471b12b719c388f772 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 16 Dec 2012 05:30:38 -0800 Subject: [PATCH 1/2] Avoid another loop for decoding audio --- apps/openmw/mwrender/videoplayer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 817ec0a3f..1c22b7b3d 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -401,7 +401,7 @@ public: while(total < len) { - while(mFramePos >= mFrameSize) + if(mFramePos >= mFrameSize) { /* We have already sent all our data; get more */ mFrameSize = audio_decode_frame(mFrame); @@ -413,6 +413,7 @@ public: mFramePos = std::min(mFrameSize, sample_skip); sample_skip -= mFramePos; + continue; } size_t len1 = len - total; From c92cde2be92f092cbb00249457f39e355146fde3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 16 Dec 2012 05:50:20 -0800 Subject: [PATCH 2/2] Properly flush packet queues when at EOF Note: the previous flush method was renamed to clear. Flushing a queue allows consumers to retrieve queued packets, but not expect any more to come in. --- apps/openmw/mwrender/videoplayer.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 1c22b7b3d..d2e317b71 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -29,12 +29,13 @@ enum { struct PacketQueue { PacketQueue() - : first_pkt(NULL), last_pkt(NULL), nb_packets(0), size(0) + : first_pkt(NULL), last_pkt(NULL), flushing(false), nb_packets(0), size(0) { } ~PacketQueue() - { flush(); } + { clear(); } AVPacketList *first_pkt, *last_pkt; + volatile bool flushing; int nb_packets; int size; @@ -45,6 +46,7 @@ struct PacketQueue { int get(AVPacket *pkt, VideoState *is); void flush(); + void clear(); }; struct VideoPicture { @@ -202,6 +204,8 @@ int PacketQueue::get(AVPacket *pkt, VideoState *is) return 1; } + if(this->flushing) + break; this->cond.wait(lock); } @@ -209,6 +213,12 @@ int PacketQueue::get(AVPacket *pkt, VideoState *is) } void PacketQueue::flush() +{ + this->flushing = true; + this->cond.notify_one(); +} + +void PacketQueue::clear() { AVPacketList *pkt, *pkt1; @@ -753,7 +763,10 @@ void VideoState::decode_thread_loop(VideoState *self) else av_free_packet(packet); } + /* all done - wait for it */ + self->videoq.flush(); + self->audioq.flush(); while(!self->quit) { // EOF reached, all packets processed, we can exit now