aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <nfxjfg@googlemail.com>2015-09-08 19:42:23 +0200
committerLuca Barbato <lu_zero@gentoo.org>2015-09-12 12:25:39 +0200
commit6b652c0273d79f2e0c52ad91450bd0737cf3c8a6 (patch)
tree69dadd891c262b441d628fa8a3c44698f35deaaa
parentb84675d63aaede8f6944b901250a10456c5477e6 (diff)
downloadffmpeg-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.c13
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