📄 bitstream.c
字号:
/***************************************************************************** * * 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.c,v 1.55.2.1 2006/07/10 15:05:30 Isibaar Exp $ * ****************************************************************************/#include <string.h>#include <stdio.h>#include "bitstream.h"#include "zigzag.h"#include "../quant/quant_matrix.h"#include "mbcoding.h"static const uint8_t log2_tab_16[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; static uint32_t __inline log2bin(uint32_t value){ int n = 0; if (value & 0xffff0000) { value >>= 16; n += 16; } if (value & 0xff00) { value >>= 8; n += 8; } if (value & 0xf0) { value >>= 4; n += 4; } return n + log2_tab_16[value];}static const uint32_t intra_dc_threshold_table[] = { 32, /* never use */ 13, 15, 17, 19, 21, 23, 1,};static voidbs_get_matrix(Bitstream * bs, uint8_t * matrix){ int i = 0; int last, value = 0; do { last = value; value = BitstreamGetBits(bs, 8); matrix[scan_tables[0][i++]] = value; } while (value != 0 && i < 64); if (value != 0) return; i--; while (i < 64) { matrix[scan_tables[0][i++]] = last; }}/* * for PVOP addbits == fcode - 1 * for BVOP addbits == max(fcode,bcode) - 1 * returns mbpos */intread_video_packet_header(Bitstream *bs, DECODER * dec, 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(dec->mb_width * dec->mb_height - 1); int mbnum; int hec = 0; BitstreamSkip(bs, BitstreamNumBitsToByteAlign(bs)); BitstreamSkip(bs, startcode_bits); DPRINTF(XVID_DEBUG_STARTCODE, "<video_packet_header>\n"); if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) { hec = BitstreamGetBit(bs); /* header_extension_code */ if (hec && !(dec->sprite_enable == SPRITE_STATIC /* && current_coding_type = I_VOP */)) { BitstreamSkip(bs, 13); /* vop_width */ READ_MARKER(); BitstreamSkip(bs, 13); /* vop_height */ READ_MARKER(); BitstreamSkip(bs, 13); /* vop_horizontal_mc_spatial_ref */ READ_MARKER(); BitstreamSkip(bs, 13); /* vop_vertical_mc_spatial_ref */ READ_MARKER(); } } mbnum = BitstreamGetBits(bs, mbnum_bits); /* macroblock_number */ DPRINTF(XVID_DEBUG_HEADER, "mbnum %i\n", mbnum); if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) { *quant = BitstreamGetBits(bs, dec->quant_bits); /* quant_scale */ DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant); } if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR) hec = BitstreamGetBit(bs); /* header_extension_code */ DPRINTF(XVID_DEBUG_HEADER, "header_extension_code %i\n", hec); if (hec) { int time_base; int time_increment; int coding_type; for (time_base=0; BitstreamGetBit(bs)!=0; time_base++); /* modulo_time_base */ READ_MARKER(); if (dec->time_inc_bits) time_increment = (BitstreamGetBits(bs, dec->time_inc_bits)); /* vop_time_increment */ READ_MARKER(); DPRINTF(XVID_DEBUG_HEADER,"time %i:%i\n", time_base, time_increment); coding_type = BitstreamGetBits(bs, 2); DPRINTF(XVID_DEBUG_HEADER,"coding_type %i\n", coding_type); if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) { BitstreamSkip(bs, 1); /* change_conv_ratio_disable */ if (coding_type != I_VOP) BitstreamSkip(bs, 1); /* vop_shape_coding_type */ } if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) { *intra_dc_threshold = intra_dc_threshold_table[BitstreamGetBits(bs, 3)]; if (dec->sprite_enable == SPRITE_GMC && coding_type == S_VOP && dec->sprite_warping_points > 0) { /* TODO: sprite trajectory */ } if (dec->reduced_resolution_enable && dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR && (coding_type == P_VOP || coding_type == I_VOP)) { BitstreamSkip(bs, 1); /* XXX: vop_reduced_resolution */ } if (coding_type != I_VOP && fcode_forward) { *fcode_forward = BitstreamGetBits(bs, 3); DPRINTF(XVID_DEBUG_HEADER,"fcode_forward %i\n", *fcode_forward); } if (coding_type == B_VOP && fcode_backward) { *fcode_backward = BitstreamGetBits(bs, 3); DPRINTF(XVID_DEBUG_HEADER,"fcode_backward %i\n", *fcode_backward); } } } if (dec->newpred_enable) { int vop_id; int vop_id_for_prediction; vop_id = BitstreamGetBits(bs, MIN(dec->time_inc_bits + 3, 15)); DPRINTF(XVID_DEBUG_HEADER, "vop_id %i\n", vop_id); if (BitstreamGetBit(bs)) /* vop_id_for_prediction_indication */ { vop_id_for_prediction = BitstreamGetBits(bs, MIN(dec->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 */static voidread_vol_complexity_estimation_header(Bitstream * bs, DECODER * dec){ ESTIMATION * e = &dec->estimation; e->method = BitstreamGetBits(bs, 2); /* estimation_method */ DPRINTF(XVID_DEBUG_HEADER,"+ complexity_estimation_header; method=%i\n", e->method); if (e->method == 0 || e->method == 1) { if (!BitstreamGetBit(bs)) /* shape_complexity_estimation_disable */ { e->opaque = BitstreamGetBit(bs); /* opaque */ e->transparent = BitstreamGetBit(bs); /* transparent */ e->intra_cae = BitstreamGetBit(bs); /* intra_cae */ e->inter_cae = BitstreamGetBit(bs); /* inter_cae */ e->no_update = BitstreamGetBit(bs); /* no_update */ e->upsampling = BitstreamGetBit(bs); /* upsampling */ } if (!BitstreamGetBit(bs)) /* texture_complexity_estimation_set_1_disable */ { e->intra_blocks = BitstreamGetBit(bs); /* intra_blocks */ e->inter_blocks = BitstreamGetBit(bs); /* inter_blocks */ e->inter4v_blocks = BitstreamGetBit(bs); /* inter4v_blocks */ e->not_coded_blocks = BitstreamGetBit(bs); /* not_coded_blocks */ } } READ_MARKER(); if (!BitstreamGetBit(bs)) /* texture_complexity_estimation_set_2_disable */ { e->dct_coefs = BitstreamGetBit(bs); /* dct_coefs */ e->dct_lines = BitstreamGetBit(bs); /* dct_lines */ e->vlc_symbols = BitstreamGetBit(bs); /* vlc_symbols */ e->vlc_bits = BitstreamGetBit(bs); /* vlc_bits */ } if (!BitstreamGetBit(bs)) /* motion_compensation_complexity_disable */ { e->apm = BitstreamGetBit(bs); /* apm */ e->npm = BitstreamGetBit(bs); /* npm */ e->interpolate_mc_q = BitstreamGetBit(bs); /* interpolate_mc_q */ e->forw_back_mc_q = BitstreamGetBit(bs); /* forw_back_mc_q */ e->halfpel2 = BitstreamGetBit(bs); /* halfpel2 */ e->halfpel4 = BitstreamGetBit(bs); /* halfpel4 */ } READ_MARKER(); if (e->method == 1) { if (!BitstreamGetBit(bs)) /* version2_complexity_estimation_disable */ { e->sadct = BitstreamGetBit(bs); /* sadct */ e->quarterpel = BitstreamGetBit(bs); /* quarterpel */ } }}/* vop estimation header */static voidread_vop_complexity_estimation_header(Bitstream * bs, DECODER * dec, int coding_type){ ESTIMATION * e = &dec->estimation; if (e->method == 0 || e->method == 1) { if (coding_type == I_VOP) { if (e->opaque) BitstreamSkip(bs, 8); /* dcecs_opaque */ if (e->transparent) BitstreamSkip(bs, 8); /* */ if (e->intra_cae) BitstreamSkip(bs, 8); /* */ if (e->inter_cae) BitstreamSkip(bs, 8); /* */ if (e->no_update) BitstreamSkip(bs, 8); /* */ if (e->upsampling) BitstreamSkip(bs, 8); /* */ if (e->intra_blocks) BitstreamSkip(bs, 8); /* */ if (e->not_coded_blocks) BitstreamSkip(bs, 8); /* */ if (e->dct_coefs) BitstreamSkip(bs, 8); /* */ if (e->dct_lines) BitstreamSkip(bs, 8); /* */ if (e->vlc_symbols) BitstreamSkip(bs, 8); /* */ if (e->vlc_bits) BitstreamSkip(bs, 8); /* */ if (e->sadct) BitstreamSkip(bs, 8); /* */ } if (coding_type == P_VOP) { if (e->opaque) BitstreamSkip(bs, 8); /* */ if (e->transparent) BitstreamSkip(bs, 8); /* */ if (e->intra_cae) BitstreamSkip(bs, 8); /* */ if (e->inter_cae) BitstreamSkip(bs, 8); /* */ if (e->no_update) BitstreamSkip(bs, 8); /* */ if (e->upsampling) BitstreamSkip(bs, 8); /* */ if (e->intra_blocks) BitstreamSkip(bs, 8); /* */ if (e->not_coded_blocks) BitstreamSkip(bs, 8); /* */ if (e->dct_coefs) BitstreamSkip(bs, 8); /* */ if (e->dct_lines) BitstreamSkip(bs, 8); /* */ if (e->vlc_symbols) BitstreamSkip(bs, 8); /* */ if (e->vlc_bits) BitstreamSkip(bs, 8); /* */ if (e->inter_blocks) BitstreamSkip(bs, 8); /* */ if (e->inter4v_blocks) BitstreamSkip(bs, 8); /* */ if (e->apm) BitstreamSkip(bs, 8); /* */ if (e->npm) BitstreamSkip(bs, 8); /* */ if (e->forw_back_mc_q) BitstreamSkip(bs, 8); /* */ if (e->halfpel2) BitstreamSkip(bs, 8); /* */ if (e->halfpel4) BitstreamSkip(bs, 8); /* */ if (e->sadct) BitstreamSkip(bs, 8); /* */ if (e->quarterpel) BitstreamSkip(bs, 8); /* */ } if (coding_type == B_VOP) { if (e->opaque) BitstreamSkip(bs, 8); /* */ if (e->transparent) BitstreamSkip(bs, 8); /* */ if (e->intra_cae) BitstreamSkip(bs, 8); /* */ if (e->inter_cae) BitstreamSkip(bs, 8); /* */ if (e->no_update) BitstreamSkip(bs, 8); /* */ if (e->upsampling) BitstreamSkip(bs, 8); /* */ if (e->intra_blocks) BitstreamSkip(bs, 8); /* */ if (e->not_coded_blocks) BitstreamSkip(bs, 8); /* */ if (e->dct_coefs) BitstreamSkip(bs, 8); /* */ if (e->dct_lines) BitstreamSkip(bs, 8); /* */ if (e->vlc_symbols) BitstreamSkip(bs, 8); /* */ if (e->vlc_bits) BitstreamSkip(bs, 8); /* */ if (e->inter_blocks) BitstreamSkip(bs, 8); /* */ if (e->inter4v_blocks) BitstreamSkip(bs, 8); /* */ if (e->apm) BitstreamSkip(bs, 8); /* */ if (e->npm) BitstreamSkip(bs, 8); /* */ if (e->forw_back_mc_q) BitstreamSkip(bs, 8); /* */ if (e->halfpel2) BitstreamSkip(bs, 8); /* */ if (e->halfpel4) BitstreamSkip(bs, 8); /* */ if (e->interpolate_mc_q) BitstreamSkip(bs, 8); /* */ if (e->sadct) BitstreamSkip(bs, 8); /* */ if (e->quarterpel) BitstreamSkip(bs, 8); /* */ } if (coding_type == S_VOP && dec->sprite_enable == SPRITE_STATIC) { if (e->intra_blocks) BitstreamSkip(bs, 8); /* */ if (e->not_coded_blocks) BitstreamSkip(bs, 8); /* */ if (e->dct_coefs) BitstreamSkip(bs, 8); /* */ if (e->dct_lines) BitstreamSkip(bs, 8); /* */ if (e->vlc_symbols) BitstreamSkip(bs, 8); /* */ if (e->vlc_bits) BitstreamSkip(bs, 8); /* */ if (e->inter_blocks) BitstreamSkip(bs, 8); /* */ if (e->inter4v_blocks) BitstreamSkip(bs, 8); /* */ if (e->apm) BitstreamSkip(bs, 8); /* */ if (e->npm) BitstreamSkip(bs, 8); /* */ if (e->forw_back_mc_q) BitstreamSkip(bs, 8); /* */ if (e->halfpel2) BitstreamSkip(bs, 8); /* */ if (e->halfpel4) BitstreamSkip(bs, 8); /* */ if (e->interpolate_mc_q) BitstreamSkip(bs, 8); /* */ } }}/*decode headersreturns coding_type, or -1 if error*/#define VIDOBJ_START_CODE_MASK 0x0000001f#define VIDOBJLAY_START_CODE_MASK 0x0000000fintBitstreamReadHeaders(Bitstream * bs, DECODER * dec, uint32_t * rounding, uint32_t * quant, uint32_t * fcode_forward, uint32_t * fcode_backward, uint32_t * intra_dc_threshold, WARPPOINTS *gmc_warp){ uint32_t vol_ver_id; uint32_t coding_type; uint32_t start_code; uint32_t time_incr = 0; int32_t time_increment = 0; int resize = 0; while ((BitstreamPos(bs) >> 3) + 4 <= bs->length) { BitstreamByteAlign(bs); start_code = BitstreamShowBits(bs, 32); if (start_code == VISOBJSEQ_START_CODE) { int profile; DPRINTF(XVID_DEBUG_STARTCODE, "<visual_object_sequence>\n"); BitstreamSkip(bs, 32); /* visual_object_sequence_start_code */ profile = BitstreamGetBits(bs, 8); /* profile_and_level_indication */ DPRINTF(XVID_DEBUG_HEADER, "profile_and_level_indication %i\n", profile); } else if (start_code == VISOBJSEQ_STOP_CODE) { BitstreamSkip(bs, 32); /* visual_object_sequence_stop_code */ DPRINTF(XVID_DEBUG_STARTCODE, "</visual_object_sequence>\n"); } else if (start_code == VISOBJ_START_CODE) { DPRINTF(XVID_DEBUG_STARTCODE, "<visual_object>\n"); BitstreamSkip(bs, 32); /* visual_object_start_code */ if (BitstreamGetBit(bs)) /* is_visual_object_identified */ { dec->ver_id = BitstreamGetBits(bs, 4); /* visual_object_ver_id */ DPRINTF(XVID_DEBUG_HEADER,"visobj_ver_id %i\n", dec->ver_id); BitstreamSkip(bs, 3); /* visual_object_priority */ } else { dec->ver_id = 1; } if (BitstreamShowBits(bs, 4) != VISOBJ_TYPE_VIDEO) /* visual_object_type */ { DPRINTF(XVID_DEBUG_ERROR, "visual_object_type != video\n"); return -1; } BitstreamSkip(bs, 4); /* video_signal_type */ if (BitstreamGetBit(bs)) /* video_signal_type */ { DPRINTF(XVID_DEBUG_HEADER,"+ video_signal_type\n"); BitstreamSkip(bs, 3); /* video_format */ BitstreamSkip(bs, 1); /* video_range */ if (BitstreamGetBit(bs)) /* color_description */ { DPRINTF(XVID_DEBUG_HEADER,"+ color_description"); BitstreamSkip(bs, 8); /* color_primaries */ BitstreamSkip(bs, 8); /* transfer_characteristics */ BitstreamSkip(bs, 8); /* matrix_coefficients */ } } } else if ((start_code & ~VIDOBJ_START_CODE_MASK) == VIDOBJ_START_CODE) { DPRINTF(XVID_DEBUG_STARTCODE, "<video_object>\n"); DPRINTF(XVID_DEBUG_HEADER, "vo id %i\n", start_code & VIDOBJ_START_CODE_MASK); BitstreamSkip(bs, 32); /* video_object_start_code */ } else if ((start_code & ~VIDOBJLAY_START_CODE_MASK) == VIDOBJLAY_START_CODE) { DPRINTF(XVID_DEBUG_STARTCODE, "<video_object_layer>\n"); DPRINTF(XVID_DEBUG_HEADER, "vol id %i\n", start_code & VIDOBJLAY_START_CODE_MASK); BitstreamSkip(bs, 32); /* video_object_layer_start_code */ BitstreamSkip(bs, 1); /* random_accessible_vol */ BitstreamSkip(bs, 8); /* video_object_type_indication */ if (BitstreamGetBit(bs)) /* is_object_layer_identifier */ { DPRINTF(XVID_DEBUG_HEADER, "+ is_object_layer_identifier\n"); vol_ver_id = BitstreamGetBits(bs, 4); /* video_object_layer_verid */ DPRINTF(XVID_DEBUG_HEADER,"ver_id %i\n", vol_ver_id); BitstreamSkip(bs, 3); /* video_object_layer_priority */ } else { vol_ver_id = dec->ver_id; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -