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

📄 shorten.c

📁 ffmpeg的完整源代码和作者自己写的文档。不但有在Linux的工程哦
💻 C
📖 第 1 页 / 共 2 页
字号:
static int shorten_decode_frame(AVCodecContext *avctx,
        void *data, int *data_size,
        uint8_t *buf, int buf_size)
{
    ShortenContext *s = avctx->priv_data;
    int i, input_buf_size = 0;
    int16_t *samples = data;
    if(s->max_framesize == 0){
        s->max_framesize= 1024; // should hopefully be enough for the first header
        s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize);
    }

    if(1 && s->max_framesize){//FIXME truncated
        buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size);
        input_buf_size= buf_size;

        if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){
            //                printf("memmove\n");
            memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
            s->bitstream_index=0;
        }
        memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size);
        buf= &s->bitstream[s->bitstream_index];
        buf_size += s->bitstream_size;
        s->bitstream_size= buf_size;

        if(buf_size < s->max_framesize){
            //dprintf(avctx, "wanna more data ... %d\n", buf_size);
            *data_size = 0;
            return input_buf_size;
        }
    }
    init_get_bits(&s->gb, buf, buf_size*8);
    skip_bits(&s->gb, s->bitindex);
    if (!s->blocksize)
    {
        int maxnlpc = 0;
        /* shorten signature */
        if (get_bits_long(&s->gb, 32) != bswap_32(ff_get_fourcc("ajkg"))) {
            av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
            return -1;
        }

        s->lpcqoffset = 0;
        s->blocksize = DEFAULT_BLOCK_SIZE;
        s->channels = 1;
        s->nmean = -1;
        s->version = get_bits(&s->gb, 8);
        s->internal_ftype = get_uint(s, TYPESIZE);

        s->channels = get_uint(s, CHANSIZE);
        if (s->channels > MAX_CHANNELS) {
            av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
            return -1;
        }

        /* get blocksize if version > 0 */
        if (s->version > 0) {
            int skip_bytes;
            s->blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
            maxnlpc = get_uint(s, LPCQSIZE);
            s->nmean = get_uint(s, 0);

            skip_bytes = get_uint(s, NSKIPSIZE);
            for (i=0; i<skip_bytes; i++) {
                skip_bits(&s->gb, 8);
            }
        }
        s->nwrap = FFMAX(NWRAP, maxnlpc);

        if (allocate_buffers(s))
            return -1;

        init_offset(s);

        if (s->version > 1)
            s->lpcqoffset = V2LPCQOFFSET;

        if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
            av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at begining of stream\n");
            return -1;
        }

        s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
        if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) {
            av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size);
            return -1;
        }

        for (i=0; i<s->header_size; i++)
            s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);

        if (decode_wave_header(avctx, s->header, s->header_size) < 0)
            return -1;

        s->cur_chan = 0;
        s->bitshift = 0;
    }
    else
    {
        int cmd;
        int len;
        cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
        switch (cmd) {
            case FN_ZERO:
            case FN_DIFF0:
            case FN_DIFF1:
            case FN_DIFF2:
            case FN_DIFF3:
            case FN_QLPC:
                {
                    int residual_size = 0;
                    int channel = s->cur_chan;
                    int32_t coffset;
                    if (cmd != FN_ZERO) {
                        residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
                        /* this is a hack as version 0 differed in defintion of get_sr_golomb_shorten */
                        if (s->version == 0)
                            residual_size--;
                    }

                    if (s->nmean == 0)
                        coffset = s->offset[channel][0];
                    else {
                        int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
                        for (i=0; i<s->nmean; i++)
                            sum += s->offset[channel][i];
                        coffset = sum / s->nmean;
                        if (s->version >= 2)
                            coffset >>= FFMIN(1, s->bitshift);
                    }
                    switch (cmd) {
                        case FN_ZERO:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = 0;
                            break;
                        case FN_DIFF0:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + coffset;
                            break;
                        case FN_DIFF1:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + s->decoded[channel][i - 1];
                            break;
                        case FN_DIFF2:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 2*s->decoded[channel][i-1]
                                                                                                      -   s->decoded[channel][i-2];
                            break;
                        case FN_DIFF3:
                            for (i=0; i<s->blocksize; i++)
                                s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + 3*s->decoded[channel][i-1]
                                                                                                      - 3*s->decoded[channel][i-2]
                                                                                                      +   s->decoded[channel][i-3];
                            break;
                        case FN_QLPC:
                            {
                                int pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
                                for (i=0; i<pred_order; i++)
                                    s->decoded[channel][i - pred_order] -= coffset;
                                decode_subframe_lpc(s, channel, residual_size, pred_order);
                                if (coffset != 0)
                                    for (i=0; i < s->blocksize; i++)
                                        s->decoded[channel][i] += coffset;
                            }
                    }
                    if (s->nmean > 0) {
                        int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
                        for (i=0; i<s->blocksize; i++)
                            sum += s->decoded[channel][i];

                        for (i=1; i<s->nmean; i++)
                            s->offset[channel][i-1] = s->offset[channel][i];

                        if (s->version < 2)
                            s->offset[channel][s->nmean - 1] = sum / s->blocksize;
                        else
                            s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
                    }
                    for (i=-s->nwrap; i<0; i++)
                        s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];

                    fix_bitshift(s, s->decoded[channel]);

                    s->cur_chan++;
                    if (s->cur_chan == s->channels) {
                        samples = interleave_buffer(samples, s->channels, s->blocksize, s->decoded);
                        s->cur_chan = 0;
                        goto frame_done;
                    }
                    break;
                }
                break;
            case FN_VERBATIM:
                len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
                while (len--) {
                    get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
                }
                break;
            case FN_BITSHIFT:
                s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
                break;
            case FN_BLOCKSIZE:
                s->blocksize = get_uint(s, av_log2(s->blocksize));
                break;
            case FN_QUIT:
                *data_size = 0;
                return buf_size;
                break;
            default:
                av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
                return -1;
                break;
        }
    }
frame_done:
    *data_size = (int8_t *)samples - (int8_t *)data;

    //    s->last_blocksize = s->blocksize;
    s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8);
    i= (get_bits_count(&s->gb))/8;
    if (i > buf_size) {
        av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);
        s->bitstream_size=0;
        s->bitstream_index=0;
        return -1;
    }
    if (s->bitstream_size) {
        s->bitstream_index += i;
        s->bitstream_size  -= i;
        return input_buf_size;
    } else
        return i;
}

static int shorten_decode_close(AVCodecContext *avctx)
{
    ShortenContext *s = avctx->priv_data;
    int i;

    for (i = 0; i < s->channels; i++) {
        s->decoded[i] -= s->nwrap;
        av_freep(&s->decoded[i]);
        av_freep(&s->offset[i]);
    }
    av_freep(&s->bitstream);
    return 0;
}

static void shorten_flush(AVCodecContext *avctx){
    ShortenContext *s = avctx->priv_data;

    s->bitstream_size=
        s->bitstream_index= 0;
}

AVCodec shorten_decoder = {
    "shorten",
    CODEC_TYPE_AUDIO,
    CODEC_ID_SHORTEN,
    sizeof(ShortenContext),
    shorten_decode_init,
    NULL,
    shorten_decode_close,
    shorten_decode_frame,
    .flush= shorten_flush,
};

⌨️ 快捷键说明

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