]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/ac3dec.c
pgssubdec: reset rle_data_len/rle_remaining_len on allocation error
[ffmpeg] / libavcodec / ac3dec.c
index a0359faa2dc904484f261889fe56527bedb570c6..ad50552ec1b097c1fd6d305f57bd713fbb1bd492 100644 (file)
@@ -182,22 +182,14 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
     ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
     ff_kbd_window_init(s->window, 5.0, 256);
     ff_bswapdsp_init(&s->bdsp);
-    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
-    ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT);
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
+    ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
     ff_fmt_convert_init(&s->fmt_conv, avctx);
     av_lfg_init(&s->dith_state, 0);
 
     avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
 
     /* allow downmixing to stereo or mono */
-#if FF_API_REQUEST_CHANNELS
-FF_DISABLE_DEPRECATION_WARNINGS
-    if (avctx->request_channels == 1)
-        avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
-    else if (avctx->request_channels == 2)
-        avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
     if (avctx->channels > 1 &&
         avctx->request_channel_layout == AV_CH_LAYOUT_MONO)
         avctx->channels = 1;
@@ -340,47 +332,57 @@ static int parse_frame_header(AC3DecodeContext *s)
  * Set stereo downmixing coefficients based on frame header info.
  * reference: Section 7.8.2 Downmixing Into Two Channels
  */
-static void set_downmix_coeffs(AC3DecodeContext *s)
+static int set_downmix_coeffs(AC3DecodeContext *s)
 {
     int i;
     float cmix = gain_levels[s->  center_mix_level];
     float smix = gain_levels[s->surround_mix_level];
     float norm0, norm1;
 
+    if (!s->downmix_coeffs[0]) {
+        s->downmix_coeffs[0] = av_malloc(2 * AC3_MAX_CHANNELS *
+                                         sizeof(**s->downmix_coeffs));
+        if (!s->downmix_coeffs[0])
+            return AVERROR(ENOMEM);
+        s->downmix_coeffs[1] = s->downmix_coeffs[0] + AC3_MAX_CHANNELS;
+    }
+
     for (i = 0; i < s->fbw_channels; i++) {
-        s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
-        s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
+        s->downmix_coeffs[0][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
+        s->downmix_coeffs[1][i] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
     }
     if (s->channel_mode > 1 && s->channel_mode & 1) {
-        s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = cmix;
+        s->downmix_coeffs[0][1] = s->downmix_coeffs[1][1] = cmix;
     }
     if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) {
         int nf = s->channel_mode - 2;
-        s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB;
+        s->downmix_coeffs[0][nf] = s->downmix_coeffs[1][nf] = smix * LEVEL_MINUS_3DB;
     }
     if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
         int nf = s->channel_mode - 4;
-        s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix;
+        s->downmix_coeffs[0][nf] = s->downmix_coeffs[1][nf+1] = smix;
     }
 
     /* renormalize */
     norm0 = norm1 = 0.0;
     for (i = 0; i < s->fbw_channels; i++) {
-        norm0 += s->downmix_coeffs[i][0];
-        norm1 += s->downmix_coeffs[i][1];
+        norm0 += s->downmix_coeffs[0][i];
+        norm1 += s->downmix_coeffs[1][i];
     }
     norm0 = 1.0f / norm0;
     norm1 = 1.0f / norm1;
     for (i = 0; i < s->fbw_channels; i++) {
-        s->downmix_coeffs[i][0] *= norm0;
-        s->downmix_coeffs[i][1] *= norm1;
+        s->downmix_coeffs[0][i] *= norm0;
+        s->downmix_coeffs[1][i] *= norm1;
     }
 
     if (s->output_mode == AC3_CHMODE_MONO) {
         for (i = 0; i < s->fbw_channels; i++)
-            s->downmix_coeffs[i][0] = (s->downmix_coeffs[i][0] +
-                                       s->downmix_coeffs[i][1]) * LEVEL_MINUS_3DB;
+            s->downmix_coeffs[0][i] = (s->downmix_coeffs[0][i] +
+                                       s->downmix_coeffs[1][i]) * LEVEL_MINUS_3DB;
     }
+
+    return 0;
 }
 
 /**
@@ -556,8 +558,8 @@ static void remove_dithering(AC3DecodeContext *s) {
     }
 }
 
-static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch,
-                                       mant_groups *m)
+static inline void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk,
+                                              int ch, mant_groups *m)
 {
     if (!s->channel_uses_aht[ch]) {
         ac3_decode_transform_coeffs_ch(s, ch, m);
@@ -576,7 +578,7 @@ static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch,
 /**
  * Decode the transform coefficients.
  */
-static void decode_transform_coeffs(AC3DecodeContext *s, int blk)
+static inline void decode_transform_coeffs(AC3DecodeContext *s, int blk)
 {
     int ch, end;
     int got_cplchan = 0;
@@ -754,6 +756,221 @@ static void decode_band_structure(GetBitContext *gbc, int blk, int eac3,
         memcpy(band_sizes, bnd_sz, n_bands);
 }
 
+static inline int spx_strategy(AC3DecodeContext *s, int blk)
+{
+    GetBitContext *bc = &s->gbc;
+    int fbw_channels = s->fbw_channels;
+    int dst_start_freq, dst_end_freq, src_start_freq,
+        start_subband, end_subband, ch;
+
+    /* 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(bc);
+    }
+
+    /* get the frequency bins of the spx copy region and the spx start
+       and end subbands */
+    dst_start_freq = get_bits(bc, 2);
+    start_subband  = get_bits(bc, 3) + 2;
+    if (start_subband > 7)
+        start_subband += start_subband - 7;
+    end_subband    = get_bits(bc, 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 AVERROR_INVALIDDATA;
+    }
+    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 AVERROR_INVALIDDATA;
+    }
+
+    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(bc, blk, s->eac3, 0,
+                          start_subband, end_subband,
+                          ff_eac3_default_spx_band_struct,
+                          &s->num_spx_bands,
+                          s->spx_band_sizes);
+
+    return 0;
+}
+
+static inline void spx_coordinates(AC3DecodeContext *s)
+{
+    GetBitContext *bc = &s->gbc;
+    int fbw_channels = s->fbw_channels;
+    int ch, bnd;
+
+    for (ch = 1; ch <= fbw_channels; ch++) {
+        if (s->channel_uses_spx[ch]) {
+            if (s->first_spx_coords[ch] || get_bits1(bc)) {
+                float spx_blend;
+                int bin, master_spx_coord;
+
+                s->first_spx_coords[ch] = 0;
+                spx_blend        = get_bits(bc, 5) * (1.0f / 32);
+                master_spx_coord = get_bits(bc, 2) * 3;
+
+                bin = s->spx_src_start_freq;
+                for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
+                    int bandsize;
+                    int spx_coord_exp, spx_coord_mant;
+                    float nratio, sblend, nblend, spx_coord;
+
+                    /* calculate blending factors */
+                    bandsize = s->spx_band_sizes[bnd];
+                    nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend;
+                    nratio = av_clipf(nratio, 0.0f, 1.0f);
+                    nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3)
+                                                   // to give unity variance
+                    sblend = sqrtf(1.0f - nratio);
+                    bin += bandsize;
+
+                    /* decode spx coordinates */
+                    spx_coord_exp  = get_bits(bc, 4);
+                    spx_coord_mant = get_bits(bc, 2);
+                    if (spx_coord_exp == 15) spx_coord_mant <<= 1;
+                    else                     spx_coord_mant += 4;
+                    spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord);
+                    spx_coord = spx_coord_mant * (1.0f / (1 << 23));
+
+                    /* multiply noise and signal blending factors by spx coordinate */
+                    s->spx_noise_blend [ch][bnd] = nblend * spx_coord;
+                    s->spx_signal_blend[ch][bnd] = sblend * spx_coord;
+                }
+            }
+        } else {
+            s->first_spx_coords[ch] = 1;
+        }
+    }
+}
+
+static inline int coupling_strategy(AC3DecodeContext *s, int blk,
+                                    uint8_t *bit_alloc_stages)
+{
+    GetBitContext *bc = &s->gbc;
+    int fbw_channels = s->fbw_channels;
+    int channel_mode = s->channel_mode;
+    int ch;
+
+    memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
+    if (!s->eac3)
+        s->cpl_in_use[blk] = get_bits1(bc);
+    if (s->cpl_in_use[blk]) {
+        /* coupling in use */
+        int cpl_start_subband, cpl_end_subband;
+
+        if (channel_mode < AC3_CHMODE_STEREO) {
+            av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        /* check for enhanced coupling */
+        if (s->eac3 && get_bits1(bc)) {
+            /* TODO: parse enhanced coupling strategy info */
+            avpriv_request_sample(s->avctx, "Enhanced coupling");
+            return AVERROR_PATCHWELCOME;
+        }
+
+        /* determine which channels are coupled */
+        if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) {
+            s->channel_in_cpl[1] = 1;
+            s->channel_in_cpl[2] = 1;
+        } else {
+            for (ch = 1; ch <= fbw_channels; ch++)
+                s->channel_in_cpl[ch] = get_bits1(bc);
+        }
+
+        /* phase flags in use */
+        if (channel_mode == AC3_CHMODE_STEREO)
+            s->phase_flags_in_use = get_bits1(bc);
+
+        /* coupling frequency range */
+        cpl_start_subband = get_bits(bc, 4);
+        cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 :
+                                          get_bits(bc, 4) + 3;
+        if (cpl_start_subband >= cpl_end_subband) {
+            av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n",
+                   cpl_start_subband, cpl_end_subband);
+            return AVERROR_INVALIDDATA;
+        }
+        s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37;
+        s->end_freq[CPL_CH]   = cpl_end_subband   * 12 + 37;
+
+        decode_band_structure(bc, blk, s->eac3, 0, cpl_start_subband,
+                              cpl_end_subband,
+                              ff_eac3_default_cpl_band_struct,
+                              &s->num_cpl_bands, s->cpl_band_sizes);
+    } else {
+        /* coupling not in use */
+        for (ch = 1; ch <= fbw_channels; ch++) {
+            s->channel_in_cpl[ch] = 0;
+            s->first_cpl_coords[ch] = 1;
+        }
+        s->first_cpl_leak = s->eac3;
+        s->phase_flags_in_use = 0;
+    }
+
+    return 0;
+}
+
+static inline int coupling_coordinates(AC3DecodeContext *s, int blk)
+{
+    GetBitContext *bc = &s->gbc;
+    int fbw_channels = s->fbw_channels;
+    int ch, bnd;
+    int cpl_coords_exist = 0;
+
+    for (ch = 1; ch <= fbw_channels; ch++) {
+        if (s->channel_in_cpl[ch]) {
+            if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(bc)) {
+                int master_cpl_coord, cpl_coord_exp, cpl_coord_mant;
+                s->first_cpl_coords[ch] = 0;
+                cpl_coords_exist = 1;
+                master_cpl_coord = 3 * get_bits(bc, 2);
+                for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
+                    cpl_coord_exp  = get_bits(bc, 4);
+                    cpl_coord_mant = get_bits(bc, 4);
+                    if (cpl_coord_exp == 15)
+                        s->cpl_coords[ch][bnd] = cpl_coord_mant << 22;
+                    else
+                        s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21;
+                    s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);
+                }
+            } else if (!blk) {
+                av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must "
+                       "be present in block 0\n");
+                return AVERROR_INVALIDDATA;
+            }
+        } else {
+            /* channel not in coupling */
+            s->first_cpl_coords[ch] = 1;
+        }
+    }
+    /* phase flags */
+    if (s->channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) {
+        for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
+            s->phase_flags[bnd] = s->phase_flags_in_use ? get_bits1(bc) : 0;
+        }
+    }
+
+    return 0;
+}
+
 /**
  * Decode a single audio block from the AC-3 bitstream.
  */
@@ -761,7 +978,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
 {
     int fbw_channels = s->fbw_channels;
     int channel_mode = s->channel_mode;
-    int i, bnd, seg, ch;
+    int i, bnd, seg, ch, ret;
     int different_transforms;
     int downmix_output;
     int cpl_in_use;
@@ -805,51 +1022,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
     if (s->eac3 && (!blk || get_bits1(gbc))) {
         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 AVERROR_INVALIDDATA;
-            }
-            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 AVERROR_INVALIDDATA;
-            }
-
-            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);
+            if ((ret = spx_strategy(s, blk)) < 0)
+                return ret;
         } else {
             for (ch = 1; ch <= fbw_channels; ch++) {
                 s->channel_uses_spx[ch] = 0;
@@ -859,110 +1033,13 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
     }
 
     /* spectral extension coordinates */
-    if (s->spx_in_use) {
-        for (ch = 1; ch <= fbw_channels; ch++) {
-            if (s->channel_uses_spx[ch]) {
-                if (s->first_spx_coords[ch] || get_bits1(gbc)) {
-                    float spx_blend;
-                    int bin, master_spx_coord;
-
-                    s->first_spx_coords[ch] = 0;
-                    spx_blend = get_bits(gbc, 5) * (1.0f/32);
-                    master_spx_coord = get_bits(gbc, 2) * 3;
-
-                    bin = s->spx_src_start_freq;
-                    for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
-                        int bandsize;
-                        int spx_coord_exp, spx_coord_mant;
-                        float nratio, sblend, nblend, spx_coord;
-
-                        /* calculate blending factors */
-                        bandsize = s->spx_band_sizes[bnd];
-                        nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend;
-                        nratio = av_clipf(nratio, 0.0f, 1.0f);
-                        nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3)
-                                                       // to give unity variance
-                        sblend = sqrtf(1.0f - nratio);
-                        bin += bandsize;
-
-                        /* decode spx coordinates */
-                        spx_coord_exp  = get_bits(gbc, 4);
-                        spx_coord_mant = get_bits(gbc, 2);
-                        if (spx_coord_exp == 15) spx_coord_mant <<= 1;
-                        else                     spx_coord_mant += 4;
-                        spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord);
-                        spx_coord = spx_coord_mant * (1.0f / (1 << 23));
-
-                        /* multiply noise and signal blending factors by spx coordinate */
-                        s->spx_noise_blend [ch][bnd] = nblend * spx_coord;
-                        s->spx_signal_blend[ch][bnd] = sblend * spx_coord;
-                    }
-                }
-            } else {
-                s->first_spx_coords[ch] = 1;
-            }
-        }
-    }
+    if (s->spx_in_use)
+        spx_coordinates(s);
 
     /* coupling strategy */
     if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) {
-        memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
-        if (!s->eac3)
-            s->cpl_in_use[blk] = get_bits1(gbc);
-        if (s->cpl_in_use[blk]) {
-            /* coupling in use */
-            int cpl_start_subband, cpl_end_subband;
-
-            if (channel_mode < AC3_CHMODE_STEREO) {
-                av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n");
-                return AVERROR_INVALIDDATA;
-            }
-
-            /* check for enhanced coupling */
-            if (s->eac3 && get_bits1(gbc)) {
-                /* TODO: parse enhanced coupling strategy info */
-                avpriv_request_sample(s->avctx, "Enhanced coupling");
-                return AVERROR_PATCHWELCOME;
-            }
-
-            /* determine which channels are coupled */
-            if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) {
-                s->channel_in_cpl[1] = 1;
-                s->channel_in_cpl[2] = 1;
-            } else {
-                for (ch = 1; ch <= fbw_channels; ch++)
-                    s->channel_in_cpl[ch] = get_bits1(gbc);
-            }
-
-            /* phase flags in use */
-            if (channel_mode == AC3_CHMODE_STEREO)
-                s->phase_flags_in_use = get_bits1(gbc);
-
-            /* coupling frequency range */
-            cpl_start_subband = get_bits(gbc, 4);
-            cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 :
-                                              get_bits(gbc, 4) + 3;
-            if (cpl_start_subband >= cpl_end_subband) {
-                av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n",
-                       cpl_start_subband, cpl_end_subband);
-                return AVERROR_INVALIDDATA;
-            }
-            s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37;
-            s->end_freq[CPL_CH]   = cpl_end_subband   * 12 + 37;
-
-            decode_band_structure(gbc, blk, s->eac3, 0, cpl_start_subband,
-                                  cpl_end_subband,
-                                  ff_eac3_default_cpl_band_struct,
-                                  &s->num_cpl_bands, s->cpl_band_sizes);
-        } else {
-            /* coupling not in use */
-            for (ch = 1; ch <= fbw_channels; ch++) {
-                s->channel_in_cpl[ch] = 0;
-                s->first_cpl_coords[ch] = 1;
-            }
-            s->first_cpl_leak = s->eac3;
-            s->phase_flags_in_use = 0;
-        }
+        if ((ret = coupling_strategy(s, blk, bit_alloc_stages)) < 0)
+            return ret;
     } else if (!s->eac3) {
         if (!blk) {
             av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must "
@@ -976,40 +1053,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
 
     /* coupling coordinates */
     if (cpl_in_use) {
-        int cpl_coords_exist = 0;
-
-        for (ch = 1; ch <= fbw_channels; ch++) {
-            if (s->channel_in_cpl[ch]) {
-                if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(gbc)) {
-                    int master_cpl_coord, cpl_coord_exp, cpl_coord_mant;
-                    s->first_cpl_coords[ch] = 0;
-                    cpl_coords_exist = 1;
-                    master_cpl_coord = 3 * get_bits(gbc, 2);
-                    for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
-                        cpl_coord_exp = get_bits(gbc, 4);
-                        cpl_coord_mant = get_bits(gbc, 4);
-                        if (cpl_coord_exp == 15)
-                            s->cpl_coords[ch][bnd] = cpl_coord_mant << 22;
-                        else
-                            s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21;
-                        s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);
-                    }
-                } else if (!blk) {
-                    av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must "
-                           "be present in block 0\n");
-                    return AVERROR_INVALIDDATA;
-                }
-            } else {
-                /* channel not in coupling */
-                s->first_cpl_coords[ch] = 1;
-            }
-        }
-        /* phase flags */
-        if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) {
-            for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
-                s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0;
-            }
-        }
+        if ((ret = coupling_coordinates(s, blk)) < 0)
+            return ret;
     }
 
     /* stereo rematrixing strategy and band structure */
@@ -1236,8 +1281,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
     /* unused dummy data */
     if (s->skip_syntax && get_bits1(gbc)) {
         int skipl = get_bits(gbc, 9);
-        while (skipl--)
-            skip_bits(gbc, 8);
+        skip_bits_long(gbc, 8 * skipl);
     }
 
     /* unpack the transform coefficients
@@ -1284,19 +1328,19 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
         do_imdct(s, s->channels);
 
         if (downmix_output) {
-            s->ac3dsp.downmix(s->outptr, s->downmix_coeffs,
+            ff_ac3dsp_downmix(&s->ac3dsp, s->outptr, s->downmix_coeffs,
                               s->out_channels, s->fbw_channels, 256);
         }
     } else {
         if (downmix_output) {
-            s->ac3dsp.downmix(s->xcfptr + 1, s->downmix_coeffs,
+            ff_ac3dsp_downmix(&s->ac3dsp, s->xcfptr + 1, s->downmix_coeffs,
                               s->out_channels, s->fbw_channels, 256);
         }
 
         if (downmix_output && !s->downmixed) {
             s->downmixed = 1;
-            s->ac3dsp.downmix(s->dlyptr, s->downmix_coeffs, s->out_channels,
-                              s->fbw_channels, 128);
+            ff_ac3dsp_downmix(&s->ac3dsp, s->dlyptr, s->downmix_coeffs,
+                              s->out_channels, s->fbw_channels, 128);
         }
 
         do_imdct(s, s->out_channels);
@@ -1355,8 +1399,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
             /* skip frame if CRC is ok. otherwise use error concealment. */
             /* TODO: add support for substreams and dependent frames */
             if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {
-                av_log(avctx, AV_LOG_WARNING, "unsupported frame type : "
-                       "skipping frame\n");
+                av_log(avctx, AV_LOG_DEBUG,
+                       "unsupported frame type %d: skipping frame\n",
+                       s->frame_type);
                 *got_frame_ptr = 0;
                 return buf_size;
             } else {
@@ -1412,7 +1457,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
         /* set downmixing coefficients if needed */
         if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
                 s->fbw_channels == s->out_channels)) {
-            set_downmix_coeffs(s);
+            if ((ret = set_downmix_coeffs(s)) < 0) {
+                av_log(avctx, AV_LOG_ERROR, "error setting downmix coeffs\n");
+                return ret;
+            }
         }
     } else if (!s->channels) {
         av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n");
@@ -1531,6 +1579,7 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx)
     AC3DecodeContext *s = avctx->priv_data;
     ff_mdct_end(&s->imdct_512);
     ff_mdct_end(&s->imdct_256);
+    av_freep(&s->downmix_coeffs[0]);
 
     return 0;
 }
@@ -1558,7 +1607,7 @@ AVCodec ff_ac3_decoder = {
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
     .decode         = ac3_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = AV_CODEC_CAP_DR1,
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &ac3_decoder_class,
@@ -1581,7 +1630,7 @@ AVCodec ff_eac3_decoder = {
     .init           = ac3_decode_init,
     .close          = ac3_decode_end,
     .decode         = ac3_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = AV_CODEC_CAP_DR1,
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
     .priv_class     = &eac3_decoder_class,