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

📄 bitstream.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 /******************************************************************************  *                                                                            *  *  This file is part of XviD, a free MPEG-4 video encoder/decoder            *  *                                                                            *  *  XviD is an implementation of a part of one or more MPEG-4 Video tools     *  *  as specified in ISO/IEC 14496-2 standard.  Those intending to use this    *  *  software module in hardware or software products are advised that its     *  *  use may infringe existing patents or copyrights, and any such use         *  *  would be at such party's own risk.  The original developer of this        *  *  software module and his/her company, and subsequent editors and their     *  *  companies, will have no liability for use of this software or             *  *  modifications or derivatives thereof.                                     *  *                                                                            *  *  XviD 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.                                       *  *                                                                            *  *  XviD 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  *  *                                                                            *  ******************************************************************************/ /******************************************************************************  *                                                                            *  *  bitstream.c                                                               *  *                                                                            *  *  Copyright (C) 2001 - Peter Ross <pross@cs.rmit.edu.au>                    *  *                                                                            *  *  For more information visit the XviD homepage: http://www.xvid.org         *  *                                                                            *  ******************************************************************************/ /******************************************************************************  *																			   *	  *  Revision history:                                                         *  *                                                                            *  *  26.03.2002 interlacing support  *  03.03.2002 qmatrix writing												   *  *  03.03.2002 merged BITREADER and BITWRITER								   *  *	 30.02.2002	intra_dc_threshold support									   *  *	 04.12.2001	support for additional headers								   *  *	 16.12.2001	inital version                                           	   *  *																			   *  ******************************************************************************/#include "bitstream.h"#include "zigzag.h"#include "../quant/quant_matrix.h"static int __inline log2bin(int value){	int n = 0;	while (value)	{		value >>= 1;		n++;	}	return n;}static const uint32_t intra_dc_threshold_table[] ={	32,	/* never use */	13,	15,	17,	19,	21,	23,	1,};void bs_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);     	while (i < 64) 	{ 		matrix[ scan_tables[0][i++] ]  = last; 	} } // for PVOP addbits == fcode - 1// for BVOP addbits == max(fcode,bcode) - 1// returns mbposint read_video_packet_header(DECODER * dec,int coding_type,Bitstream *bs, const int addbits, int * quant){	uint32_t mbpos;	uint32_t hec = 0;	int		 mb_num = 0;	int		 mb_pos_len;	int		 val;	int		 nbits = 0;			/* remove ResyncMarker */     nbits = NUMBITS_VP_RESYNC_MARKER + addbits;	BitstreamSkip(bs, BitstreamNumBitsToByteAlign(bs));	BitstreamGetBits(bs,nbits);	DEBUG("<video_packet_header>");	mb_num = dec->mb_width * dec->mb_height;	if (!(mb_num>0)) {			DEBUG("video_packet_header : mb_num = 0");		return 0;	}	/* evaluate LengthOfMBNumber (log(mb_num-1)/log(2)) + 1 */   	val = mb_num - 1;	mb_pos_len = 0;	for(; val; mb_pos_len++)		val>>=1;	mbpos = 0;	if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {		hec = BitstreamGetBits(bs,NUMBITS_VP_HEC);		/* warning : do not work with sprite */		if (hec) {			int marker;			int left;			int top;			/* width */			BitstreamGetBits(bs,NUMBITS_VOP_WIDTH);			marker = BitstreamGetBits(bs,1); // marker bit			if (!(marker==1)) {					DEBUG("video_packet_header : marker = 0");				return 0;			}					/* height */ 			BitstreamGetBits(bs,NUMBITS_VOP_HEIGHT);			marker = BitstreamGetBits(bs,1); // marker bit			if (!(marker==1)) {					DEBUG("video_packet_header : marker = 0");				return 0;			}				/* left corner */			left = (BitstreamGetBits(bs,1) == 0) ?					BitstreamGetBits(bs,NUMBITS_VOP_HORIZONTAL_SPA_REF - 1) : 					((int)BitstreamGetBits(bs,NUMBITS_VOP_HORIZONTAL_SPA_REF - 1) - (1 << (NUMBITS_VOP_HORIZONTAL_SPA_REF - 1)));			marker = BitstreamGetBits(bs,1); // marker bit			if (!(marker==1)) {					DEBUG("video_packet_header : marker = 0");				return 0;			}			/* top corner */			top = (BitstreamGetBits(bs,1) == 0) ?				   BitstreamGetBits(bs,NUMBITS_VOP_VERTICAL_SPA_REF - 1) : 				   ((int)BitstreamGetBits(bs,NUMBITS_VOP_VERTICAL_SPA_REF - 1) - (1 << (NUMBITS_VOP_VERTICAL_SPA_REF - 1)));			marker = BitstreamGetBits(bs,1); // marker bit			if (!(marker==1)) {					DEBUG("video_packet_header : marker = 0");				return 0;			}			/* must be even pix unit */			if (!(((left | top)&1)==0)) {					DEBUG("video_packet_header : marker = 0");				return 0;			}	  }	}	/* reading mbpos */	if(mb_num>1)		mbpos = BitstreamGetBits(bs,mb_pos_len);		/* reading quant */	if(dec->shape!=VIDOBJLAY_SHAPE_BINARY_ONLY) {		*quant = BitstreamGetBits(bs,NUMBITS_VP_QUANTIZER);	}	if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR)		hec = BitstreamGetBits(bs,NUMBITS_VP_HEC);	if (hec){		DEBUG("Time reference and VOP_pred_type not supported");	}	return	mbpos;}/*decode headersreturns coding_type, or -1 if error*/int BitstreamReadHeaders(Bitstream * bs, DECODER * dec, uint32_t * rounding, 			 uint32_t * quant, uint32_t * fcode, uint32_t * intra_dc_threshold,			 int findvol){	uint32_t vol_ver_id;	uint32_t time_inc_resolution;	uint32_t coding_type;	uint32_t start_code;#ifdef MPEG4IP	uint32_t width, height;#endif		do	{		BitstreamByteAlign(bs);		start_code = BitstreamShowBits(bs, 32);		if (start_code == VISOBJSEQ_START_CODE)		{			// DEBUG("visual_object_sequence");			BitstreamSkip(bs, 32);				// visual_object_sequence_start_code			BitstreamSkip(bs, 8);					// profile_and_level_indication		}		else if (start_code == VISOBJSEQ_STOP_CODE)		{			BitstreamSkip(bs, 32);				// visual_object_sequence_stop_code		}		else if (start_code == VISOBJ_START_CODE)		{			// DEBUG("visual_object");			BitstreamSkip(bs,32);					// visual_object_start_code			if (BitstreamGetBit(bs))				// is_visual_object_identified			{				vol_ver_id = BitstreamGetBits(bs,4);	// visual_object_ver_id				BitstreamSkip(bs, 3);				// visual_object_priority			}			else			{				vol_ver_id = 1;			}			if (BitstreamShowBits(bs, 4) != VISOBJ_TYPE_VIDEO)	// visual_object_type			{				DEBUG("visual_object_type != video");				return -1;			}			BitstreamSkip(bs, 4);			// video_signal_type			if (BitstreamGetBit(bs))				// video_signal_type			{				DEBUG("+ video_signal_type");				BitstreamSkip(bs, 3);				// video_format				BitstreamSkip(bs, 1);				// video_range				if (BitstreamGetBit(bs))			// color_description				{					DEBUG("+ color_description");					BitstreamSkip(bs, 8);			// color_primaries					BitstreamSkip(bs, 8);			// transfer_characteristics					BitstreamSkip(bs, 8);			// matrix_coefficients				}			}		}		else if ((start_code & ~0x1f) == VIDOBJ_START_CODE)		{			BitstreamSkip(bs, 32);		// video_object_start_code		} 		else if ((start_code & ~0xf) == VIDOBJLAY_START_CODE)		{			// DEBUG("video_object_layer");			BitstreamSkip(bs, 32);					// video_object_layer_start_code			BitstreamSkip(bs, 1);									// random_accessible_vol			// video_object_type_indication			if (BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_SIMPLE &&				BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_CORE &&				BitstreamShowBits(bs, 8) != VIDOBJLAY_TYPE_MAIN &&				BitstreamShowBits(bs, 8) != 0)		// BUGGY DIVX			{				DEBUG1("video_object_type_indication not supported", BitstreamShowBits(bs, 8));				return -1;			}			BitstreamSkip(bs, 8);			if (BitstreamGetBit(bs))					// is_object_layer_identifier			{				DEBUG("+ is_object_layer_identifier");				vol_ver_id = BitstreamGetBits(bs,4);		// video_object_layer_verid				BitstreamSkip(bs, 3);					// video_object_layer_priority			}			else			{				vol_ver_id = 1;			}			//DEBUGI("vol_ver_id", vol_ver_id);			if (BitstreamGetBits(bs, 4) == VIDOBJLAY_AR_EXTPAR)	// aspect_ratio_info			{				DEBUG("+ aspect_ratio_info");				BitstreamSkip(bs, 8);						// par_width				BitstreamSkip(bs, 8);						// par_height			}			if (BitstreamGetBit(bs))		// vol_control_parameters			{				DEBUG("+ vol_control_parameters");				BitstreamSkip(bs, 2);						// chroma_format				BitstreamSkip(bs, 1);						// low_delay				if (BitstreamGetBit(bs))					// vbv_parameters				{					DEBUG("+ vbv_parameters");					BitstreamSkip(bs, 15);				// first_half_bitrate					READ_MARKER();					BitstreamSkip(bs, 15);				// latter_half_bitrate					READ_MARKER();					BitstreamSkip(bs, 15);				// first_half_vbv_buffer_size					READ_MARKER();					BitstreamSkip(bs, 3);					// latter_half_vbv_buffer_size					BitstreamSkip(bs, 11);				// first_half_vbv_occupancy					READ_MARKER();					BitstreamSkip(bs, 15);				// latter_half_vbv_occupancy					READ_MARKER();								}			}			dec->shape = BitstreamGetBits(bs, 2);	// video_object_layer_shape			// DEBUG1("shape", dec->shape);						if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1)			{				BitstreamSkip(bs, 4);		// video_object_layer_shape_extension			}			READ_MARKER();			time_inc_resolution = BitstreamGetBits(bs, 16);	// vop_time_increment_resolution			time_inc_resolution--;			if (time_inc_resolution > 0)			{				dec->time_inc_bits = log2bin(time_inc_resolution);			}			else			{				// dec->time_inc_bits = 0;				// for "old" xvid compatibility, set time_inc_bits = 1				dec->time_inc_bits = 1;			}			READ_MARKER();			if (BitstreamGetBit(bs))						// fixed_vop_rate			{				BitstreamSkip(bs, dec->time_inc_bits);	// fixed_vop_time_increment			}			if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY)			{				if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR)				{					uint32_t width, height;					READ_MARKER();					width = BitstreamGetBits(bs, 13);			// video_object_layer_width					//DEBUGI("width", width);					READ_MARKER();					height = BitstreamGetBits(bs, 13);		// video_object_layer_height					//DEBUGI("height", height);						READ_MARKER();					if (findvol == 0) {					  if (width != dec->width || height != dec->height)					    {					      DEBUG("FATAL: video dimension discrepancy ***");					      DEBUG2("bitstream width/height", width, height);					      DEBUG2("param width/height", dec->width, dec->height);					      return -1;					    }					} else {					  dec->width = width;					  dec->height = height;					}				}				if ((dec->interlacing = BitstreamGetBit(bs)))				{					DEBUG("vol: interlacing");				}				if (!BitstreamGetBit(bs))				// obmc_disable				{					DEBUG("IGNORED/TODO: !obmc_disable");					// TODO					// fucking divx4.02 has this enabled				}				if (BitstreamGetBits(bs, (vol_ver_id == 1 ? 1 : 2)))  // sprite_enable				{					DEBUG("sprite_enable; not supported");					return -1;				}							if (vol_ver_id != 1 && dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR)				{					BitstreamSkip(bs, 1);					// sadct_disable				}				if (BitstreamGetBit(bs))						// not_8_bit				{					DEBUG("+ not_8_bit [IGNORED/TODO]");					dec->quant_bits = BitstreamGetBits(bs, 4);	// quant_precision					BitstreamSkip(bs, 4);						// bits_per_pixel				}				else				{					dec->quant_bits = 5;				}				if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE)				{					BitstreamSkip(bs, 1);			// no_gray_quant_update					BitstreamSkip(bs, 1);			// composition_method					BitstreamSkip(bs, 1);			// linear_composition				}				dec->quant_type = BitstreamGetBit(bs);		// quant_type				// DEBUG1("**** quant_type", dec->quant_type);				if (dec->quant_type)				{					if (BitstreamGetBit(bs))		// load_intra_quant_mat					{						uint8_t matrix[64];						bs_get_matrix(bs, matrix);						set_intra_matrix(matrix);					}					else						set_intra_matrix(get_default_intra_matrix());					if (BitstreamGetBit(bs))		// load_inter_quant_mat					{						uint8_t matrix[64]; 						bs_get_matrix(bs, matrix);						set_inter_matrix(matrix);					}					else						set_inter_matrix(get_default_inter_matrix());					if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE)					{						// TODO						DEBUG("TODO: grayscale matrix stuff");						return -1;					}				}							if (vol_ver_id != 1)				{					dec->quarterpel = BitstreamGetBit(bs);	// quarter_sampe					if (dec->quarterpel)					{						DEBUG("IGNORED/TODO: quarter_sample");					}				}				else				{

⌨️ 快捷键说明

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