[FFmpeg-cvslog] avcodec/mediacodecenc: remove the strategy to create DTS

Zhao Zhili git at videolan.org
Fri Dec 16 14:35:55 EET 2022


ffmpeg | branch: master | Zhao Zhili <zhilizhao at tencent.com> | Wed Dec  7 17:31:20 2022 +0800| [7da1adfc026a57ab3fb42516354f8e62f3f7d35d] | committer: Zhao Zhili

avcodec/mediacodecenc: remove the strategy to create DTS

Use input PTS as DTS has multiple problems:
1. If there is no reordering, it's better to just use the output
PTS as DTS, since encoder may change the timestamp value (do it
on purpose or rounding error).

2. If there is reordering, input PTS should be shift a few frames
as DTS to satisfy the requirement of PTS >= DTS. I can't find a
reliable way to determine how many frames to be shift. For example,
we don't known if the encoder use hierarchical B frames. The
max_num_reorder_frames can be get from VUI, but VUI is optional.

3. Encoder dropping frames makes the case worse. Android has an
BITRATE_MODE_CBR_FD option to allow it explicitly.

Signed-off-by: Zhao Zhili <zhilizhao at tencent.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=7da1adfc026a57ab3fb42516354f8e62f3f7d35d
---

 libavcodec/mediacodecenc.c | 28 +---------------------------
 1 file changed, 1 insertion(+), 27 deletions(-)

diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c
index 4e8716e3a5..96bc9c9c28 100644
--- a/libavcodec/mediacodecenc.c
+++ b/libavcodec/mediacodecenc.c
@@ -64,18 +64,6 @@ typedef struct MediaCodecEncContext {
 
     uint8_t *extradata;
     int extradata_size;
-
-    // Since MediaCodec doesn't output DTS, use a timestamp queue to save pts
-    // of AVFrame and generate DTS for AVPacket.
-    //
-    // This doesn't work when use Surface as input, in that case frames can be
-    // sent to encoder without our notice. One exception is frames come from
-    // our MediaCodec decoder wrapper, since we can control it's render by
-    // av_mediacodec_release_buffer.
-    int64_t timestamps[32];
-    int ts_head;
-    int ts_tail;
-
     int eof_sent;
 
     AVFrame *frame;
@@ -379,11 +367,6 @@ static int mediacodec_receive(AVCodecContext *avctx,
     }
     memcpy(pkt->data + extradata_size, out_buf + out_info.offset, out_info.size);
     pkt->pts = av_rescale_q(out_info.presentationTimeUs, AV_TIME_BASE_Q, avctx->time_base);
-    if (s->ts_tail != s->ts_head) {
-        pkt->dts = s->timestamps[s->ts_tail];
-        s->ts_tail = (s->ts_tail + 1) % FF_ARRAY_ELEMS(s->timestamps);
-    }
-
     if (out_info.flags & ff_AMediaCodec_getBufferFlagKeyFrame(codec))
         pkt->flags |= AV_PKT_FLAG_KEY;
     ret = 0;
@@ -448,14 +431,8 @@ static int mediacodec_send(AVCodecContext *avctx,
             return ff_AMediaCodec_signalEndOfInputStream(codec);
         }
 
-
-        if (frame->data[3]) {
-            pts = av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q);
-            s->timestamps[s->ts_head] = frame->pts;
-            s->ts_head = (s->ts_head + 1) % FF_ARRAY_ELEMS(s->timestamps);
-
+        if (frame->data[3])
             av_mediacodec_release_buffer((AVMediaCodecBuffer *)frame->data[3], 1);
-        }
         return 0;
     }
 
@@ -474,9 +451,6 @@ static int mediacodec_send(AVCodecContext *avctx,
         copy_frame_to_buffer(avctx, frame, input_buf, input_size);
 
         pts = av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q);
-
-        s->timestamps[s->ts_head] = frame->pts;
-        s->ts_head = (s->ts_head + 1) % FF_ARRAY_ELEMS(s->timestamps);
     } else {
         flags |= ff_AMediaCodec_getBufferFlagEndOfStream(codec);
         s->eof_sent = 1;



More information about the ffmpeg-cvslog mailing list