libfdk-aacenc: Fix building with libfdk-aac v2

Message ID 20180902204829.83151-1-martin@martin.st
State Committed
Commit 141c960e21d2860e354f9b90df136184dd00a9a8
Headers show
Series
  • libfdk-aacenc: Fix building with libfdk-aac v2
Related show

Commit Message

Martin Storsjö Sept. 2, 2018, 8:48 p.m.
When flushing the encoder, we now need to provide non-null buffer
parameters for everything, even if they are unused.

The encoderDelay parameter has been replaced by two, nDelay and
nDelayCore.
---
libfdk-aac v2 also has a bunch of other new, yet untested features,
like support for xHE-AAC.
---
 libavcodec/libfdk-aacenc.c | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

Comments

Luca Barbato Sept. 3, 2018, 7:10 a.m. | #1
On 02/09/2018 22:48, Martin Storsjö wrote:
> When flushing the encoder, we now need to provide non-null buffer
> parameters for everything, even if they are unused.
> 
> The encoderDelay parameter has been replaced by two, nDelay and
> nDelayCore.
> ---
> libfdk-aac v2 also has a bunch of other new, yet untested features,
> like support for xHE-AAC.
> ---
>  libavcodec/libfdk-aacenc.c | 34 +++++++++++++++++++++++++---------
>  1 file changed, 25 insertions(+), 9 deletions(-)

Ok.

Patch

diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
index c340a1e3e0..2ad768ed44 100644
--- a/libavcodec/libfdk-aacenc.c
+++ b/libavcodec/libfdk-aacenc.c
@@ -26,6 +26,11 @@ 
 #include "audio_frame_queue.h"
 #include "internal.h"
 
+#define FDKENC_VER_AT_LEAST(vl0, vl1) \
+    (defined(AACENCODER_LIB_VL0) && \
+        ((AACENCODER_LIB_VL0 > vl0) || \
+         (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1)))
+
 typedef struct AACContext {
     const AVClass *class;
     HANDLE_AACENCODER handle;
@@ -290,7 +295,11 @@  static av_cold int aac_encode_init(AVCodecContext *avctx)
     }
 
     avctx->frame_size = info.frameLength;
+#if FDKENC_VER_AT_LEAST(4, 0)
+    avctx->initial_padding = info.nDelay;
+#else
     avctx->initial_padding = info.encoderDelay;
+#endif
     ff_af_queue_init(avctx, &s->afq);
 
     if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
@@ -323,28 +332,35 @@  static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
     int out_buffer_size, out_buffer_element_size;
     void *in_ptr, *out_ptr;
     int ret;
+    uint8_t dummy_buf[1];
     AACENC_ERROR err;
 
     /* handle end-of-stream small frame and flushing */
     if (!frame) {
+        /* Must be a non-null pointer, even if it's a dummy. We could use
+         * the address of anything else on the stack as well. */
+        in_ptr               = dummy_buf;
+        in_buffer_size       = 0;
+
         in_args.numInSamples = -1;
     } else {
-        in_ptr                   = frame->data[0];
-        in_buffer_size           = 2 * avctx->channels * frame->nb_samples;
-        in_buffer_element_size   = 2;
+        in_ptr               = frame->data[0];
+        in_buffer_size       = 2 * avctx->channels * frame->nb_samples;
 
-        in_args.numInSamples     = avctx->channels * frame->nb_samples;
-        in_buf.numBufs           = 1;
-        in_buf.bufs              = &in_ptr;
-        in_buf.bufferIdentifiers = &in_buffer_identifier;
-        in_buf.bufSizes          = &in_buffer_size;
-        in_buf.bufElSizes        = &in_buffer_element_size;
+        in_args.numInSamples = avctx->channels * frame->nb_samples;
 
         /* add current frame to the queue */
         if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
             return ret;
     }
 
+    in_buffer_element_size   = 2;
+    in_buf.numBufs           = 1;
+    in_buf.bufs              = &in_ptr;
+    in_buf.bufferIdentifiers = &in_buffer_identifier;
+    in_buf.bufSizes          = &in_buffer_size;
+    in_buf.bufElSizes        = &in_buffer_element_size;
+
     /* The maximum packet size is 6144 bits aka 768 bytes per channel. */
     if ((ret = ff_alloc_packet(avpkt, FFMAX(8192, 768 * avctx->channels)))) {
         av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");