⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlpdec.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        return -1;    }    m->access_unit_size      = mh.access_unit_size;    m->access_unit_size_pow2 = mh.access_unit_size_pow2;    m->num_substreams        = mh.num_substreams;    m->max_decoded_substream = m->num_substreams - 1;    m->avctx->sample_rate    = mh.group1_samplerate;    m->avctx->frame_size     = mh.access_unit_size;#ifdef CONFIG_AUDIO_NONSHORT    m->avctx->bits_per_sample = mh.group1_bits;    if (mh.group1_bits > 16) {        m->avctx->sample_fmt = SAMPLE_FMT_S32;    }#endif    m->params_valid = 1;    for (substr = 0; substr < MAX_SUBSTREAMS; substr++)        m->substream[substr].restart_seen = 0;    return 0;}/** Read a restart header from a block in a substream. This contains parameters *  required to decode the audio that do not change very often. Generally *  (always) present only in blocks following a major sync. */static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,                               const uint8_t *buf, unsigned int substr){    SubStream *s = &m->substream[substr];    unsigned int ch;    int sync_word, tmp;    uint8_t checksum;    uint8_t lossless_check;    int start_count = get_bits_count(gbp);    sync_word = get_bits(gbp, 13);    if (sync_word != 0x31ea >> 1) {        av_log(m->avctx, AV_LOG_ERROR,               "restart header sync incorrect (got 0x%04x)\n", sync_word);        return -1;    }    s->noise_type = get_bits1(gbp);    skip_bits(gbp, 16); /* Output timestamp */    s->min_channel        = get_bits(gbp, 4);    s->max_channel        = get_bits(gbp, 4);    s->max_matrix_channel = get_bits(gbp, 4);    if (s->min_channel > s->max_channel) {        av_log(m->avctx, AV_LOG_ERROR,               "Substream min channel cannot be greater than max channel.\n");        return -1;    }    if (m->avctx->request_channels > 0        && s->max_channel + 1 >= m->avctx->request_channels        && substr < m->max_decoded_substream) {        av_log(m->avctx, AV_LOG_INFO,               "Extracting %d channel downmix from substream %d. "               "Further substreams will be skipped.\n",               s->max_channel + 1, substr);        m->max_decoded_substream = substr;    }    s->noise_shift   = get_bits(gbp,  4);    s->noisegen_seed = get_bits(gbp, 23);    skip_bits(gbp, 19);    s->data_check_present = get_bits1(gbp);    lossless_check = get_bits(gbp, 8);    if (substr == m->max_decoded_substream        && s->lossless_check_data != 0xffffffff) {        tmp = s->lossless_check_data;        tmp ^= tmp >> 16;        tmp ^= tmp >> 8;        tmp &= 0xff;        if (tmp != lossless_check)            av_log(m->avctx, AV_LOG_WARNING,                   "Lossless check failed - expected %02x, calculated %02x.\n",                   lossless_check, tmp);        else            dprintf(m->avctx, "Lossless check passed for substream %d (%x).\n",                    substr, tmp);    }    skip_bits(gbp, 16);    for (ch = 0; ch <= s->max_matrix_channel; ch++) {        int ch_assign = get_bits(gbp, 6);        dprintf(m->avctx, "ch_assign[%d][%d] = %d\n", substr, ch,                ch_assign);        if (ch_assign != ch) {            av_log(m->avctx, AV_LOG_ERROR,                   "Non-1:1 channel assignments are used in this stream. %s\n",                   sample_message);            return -1;        }    }    checksum = mlp_restart_checksum(buf, get_bits_count(gbp) - start_count);    if (checksum != get_bits(gbp, 8))        av_log(m->avctx, AV_LOG_ERROR, "restart header checksum error\n");    /* Set default decoding parameters. */    s->param_presence_flags   = 0xff;    s->num_primitive_matrices = 0;    s->blocksize              = 8;    s->lossless_check_data    = 0;    memset(s->output_shift   , 0, sizeof(s->output_shift   ));    memset(s->quant_step_size, 0, sizeof(s->quant_step_size));    for (ch = s->min_channel; ch <= s->max_channel; ch++) {        m->filter_order[ch][FIR] = 0;        m->filter_order[ch][IIR] = 0;        m->filter_shift[ch][FIR] = 0;        m->filter_shift[ch][IIR] = 0;        /* Default audio coding is 24-bit raw PCM. */        m->huff_offset     [ch] = 0;        m->sign_huff_offset[ch] = (-1) << 23;        m->codebook        [ch] = 0;        m->huff_lsbs       [ch] = 24;    }    if (substr == m->max_decoded_substream) {        m->avctx->channels = s->max_channel + 1;    }    return 0;}/** Read parameters for one of the prediction filters. */static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,                              unsigned int channel, unsigned int filter){    const char fchar = filter ? 'I' : 'F';    int i, order;    // Filter is 0 for FIR, 1 for IIR.    assert(filter < 2);    order = get_bits(gbp, 4);    if (order > MAX_FILTER_ORDER) {        av_log(m->avctx, AV_LOG_ERROR,               "%cIR filter order %d is greater than maximum %d.\n",               fchar, order, MAX_FILTER_ORDER);        return -1;    }    m->filter_order[channel][filter] = order;    if (order > 0) {        int coeff_bits, coeff_shift;        m->filter_shift[channel][filter] = get_bits(gbp, 4);        coeff_bits  = get_bits(gbp, 5);        coeff_shift = get_bits(gbp, 3);        if (coeff_bits < 1 || coeff_bits > 16) {            av_log(m->avctx, AV_LOG_ERROR,                   "%cIR filter coeff_bits must be between 1 and 16.\n",                   fchar);            return -1;        }        if (coeff_bits + coeff_shift > 16) {            av_log(m->avctx, AV_LOG_ERROR,                   "Sum of coeff_bits and coeff_shift for %cIR filter must be 16 or less.\n",                   fchar);            return -1;        }        for (i = 0; i < order; i++)            m->filter_coeff[channel][filter][i] =                    get_sbits(gbp, coeff_bits) << coeff_shift;        if (get_bits1(gbp)) {            int state_bits, state_shift;            if (filter == FIR) {                av_log(m->avctx, AV_LOG_ERROR,                       "FIR filter has state data specified.\n");                return -1;            }            state_bits  = get_bits(gbp, 4);            state_shift = get_bits(gbp, 4);            /* TODO: Check validity of state data. */            for (i = 0; i < order; i++)                m->filter_state[channel][filter][i] =                    get_sbits(gbp, state_bits) << state_shift;        }    }    return 0;}/** Read decoding parameters that change more often than those in the restart *  header. */static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,                                unsigned int substr){    SubStream *s = &m->substream[substr];    unsigned int mat, ch;    if (get_bits1(gbp))        s->param_presence_flags = get_bits(gbp, 8);    if (s->param_presence_flags & PARAM_BLOCKSIZE)        if (get_bits1(gbp)) {            s->blocksize = get_bits(gbp, 9);            if (s->blocksize > MAX_BLOCKSIZE) {                av_log(m->avctx, AV_LOG_ERROR, "block size too large\n");                s->blocksize = 0;                return -1;            }        }    if (s->param_presence_flags & PARAM_MATRIX)        if (get_bits1(gbp)) {            s->num_primitive_matrices = get_bits(gbp, 4);            for (mat = 0; mat < s->num_primitive_matrices; mat++) {                int frac_bits, max_chan;                s->matrix_out_ch[mat] = get_bits(gbp, 4);                frac_bits             = get_bits(gbp, 4);                s->lsb_bypass   [mat] = get_bits1(gbp);                if (s->matrix_out_ch[mat] > s->max_channel) {                    av_log(m->avctx, AV_LOG_ERROR,                           "Invalid channel %d specified as output from matrix.\n",                           s->matrix_out_ch[mat]);                    return -1;                }                if (frac_bits > 14) {                    av_log(m->avctx, AV_LOG_ERROR,                           "Too many fractional bits specified.\n");                    return -1;                }                max_chan = s->max_matrix_channel;                if (!s->noise_type)                    max_chan+=2;                for (ch = 0; ch <= max_chan; ch++) {                    int coeff_val = 0;                    if (get_bits1(gbp))                        coeff_val = get_sbits(gbp, frac_bits + 2);                    s->matrix_coeff[mat][ch] = coeff_val << (14 - frac_bits);                }                if (s->noise_type)                    s->matrix_noise_shift[mat] = get_bits(gbp, 4);                else                    s->matrix_noise_shift[mat] = 0;            }        }    if (s->param_presence_flags & PARAM_OUTSHIFT)        if (get_bits1(gbp))            for (ch = 0; ch <= s->max_matrix_channel; ch++) {                s->output_shift[ch] = get_bits(gbp, 4);                dprintf(m->avctx, "output shift[%d] = %d\n",                        ch, s->output_shift[ch]);                /* TODO: validate */            }    if (s->param_presence_flags & PARAM_QUANTSTEP)        if (get_bits1(gbp))            for (ch = 0; ch <= s->max_channel; ch++) {                s->quant_step_size[ch] = get_bits(gbp, 4);                /* TODO: validate */                m->sign_huff_offset[ch] = calculate_sign_huff(m, substr, ch);            }    for (ch = s->min_channel; ch <= s->max_channel; ch++)        if (get_bits1(gbp)) {            if (s->param_presence_flags & PARAM_FIR)                if (get_bits1(gbp))                    if (read_filter_params(m, gbp, ch, FIR) < 0)                        return -1;            if (s->param_presence_flags & PARAM_IIR)                if (get_bits1(gbp))                    if (read_filter_params(m, gbp, ch, IIR) < 0)                        return -1;            if (m->filter_order[ch][FIR] && m->filter_order[ch][IIR] &&                m->filter_shift[ch][FIR] != m->filter_shift[ch][IIR]) {                av_log(m->avctx, AV_LOG_ERROR,                       "FIR and IIR filters must use the same precision.\n");                return -1;            }            /* The FIR and IIR filters must have the same precision.             * To simplify the filtering code, only the precision of the             * FIR filter is considered. If only the IIR filter is employed,             * the FIR filter precision is set to that of the IIR filter, so             * that the filtering code can use it. */            if (!m->filter_order[ch][FIR] && m->filter_order[ch][IIR])                m->filter_shift[ch][FIR] = m->filter_shift[ch][IIR];            if (s->param_presence_flags & PARAM_HUFFOFFSET)                if (get_bits1(gbp))                    m->huff_offset[ch] = get_sbits(gbp, 15);            m->codebook [ch] = get_bits(gbp, 2);            m->huff_lsbs[ch] = get_bits(gbp, 5);            m->sign_huff_offset[ch] = calculate_sign_huff(m, substr, ch);            /* TODO: validate */        }    return 0;}#define MSB_MASK(bits)  (-1u << bits)/** Generate PCM samples using the prediction filters and residual values *  read from the data stream, and update the filter state. */static void filter_channel(MLPDecodeContext *m, unsigned int substr,                           unsigned int channel){    SubStream *s = &m->substream[substr];    int32_t filter_state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FILTER_ORDER];    unsigned int filter_shift = m->filter_shift[channel][FIR];    int32_t mask = MSB_MASK(s->quant_step_size[channel]);    int index = MAX_BLOCKSIZE;    int j, i;    for (j = 0; j < NUM_FILTERS; j++) {        memcpy(&   filter_state_buffer  [j][MAX_BLOCKSIZE],               &m->filter_state[channel][j][0],               MAX_FILTER_ORDER * sizeof(int32_t));    }    for (i = 0; i < s->blocksize; i++) {        int32_t residual = m->sample_buffer[i + s->blockpos][channel];        unsigned int order;        int64_t accum = 0;        int32_t result;        /* TODO: Move this code to DSPContext? */        for (j = 0; j < NUM_FILTERS; j++)            for (order = 0; order < m->filter_order[channel][j]; order++)                accum += (int64_t)filter_state_buffer[j][index + order] *                        m->filter_coeff[channel][j][order];        accum  = accum >> filter_shift;        result = (accum + residual) & mask;        --index;        filter_state_buffer[FIR][index] = result;        filter_state_buffer[IIR][index] = result - accum;        m->sample_buffer[i + s->blockpos][channel] = result;    }    for (j = 0; j < NUM_FILTERS; j++) {        memcpy(&m->filter_state[channel][j][0],               &   filter_state_buffer  [j][index],               MAX_FILTER_ORDER * sizeof(int32_t));    }}/** Read a block of PCM residual data (or actual if no filtering active). */static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp,                           unsigned int substr){    SubStream *s = &m->substream[substr];    unsigned int i, ch, expected_stream_pos = 0;    if (s->data_check_present) {        expected_stream_pos  = get_bits_count(gbp);        expected_stream_pos += get_bits(gbp, 16);        av_log(m->avctx, AV_LOG_WARNING, "This file contains some features "               "we have not tested yet. %s\n", sample_message);    }    if (s->blockpos + s->blocksize > m->access_unit_size) {        av_log(m->avctx, AV_LOG_ERROR, "too many audio samples in frame\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -