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

📄 h261.c

📁 FFmpeg is an audio/video conversion tool. It includes libavcodec, the leading open source codec libr
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * H261 decoder * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//** * @file h261.c * h261codec. */#include "common.h"#include "dsputil.h"#include "avcodec.h"#include "mpegvideo.h"#include "h261data.h"#define H261_MBA_VLC_BITS 9#define H261_MTYPE_VLC_BITS 6#define H261_MV_VLC_BITS 7#define H261_CBP_VLC_BITS 9#define TCOEFF_VLC_BITS 9#define MAX_MBA 33#define IS_FIL(a)    ((a)&MB_TYPE_H261_FIL)/** * H261Context */typedef struct H261Context{    MpegEncContext s;    int current_mba;    int mba_diff;    int mtype;    int current_mv_x;    int current_mv_y;    int gob_number;    int loop_filter;    int bits_left; //8 - nr of bits left of the following frame in the last byte in this frame    int last_bits; //bits left of the following frame in the last byte in this frame}H261Context;void ff_h261_loop_filter(H261Context * h){    MpegEncContext * const s = &h->s;    const int linesize  = s->linesize;    const int uvlinesize= s->uvlinesize;    uint8_t *dest_y = s->dest[0];    uint8_t *dest_cb= s->dest[1];    uint8_t *dest_cr= s->dest[2];        s->dsp.h261_loop_filter(dest_y                   , linesize);    s->dsp.h261_loop_filter(dest_y                + 8, linesize);    s->dsp.h261_loop_filter(dest_y + 8 * linesize    , linesize);    s->dsp.h261_loop_filter(dest_y + 8 * linesize + 8, linesize);    s->dsp.h261_loop_filter(dest_cb, uvlinesize);    s->dsp.h261_loop_filter(dest_cr, uvlinesize);}static int h261_decode_block(H261Context *h, DCTELEM *block,                             int n, int coded);static int h261_decode_mb(H261Context *h,                      DCTELEM block[6][64]);void ff_set_qscale(MpegEncContext * s, int qscale);/***********************************************//* decoding */static VLC h261_mba_vlc;static VLC h261_mtype_vlc;static VLC h261_mv_vlc;static VLC h261_cbp_vlc;void init_vlc_rl(RLTable *rl);static void h261_decode_init_vlc(H261Context *h){    static int done = 0;    if(!done){        done = 1;        init_vlc(&h261_mba_vlc, H261_MBA_VLC_BITS, 34,                 h261_mba_bits, 1, 1,                 h261_mba_code, 1, 1);        init_vlc(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10,                 h261_mtype_bits, 1, 1,                 h261_mtype_code, 1, 1);        init_vlc(&h261_mv_vlc, H261_MV_VLC_BITS, 17,                 &h261_mv_tab[0][1], 2, 1,                 &h261_mv_tab[0][0], 2, 1);        init_vlc(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63,                 &h261_cbp_tab[0][1], 2, 1,                 &h261_cbp_tab[0][0], 2, 1);        init_rl(&h261_rl_tcoeff);        init_vlc_rl(&h261_rl_tcoeff);    }}static int h261_decode_init(AVCodecContext *avctx){    H261Context *h= avctx->priv_data;    MpegEncContext * const s = &h->s;    // set defaults    MPV_decode_defaults(s);    s->avctx = avctx;    s->width = s->avctx->width;    s->height = s->avctx->height;    s->codec_id = s->avctx->codec->id;    s->out_format = FMT_H261;    s->low_delay= 1;    avctx->pix_fmt= PIX_FMT_YUV420P;    s->codec_id= avctx->codec->id;    h261_decode_init_vlc(h);    h->bits_left = 0;    h->last_bits = 0;        return 0;}/** * decodes the group of blocks header or slice header. * @return <0 if an error occured */static int h261_decode_gob_header(H261Context *h){    unsigned int val;    MpegEncContext * const s = &h->s;        /* Check for GOB Start Code */    val = show_bits(&s->gb, 15);    if(val)        return -1;    /* We have a GBSC */    skip_bits(&s->gb, 16);    h->gob_number = get_bits(&s->gb, 4); /* GN */    s->qscale = get_bits(&s->gb, 5); /* GQUANT */    /* GEI */    while (get_bits1(&s->gb) != 0) {        skip_bits(&s->gb, 8);    }    if(s->qscale==0)        return -1;    // For the first transmitted macroblock in a GOB, MBA is the absolute address. For    // subsequent macroblocks, MBA is the difference between the absolute addresses of    // the macroblock and the last transmitted macroblock.    h->current_mba = 0;    h->mba_diff = 0;    return 0;}/** * decodes the group of blocks / video packet header. * @return <0 if no resync found */static int ff_h261_resync(H261Context *h){    MpegEncContext * const s = &h->s;    int left, ret;    if(show_bits(&s->gb, 15)==0){        ret= h261_decode_gob_header(h);        if(ret>=0)            return 0;    }    //ok, its not where its supposed to be ...    s->gb= s->last_resync_gb;    align_get_bits(&s->gb);    left= s->gb.size_in_bits - get_bits_count(&s->gb);    for(;left>15+1+4+5; left-=8){        if(show_bits(&s->gb, 15)==0){            GetBitContext bak= s->gb;            ret= h261_decode_gob_header(h);            if(ret>=0)                return 0;            s->gb= bak;        }        skip_bits(&s->gb, 8);    }    return -1;}/** * decodes a skipped macroblock, called when when mba_diff > 1. * @return 0 */static int h261_decode_mb_skipped(H261Context *h,                                  DCTELEM block[6][64]){    MpegEncContext * const s = &h->s;    int i;    const int xy = s->mb_x + s->mb_y * s->mb_stride;    s->mb_intra = 0;    for(i=0;i<6;i++)        s->block_last_index[i] = -1;    s->mv_dir = MV_DIR_FORWARD;    s->mv_type = MV_TYPE_16X16;    s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;    s->mv[0][0][0] = 0;    s->mv[0][0][1] = 0;    s->mb_skiped = 1;    return 0;}static int decode_mv_component(GetBitContext *gb, int v){    int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2);    mv_diff = mvmap[mv_diff];    if(mv_diff && !get_bits1(gb))        mv_diff= -mv_diff;        v += mv_diff;    if     (v <=-16) v+= 32;    else if(v >= 16) v-= 32;    return v;}static int h261_decode_mb(H261Context *h,                          DCTELEM block[6][64]){    MpegEncContext * const s = &h->s;    int i, cbp, xy, old_mtype;    cbp = 63;    // Read mba    do{        h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2)+1;    }    while( h->mba_diff == MAX_MBA + 1 ); // stuffing    if ( h->mba_diff < 0 )        return -1;    h->current_mba += h->mba_diff;    if ( h->current_mba > MAX_MBA )        return -1;        s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1) % 11);    s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1) / 11);    xy = s->mb_x + s->mb_y * s->mb_stride;    ff_init_block_index(s);    ff_update_block_index(s);    // Read mtype    old_mtype = h->mtype;    h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);    h->mtype = h261_mtype_map[h->mtype];    if (IS_FIL (h->mtype))        h->loop_filter = 1;    // Read mquant    if ( IS_QUANT ( h->mtype ) ){        s->qscale = get_bits(&s->gb, 5);    }    s->mb_intra = IS_INTRA4x4(h->mtype);    // Read mv    if ( IS_16X16 ( h->mtype ) ){        // Motion vector data is included for all MC macroblocks. MVD is obtained from the macroblock vector by subtracting the        // vector of the preceding macroblock. For this calculation the vector of the preceding macroblock is regarded as zero in the        // following three situations:        // 1) evaluating MVD for macroblocks 1, 12 and 23;        // 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1;        // 3) MTYPE of the previous macroblock was not MC.        if ( ( h->current_mba == 1 ) || ( h->current_mba == 12 ) || ( h->current_mba == 23 ) ||             ( h->mba_diff != 1) || ( !IS_16X16 ( old_mtype ) ))        {            h->current_mv_x = 0;            h->current_mv_y = 0;        }        h->current_mv_x= decode_mv_component(&s->gb, h->current_mv_x);        h->current_mv_y= decode_mv_component(&s->gb, h->current_mv_y);    }    // Read cbp    if ( HAS_CBP( h->mtype ) ){        cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1;    }    if(s->mb_intra){        s->current_picture.mb_type[xy]= MB_TYPE_INTRA;        goto intra;    }    //set motion vectors    s->mv_dir = MV_DIR_FORWARD;    s->mv_type = MV_TYPE_16X16;    s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;    if(IS_16X16 ( h->mtype )){        s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation        s->mv[0][0][1] = h->current_mv_y * 2;    }    else{        h->current_mv_x = s->mv[0][0][0] = 0;        h->current_mv_x = s->mv[0][0][1] = 0;    }intra:    /* decode each block */    if(s->mb_intra || HAS_CBP(h->mtype)){        for (i = 0; i < 6; i++) {            if (h261_decode_block(h, block[i], i, cbp&32) < 0){                return -1;            }            cbp+=cbp;        }    }    /* per-MB end of slice check */    {        int v= show_bits(&s->gb, 15);        if(get_bits_count(&s->gb) + 15 > s->gb.size_in_bits){            v>>= get_bits_count(&s->gb) + 15 - s->gb.size_in_bits;        }        if(v==0){            return SLICE_END;        }    }    return SLICE_OK;}/** * decodes a macroblock * @return <0 if an error occured */static int h261_decode_block(H261Context * h, DCTELEM * block,                             int n, int coded){    MpegEncContext * const s = &h->s;    int code, level, i, j, run;    RLTable *rl = &h261_rl_tcoeff;    const uint8_t *scan_table;        // For the variable length encoding there are two code tables, one being used for    // the first transmitted LEVEL in INTER, INTER+MC and INTER+MC+FIL blocks, the second    // for all other LEVELs except the first one in INTRA blocks which is fixed length    // coded with 8 bits.    // NOTE: the two code tables only differ in one VLC so we handle that manually.    scan_table = s->intra_scantable.permutated;    if (s->mb_intra){        /* DC coef */        level = get_bits(&s->gb, 8);        // 0 (00000000b) and -128 (10000000b) are FORBIDDEN        if((level&0x7F) == 0){            av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);            return -1;        }        // The code 1000 0000 is not used, the reconstruction level of 1024 being coded as 1111 1111.        if (level == 255)            level = 128;        block[0] = level;        i = 1;    }else if(coded){        // Run  Level   Code        // EOB                  Not possible for first level when cbp is available (that's why the table is different)        // 0    1               1s        // *    *               0*        int check = show_bits(&s->gb, 2);        i = 0;        if ( check & 0x2 ){            skip_bits(&s->gb, 2);            block[0] = ( check & 0x1 ) ? -1 : 1;            i = 1;        }    }else{        i = 0;    }

⌨️ 快捷键说明

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