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>tags/n0.8
@@ -59,7 +59,8 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \ | |||||
mpeg4audio.o kbdwin.o | mpeg4audio.o kbdwin.o | ||||
OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.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_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_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3tab.o ac3.o | ||||
OBJS-$(CONFIG_ALAC_DECODER) += alac.o | OBJS-$(CONFIG_ALAC_DECODER) += alac.o | ||||
OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o | OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o | ||||
@@ -38,6 +38,8 @@ | |||||
#define AC3_CRITICAL_BANDS 50 | #define AC3_CRITICAL_BANDS 50 | ||||
#define AC3_MAX_CPL_BANDS 18 | #define AC3_MAX_CPL_BANDS 18 | ||||
#include "libavutil/opt.h" | |||||
#include "avcodec.h" | |||||
#include "ac3tab.h" | #include "ac3tab.h" | ||||
/* exponent encoding strategy */ | /* exponent encoding strategy */ | ||||
@@ -128,8 +130,45 @@ typedef enum { | |||||
EAC3_FRAME_TYPE_RESERVED | EAC3_FRAME_TYPE_RESERVED | ||||
} EAC3FrameType; | } 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); | 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. | * Calculate the log power-spectral density of the input signal. | ||||
* This gives a rough estimate of signal power in the frequency domain by using | * This gives a rough estimate of signal power in the frequency domain by using | ||||
@@ -75,36 +75,6 @@ typedef struct AC3MDCTContext { | |||||
FFTContext fft; ///< FFT context for MDCT calculation | FFTContext fft; ///< FFT context for MDCT calculation | ||||
} 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. | * Data for a single audio block. | ||||
*/ | */ | ||||
@@ -229,7 +199,8 @@ static const float extmixlev_options[EXTMIXLEV_NUM_OPTIONS] = { | |||||
#define OFFSET(param) offsetof(AC3EncodeContext, options.param) | #define OFFSET(param) offsetof(AC3EncodeContext, options.param) | ||||
#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_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 */ | /* Metadata Options */ | ||||
{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), FF_OPT_TYPE_INT, 0, 0, 1, AC3ENC_PARAM}, | {"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), FF_OPT_TYPE_INT, 0, 0, 1, AC3ENC_PARAM}, | ||||
/* downmix levels */ | /* 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"}, | {"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, | ||||
{NULL} | {NULL} | ||||
}; | }; | ||||
#endif | |||||
#if CONFIG_AC3ENC_FLOAT | #if CONFIG_AC3ENC_FLOAT | ||||
static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, | static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, | ||||
options, LIBAVUTIL_VERSION_INT }; | |||||
ff_ac3_options, LIBAVUTIL_VERSION_INT }; | |||||
#else | #else | ||||
static AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name, | static AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name, | ||||
options, LIBAVUTIL_VERSION_INT }; | |||||
ff_ac3_options, LIBAVUTIL_VERSION_INT }; | |||||
#endif | #endif | ||||
@@ -306,7 +278,8 @@ static uint8_t exponent_group_tab[3][256]; | |||||
/** | /** | ||||
* List of supported channel layouts. | * 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_MONO, | ||||
AV_CH_LAYOUT_STEREO, | AV_CH_LAYOUT_STEREO, | ||||
AV_CH_LAYOUT_2_1, | AV_CH_LAYOUT_2_1, | ||||
@@ -327,6 +300,7 @@ static const int64_t ac3_channel_layouts[] = { | |||||
AV_CH_LAYOUT_5POINT1_BACK, | AV_CH_LAYOUT_5POINT1_BACK, | ||||
0 | 0 | ||||
}; | }; | ||||
#endif | |||||
/** | /** | ||||
@@ -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, | |||||
}; |
@@ -121,5 +121,5 @@ AVCodec ff_ac3_fixed_encoder = { | |||||
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, | .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, | ||||
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), | .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), | ||||
.priv_class = &ac3enc_class, | .priv_class = &ac3enc_class, | ||||
.channel_layouts = ac3_channel_layouts, | |||||
.channel_layouts = ff_ac3_channel_layouts, | |||||
}; | }; |
@@ -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, | AVMEDIA_TYPE_AUDIO, | ||||
CODEC_ID_AC3, | CODEC_ID_AC3, | ||||
sizeof(AC3EncodeContext), | sizeof(AC3EncodeContext), | ||||
@@ -110,5 +110,5 @@ AVCodec ff_ac3_encoder = { | |||||
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE}, | .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE}, | ||||
.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), | .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), | ||||
.priv_class = &ac3enc_class, | .priv_class = &ac3enc_class, | ||||
.channel_layouts = ac3_channel_layouts, | |||||
.channel_layouts = ff_ac3_channel_layouts, | |||||
}; | }; |
@@ -234,7 +234,8 @@ void avcodec_register_all(void) | |||||
REGISTER_ENCDEC (AAC, aac); | REGISTER_ENCDEC (AAC, aac); | ||||
REGISTER_DECODER (AAC_LATM, aac_latm); | REGISTER_DECODER (AAC_LATM, aac_latm); | ||||
REGISTER_ENCDEC (AC3, ac3); | 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_ENCDEC (ALAC, alac); | ||||
REGISTER_DECODER (ALS, als); | REGISTER_DECODER (ALS, als); | ||||
REGISTER_DECODER (AMRNB, amrnb); | REGISTER_DECODER (AMRNB, amrnb); | ||||