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

📄 bitstream.c

📁 基于Linux的ffmepg decoder
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include "bitstream.h"#include "zigzag.h"#include "../quant/quant_matrix.h"#include "../local_mem.h"#include "../define.h"#include "../vpe.h"#include "../mp4.h"int old_time_incre;uint32_t time_increment_resolution;/***************************************************************************** * Functions ****************************************************************************/static int32_t vop_width[8] = {0, 128, 176, 352, 704, 1408, 0, 0};static int32_t vop_height[8] = {0, 96, 144, 288, 576, 1152, 0, 0};static uint32_t __inlinelog2bin(uint32_t value){/* Changed by Chenm001 */	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,};*/voidbs_get_matrix(Bitstream * bs,			  uint8_t * matrix){	int i = 0, j = 0;	int last, value = 0;	do {		last = value;		j++;		if (j == 8) {			j=0;		}		value = BitstreamGetBits(bs, 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;	}}boolbRead_video_packet_header(DECODER * dec,						int *fcode_forward,						int *fcode_backward,						int32_t * mbnum){	int tmp;	int coding_type;	uint32_t * Table_Output = ((uint32_t *) ((uint32_t)dec->pu32BaseAddr + TABLE_OUTPUT_OFF));	tmp = Table_Output[0] & 0xFFFF;		/* macroblock_number */	if (dec->h263==1)		*mbnum = (tmp >> 2) * dec->mb_width;	else {		*mbnum = tmp;		//extent bit		if (Table_Output[0] & BIT24) {			coding_type = Table_Output[2] & 0xff;			// hardware not support			if (coding_type >= B_VOP)				return -1;			if (coding_type != I_VOP && *fcode_forward)				*fcode_forward = (Table_Output[2] >> 16) & 0xff;			if (coding_type == B_VOP && *fcode_backward)				*fcode_backward = 0;		}	}	return 0;}/*decode headersreturns coding_type, or -1 if error*/#define VIDOBJ_START_CODE_MASK		0x0000001f#define VIDOBJLAY_START_CODE_MASK	0x0000000f#define VIDO_SHORT_HEADER_MASK 0x000003ff#define VIDO_SHORT_HEADER 0x8000#define VIDO_SHORT_HEADER_END 0x3fintBitstreamReadHeaders(Bitstream * bs,					 DECODER * dec,					 uint32_t * rounding,					 uint32_t * quant,					 uint32_t * fcode_forward,					 uint32_t * fcode_backward,					 uint32_t * intra_dc_threshold_bit){	uint32_t vol_ver_id;	uint32_t coding_type;	uint32_t start_code;	uint32_t time_incr = 0;	int32_t time_increment = 0;	do {		BitstreamByteAlign(bs);		start_code = BitstreamShowBits(bs, 32);		vVpe_Indicator(0x93000000 | (start_code >> 16));		vVpe_Indicator(0x93000000 | (start_code & 0xFFFF));		if (start_code == VISOBJSEQ_START_CODE) {			int profile;			BitstreamSkip(bs, 32);	/* visual_object_sequence_start_code */			profile = BitstreamGetBits(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) {			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 */			{				return -1;			}			BitstreamSkip(bs, 4);			/* video_signal_type */			if (BitstreamGetBit(bs))	/* video_signal_type */			{				BitstreamSkip(bs, 3);	/* video_format */				BitstreamSkip(bs, 1);	/* video_range */				if (BitstreamGetBit(bs))	/* 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) {			BitstreamSkip(bs, 32);	/* video_object_start_code */		} else if ((start_code & ~VIDO_SHORT_HEADER_MASK) == VIDO_SHORT_HEADER) {			int temp, pei, psupp = 0;			uint32_t width, height;		// ben add			dec->h263 = 1;			dec->quant_type = 0;			*fcode_forward = 1;			dec->quarterpel = 0;			BitstreamSkip(bs, 22);			BitstreamSkip(bs, 8);			READ_MARKER();			temp = BitstreamGetBit(bs);			//  zero_bit			dec->split_screen_indicator = BitstreamGetBit(bs);			//  split_screen_indicator			dec->document_camera_indicator = BitstreamGetBit(bs);			//  document_camera_indicator			dec->full_picture_freeze_release = BitstreamGetBit(bs);			//  full_picture_freeze_release			dec->source_format = BitstreamGetBits(bs,3);			//  source_format			dec->picture_coding_type = BitstreamGetBit(bs);			//  picture_coding_type			temp = BitstreamGetBits(bs,4);			//  four_reserved_zero_bits			*quant = BitstreamGetBits(bs,5);		//	quant			temp = BitstreamGetBit(bs);			//  zero_bit			do {				pei = BitstreamGetBit(bs);				if (pei == 1)					psupp=BitstreamGetBits(bs,8);			} while (pei == 1);			width = vop_width[dec->source_format];			height = vop_height[dec->source_format];//ben add#if 0			dec->width = width;			dec->height = height;#else			/* for auto set width & height */			if (dec->width == 0)					dec->width = width;			if (dec->height == 0)				dec->height = height;			if (width != dec->width || height != dec->height)				return -1;#endif			return dec->picture_coding_type;		}		else if ((start_code & ~VIDOBJLAY_START_CODE_MASK) == VIDOBJLAY_START_CODE) {			BitstreamSkip(bs, 32);	/* video_object_layer_start_code */			BitstreamSkip(bs, 1);	/* random_accessible_vol */			dec->h263 = 0;			/* 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 */			{				return -1;			}			BitstreamSkip(bs, 8);			if (BitstreamGetBit(bs))	/* 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;			}			if (BitstreamGetBits(bs, 4) == VIDOBJLAY_AR_EXTPAR)	/* aspect_ratio_info */			{				BitstreamSkip(bs, 8);	/* par_width */				BitstreamSkip(bs, 8);	/* par_height */			}			if (BitstreamGetBit(bs))	/* vol_control_parameters */			{				BitstreamSkip(bs, 2);	/* chroma_format */				dec->low_delay = (uint8_t)BitstreamGetBit(bs);	/* low_delay */				if (BitstreamGetBit(bs))	/* 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 */			if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1) {				BitstreamSkip(bs, 4);	/* video_object_layer_shape_extension */			}			READ_MARKER();/* *************************** for decode B-frame time *********************** */			time_increment_resolution = BitstreamGetBits(bs, 16);	/* vop_time_increment_resolution *//*			time_increment_resolution--; */			if (time_increment_resolution > 0) {				dec->time_inc_bits = MAX(log2bin(time_increment_resolution-1), 1);			} 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 */					READ_MARKER();					height = BitstreamGetBits(bs, 13);	/* video_object_layer_height */					READ_MARKER();#if 0				//ben modify					dec->width = width;					dec->height = height;#else					/* for auto set width & height */					if (dec->width == 0)							dec->width = width;					if (dec->height == 0)						dec->height = height;					if (width != dec->width || height != dec->height)						return -1;#endif				}				dec->interlacing = BitstreamGetBit(bs);				if (!BitstreamGetBit(bs))	/* obmc_disable */				{					/* TODO */					/* fucking divx4.02 has this enabled */				}				if (BitstreamGetBits(bs, (vol_ver_id == 1 ? 1 : 2)))	/* sprite_enable */				{					return -1;				}				if (vol_ver_id != 1 &&					dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {					BitstreamSkip(bs, 1);	/* sadct_disable */				}				if (BitstreamGetBit(bs))	/* not_8_bit */				{					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 */				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) {						return -1;					}				}				if (vol_ver_id != 1) {					dec->quarterpel = BitstreamGetBit(bs);	/* quarter_sample */				}				else {					dec->quarterpel = 0;				}				if (!BitstreamGetBit(bs))	/* complexity_estimation_disable */				{					return -1;				}				dec->resync_marker_disable = BitstreamGetBits(bs,1);				/* resync_marker_disable */				dec->data_partitioned = BitstreamGetBits(bs,1);				if (dec->data_partitioned)	/* data_partitioned */				{					dec->reversible_vlc = BitstreamGetBits(bs,1);				}				if (vol_ver_id != 1) {					if (BitstreamGetBit(bs))	/* newpred_enable */					{						BitstreamSkip(bs, 2);	/* requested_upstream_message_type */						BitstreamSkip(bs, 1);	/* newpred_segment_type */					}					if (BitstreamGetBit(bs))	/* reduced_resolution_vop_enable */					{						return -1;					}				}				if ((dec->scalability = (int8_t)BitstreamGetBit(bs)))	/* scalability */				{					return -1;				}			} else				/* dec->shape == BINARY_ONLY */			{				if (vol_ver_id != 1) {					if (BitstreamGetBit(bs))	/* scalability */					{						return -1;					}				}				BitstreamSkip(bs, 1);	/* resync_marker_disable */			}		}		else if (start_code == GRPOFVOP_START_CODE) {			BitstreamSkip(bs, 32);			{				int hours, minutes, seconds;				hours = BitstreamGetBits(bs, 5);				minutes = BitstreamGetBits(bs, 6);				READ_MARKER();				seconds = BitstreamGetBits(bs, 6);							}			BitstreamSkip(bs, 1);	/* closed_gov */			BitstreamSkip(bs, 1);	/* broken_link */		} else if (start_code == VOP_START_CODE) {			BitstreamSkip(bs, 32);	/* vop_start_code */			coding_type = BitstreamGetBits(bs, 2);	/* vop_coding_type */			dec->picture_coding_type = coding_type;//**********************NOTE*****************************************			coding_type = coding_type & 0x1;/* *************************** for decode B-frame time *********************** */			while (BitstreamGetBit(bs) != 0)	/* time_base */				time_incr++;			READ_MARKER();			if (dec->time_inc_bits) {				time_increment = (BitstreamGetBits(bs, dec->time_inc_bits));	/* vop_time_increment */			}			if (coding_type != B_VOP) {				dec->last_time_base = dec->time_base;				dec->time_base += time_incr;				dec->time = time_increment;/*					dec->time_base * time_increment_resolution +					time_increment;*/				if (time_increment_resolution!= 0)					dec->time_pp = (uint32_t) 						(time_increment_resolution + dec->time - dec->last_non_b_time)%time_increment_resolution;				dec->last_non_b_time = dec->time;			} else {				dec->time = time_increment; /*					(dec->last_time_base +					 time_incr) * time_increment_resolution + time_increment; */				dec->time_bp = (uint32_t) 					(time_increment_resolution + dec->last_non_b_time - dec->time)%time_increment_resolution;			}			READ_MARKER();			if (!BitstreamGetBit(bs))	/* vop_coded */			{				return N_VOP;			}			/* fix a little bug by MinChen <chenm002@163.com> */			if ((dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) &&				(coding_type == P_VOP)) {				*rounding = BitstreamGetBit(bs);	/* rounding_type */			}			if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {				uint32_t width, height;				uint32_t horiz_mc_ref, vert_mc_ref;				width = BitstreamGetBits(bs, 13);				READ_MARKER();				height = BitstreamGetBits(bs, 13);				READ_MARKER();				horiz_mc_ref = BitstreamGetBits(bs, 13);				READ_MARKER();				vert_mc_ref = BitstreamGetBits(bs, 13);				READ_MARKER();				BitstreamSkip(bs, 1);	/* change_conv_ratio_disable */				if (BitstreamGetBit(bs))	/* vop_constant_alpha */				{					BitstreamSkip(bs, 8);	/* vop_constant_alpha_value */				}			}			if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) {				/* intra_dc_vlc_threshold */				* intra_dc_threshold_bit= BitstreamGetBits(bs, 3);//				* intra_dc_threshold_bit= BitstreamShowBits(bs, 3);//				*intra_dc_threshold = intra_dc_threshold_table[BitstreamGetBits(bs, 3)];				if (dec->interlacing) {					dec->top_field_first = BitstreamGetBit(bs);					dec->alternate_vertical_scan = BitstreamGetBit(bs);				}			}			if ((*quant = BitstreamGetBits(bs, dec->quant_bits)) < 1)	/* vop_quant */				*quant = 1;			if (coding_type != I_VOP) {				*fcode_forward = BitstreamGetBits(bs, 3);	/* fcode_forward *///**********************NOTE*****************************************				if (*fcode_forward < 1) *fcode_forward = 1;			}			if (coding_type == B_VOP) {				*fcode_backward = BitstreamGetBits(bs, 3);	/* fcode_backward */			}			if (!dec->scalability) {				if ((dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) &&					(coding_type != I_VOP)) {					BitstreamSkip(bs, 1);	/* vop_shape_coding_type */				}			}			return coding_type;		} else if (start_code == USERDATA_START_CODE) {			BitstreamSkip(bs, 32);	/* user_data_start_code */		} else					/* start_code == ? */		{			if (BitstreamShowBits(bs, 24) == 0x000001) {			}			BitstreamSkip(bs, 8);		}	}	while ((BitstreamPos(bs) >> 3) < bs->length);	return -1;					/* ignore it */}

⌨️ 快捷键说明

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