diff options
author | wm4 <nfxjfg@googlemail.com> | 2015-09-08 19:42:23 +0200 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2015-09-12 12:25:39 +0200 |
commit | 6b652c0273d79f2e0c52ad91450bd0737cf3c8a6 (patch) | |
tree | 69dadd891c262b441d628fa8a3c44698f35deaaa | |
parent | b84675d63aaede8f6944b901250a10456c5477e6 (diff) | |
download | ffmpeg-6b652c0273d79f2e0c52ad91450bd0737cf3c8a6.tar.gz |
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@gentoo.org>
-rw-r--r-- | libavcodec/mmaldec.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/libavcodec/mmaldec.c b/libavcodec/mmaldec.c index 374bd2f30c..5692f505c0 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 |