+ s->spx_in_use = get_bits1(gbc);
+ if (s->spx_in_use) {
+ int dst_start_freq, dst_end_freq, src_start_freq,
+ start_subband, end_subband;
+
+ /* determine which channels use spx */
+ if (s->channel_mode == AC3_CHMODE_MONO) {
+ s->channel_uses_spx[1] = 1;
+ } else {
+ for (ch = 1; ch <= fbw_channels; ch++)
+ s->channel_uses_spx[ch] = get_bits1(gbc);
+ }
+
+ /* get the frequency bins of the spx copy region and the spx start
+ and end subbands */
+ dst_start_freq = get_bits(gbc, 2);
+ start_subband = get_bits(gbc, 3) + 2;
+ if (start_subband > 7)
+ start_subband += start_subband - 7;
+ end_subband = get_bits(gbc, 3) + 5;
+ if (end_subband > 7)
+ end_subband += end_subband - 7;
+ dst_start_freq = dst_start_freq * 12 + 25;
+ src_start_freq = start_subband * 12 + 25;
+ dst_end_freq = end_subband * 12 + 25;
+
+ /* check validity of spx ranges */
+ if (start_subband >= end_subband) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension "
+ "range (%d >= %d)\n", start_subband, end_subband);
+ return -1;
+ }
+ if (dst_start_freq >= src_start_freq) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension "
+ "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq);
+ return -1;
+ }
+
+ s->spx_dst_start_freq = dst_start_freq;
+ s->spx_src_start_freq = src_start_freq;
+ s->spx_dst_end_freq = dst_end_freq;
+
+ decode_band_structure(gbc, blk, s->eac3, 0,
+ start_subband, end_subband,
+ ff_eac3_default_spx_band_struct,
+ &s->num_spx_bands,
+ s->spx_band_sizes);
+ } else {
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ s->channel_uses_spx[ch] = 0;
+ s->first_spx_coords[ch] = 1;
+ }