You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	Convert floating-point MDCT coefficients to 24-bit fixed-point all at once
instead of doing it separately in 2 different functions. This makes float AC-3 encoding approx. 3-7% faster overall. Also, the coefficient conversion can now be easily SIMD-optimized. Originally committed as revision 26232 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		| @@ -62,6 +62,7 @@ | ||||
| typedef struct AC3Block { | ||||
|     uint8_t  **bap;                             ///< bit allocation pointers (bap) | ||||
|     CoefType **mdct_coef;                       ///< MDCT coefficients | ||||
|     int32_t  **fixed_coef;                      ///< fixed-point MDCT coefficients | ||||
|     uint8_t  **exp;                             ///< original exponents | ||||
|     uint8_t  **grouped_exp;                     ///< grouped exponents | ||||
|     int16_t  **psd;                             ///< psd per frequency bin | ||||
| @@ -128,6 +129,7 @@ typedef struct AC3EncodeContext { | ||||
|     uint8_t *bap_buffer; | ||||
|     uint8_t *bap1_buffer; | ||||
|     CoefType *mdct_coef_buffer; | ||||
|     int32_t *fixed_coef_buffer; | ||||
|     uint8_t *exp_buffer; | ||||
|     uint8_t *grouped_exp_buffer; | ||||
|     int16_t *psd_buffer; | ||||
| @@ -153,6 +155,8 @@ static void apply_window(SampleType *output, const SampleType *input, | ||||
|  | ||||
| static int normalize_samples(AC3EncodeContext *s); | ||||
|  | ||||
| static void scale_coefficients(AC3EncodeContext *s); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * LUT for number of exponent groups. | ||||
| @@ -286,11 +290,11 @@ static void extract_exponents(AC3EncodeContext *s) | ||||
|         for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||||
|             AC3Block *block = &s->blocks[blk]; | ||||
|             uint8_t *exp   = block->exp[ch]; | ||||
|             CoefType *coef = block->mdct_coef[ch]; | ||||
|             int32_t *coef = block->fixed_coef[ch]; | ||||
|             int exp_shift  = block->exp_shift[ch]; | ||||
|             for (i = 0; i < AC3_MAX_COEFS; i++) { | ||||
|                 int e; | ||||
|                 int v = abs(SCALE_COEF(coef[i])); | ||||
|                 int v = abs(coef[i]); | ||||
|                 if (v == 0) | ||||
|                     e = 24; | ||||
|                 else { | ||||
| @@ -1017,7 +1021,7 @@ static inline int asym_quant(int c, int e, int qbits) | ||||
| /** | ||||
|  * Quantize a set of mantissas for a single channel in a single block. | ||||
|  */ | ||||
| static void quantize_mantissas_blk_ch(AC3EncodeContext *s, CoefType *mdct_coef, | ||||
| static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef, | ||||
|                                       int8_t exp_shift, uint8_t *exp, | ||||
|                                       uint8_t *bap, uint16_t *qmant, int n) | ||||
| { | ||||
| @@ -1025,7 +1029,7 @@ static void quantize_mantissas_blk_ch(AC3EncodeContext *s, CoefType *mdct_coef, | ||||
|  | ||||
|     for (i = 0; i < n; i++) { | ||||
|         int v; | ||||
|         int c = SCALE_COEF(mdct_coef[i]); | ||||
|         int c = fixed_coef[i]; | ||||
|         int e = exp[i] - exp_shift; | ||||
|         int b = bap[i]; | ||||
|         switch (b) { | ||||
| @@ -1122,7 +1126,7 @@ static void quantize_mantissas(AC3EncodeContext *s) | ||||
|         s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL; | ||||
|  | ||||
|         for (ch = 0; ch < s->channels; ch++) { | ||||
|             quantize_mantissas_blk_ch(s, block->mdct_coef[ch], block->exp_shift[ch], | ||||
|             quantize_mantissas_blk_ch(s, block->fixed_coef[ch], block->exp_shift[ch], | ||||
|                                       block->exp[ch], block->bap[ch], | ||||
|                                       block->qmant[ch], s->nb_coefs[ch]); | ||||
|         } | ||||
| @@ -1390,6 +1394,8 @@ static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame, | ||||
|  | ||||
|     apply_mdct(s); | ||||
|  | ||||
|     scale_coefficients(s); | ||||
|  | ||||
|     process_exponents(s); | ||||
|  | ||||
|     ret = compute_bit_allocation(s); | ||||
| @@ -1420,6 +1426,7 @@ static av_cold int ac3_encode_close(AVCodecContext *avctx) | ||||
|     av_freep(&s->bap_buffer); | ||||
|     av_freep(&s->bap1_buffer); | ||||
|     av_freep(&s->mdct_coef_buffer); | ||||
|     av_freep(&s->fixed_coef_buffer); | ||||
|     av_freep(&s->exp_buffer); | ||||
|     av_freep(&s->grouped_exp_buffer); | ||||
|     av_freep(&s->psd_buffer); | ||||
| @@ -1430,6 +1437,7 @@ static av_cold int ac3_encode_close(AVCodecContext *avctx) | ||||
|         AC3Block *block = &s->blocks[blk]; | ||||
|         av_freep(&block->bap); | ||||
|         av_freep(&block->mdct_coef); | ||||
|         av_freep(&block->fixed_coef); | ||||
|         av_freep(&block->exp); | ||||
|         av_freep(&block->grouped_exp); | ||||
|         av_freep(&block->psd); | ||||
| @@ -1639,6 +1647,26 @@ static av_cold int allocate_buffers(AVCodecContext *avctx) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (CONFIG_AC3ENC_FLOAT) { | ||||
|         FF_ALLOC_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * s->channels * | ||||
|                          AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail); | ||||
|         for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||||
|             AC3Block *block = &s->blocks[blk]; | ||||
|             FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * | ||||
|                               sizeof(*block->fixed_coef), alloc_fail); | ||||
|             for (ch = 0; ch < s->channels; ch++) | ||||
|                 block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; | ||||
|         } | ||||
|     } else { | ||||
|         for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | ||||
|             AC3Block *block = &s->blocks[blk]; | ||||
|             FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * | ||||
|                               sizeof(*block->fixed_coef), alloc_fail); | ||||
|             for (ch = 0; ch < s->channels; ch++) | ||||
|                 block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| alloc_fail: | ||||
|     return AVERROR(ENOMEM); | ||||
|   | ||||
| @@ -319,6 +319,17 @@ static int normalize_samples(AC3EncodeContext *s) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Scale MDCT coefficients from float to fixed-point. | ||||
|  */ | ||||
| static void scale_coefficients(AC3EncodeContext *s) | ||||
| { | ||||
|     /* scaling/conversion is obviously not needed for the fixed-point encoder | ||||
|        since the coefficients are already fixed-point. */ | ||||
|     return; | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef TEST | ||||
| /*************************************************************************/ | ||||
| /* TEST */ | ||||
|   | ||||
| @@ -35,8 +35,6 @@ | ||||
| typedef int16_t SampleType; | ||||
| typedef int32_t CoefType; | ||||
|  | ||||
| #define SCALE_COEF(a) (a) | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Compex number. | ||||
|   | ||||
| @@ -102,6 +102,17 @@ static int normalize_samples(AC3EncodeContext *s) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Scale MDCT coefficients from float to 24-bit fixed-point. | ||||
|  */ | ||||
| static void scale_coefficients(AC3EncodeContext *s) | ||||
| { | ||||
|     int i; | ||||
|     for (i = 0; i < AC3_MAX_COEFS * AC3_MAX_BLOCKS * s->channels; i++) | ||||
|         s->fixed_coef_buffer[i] = SCALE_FLOAT(s->mdct_coef_buffer[i], 24); | ||||
| } | ||||
|  | ||||
|  | ||||
| AVCodec ac3_encoder = { | ||||
|     "ac3", | ||||
|     AVMEDIA_TYPE_AUDIO, | ||||
|   | ||||
| @@ -35,8 +35,6 @@ | ||||
| typedef float SampleType; | ||||
| typedef float CoefType; | ||||
|  | ||||
| #define SCALE_COEF(a) SCALE_FLOAT((a), 24) | ||||
|  | ||||
|  | ||||
| typedef struct AC3MDCTContext { | ||||
|     const float *window;    ///< MDCT window function | ||||
|   | ||||
		Reference in New Issue
	
	Block a user