diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2008-11-13 03:18:07 +0000 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2008-11-13 03:18:07 +0000 |
commit | 0c5d750df9d0293b2ce27b6821c3209952c4e6b8 (patch) | |
tree | 4592966be28f73400c1c9b47c2801feea58444d7 /libavcodec/ac3dec.c | |
parent | 6c6f9272891d17be3e082e34ae60b33c0b31f1e3 (diff) | |
download | ffmpeg-0c5d750df9d0293b2ce27b6821c3209952c4e6b8.tar.gz |
add a generic function to decode banding structure for coupling, spectral
extension, or enhanced coupling
Originally committed as revision 15811 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/ac3dec.c')
-rw-r--r-- | libavcodec/ac3dec.c | 84 |
1 files changed, 67 insertions, 17 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 4cb1154f27..3e8b0b5afc 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -711,6 +711,68 @@ static void ac3_upmix_delay(AC3DecodeContext *s) } /** + * Decode band structure for coupling, spectral extension, or enhanced coupling. + * @param[in] gbc bit reader context + * @param[in] blk block number + * @param[in] eac3 flag to indicate E-AC-3 + * @param[in] ecpl flag to indicate enhanced coupling + * @param[in] start_subband subband number for start of range + * @param[in] end_subband subband number for end of range + * @param[in] default_band_struct default band structure table + * @param[out] band_struct decoded band structure + * @param[out] num_subbands number of subbands (optionally NULL) + * @param[out] num_bands number of bands (optionally NULL) + * @param[out] band_sizes array containing the number of bins in each band (optionally NULL) + */ +static void decode_band_structure(GetBitContext *gbc, int blk, int eac3, + int ecpl, int start_subband, int end_subband, + const uint8_t *default_band_struct, + uint8_t *band_struct, int *num_subbands, + int *num_bands, int *band_sizes) +{ + int subbnd, bnd, n_subbands, n_bands, bnd_sz[22]; + + n_subbands = end_subband - start_subband; + + /* decode band structure from bitstream or use default */ + if (!eac3 || get_bits1(gbc)) { + for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) { + band_struct[subbnd] = get_bits1(gbc); + } + } else if (!blk) { + memcpy(band_struct, + &default_band_struct[start_subband+1], + n_subbands-1); + } + band_struct[n_subbands-1] = 0; + + /* calculate number of bands and band sizes based on band structure. + note that the first 4 subbands in enhanced coupling span only 6 bins + instead of 12. */ + if (num_bands || band_sizes ) { + n_bands = n_subbands; + bnd_sz[0] = ecpl ? 6 : 12; + for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) { + int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12; + if (band_struct[subbnd-1]) { + n_bands--; + bnd_sz[bnd] += subbnd_size; + } else { + bnd_sz[++bnd] = subbnd_size; + } + } + } + + /* set optional output params */ + if (num_subbands) + *num_subbands = n_subbands; + if (num_bands) + *num_bands = n_bands; + if (band_sizes) + memcpy(band_sizes, bnd_sz, sizeof(int)*n_bands); +} + +/** * Decode a single audio block from the AC-3 bitstream. */ static int decode_audio_block(AC3DecodeContext *s, int blk) @@ -812,23 +874,11 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; - /* coupling band structure */ - s->num_cpl_bands = s->num_cpl_subbands; - if (!s->eac3 || get_bits1(gbc)) { - for (bnd = 0; bnd < s->num_cpl_subbands - 1; bnd++) { - s->cpl_band_struct[bnd] = get_bits1(gbc); - } - } else if (!blk) { - memcpy(s->cpl_band_struct, - &ff_eac3_default_cpl_band_struct[cpl_start_subband+1], - s->num_cpl_subbands-1); - } - s->cpl_band_struct[s->num_cpl_subbands-1] = 0; - - /* calculate number of coupling bands based on band structure */ - for (bnd = 0; bnd < s->num_cpl_subbands-1; bnd++) { - s->num_cpl_bands -= s->cpl_band_struct[bnd]; - } + decode_band_structure(gbc, blk, s->eac3, 0, + cpl_start_subband, cpl_end_subband, + ff_eac3_default_cpl_band_struct, + s->cpl_band_struct, &s->num_cpl_subbands, + &s->num_cpl_bands, NULL); } else { /* coupling not in use */ for (ch = 1; ch <= fbw_channels; ch++) { |