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

📄 mbcoding.c

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 C
📖 第 1 页 / 共 4 页
字号:

	/* write dquant */
	if (pMB->mode == MODE_INTRA_Q)
		BitstreamPutBits(bs, DQ_VALUE2INDEX(pMB->dquant), 2);

	/* write interlacing */
	if (frame->vol_flags & XVID_VOL_INTERLACING) {
		BitstreamPutBit(bs, pMB->field_dct);
	}
	/* code block coeffs */
	for (i = 0; i < 6; i++) {
		if (i < 4)
			BitstreamPutBits(bs, dcy_tab[qcoeff[i * 64 + 0] + 255].code,
							 dcy_tab[qcoeff[i * 64 + 0] + 255].len);
		else
			BitstreamPutBits(bs, dcc_tab[qcoeff[i * 64 + 0] + 255].code,
							 dcc_tab[qcoeff[i * 64 + 0] + 255].len);

		if (pMB->cbp & (1 << (5 - i))) {
			const uint16_t *scan_table =
				frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
				scan_tables[2] : scan_tables[pMB->acpred_directions[i]];

			bits = BitstreamPos(bs);

			CodeCoeffIntra(bs, &qcoeff[i * 64], scan_table);

			bits = BitstreamPos(bs) - bits;
			pStat->iTextBits += bits;
		}
	}

}


static void
CodeBlockInter(const FRAMEINFO * const frame,
			   const MACROBLOCK * pMB,
			   int16_t qcoeff[6 * 64],
			   Bitstream * bs,
			   Statistics * pStat)
{

	int32_t i;
	uint32_t bits, mcbpc, cbpy;

	mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3);
	cbpy = 15 - (pMB->cbp >> 2);

	/* write mcbpc */
	BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code,
					 mcbpc_inter_tab[mcbpc].len);

	if ( (frame->coding_type == S_VOP) && (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) )
		BitstreamPutBit(bs, pMB->mcsel);		/* mcsel: '0'=local motion, '1'=GMC */

	/* write cbpy */
	BitstreamPutBits(bs, xvid_cbpy_tab[cbpy].code, xvid_cbpy_tab[cbpy].len);

	/* write dquant */
	if (pMB->mode == MODE_INTER_Q)
		BitstreamPutBits(bs, DQ_VALUE2INDEX(pMB->dquant), 2);

	/* interlacing */
	if (frame->vol_flags & XVID_VOL_INTERLACING) {
		if (pMB->cbp) {
			BitstreamPutBit(bs, pMB->field_dct);
			DPRINTF(XVID_DEBUG_MB,"codep: field_dct: %i\n", pMB->field_dct);
		}

		/* if inter block, write field ME flag */
		if ((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) && (pMB->mcsel == 0)) {
			BitstreamPutBit(bs, 0 /*pMB->field_pred*/); /* not implemented yet */
			DPRINTF(XVID_DEBUG_MB,"codep: field_pred: %i\n", pMB->field_pred);

			/* write field prediction references */
#if 0 /* Remove the #if once field_pred is supported */
			if (pMB->field_pred) {
				BitstreamPutBit(bs, pMB->field_for_top);
				BitstreamPutBit(bs, pMB->field_for_bot);
			}
#endif
		}
	}

	bits = BitstreamPos(bs);

	/* code motion vector(s) if motion is local  */
	if (!pMB->mcsel)
		for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) {
			CodeVector(bs, pMB->pmvs[i].x, frame->fcode);
			CodeVector(bs, pMB->pmvs[i].y, frame->fcode);

#ifdef _DEBUG
			if (i == 0) /* for simplicity */ {
				int coded_length = BitstreamPos(bs) - bits;
				int estimated_length = d_mv_bits(pMB->pmvs[i].x, pMB->pmvs[i].y, zeroMV, frame->fcode, 0);
				assert(estimated_length == coded_length);
				d_mv_bits(pMB->pmvs[i].x, pMB->pmvs[i].y, zeroMV, frame->fcode, 0);
			}
#endif
		}

	bits = BitstreamPos(bs) - bits;
	pStat->iMVBits += bits;

	bits = BitstreamPos(bs);

	/* code block coeffs */
	for (i = 0; i < 6; i++)
		if (pMB->cbp & (1 << (5 - i))) {
			const uint16_t *scan_table =
				frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
				scan_tables[2] : scan_tables[0];

			CodeCoeffInter(bs, &qcoeff[i * 64], scan_table);
		}

	bits = BitstreamPos(bs) - bits;
	pStat->iTextBits += bits;
}


void
MBCoding(const FRAMEINFO * const frame,
		 MACROBLOCK * pMB,
		 int16_t qcoeff[6 * 64],
		 Bitstream * bs,
		 Statistics * pStat)
{
	if (frame->coding_type != I_VOP)
			BitstreamPutBit(bs, 0);	/* not_coded */

	if (frame->vop_flags & XVID_VOP_GREYSCALE) {
		pMB->cbp &= 0x3C;		/* keep only bits 5-2 */
		qcoeff[4*64+0]=0;		/* for INTRA DC value is saved */
		qcoeff[5*64+0]=0;
	}

	if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
		CodeBlockIntra(frame, pMB, qcoeff, bs, pStat);
	else
		CodeBlockInter(frame, pMB, qcoeff, bs, pStat);

}

/***************************************************************
 * bframe encoding start
 ***************************************************************/

/*
	mbtype
	0	1b		direct(h263)		mvdb
	1	01b		interpolate mc+q	dbquant, mvdf, mvdb
	2	001b	backward mc+q		dbquant, mvdb
	3	0001b	forward mc+q		dbquant, mvdf
*/

static __inline void
put_bvop_mbtype(Bitstream * bs,
				int value)
{
	switch (value) {
		case MODE_FORWARD:
			BitstreamPutBit(bs, 0);
		case MODE_BACKWARD:
			BitstreamPutBit(bs, 0);
		case MODE_INTERPOLATE:
			BitstreamPutBit(bs, 0);
		case MODE_DIRECT:
			BitstreamPutBit(bs, 1);
		default:
			break;
	}
}

/*
	dbquant
	-2	10b
	0	0b
	+2	11b
*/

static __inline void
put_bvop_dbquant(Bitstream * bs,
				 int value)
{
	switch (value) {
	case 0:
		BitstreamPutBit(bs, 0);
		return;

	case -2:
		BitstreamPutBit(bs, 1);
		BitstreamPutBit(bs, 0);
		return;

	case 2:
		BitstreamPutBit(bs, 1);
		BitstreamPutBit(bs, 1);
		return;

	default:;					/* invalid */
	}
}



void
MBCodingBVOP(const FRAMEINFO * const frame,
			 const MACROBLOCK * mb,
			 const int16_t qcoeff[6 * 64],
			 const int32_t fcode,
			 const int32_t bcode,
			 Bitstream * bs,
			 Statistics * pStat)
{
	int vcode = fcode;
	unsigned int i;

	const uint16_t *scan_table =
		frame->vop_flags & XVID_VOP_ALTERNATESCAN ?
		scan_tables[2] : scan_tables[0];
	int bits;

/*	------------------------------------------------------------------
		when a block is skipped it is decoded DIRECT(0,0)
		hence is interpolated from forward & backward frames
	------------------------------------------------------------------ */

	if (mb->mode == MODE_DIRECT_NONE_MV) {
		BitstreamPutBit(bs, 1);	/* skipped */
		return;
	}

	BitstreamPutBit(bs, 0);		/* not skipped */

	if (mb->cbp == 0) {
		BitstreamPutBit(bs, 1);	/* cbp == 0 */
	} else {
		BitstreamPutBit(bs, 0);	/* cbp == xxx */
	}

	put_bvop_mbtype(bs, mb->mode);

	if (mb->cbp) {
		BitstreamPutBits(bs, mb->cbp, 6);
	}

	if (mb->mode != MODE_DIRECT && mb->cbp != 0) {
		put_bvop_dbquant(bs, 0);	/* todo: mb->dquant = 0 */
	}

	if (frame->vol_flags & XVID_VOL_INTERLACING) {
		if (mb->cbp) {
			BitstreamPutBit(bs, mb->field_dct);
			DPRINTF(XVID_DEBUG_MB,"codep: field_dct: %i\n", mb->field_dct);
		}

		/* if not direct block, write field ME flag */
		if (mb->mode != MODE_DIRECT) {
			BitstreamPutBit(bs, 0 /*mb->field_pred*/); /* field ME not implemented */
			
			/* write field prediction references */
#if 0 /* Remove the #if once field_pred is supported */
			if (mb->field_pred) {
				BitstreamPutBit(bs, mb->field_for_top);
				BitstreamPutBit(bs, mb->field_for_bot);
			}
#endif
		}
	}

	bits = BitstreamPos(bs);

	switch (mb->mode) {
		case MODE_INTERPOLATE:
			CodeVector(bs, mb->pmvs[1].x, vcode); /* forward vector of interpolate mode */
			CodeVector(bs, mb->pmvs[1].y, vcode);
		case MODE_BACKWARD:
			vcode = bcode;
		case MODE_FORWARD:
			CodeVector(bs, mb->pmvs[0].x, vcode);
			CodeVector(bs, mb->pmvs[0].y, vcode);
			break;
		case MODE_DIRECT:
			CodeVector(bs, mb->pmvs[3].x, 1);	/* fcode is always 1 for delta vector */
			CodeVector(bs, mb->pmvs[3].y, 1);	/* prediction is always (0,0) */
		default: break;
	}
	pStat->iMVBits += BitstreamPos(bs) - bits;

	bits = BitstreamPos(bs);
	for (i = 0; i < 6; i++) {
		if (mb->cbp & (1 << (5 - i))) {
			CodeCoeffInter(bs, &qcoeff[i * 64], scan_table);
		}
	}
	pStat->iTextBits += BitstreamPos(bs) - bits;
}



/***************************************************************
 * decoding stuff starts here                                  *
 ***************************************************************/


/*
 * for IVOP addbits == 0
 * for PVOP addbits == fcode - 1
 * for BVOP addbits == max(fcode,bcode) - 1
 * returns true or false
 */
int
check_resync_marker(Bitstream * bs, int addbits)
{
	uint32_t nbits;
	uint32_t code;
	uint32_t nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER + addbits;

	nbits = BitstreamNumBitsToByteAlign(bs);
	code = BitstreamShowBits(bs, nbits);

	if (code == (((uint32_t)1 << (nbits - 1)) - 1))
	{
		return BitstreamShowBitsFromByteAlign(bs, nbitsresyncmarker) == RESYNC_MARKER;
	}

	return 0;
}



int
get_mcbpc_intra(Bitstream * bs)
{

	uint32_t index;

	index = BitstreamShowBits(bs, 9);
	index >>= 3;

	BitstreamSkip(bs, mcbpc_intra_table[index].len);

	return mcbpc_intra_table[index].code;

}

int
get_mcbpc_inter(Bitstream * bs)
{

	uint32_t index;

	index = MIN(BitstreamShowBits(bs, 9), 256);

	BitstreamSkip(bs, mcbpc_inter_table[index].len);

	return mcbpc_inter_table[index].code;

}

int
get_cbpy(Bitstream * bs,
		 int intra)
{

	int cbpy;
	uint32_t index = BitstreamShowBits(bs, 6);

	BitstreamSkip(bs, cbpy_table[index].len);
	cbpy = cbpy_table[index].code;

	if (!intra)
		cbpy = 15 - cbpy;

	return cbpy;

}

static __inline int
get_mv_data(Bitstream * bs)
{

	uint32_t index;

	if (BitstreamGetBit(bs))
		return 0;

	index = BitstreamShowBits(bs, 12);

	if (index >= 512) {
		index = (index >> 8) - 2;
		BitstreamSkip(bs, TMNMVtab0[index].len);
		return TMNMVtab0[index].code;
	}

	if (index >= 128) {
		index = (index >> 2) - 32;
		BitstreamSkip(bs, TMNMVtab1[index].len);
		return TMNMVtab1[index].code;
	}

	index -= 4;

	BitstreamSkip(bs, TMNMVtab2[index].len);
	return TMNMVtab2[index].code;

}

int
get_mv(Bitstream * bs,
	   int fcode)
{

	int data;
	int res;
	int mv;
	int scale_fac = 1 << (fcode - 1);

	data = get_mv_data(bs);

	if (scale_fac == 1 || data == 0)
		return data;

	res = BitstreamGetBits(bs, fcode - 1);
	mv = ((abs(data) - 1) * scale_fac) + res + 1;

	return data < 0 ? -mv : mv;

}

int
get_dc_dif(Bitstream * bs,
		   uint32_t dc_size)
{

	int code = BitstreamGetBits(bs, dc_size);
	int msb = code >> (dc_size - 1);

	if (msb == 0)
		return (-1 * (code ^ ((1 << dc_size) - 1)));

	return code;

}

int
get_dc_size_lum(Bitstream * bs)
{

	int code, i;

	code = BitstreamShowBits(bs, 11);

	for (i = 11; i > 3; i--) {
		if (code == 1) {
			BitstreamSkip(bs, i);
			return i + 1;
		}
		code >>= 1;
	}

	BitstreamSkip(bs, dc_lum_tab[code].len);
	return dc_lum_tab[code].code;

}


int
get_dc_size_chrom(Bitstream * bs)
{

	uint32_t code, i;

	code = BitstreamShowBits(bs, 12);

	for (i = 12; i > 2; i--) {
		if (code == 1) {
			BitstreamSkip(bs, i);
			return i;
		}
		code >>= 1;
	}

	return 3 - BitstreamGetBits(bs, 2);

}

#define GET_BITS(cache, n) ((cache)>>(32-(n)))

static __inline int
get_coeff(Bitstream * bs,
		  int *run,
		  int *last,
		  int intra,

⌨️ 快捷键说明

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