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

📄 bitstream.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
			}			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) {			char tmp[256];		    int i, version, build;			char packed;			BitstreamSkip(bs, 32);	/* user_data_start_code */			memset(tmp, 0, 256);			tmp[0] = BitstreamShowBits(bs, 8);			for(i = 1; i < 256; i++){				tmp[i] = (BitstreamShowBits(bs, 16) & 0xFF);				if(tmp[i] == 0)					break;				BitstreamSkip(bs, 8);			}			DPRINTF(XVID_DEBUG_STARTCODE, "<user_data>: %s\n", tmp);			/* read xvid bitstream version */			if(strncmp(tmp, "XviD", 4) == 0) {				if (tmp[strlen(tmp)-1] == 'C') {									sscanf(tmp, "XviD%dC", &dec->bs_version);					dec->cartoon_mode = 1;				}				else					sscanf(tmp, "XviD%d", &dec->bs_version);				DPRINTF(XVID_DEBUG_HEADER, "xvid bitstream version=%i\n", dec->bs_version);			}		    /* divx detection */			i = sscanf(tmp, "DivX%dBuild%d%c", &version, &build, &packed);			if (i < 2)				i = sscanf(tmp, "DivX%db%d%c", &version, &build, &packed);			if (i >= 2)			{				dec->packed_mode = (i == 3 && packed == 'p');				DPRINTF(XVID_DEBUG_HEADER, "divx version=%i, build=%i packed=%i\n",						version, build, dec->packed_mode);			}		} else					/* start_code == ? */		{			if (BitstreamShowBits(bs, 24) == 0x000001) {				DPRINTF(XVID_DEBUG_STARTCODE, "<unknown: %x>\n", BitstreamShowBits(bs, 32));			}			BitstreamSkip(bs, 8);		}	}#if 0	DPRINTF("*** WARNING: no vop_start_code found");#endif	return -1;					/* ignore it */}/* write custom quant matrix */static voidbs_put_matrix(Bitstream * bs,			  const uint16_t * matrix){	int i, j;	const int last = matrix[scan_tables[0][63]];	for (j = 63; j > 0 && matrix[scan_tables[0][j - 1]] == last; j--);	for (i = 0; i <= j; i++) {		BitstreamPutBits(bs, matrix[scan_tables[0][i]], 8);	}	if (j < 63) {		BitstreamPutBits(bs, 0, 8);	}}/*	write vol header*/voidBitstreamWriteVolHeader(Bitstream * const bs,						const MBParam * pParam,						const FRAMEINFO * const frame){	static const unsigned int vo_id = 0;	static const unsigned int vol_id = 0;	int vol_ver_id = 1;	int vol_type_ind = VIDOBJLAY_TYPE_SIMPLE;	int vol_profile = pParam->profile;	if ( (pParam->vol_flags & XVID_VOL_QUARTERPEL) ||         (pParam->vol_flags & XVID_VOL_GMC))		vol_ver_id = 2;    if ((pParam->vol_flags & (XVID_VOL_MPEGQUANT|XVID_VOL_QUARTERPEL|XVID_VOL_GMC|XVID_VOL_INTERLACING)) ||         pParam->max_bframes>0) {        vol_type_ind = VIDOBJLAY_TYPE_ASP;    }	/* visual_object_sequence_start_code */#if 0	BitstreamPad(bs);#endif	/*	 * no padding here, anymore. You have to make sure that you are	 * byte aligned, and that always 1-8 padding bits have been written	 */    if (!vol_profile) {		/* Profile was not set by client app, use the more permissive profile		 * compatible with the vol_type_id */		switch(vol_type_ind) {		case VIDOBJLAY_TYPE_ASP:			vol_profile = 0xf5; /* ASP level 5 */			break;		case VIDOBJLAY_TYPE_ART_SIMPLE:			vol_profile = 0x94; /* ARTS level 4 */			break;		default:			vol_profile = 0x03; /* Simple level 3 */			break;		}	}	/* Write the VOS header */	BitstreamPutBits(bs, VISOBJSEQ_START_CODE, 32);	BitstreamPutBits(bs, vol_profile, 8); 	/* profile_and_level_indication */	/* visual_object_start_code */	BitstreamPad(bs);	BitstreamPutBits(bs, VISOBJ_START_CODE, 32);	BitstreamPutBits(bs, 0, 1);		/* is_visual_object_identifier */	/* Video type */	BitstreamPutBits(bs, VISOBJ_TYPE_VIDEO, 4);		/* visual_object_type */	BitstreamPutBit(bs, 0); /* video_signal_type */	/* video object_start_code & vo_id */	BitstreamPadAlways(bs); /* next_start_code() */	BitstreamPutBits(bs, VIDOBJ_START_CODE|(vo_id&0x5), 32);	/* video_object_layer_start_code & vol_id */	BitstreamPad(bs);	BitstreamPutBits(bs, VIDOBJLAY_START_CODE|(vol_id&0x4), 32);	BitstreamPutBit(bs, 0);		/* random_accessible_vol */	BitstreamPutBits(bs, vol_type_ind, 8);	/* video_object_type_indication */	if (vol_ver_id == 1) {		BitstreamPutBit(bs, 0);				/* is_object_layer_identified (0=not given) */	} else {		BitstreamPutBit(bs, 1);		/* is_object_layer_identified */		BitstreamPutBits(bs, vol_ver_id, 4);	/* vol_ver_id == 2 */		BitstreamPutBits(bs, 4, 3); /* vol_ver_priority (1==highest, 7==lowest) */	}	/* Aspect ratio */	BitstreamPutBits(bs, pParam->par, 4); /* aspect_ratio_info (1=1:1) */	if(pParam->par == XVID_PAR_EXT) {		BitstreamPutBits(bs, pParam->par_width, 8);		BitstreamPutBits(bs, pParam->par_height, 8);	}	BitstreamPutBit(bs, 1);	/* vol_control_parameters */	BitstreamPutBits(bs, 1, 2);	/* chroma_format 1="4:2:0" */	if (pParam->max_bframes > 0) {		BitstreamPutBit(bs, 0);	/* low_delay */	} else	{		BitstreamPutBit(bs, 1);	/* low_delay */	}	BitstreamPutBit(bs, 0);	/* vbv_parameters (0=not given) */	BitstreamPutBits(bs, 0, 2);	/* video_object_layer_shape (0=rectangular) */	WRITE_MARKER();	/*	 * time_inc_resolution; ignored by current decore versions	 * eg. 2fps     res=2       inc=1	 *     25fps    res=25      inc=1	 *     29.97fps res=30000   inc=1001	 */	BitstreamPutBits(bs, pParam->fbase, 16);	WRITE_MARKER();    if (pParam->fincr>0) {		BitstreamPutBit(bs, 1);		/* fixed_vop_rate = 1 */		BitstreamPutBits(bs, pParam->fincr, MAX(log2bin(pParam->fbase-1),1));	/* fixed_vop_time_increment */    }else{        BitstreamPutBit(bs, 0);		/* fixed_vop_rate = 0 */    }	WRITE_MARKER();	BitstreamPutBits(bs, pParam->width, 13);	/* width */	WRITE_MARKER();	BitstreamPutBits(bs, pParam->height, 13);	/* height */	WRITE_MARKER();	BitstreamPutBit(bs, pParam->vol_flags & XVID_VOL_INTERLACING);	/* interlace */	BitstreamPutBit(bs, 1);		/* obmc_disable (overlapped block motion compensation) */	if (vol_ver_id != 1)	{	if ((pParam->vol_flags & XVID_VOL_GMC))		{	BitstreamPutBits(bs, 2, 2);		/* sprite_enable=='GMC' */			BitstreamPutBits(bs, 3, 6);		/* no_of_sprite_warping_points */			BitstreamPutBits(bs, 3, 2);		/* sprite_warping_accuracy 0==1/2, 1=1/4, 2=1/8, 3=1/16 */			BitstreamPutBit(bs, 0);			/* sprite_brightness_change (not supported) */			/*			 * currently we use no_of_sprite_warping_points==2, sprite_warping_accuracy==3			 * for DivX5 compatability			 */		} else			BitstreamPutBits(bs, 0, 2);		/* sprite_enable==off */	}	else		BitstreamPutBit(bs, 0);		/* sprite_enable==off */	BitstreamPutBit(bs, 0);		/* not_8_bit */	/* quant_type   0=h.263  1=mpeg4(quantizer tables) */	BitstreamPutBit(bs, pParam->vol_flags & XVID_VOL_MPEGQUANT);	if ((pParam->vol_flags & XVID_VOL_MPEGQUANT)) {		BitstreamPutBit(bs, is_custom_intra_matrix(pParam->mpeg_quant_matrices));	/* load_intra_quant_mat */		if(is_custom_intra_matrix(pParam->mpeg_quant_matrices))			bs_put_matrix(bs, get_intra_matrix(pParam->mpeg_quant_matrices));		BitstreamPutBit(bs, is_custom_inter_matrix(pParam->mpeg_quant_matrices));	/* load_inter_quant_mat */		if(is_custom_inter_matrix(pParam->mpeg_quant_matrices))			bs_put_matrix(bs, get_inter_matrix(pParam->mpeg_quant_matrices));	}	if (vol_ver_id != 1) {		if ((pParam->vol_flags & XVID_VOL_QUARTERPEL))			BitstreamPutBit(bs, 1);	 	/* quarterpel  */		else			BitstreamPutBit(bs, 0);		/* no quarterpel */	}	BitstreamPutBit(bs, 1);		/* complexity_estimation_disable */	BitstreamPutBit(bs, 1);		/* resync_marker_disable */	BitstreamPutBit(bs, 0);		/* data_partitioned */	if (vol_ver_id != 1) {		BitstreamPutBit(bs, 0);		/* newpred_enable */		BitstreamPutBit(bs, 0);		/* reduced_resolution_vop_enabled */	}	BitstreamPutBit(bs, 0);		/* scalability */	BitstreamPadAlways(bs); /* next_start_code(); */	/* divx5 userdata string */#define DIVX5_ID ((char *)"DivX503b1393")  if ((pParam->global_flags & XVID_GLOBAL_DIVX5_USERDATA)) {    BitstreamWriteUserData(bs, DIVX5_ID, strlen(DIVX5_ID));  	if (pParam->max_bframes > 0 && (pParam->global_flags & XVID_GLOBAL_PACKED))      BitstreamPutBits(bs, 'p', 8);	}	/* xvid id */	{		const char xvid_user_format[] = "XviD%04d%c";		char xvid_user_data[100];		sprintf(xvid_user_data,				xvid_user_format,				XVID_BS_VERSION,				(frame->vop_flags & XVID_VOP_CARTOON)?'C':'\0');		BitstreamWriteUserData(bs, xvid_user_data, strlen(xvid_user_data));	}}/*  write vop header*/voidBitstreamWriteVopHeader(						Bitstream * const bs,						const MBParam * pParam,						const FRAMEINFO * const frame,						int vop_coded,						unsigned int quant){	uint32_t i;#if 0	BitstreamPad(bs);#endif	/*	 * no padding here, anymore. You have to make sure that you are	 * byte aligned, and that always 1-8 padding bits have been written	 */	BitstreamPutBits(bs, VOP_START_CODE, 32);	BitstreamPutBits(bs, frame->coding_type, 2);#if 0	DPRINTF(XVID_DEBUG_HEADER, "coding_type = %i\n", frame->coding_type);#endif	for (i = 0; i < frame->seconds; i++) {		BitstreamPutBit(bs, 1);	}	BitstreamPutBit(bs, 0);	WRITE_MARKER();	/* time_increment: value=nth_of_sec, nbits = log2(resolution) */	BitstreamPutBits(bs, frame->ticks, MAX(log2bin(pParam->fbase-1), 1));#if 0	DPRINTF("[%i:%i] %c",			frame->seconds, frame->ticks,			frame->coding_type == I_VOP ? 'I' :			frame->coding_type == P_VOP ? 'P' :			frame->coding_type == S_VOP ? 'S' :	'B');#endif	WRITE_MARKER();	if (!vop_coded) {		BitstreamPutBits(bs, 0, 1);#if 0		BitstreamPadAlways(bs); /*  next_start_code() */#endif		/* NB: It's up to the function caller to write the next_start_code().		 * At the moment encoder.c respects that requisite because a VOP		 * always ends with a next_start_code either if it's coded or not		 * and encoder.c terminates a frame with a next_start_code in whatever		 * case */		return;	}	BitstreamPutBits(bs, 1, 1);	/* vop_coded */	if ( (frame->coding_type == P_VOP) || (frame->coding_type == S_VOP) )		BitstreamPutBits(bs, frame->rounding_type, 1);	BitstreamPutBits(bs, 0, 3);	/* intra_dc_vlc_threshold */	if ((frame->vol_flags & XVID_VOL_INTERLACING)) {		BitstreamPutBit(bs, (frame->vop_flags & XVID_VOP_TOPFIELDFIRST));		BitstreamPutBit(bs, (frame->vop_flags & XVID_VOP_ALTERNATESCAN));	}	if (frame->coding_type == S_VOP) {		if (1)	{		/* no_of_sprite_warping_points>=1 (we use 2!) */			int k;			for (k=0;k<3;k++)			{				bs_put_spritetrajectory(bs, frame->warp.duv[k].x ); /* du[k]  */				WRITE_MARKER();				bs_put_spritetrajectory(bs, frame->warp.duv[k].y ); /* dv[k]  */				WRITE_MARKER();			if ((frame->vol_flags & XVID_VOL_QUARTERPEL))			{				DPRINTF(XVID_DEBUG_HEADER,"sprite_warping_point[%i] xy=(%i,%i) *QPEL*\n", k, frame->warp.duv[k].x/2, frame->warp.duv[k].y/2);			}			else			{				DPRINTF(XVID_DEBUG_HEADER,"sprite_warping_point[%i] xy=(%i,%i)\n", k, frame->warp.duv[k].x, frame->warp.duv[k].y);			}			}		}	}#if 0	DPRINTF(XVID_DEBUG_HEADER, "quant = %i\n", quant);#endif	BitstreamPutBits(bs, quant, 5);	/* quantizer */	if (frame->coding_type != I_VOP)		BitstreamPutBits(bs, frame->fcode, 3);	/* forward_fixed_code */	if (frame->coding_type == B_VOP)		BitstreamPutBits(bs, frame->bcode, 3);	/* backward_fixed_code */}voidBitstreamWriteUserData(Bitstream * const bs,						const char *data,						const unsigned int length){	int i;	BitstreamPad(bs);	BitstreamPutBits(bs, USERDATA_START_CODE, 32);	for (i = 0; i < length; i++) {		BitstreamPutBits(bs, data[i], 8);	}}/* * Group of VOP */voidBitstreamWriteGroupOfVopHeader(Bitstream * const bs,                               const MBParam * pParam,                               uint32_t is_closed_gov){  int64_t time = (pParam->m_stamp + (pParam->fbase/2)) / pParam->fbase;  int hours, minutes, seconds;  /* compute time_code */  seconds = time % 60; time /= 60;  minutes = time % 60; time /= 60;  hours = time % 24; /* don't overflow */        BitstreamPutBits(bs, GRPOFVOP_START_CODE, 32);  BitstreamPutBits(bs, hours, 5);  BitstreamPutBits(bs, minutes, 6);  BitstreamPutBit(bs, 1);  BitstreamPutBits(bs, seconds, 6);  BitstreamPutBits(bs, is_closed_gov, 1);  BitstreamPutBits(bs, 0, 1); /* broken_link */}/* * End of Sequence */voidBitstreamWriteEndOfSequence(Bitstream * const bs){    BitstreamPadAlways(bs);    BitstreamPutBits(bs, VISOBJSEQ_STOP_CODE, 32);}/* * Video Packet (resync marker) */void write_video_packet_header(Bitstream * const bs,                               const MBParam * pParam,                               const FRAMEINFO * const frame,                               int mbnum){    const int mbnum_bits = log2bin(pParam->mb_width *  pParam->mb_height - 1);    uint32_t nbitsresyncmarker;    if (frame->coding_type == I_VOP)      nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER;  /* 16 zeros followed by a 1. */    else if (frame->coding_type == P_VOP)      nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER-1 + frame->fcode;    else /* B_VOP */      nbitsresyncmarker = MAX(NUMBITS_VP_RESYNC_MARKER, NUMBITS_VP_RESYNC_MARKER-1 + MAX(frame->fcode, frame->bcode));    BitstreamPadAlways(bs);    BitstreamPutBits(bs, RESYNC_MARKER, nbitsresyncmarker);    BitstreamPutBits(bs, mbnum, mbnum_bits);    BitstreamPutBits(bs, frame->quant, 5);    BitstreamPutBit(bs, 0); /* hec */}

⌨️ 快捷键说明

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