Browse code

Correctly implement ac3 float/fixed encoder. There is no need to have 2 encoders, the input sample format can,does and should choose which is used Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2011/04/17 06:20:48
Showing 7 changed files
... ...
@@ -59,7 +59,8 @@ OBJS-$(CONFIG_AAC_ENCODER)             += aacenc.o aaccoder.o    \
59 59
                                           mpeg4audio.o kbdwin.o
60 60
 OBJS-$(CONFIG_AASC_DECODER)            += aasc.o msrledec.o
61 61
 OBJS-$(CONFIG_AC3_DECODER)             += ac3dec.o ac3dec_data.o ac3.o kbdwin.o
62
-OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_float.o ac3tab.o ac3.o kbdwin.o
62
+OBJS-$(CONFIG_AC3_ENCODER)             += ac3enc_combined.o ac3enc_fixed.o ac3enc_float.o ac3tab.o ac3.o kbdwin.o
63
+OBJS-$(CONFIG_AC3_FLOAT_ENCODER)       += ac3enc_float.o ac3tab.o ac3.o kbdwin.o
63 64
 OBJS-$(CONFIG_AC3_FIXED_ENCODER)       += ac3enc_fixed.o ac3tab.o ac3.o
64 65
 OBJS-$(CONFIG_ALAC_DECODER)            += alac.o
65 66
 OBJS-$(CONFIG_ALAC_ENCODER)            += alacenc.o
... ...
@@ -38,6 +38,8 @@
38 38
 #define AC3_CRITICAL_BANDS 50
39 39
 #define AC3_MAX_CPL_BANDS  18
40 40
 
41
+#include "libavutil/opt.h"
42
+#include "avcodec.h"
41 43
 #include "ac3tab.h"
42 44
 
43 45
 /* exponent encoding strategy */
... ...
@@ -128,8 +130,45 @@ typedef enum {
128 128
     EAC3_FRAME_TYPE_RESERVED
129 129
 } EAC3FrameType;
130 130
 
131
+/**
132
+ * Encoding Options used by AVOption.
133
+ */
134
+typedef struct AC3EncOptions {
135
+    /* AC-3 metadata options*/
136
+    int dialogue_level;
137
+    int bitstream_mode;
138
+    float center_mix_level;
139
+    float surround_mix_level;
140
+    int dolby_surround_mode;
141
+    int audio_production_info;
142
+    int mixing_level;
143
+    int room_type;
144
+    int copyright;
145
+    int original;
146
+    int extended_bsi_1;
147
+    int preferred_stereo_downmix;
148
+    float ltrt_center_mix_level;
149
+    float ltrt_surround_mix_level;
150
+    float loro_center_mix_level;
151
+    float loro_surround_mix_level;
152
+    int extended_bsi_2;
153
+    int dolby_surround_ex_mode;
154
+    int dolby_headphone_mode;
155
+    int ad_converter_type;
156
+
157
+    /* other encoding options */
158
+    int allow_per_frame_metadata;
159
+} AC3EncOptions;
160
+
161
+
131 162
 void ff_ac3_common_init(void);
132 163
 
164
+extern const int64_t ff_ac3_channel_layouts[];
165
+extern const AVOption ff_ac3_options[];
166
+
167
+extern AVCodec ff_ac3_float_encoder;
168
+extern AVCodec ff_ac3_fixed_encoder;
169
+
133 170
 /**
134 171
  * Calculate the log power-spectral density of the input signal.
135 172
  * This gives a rough estimate of signal power in the frequency domain by using
... ...
@@ -76,36 +76,6 @@ typedef struct AC3MDCTContext {
76 76
 } AC3MDCTContext;
77 77
 
78 78
 /**
79
- * Encoding Options used by AVOption.
80
- */
81
-typedef struct AC3EncOptions {
82
-    /* AC-3 metadata options*/
83
-    int dialogue_level;
84
-    int bitstream_mode;
85
-    float center_mix_level;
86
-    float surround_mix_level;
87
-    int dolby_surround_mode;
88
-    int audio_production_info;
89
-    int mixing_level;
90
-    int room_type;
91
-    int copyright;
92
-    int original;
93
-    int extended_bsi_1;
94
-    int preferred_stereo_downmix;
95
-    float ltrt_center_mix_level;
96
-    float ltrt_surround_mix_level;
97
-    float loro_center_mix_level;
98
-    float loro_surround_mix_level;
99
-    int extended_bsi_2;
100
-    int dolby_surround_ex_mode;
101
-    int dolby_headphone_mode;
102
-    int ad_converter_type;
103
-
104
-    /* other encoding options */
105
-    int allow_per_frame_metadata;
106
-} AC3EncOptions;
107
-
108
-/**
109 79
  * Data for a single audio block.
110 80
  */
111 81
 typedef struct AC3Block {
... ...
@@ -229,7 +199,8 @@ static const float extmixlev_options[EXTMIXLEV_NUM_OPTIONS] = {
229 229
 #define OFFSET(param) offsetof(AC3EncodeContext, options.param)
230 230
 #define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
231 231
 
232
-static const AVOption options[] = {
232
+#if CONFIG_AC3ENC_FLOAT || !CONFIG_AC3_FLOAT_ENCODER //we need this exactly once compiled in
233
+const AVOption ff_ac3_options[] = {
233 234
 /* Metadata Options */
234 235
 {"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), FF_OPT_TYPE_INT, 0, 0, 1, AC3ENC_PARAM},
235 236
 /* downmix levels */
... ...
@@ -271,13 +242,14 @@ static const AVOption options[] = {
271 271
     {"hdcd",     "HDCD",               0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
272 272
 {NULL}
273 273
 };
274
+#endif
274 275
 
275 276
 #if CONFIG_AC3ENC_FLOAT
276 277
 static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
277
-                                options, LIBAVUTIL_VERSION_INT };
278
+                                ff_ac3_options, LIBAVUTIL_VERSION_INT };
278 279
 #else
279 280
 static AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name,
280
-                                options, LIBAVUTIL_VERSION_INT };
281
+                                ff_ac3_options, LIBAVUTIL_VERSION_INT };
281 282
 #endif
282 283
 
283 284
 
... ...
@@ -306,7 +278,8 @@ static uint8_t exponent_group_tab[3][256];
306 306
 /**
307 307
  * List of supported channel layouts.
308 308
  */
309
-static const int64_t ac3_channel_layouts[] = {
309
+#if CONFIG_AC3ENC_FLOAT || !CONFIG_AC3_FLOAT_ENCODER //we need this exactly once compiled in
310
+const int64_t ff_ac3_channel_layouts[] = {
310 311
      AV_CH_LAYOUT_MONO,
311 312
      AV_CH_LAYOUT_STEREO,
312 313
      AV_CH_LAYOUT_2_1,
... ...
@@ -327,6 +300,7 @@ static const int64_t ac3_channel_layouts[] = {
327 327
      AV_CH_LAYOUT_5POINT1_BACK,
328 328
      0
329 329
 };
330
+#endif
330 331
 
331 332
 
332 333
 /**
333 334
new file mode 100644
... ...
@@ -0,0 +1,90 @@
0
+
1
+#include "libavutil/opt.h"
2
+#include "libavutil/samplefmt.h"
3
+#include "avcodec.h"
4
+#include "ac3.h"
5
+
6
+typedef struct CombineContext{
7
+    AVClass *av_class;                      ///< AVClass used for AVOption
8
+    AC3EncOptions options;                  ///< encoding options
9
+    void *ctx;
10
+    AVCodec *codec;
11
+}CombineContext;
12
+
13
+static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
14
+                                ff_ac3_options, LIBAVUTIL_VERSION_INT };
15
+
16
+static av_cold AVCodec *get_codec(enum AVSampleFormat s){
17
+#if CONFIG_AC3_FIXED_ENCODER
18
+    if(s==AV_SAMPLE_FMT_S16) return &ff_ac3_fixed_encoder;
19
+#endif
20
+#if CONFIG_AC3_FLOAT_ENCODER
21
+    if(s==AV_SAMPLE_FMT_FLT) return &ff_ac3_float_encoder;
22
+#endif
23
+    return NULL;
24
+}
25
+
26
+
27
+static av_cold int encode_init(AVCodecContext *avctx)
28
+{
29
+    CombineContext *c= avctx->priv_data;
30
+    int ret;
31
+    int offset= (uint8_t*)&c->options - (uint8_t*)c;
32
+
33
+    c->codec= get_codec(avctx->sample_fmt);
34
+    if(!c->codec){
35
+        av_log(avctx, AV_LOG_ERROR, "Unsupported sample format\n");
36
+        return -1;
37
+    }
38
+    c->ctx= av_mallocz(c->codec->priv_data_size);
39
+    memcpy((uint8_t*)c->ctx + offset, &c->options, (uint8_t*)&c->ctx - (uint8_t*)&c->options);
40
+    FFSWAP(void *,avctx->priv_data, c->ctx);
41
+    ret= c->codec->init(avctx);
42
+    FFSWAP(void *,avctx->priv_data, c->ctx);
43
+    return ret;
44
+}
45
+
46
+static int encode_frame(AVCodecContext *avctx, unsigned char *frame,
47
+                        int buf_size, void *data)
48
+{
49
+    CombineContext *c= avctx->priv_data;
50
+    int ret;
51
+
52
+    FFSWAP(void *,avctx->priv_data, c->ctx);
53
+    ret= c->codec->encode(avctx, frame, buf_size, data);
54
+    FFSWAP(void *,avctx->priv_data, c->ctx);
55
+    return ret;
56
+}
57
+
58
+static av_cold int encode_close(AVCodecContext *avctx)
59
+{
60
+    CombineContext *c= avctx->priv_data;
61
+    int ret;
62
+
63
+    FFSWAP(void *,avctx->priv_data, c->ctx);
64
+    ret= c->codec->close(avctx);
65
+    FFSWAP(void *,avctx->priv_data, c->ctx);
66
+    return ret;
67
+}
68
+
69
+AVCodec ff_ac3_encoder = {
70
+    "ac3",
71
+    AVMEDIA_TYPE_AUDIO,
72
+    CODEC_ID_AC3,
73
+    sizeof(CombineContext),
74
+    encode_init,
75
+    encode_frame,
76
+    encode_close,
77
+    NULL,
78
+    .sample_fmts = (const enum AVSampleFormat[]){
79
+#if CONFIG_AC3_FLOAT_ENCODER
80
+        AV_SAMPLE_FMT_FLT,
81
+#endif
82
+#if CONFIG_AC3_FIXED_ENCODER
83
+        AV_SAMPLE_FMT_S16,
84
+#endif
85
+        AV_SAMPLE_FMT_NONE},
86
+    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
87
+    .priv_class = &ac3enc_class,
88
+    .channel_layouts = ff_ac3_channel_layouts,
89
+};
... ...
@@ -121,5 +121,5 @@ AVCodec ff_ac3_fixed_encoder = {
121 121
     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
122 122
     .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
123 123
     .priv_class = &ac3enc_class,
124
-    .channel_layouts = ac3_channel_layouts,
124
+    .channel_layouts = ff_ac3_channel_layouts,
125 125
 };
... ...
@@ -98,8 +98,8 @@ static void scale_coefficients(AC3EncodeContext *s)
98 98
 }
99 99
 
100 100
 
101
-AVCodec ff_ac3_encoder = {
102
-    "ac3",
101
+AVCodec ff_ac3_float_encoder = {
102
+    "ac3_float",
103 103
     AVMEDIA_TYPE_AUDIO,
104 104
     CODEC_ID_AC3,
105 105
     sizeof(AC3EncodeContext),
... ...
@@ -110,5 +110,5 @@ AVCodec ff_ac3_encoder = {
110 110
     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},
111 111
     .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
112 112
     .priv_class = &ac3enc_class,
113
-    .channel_layouts = ac3_channel_layouts,
113
+    .channel_layouts = ff_ac3_channel_layouts,
114 114
 };
... ...
@@ -234,7 +234,8 @@ void avcodec_register_all(void)
234 234
     REGISTER_ENCDEC  (AAC, aac);
235 235
     REGISTER_DECODER (AAC_LATM, aac_latm);
236 236
     REGISTER_ENCDEC  (AC3, ac3);
237
-    REGISTER_ENCODER (AC3_FIXED, ac3_fixed);
237
+    REGISTER_ENCODER (AC3_FIXED, ac3_fixed); //deprecated, just for libav compatibility
238
+//    REGISTER_ENCODER (AC3_FLOAT, ac3_float); dont remove dont outcomment, for configure
238 239
     REGISTER_ENCDEC  (ALAC, alac);
239 240
     REGISTER_DECODER (ALS, als);
240 241
     REGISTER_DECODER (AMRNB, amrnb);