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

📄 h261.c

📁 FFmpeg is an audio/video conversion tool. It includes libavcodec, the leading open source codec libr
💻 C
📖 第 1 页 / 共 2 页
字号:
    if(!coded){        s->block_last_index[n] = i - 1;        return 0;    }    for(;;){        code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2);        if (code < 0){            av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y);            return -1;        }        if (code == rl->n) {            /* escape */            // The remaining combinations of (run, level) are encoded with a 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits level.            run = get_bits(&s->gb, 6);            level = (int8_t)get_bits(&s->gb, 8);        }else if(code == 0){            break;        }else{            run = rl->table_run[code];            level = rl->table_level[code];            if (get_bits1(&s->gb))                level = -level;        }        i += run;        if (i >= 64){            av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y);            return -1;        }        j = scan_table[i];        block[j] = level;        i++;    }    s->block_last_index[n] = i;    return 0;}/** * decodes the H261 picture header. * @return <0 if no startcode found */int h261_decode_picture_header(H261Context *h){    MpegEncContext * const s = &h->s;    int format, i;    static int h261_framecounter = 0;    uint32_t startcode;    align_get_bits(&s->gb);    startcode = (h->last_bits << (12 - (8-h->bits_left))) | get_bits(&s->gb, 20-8 - (8- h->bits_left));    for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=1){        startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF;        if(startcode == 0x10)            break;    }    if (startcode != 0x10){        av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");        return -1;    }    /* temporal reference */    s->picture_number = get_bits(&s->gb, 5); /* picture timestamp */    /* PTYPE starts here */    skip_bits1(&s->gb); /* split screen off */    skip_bits1(&s->gb); /* camera  off */    skip_bits1(&s->gb); /* freeze picture release off */    format = get_bits1(&s->gb);    //only 2 formats possible    if (format == 0){//QCIF        s->width = 176;        s->height = 144;        s->mb_width = 11;        s->mb_height = 9;    }else{//CIF        s->width = 352;        s->height = 288;        s->mb_width = 22;        s->mb_height = 18;    }    s->mb_num = s->mb_width * s->mb_height;    skip_bits1(&s->gb); /* still image mode off */    skip_bits1(&s->gb); /* Reserved */    /* PEI */    while (get_bits1(&s->gb) != 0){        skip_bits(&s->gb, 8);    }    //h261 has no I-FRAMES, pass the test in MPV_frame_start in mpegvideo.c    if(h261_framecounter > 1)        s->pict_type = P_TYPE;    else        s->pict_type = I_TYPE;    h261_framecounter++;    h->gob_number = 0;    return 0;}static int h261_decode_gob(H261Context *h){    MpegEncContext * const s = &h->s;    int i;        ff_set_qscale(s, s->qscale);    while(h->current_mba <= MAX_MBA)    {        int ret;        /* DCT & quantize */        s->dsp.clear_blocks(s->block[0]);        ret= h261_decode_mb(h, s->block);        if(ret<0){            const int xy= s->mb_x + s->mb_y*s->mb_stride;            if(ret==SLICE_END){                MPV_decode_mb(s, s->block);                if(h->loop_filter){                    ff_h261_loop_filter(h);                }                h->loop_filter = 0;                for(i=1; i<h->mba_diff; i++){                    s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1-i) % 11);                    s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1-i) / 11);                    ff_init_block_index(s);                    ff_update_block_index(s);                    s->dsp.clear_blocks(s->block[0]);                    ret= h261_decode_mb_skipped(h, s->block);                    MPV_decode_mb(s, s->block);                }                                return 0;            }else if(ret==SLICE_NOEND){                av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy);                return -1;            }            av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);            return -1;        }        MPV_decode_mb(s, s->block);        if(h->loop_filter){            ff_h261_loop_filter(h);        }        h->loop_filter = 0;        for(i=1; i<h->mba_diff; i++){            s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1-i) % 11);            s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1-i) / 11);            ff_init_block_index(s);            ff_update_block_index(s);            s->dsp.clear_blocks(s->block[0]);            ret= h261_decode_mb_skipped(h, s->block);            MPV_decode_mb(s, s->block);        }    }        return -1;}static int h261_find_frame_end(ParseContext *pc, AVCodecContext* avctx, const uint8_t *buf, int buf_size){    int vop_found, i, j, bits_left, last_bits;    uint32_t state;    H261Context *h = avctx->priv_data;    if(h){        bits_left = h->bits_left;        last_bits = h->last_bits;    }    else{        bits_left = 0;        last_bits = 0;    }    vop_found= pc->frame_start_found;    state= pc->state;    if(bits_left!=0 && !vop_found)        state = state << (8-bits_left) | last_bits;    i=0;    if(!vop_found){        for(i=0; i<buf_size; i++){            state= (state<<8) | buf[i];            for(j=0; j<8; j++){                if(( (  (state<<j)  |  (buf[i]>>(8-j))  )>>(32-20) == 0x10 )&&(((state >> (17-j)) & 0x4000) == 0x0)){                    i++;                    vop_found=1;                    break;                }            }            if(vop_found)                    break;            }    }    if(vop_found){        for(; i<buf_size; i++){            if(avctx->flags & CODEC_FLAG_TRUNCATED)//XXX ffplay workaround, someone a better solution?                state= (state<<8) | buf[i];            for(j=0; j<8; j++){                if(( (  (state<<j)  |  (buf[i]>>(8-j))  )>>(32-20) == 0x10 )&&(((state >> (17-j)) & 0x4000) == 0x0)){                    pc->frame_start_found=0;                    pc->state=-1;                    return i-3;                }            }        }    }    pc->frame_start_found= vop_found;    pc->state= state;    return END_NOT_FOUND;}static int h261_parse(AVCodecParserContext *s,                      AVCodecContext *avctx,                      uint8_t **poutbuf, int *poutbuf_size,                       const uint8_t *buf, int buf_size){    ParseContext *pc = s->priv_data;    int next;        next= h261_find_frame_end(pc,avctx, buf, buf_size);    if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {        *poutbuf = NULL;        *poutbuf_size = 0;        return buf_size;    }    *poutbuf = (uint8_t *)buf;    *poutbuf_size = buf_size;    return next;}/** * returns the number of bytes consumed for building the current frame */static int get_consumed_bytes(MpegEncContext *s, int buf_size){    int pos= (get_bits_count(&s->gb)+7)>>3;    if(s->flags&CODEC_FLAG_TRUNCATED){        pos -= s->parse_context.last_index;        if(pos<0) pos=0;// padding is not really read so this might be -1        return pos;    }else{        if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...)        if(pos+10>buf_size) pos=buf_size; // oops ;)        return pos;    }}static int h261_decode_frame(AVCodecContext *avctx,                             void *data, int *data_size,                             uint8_t *buf, int buf_size){    H261Context *h= avctx->priv_data;    MpegEncContext *s = &h->s;    int ret;    AVFrame *pict = data;#ifdef DEBUG    printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);    printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);#endif    s->flags= avctx->flags;    s->flags2= avctx->flags2;    /* no supplementary picture */    if (buf_size == 0) {        return 0;    }    if(s->flags&CODEC_FLAG_TRUNCATED){        int next;        next= h261_find_frame_end(&s->parse_context,avctx, buf, buf_size);        if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )            return buf_size;    }retry:    init_get_bits(&s->gb, buf, buf_size*8);    if(!s->context_initialized){        if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix            return -1;    }    //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there    if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){        int i= ff_find_unused_picture(s, 0);        s->current_picture_ptr= &s->picture[i];    }    ret = h261_decode_picture_header(h);    /* skip if the header was thrashed */    if (ret < 0){        av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");        return -1;    }    if (s->width != avctx->width || s->height != avctx->height){        ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat        s->parse_context.buffer=0;        MPV_common_end(s);        s->parse_context= pc;    }    if (!s->context_initialized) {        avctx->width = s->width;        avctx->height = s->height;        goto retry;    }    // for hurry_up==5    s->current_picture.pict_type= s->pict_type;    s->current_picture.key_frame= s->pict_type == I_TYPE;    /* skip everything if we are in a hurry>=5 */    if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size);    if(MPV_frame_start(s, avctx) < 0)        return -1;    ff_er_frame_start(s);    /* decode each macroblock */    s->mb_x=0;    s->mb_y=0;    while(h->gob_number < (s->mb_height==18 ? 12 : 5)){        if(ff_h261_resync(h)<0)            break;        h261_decode_gob(h);    }    MPV_frame_end(s);    // h261 doesn't have byte aligned codes    // store the bits of the next frame that are left in the last byte    // in the H261Context and remember the number of stored bits    {        int bitsleft;        int current_pos= get_bits_count(&s->gb)>>3;        bitsleft =  (current_pos<<3) - get_bits_count(&s->gb);        h->bits_left = - bitsleft;        if(bitsleft > 0)            h->last_bits= get_bits(&s->gb, 8 - h->bits_left);        else            h->last_bits = 0;    }assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);assert(s->current_picture.pict_type == s->pict_type);    *pict= *(AVFrame*)&s->current_picture;    ff_print_debug_info(s, pict);    /* Return the Picture timestamp as the frame number */    /* we substract 1 because it is added on utils.c    */    avctx->frame_number = s->picture_number - 1;    *data_size = sizeof(AVFrame);    return get_consumed_bytes(s, buf_size);}static int h261_decode_end(AVCodecContext *avctx){    H261Context *h= avctx->priv_data;    MpegEncContext *s = &h->s;    MPV_common_end(s);    return 0;}AVCodec h261_decoder = {    "h261",    CODEC_TYPE_VIDEO,    CODEC_ID_H261,    sizeof(H261Context),    h261_decode_init,    NULL,    h261_decode_end,    h261_decode_frame,    CODEC_CAP_TRUNCATED,};AVCodecParser h261_parser = {    { CODEC_ID_H261 },    sizeof(ParseContext),    NULL,    h261_parse,    ff_parse_close,};

⌨️ 快捷键说明

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