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 @@ -75,36 +75,6 @@ typedef struct AC3MDCTContext { FFTContext fft; ///< FFT context for MDCT calculation } 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. */ @@ -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);