static int dca_decode_frame(AVCodecContext *avctx, void *data,

                            int *got_frame_ptr, AVPacket *avpkt)

{

    AVFrame *frame     = data;

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;



    int lfe_samples;

    int num_core_channels = 0;

    int i, ret;

    float  **samples_flt;

    DCAContext *s = avctx->priv_data;

    int channels, full_channels;

    int core_ss_end;





    s->xch_present = 0;



    s->dca_buffer_size = ff_dca_convert_bitstream(buf, buf_size, s->dca_buffer,

                                                  DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);

    if (s->dca_buffer_size == AVERROR_INVALIDDATA) {

        av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");

        return AVERROR_INVALIDDATA;

    }



    init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);

    if ((ret = dca_parse_frame_header(s)) < 0) {

        //seems like the frame is corrupt, try with the next one

        return ret;

    }

    //set AVCodec values with parsed data

    avctx->sample_rate = s->sample_rate;

    avctx->bit_rate    = s->bit_rate;



    s->profile = FF_PROFILE_DTS;



    for (i = 0; i < (s->sample_blocks / 8); i++) {

        if ((ret = dca_decode_block(s, 0, i))) {

            av_log(avctx, AV_LOG_ERROR, "error decoding block\n");

            return ret;

        }

    }



    /* record number of core channels incase less than max channels are requested */

    num_core_channels = s->prim_channels;



    if (s->ext_coding)

        s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];

    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) {



        /* 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 0x5a5a5a5a: {

                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;

                }



                /* much like core primary audio coding header */

                dca_parse_audio_coding_header(s, s->xch_base_channel);



                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 0x47004a03:

                /* 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;

                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_HD_MARKER)

        dca_exss_parse_header(s);



    avctx->profile = s->profile;



    full_channels = channels = s->prim_channels + !!s->lfe;



    if (s->amode < 16) {

        avctx->channel_layout = dca_core_channel_layout[s->amode];



        if (s->prim_channels + !!s->lfe > 2 &&

            avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {

            /*

             * Neither the core's auxiliary data nor our default tables contain

             * downmix coefficients for the additional channel coded in the XCh

             * extension, so when we're doing a Stereo downmix, don't decode it.

             */

            s->xch_disable = 1;

        }



#if FF_API_REQUEST_CHANNELS

FF_DISABLE_DEPRECATION_WARNINGS

        if (s->xch_present && !s->xch_disable &&

            (!avctx->request_channels ||

             avctx->request_channels > num_core_channels + !!s->lfe)) {

FF_ENABLE_DEPRECATION_WARNINGS

#else

        if (s->xch_present && !s->xch_disable) {

#endif

            avctx->channel_layout |= AV_CH_BACK_CENTER;

            if (s->lfe) {

                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;

                s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode];

            } else {

                s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];

            }

        } else {

            channels = num_core_channels + !!s->lfe;

            s->xch_present = 0; /* disable further xch processing */

            if (s->lfe) {

                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;

                s->channel_order_tab = dca_channel_reorder_lfe[s->amode];

            } else

                s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];

        }



        if (channels > !!s->lfe &&

            s->channel_order_tab[channels - 1 - !!s->lfe] < 0)

            return AVERROR_INVALIDDATA;



        if (s->prim_channels + !!s->lfe > 2 &&

            avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {

            channels = 2;

            s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO;

            avctx->channel_layout = AV_CH_LAYOUT_STEREO;



            /* Stereo downmix coefficients

             *

             * The decoder can only downmix to 2-channel, so we need to ensure

             * embedded downmix coefficients are actually targeting 2-channel.

             */

            if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||

                                    s->core_downmix_amode == DCA_STEREO_TOTAL)) {

                int sign, code;

                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {

                    sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1;

                    code = s->core_downmix_codes[i][0] & 0x0FF;

                    s->downmix_coef[i][0] = (!code ? 0.0f :

                                             sign * dca_dmixtable[code - 1]);

                    sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1;

                    code = s->core_downmix_codes[i][1] & 0x0FF;

                    s->downmix_coef[i][1] = (!code ? 0.0f :

                                             sign * dca_dmixtable[code - 1]);

                }

                s->output = s->core_downmix_amode;

            } else {

                int am = s->amode & DCA_CHANNEL_MASK;

                if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {

                    av_log(s->avctx, AV_LOG_ERROR,

                           "Invalid channel mode %d\n", am);

                    return AVERROR_INVALIDDATA;

                }

                if (s->prim_channels + !!s->lfe >

                    FF_ARRAY_ELEMS(dca_default_coeffs[0])) {

                    avpriv_request_sample(s->avctx, "Downmixing %d channels",

                                          s->prim_channels + !!s->lfe);

                    return AVERROR_PATCHWELCOME;

                }

                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {

                    s->downmix_coef[i][0] = dca_default_coeffs[am][i][0];

                    s->downmix_coef[i][1] = dca_default_coeffs[am][i][1];

                }

            }

            av_dlog(s->avctx, "Stereo downmix coeffs:\n");

            for (i = 0; i < s->prim_channels + !!s->lfe; i++) {

                av_dlog(s->avctx, "L, input channel %d = %f\n", i,

                        s->downmix_coef[i][0]);

                av_dlog(s->avctx, "R, input channel %d = %f\n", i,

                        s->downmix_coef[i][1]);

            }

            av_dlog(s->avctx, "\n");

        }

    } else {

        av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);

        return AVERROR_INVALIDDATA;

    }

    avctx->channels = channels;



    /* get output buffer */

    frame->nb_samples = 256 * (s->sample_blocks / 8);

    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return ret;

    }

    samples_flt = (float **)frame->extended_data;



    /* allocate buffer for extra channels if downmixing */

    if (avctx->channels < full_channels) {

        ret = av_samples_get_buffer_size(NULL, full_channels - channels,

                                         frame->nb_samples,

                                         avctx->sample_fmt, 0);

        if (ret < 0)

            return ret;



        av_fast_malloc(&s->extra_channels_buffer,

                       &s->extra_channels_buffer_size, ret);

        if (!s->extra_channels_buffer)

            return AVERROR(ENOMEM);



        ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,

                                     s->extra_channels_buffer,

                                     full_channels - channels,

                                     frame->nb_samples, avctx->sample_fmt, 0);

        if (ret < 0)

            return ret;

    }



    /* filter to get final output */

    for (i = 0; i < (s->sample_blocks / 8); i++) {

        int ch;



        for (ch = 0; ch < channels; ch++)

            s->samples_chanptr[ch] = samples_flt[ch] + i * 256;

        for (; ch < full_channels; ch++)

            s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * 256;



        dca_filter_channels(s, i);



        /* If this was marked as a DTS-ES stream we need to subtract back- */

        /* channel from SL & SR to remove matrixed back-channel signal */

        if ((s->source_pcm_res & 1) && s->xch_present) {

            float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]];

            float *lt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]];

            float *rt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 1]];

            s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);

            s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);

        }

    }



    /* update lfe history */

    lfe_samples = 2 * s->lfe * (s->sample_blocks / 8);

    for (i = 0; i < 2 * s->lfe * 4; i++)

        s->lfe_data[i] = s->lfe_data[i + lfe_samples];



    /* AVMatrixEncoding

     *

     * DCA_STEREO_TOTAL (Lt/Rt) is equivalent to Dolby Surround */

    ret = ff_side_data_update_matrix_encoding(frame,

                                              (s->output & ~DCA_LFE) == DCA_STEREO_TOTAL ?

                                              AV_MATRIX_ENCODING_DOLBY : AV_MATRIX_ENCODING_NONE);

    if (ret < 0)

        return ret;



    *got_frame_ptr = 1;



    return buf_size;

}

static int dca_decode_frame(AVCodecContext *avctx, void *data,

                            int *got_frame_ptr, AVPacket *avpkt)

{

    AVFrame *frame     = data;

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;



    int lfe_samples;

    int num_core_channels = 0;

    int i, ret;

    float  **samples_flt;

    DCAContext *s = avctx->priv_data;

    int channels, full_channels;

    int core_ss_end;





    s->xch_present = 0;



    s->dca_buffer_size = ff_dca_convert_bitstream(buf, buf_size, s->dca_buffer,

                                                  DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);

    if (s->dca_buffer_size == AVERROR_INVALIDDATA) {

        av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");

        return AVERROR_INVALIDDATA;

    }



    init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);

    if ((ret = dca_parse_frame_header(s)) < 0) {

        

        return ret;

    }

    

    avctx->sample_rate = s->sample_rate;

    avctx->bit_rate    = s->bit_rate;



    s->profile = FF_PROFILE_DTS;



    for (i = 0; i < (s->sample_blocks / 8); i++) {

        if ((ret = dca_decode_block(s, 0, i))) {

            av_log(avctx, AV_LOG_ERROR, "error decoding block\n");

            return ret;

        }

    }



    

    num_core_channels = s->prim_channels;



    if (s->ext_coding)

        s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];

    else

        s->core_ext_mask = 0;



    core_ss_end = FFMIN(s->frame_size, s->dca_buffer_size) * 8;



    



    if (s->core_ext_mask < 0 || s->core_ext_mask & DCA_EXT_XCH) {



        



        s->core_ext_mask = FFMAX(s->core_ext_mask, 0);



        

        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 0x5a5a5a5a: {

                int ext_amode, xch_fsize;



                s->xch_base_channel = s->prim_channels;



                

                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_bits(&s->gb, 10);



                s->core_ext_mask |= DCA_EXT_XCH;



                

                

                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;

                }



                

                dca_parse_audio_coding_header(s, s->xch_base_channel);



                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 0x47004a03:

                

                



                s->core_ext_mask |= DCA_EXT_XXCH;

                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 {

        

        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;



    

    if (s->dca_buffer_size - s->frame_size > 32 &&

        get_bits_long(&s->gb, 32) == DCA_HD_MARKER)

        dca_exss_parse_header(s);



    avctx->profile = s->profile;



    full_channels = channels = s->prim_channels + !!s->lfe;



    if (s->amode < 16) {

        avctx->channel_layout = dca_core_channel_layout[s->amode];



        if (s->prim_channels + !!s->lfe > 2 &&

            avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {

            









            s->xch_disable = 1;

        }



#if FF_API_REQUEST_CHANNELS

FF_DISABLE_DEPRECATION_WARNINGS

        if (s->xch_present && !s->xch_disable &&

            (!avctx->request_channels ||

             avctx->request_channels > num_core_channels + !!s->lfe)) {

FF_ENABLE_DEPRECATION_WARNINGS

#else

        if (s->xch_present && !s->xch_disable) {

#endif

            avctx->channel_layout |= AV_CH_BACK_CENTER;

            if (s->lfe) {

                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;

                s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode];

            } else {

                s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];

            }

        } else {

            channels = num_core_channels + !!s->lfe;

            s->xch_present = 0; 

            if (s->lfe) {

                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;

                s->channel_order_tab = dca_channel_reorder_lfe[s->amode];

            } else

                s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];

        }



        if (channels > !!s->lfe &&

            s->channel_order_tab[channels - 1 - !!s->lfe] < 0)

            return AVERROR_INVALIDDATA;



        if (s->prim_channels + !!s->lfe > 2 &&

            avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {

            channels = 2;

            s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO;

            avctx->channel_layout = AV_CH_LAYOUT_STEREO;



            









            if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||

                                    s->core_downmix_amode == DCA_STEREO_TOTAL)) {

                int sign, code;

                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {

                    sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1;

                    code = s->core_downmix_codes[i][0] & 0x0FF;

                    s->downmix_coef[i][0] = (!code ? 0.0f :

                                             sign * dca_dmixtable[code - 1]);

                    sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1;

                    code = s->core_downmix_codes[i][1] & 0x0FF;

                    s->downmix_coef[i][1] = (!code ? 0.0f :

                                             sign * dca_dmixtable[code - 1]);

                }

                s->output = s->core_downmix_amode;

            } else {

                int am = s->amode & DCA_CHANNEL_MASK;

                if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) {

                    av_log(s->avctx, AV_LOG_ERROR,

                           "Invalid channel mode %d\n", am);

                    return AVERROR_INVALIDDATA;

                }

                if (s->prim_channels + !!s->lfe >

                    FF_ARRAY_ELEMS(dca_default_coeffs[0])) {

                    avpriv_request_sample(s->avctx, "Downmixing %d channels",

                                          s->prim_channels + !!s->lfe);

                    return AVERROR_PATCHWELCOME;

                }

                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {

                    s->downmix_coef[i][0] = dca_default_coeffs[am][i][0];

                    s->downmix_coef[i][1] = dca_default_coeffs[am][i][1];

                }

            }

            av_dlog(s->avctx, "Stereo downmix coeffs:\n");

            for (i = 0; i < s->prim_channels + !!s->lfe; i++) {

                av_dlog(s->avctx, "L, input channel %d = %f\n", i,

                        s->downmix_coef[i][0]);

                av_dlog(s->avctx, "R, input channel %d = %f\n", i,

                        s->downmix_coef[i][1]);

            }

            av_dlog(s->avctx, "\n");

        }

    } else {

        av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);

        return AVERROR_INVALIDDATA;

    }

    avctx->channels = channels;



    

    frame->nb_samples = 256 * (s->sample_blocks / 8);

    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return ret;

    }

    samples_flt = (float **)frame->extended_data;



    

    if (avctx->channels < full_channels) {

        ret = av_samples_get_buffer_size(NULL, full_channels - channels,

                                         frame->nb_samples,

                                         avctx->sample_fmt, 0);

        if (ret < 0)

            return ret;



        av_fast_malloc(&s->extra_channels_buffer,

                       &s->extra_channels_buffer_size, ret);

        if (!s->extra_channels_buffer)

            return AVERROR(ENOMEM);



        ret = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,

                                     s->extra_channels_buffer,

                                     full_channels - channels,

                                     frame->nb_samples, avctx->sample_fmt, 0);

        if (ret < 0)

            return ret;

    }



    

    for (i = 0; i < (s->sample_blocks / 8); i++) {

        int ch;



        for (ch = 0; ch < channels; ch++)

            s->samples_chanptr[ch] = samples_flt[ch] + i * 256;

        for (; ch < full_channels; ch++)

            s->samples_chanptr[ch] = s->extra_channels[ch - channels] + i * 256;



        dca_filter_channels(s, i);



        

        

        if ((s->source_pcm_res & 1) && s->xch_present) {

            float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]];

            float *lt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]];

            float *rt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 1]];

            s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);

            s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);

        }

    }



    

    lfe_samples = 2 * s->lfe * (s->sample_blocks / 8);

    for (i = 0; i < 2 * s->lfe * 4; i++)

        s->lfe_data[i] = s->lfe_data[i + lfe_samples];



    





    ret = ff_side_data_update_matrix_encoding(frame,

                                              (s->output & ~DCA_LFE) == DCA_STEREO_TOTAL ?

                                              AV_MATRIX_ENCODING_DOLBY : AV_MATRIX_ENCODING_NONE);

    if (ret < 0)

        return ret;



    *got_frame_ptr = 1;



    return buf_size;

}

static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1,

                            int *VAR_2, AVPacket *VAR_3)

{

    AVFrame *frame     = VAR_1;

    const uint8_t *VAR_4 = VAR_3->VAR_1;

    int VAR_5 = VAR_3->size;



    int VAR_6;

    int VAR_7 = 0;

    int VAR_8, VAR_9;

    float  **VAR_10;

    DCAContext *s = VAR_0->priv_data;

    int VAR_11, VAR_12;

    int VAR_13;





    s->xch_present = 0;



    s->dca_buffer_size = ff_dca_convert_bitstream(VAR_4, VAR_5, s->dca_buffer,

                                                  DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE);

    if (s->dca_buffer_size == AVERROR_INVALIDDATA) {

        av_log(VAR_0, AV_LOG_ERROR, "Not a valid DCA frame\n");

        return AVERROR_INVALIDDATA;

    }



    init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);

    if ((VAR_9 = dca_parse_frame_header(s)) < 0) {

        

        return VAR_9;

    }

    

    VAR_0->sample_rate = s->sample_rate;

    VAR_0->bit_rate    = s->bit_rate;



    s->profile = FF_PROFILE_DTS;



    for (VAR_8 = 0; VAR_8 < (s->sample_blocks / 8); VAR_8++) {

        if ((VAR_9 = dca_decode_block(s, 0, VAR_8))) {

            av_log(VAR_0, AV_LOG_ERROR, "error decoding block\n");

            return VAR_9;

        }

    }



    

    VAR_7 = s->prim_channels;



    if (s->ext_coding)

        s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr];

    else

        s->core_ext_mask = 0;



    VAR_13 = FFMIN(s->frame_size, s->dca_buffer_size) * 8;



    



    if (s->core_ext_mask < 0 || s->core_ext_mask & DCA_EXT_XCH) {



        



        s->core_ext_mask = FFMAX(s->core_ext_mask, 0);



        

        skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);



        while (VAR_13 - get_bits_count(&s->gb) >= 32) {

            uint32_t bits = get_bits_long(&s->gb, 32);



            switch (bits) {

            case 0x5a5a5a5a: {

                int VAR_14, VAR_15;



                s->xch_base_channel = s->prim_channels;



                

                VAR_15 = show_bits(&s->gb, 10);

                if ((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + VAR_15) &&

                    (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + VAR_15 + 1))

                    continue;



                

                skip_bits(&s->gb, 10);



                s->core_ext_mask |= DCA_EXT_XCH;



                

                

                if ((VAR_14 = get_bits(&s->gb, 4)) != 1) {

                    av_log(VAR_0, AV_LOG_ERROR, "XCh extension amode %d not"

                           " supported!\n", VAR_14);

                    continue;

                }



                

                dca_parse_audio_coding_header(s, s->xch_base_channel);



                for (VAR_8 = 0; VAR_8 < (s->sample_blocks / 8); VAR_8++)

                    if ((VAR_9 = dca_decode_block(s, s->xch_base_channel, VAR_8))) {

                        av_log(VAR_0, AV_LOG_ERROR, "error decoding XCh extension\n");

                        continue;

                    }



                s->xch_present = 1;

                break;

            }

            case 0x47004a03:

                

                



                s->core_ext_mask |= DCA_EXT_XXCH;

                break;



            case 0x1d95f262: {

                int VAR_16 = show_bits(&s->gb, 12) + 1;

                if (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + VAR_16)

                    continue;



                av_log(VAR_0, AV_LOG_DEBUG, "X96 extension found at %d bits\n",

                       get_bits_count(&s->gb));

                skip_bits(&s->gb, 12);

                av_log(VAR_0, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", VAR_16);

                av_log(VAR_0, 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 {

        

        skip_bits_long(&s->gb, VAR_13 - 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;



    

    if (s->dca_buffer_size - s->frame_size > 32 &&

        get_bits_long(&s->gb, 32) == DCA_HD_MARKER)

        dca_exss_parse_header(s);



    VAR_0->profile = s->profile;



    VAR_12 = VAR_11 = s->prim_channels + !!s->lfe;



    if (s->amode < 16) {

        VAR_0->channel_layout = dca_core_channel_layout[s->amode];



        if (s->prim_channels + !!s->lfe > 2 &&

            VAR_0->request_channel_layout == AV_CH_LAYOUT_STEREO) {

            









            s->xch_disable = 1;

        }



#if FF_API_REQUEST_CHANNELS

FF_DISABLE_DEPRECATION_WARNINGS

        if (s->xch_present && !s->xch_disable &&

            (!VAR_0->request_channels ||

             VAR_0->request_channels > VAR_7 + !!s->lfe)) {

FF_ENABLE_DEPRECATION_WARNINGS

#else

        if (s->xch_present && !s->xch_disable) {

#endif

            VAR_0->channel_layout |= AV_CH_BACK_CENTER;

            if (s->lfe) {

                VAR_0->channel_layout |= AV_CH_LOW_FREQUENCY;

                s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode];

            } else {

                s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];

            }

        } else {

            VAR_11 = VAR_7 + !!s->lfe;

            s->xch_present = 0; 

            if (s->lfe) {

                VAR_0->channel_layout |= AV_CH_LOW_FREQUENCY;

                s->channel_order_tab = dca_channel_reorder_lfe[s->amode];

            } else

                s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];

        }



        if (VAR_11 > !!s->lfe &&

            s->channel_order_tab[VAR_11 - 1 - !!s->lfe] < 0)

            return AVERROR_INVALIDDATA;



        if (s->prim_channels + !!s->lfe > 2 &&

            VAR_0->request_channel_layout == AV_CH_LAYOUT_STEREO) {

            VAR_11 = 2;

            s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO;

            VAR_0->channel_layout = AV_CH_LAYOUT_STEREO;



            









            if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||

                                    s->core_downmix_amode == DCA_STEREO_TOTAL)) {

                int VAR_17, VAR_18;

                for (VAR_8 = 0; VAR_8 < s->prim_channels + !!s->lfe; VAR_8++) {

                    VAR_17 = s->core_downmix_codes[VAR_8][0] & 0x100 ? 1 : -1;

                    VAR_18 = s->core_downmix_codes[VAR_8][0] & 0x0FF;

                    s->downmix_coef[VAR_8][0] = (!VAR_18 ? 0.0f :

                                             VAR_17 * dca_dmixtable[VAR_18 - 1]);

                    VAR_17 = s->core_downmix_codes[VAR_8][1] & 0x100 ? 1 : -1;

                    VAR_18 = s->core_downmix_codes[VAR_8][1] & 0x0FF;

                    s->downmix_coef[VAR_8][1] = (!VAR_18 ? 0.0f :

                                             VAR_17 * dca_dmixtable[VAR_18 - 1]);

                }

                s->output = s->core_downmix_amode;

            } else {

                int VAR_19 = s->amode & DCA_CHANNEL_MASK;

                if (VAR_19 >= FF_ARRAY_ELEMS(dca_default_coeffs)) {

                    av_log(s->VAR_0, AV_LOG_ERROR,

                           "Invalid channel mode %d\n", VAR_19);

                    return AVERROR_INVALIDDATA;

                }

                if (s->prim_channels + !!s->lfe >

                    FF_ARRAY_ELEMS(dca_default_coeffs[0])) {

                    avpriv_request_sample(s->VAR_0, "Downmixing %d VAR_11",

                                          s->prim_channels + !!s->lfe);

                    return AVERROR_PATCHWELCOME;

                }

                for (VAR_8 = 0; VAR_8 < s->prim_channels + !!s->lfe; VAR_8++) {

                    s->downmix_coef[VAR_8][0] = dca_default_coeffs[VAR_19][VAR_8][0];

                    s->downmix_coef[VAR_8][1] = dca_default_coeffs[VAR_19][VAR_8][1];

                }

            }

            av_dlog(s->VAR_0, "Stereo downmix coeffs:\n");

            for (VAR_8 = 0; VAR_8 < s->prim_channels + !!s->lfe; VAR_8++) {

                av_dlog(s->VAR_0, "L, input channel %d = %f\n", VAR_8,

                        s->downmix_coef[VAR_8][0]);

                av_dlog(s->VAR_0, "R, input channel %d = %f\n", VAR_8,

                        s->downmix_coef[VAR_8][1]);

            }

            av_dlog(s->VAR_0, "\n");

        }

    } else {

        av_log(VAR_0, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);

        return AVERROR_INVALIDDATA;

    }

    VAR_0->VAR_11 = VAR_11;



    

    frame->nb_samples = 256 * (s->sample_blocks / 8);

    if ((VAR_9 = ff_get_buffer(VAR_0, frame, 0)) < 0) {

        av_log(VAR_0, AV_LOG_ERROR, "get_buffer() failed\n");

        return VAR_9;

    }

    VAR_10 = (float **)frame->extended_data;



    

    if (VAR_0->VAR_11 < VAR_12) {

        VAR_9 = av_samples_get_buffer_size(NULL, VAR_12 - VAR_11,

                                         frame->nb_samples,

                                         VAR_0->sample_fmt, 0);

        if (VAR_9 < 0)

            return VAR_9;



        av_fast_malloc(&s->extra_channels_buffer,

                       &s->extra_channels_buffer_size, VAR_9);

        if (!s->extra_channels_buffer)

            return AVERROR(ENOMEM);



        VAR_9 = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,

                                     s->extra_channels_buffer,

                                     VAR_12 - VAR_11,

                                     frame->nb_samples, VAR_0->sample_fmt, 0);

        if (VAR_9 < 0)

            return VAR_9;

    }



    

    for (VAR_8 = 0; VAR_8 < (s->sample_blocks / 8); VAR_8++) {

        int ch;



        for (ch = 0; ch < VAR_11; ch++)

            s->samples_chanptr[ch] = VAR_10[ch] + VAR_8 * 256;

        for (; ch < VAR_12; ch++)

            s->samples_chanptr[ch] = s->extra_channels[ch - VAR_11] + VAR_8 * 256;



        dca_filter_channels(s, VAR_8);



        

        

        if ((s->source_pcm_res & 1) && s->xch_present) {

            float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]];

            float *lt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]];

            float *rt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 1]];

            s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);

            s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);

        }

    }



    

    VAR_6 = 2 * s->lfe * (s->sample_blocks / 8);

    for (VAR_8 = 0; VAR_8 < 2 * s->lfe * 4; VAR_8++)

        s->lfe_data[VAR_8] = s->lfe_data[VAR_8 + VAR_6];



    





    VAR_9 = ff_side_data_update_matrix_encoding(frame,

                                              (s->output & ~DCA_LFE) == DCA_STEREO_TOTAL ?

                                              AV_MATRIX_ENCODING_DOLBY : AV_MATRIX_ENCODING_NONE);

    if (VAR_9 < 0)

        return VAR_9;



    *VAR_2 = 1;



    return VAR_5;

}

static int FUNC_0(AVCodecContext *VAR_0, void *VAR_1,
int *VAR_2, AVPacket *VAR_3)
{ AVFrame *frame     = VAR_1; const uint8_t *VAR_4 = VAR_3->VAR_1; int VAR_5 = VAR_3->size; int VAR_6; int VAR_7 = 0; int VAR_8, VAR_9; float  **VAR_10; DCAContext *s = VAR_0->priv_data; int VAR_11, VAR_12; int VAR_13; s->xch_present = 0; s->dca_buffer_size = ff_dca_convert_bitstream(VAR_4, VAR_5, s->dca_buffer,
DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE); if (s->dca_buffer_size == AVERROR_INVALIDDATA) { av_log(VAR_0, AV_LOG_ERROR, "Not a valid DCA frame\n"); return AVERROR_INVALIDDATA; } init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); if ((VAR_9 = dca_parse_frame_header(s)) < 0) { return VAR_9; } VAR_0->sample_rate = s->sample_rate; VAR_0->bit_rate    = s->bit_rate; s->profile = FF_PROFILE_DTS; for (VAR_8 = 0; VAR_8 < (s->sample_blocks / 8); VAR_8++) { if ((VAR_9 = dca_decode_block(s, 0, VAR_8))) { av_log(VAR_0, AV_LOG_ERROR, "error decoding block\n"); return VAR_9; } } VAR_7 = s->prim_channels; if (s->ext_coding)
s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr]; else
s->core_ext_mask = 0; VAR_13 = FFMIN(s->frame_size, s->dca_buffer_size) * 8; if (s->core_ext_mask < 0 || s->core_ext_mask & DCA_EXT_XCH) { s->core_ext_mask = FFMAX(s->core_ext_mask, 0); skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31); while (VAR_13 - get_bits_count(&s->gb) >= 32) { uint32_t bits = get_bits_long(&s->gb, 32); switch (bits) { case 0x5a5a5a5a: { int VAR_14, VAR_15; s->xch_base_channel = s->prim_channels; VAR_15 = show_bits(&s->gb, 10); if ((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + VAR_15) &&
(s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + VAR_15 + 1))
continue; skip_bits(&s->gb, 10); s->core_ext_mask |= DCA_EXT_XCH; if ((VAR_14 = get_bits(&s->gb, 4)) != 1) { av_log(VAR_0, AV_LOG_ERROR, "XCh extension amode %d not"
" supported!\n", VAR_14); continue; } dca_parse_audio_coding_header(s, s->xch_base_channel); for (VAR_8 = 0; VAR_8 < (s->sample_blocks / 8); VAR_8++) if ((VAR_9 = dca_decode_block(s, s->xch_base_channel, VAR_8))) { av_log(VAR_0, AV_LOG_ERROR, "error decoding XCh extension\n"); continue; } s->xch_present = 1; break; } case 0x47004a03:
s->core_ext_mask |= DCA_EXT_XXCH; break; case 0x1d95f262: { int VAR_16 = show_bits(&s->gb, 12) + 1; if (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + VAR_16)
continue; av_log(VAR_0, AV_LOG_DEBUG, "X96 extension found at %d bits\n",
get_bits_count(&s->gb)); skip_bits(&s->gb, 12); av_log(VAR_0, AV_LOG_DEBUG, "FSIZE96 = %d bytes\n", VAR_16); av_log(VAR_0, 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 { skip_bits_long(&s->gb, VAR_13 - 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; if (s->dca_buffer_size - s->frame_size > 32 &&
get_bits_long(&s->gb, 32) == DCA_HD_MARKER)
dca_exss_parse_header(s); VAR_0->profile = s->profile; VAR_12 = VAR_11 = s->prim_channels + !!s->lfe; if (s->amode < 16) { VAR_0->channel_layout = dca_core_channel_layout[s->amode]; if (s->prim_channels + !!s->lfe > 2 &&
VAR_0->request_channel_layout == AV_CH_LAYOUT_STEREO) { s->xch_disable = 1; } #if FF_API_REQUEST_CHANNELS
FF_DISABLE_DEPRECATION_WARNINGS
if (s->xch_present && !s->xch_disable &&
(!VAR_0->request_channels ||
VAR_0->request_channels > VAR_7 + !!s->lfe)) { FF_ENABLE_DEPRECATION_WARNINGS
#else
if (s->xch_present && !s->xch_disable) { #endif
VAR_0->channel_layout |= AV_CH_BACK_CENTER; if (s->lfe) { VAR_0->channel_layout |= AV_CH_LOW_FREQUENCY; s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode]; } else { s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode]; } } else { VAR_11 = VAR_7 + !!s->lfe; s->xch_present = 0; if (s->lfe) { VAR_0->channel_layout |= AV_CH_LOW_FREQUENCY; s->channel_order_tab = dca_channel_reorder_lfe[s->amode]; } else s->channel_order_tab = dca_channel_reorder_nolfe[s->amode]; } if (VAR_11 > !!s->lfe &&
s->channel_order_tab[VAR_11 - 1 - !!s->lfe] < 0)
return AVERROR_INVALIDDATA; if (s->prim_channels + !!s->lfe > 2 &&
VAR_0->request_channel_layout == AV_CH_LAYOUT_STEREO) { VAR_11 = 2; s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO; VAR_0->channel_layout = AV_CH_LAYOUT_STEREO; if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||
s->core_downmix_amode == DCA_STEREO_TOTAL)) { int VAR_17, VAR_18; for (VAR_8 = 0; VAR_8 < s->prim_channels + !!s->lfe; VAR_8++) { VAR_17 = s->core_downmix_codes[VAR_8][0] & 0x100 ? 1 : -1; VAR_18 = s->core_downmix_codes[VAR_8][0] & 0x0FF; s->downmix_coef[VAR_8][0] = (!VAR_18 ? 0.0f :
VAR_17 * dca_dmixtable[VAR_18 - 1]); VAR_17 = s->core_downmix_codes[VAR_8][1] & 0x100 ? 1 : -1; VAR_18 = s->core_downmix_codes[VAR_8][1] & 0x0FF; s->downmix_coef[VAR_8][1] = (!VAR_18 ? 0.0f :
VAR_17 * dca_dmixtable[VAR_18 - 1]); } s->output = s->core_downmix_amode; } else { int VAR_19 = s->amode & DCA_CHANNEL_MASK; if (VAR_19 >= FF_ARRAY_ELEMS(dca_default_coeffs)) { av_log(s->VAR_0, AV_LOG_ERROR,
"Invalid channel mode %d\n", VAR_19); return AVERROR_INVALIDDATA; } if (s->prim_channels + !!s->lfe >
FF_ARRAY_ELEMS(dca_default_coeffs[0])) { avpriv_request_sample(s->VAR_0, "Downmixing %d VAR_11",
s->prim_channels + !!s->lfe); return AVERROR_PATCHWELCOME; } for (VAR_8 = 0; VAR_8 < s->prim_channels + !!s->lfe; VAR_8++) { s->downmix_coef[VAR_8][0] = dca_default_coeffs[VAR_19][VAR_8][0]; s->downmix_coef[VAR_8][1] = dca_default_coeffs[VAR_19][VAR_8][1]; } } av_dlog(s->VAR_0, "Stereo downmix coeffs:\n"); for (VAR_8 = 0; VAR_8 < s->prim_channels + !!s->lfe; VAR_8++) { av_dlog(s->VAR_0, "L, input channel %d = %f\n", VAR_8,
s->downmix_coef[VAR_8][0]); av_dlog(s->VAR_0, "R, input channel %d = %f\n", VAR_8,
s->downmix_coef[VAR_8][1]); } av_dlog(s->VAR_0, "\n"); } } else { av_log(VAR_0, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode); return AVERROR_INVALIDDATA; } VAR_0->VAR_11 = VAR_11; frame->nb_samples = 256 * (s->sample_blocks / 8); if ((VAR_9 = ff_get_buffer(VAR_0, frame, 0)) < 0) { av_log(VAR_0, AV_LOG_ERROR, "get_buffer() failed\n"); return VAR_9; } VAR_10 = (float **)frame->extended_data; if (VAR_0->VAR_11 < VAR_12) { VAR_9 = av_samples_get_buffer_size(NULL, VAR_12 - VAR_11,
frame->nb_samples,
VAR_0->sample_fmt, 0); if (VAR_9 < 0)
return VAR_9; av_fast_malloc(&s->extra_channels_buffer,
&s->extra_channels_buffer_size, VAR_9); if (!s->extra_channels_buffer)
return AVERROR(ENOMEM); VAR_9 = av_samples_fill_arrays((uint8_t **)s->extra_channels, NULL,
s->extra_channels_buffer,
VAR_12 - VAR_11,
frame->nb_samples, VAR_0->sample_fmt, 0); if (VAR_9 < 0)
return VAR_9; } for (VAR_8 = 0; VAR_8 < (s->sample_blocks / 8); VAR_8++) { int ch; for (ch = 0; ch < VAR_11; ch++) s->samples_chanptr[ch] = VAR_10[ch] + VAR_8 * 256; for (; ch < VAR_12; ch++) s->samples_chanptr[ch] = s->extra_channels[ch - VAR_11] + VAR_8 * 256; dca_filter_channels(s, VAR_8); if ((s->source_pcm_res & 1) && s->xch_present) { float *back_chan = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel]]; float *lt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 2]]; float *rt_chan   = s->samples_chanptr[s->channel_order_tab[s->xch_base_channel - 1]]; s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256); s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256); } } VAR_6 = 2 * s->lfe * (s->sample_blocks / 8); for (VAR_8 = 0; VAR_8 < 2 * s->lfe * 4; VAR_8++) s->lfe_data[VAR_8] = s->lfe_data[VAR_8 + VAR_6]; VAR_9 = ff_side_data_update_matrix_encoding(frame,
(s->output & ~DCA_LFE) == DCA_STEREO_TOTAL ?
AV_MATRIX_ENCODING_DOLBY : AV_MATRIX_ENCODING_NONE); if (VAR_9 < 0)
return VAR_9; *VAR_2 = 1; return VAR_5; }