|
|
|
@ -33,6 +33,7 @@ |
|
|
|
|
#include "ac3.h" |
|
|
|
|
#include "audioconvert.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define MDCT_NBITS 9 |
|
|
|
|
#define MDCT_SAMPLES (1 << MDCT_NBITS) |
|
|
|
|
|
|
|
|
@ -40,6 +41,7 @@ |
|
|
|
|
|
|
|
|
|
#define FIX15(a) av_clip_int16(SCALE_FLOAT(a, 15)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct IComplex { |
|
|
|
|
int16_t re,im; |
|
|
|
|
} IComplex; |
|
|
|
@ -86,11 +88,13 @@ typedef struct AC3EncodeContext { |
|
|
|
|
int16_t last_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< last 256 samples from previous frame
|
|
|
|
|
} AC3EncodeContext; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int16_t costab[64]; |
|
|
|
|
static int16_t sintab[64]; |
|
|
|
|
static int16_t xcos1[128]; |
|
|
|
|
static int16_t xsin1[128]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static av_cold void fft_init(int ln) |
|
|
|
|
{ |
|
|
|
|
int i, n, n2; |
|
|
|
@ -106,6 +110,7 @@ static av_cold void fft_init(int ln) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static av_cold void mdct_init(int nbits) |
|
|
|
|
{ |
|
|
|
|
int i, n, n4; |
|
|
|
@ -122,6 +127,7 @@ static av_cold void mdct_init(int nbits) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* butter fly op */ |
|
|
|
|
#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \ |
|
|
|
|
{ \
|
|
|
|
@ -136,6 +142,7 @@ static av_cold void mdct_init(int nbits) |
|
|
|
|
qim = (by - ay) >> 1; \
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CMUL(pre, pim, are, aim, bre, bim) \ |
|
|
|
|
{ \
|
|
|
|
|
pre = (MUL16(are, bre) - MUL16(aim, bim)) >> 15; \
|
|
|
|
@ -210,6 +217,7 @@ static void fft(IComplex *z, int ln) |
|
|
|
|
} while (nblocks); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void mdct512(int32_t *out, int16_t *in) |
|
|
|
|
{ |
|
|
|
|
int i, re, im, re1, im1; |
|
|
|
@ -241,6 +249,7 @@ static void mdct512(int32_t *out, int16_t *in) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* compute log2(max(abs(tab[]))) */ |
|
|
|
|
static int log2_tab(int16_t *tab, int n) |
|
|
|
|
{ |
|
|
|
@ -253,6 +262,7 @@ static int log2_tab(int16_t *tab, int n) |
|
|
|
|
return av_log2(v); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void lshift_tab(int16_t *tab, int n, int lshift) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
@ -267,6 +277,7 @@ static void lshift_tab(int16_t *tab, int n, int lshift) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int calc_exp_diff(uint8_t *exp1, uint8_t *exp2, int n) |
|
|
|
|
{ |
|
|
|
|
int sum, i; |
|
|
|
@ -276,9 +287,11 @@ static int calc_exp_diff(uint8_t *exp1, uint8_t *exp2, int n) |
|
|
|
|
return sum; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* new exponents are sent if their Norm 1 exceed this number */ |
|
|
|
|
#define EXP_DIFF_THRESHOLD 1000 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void compute_exp_strategy(uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS], |
|
|
|
|
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS], |
|
|
|
|
int ch, int is_lfe) |
|
|
|
@ -316,6 +329,7 @@ static void compute_exp_strategy(uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CH |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* set exp[i] to min(exp[i], exp1[i]) */ |
|
|
|
|
static void exponent_min(uint8_t exp[AC3_MAX_COEFS], uint8_t exp1[AC3_MAX_COEFS], int n) |
|
|
|
|
{ |
|
|
|
@ -326,6 +340,7 @@ static void exponent_min(uint8_t exp[AC3_MAX_COEFS], uint8_t exp1[AC3_MAX_COEFS] |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* update the exponents so that they are the ones the decoder will
|
|
|
|
|
decode. Return the number of bits used to code the exponents */ |
|
|
|
|
static int encode_exp(uint8_t encoded_exp[AC3_MAX_COEFS], |
|
|
|
@ -375,6 +390,7 @@ static int encode_exp(uint8_t encoded_exp[AC3_MAX_COEFS], |
|
|
|
|
return 4 + (nb_groups / 3) * 7; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* return the size in bits taken by the mantissa */ |
|
|
|
|
static int compute_mantissa_size(AC3EncodeContext *s, uint8_t *m, int nb_coefs) |
|
|
|
|
{ |
|
|
|
@ -455,6 +471,7 @@ static void bit_alloc_masking(AC3EncodeContext *s, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int bit_alloc(AC3EncodeContext *s, |
|
|
|
|
int16_t mask[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][50], |
|
|
|
|
int16_t psd[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS], |
|
|
|
@ -481,6 +498,7 @@ static int bit_alloc(AC3EncodeContext *s, |
|
|
|
|
return 16 * s->frame_size - frame_bits; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define SNR_INC1 4 |
|
|
|
|
|
|
|
|
|
static int compute_bit_allocation(AC3EncodeContext *s, |
|
|
|
@ -597,6 +615,7 @@ static int compute_bit_allocation(AC3EncodeContext *s, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* output the AC-3 frame header */ |
|
|
|
|
static void output_frame_header(AC3EncodeContext *s, unsigned char *frame) |
|
|
|
|
{ |
|
|
|
@ -627,6 +646,7 @@ static void output_frame_header(AC3EncodeContext *s, unsigned char *frame) |
|
|
|
|
put_bits(&s->pb, 1, 0); /* no additional bit stream info */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* symetric quantization on 'levels' levels */ |
|
|
|
|
static inline int sym_quant(int c, int e, int levels) |
|
|
|
|
{ |
|
|
|
@ -645,6 +665,7 @@ static inline int sym_quant(int c, int e, int levels) |
|
|
|
|
return v; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* asymetric quantization on 2^qbits levels */ |
|
|
|
|
static inline int asym_quant(int c, int e, int qbits) |
|
|
|
|
{ |
|
|
|
@ -664,6 +685,7 @@ static inline int asym_quant(int c, int e, int qbits) |
|
|
|
|
return v & ((1 << qbits)-1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Output one audio block. There are AC3_MAX_BLOCKS audio blocks in one AC-3
|
|
|
|
|
frame */ |
|
|
|
|
static void output_audio_block(AC3EncodeContext *s, |
|
|
|
@ -897,8 +919,10 @@ static void output_audio_block(AC3EncodeContext *s, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CRC16_POLY ((1 << 0) | (1 << 2) | (1 << 15) | (1 << 16)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned int mul_poly(unsigned int a, unsigned int b, unsigned int poly) |
|
|
|
|
{ |
|
|
|
|
unsigned int c; |
|
|
|
@ -915,6 +939,7 @@ static unsigned int mul_poly(unsigned int a, unsigned int b, unsigned int poly) |
|
|
|
|
return c; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly) |
|
|
|
|
{ |
|
|
|
|
unsigned int r; |
|
|
|
@ -928,6 +953,7 @@ static unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly) |
|
|
|
|
return r; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* fill the end of the frame and compute the two crcs */ |
|
|
|
|
static int output_frame_end(AC3EncodeContext *s) |
|
|
|
|
{ |
|
|
|
@ -964,6 +990,7 @@ static int output_frame_end(AC3EncodeContext *s) |
|
|
|
|
return frame_size * 2; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int AC3_encode_frame(AVCodecContext *avctx, |
|
|
|
|
unsigned char *frame, int buf_size, void *data) |
|
|
|
|
{ |
|
|
|
@ -1077,12 +1104,14 @@ static int AC3_encode_frame(AVCodecContext *avctx, |
|
|
|
|
return output_frame_end(s); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static av_cold int AC3_encode_close(AVCodecContext *avctx) |
|
|
|
|
{ |
|
|
|
|
av_freep(&avctx->coded_frame); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static av_cold int set_channel_info(AC3EncodeContext *s, int channels, |
|
|
|
|
int64_t *channel_layout) |
|
|
|
|
{ |
|
|
|
@ -1127,6 +1156,7 @@ static av_cold int set_channel_info(AC3EncodeContext *s, int channels, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static av_cold int AC3_encode_init(AVCodecContext *avctx) |
|
|
|
|
{ |
|
|
|
|
int freq = avctx->sample_rate; |
|
|
|
@ -1208,6 +1238,7 @@ static av_cold int AC3_encode_init(AVCodecContext *avctx) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef TEST |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/* TEST */ |
|
|
|
@ -1216,6 +1247,7 @@ static av_cold int AC3_encode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
|
|
#define FN (MDCT_SAMPLES/4) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void fft_test(AVLFG *lfg) |
|
|
|
|
{ |
|
|
|
|
IComplex in[FN], in1[FN]; |
|
|
|
@ -1243,6 +1275,7 @@ static void fft_test(AVLFG *lfg) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void mdct_test(AVLFG *lfg) |
|
|
|
|
{ |
|
|
|
|
int16_t input[MDCT_SAMPLES]; |
|
|
|
@ -1281,6 +1314,7 @@ static void mdct_test(AVLFG *lfg) |
|
|
|
|
av_log(NULL, AV_LOG_DEBUG, "err2=%f emax=%f\n", err / AC3_MAX_COEFS, emax); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(void) |
|
|
|
|
{ |
|
|
|
|
AVLFG lfg; |
|
|
|
@ -1295,6 +1329,7 @@ int main(void) |
|
|
|
|
} |
|
|
|
|
#endif /* TEST */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AVCodec ac3_encoder = { |
|
|
|
|
"ac3", |
|
|
|
|
AVMEDIA_TYPE_AUDIO, |
|
|
|
|