summaryrefslogtreecommitdiff
path: root/libavcodec/mediacodecdec.c
diff options
context:
space:
mode:
authorZhao Zhili <zhilizhao@tencent.com>2022-10-19 10:38:41 +0800
committerZhao Zhili <zhilizhao@tencent.com>2022-11-21 23:52:02 +0800
commitb1facd11a3cc00362949ea14d9eab30496cf0268 (patch)
tree62526e3e9345675fa88006fa913a58b0aa903d88 /libavcodec/mediacodecdec.c
parent093c4373214f002decc73ce337450d7ec641b3f4 (diff)
avcodec/mediacodecdec: don't break out if both input and output port return try again
At the beginning of decoding, if we feed mediacodec too fast, the input port will return try again. It takes some time for mediacodec to consume bitstream and output frame. So the output port also return try again. It possible that mediacodec_receive_frame doesn't consume any AVPacket and no AVFrame is output. Then both avcodec_send_packet() and avcodec_receive_frame() return EAGAIN, which shouldn't happen. This bug can be produced with decoding benchmark on Pixel 3. Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
Diffstat (limited to 'libavcodec/mediacodecdec.c')
-rw-r--r--libavcodec/mediacodecdec.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c
index 322b448d27..2c66f38541 100644
--- a/libavcodec/mediacodecdec.c
+++ b/libavcodec/mediacodecdec.c
@@ -444,7 +444,16 @@ static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
index = ff_AMediaCodec_dequeueInputBuffer(s->ctx->codec, 0);
if (index < 0) {
/* no space, block for an output frame to appear */
- return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
+ ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, true);
+ /* Try again if both input port and output port return EAGAIN.
+ * If no data is consumed and no frame in output, it can make
+ * both avcodec_send_packet() and avcodec_receive_frame()
+ * return EAGAIN, which violate the design.
+ */
+ if (ff_AMediaCodec_infoTryAgainLater(s->ctx->codec, index) &&
+ ret == AVERROR(EAGAIN))
+ continue;
+ return ret;
}
s->ctx->current_input_buffer = index;
}