📄 bitstream.cpp
字号:
/***************************************************************************** * * XVID MPEG-4 VIDEO CODEC * - Bitstream reader/writer - * * Copyright (C) 2001-2003 Peter Ross <pross@xvid.org> * 2003 Cristoph Lampert <gruel@web.de> * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation ; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: bitstream.cpp,v 1.1.1.1 2005/07/13 14:36:12 jeanlf Exp $ * ****************************************************************************/#include "bitstream.h"#include "quant_matrix.h"#ifdef WIN32#include <stdio.h>#endif//----------------------------inline dword ByteSwap(dword a){ return (a<<24) | ((a&0xff00) << 8) | ((a&0xff0000) >> 8) | (a>>24);}//----------------------------void Bitstream::Init(const void *bitstream, dword _length){ dword adjbitstream = (dword)bitstream; /* * Start the stream on a dword boundary, by rounding down to the * previous dword and skipping the intervening bytes. */ long bitpos = ((sizeof(dword)-1) & (long)bitstream); adjbitstream = adjbitstream - bitpos; start = tail = (dword *) adjbitstream; if(_length){ dword tmp = *start;#ifndef ARCH_IS_BIG_ENDIAN tmp = ByteSwap(tmp);#endif bufa = tmp; if(_length>4){ tmp = *(start + 1);#ifndef ARCH_IS_BIG_ENDIAN tmp = ByteSwap(tmp);#endif bufb = tmp; }else bufb = 0; }else bufa = bufb = 0; buf = 0; pos = initpos = bitpos*8; length = _length;}//---------------------------/* reads n bits from bitstream without changing the stream pos */dword Bitstream::ShowBits(dword bits){ int nbit = (bits + pos) - 32; if(nbit > 0) return ((bufa & (0xffffffff >> pos)) << nbit) | (bufb >> (32 - nbit)); return (bufa & (0xffffffff >> pos)) >> (32 - pos - bits);}//---------------------------// skip n bits forward in bitstreamvoid Bitstream::Skip(dword bits){ pos += bits; if(pos >= 32){ dword tmp; bufa = bufb; tmp = *((dword *) tail + 2);#ifndef ARCH_IS_BIG_ENDIAN tmp = ByteSwap(tmp);#endif bufb = tmp; tail++; pos -= 32; }}//---------------------------/* show nbits from next byte alignment */dword Bitstream::ShowBitsFromByteAlign(int bits){ int bspos = pos + NumBitsToByteAlign(); int nbit = (bits + bspos) - 32; if (bspos >= 32) { return bufb >> (32 - nbit); } else if (nbit > 0) { return ((bufa & (0xffffffff >> bspos)) << nbit) | (bufb >> (32 - nbit)); } else { return (bufa & (0xffffffff >> bspos)) >> (32 - bspos - bits); }}//---------------------------/* read n bits from bitstream */dword Bitstream::GetBits(dword n){ dword ret = ShowBits(n); Skip(n); return ret;}//---------------------------static const dword intra_dc_threshold_table[] = { 32, /* never use */ 13, 15, 17, 19, 21, 23, 1,};//----------------------------void Bitstream::get_matrix(byte * matrix){ int i = 0; int last, value = 0; do { last = value; value = GetBits(8); matrix[scan_tables[0][i++]] = value; } while (value != 0 && i < 64); i--; /* fix little bug at coeff not full */ while (i < 64) { matrix[scan_tables[0][i++]] = last; }}//----------------------------/* * for PVOP addbits == fcode - 1 * for BVOP addbits == max(fcode,bcode) - 1 * returns mbpos */int S_decoder::read_video_packet_header(Bitstream *bs, const int addbits, int *quant, int *fcode_forward, int *fcode_backward, int *intra_dc_threshold){ int startcode_bits = NUMBITS_VP_RESYNC_MARKER + addbits; int mbnum_bits = log2bin(mb_width * mb_height - 1); int mbnum; int hec = 0; bs->Skip(bs->NumBitsToByteAlign()); bs->Skip(startcode_bits); DPRINTF(XVID_DEBUG_STARTCODE, "<video_packet_header>\n"); if (shape != VIDOBJLAY_SHAPE_RECTANGULAR) { hec = bs->GetBit(); /* header_extension_code */ if (hec && !(sprite_enable == SPRITE_STATIC /* && current_coding_type = I_VOP */)) { bs->Skip(13); /* vop_width */ READ_MARKER(); bs->Skip(13); /* vop_height */ READ_MARKER(); bs->Skip(13); /* vop_horizontal_mc_spatial_ref */ READ_MARKER(); bs->Skip(13); /* vop_vertical_mc_spatial_ref */ READ_MARKER(); } } mbnum = bs->GetBits(mbnum_bits); /* macroblock_number */ DPRINTF(XVID_DEBUG_HEADER, "mbnum %i\n", mbnum); if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY) { *quant = bs->GetBits(quant_bits); /* quant_scale */ DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant); } if (shape == VIDOBJLAY_SHAPE_RECTANGULAR) hec = bs->GetBit(); /* header_extension_code */ DPRINTF(XVID_DEBUG_HEADER, "header_extension_code %i\n", hec); if (hec) { int time_base; int time_increment = 0; int coding_type; for (time_base=0; bs->GetBit()!=0; time_base++); /* modulo_time_base */ READ_MARKER(); if (time_inc_bits) time_increment = (bs->GetBits(time_inc_bits)); /* vop_time_increment */ READ_MARKER(); //DPRINTF(XVID_DEBUG_HEADER,"time %i:%i\n", time_base, time_increment); coding_type = bs->GetBits(2); DPRINTF(XVID_DEBUG_HEADER,"coding_type %i\n", coding_type); if (shape != VIDOBJLAY_SHAPE_RECTANGULAR) { bs->Skip(1); /* change_conv_ratio_disable */ if (coding_type != I_VOP) bs->Skip(1); /* vop_shape_coding_type */ } if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY) { *intra_dc_threshold = intra_dc_threshold_table[bs->GetBits(3)]; if (sprite_enable == SPRITE_GMC && coding_type == S_VOP && sprite_warping_points > 0) { /* TODO: sprite trajectory */ } if(reduced_resolution_enable && shape == VIDOBJLAY_SHAPE_RECTANGULAR && (coding_type == P_VOP || coding_type == I_VOP)){ bs->Skip(1); /* XXX: vop_reduced_resolution */ } if (coding_type != I_VOP && fcode_forward) { *fcode_forward = bs->GetBits(3); DPRINTF(XVID_DEBUG_HEADER,"fcode_forward %i\n", *fcode_forward); } if (coding_type == B_VOP && fcode_backward) { *fcode_backward = bs->GetBits(3); DPRINTF(XVID_DEBUG_HEADER,"fcode_backward %i\n", *fcode_backward); } } } if (newpred_enable) { int vop_id; int vop_id_for_prediction; vop_id = bs->GetBits(MIN(time_inc_bits + 3, 15)); DPRINTF(XVID_DEBUG_HEADER, "vop_id %i\n", vop_id); if (bs->GetBit()) /* vop_id_for_prediction_indication */ { vop_id_for_prediction = bs->GetBits(MIN(time_inc_bits + 3, 15)); DPRINTF(XVID_DEBUG_HEADER, "vop_id_for_prediction %i\n", vop_id_for_prediction); } READ_MARKER(); } return mbnum;}//----------------------------/* vol estimation header */void S_decoder::read_vol_complexity_estimation_header(Bitstream * bs){ ESTIMATION * e = &estimation; e->method = bs->GetBits(2); /* estimation_method */ DPRINTF(XVID_DEBUG_HEADER,"+ complexity_estimation_header; method=%i\n", e->method); if (e->method == 0 || e->method == 1){ if(!bs->GetBit()){ //shape_complexity_estimation_disable e->opaque = bs->GetBit(); /* opaque */ e->transparent = bs->GetBit(); /* transparent */ e->intra_cae = bs->GetBit(); /* intra_cae */ e->inter_cae = bs->GetBit(); /* inter_cae */ e->no_update = bs->GetBit(); /* no_update */ e->upsampling = bs->GetBit(); /* upsampling */ } if (!bs->GetBit()) /* texture_complexity_estimation_set_1_disable */ { e->intra_blocks = bs->GetBit(); /* intra_blocks */ e->inter_blocks = bs->GetBit(); /* inter_blocks */ e->inter4v_blocks = bs->GetBit(); /* inter4v_blocks */ e->not_coded_blocks = bs->GetBit(); /* not_coded_blocks */ } } READ_MARKER(); if (!bs->GetBit()){ //texture_complexity_estimation_set_2_disable e->dct_coefs = bs->GetBit(); /* dct_coefs */ e->dct_lines = bs->GetBit(); /* dct_lines */ e->vlc_symbols = bs->GetBit(); /* vlc_symbols */ e->vlc_bits = bs->GetBit(); /* vlc_bits */ } if (!bs->GetBit()){ //motion_compensation_complexity_disable e->apm = bs->GetBit(); /* apm */ e->npm = bs->GetBit(); /* npm */ e->interpolate_mc_q = bs->GetBit(); /* interpolate_mc_q */ e->forw_back_mc_q = bs->GetBit(); /* forw_back_mc_q */ e->halfpel2 = bs->GetBit(); /* halfpel2 */ e->halfpel4 = bs->GetBit(); /* halfpel4 */ } READ_MARKER(); if (e->method == 1){ if (!bs->GetBit()){ //version2_complexity_estimation_disable e->sadct = bs->GetBit(); /* sadct */ e->quarterpel = bs->GetBit(); /* quarterpel */ } }}//----------------------------/* vop estimation header */void S_decoder::read_vop_complexity_estimation_header(Bitstream * bs, int coding_type){ ESTIMATION * e = &estimation; if (e->method == 0 || e->method == 1) { if (coding_type == I_VOP) { if (e->opaque) bs->Skip(8); /* dcecs_opaque */ if (e->transparent) bs->Skip(8); /* */ if (e->intra_cae) bs->Skip(8); /* */ if (e->inter_cae) bs->Skip(8); /* */ if (e->no_update) bs->Skip(8); /* */ if (e->upsampling) bs->Skip(8); /* */ if (e->intra_blocks) bs->Skip(8); /* */ if (e->not_coded_blocks) bs->Skip(8); /* */ if (e->dct_coefs) bs->Skip(8); /* */ if (e->dct_lines) bs->Skip(8); /* */ if (e->vlc_symbols) bs->Skip(8); /* */ if (e->vlc_bits) bs->Skip(8); /* */ if (e->sadct) bs->Skip(8); /* */ } if (coding_type == P_VOP) { if (e->opaque) bs->Skip(8); /* */ if (e->transparent) bs->Skip(8); /* */ if (e->intra_cae) bs->Skip(8); /* */ if (e->inter_cae) bs->Skip(8); /* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -