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

📄 h261dec.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * H261 decoder * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * Copyright (c) 2004 Maarten Daniels * * This file is part of FFmpeg. * * FFmpeg 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.1 of the License, or (at your option) any later version. * * FFmpeg 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file h261dec.c * H.261 decoder. */#include "dsputil.h"#include "avcodec.h"#include "mpegvideo.h"#include "h261.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 MBA_STUFFING 33#define MBA_STARTCODE 34extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];static VLC h261_mba_vlc;static VLC h261_mtype_vlc;static VLC h261_mv_vlc;static VLC h261_cbp_vlc;static int h261_decode_block(H261Context * h, DCTELEM * block, int n, int coded);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, 35,                 h261_mba_bits, 1, 1,                 h261_mba_code, 1, 1, 1);        init_vlc(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10,                 h261_mtype_bits, 1, 1,                 h261_mtype_code, 1, 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, 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, 1);        init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store);        init_vlc_rl(&h261_rl_tcoeff, 1);    }}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->coded_width;    s->height = s->avctx->coded_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->gob_start_code_skipped = 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;    if ( !h->gob_start_code_skipped ){        /* 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_start_code_skipped = 0;    h->gob_number = get_bits(&s->gb, 4); /* GN */    s->qscale = get_bits(&s->gb, 5); /* GQUANT */    /* Check if gob_number is valid */    if (s->mb_height==18){ //cif        if ((h->gob_number<=0) || (h->gob_number>12))            return -1;    }    else{ //qcif        if ((h->gob_number!=1) && (h->gob_number!=3) && (h->gob_number!=5))            return -1;    }    /* 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 ( h->gob_start_code_skipped ){        ret= h261_decode_gob_header(h);        if(ret>=0)            return 0;    }    else{        if(show_bits(&s->gb, 15)==0){            ret= h261_decode_gob_header(h);            if(ret>=0)                return 0;        }        //OK, it is not where it is 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 skipped macroblocks * @return 0 */static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 ){    MpegEncContext * const s = &h->s;    int i;    s->mb_intra = 0;    for(i=mba1; i<mba2; i++){        int j, xy;        s->mb_x= ((h->gob_number-1) % 2) * 11 + i % 11;        s->mb_y= ((h->gob_number-1) / 2) * 3 + i / 11;        xy = s->mb_x + s->mb_y * s->mb_stride;        ff_init_block_index(s);        ff_update_block_index(s);        for(j=0;j<6;j++)            s->block_last_index[j] = -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_skipped = 1;        h->mtype &= ~MB_TYPE_H261_FIL;        MPV_decode_mb(s, s->block);    }    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);    /* check if mv_diff is valid */    if ( mv_diff < 0 )        return v;    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){    MpegEncContext * const s = &h->s;    int i, cbp, xy;    cbp = 63;    // Read mba    do{        h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2);        /* Check for slice end */        /* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */        if (h->mba_diff == MBA_STARTCODE){ // start code            h->gob_start_code_skipped = 1;            return SLICE_END;        }    }    while( h->mba_diff == MBA_STUFFING ); // stuffing    if ( h->mba_diff < 0 ){        if ( get_bits_count(&s->gb) + 7 >= s->gb.size_in_bits )            return SLICE_END;        av_log(s->avctx, AV_LOG_ERROR, "illegal mba at %d %d\n", s->mb_x, s->mb_y);        return SLICE_ERROR;    }    h->mba_diff += 1;    h->current_mba += h->mba_diff;    if ( h->current_mba > MBA_STUFFING )        return SLICE_ERROR;    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    h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);    h->mtype = h261_mtype_map[h->mtype];    // Read mquant    if ( IS_QUANT ( h->mtype ) ){        ff_set_qscale(s, 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))        {            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);    }else{        h->current_mv_x = 0;        h->current_mv_y = 0;    }    // 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

⌨️ 快捷键说明

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