mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
bdf3d3bf9d
commit
1aeb88b77d
@ -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
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
90
libavcodec/ac3enc_combined.c
Normal file
90
libavcodec/ac3enc_combined.c
Normal file
@ -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 = {
|
AVCodec ff_ac3_float_encoder = {
|
||||||
"ac3",
|
"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);
|
||||||
|
Loading…
Reference in New Issue
Block a user