diff mbox series

[FFmpeg-devel,8/9] avcodec/encode: Enable encoders to control padding of last frame

Message ID GV1P250MB07373702C286FD86E3A75A778F499@GV1P250MB0737.EURP250.PROD.OUTLOOK.COM
State Accepted
Commit 017d976629ea272965ea67201543c8b5538cbf09
Headers show
Series [FFmpeg-devel,1/9] fate/audio: Add tests for APTX (HD) | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Andreas Rheinhardt Sept. 15, 2022, 7:28 p.m. UTC
Some audio codecs work with atomic units that decode to a fixed
number of audio samples with this number being so small that it is
common to put multiple of these atoms into one packet. In these
cases it makes no sense to pad the last frame to the big frame_size,
so allow encoders to set the number of samples that they want
the last frame to be padded to instead.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavcodec/encode.c   | 17 +++++++++++------
 libavcodec/internal.h |  6 ++++++
 2 files changed, 17 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 9bd9f9bc08..049b71c6f4 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -127,12 +127,12 @@  static int encode_make_refcounted(AVCodecContext *avctx, AVPacket *avpkt)
 /**
  * Pad last frame with silence.
  */
-static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src)
+static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src, int out_samples)
 {
     int ret;
 
     frame->format         = src->format;
-    frame->nb_samples     = s->frame_size;
+    frame->nb_samples     = out_samples;
     ret = av_channel_layout_copy(&frame->ch_layout, &s->ch_layout);
     if (ret < 0)
         goto fail;
@@ -406,10 +406,15 @@  static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src)
             if (src->nb_samples < avctx->frame_size) {
                 avctx->internal->last_audio_frame = 1;
                 if (!(avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME)) {
-                ret = pad_last_frame(avctx, dst, src);
-                if (ret < 0)
-                    return ret;
-                goto finish;
+                    int pad_samples = avci->pad_samples ? avci->pad_samples : avctx->frame_size;
+                    int out_samples = (src->nb_samples + pad_samples - 1) / pad_samples * pad_samples;
+
+                    if (out_samples != src->nb_samples) {
+                        ret = pad_last_frame(avctx, dst, src, out_samples);
+                        if (ret < 0)
+                            return ret;
+                        goto finish;
+                    }
                 }
             }
         }
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 45aec38a60..76a6ea6bc6 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -62,6 +62,12 @@  typedef struct AVCodecInternal {
      */
     int last_audio_frame;
 
+    /**
+     * Audio encoders can set this flag during init to indicate that they
+     * want the small last frame to be padded to a multiple of pad_samples.
+     */
+    int pad_samples;
+
     AVBufferRef *pool;
 
     void *thread_ctx;