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

📄 bitstream.c

📁 基于Linux的ffmepg decoder
💻 C
字号:
/**
 *  @file bitstream.c
 *  @brief The related functions for writing bitstream header are implemented in this
 *         file.
 *
 */

#include "quant_matrix.h"
#include "bitstream.h"
#include "zigzag.h"

/*****************************************************************************
 * Functions
 ****************************************************************************/

static uint32_t __inline
log2bin(uint32_t value)
{
/* Changed by Chenm001 */
	int n = 0;

	while (value) {
		value >>= 1;
		n++;
	}
	return n;
}

/*
decode headers
returns coding_type, or -1 if error
*/

#define VIDOBJ_START_CODE_MASK		0x0000001f
#define VIDOBJLAY_START_CODE_MASK	0x0000000f

/* write custom quant matrix */


static void
bs_put_matrix(const int16_t * matrix,FTMCP100_CODEC *pCodec)
{
	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(matrix[scan_tables[0][i]], 8,pCodec);
	}

	if (j < 63) {
		BitstreamPutBits(0, 8,pCodec);
	}
}

void BitstreamWriteShortHeader(MBParam * pParam,
						const FRAMEINFO * frame,
						int vop_coded,FTMCP100_CODEC *pCodec)
{
	uint32_t a;

	BitstreamPad(pCodec);
	BitstreamPutBits(VIDO_SHORT_HEADER, 22,pCodec);
	a = pParam->temporal_ref;
	BitstreamPutBits(a, 8,pCodec);
	a++;
	a &= 0xff;
	pParam->temporal_ref = a;
	WRITE_MARKER();

	if (pParam->width == 128)
		BitstreamPutBits(1, 7,pCodec);			//  source_format
	else if (pParam->width == 176)
		BitstreamPutBits(2, 7,pCodec);			//  source_format
	else if (pParam->width == 352)
		BitstreamPutBits(3, 7,pCodec);			//  source_format
	else if (pParam->width == 704)
		BitstreamPutBits(4, 7,pCodec);			//  source_format
	else if (pParam->width == 1408)
		BitstreamPutBits(5, 7,pCodec);			//  source_format
	else
		BitstreamPutBits(5, 7,pCodec);			//  source_format

//	BitstreamPutBits(3, 7);
//	BitstreamPutBit(0);		/* zero_bit */
//	BitstreamPutBit(0);			//  split_screen_indicator
//	BitstreamPutBit(0);			//  document_camera_indicator
//	BitstreamPutBit(0);			//  full_picture_freeze_release
//	BitstreamPutBits(2, 3);			//  source_format

	BitstreamPutBit(vop_coded,pCodec);  //  picture_coding_type
	BitstreamPutBits(0, 4,pCodec);			//  four_reserved_zero_bits
	BitstreamPutBits(frame->quant, 5,pCodec);	/* quantizer */
	BitstreamPutBit(0,pCodec);			//  zero_bit
	BitstreamPutBit(0,pCodec);			//  pei

}


/*
	write vol header
*/
void
BitstreamWriteVolHeader(const MBParam * pParam,
						const FRAMEINFO * frame,FTMCP100_CODEC *pCodec)
{
	// video object_start_code & vo_id
	BitstreamPad(pCodec);
	BitstreamPutBits(VO_START_CODE, 27,pCodec);
	BitstreamPutBits(0, 5,pCodec);

	// video_object_layer_start_code & vol_id
	BitstreamPutBits(VOL_START_CODE, 28,pCodec);

	BitstreamPutBits(0, 14,pCodec);
//	BitstreamPutBits(bs, 0, 4);
//	BitstreamPutBit(bs, 0);		// random_accessible_vol
//	BitstreamPutBits(bs, 0, 8);	// video_object_type_indication
//	BitstreamPutBit(bs, 0);		// is_object_layer_identified (0=not given)

	BitstreamPutBits(216, 11,pCodec);
//	BitstreamPutBits(bs, 1, 4);	// aspect_ratio_info (1=1:1)
//	BitstreamPutBit(bs, 1);	// vol_control_parameters
//	BitstreamPutBits(bs, 1, 2);	// chroma_format 1="4:2:0"
//	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_increment_resolution; ignored by current decore versions
	 *  eg. 2fps     res=2       inc=1
	 *      25fps    res=25      inc=1
	 *      29.97fps res=30000   inc=1001
	 */
	BitstreamPutBits(pParam->fbase, 16,pCodec);


	WRITE_MARKER();

	BitstreamPutBit(1,pCodec);		// fixed_vop_rate = 1
	
	// The following line was the bug of xvid version 0.9 and was fixed
	// on 07-15-2005.We should send the (pParam->fbase-1) value to 
	// calculate the minimum number of bits representing the range.
	//BitstreamPutBits(pParam->fincr, log2bin(pParam->fbase),pCodec);	// fixed_vop_time_increment
	BitstreamPutBits(pParam->fincr, MAX(log2bin(pParam->fbase-1),1),pCodec);	// fixed_vop_time_increment

	WRITE_MARKER();
	BitstreamPutBits(pParam->width, 13,pCodec);	// width
	WRITE_MARKER();
	BitstreamPutBits(pParam->height, 13,pCodec);	// height
	WRITE_MARKER();

	BitstreamPutBit(frame->global_flags & Faraday_INTERLACING,pCodec);	// interlace
	BitstreamPutBits(4, 3,pCodec);

//	BitstreamPutBit(bs, 1);		// obmc_disable (overlapped block motion compensation)
//	BitstreamPutBit(bs, 0);		// sprite_enable
//	BitstreamPutBit(bs, 0);		// not_in_bit

	// quant_type   0=h.263  1=mpeg4(quantizer tables)
	BitstreamPutBit(pParam->m_quant_type,pCodec);

	if (pParam->m_quant_type) {
		BitstreamPutBit(get_intra_matrix_status(),pCodec);	// load_intra_quant_mat
		if (get_intra_matrix_status()) {
			bs_put_matrix(get_intra_matrix(),pCodec);
		}

		BitstreamPutBit(get_inter_matrix_status(),pCodec);	// load_inter_quant_mat
		if (get_inter_matrix_status()) {
			bs_put_matrix(get_inter_matrix(),pCodec);
		}
	}

	if (pParam->resyn)
	  BitstreamPutBits(8, 4,pCodec);
	else
	  BitstreamPutBits(12, 4,pCodec);

//	BitstreamPutBit(bs, 1);		// complexity_estimation_disable
//	BitstreamPutBit(bs, 1);		// resync_marker_disable
//	BitstreamPutBit(bs, 0);		// data_partitioned
//	BitstreamPutBit(bs, 0);		// scalability
}


/*
  write vop header

  NOTE: doesnt handle bother with time_base & time_inc
  time_base = n seconds since last resync (eg. last iframe)
  time_inc = nth of a second since last resync
  (decoder uses these values to determine precise time since last resync)
*/
void
BitstreamWriteVopHeader(const MBParam * pParam,
						const FRAMEINFO * frame,
						int vop_coded,FTMCP100_CODEC *pCodec)
{
	uint32_t i;

	BitstreamPad(pCodec);
	BitstreamPutBits(VOP_START_CODE0, 16,pCodec);
	BitstreamPutBits(VOP_START_CODE1, 16,pCodec);

	BitstreamPutBits(frame->coding_type, 2,pCodec);

	// time_base = 0  write n x PutBit(1), PutBit(0)
	for (i = frame->seconds; i > 0 ; i--) {
		BitstreamPutBit(1,pCodec);
	}
	BitstreamPutBit(0,pCodec);

	WRITE_MARKER();

	// time_increment: value=nth_of_sec, nbits = log2(resolution)
	BitstreamPutBits(frame->ticks, log2bin(pParam->fbase),pCodec);

	WRITE_MARKER();

	if (!vop_coded) {
		BitstreamPutBits(0, 1,pCodec);
		return;
	}

	BitstreamPutBits(1, 1,pCodec);	// vop_coded

	if (frame->coding_type == P_VOP)
		BitstreamPutBits(frame->rounding_type, 1,pCodec);

	BitstreamPutBits(0, 3,pCodec);	// intra_dc_vlc_threshold

	BitstreamPutBits(frame->quant, 5,pCodec);	// quantizer

	if (frame->coding_type != I_VOP)
		BitstreamPutBits(frame->fcode, 3,pCodec);	// forward_fixed_code

	if (frame->coding_type == B_VOP)
		BitstreamPutBits(frame->bcode, 3,pCodec);	// backward_fixed_code

}

⌨️ 快捷键说明

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