diff mbox series

[FFmpeg-devel,201/281] dolby_e: convert to new channel layout API

Message ID 20220113020242.661-22-jamrial@gmail.com
State Accepted
Commit a7a672c88edf51425e587f377c568b06f786d776
Headers show
Series New channel layout API | expand

Commit Message

James Almer Jan. 13, 2022, 2:02 a.m. UTC
From: Anton Khirnov <anton@khirnov.net>

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/dolby_e.c        | 52 ++++++++++++++++++++++++++++++++-----
 libavcodec/dolby_e.h        |  2 ++
 libavcodec/dolby_e_parser.c | 11 +++++---
 3 files changed, 55 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/dolby_e.c b/libavcodec/dolby_e.c
index 6c0d54be4c..a9106a7632 100644
--- a/libavcodec/dolby_e.c
+++ b/libavcodec/dolby_e.c
@@ -23,6 +23,7 @@ 
 #include "libavutil/thread.h"
 #include "libavutil/mem.h"
 #include "libavutil/mem_internal.h"
+#include "libavutil/opt.h"
 
 #include "internal.h"
 #include "get_bits.h"
@@ -39,6 +40,11 @@ 
 #define MAX_MSTR_EXP    2
 #define MAX_BIAS_EXP    50
 
+enum DBEOutputChannelOrder {
+    CHANNEL_ORDER_DEFAULT,
+    CHANNEL_ORDER_CODED,
+};
+
 typedef struct DBEGroup {
     uint8_t         nb_exponent;
     uint8_t         nb_bias_exp[MAX_MSTR_EXP];
@@ -70,6 +76,7 @@  typedef struct DBEChannel {
 } DBEChannel;
 
 typedef struct DBEDecodeContext {
+    const AVClass   *class;
     AVCodecContext  *avctx;
     DBEContext  dectx;
 
@@ -1057,7 +1064,7 @@  static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
         reorder = ch_reorder_4;
     else if (metadata->nb_channels == 6)
         reorder = ch_reorder_6;
-    else if (metadata->nb_programs == 1 && !(s->avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE))
+    else if (metadata->nb_programs == 1 && metadata->output_channel_order == CHANNEL_ORDER_DEFAULT)
         reorder = ch_reorder_8;
     else
         reorder = ch_reorder_n;
@@ -1093,19 +1100,23 @@  static int dolby_e_decode_frame(AVCodecContext *avctx, void *data,
         s->metadata.multi_prog_warned = 1;
     }
 
+    av_channel_layout_uninit(&avctx->ch_layout);
     switch (s->metadata.nb_channels) {
     case 4:
-        avctx->channel_layout = AV_CH_LAYOUT_4POINT0;
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT0;
         break;
     case 6:
-        avctx->channel_layout = AV_CH_LAYOUT_5POINT1;
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1;
         break;
     case 8:
-        avctx->channel_layout = AV_CH_LAYOUT_7POINT1;
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1;
+        break;
+    default:
+        avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+        avctx->ch_layout.nb_channels = s->metadata.nb_channels;
         break;
     }
 
-    avctx->channels    = s->metadata.nb_channels;
     avctx->sample_rate = s->metadata.sample_rate;
     avctx->sample_fmt  = AV_SAMPLE_FMT_FLTP;
 
@@ -1252,17 +1263,46 @@  static av_cold int dolby_e_init(AVCodecContext *avctx)
     if (!(s->fdsp = avpriv_float_dsp_alloc(0)))
         return AVERROR(ENOMEM);
 
-    s->dectx.metadata.multi_prog_warned = !!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE);
+#if FF_API_OLD_CHANNEL_LAYOUT
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)
+        s->dectx.metadata.output_channel_order = CHANNEL_ORDER_CODED;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+    s->dectx.metadata.multi_prog_warned = s->dectx.metadata.output_channel_order == CHANNEL_ORDER_CODED;
     s->dectx.avctx = s->avctx = avctx;
     return 0;
 }
 
+#define OFFSET(x) offsetof(DBEDecodeContext, x)
+#define FLAGS (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
+static const AVOption options[] = {
+    { "channel_order", "Order in which the channels are to be exported",
+        OFFSET(dectx.metadata.output_channel_order), AV_OPT_TYPE_INT,
+        { .i64 = CHANNEL_ORDER_DEFAULT }, 0, 1, FLAGS, "channel_order" },
+      { "default", "normal libavcodec channel order", 0, AV_OPT_TYPE_CONST,
+        { .i64 = CHANNEL_ORDER_DEFAULT }, .flags = FLAGS, "channel_order" },
+      { "coded",    "order in which the channels are coded in the bitstream",
+        0, AV_OPT_TYPE_CONST, { .i64 = CHANNEL_ORDER_CODED }, .flags = FLAGS, "channel_order" },
+
+      { NULL },
+};
+
+static const AVClass dolby_e_decoder_class = {
+    .class_name = "Dolby E decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 const AVCodec ff_dolby_e_decoder = {
     .name           = "dolby_e",
     .long_name      = NULL_IF_CONFIG_SMALL("Dolby E"),
     .type           = AVMEDIA_TYPE_AUDIO,
     .id             = AV_CODEC_ID_DOLBY_E,
     .priv_data_size = sizeof(DBEDecodeContext),
+    .priv_class     = &dolby_e_decoder_class,
     .init           = dolby_e_init,
     .decode         = dolby_e_decode_frame,
     .close          = dolby_e_close,
diff --git a/libavcodec/dolby_e.h b/libavcodec/dolby_e.h
index 9f0c065729..b2eadfea4a 100644
--- a/libavcodec/dolby_e.h
+++ b/libavcodec/dolby_e.h
@@ -59,6 +59,8 @@  typedef struct DolbyEHeaderInfo {
      */
     int         multi_prog_warned;
 
+    int         output_channel_order;
+
     int         sample_rate;
     /** @} */
 } DolbyEHeaderInfo;
diff --git a/libavcodec/dolby_e_parser.c b/libavcodec/dolby_e_parser.c
index 23bddd14f3..9f54627356 100644
--- a/libavcodec/dolby_e_parser.c
+++ b/libavcodec/dolby_e_parser.c
@@ -42,17 +42,20 @@  static int dolby_e_parse(AVCodecParserContext *s2, AVCodecContext *avctx,
     s2->duration = FRAME_SAMPLES;
     switch (s->metadata.nb_channels) {
     case 4:
-        avctx->channel_layout = AV_CH_LAYOUT_4POINT0;
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_4POINT0;
         break;
     case 6:
-        avctx->channel_layout = AV_CH_LAYOUT_5POINT1;
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1;
         break;
     case 8:
-        avctx->channel_layout = AV_CH_LAYOUT_7POINT1;
+        avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1;
+        break;
+    default:
+        avctx->ch_layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+        avctx->ch_layout.nb_channels = s->metadata.nb_channels;
         break;
     }
 
-    avctx->channels    = s->metadata.nb_channels;
     avctx->sample_rate = s->metadata.sample_rate;
     avctx->sample_fmt  = AV_SAMPLE_FMT_FLTP;