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

Submitted by Matthieu Bouron on Sept. 6, 2019, 1:57 p.m.

Details

Message ID 20190906135758.14768-2-matthieu.bouron@gmail.com
State New
Headers show

Commit Message

Matthieu Bouron Sept. 6, 2019, 1:57 p.m.
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(-)

Patch hide | download patch | download mbox

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,