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

📄 bitstream.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 3 页
字号:
				DPRINTF(XVID_DEBUG_HEADER, "fcode_backward %i\n", *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) {
			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 void
bs_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
*/
void
BitstreamWriteVolHeader(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
*/
void
BitstreamWriteVopHeader(
						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 */

}

void
BitstreamWriteUserData(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
 */
void
BitstreamWriteGroupOfVopHeader(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
 */
void
BitstreamWriteEndOfSequence(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+1, 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 + -