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

📄 flac.c

📁 arm平台下的H264编码和解码源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        av_log(s->avctx, AV_LOG_DEBUG, "%d wasted bits\n", wasted);    }#endif//FIXME use av_log2 for types    if (type == 0)    {        av_log(s->avctx, AV_LOG_DEBUG, "coding type: constant\n");        tmp = get_sbits(&s->gb, s->curr_bps);        for (i = 0; i < s->blocksize; i++)            s->decoded[channel][i] = tmp;    }    else if (type == 1)    {        av_log(s->avctx, AV_LOG_DEBUG, "coding type: verbatim\n");        for (i = 0; i < s->blocksize; i++)            s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps);    }    else if ((type >= 8) && (type <= 12))    {//        av_log(s->avctx, AV_LOG_DEBUG, "coding type: fixed\n");        if (decode_subframe_fixed(s, channel, type & ~0x8) < 0)            return -1;    }    else if (type >= 32)    {//        av_log(s->avctx, AV_LOG_DEBUG, "coding type: lpc\n");        if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0)            return -1;    }    else    {        av_log(s->avctx, AV_LOG_DEBUG, "invalid coding type\n");        return -1;    }            if (wasted)    {        int i;        for (i = 0; i < s->blocksize; i++)            s->decoded[channel][i] <<= wasted;    }    return 0;}static int decode_frame(FLACContext *s){    int blocksize_code, sample_rate_code, sample_size_code, assignment, i, crc8;    int decorrelation, bps, blocksize, samplerate;        blocksize_code = get_bits(&s->gb, 4);    sample_rate_code = get_bits(&s->gb, 4);        assignment = get_bits(&s->gb, 4); /* channel assignment */    if (assignment < 8 && s->channels == assignment+1)        decorrelation = INDEPENDENT;    else if (assignment >=8 && assignment < 11 && s->channels == 2)        decorrelation = LEFT_SIDE + assignment - 8;    else    {        av_log(s->avctx, AV_LOG_DEBUG, "unsupported channel assignment %d (channels=%d)\n", assignment, s->channels);        return -1;    }            sample_size_code = get_bits(&s->gb, 3);    if(sample_size_code == 0)        bps= s->bps;    else if((sample_size_code != 3) && (sample_size_code != 7))        bps = sample_size_table[sample_size_code];    else     {        av_log(s->avctx, AV_LOG_DEBUG, "invalid sample size code (%d)\n", sample_size_code);        return -1;    }    if (get_bits1(&s->gb))    {        av_log(s->avctx, AV_LOG_DEBUG, "broken stream, invalid padding\n");        return -1;    }        if(get_utf8(&s->gb) < 0){        av_log(s->avctx, AV_LOG_ERROR, "utf8 fscked\n");        return -1;    }#if 0        if (/*((blocksize_code == 6) || (blocksize_code == 7)) &&*/        (s->min_blocksize != s->max_blocksize)){    }else{    }#endif        if (blocksize_code == 0)        blocksize = s->min_blocksize;    else if (blocksize_code == 6)        blocksize = get_bits(&s->gb, 8)+1;    else if (blocksize_code == 7)        blocksize = get_bits(&s->gb, 16)+1;    else         blocksize = blocksize_table[blocksize_code];    if(blocksize > s->max_blocksize){        av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", blocksize, s->max_blocksize);        return -1;    }    if (sample_rate_code == 0){        samplerate= s->samplerate;    }else if ((sample_rate_code > 3) && (sample_rate_code < 12))        samplerate = sample_rate_table[sample_rate_code];    else if (sample_rate_code == 12)        samplerate = get_bits(&s->gb, 8) * 1000;    else if (sample_rate_code == 13)        samplerate = get_bits(&s->gb, 16);    else if (sample_rate_code == 14)        samplerate = get_bits(&s->gb, 16) * 10;    else{        av_log(s->avctx, AV_LOG_ERROR, "illegal sample rate code %d\n", sample_rate_code);        return -1;    }    skip_bits(&s->gb, 8);    crc8= get_crc8(s->gb.buffer, get_bits_count(&s->gb)/8);    if(crc8){        av_log(s->avctx, AV_LOG_ERROR, "header crc missmatch crc=%2X\n", crc8);        return -1;    }        s->blocksize    = blocksize;    s->samplerate   = samplerate;    s->bps          = bps;    s->decorrelation= decorrelation;//    dump_headers(s);    /* subframes */    for (i = 0; i < s->channels; i++)    {//        av_log(s->avctx, AV_LOG_DEBUG, "decoded: %x residual: %x\n", s->decoded[i], s->residual[i]);        if (decode_subframe(s, i) < 0)            return -1;    }        align_get_bits(&s->gb);    /* frame footer */    skip_bits(&s->gb, 16); /* data crc */    return 0;}static int flac_decode_frame(AVCodecContext *avctx,                            void *data, int *data_size,                            uint8_t *buf, int buf_size){    FLACContext *s = avctx->priv_data;    int metadata_last, metadata_type, metadata_size;    int tmp = 0, i, j = 0, input_buf_size;    int16_t *samples = data, *left, *right;    *data_size = 0;    s->avctx = avctx;        if(s->max_framesize == 0){        s->max_framesize= 8192; // 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){//                printf("wanna more data ...\n");                return input_buf_size;            }    }    init_get_bits(&s->gb, buf, buf_size*8);        /* fLaC signature (be) */    if (show_bits_long(&s->gb, 32) == bswap_32(ff_get_fourcc("fLaC")))    {        skip_bits(&s->gb, 32);        av_log(s->avctx, AV_LOG_DEBUG, "STREAM HEADER\n");        do {            metadata_last = get_bits(&s->gb, 1);            metadata_type = get_bits(&s->gb, 7);            metadata_size = get_bits_long(&s->gb, 24);                        av_log(s->avctx, AV_LOG_DEBUG, " metadata block: flag = %d, type = %d, size = %d\n",                metadata_last, metadata_type,                metadata_size);            if(metadata_size){                switch(metadata_type)                {                case METADATA_TYPE_STREAMINFO:                    metadata_streaminfo(s);                    dump_headers(s);                    break;                default:                    for(i=0; i<metadata_size; i++)                        skip_bits(&s->gb, 8);                }            }        } while(!metadata_last);    }    else    {                tmp = show_bits(&s->gb, 16);        if(tmp != 0xFFF8){            av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n");            while(get_bits_count(&s->gb)/8+2 < buf_size && show_bits(&s->gb, 16) != 0xFFF8)                skip_bits(&s->gb, 8);            goto end; // we may not have enough bits left to decode a frame, so try next time        }        skip_bits(&s->gb, 16);        if (decode_frame(s) < 0){            av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");            s->bitstream_size=0;            s->bitstream_index=0;            return -1;        }    }    #if 0    /* fix the channel order here */    if (s->order == MID_SIDE)    {        short *left = samples;        short *right = samples + s->blocksize;        for (i = 0; i < s->blocksize; i += 2)        {            uint32_t x = s->decoded[0][i];            uint32_t y = s->decoded[0][i+1];            right[i] = x - (y / 2);            left[i] = right[i] + y;        }        *data_size = 2 * s->blocksize;    }    else    {    for (i = 0; i < s->channels; i++)    {        switch(s->order)        {            case INDEPENDENT:                for (j = 0; j < s->blocksize; j++)                    samples[(s->blocksize*i)+j] = s->decoded[i][j];                break;            case LEFT_SIDE:            case RIGHT_SIDE:                if (i == 0)                    for (j = 0; j < s->blocksize; j++)                        samples[(s->blocksize*i)+j] = s->decoded[0][j];                else                    for (j = 0; j < s->blocksize; j++)                        samples[(s->blocksize*i)+j] = s->decoded[0][j] - s->decoded[i][j];                break;//            case MID_SIDE://                av_log(s->avctx, AV_LOG_DEBUG, "mid-side unsupported\n");        }        *data_size += s->blocksize;    }    }#else    switch(s->decorrelation)    {        case INDEPENDENT:            for (j = 0; j < s->blocksize; j++)            {                for (i = 0; i < s->channels; i++)                    *(samples++) = s->decoded[i][j];            }            break;        case LEFT_SIDE:            assert(s->channels == 2);            for (i = 0; i < s->blocksize; i++)            {                *(samples++) = s->decoded[0][i];                *(samples++) = s->decoded[0][i] - s->decoded[1][i];            }            break;        case RIGHT_SIDE:            assert(s->channels == 2);            for (i = 0; i < s->blocksize; i++)            {                *(samples++) = s->decoded[0][i] + s->decoded[1][i];                *(samples++) = s->decoded[1][i];            }            break;        case MID_SIDE:            assert(s->channels == 2);            for (i = 0; i < s->blocksize; i++)            {                int mid, side;                mid = s->decoded[0][i];                side = s->decoded[1][i];#if 1 //needs to be checked but IMHO it should be binary identical                mid -= side>>1;                *(samples++) = mid + side;                *(samples++) = mid;#else                                mid <<= 1;                if (side & 1)                    mid++;                *(samples++) = (mid + side) >> 1;                *(samples++) = (mid - side) >> 1;#endif            }            break;    }#endif    *data_size = (int8_t *)samples - (int8_t *)data;//    av_log(s->avctx, AV_LOG_DEBUG, "data size: %d\n", *data_size);//    s->last_blocksize = s->blocksize;end:    i= (get_bits_count(&s->gb)+7)/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 flac_decode_close(AVCodecContext *avctx){    FLACContext *s = avctx->priv_data;    int i;        for (i = 0; i < s->channels; i++)    {        av_freep(&s->decoded[i]);    }    av_freep(&s->bitstream);        return 0;}static void flac_flush(AVCodecContext *avctx){    FLACContext *s = avctx->priv_data;    s->bitstream_size=    s->bitstream_index= 0;}AVCodec flac_decoder = {    "flac",    CODEC_TYPE_AUDIO,    CODEC_ID_FLAC,    sizeof(FLACContext),    flac_decode_init,    NULL,    flac_decode_close,    flac_decode_frame,    .flush= flac_flush,    };

⌨️ 快捷键说明

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