aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-04-16 23:20:48 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-04-16 23:24:10 +0200
commit1aeb88b77ddbd3802127a61bf8610e55b6c49a6f (patch)
tree784f8679e8f6a5ca5a7980e20e8b3b5fff47cbd4
parentbdf3d3bf9dce398acce608de77da205e08bdace3 (diff)
downloadffmpeg-1aeb88b77ddbd3802127a61bf8610e55b6c49a6f.tar.gz
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>
-rw-r--r--libavcodec/Makefile3
-rw-r--r--libavcodec/ac3.h39
-rw-r--r--libavcodec/ac3enc.c42
-rw-r--r--libavcodec/ac3enc_combined.c90
-rw-r--r--libavcodec/ac3enc_fixed.c2
-rw-r--r--libavcodec/ac3enc_float.c6
-rw-r--r--libavcodec/allcodecs.c3
7 files changed, 145 insertions, 40 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index ad0a3cc6bc..e1432b3a96 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -59,7 +59,8 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \
mpeg4audio.o kbdwin.o
OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o kbdwin.o
-OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3tab.o ac3.o kbdwin.o
+OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_combined.o ac3enc_fixed.o ac3enc_float.o ac3tab.o ac3.o kbdwin.o
+OBJS-$(CONFIG_AC3_FLOAT_ENCODER) += ac3enc_float.o ac3tab.o ac3.o kbdwin.o
OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3tab.o ac3.o
OBJS-$(CONFIG_ALAC_DECODER) += alac.o
OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o
diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h
index 371d0a2532..6baf989394 100644
--- a/libavcodec/ac3.h
+++ b/libavcodec/ac3.h
@@ -38,6 +38,8 @@
#define AC3_CRITICAL_BANDS 50
#define AC3_MAX_CPL_BANDS 18
+#include "libavutil/opt.h"
+#include "avcodec.h"
#include "ac3tab.h"
/* exponent encoding strategy */
@@ -128,8 +130,45 @@ typedef enum {
EAC3_FRAME_TYPE_RESERVED
} EAC3FrameType;
+/**
+ * Encoding Options used by AVOption.
+ */
+typedef struct AC3EncOptions {
+ /* AC-3 metadata options*/
+ int dialogue_level;
+ int bitstream_mode;
+ float center_mix_level;
+ float surround_mix_level;
+ int dolby_surround_mode;
+ int audio_production_info;
+ int mixing_level;
+ int room_type;
+ int copyright;
+ int original;
+ int extended_bsi_1;
+ int preferred_stereo_downmix;
+ float ltrt_center_mix_level;
+ float ltrt_surround_mix_level;
+ float loro_center_mix_level;
+ float loro_surround_mix_level;
+ int extended_bsi_2;
+ int dolby_surround_ex_mode;
+ int dolby_headphone_mode;
+ int ad_converter_type;
+
+ /* other encoding options */
+ int allow_per_frame_metadata;
+} AC3EncOptions;
+
+
void ff_ac3_common_init(void);
+extern const int64_t ff_ac3_channel_layouts[];
+extern const AVOption ff_ac3_options[];
+
+extern AVCodec ff_ac3_float_encoder;
+extern AVCodec ff_ac3_fixed_encoder;
+
/**
* Calculate the log power-spectral density of the input signal.
* This gives a rough estimate of signal power in the frequency domain by using
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 1c353b6a43..77ebcdc9e2 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -76,36 +76,6 @@ typedef struct AC3MDCTContext {
} AC3MDCTContext;
/**
- * Encoding Options used by AVOption.
- */
-typedef struct AC3EncOptions {
- /* AC-3 metadata options*/
- int dialogue_level;
- int bitstream_mode;
- float center_mix_level;
- float surround_mix_level;
- int dolby_surround_mode;
- int audio_production_info;
- int mixing_level;
- int room_type;
- int copyright;
- int original;
- int extended_bsi_1;
- int preferred_stereo_downmix;
- float ltrt_center_mix_level;
- float ltrt_surround_mix_level;
- float loro_center_mix_level;
- float loro_surround_mix_level;
- int extended_bsi_2;
- int dolby_surround_ex_mode;
- int dolby_headphone_mode;
- int ad_converter_type;
-
- /* other encoding options */
- int allow_per_frame_metadata;
-} AC3EncOptions;
-
-/**
* Data for a single audio block.
*/
typedef struct AC3Block {
@@ -229,7 +199,8 @@ static const float extmixlev_options[EXTMIXLEV_NUM_OPTIONS] = {
#define OFFSET(param) offsetof(AC3EncodeContext, options.param)
#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
-static const AVOption options[] = {
+#if CONFIG_AC3ENC_FLOAT || !CONFIG_AC3_FLOAT_ENCODER //we need this exactly once compiled in
+const AVOption ff_ac3_options[] = {
/* Metadata Options */
{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), FF_OPT_TYPE_INT, 0, 0, 1, AC3ENC_PARAM},
/* downmix levels */
@@ -271,13 +242,14 @@ static const AVOption options[] = {
{"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
{NULL}
};
+#endif
#if CONFIG_AC3ENC_FLOAT
static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
- options, LIBAVUTIL_VERSION_INT };
+ ff_ac3_options, LIBAVUTIL_VERSION_INT };
#else
static AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name,
- options, LIBAVUTIL_VERSION_INT };
+ ff_ac3_options, LIBAVUTIL_VERSION_INT };
#endif
@@ -306,7 +278,8 @@ static uint8_t exponent_group_tab[3][256];
/**
* List of supported channel layouts.
*/
-static const int64_t ac3_channel_layouts[] = {
+#if CONFIG_AC3ENC_FLOAT || !CONFIG_AC3_FLOAT_ENCODER //we need this exactly once compiled in
+const int64_t ff_ac3_channel_layouts[] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_2_1,
@@ -327,6 +300,7 @@ static const int64_t ac3_channel_layouts[] = {
AV_CH_LAYOUT_5POINT1_BACK,
0
};
+#endif
/**
diff --git a/libavcodec/ac3enc_combined.c b/libavcodec/ac3enc_combined.c
new file mode 100644
index 0000000000..3d6b3d9335
--- /dev/null
+++ b/libavcodec/ac3enc_combined.c
@@ -0,0 +1,90 @@
+
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+#include "avcodec.h"
+#include "ac3.h"
+
+typedef struct CombineContext{
+ AVClass *av_class; ///< AVClass used for AVOption
+ AC3EncOptions options; ///< encoding options
+ void *ctx;
+ AVCodec *codec;
+}CombineContext;
+
+static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
+ ff_ac3_options, LIBAVUTIL_VERSION_INT };
+
+static av_cold AVCodec *get_codec(enum AVSampleFormat s){
+#if CONFIG_AC3_FIXED_ENCODER
+ if(s==AV_SAMPLE_FMT_S16) return &ff_ac3_fixed_encoder;
+#endif
+#if CONFIG_AC3_FLOAT_ENCODER
+ if(s==AV_SAMPLE_FMT_FLT) return &ff_ac3_float_encoder;
+#endif
+ return NULL;
+}
+
+
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+ CombineContext *c= avctx->priv_data;
+ int ret;
+ int offset= (uint8_t*)&c->options - (uint8_t*)c;
+
+ c->codec= get_codec(avctx->sample_fmt);
+ if(!c->codec){
+ av_log(avctx, AV_LOG_ERROR, "Unsupported sample format\n");
+ return -1;
+ }
+ c->ctx= av_mallocz(c->codec->priv_data_size);
+ memcpy((uint8_t*)c->ctx + offset, &c->options, (uint8_t*)&c->ctx - (uint8_t*)&c->options);
+ FFSWAP(void *,avctx->priv_data, c->ctx);
+ ret= c->codec->init(avctx);
+ FFSWAP(void *,avctx->priv_data, c->ctx);
+ return ret;
+}
+
+static int encode_frame(AVCodecContext *avctx, unsigned char *frame,
+ int buf_size, void *data)
+{
+ CombineContext *c= avctx->priv_data;
+ int ret;
+
+ FFSWAP(void *,avctx->priv_data, c->ctx);
+ ret= c->codec->encode(avctx, frame, buf_size, data);
+ FFSWAP(void *,avctx->priv_data, c->ctx);
+ return ret;
+}
+
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+ CombineContext *c= avctx->priv_data;
+ int ret;
+
+ FFSWAP(void *,avctx->priv_data, c->ctx);
+ ret= c->codec->close(avctx);
+ FFSWAP(void *,avctx->priv_data, c->ctx);
+ return ret;
+}
+
+AVCodec ff_ac3_encoder = {
+ "ac3",
+ AVMEDIA_TYPE_AUDIO,
+ CODEC_ID_AC3,
+ sizeof(CombineContext),
+ encode_init,
+ encode_frame,
+ encode_close,
+ NULL,
+ .sample_fmts = (const enum AVSampleFormat[]){
+#if CONFIG_AC3_FLOAT_ENCODER
+ AV_SAMPLE_FMT_FLT,
+#endif
+#if CONFIG_AC3_FIXED_ENCODER
+ AV_SAMPLE_FMT_S16,
+#endif
+ AV_SAMPLE_FMT_NONE},
+ .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+ .priv_class = &ac3enc_class,
+ .channel_layouts = ff_ac3_channel_layouts,
+};
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index 4d8b756b9b..462e658a8c 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -121,5 +121,5 @@ AVCodec ff_ac3_fixed_encoder = {
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
.priv_class = &ac3enc_class,
- .channel_layouts = ac3_channel_layouts,
+ .channel_layouts = ff_ac3_channel_layouts,
};
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index d89880535e..1a145e5ab2 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -98,8 +98,8 @@ static void scale_coefficients(AC3EncodeContext *s)
}
-AVCodec ff_ac3_encoder = {
- "ac3",
+AVCodec ff_ac3_float_encoder = {
+ "ac3_float",
AVMEDIA_TYPE_AUDIO,
CODEC_ID_AC3,
sizeof(AC3EncodeContext),
@@ -110,5 +110,5 @@ AVCodec ff_ac3_encoder = {
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
.priv_class = &ac3enc_class,
- .channel_layouts = ac3_channel_layouts,
+ .channel_layouts = ff_ac3_channel_layouts,
};
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 8f53e257b4..56fa6280a2 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -234,7 +234,8 @@ void avcodec_register_all(void)
REGISTER_ENCDEC (AAC, aac);
REGISTER_DECODER (AAC_LATM, aac_latm);
REGISTER_ENCDEC (AC3, ac3);
- REGISTER_ENCODER (AC3_FIXED, ac3_fixed);
+ REGISTER_ENCODER (AC3_FIXED, ac3_fixed); //deprecated, just for libav compatibility
+// REGISTER_ENCODER (AC3_FLOAT, ac3_float); dont remove dont outcomment, for configure
REGISTER_ENCDEC (ALAC, alac);
REGISTER_DECODER (ALS, als);
REGISTER_DECODER (AMRNB, amrnb);