[FFmpeg-devel] [PATCH 2/2] avcodec/mediacodecdec_common: do not split input packets into multiple buffers in ff_mediacodec_dec_send()

Matthieu Bouron matthieu.bouron at gmail.com
Fri Sep 6 16:57:58 EEST 2019


MediaCodec expects exactly one incoming buffer with a given PTS, it is
not valid to split data for a given PTS across multiple input buffers.

See https://developer.android.com/reference/android/media/MediaCodec#data-processing

  > Do not submit multiple input buffers with the same timestamp
---
 libavcodec/mediacodecdec_common.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c
index 6c0a1212c1..74fa29cc7d 100644
--- a/libavcodec/mediacodecdec_common.c
+++ b/libavcodec/mediacodecdec_common.c
@@ -566,7 +566,6 @@ fail:
 int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s,
                            AVPacket *pkt, bool wait)
 {
-    int offset = 0;
     int need_draining = pkt->size == 0;
     uint8_t *data;
     ssize_t index = s->current_input_buffer;
@@ -586,12 +585,15 @@ int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s,
         return AVERROR_EOF;
     }
 
-    while (offset < pkt->size || (need_draining && !s->draining)) {
+    if (s->draining) {
+        return 0;
+    }
+
         if (index < 0) {
             index = ff_AMediaCodec_dequeueInputBuffer(codec, input_dequeue_timeout_us);
             if (ff_AMediaCodec_infoTryAgainLater(codec, index)) {
                 av_log(avctx, AV_LOG_TRACE, "No input buffer available, try again later\n");
-                break;
+                return AVERROR(EAGAIN);
             }
 
             if (index < 0) {
@@ -630,9 +632,8 @@ int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s,
             return 0;
         }
 
-        size = FFMIN(pkt->size - offset, size);
-        memcpy(data, pkt->data + offset, size);
-        offset += size;
+        size = FFMIN(pkt->size, size);
+        memcpy(data, pkt->data, size);
 
         status = ff_AMediaCodec_queueInputBuffer(codec, index, 0, size, pts, 0);
         if (status < 0) {
@@ -642,11 +643,8 @@ int ff_mediacodec_dec_send(AVCodecContext *avctx, MediaCodecDecContext *s,
 
         av_log(avctx, AV_LOG_TRACE,
                "Queued input buffer %zd size=%zd ts=%"PRIi64"\n", index, size, pts);
-    }
 
-    if (offset == 0)
-        return AVERROR(EAGAIN);
-    return offset;
+    return size;
 }
 
 int ff_mediacodec_dec_receive(AVCodecContext *avctx, MediaCodecDecContext *s,
-- 
2.23.0



More information about the ffmpeg-devel mailing list