diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 741f2f766dd176b9172a36e4a6e56802db711468..2302a05fff858e0d66fa1ff369290f0db44eb1b3 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -1453,6 +1453,114 @@ static float dca_dmix_code(unsigned code)
     return ((ff_dca_dmixtable[code] ^ sign) - sign) * (1.0 / (1 << 15));
 }
 
+static int scan_for_extensions(AVCodecContext *avctx)
+{
+    DCAContext *s = avctx->priv_data;
+    int core_ss_end, ret;
+
+    core_ss_end = FFMIN(s->frame_size, s->dca_buffer_size) * 8;
+
+    /* only scan for extensions if ext_descr was unknown or indicated a
+     * supported XCh extension */
+    if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {
+        /* if ext_descr was unknown, clear s->core_ext_mask so that the
+         * extensions scan can fill it up */
+        s->core_ext_mask = FFMAX(s->core_ext_mask, 0);
+
+        /* extensions start at 32-bit boundaries into bitstream */
+        skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
+
+        while (core_ss_end - get_bits_count(&s->gb) >= 32) {
+            uint32_t bits = get_bits_long(&s->gb, 32);
+            int i;
+
+            switch (bits) {
+            case DCA_SYNCWORD_XCH: {
+                int ext_amode, xch_fsize;
+
+                s->xch_base_channel = s->prim_channels;
+
+                /* validate sync word using XCHFSIZE field */
+                xch_fsize = show_bits(&s->gb, 10);
+                if ((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize) &&
+                    (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize + 1))
+                    continue;
+
+                /* skip length-to-end-of-frame field for the moment */
+                skip_bits(&s->gb, 10);
+
+                s->core_ext_mask |= DCA_EXT_XCH;
+
+                /* extension amode(number of channels in extension) should be 1 */
+                /* AFAIK XCh is not used for more channels */
+                if ((ext_amode = get_bits(&s->gb, 4)) != 1) {
+                    av_log(avctx, AV_LOG_ERROR,
+                           "XCh extension amode %d not supported!\n",
+                           ext_amode);
+                    continue;
+                }
+
+                if (s->xch_base_channel < 2) {
+                    avpriv_request_sample(avctx, "XCh with fewer than 2 base channels");
+                    continue;
+                }
+
+                /* much like core primary audio coding header */
+                dca_parse_audio_coding_header(s, s->xch_base_channel, 0);
+
+                for (i = 0; i < (s->sample_blocks / 8); i++)
+                    if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
+                        av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n");
+                        continue;
+                    }
+
+                s->xch_present = 1;
+                break;
+            }
+            case DCA_SYNCWORD_XXCH:
+                /* XXCh: extended channels */
+                /* usually found either in core or HD part in DTS-HD HRA streams,
+                 * but not in DTS-ES which contains XCh extensions instead */
+                s->core_ext_mask |= DCA_EXT_XXCH;
+                ff_dca_xxch_decode_frame(s);
+                break;
+
+            case 0x1d95f262: {
+                int fsize96 = show_bits(&s->gb, 12) + 1;
+                if (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + fsize96)
+                    continue;
+
+                av_log(avctx, AV_LOG_DEBUG, "X96 extension found at %d bits\n",
+                       get_bits_count(&s->gb));
+                skip_bits(&s->gb, 12);
+                av_log(avctx, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", fsize96);
+                av_log(avctx, AV_LOG_DEBUG, "REVNO = %d\n", get_bits(&s->gb, 4));
+
+                s->core_ext_mask |= DCA_EXT_X96;
+                break;
+            }
+            }
+
+            skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
+        }
+    } else {
+        /* no supported extensions, skip the rest of the core substream */
+        skip_bits_long(&s->gb, core_ss_end - get_bits_count(&s->gb));
+    }
+
+    if (s->core_ext_mask & DCA_EXT_X96)
+        s->profile = FF_PROFILE_DTS_96_24;
+    else if (s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH))
+        s->profile = FF_PROFILE_DTS_ES;
+
+    /* check for ExSS (HD part) */
+    if (s->dca_buffer_size - s->frame_size > 32 &&
+        get_bits_long(&s->gb, 32) == DCA_SYNCWORD_SUBSTREAM)
+        ff_dca_exss_parse_header(s);
+
+    return ret;
+}
+
 /**
  * Main frame decoding function
  * FIXME add arguments
@@ -1472,7 +1580,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     float *src_chan;
     float *dst_chan;
     DCAContext *s = avctx->priv_data;
-    int core_ss_end;
     int channels, full_channels;
     float scale;
     int achan;
@@ -1564,104 +1671,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     else
         s->core_ext_mask = 0;
 
-    core_ss_end = FFMIN(s->frame_size, s->dca_buffer_size) * 8;
-
-    /* only scan for extensions if ext_descr was unknown or indicated a
-     * supported XCh extension */
-    if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {
-        /* if ext_descr was unknown, clear s->core_ext_mask so that the
-         * extensions scan can fill it up */
-        s->core_ext_mask = FFMAX(s->core_ext_mask, 0);
-
-        /* extensions start at 32-bit boundaries into bitstream */
-        skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
-
-        while (core_ss_end - get_bits_count(&s->gb) >= 32) {
-            uint32_t bits = get_bits_long(&s->gb, 32);
-
-            switch (bits) {
-            case DCA_SYNCWORD_XCH: {
-                int ext_amode, xch_fsize;
-
-                s->xch_base_channel = s->prim_channels;
-
-                /* validate sync word using XCHFSIZE field */
-                xch_fsize = show_bits(&s->gb, 10);
-                if ((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize) &&
-                    (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize + 1))
-                    continue;
-
-                /* skip length-to-end-of-frame field for the moment */
-                skip_bits(&s->gb, 10);
-
-                s->core_ext_mask |= DCA_EXT_XCH;
-
-                /* extension amode(number of channels in extension) should be 1 */
-                /* AFAIK XCh is not used for more channels */
-                if ((ext_amode = get_bits(&s->gb, 4)) != 1) {
-                    av_log(avctx, AV_LOG_ERROR,
-                           "XCh extension amode %d not supported!\n",
-                           ext_amode);
-                    continue;
-                }
-
-                if (s->xch_base_channel < 2) {
-                    avpriv_request_sample(avctx, "XCh with fewer than 2 base channels");
-                    continue;
-                }
-
-                /* much like core primary audio coding header */
-                dca_parse_audio_coding_header(s, s->xch_base_channel, 0);
-
-                for (i = 0; i < (s->sample_blocks / 8); i++)
-                    if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
-                        av_log(avctx, AV_LOG_ERROR, "error decoding XCh extension\n");
-                        continue;
-                    }
-
-                s->xch_present = 1;
-                break;
-            }
-            case DCA_SYNCWORD_XXCH:
-                /* XXCh: extended channels */
-                /* usually found either in core or HD part in DTS-HD HRA streams,
-                 * but not in DTS-ES which contains XCh extensions instead */
-                s->core_ext_mask |= DCA_EXT_XXCH;
-                ff_dca_xxch_decode_frame(s);
-                break;
-
-            case 0x1d95f262: {
-                int fsize96 = show_bits(&s->gb, 12) + 1;
-                if (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + fsize96)
-                    continue;
-
-                av_log(avctx, AV_LOG_DEBUG, "X96 extension found at %d bits\n",
-                       get_bits_count(&s->gb));
-                skip_bits(&s->gb, 12);
-                av_log(avctx, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", fsize96);
-                av_log(avctx, AV_LOG_DEBUG, "REVNO = %d\n", get_bits(&s->gb, 4));
-
-                s->core_ext_mask |= DCA_EXT_X96;
-                break;
-            }
-            }
-
-            skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
-        }
-    } else {
-        /* no supported extensions, skip the rest of the core substream */
-        skip_bits_long(&s->gb, core_ss_end - get_bits_count(&s->gb));
-    }
-
-    if (s->core_ext_mask & DCA_EXT_X96)
-        s->profile = FF_PROFILE_DTS_96_24;
-    else if (s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH))
-        s->profile = FF_PROFILE_DTS_ES;
-
-    /* check for ExSS (HD part) */
-    if (s->dca_buffer_size - s->frame_size > 32 &&
-        get_bits_long(&s->gb, 32) == DCA_SYNCWORD_SUBSTREAM)
-        ff_dca_exss_parse_header(s);
+    ret = scan_for_extensions(avctx);
 
     avctx->profile = s->profile;