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

📄 mlpdec.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        return -1;    }    memset(&m->bypassed_lsbs[s->blockpos][0], 0,           s->blocksize * sizeof(m->bypassed_lsbs[0]));    for (i = 0; i < s->blocksize; i++) {        if (read_huff_channels(m, gbp, substr, i) < 0)            return -1;    }    for (ch = s->min_channel; ch <= s->max_channel; ch++) {        filter_channel(m, substr, ch);    }    s->blockpos += s->blocksize;    if (s->data_check_present) {        if (get_bits_count(gbp) != expected_stream_pos)            av_log(m->avctx, AV_LOG_ERROR, "block data length mismatch\n");        skip_bits(gbp, 8);    }    return 0;}/** Data table used for TrueHD noise generation function. */static const int8_t noise_table[256] = {     30,  51,  22,  54,   3,   7,  -4,  38,  14,  55,  46,  81,  22,  58,  -3,   2,     52,  31,  -7,  51,  15,  44,  74,  30,  85, -17,  10,  33,  18,  80,  28,  62,     10,  32,  23,  69,  72,  26,  35,  17,  73,  60,   8,  56,   2,   6,  -2,  -5,     51,   4,  11,  50,  66,  76,  21,  44,  33,  47,   1,  26,  64,  48,  57,  40,     38,  16, -10, -28,  92,  22, -18,  29, -10,   5, -13,  49,  19,  24,  70,  34,     61,  48,  30,  14,  -6,  25,  58,  33,  42,  60,  67,  17,  54,  17,  22,  30,     67,  44,  -9,  50, -11,  43,  40,  32,  59,  82,  13,  49, -14,  55,  60,  36,     48,  49,  31,  47,  15,  12,   4,  65,   1,  23,  29,  39,  45,  -2,  84,  69,      0,  72,  37,  57,  27,  41, -15, -16,  35,  31,  14,  61,  24,   0,  27,  24,     16,  41,  55,  34,  53,   9,  56,  12,  25,  29,  53,   5,  20, -20,  -8,  20,     13,  28,  -3,  78,  38,  16,  11,  62,  46,  29,  21,  24,  46,  65,  43, -23,     89,  18,  74,  21,  38, -12,  19,  12, -19,   8,  15,  33,   4,  57,   9,  -8,     36,  35,  26,  28,   7,  83,  63,  79,  75,  11,   3,  87,  37,  47,  34,  40,     39,  19,  20,  42,  27,  34,  39,  77,  13,  42,  59,  64,  45,  -1,  32,  37,     45,  -5,  53,  -6,   7,  36,  50,  23,   6,  32,   9, -21,  18,  71,  27,  52,    -25,  31,  35,  42,  -1,  68,  63,  52,  26,  43,  66,  37,  41,  25,  40,  70,};/** Noise generation functions. *  I'm not sure what these are for - they seem to be some kind of pseudorandom *  sequence generators, used to generate noise data which is used when the *  channels are rematrixed. I'm not sure if they provide a practical benefit *  to compression, or just obfuscate the decoder. Are they for some kind of *  dithering? *//** Generate two channels of noise, used in the matrix when *  restart sync word == 0x31ea. */static void generate_2_noise_channels(MLPDecodeContext *m, unsigned int substr){    SubStream *s = &m->substream[substr];    unsigned int i;    uint32_t seed = s->noisegen_seed;    unsigned int maxchan = s->max_matrix_channel;    for (i = 0; i < s->blockpos; i++) {        uint16_t seed_shr7 = seed >> 7;        m->sample_buffer[i][maxchan+1] = ((int8_t)(seed >> 15)) << s->noise_shift;        m->sample_buffer[i][maxchan+2] = ((int8_t) seed_shr7)   << s->noise_shift;        seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5);    }    s->noisegen_seed = seed;}/** Generate a block of noise, used when restart sync word == 0x31eb. */static void fill_noise_buffer(MLPDecodeContext *m, unsigned int substr){    SubStream *s = &m->substream[substr];    unsigned int i;    uint32_t seed = s->noisegen_seed;    for (i = 0; i < m->access_unit_size_pow2; i++) {        uint8_t seed_shr15 = seed >> 15;        m->noise_buffer[i] = noise_table[seed_shr15];        seed = (seed << 8) ^ seed_shr15 ^ (seed_shr15 << 5);    }    s->noisegen_seed = seed;}/** Apply the channel matrices in turn to reconstruct the original audio *  samples. */static void rematrix_channels(MLPDecodeContext *m, unsigned int substr){    SubStream *s = &m->substream[substr];    unsigned int mat, src_ch, i;    unsigned int maxchan;    maxchan = s->max_matrix_channel;    if (!s->noise_type) {        generate_2_noise_channels(m, substr);        maxchan += 2;    } else {        fill_noise_buffer(m, substr);    }    for (mat = 0; mat < s->num_primitive_matrices; mat++) {        int matrix_noise_shift = s->matrix_noise_shift[mat];        unsigned int dest_ch = s->matrix_out_ch[mat];        int32_t mask = MSB_MASK(s->quant_step_size[dest_ch]);        /* TODO: DSPContext? */        for (i = 0; i < s->blockpos; i++) {            int64_t accum = 0;            for (src_ch = 0; src_ch <= maxchan; src_ch++) {                accum += (int64_t)m->sample_buffer[i][src_ch]                                  * s->matrix_coeff[mat][src_ch];            }            if (matrix_noise_shift) {                uint32_t index = s->num_primitive_matrices - mat;                index = (i * (index * 2 + 1) + index) & (m->access_unit_size_pow2 - 1);                accum += m->noise_buffer[index] << (matrix_noise_shift + 7);            }            m->sample_buffer[i][dest_ch] = ((accum >> 14) & mask)                                             + m->bypassed_lsbs[i][mat];        }    }}/** Write the audio data into the output buffer. */static int output_data_internal(MLPDecodeContext *m, unsigned int substr,                                uint8_t *data, unsigned int *data_size, int is32){    SubStream *s = &m->substream[substr];    unsigned int i, ch = 0;    int32_t *data_32 = (int32_t*) data;    int16_t *data_16 = (int16_t*) data;    if (*data_size < (s->max_channel + 1) * s->blockpos * (is32 ? 4 : 2))        return -1;    for (i = 0; i < s->blockpos; i++) {        for (ch = 0; ch <= s->max_channel; ch++) {            int32_t sample = m->sample_buffer[i][ch] << s->output_shift[ch];            s->lossless_check_data ^= (sample & 0xffffff) << ch;            if (is32) *data_32++ = sample << 8;            else      *data_16++ = sample >> 8;        }    }    *data_size = i * ch * (is32 ? 4 : 2);    return 0;}static int output_data(MLPDecodeContext *m, unsigned int substr,                       uint8_t *data, unsigned int *data_size){    if (m->avctx->sample_fmt == SAMPLE_FMT_S32)        return output_data_internal(m, substr, data, data_size, 1);    else        return output_data_internal(m, substr, data, data_size, 0);}/** XOR together all the bytes of a buffer. *  Does this belong in dspcontext? */static uint8_t calculate_parity(const uint8_t *buf, unsigned int buf_size){    uint32_t scratch = 0;    const uint8_t *buf_end = buf + buf_size;    for (; buf < buf_end - 3; buf += 4)        scratch ^= *((const uint32_t*)buf);    scratch ^= scratch >> 16;    scratch ^= scratch >> 8;    for (; buf < buf_end; buf++)        scratch ^= *buf;    return scratch;}/** Read an access unit from the stream. *  Returns < 0 on error, 0 if not enough data is present in the input stream *  otherwise returns the number of bytes consumed. */static int read_access_unit(AVCodecContext *avctx, void* data, int *data_size,                            const uint8_t *buf, int buf_size){    MLPDecodeContext *m = avctx->priv_data;    GetBitContext gb;    unsigned int length, substr;    unsigned int substream_start;    unsigned int header_size = 4;    unsigned int substr_header_size = 0;    uint8_t substream_parity_present[MAX_SUBSTREAMS];    uint16_t substream_data_len[MAX_SUBSTREAMS];    uint8_t parity_bits;    if (buf_size < 4)        return 0;    length = (AV_RB16(buf) & 0xfff) * 2;    if (length > buf_size)        return -1;    init_get_bits(&gb, (buf + 4), (length - 4) * 8);    if (show_bits_long(&gb, 31) == (0xf8726fba >> 1)) {        dprintf(m->avctx, "Found major sync.\n");        if (read_major_sync(m, &gb) < 0)            goto error;        header_size += 28;    }    if (!m->params_valid) {        av_log(m->avctx, AV_LOG_WARNING,               "Stream parameters not seen; skipping frame.\n");        *data_size = 0;        return length;    }    substream_start = 0;    for (substr = 0; substr < m->num_substreams; substr++) {        int extraword_present, checkdata_present, end;        extraword_present = get_bits1(&gb);        skip_bits1(&gb);        checkdata_present = get_bits1(&gb);        skip_bits1(&gb);        end = get_bits(&gb, 12) * 2;        substr_header_size += 2;        if (extraword_present) {            skip_bits(&gb, 16);            substr_header_size += 2;        }        if (end + header_size + substr_header_size > length) {            av_log(m->avctx, AV_LOG_ERROR,                   "Indicated length of substream %d data goes off end of "                   "packet.\n", substr);            end = length - header_size - substr_header_size;        }        if (end < substream_start) {            av_log(avctx, AV_LOG_ERROR,                   "Indicated end offset of substream %d data "                   "is smaller than calculated start offset.\n",                   substr);            goto error;        }        if (substr > m->max_decoded_substream)            continue;        substream_parity_present[substr] = checkdata_present;        substream_data_len[substr] = end - substream_start;        substream_start = end;    }    parity_bits  = calculate_parity(buf, 4);    parity_bits ^= calculate_parity(buf + header_size, substr_header_size);    if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {        av_log(avctx, AV_LOG_ERROR, "Parity check failed.\n");        goto error;    }    buf += header_size + substr_header_size;    for (substr = 0; substr <= m->max_decoded_substream; substr++) {        SubStream *s = &m->substream[substr];        init_get_bits(&gb, buf, substream_data_len[substr] * 8);        s->blockpos = 0;        do {            if (get_bits1(&gb)) {                if (get_bits1(&gb)) {                    /* A restart header should be present. */                    if (read_restart_header(m, &gb, buf, substr) < 0)                        goto next_substr;                    s->restart_seen = 1;                }                if (!s->restart_seen) {                    av_log(m->avctx, AV_LOG_ERROR,                           "No restart header present in substream %d.\n",                           substr);                    goto next_substr;                }                if (read_decoding_params(m, &gb, substr) < 0)                    goto next_substr;            }            if (!s->restart_seen) {                av_log(m->avctx, AV_LOG_ERROR,                       "No restart header present in substream %d.\n",                       substr);                goto next_substr;            }            if (read_block_data(m, &gb, substr) < 0)                return -1;        } while ((get_bits_count(&gb) < substream_data_len[substr] * 8)                 && get_bits1(&gb) == 0);        skip_bits(&gb, (-get_bits_count(&gb)) & 15);        if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 32 &&            (show_bits_long(&gb, 32) == 0xd234d234 ||             show_bits_long(&gb, 20) == 0xd234e)) {            skip_bits(&gb, 18);            if (substr == m->max_decoded_substream)                av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n");            if (get_bits1(&gb)) {                int shorten_by = get_bits(&gb, 13);                shorten_by = FFMIN(shorten_by, s->blockpos);                s->blockpos -= shorten_by;            } else                skip_bits(&gb, 13);        }        if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 16 &&            substream_parity_present[substr]) {            uint8_t parity, checksum;            parity = calculate_parity(buf, substream_data_len[substr] - 2);            if ((parity ^ get_bits(&gb, 8)) != 0xa9)                av_log(m->avctx, AV_LOG_ERROR,                       "Substream %d parity check failed.\n", substr);            checksum = mlp_checksum8(buf, substream_data_len[substr] - 2);            if (checksum != get_bits(&gb, 8))                av_log(m->avctx, AV_LOG_ERROR, "Substream %d checksum failed.\n",                       substr);        }        if (substream_data_len[substr] * 8 != get_bits_count(&gb)) {            av_log(m->avctx, AV_LOG_ERROR, "substream %d length mismatch\n",                   substr);            return -1;        }next_substr:        buf += substream_data_len[substr];    }    rematrix_channels(m, m->max_decoded_substream);#ifdef __CW32__    if (output_data(m, m->max_decoded_substream, data, (unsigned int*)data_size) < 0)#else    if (output_data(m, m->max_decoded_substream, data, data_size) < 0)#endif        return -1;    return length;error:    m->params_valid = 0;    return -1;}AVCodec mlp_decoder = {    "mlp",    CODEC_TYPE_AUDIO,    CODEC_ID_MLP,    sizeof(MLPDecodeContext),    mlp_decode_init,    NULL,    NULL,    read_access_unit,#ifdef __CW32__    0,    0,    0,    0,    0,    NULL_IF_CONFIG_SMALL("Meridian Lossless Packing"),#else    .long_name = NULL_IF_CONFIG_SMALL("Meridian Lossless Packing"),#endif};

⌨️ 快捷键说明

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