You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	ac3enc: Add channel coupling support for the fixed-point AC-3 encoder.
Update FATE references accordingly.
This commit is contained in:
		| @@ -2167,7 +2167,7 @@ static av_cold int validate_options(AC3EncodeContext *s) | ||||
|                              (s->channel_mode == AC3_CHMODE_STEREO); | ||||
|  | ||||
|     s->cpl_enabled = s->options.channel_coupling && | ||||
|                      s->channel_mode >= AC3_CHMODE_STEREO && !s->fixed_point; | ||||
|                      s->channel_mode >= AC3_CHMODE_STEREO; | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -52,6 +52,7 @@ | ||||
| #define MAC_COEF(d,a,b) ((d)+=(a)*(b)) | ||||
| #define COEF_MIN (-16777215.0/16777216.0) | ||||
| #define COEF_MAX ( 16777215.0/16777216.0) | ||||
| #define NEW_CPL_COORD_THRESHOLD 0.03 | ||||
| typedef float SampleType; | ||||
| typedef float CoefType; | ||||
| typedef float CoefSumType; | ||||
| @@ -60,6 +61,7 @@ typedef float CoefSumType; | ||||
| #define MAC_COEF(d,a,b) MAC64(d,a,b) | ||||
| #define COEF_MIN -16777215 | ||||
| #define COEF_MAX  16777215 | ||||
| #define NEW_CPL_COORD_THRESHOLD 503317 | ||||
| typedef int16_t SampleType; | ||||
| typedef int32_t CoefType; | ||||
| typedef int64_t CoefSumType; | ||||
|   | ||||
| @@ -29,6 +29,7 @@ | ||||
| #define CONFIG_FFT_FLOAT 0 | ||||
| #undef CONFIG_AC3ENC_FLOAT | ||||
| #include "ac3enc.h" | ||||
| #include "eac3enc.h" | ||||
|  | ||||
| #define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED | ||||
| #include "ac3enc_opts_template.c" | ||||
| @@ -112,6 +113,22 @@ static void clip_coefficients(DSPContext *dsp, int32_t *coef, unsigned int len) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Calculate a single coupling coordinate. | ||||
|  */ | ||||
| static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) | ||||
| { | ||||
|     if (energy_cpl <= COEF_MAX) { | ||||
|         return 1048576; | ||||
|     } else { | ||||
|         uint64_t coord   = energy_ch / (energy_cpl >> 24); | ||||
|         uint32_t coord32 = FFMIN(coord, 1073741824); | ||||
|         coord32          = ff_sqrt(coord32) << 9; | ||||
|         return FFMIN(coord32, COEF_MAX); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) | ||||
| { | ||||
|     AC3EncodeContext *s = avctx->priv_data; | ||||
|   | ||||
| @@ -120,6 +120,18 @@ static void clip_coefficients(DSPContext *dsp, float *coef, unsigned int len) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Calculate a single coupling coordinate. | ||||
|  */ | ||||
| static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) | ||||
| { | ||||
|     float coord = 0.125; | ||||
|     if (energy_cpl > 0) | ||||
|         coord *= sqrtf(energy_ch / energy_cpl); | ||||
|     return FFMIN(coord, COEF_MAX); | ||||
| } | ||||
|  | ||||
|  | ||||
| #if CONFIG_AC3_ENCODER | ||||
| AVCodec ff_ac3_encoder = { | ||||
|     .name           = "ac3", | ||||
|   | ||||
| @@ -72,11 +72,9 @@ static const AVOption eac3_options[] = { | ||||
|     {"hdcd",     "HDCD",               0, FF_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_ADCONV_HDCD     }, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"}, | ||||
| /* Other Encoding Options */ | ||||
| {"stereo_rematrixing", "Stereo Rematrixing", OFFSET(stereo_rematrixing), FF_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_ON }, AC3ENC_OPT_OFF, AC3ENC_OPT_ON, AC3ENC_PARAM}, | ||||
| #if AC3ENC_TYPE != AC3ENC_TYPE_AC3_FIXED | ||||
| {"channel_coupling",   "Channel Coupling",   OFFSET(channel_coupling),   FF_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, AC3ENC_OPT_ON, AC3ENC_PARAM, "channel_coupling"}, | ||||
|     {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "channel_coupling"}, | ||||
| {"cpl_start_band", "Coupling Start Band", OFFSET(cpl_start), FF_OPT_TYPE_INT, {.dbl = AC3ENC_OPT_AUTO }, AC3ENC_OPT_AUTO, 15, AC3ENC_PARAM, "cpl_start_band"}, | ||||
|     {"auto", "Selected by the Encoder", 0, FF_OPT_TYPE_CONST, {.dbl = AC3ENC_OPT_AUTO }, INT_MIN, INT_MAX, AC3ENC_PARAM, "cpl_start_band"}, | ||||
| #endif | ||||
| {NULL} | ||||
| }; | ||||
|   | ||||
| @@ -41,6 +41,8 @@ static int normalize_samples(AC3EncodeContext *s); | ||||
|  | ||||
| static void clip_coefficients(DSPContext *dsp, CoefType *coef, unsigned int len); | ||||
|  | ||||
| static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl); | ||||
|  | ||||
|  | ||||
| int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) | ||||
| { | ||||
| @@ -118,32 +120,25 @@ static void apply_mdct(AC3EncodeContext *s) | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Calculate a single coupling coordinate. | ||||
|  */ | ||||
| static inline float calc_cpl_coord(float energy_ch, float energy_cpl) | ||||
| { | ||||
|     float coord = 0.125; | ||||
|     if (energy_cpl > 0) | ||||
|         coord *= sqrtf(energy_ch / energy_cpl); | ||||
|     return FFMIN(coord, COEF_MAX); | ||||
| } | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Calculate coupling channel and coupling coordinates. | ||||
|  */ | ||||
| static void apply_channel_coupling(AC3EncodeContext *s) | ||||
| { | ||||
|     LOCAL_ALIGNED_16(CoefType, cpl_coords,      [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); | ||||
| #if CONFIG_AC3ENC_FLOAT | ||||
|     LOCAL_ALIGNED_16(float,   cpl_coords,       [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); | ||||
|     LOCAL_ALIGNED_16(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]); | ||||
| #else | ||||
|     int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords; | ||||
| #endif | ||||
|     int blk, ch, bnd, i, j; | ||||
|     CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}}; | ||||
|     int cpl_start, num_cpl_coefs; | ||||
|  | ||||
|     memset(cpl_coords,       0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); | ||||
|     memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*fixed_cpl_coords)); | ||||
| #if CONFIG_AC3ENC_FLOAT | ||||
|     memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords)); | ||||
| #endif | ||||
|  | ||||
|     /* align start to 16-byte boundary. align length to multiple of 32. | ||||
|         note: coupling start bin % 4 will always be 1 */ | ||||
| @@ -231,11 +226,11 @@ static void apply_channel_coupling(AC3EncodeContext *s) | ||||
|                     } else { | ||||
|                         CoefSumType coord_diff = 0; | ||||
|                         for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { | ||||
|                             coord_diff += fabs(cpl_coords[blk-1][ch][bnd] - | ||||
|                                                cpl_coords[blk  ][ch][bnd]); | ||||
|                             coord_diff += FFABS(cpl_coords[blk-1][ch][bnd] - | ||||
|                                                 cpl_coords[blk  ][ch][bnd]); | ||||
|                         } | ||||
|                         coord_diff /= s->num_cpl_bands; | ||||
|                         if (coord_diff > 0.03) | ||||
|                         if (coord_diff > NEW_CPL_COORD_THRESHOLD) | ||||
|                             block->new_cpl_coords[ch] = 1; | ||||
|                     } | ||||
|                 } | ||||
| @@ -282,9 +277,11 @@ static void apply_channel_coupling(AC3EncodeContext *s) | ||||
|         if (!block->cpl_in_use) | ||||
|             continue; | ||||
|  | ||||
| #if CONFIG_AC3ENC_FLOAT | ||||
|         s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1], | ||||
|                                    cpl_coords[blk][1], | ||||
|                                    s->fbw_channels * 16); | ||||
| #endif | ||||
|         s->ac3dsp.extract_exponents(block->cpl_coord_exp[1], | ||||
|                                     fixed_cpl_coords[blk][1], | ||||
|                                     s->fbw_channels * 16); | ||||
| @@ -328,7 +325,6 @@ static void apply_channel_coupling(AC3EncodeContext *s) | ||||
|  | ||||
|     if (CONFIG_EAC3_ENCODER && s->eac3) | ||||
|         ff_eac3_set_cpl_states(s); | ||||
| #endif /* CONFIG_AC3ENC_FLOAT */ | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,2 +1,2 @@ | ||||
| 0f14801e166819dd4a58981aea36e08b *./tests/data/acodec/ac3.rm | ||||
| e7fa185030a56d9db8663ad9e38c6c94 *./tests/data/acodec/ac3.rm | ||||
| 98751 ./tests/data/acodec/ac3.rm | ||||
|   | ||||
| @@ -5,35 +5,40 @@ ret:-1         st:-1 flags:1  ts: 1.894167 | ||||
| ret:-1         st: 0 flags:0  ts: 0.788000 | ||||
| ret: 0         st: 0 flags:1  ts:-0.317000 | ||||
| ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    271 size:   556 | ||||
| ret: 0         st:-1 flags:0  ts: 2.576668 | ||||
| ret: 0         st: 0 flags:1 dts: 2.577000 pts: 2.577000 pos:  42397 size:   558 | ||||
| ret:-1         st:-1 flags:0  ts: 2.576668 | ||||
| ret:-1         st:-1 flags:1  ts: 1.470835 | ||||
| ret:-1         st: 0 flags:0  ts: 0.365000 | ||||
| ret: 0         st: 0 flags:1  ts:-0.741000 | ||||
| ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    271 size:   556 | ||||
| ret: 0         st:-1 flags:0  ts: 2.153336 | ||||
| ret: 0         st: 0 flags:1 dts: 2.159000 pts: 2.159000 pos:  35567 size:   556 | ||||
| ret:-1         st:-1 flags:0  ts: 2.153336 | ||||
| ret:-1         st:-1 flags:1  ts: 1.047503 | ||||
| ret: 0         st: 0 flags:0  ts:-0.058000 | ||||
| ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    271 size:   556 | ||||
| ret:-1         st: 0 flags:1  ts: 2.836000 | ||||
| ret:-1         st:-1 flags:0  ts: 1.730004 | ||||
| ret:-1         st:-1 flags:1  ts: 0.624171 | ||||
| ret: 0         st:-1 flags:0  ts: 1.730004 | ||||
| ret: 0         st: 0 flags:1 dts:8589.800000 pts:8589.800000 pos:  65950 size: 32801 | ||||
| ret: 0         st:-1 flags:1  ts: 0.624171 | ||||
| ret: 0         st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos:  65337 size:   400 | ||||
| ret: 0         st: 0 flags:0  ts:-0.482000 | ||||
| ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    271 size:   556 | ||||
| ret: 0         st: 0 flags:1  ts: 2.413000 | ||||
| ret: 0         st: 0 flags:1 dts: 2.368000 pts: 2.368000 pos:  38981 size:   558 | ||||
| ret:-1         st:-1 flags:0  ts: 1.306672 | ||||
| ret:-1         st:-1 flags:1  ts: 0.200839 | ||||
| ret:-1         st: 0 flags:1  ts: 2.413000 | ||||
| ret: 0         st:-1 flags:0  ts: 1.306672 | ||||
| ret: 0         st: 0 flags:1 dts:8589.800000 pts:8589.800000 pos:  65950 size: 32801 | ||||
| ret: 0         st:-1 flags:1  ts: 0.200839 | ||||
| ret: 0         st: 0 flags:1 dts: 0.034000 pts: 0.034000 pos:    839 size:   558 | ||||
| ret: 0         st: 0 flags:0  ts:-0.905000 | ||||
| ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    271 size:   556 | ||||
| ret:-1         st: 0 flags:1  ts: 1.989000 | ||||
| ret:-1         st:-1 flags:0  ts: 0.883340 | ||||
| ret: 0         st: 0 flags:1  ts: 1.989000 | ||||
| ret: 0         st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos:  65337 size:   400 | ||||
| ret: 0         st:-1 flags:0  ts: 0.883340 | ||||
| ret: 0         st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos:  55491 size:   558 | ||||
| ret: 0         st:-1 flags:1  ts:-0.222493 | ||||
| ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    271 size:   556 | ||||
| ret: 0         st: 0 flags:0  ts: 2.672000 | ||||
| ret: 0         st: 0 flags:1 dts: 2.821000 pts: 2.821000 pos:  46383 size:   556 | ||||
| ret:-1         st: 0 flags:1  ts: 1.566000 | ||||
| ret:-1         st:-1 flags:0  ts: 0.460008 | ||||
| ret: 0         st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos:  55491 size:   558 | ||||
| ret: 0         st: 0 flags:1  ts: 1.566000 | ||||
| ret: 0         st: 0 flags:1 dts: 0.256000 pts: 0.256000 pos:  65337 size:   400 | ||||
| ret: 0         st:-1 flags:0  ts: 0.460008 | ||||
| ret: 0         st: 0 flags:1 dts: 3.378000 pts: 3.378000 pos:  55491 size:   558 | ||||
| ret: 0         st:-1 flags:1  ts:-0.645825 | ||||
| ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    271 size:   556 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user