[FFmpeg-cvslog] mmaldec: fix problems with flush logic

wm4 git at videolan.org
Sat Sep 12 13:30:54 CEST 2015


ffmpeg | branch: master | wm4 <nfxjfg at googlemail.com> | Tue Sep  8 19:42:23 2015 +0200| [6b652c0273d79f2e0c52ad91450bd0737cf3c8a6] | committer: Luca Barbato

mmaldec: fix problems with flush logic

Don't try to do a blocking wait for MMAL output if we haven't even sent
a single real packet, but only flush packets. Obviously we can't expect
to get anything back.

Additionally, don't send a flush packet to MMAL in the same case. It
appears the MMAL decoder will sometimes hang in mmal_vc_port_disable()
(called from ffmmal_close_decoder()), waiting for a reply from the GPU
which never arrives. Either MMAL disallows sending flush packets without
preceding real data, or it's a MMAL bug.

Signed-off-by: Luca Barbato <lu_zero at gentoo.org>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6b652c0273d79f2e0c52ad91450bd0737cf3c8a6
---

 libavcodec/mmaldec.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c
index 374bd2f..5692f50 100644
--- a/libavcodec/mmaldec.c
+++ b/libavcodec/mmaldec.c
@@ -447,8 +447,6 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt)
     uint8_t *start;
     int ret = 0;
 
-    ctx->packets_sent++;
-
     if (avpkt->size) {
         if (ctx->bsfc) {
             uint8_t *tmp_data;
@@ -474,6 +472,14 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt)
         }
         size = buf->size;
         data = buf->data;
+        ctx->packets_sent++;
+    } else {
+        if (!ctx->packets_sent) {
+            // Short-cut the flush logic to avoid upsetting MMAL.
+            ctx->eos_sent = 1;
+            ctx->eos_received = 1;
+            goto done;
+        }
     }
 
     start = data;
@@ -643,7 +649,8 @@ static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_fra
         // excessive buffering.
         // We also wait if we sent eos, but didn't receive it yet (think of decoding
         // stream with a very low number of frames).
-        if (ctx->frames_output || ctx->packets_sent > MAX_DELAYED_FRAMES || ctx->eos_sent) {
+        if (ctx->frames_output || ctx->packets_sent > MAX_DELAYED_FRAMES ||
+            (ctx->packets_sent && ctx->eos_sent)) {
             // MMAL will ignore broken input packets, which means the frame we
             // expect here may never arrive. Dealing with this correctly is
             // complicated, so here's a hack to avoid that it freezes forever



More information about the ffmpeg-cvslog mailing list