ac3dec: Split coupling-specific code from decode_audio_block()
authorLuca Barbato <lu_zero@gentoo.org>
Mon, 18 Jul 2016 17:50:33 +0000 (19:50 +0200)
committerDiego Biurrun <diego@biurrun.de>
Fri, 29 Jul 2016 16:46:48 +0000 (18:46 +0200)
Signed-off-by: Diego Biurrun <diego@biurrun.de>
libavcodec/ac3dec.c

index 4de7475..f3e3da5 100644 (file)
@@ -849,6 +849,118 @@ static inline void spx_coordinates(AC3DecodeContext *s)
     }
 }
 
+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.
  */
@@ -916,63 +1028,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
 
     /* 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 "
@@ -986,40 +1043,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 */