Re: [FFmpeg-devel] [PATCH v2 2/4] avcodec/mediacodecdec: restructure mediacodec_receive_frame
On Fri, May 4, 2018 at 8:13 AM, Matthieu Bouron wrote: > On Thu, May 03, 2018 at 10:24:49AM -0700, Aman Gupta wrote: > > On Thu, May 3, 2018 at 12:33 AM, Matthieu Bouron < > matthieu.bou...@gmail.com> > > wrote: > > > > > On Wed, May 02, 2018 at 07:24:58PM -0700, Aman Gupta wrote: > > > > From: Aman Gupta > > > > > > > > The new logic follows a recommendation by @rcombs to use > > > > dequeueInputBuffer with a timeout of 0 as a way to detect > > > > whether the codec wants more data. The dequeued buffer index is > > > > kept in MediaCodecDecContext until it can be used next. > > > > > > > > A similar technique is also used by the Google's official media > > > > player Exoplayer: see MediaCodecRenderer.feedInputBuffer(). > > > > > > > > Signed-off-by: Aman Gupta > > > > --- > > > > libavcodec/mediacodecdec.c| 80 > -- > > > - > > > > libavcodec/mediacodecdec_common.c | 28 -- > > > > libavcodec/mediacodecdec_common.h | 4 +- > > > > 3 files changed, 61 insertions(+), 51 deletions(-) > > > > > > > > diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c > > > > index 86ceee5a83..2ac22dd1f6 100644 > > > > --- a/libavcodec/mediacodecdec.c > > > > +++ b/libavcodec/mediacodecdec.c > > > > @@ -391,33 +391,11 @@ done: > > > > return ret; > > > > } > > > > > > > > -static int mediacodec_send_receive(AVCodecContext *avctx, > > > > - MediaCodecH264DecContext *s, > > > > - AVFrame *frame, bool wait) > > > > -{ > > > > -int ret; > > > > - > > > > -/* send any pending data from buffered packet */ > > > > -while (s->buffered_pkt.size) { > > > > -ret = ff_mediacodec_dec_send(avctx, s->ctx, > &s->buffered_pkt); > > > > -if (ret == AVERROR(EAGAIN)) > > > > -break; > > > > -else if (ret < 0) > > > > -return ret; > > > > -s->buffered_pkt.size -= ret; > > > > -s->buffered_pkt.data += ret; > > > > -if (s->buffered_pkt.size <= 0) > > > > -av_packet_unref(&s->buffered_pkt); > > > > -} > > > > - > > > > -/* check for new frame */ > > > > -return ff_mediacodec_dec_receive(avctx, s->ctx, frame, wait); > > > > -} > > > > - > > > > static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame > > > *frame) > > > > { > > > > MediaCodecH264DecContext *s = avctx->priv_data; > > > > int ret; > > > > +ssize_t index; > > > > > > > > /* In delay_flush mode, wait until the user has released or > rendered > > > > all retained frames. */ > > > > @@ -427,28 +405,54 @@ static int mediacodec_receive_frame( > AVCodecContext > > > *avctx, AVFrame *frame) > > > > } > > > > } > > > > > > > > -/* flush buffered packet and check for new frame */ > > > > -ret = mediacodec_send_receive(avctx, s, frame, false); > > > > +/* poll for new frame */ > > > > +ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false); > > > > if (ret != AVERROR(EAGAIN)) > > > > return ret; > > > > > > > > -/* skip fetching new packet if we still have one buffered */ > > > > -if (s->buffered_pkt.size > 0) > > > > -return mediacodec_send_receive(avctx, s, frame, true); > > > > +/* feed decoder */ > > > > +while (1) { > > > > +if (s->ctx->current_input_buffer < 0) { > > > > +/* poll for input space */ > > > > +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); > > > > +} > > > > +s->ctx->current_input_buffer = index; > > > > +} > > > > > > > > -/* fetch new packet or eof */ > > > > -ret = ff_decode_get_packet(avctx, &s->buffered_pkt); > > > > -if (ret == AVERROR_EOF) { > > > > -AVPacket null_pkt = { 0 }; > > > > -ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt); > > > > -if (ret < 0) > > > > +/* try to flush any buffered packet data */ > > > > +if (s->buffered_pkt.size > 0) { > > > > +ret = ff_mediacodec_dec_send(avctx, s->ctx, > > > &s->buffered_pkt, false); > > > > +if (ret >= 0) { > > > > +s->buffered_pkt.size -= ret; > > > > +s->buffered_pkt.data += ret; > > > > +if (s->buffered_pkt.size <= 0) > > > > +av_packet_unref(&s->buffered_pkt); > > > > +} else if (ret < 0 && ret != AVERROR(EAGAIN)) { > > > > +return ret; > > > > +} > > > > + > > > > +/* poll for space again */ > > > > +continue; > > > > +} > > > > + > > > > +/* fetch new packet or eof */ > > > > +ret = ff_decode_get_packet(avctx, &s->buffered_
Re: [FFmpeg-devel] [PATCH v2 2/4] avcodec/mediacodecdec: restructure mediacodec_receive_frame
On Thu, May 03, 2018 at 10:24:49AM -0700, Aman Gupta wrote: > On Thu, May 3, 2018 at 12:33 AM, Matthieu Bouron > wrote: > > > On Wed, May 02, 2018 at 07:24:58PM -0700, Aman Gupta wrote: > > > From: Aman Gupta > > > > > > The new logic follows a recommendation by @rcombs to use > > > dequeueInputBuffer with a timeout of 0 as a way to detect > > > whether the codec wants more data. The dequeued buffer index is > > > kept in MediaCodecDecContext until it can be used next. > > > > > > A similar technique is also used by the Google's official media > > > player Exoplayer: see MediaCodecRenderer.feedInputBuffer(). > > > > > > Signed-off-by: Aman Gupta > > > --- > > > libavcodec/mediacodecdec.c| 80 -- > > - > > > libavcodec/mediacodecdec_common.c | 28 -- > > > libavcodec/mediacodecdec_common.h | 4 +- > > > 3 files changed, 61 insertions(+), 51 deletions(-) > > > > > > diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c > > > index 86ceee5a83..2ac22dd1f6 100644 > > > --- a/libavcodec/mediacodecdec.c > > > +++ b/libavcodec/mediacodecdec.c > > > @@ -391,33 +391,11 @@ done: > > > return ret; > > > } > > > > > > -static int mediacodec_send_receive(AVCodecContext *avctx, > > > - MediaCodecH264DecContext *s, > > > - AVFrame *frame, bool wait) > > > -{ > > > -int ret; > > > - > > > -/* send any pending data from buffered packet */ > > > -while (s->buffered_pkt.size) { > > > -ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt); > > > -if (ret == AVERROR(EAGAIN)) > > > -break; > > > -else if (ret < 0) > > > -return ret; > > > -s->buffered_pkt.size -= ret; > > > -s->buffered_pkt.data += ret; > > > -if (s->buffered_pkt.size <= 0) > > > -av_packet_unref(&s->buffered_pkt); > > > -} > > > - > > > -/* check for new frame */ > > > -return ff_mediacodec_dec_receive(avctx, s->ctx, frame, wait); > > > -} > > > - > > > static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame > > *frame) > > > { > > > MediaCodecH264DecContext *s = avctx->priv_data; > > > int ret; > > > +ssize_t index; > > > > > > /* In delay_flush mode, wait until the user has released or rendered > > > all retained frames. */ > > > @@ -427,28 +405,54 @@ static int mediacodec_receive_frame(AVCodecContext > > *avctx, AVFrame *frame) > > > } > > > } > > > > > > -/* flush buffered packet and check for new frame */ > > > -ret = mediacodec_send_receive(avctx, s, frame, false); > > > +/* poll for new frame */ > > > +ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false); > > > if (ret != AVERROR(EAGAIN)) > > > return ret; > > > > > > -/* skip fetching new packet if we still have one buffered */ > > > -if (s->buffered_pkt.size > 0) > > > -return mediacodec_send_receive(avctx, s, frame, true); > > > +/* feed decoder */ > > > +while (1) { > > > +if (s->ctx->current_input_buffer < 0) { > > > +/* poll for input space */ > > > +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); > > > +} > > > +s->ctx->current_input_buffer = index; > > > +} > > > > > > -/* fetch new packet or eof */ > > > -ret = ff_decode_get_packet(avctx, &s->buffered_pkt); > > > -if (ret == AVERROR_EOF) { > > > -AVPacket null_pkt = { 0 }; > > > -ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt); > > > -if (ret < 0) > > > +/* try to flush any buffered packet data */ > > > +if (s->buffered_pkt.size > 0) { > > > +ret = ff_mediacodec_dec_send(avctx, s->ctx, > > &s->buffered_pkt, false); > > > +if (ret >= 0) { > > > +s->buffered_pkt.size -= ret; > > > +s->buffered_pkt.data += ret; > > > +if (s->buffered_pkt.size <= 0) > > > +av_packet_unref(&s->buffered_pkt); > > > +} else if (ret < 0 && ret != AVERROR(EAGAIN)) { > > > +return ret; > > > +} > > > + > > > +/* poll for space again */ > > > +continue; > > > +} > > > + > > > +/* fetch new packet or eof */ > > > +ret = ff_decode_get_packet(avctx, &s->buffered_pkt); > > > +if (ret == AVERROR_EOF) { > > > +AVPacket null_pkt = { 0 }; > > > +ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, > > true); > > > +if (ret < 0) > > > +return ret; > > > +} else if (ret == AVERROR(EAGAIN) && > > s->ctx->current_input_buffer < 0)
Re: [FFmpeg-devel] [PATCH v2 2/4] avcodec/mediacodecdec: restructure mediacodec_receive_frame
On Thu, May 3, 2018 at 12:33 AM, Matthieu Bouron wrote: > On Wed, May 02, 2018 at 07:24:58PM -0700, Aman Gupta wrote: > > From: Aman Gupta > > > > The new logic follows a recommendation by @rcombs to use > > dequeueInputBuffer with a timeout of 0 as a way to detect > > whether the codec wants more data. The dequeued buffer index is > > kept in MediaCodecDecContext until it can be used next. > > > > A similar technique is also used by the Google's official media > > player Exoplayer: see MediaCodecRenderer.feedInputBuffer(). > > > > Signed-off-by: Aman Gupta > > --- > > libavcodec/mediacodecdec.c| 80 -- > - > > libavcodec/mediacodecdec_common.c | 28 -- > > libavcodec/mediacodecdec_common.h | 4 +- > > 3 files changed, 61 insertions(+), 51 deletions(-) > > > > diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c > > index 86ceee5a83..2ac22dd1f6 100644 > > --- a/libavcodec/mediacodecdec.c > > +++ b/libavcodec/mediacodecdec.c > > @@ -391,33 +391,11 @@ done: > > return ret; > > } > > > > -static int mediacodec_send_receive(AVCodecContext *avctx, > > - MediaCodecH264DecContext *s, > > - AVFrame *frame, bool wait) > > -{ > > -int ret; > > - > > -/* send any pending data from buffered packet */ > > -while (s->buffered_pkt.size) { > > -ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt); > > -if (ret == AVERROR(EAGAIN)) > > -break; > > -else if (ret < 0) > > -return ret; > > -s->buffered_pkt.size -= ret; > > -s->buffered_pkt.data += ret; > > -if (s->buffered_pkt.size <= 0) > > -av_packet_unref(&s->buffered_pkt); > > -} > > - > > -/* check for new frame */ > > -return ff_mediacodec_dec_receive(avctx, s->ctx, frame, wait); > > -} > > - > > static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame > *frame) > > { > > MediaCodecH264DecContext *s = avctx->priv_data; > > int ret; > > +ssize_t index; > > > > /* In delay_flush mode, wait until the user has released or rendered > > all retained frames. */ > > @@ -427,28 +405,54 @@ static int mediacodec_receive_frame(AVCodecContext > *avctx, AVFrame *frame) > > } > > } > > > > -/* flush buffered packet and check for new frame */ > > -ret = mediacodec_send_receive(avctx, s, frame, false); > > +/* poll for new frame */ > > +ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false); > > if (ret != AVERROR(EAGAIN)) > > return ret; > > > > -/* skip fetching new packet if we still have one buffered */ > > -if (s->buffered_pkt.size > 0) > > -return mediacodec_send_receive(avctx, s, frame, true); > > +/* feed decoder */ > > +while (1) { > > +if (s->ctx->current_input_buffer < 0) { > > +/* poll for input space */ > > +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); > > +} > > +s->ctx->current_input_buffer = index; > > +} > > > > -/* fetch new packet or eof */ > > -ret = ff_decode_get_packet(avctx, &s->buffered_pkt); > > -if (ret == AVERROR_EOF) { > > -AVPacket null_pkt = { 0 }; > > -ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt); > > -if (ret < 0) > > +/* try to flush any buffered packet data */ > > +if (s->buffered_pkt.size > 0) { > > +ret = ff_mediacodec_dec_send(avctx, s->ctx, > &s->buffered_pkt, false); > > +if (ret >= 0) { > > +s->buffered_pkt.size -= ret; > > +s->buffered_pkt.data += ret; > > +if (s->buffered_pkt.size <= 0) > > +av_packet_unref(&s->buffered_pkt); > > +} else if (ret < 0 && ret != AVERROR(EAGAIN)) { > > +return ret; > > +} > > + > > +/* poll for space again */ > > +continue; > > +} > > + > > +/* fetch new packet or eof */ > > +ret = ff_decode_get_packet(avctx, &s->buffered_pkt); > > +if (ret == AVERROR_EOF) { > > +AVPacket null_pkt = { 0 }; > > +ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, > true); > > +if (ret < 0) > > +return ret; > > +} else if (ret == AVERROR(EAGAIN) && > s->ctx->current_input_buffer < 0) { > > +return ff_mediacodec_dec_receive(avctx, s->ctx, frame, > true); > > +} else if (ret < 0) { > > return ret; > > +} > > Same comment as for the previous version of the patch: > https://ffmpeg.org/pipermail/ffmpeg-devel/2018-April/228978.html I think that comm
Re: [FFmpeg-devel] [PATCH v2 2/4] avcodec/mediacodecdec: restructure mediacodec_receive_frame
On Wed, May 02, 2018 at 07:24:58PM -0700, Aman Gupta wrote: > From: Aman Gupta > > The new logic follows a recommendation by @rcombs to use > dequeueInputBuffer with a timeout of 0 as a way to detect > whether the codec wants more data. The dequeued buffer index is > kept in MediaCodecDecContext until it can be used next. > > A similar technique is also used by the Google's official media > player Exoplayer: see MediaCodecRenderer.feedInputBuffer(). > > Signed-off-by: Aman Gupta > --- > libavcodec/mediacodecdec.c| 80 > --- > libavcodec/mediacodecdec_common.c | 28 -- > libavcodec/mediacodecdec_common.h | 4 +- > 3 files changed, 61 insertions(+), 51 deletions(-) > > diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c > index 86ceee5a83..2ac22dd1f6 100644 > --- a/libavcodec/mediacodecdec.c > +++ b/libavcodec/mediacodecdec.c > @@ -391,33 +391,11 @@ done: > return ret; > } > > -static int mediacodec_send_receive(AVCodecContext *avctx, > - MediaCodecH264DecContext *s, > - AVFrame *frame, bool wait) > -{ > -int ret; > - > -/* send any pending data from buffered packet */ > -while (s->buffered_pkt.size) { > -ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt); > -if (ret == AVERROR(EAGAIN)) > -break; > -else if (ret < 0) > -return ret; > -s->buffered_pkt.size -= ret; > -s->buffered_pkt.data += ret; > -if (s->buffered_pkt.size <= 0) > -av_packet_unref(&s->buffered_pkt); > -} > - > -/* check for new frame */ > -return ff_mediacodec_dec_receive(avctx, s->ctx, frame, wait); > -} > - > static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) > { > MediaCodecH264DecContext *s = avctx->priv_data; > int ret; > +ssize_t index; > > /* In delay_flush mode, wait until the user has released or rendered > all retained frames. */ > @@ -427,28 +405,54 @@ static int mediacodec_receive_frame(AVCodecContext > *avctx, AVFrame *frame) > } > } > > -/* flush buffered packet and check for new frame */ > -ret = mediacodec_send_receive(avctx, s, frame, false); > +/* poll for new frame */ > +ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false); > if (ret != AVERROR(EAGAIN)) > return ret; > > -/* skip fetching new packet if we still have one buffered */ > -if (s->buffered_pkt.size > 0) > -return mediacodec_send_receive(avctx, s, frame, true); > +/* feed decoder */ > +while (1) { > +if (s->ctx->current_input_buffer < 0) { > +/* poll for input space */ > +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); > +} > +s->ctx->current_input_buffer = index; > +} > > -/* fetch new packet or eof */ > -ret = ff_decode_get_packet(avctx, &s->buffered_pkt); > -if (ret == AVERROR_EOF) { > -AVPacket null_pkt = { 0 }; > -ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt); > -if (ret < 0) > +/* try to flush any buffered packet data */ > +if (s->buffered_pkt.size > 0) { > +ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt, > false); > +if (ret >= 0) { > +s->buffered_pkt.size -= ret; > +s->buffered_pkt.data += ret; > +if (s->buffered_pkt.size <= 0) > +av_packet_unref(&s->buffered_pkt); > +} else if (ret < 0 && ret != AVERROR(EAGAIN)) { > +return ret; > +} > + > +/* poll for space again */ > +continue; > +} > + > +/* fetch new packet or eof */ > +ret = ff_decode_get_packet(avctx, &s->buffered_pkt); > +if (ret == AVERROR_EOF) { > +AVPacket null_pkt = { 0 }; > +ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, true); > +if (ret < 0) > +return ret; > +} else if (ret == AVERROR(EAGAIN) && s->ctx->current_input_buffer < > 0) { > +return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); > +} else if (ret < 0) { > return ret; > +} Same comment as for the previous version of the patch: https://ffmpeg.org/pipermail/ffmpeg-devel/2018-April/228978.html [...] -- Matthieu B. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 2/4] avcodec/mediacodecdec: restructure mediacodec_receive_frame
From: Aman Gupta The new logic follows a recommendation by @rcombs to use dequeueInputBuffer with a timeout of 0 as a way to detect whether the codec wants more data. The dequeued buffer index is kept in MediaCodecDecContext until it can be used next. A similar technique is also used by the Google's official media player Exoplayer: see MediaCodecRenderer.feedInputBuffer(). Signed-off-by: Aman Gupta --- libavcodec/mediacodecdec.c| 80 --- libavcodec/mediacodecdec_common.c | 28 -- libavcodec/mediacodecdec_common.h | 4 +- 3 files changed, 61 insertions(+), 51 deletions(-) diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index 86ceee5a83..2ac22dd1f6 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -391,33 +391,11 @@ done: return ret; } -static int mediacodec_send_receive(AVCodecContext *avctx, - MediaCodecH264DecContext *s, - AVFrame *frame, bool wait) -{ -int ret; - -/* send any pending data from buffered packet */ -while (s->buffered_pkt.size) { -ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt); -if (ret == AVERROR(EAGAIN)) -break; -else if (ret < 0) -return ret; -s->buffered_pkt.size -= ret; -s->buffered_pkt.data += ret; -if (s->buffered_pkt.size <= 0) -av_packet_unref(&s->buffered_pkt); -} - -/* check for new frame */ -return ff_mediacodec_dec_receive(avctx, s->ctx, frame, wait); -} - static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) { MediaCodecH264DecContext *s = avctx->priv_data; int ret; +ssize_t index; /* In delay_flush mode, wait until the user has released or rendered all retained frames. */ @@ -427,28 +405,54 @@ static int mediacodec_receive_frame(AVCodecContext *avctx, AVFrame *frame) } } -/* flush buffered packet and check for new frame */ -ret = mediacodec_send_receive(avctx, s, frame, false); +/* poll for new frame */ +ret = ff_mediacodec_dec_receive(avctx, s->ctx, frame, false); if (ret != AVERROR(EAGAIN)) return ret; -/* skip fetching new packet if we still have one buffered */ -if (s->buffered_pkt.size > 0) -return mediacodec_send_receive(avctx, s, frame, true); +/* feed decoder */ +while (1) { +if (s->ctx->current_input_buffer < 0) { +/* poll for input space */ +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); +} +s->ctx->current_input_buffer = index; +} -/* fetch new packet or eof */ -ret = ff_decode_get_packet(avctx, &s->buffered_pkt); -if (ret == AVERROR_EOF) { -AVPacket null_pkt = { 0 }; -ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt); -if (ret < 0) +/* try to flush any buffered packet data */ +if (s->buffered_pkt.size > 0) { +ret = ff_mediacodec_dec_send(avctx, s->ctx, &s->buffered_pkt, false); +if (ret >= 0) { +s->buffered_pkt.size -= ret; +s->buffered_pkt.data += ret; +if (s->buffered_pkt.size <= 0) +av_packet_unref(&s->buffered_pkt); +} else if (ret < 0 && ret != AVERROR(EAGAIN)) { +return ret; +} + +/* poll for space again */ +continue; +} + +/* fetch new packet or eof */ +ret = ff_decode_get_packet(avctx, &s->buffered_pkt); +if (ret == AVERROR_EOF) { +AVPacket null_pkt = { 0 }; +ret = ff_mediacodec_dec_send(avctx, s->ctx, &null_pkt, true); +if (ret < 0) +return ret; +} else if (ret == AVERROR(EAGAIN) && s->ctx->current_input_buffer < 0) { +return ff_mediacodec_dec_receive(avctx, s->ctx, frame, true); +} else if (ret < 0) { return ret; +} } -else if (ret < 0) -return ret; -/* crank decoder with new packet */ -return mediacodec_send_receive(avctx, s, frame, true); +return AVERROR(EAGAIN); } static void mediacodec_decode_flush(AVCodecContext *avctx) diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c index c0f0a6b983..887865a281 100644 --- a/libavcodec/mediacodecdec_common.c +++ b/libavcodec/mediacodecdec_common.c @@ -450,6 +450,7 @@ static int mediacodec_dec_flush_codec(AVCodecContext *avctx, MediaCodecDecContex s->eos = 0; atomic_fetch_add(&s->serial, 1); atomic_init(&s->hw_buffer_count, 0); +s->current_input_buffer = -1; status = ff_AMediaCodec_flush(codec);