📄 h261.c
字号:
/* * 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 + -