diff options
author | Alex Converse <alex.converse@gmail.com> | 2008-10-06 16:12:30 +0000 |
---|---|---|
committer | Robert Swain <robert.swain@gmail.com> | 2008-10-06 16:12:30 +0000 |
commit | 88de95c2f9e4a6e08149e1ce731a5ce7db01a8e8 (patch) | |
tree | 89048bd75545b244d28f5848c54855e72b1b4f8e /libavcodec/aac.c | |
parent | 69bf69c77eb801d50dcbf8031c3c0f3feadb2a4c (diff) | |
download | ffmpeg-streaming-88de95c2f9e4a6e08149e1ce731a5ce7db01a8e8.zip ffmpeg-streaming-88de95c2f9e4a6e08149e1ce731a5ce7db01a8e8.tar.gz |
Corrections to channel coupling code to attain conformance for appropriate
streams.
Slightly reworked from a patch by Alex Converse (alex converse gmail com)
Originally committed as revision 15573 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/aac.c')
-rw-r--r-- | libavcodec/aac.c | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/libavcodec/aac.c b/libavcodec/aac.c index eca6a9a..dbf39b4 100644 --- a/libavcodec/aac.c +++ b/libavcodec/aac.c @@ -967,7 +967,7 @@ static int decode_cce(AACContext * ac, GetBitContext * gb, ChannelElement * che) if (coup->ch_select[c] == 3) num_gain++; } else - coup->ch_select[c] = 1; + coup->ch_select[c] = 2; } coup->coupling_point += get_bits1(gb); @@ -992,7 +992,7 @@ static int decode_cce(AACContext * ac, GetBitContext * gb, ChannelElement * che) if (c) { cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb); gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0; - gain_cache = pow(scale, gain); + gain_cache = pow(scale, -gain); } for (g = 0; g < sce->ics.num_window_groups; g++) { for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) { @@ -1001,12 +1001,12 @@ static int decode_cce(AACContext * ac, GetBitContext * gb, ChannelElement * che) int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; if (t) { int s = 1; + t = gain += t; if (sign) { s -= 2 * (t & 0x1); t >>= 1; } - gain += t; - gain_cache = pow(scale, gain) * s; + gain_cache = pow(scale, -t) * s; } } coup->gain[c][idx] = gain_cache; @@ -1292,25 +1292,30 @@ static void apply_independent_coupling(AACContext * ac, SingleChannelElement * s * @param apply_coupling_method pointer to (in)dependent coupling function */ static void apply_channel_coupling(AACContext * ac, ChannelElement * cc, + enum RawDataBlockType type, int elem_id, enum CouplingPoint coupling_point, void (*apply_coupling_method)(AACContext * ac, SingleChannelElement * sce, ChannelElement * cc, int index)) { - int c; - int index = 0; - ChannelCoupling * coup = &cc->coup; - for (c = 0; c <= coup->num_coupled; c++) { - if (ac->che[coup->type[c]][coup->id_select[c]]) { - if (coup->ch_select[c] != 2) { - apply_coupling_method(ac, &ac->che[coup->type[c]][coup->id_select[c]]->ch[0], cc, index); - if (coup->ch_select[c] != 0) - index++; + int i, c; + + for (i = 0; i < MAX_ELEM_ID; i++) { + ChannelElement *cce = ac->che[TYPE_CCE][i]; + int index = 0; + + if (cce && cce->coup.coupling_point == coupling_point) { + ChannelCoupling * coup = &cce->coup; + + for (c = 0; c <= coup->num_coupled; c++) { + if (coup->type[c] == type && coup->id_select[c] == elem_id) { + if (coup->ch_select[c] != 1) { + apply_coupling_method(ac, &cc->ch[0], cce, index); + if (coup->ch_select[c] != 0) + index++; + } + if (coup->ch_select[c] != 2) + apply_coupling_method(ac, &cc->ch[1], cce, index++); + } else + index += 1 + (coup->ch_select[c] == 3); } - if (coup->ch_select[c] != 1) - apply_coupling_method(ac, &ac->che[coup->type[c]][coup->id_select[c]]->ch[1], cc, index++); - } else { - av_log(ac->avccontext, AV_LOG_ERROR, - "coupling target %sE[%d] not available\n", - coup->type[c] == TYPE_CPE ? "CP" : "SC", coup->id_select[c]); - break; } } } @@ -1320,23 +1325,24 @@ static void apply_channel_coupling(AACContext * ac, ChannelElement * cc, */ static void spectral_to_sample(AACContext * ac) { int i, type; - for (i = 0; i < MAX_ELEM_ID; i++) { - for(type = 0; type < 4; type++) { + for(type = 3; type >= 0; type--) { + for (i = 0; i < MAX_ELEM_ID; i++) { ChannelElement *che = ac->che[type][i]; if(che) { - if(che->coup.coupling_point == BEFORE_TNS) - apply_channel_coupling(ac, che, apply_dependent_coupling); + if(type <= TYPE_CPE) + apply_channel_coupling(ac, che, type, i, BEFORE_TNS, apply_dependent_coupling); if(che->ch[0].tns.present) apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1); if(che->ch[1].tns.present) apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1); - if(che->coup.coupling_point == BETWEEN_TNS_AND_IMDCT) - apply_channel_coupling(ac, che, apply_dependent_coupling); - imdct_and_windowing(ac, &che->ch[0]); + if(type <= TYPE_CPE) + apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, apply_dependent_coupling); + if(type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) + imdct_and_windowing(ac, &che->ch[0]); if(type == TYPE_CPE) imdct_and_windowing(ac, &che->ch[1]); - if(che->coup.coupling_point == AFTER_IMDCT) - apply_channel_coupling(ac, che, apply_independent_coupling); + if(type <= TYPE_CCE) + apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, apply_independent_coupling); } } } |