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

📄 mbcoding.c

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

	uint32_t mode;
	int32_t level;
	REVERSE_EVENT *reverse_event;

	uint32_t cache = BitstreamShowBits(bs, 32);
	
	if (short_video_header)		/* inter-VLCs will be used for both intra and inter blocks */
		intra = 0;

	if (GET_BITS(cache, 7) != ESCAPE) {
		reverse_event = &DCT3D[intra][GET_BITS(cache, 12)];

		if ((level = reverse_event->event.level) == 0)
			goto error;

		*last = reverse_event->event.last;
		*run  = reverse_event->event.run;

		/* Don't forget to update the bitstream position */
		BitstreamSkip(bs, reverse_event->len+1);

		return (GET_BITS(cache, reverse_event->len+1)&0x01) ? -level : level;
	}

	/* flush 7bits of cache */
	cache <<= 7;

	if (short_video_header) {
		/* escape mode 4 - H.263 type, only used if short_video_header = 1  */
		*last =  GET_BITS(cache, 1);
		*run  = (GET_BITS(cache, 7) &0x3f);
		level = (GET_BITS(cache, 15)&0xff);

		if (level == 0 || level == 128)
			DPRINTF(XVID_DEBUG_ERROR, "Illegal LEVEL for ESCAPE mode 4: %d\n", level);

		/* We've "eaten" 22 bits */
		BitstreamSkip(bs, 22);

		return (level << 24) >> 24;
	}

	if ((mode = GET_BITS(cache, 2)) < 3) {
		const int skip[3] = {1, 1, 2};
		cache <<= skip[mode];

		reverse_event = &DCT3D[intra][GET_BITS(cache, 12)];

		if ((level = reverse_event->event.level) == 0)
			goto error;

		*last = reverse_event->event.last;
		*run  = reverse_event->event.run;

		if (mode < 2) {
			/* first escape mode, level is offset */
			level += max_level[intra][*last][*run];
		} else {
			/* second escape mode, run is offset */
			*run += max_run[intra][*last][level] + 1;
		}
		
		/* Update bitstream position */
		BitstreamSkip(bs, 7 + skip[mode] + reverse_event->len + 1);

		return (GET_BITS(cache, reverse_event->len+1)&0x01) ? -level : level;
	}

	/* third escape mode - fixed length codes */
	cache <<= 2;
	*last =  GET_BITS(cache, 1);
	*run  = (GET_BITS(cache, 7)&0x3f);
	level = (GET_BITS(cache, 20)&0xfff);
	
	/* Update bitstream position */
	BitstreamSkip(bs, 30);

	return (level << 20) >> 20;

  error:
	*run = 64;
	return 0;
}

void
get_intra_block(Bitstream * bs,
				int16_t * block,
				int direction,
				int coeff)
{

	const uint16_t *scan = scan_tables[direction];
	int level, run, last;

	do {
		level = get_coeff(bs, &run, &last, 1, 0);
		coeff += run;
		if (coeff & ~63) {
			DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run or index");
			break;
		}

		block[scan[coeff]] = level;

		DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i\n", scan[coeff], level);
#if 0
		DPRINTF(XVID_DEBUG_COEFF,"block[%i] %i %08x\n", scan[coeff], level, BitstreamShowBits(bs, 32));
#endif

		if (level < -2047 || level > 2047) {
			DPRINTF(XVID_DEBUG_ERROR,"warning: intra_overflow %i\n", level);
		}
		coeff++;
	} while (!last);

}

void
get_inter_block_h263(
		Bitstream * bs,
		int16_t * block,
		int direction,
		const int quant,
		const uint16_t *matrix)
{

	const uint16_t *scan = scan_tables[direction];
	const uint16_t quant_m_2 = quant << 1;
	const uint16_t quant_add = (quant & 1 ? quant : quant - 1);
	int p;
	int level;
	int run;
	int last;

	p = 0;
	do {
		level = get_coeff(bs, &run, &last, 0, 0);
		p += run;
		if (p & ~63) {
			DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run or index");
			break;
		}

		if (level < 0) {
			level = level*quant_m_2 - quant_add;
			block[scan[p]] = (level >= -2048 ? level : -2048);
		} else {
			level = level * quant_m_2 + quant_add;
			block[scan[p]] = (level <= 2047 ? level : 2047);
		}		
		p++;
	} while (!last);
}

void
get_inter_block_mpeg(
		Bitstream * bs,
		int16_t * block,
		int direction,
		const int quant,
		const uint16_t *matrix)
{
	const uint16_t *scan = scan_tables[direction];
	uint32_t sum = 0;
	int p;
	int level;
	int run;
	int last;

	p = 0;
	do {
		level = get_coeff(bs, &run, &last, 0, 0);
		p += run;
		if (p & ~63) {
			DPRINTF(XVID_DEBUG_ERROR,"fatal: invalid run or index");
			break;
		}

		if (level < 0) {
			level = ((2 * -level + 1) * matrix[scan[p]] * quant) >> 4;
			block[scan[p]] = (level <= 2048 ? -level : -2048);
		} else {
			level = ((2 *  level + 1) * matrix[scan[p]] * quant) >> 4;
			block[scan[p]] = (level <= 2047 ? level : 2047);
		}

		sum ^= block[scan[p]];
		
		p++;
	} while (!last);

	/*	mismatch control */
	if ((sum & 1) == 0) {
		block[63] ^= 1;
	}
}


/*****************************************************************************
 * VLC tables and other constant arrays
 ****************************************************************************/

VLC_TABLE const coeff_tab[2][102] =
{
	/* intra = 0 */
	{
		{{ 2,  2}, {0, 0, 1}},
		{{15,  4}, {0, 0, 2}},
		{{21,  6}, {0, 0, 3}},
		{{23,  7}, {0, 0, 4}},
		{{31,  8}, {0, 0, 5}},
		{{37,  9}, {0, 0, 6}},
		{{36,  9}, {0, 0, 7}},
		{{33, 10}, {0, 0, 8}},
		{{32, 10}, {0, 0, 9}},
		{{ 7, 11}, {0, 0, 10}},
		{{ 6, 11}, {0, 0, 11}},
		{{32, 11}, {0, 0, 12}},
		{{ 6,  3}, {0, 1, 1}},
		{{20,  6}, {0, 1, 2}},
		{{30,  8}, {0, 1, 3}},
		{{15, 10}, {0, 1, 4}},
		{{33, 11}, {0, 1, 5}},
		{{80, 12}, {0, 1, 6}},
		{{14,  4}, {0, 2, 1}},
		{{29,  8}, {0, 2, 2}},
		{{14, 10}, {0, 2, 3}},
		{{81, 12}, {0, 2, 4}},
		{{13,  5}, {0, 3, 1}},
		{{35,  9}, {0, 3, 2}},
		{{13, 10}, {0, 3, 3}},
		{{12,  5}, {0, 4, 1}},
		{{34,  9}, {0, 4, 2}},
		{{82, 12}, {0, 4, 3}},
		{{11,  5}, {0, 5, 1}},
		{{12, 10}, {0, 5, 2}},
		{{83, 12}, {0, 5, 3}},
		{{19,  6}, {0, 6, 1}},
		{{11, 10}, {0, 6, 2}},
		{{84, 12}, {0, 6, 3}},
		{{18,  6}, {0, 7, 1}},
		{{10, 10}, {0, 7, 2}},
		{{17,  6}, {0, 8, 1}},
		{{ 9, 10}, {0, 8, 2}},
		{{16,  6}, {0, 9, 1}},
		{{ 8, 10}, {0, 9, 2}},
		{{22,  7}, {0, 10, 1}},
		{{85, 12}, {0, 10, 2}},
		{{21,  7}, {0, 11, 1}},
		{{20,  7}, {0, 12, 1}},
		{{28,  8}, {0, 13, 1}},
		{{27,  8}, {0, 14, 1}},
		{{33,  9}, {0, 15, 1}},
		{{32,  9}, {0, 16, 1}},
		{{31,  9}, {0, 17, 1}},
		{{30,  9}, {0, 18, 1}},
		{{29,  9}, {0, 19, 1}},
		{{28,  9}, {0, 20, 1}},
		{{27,  9}, {0, 21, 1}},
		{{26,  9}, {0, 22, 1}},
		{{34, 11}, {0, 23, 1}},
		{{35, 11}, {0, 24, 1}},
		{{86, 12}, {0, 25, 1}},
		{{87, 12}, {0, 26, 1}},
		{{ 7,  4}, {1, 0, 1}},
		{{25,  9}, {1, 0, 2}},
		{{ 5, 11}, {1, 0, 3}},
		{{15,  6}, {1, 1, 1}},
		{{ 4, 11}, {1, 1, 2}},
		{{14,  6}, {1, 2, 1}},
		{{13,  6}, {1, 3, 1}},
		{{12,  6}, {1, 4, 1}},
		{{19,  7}, {1, 5, 1}},
		{{18,  7}, {1, 6, 1}},
		{{17,  7}, {1, 7, 1}},
		{{16,  7}, {1, 8, 1}},
		{{26,  8}, {1, 9, 1}},
		{{25,  8}, {1, 10, 1}},
		{{24,  8}, {1, 11, 1}},
		{{23,  8}, {1, 12, 1}},
		{{22,  8}, {1, 13, 1}},
		{{21,  8}, {1, 14, 1}},
		{{20,  8}, {1, 15, 1}},
		{{19,  8}, {1, 16, 1}},
		{{24,  9}, {1, 17, 1}},
		{{23,  9}, {1, 18, 1}},
		{{22,  9}, {1, 19, 1}},
		{{21,  9}, {1, 20, 1}},
		{{20,  9}, {1, 21, 1}},
		{{19,  9}, {1, 22, 1}},
		{{18,  9}, {1, 23, 1}},
		{{17,  9}, {1, 24, 1}},
		{{ 7, 10}, {1, 25, 1}},
		{{ 6, 10}, {1, 26, 1}},
		{{ 5, 10}, {1, 27, 1}},
		{{ 4, 10}, {1, 28, 1}},
		{{36, 11}, {1, 29, 1}},
		{{37, 11}, {1, 30, 1}},
		{{38, 11}, {1, 31, 1}},
		{{39, 11}, {1, 32, 1}},
		{{88, 12}, {1, 33, 1}},
		{{89, 12}, {1, 34, 1}},
		{{90, 12}, {1, 35, 1}},
		{{91, 12}, {1, 36, 1}},
		{{92, 12}, {1, 37, 1}},
		{{93, 12}, {1, 38, 1}},
		{{94, 12}, {1, 39, 1}},
		{{95, 12}, {1, 40, 1}}
	},
	/* intra = 1 */
	{
		{{ 2,  2}, {0, 0, 1}},
		{{15,  4}, {0, 0, 3}},
		{{21,  6}, {0, 0, 6}},
		{{23,  7}, {0, 0, 9}},
		{{31,  8}, {0, 0, 10}},
		{{37,  9}, {0, 0, 13}},
		{{36,  9}, {0, 0, 14}},
		{{33, 10}, {0, 0, 17}},
		{{32, 10}, {0, 0, 18}},
		{{ 7, 11}, {0, 0, 21}},
		{{ 6, 11}, {0, 0, 22}},
		{{32, 11}, {0, 0, 23}},
		{{ 6,  3}, {0, 0, 2}},
		{{20,  6}, {0, 1, 2}},
		{{30,  8}, {0, 0, 11}},
		{{15, 10}, {0, 0, 19}},
		{{33, 11}, {0, 0, 24}},
		{{80, 12}, {0, 0, 25}},
		{{14,  4}, {0, 1, 1}},
		{{29,  8}, {0, 0, 12}},
		{{14, 10}, {0, 0, 20}},
		{{81, 12}, {0, 0, 26}},
		{{13,  5}, {0, 0, 4}},
		{{35,  9}, {0, 0, 15}},
		{{13, 10}, {0, 1, 7}},
		{{12,  5}, {0, 0, 5}},
		{{34,  9}, {0, 4, 2}},
		{{82, 12}, {0, 0, 27}},
		{{11,  5}, {0, 2, 1}},
		{{12, 10}, {0, 2, 4}},
		{{83, 12}, {0, 1, 9}},
		{{19,  6}, {0, 0, 7}},
		{{11, 10}, {0, 3, 4}},
		{{84, 12}, {0, 6, 3}},
		{{18,  6}, {0, 0, 8}},
		{{10, 10}, {0, 4, 3}},
		{{17,  6}, {0, 3, 1}},
		{{ 9, 10}, {0, 8, 2}},
		{{16,  6}, {0, 4, 1}},
		{{ 8, 10}, {0, 5, 3}},
		{{22,  7}, {0, 1, 3}},
		{{85, 12}, {0, 1, 10}},
		{{21,  7}, {0, 2, 2}},
		{{20,  7}, {0, 7, 1}},
		{{28,  8}, {0, 1, 4}},
		{{27,  8}, {0, 3, 2}},
		{{33,  9}, {0, 0, 16}},
		{{32,  9}, {0, 1, 5}},
		{{31,  9}, {0, 1, 6}},
		{{30,  9}, {0, 2, 3}},
		{{29,  9}, {0, 3, 3}},
		{{28,  9}, {0, 5, 2}},
		{{27,  9}, {0, 6, 2}},
		{{26,  9}, {0, 7, 2}},
		{{34, 11}, {0, 1, 8}},
		{{35, 11}, {0, 9, 2}},
		{{86, 12}, {0, 2, 5}},
		{{87, 12}, {0, 7, 3}},
		{{ 7,  4}, {1, 0, 1}},
		{{25,  9}, {0, 11, 1}},
		{{ 5, 11}, {1, 0, 6}},
		{{15,  6}, {1, 1, 1}},
		{{ 4, 11}, {1, 0, 7}},
		{{14,  6}, {1, 2, 1}},
		{{13,  6}, {0, 5, 1}},
		{{12,  6}, {1, 0, 2}},
		{{19,  7}, {1, 5, 1}},
		{{18,  7}, {0, 6, 1}},
		{{17,  7}, {1, 3, 1}},
		{{16,  7}, {1, 4, 1}},
		{{26,  8}, {1, 9, 1}},
		{{25,  8}, {0, 8, 1}},
		{{24,  8}, {0, 9, 1}},
		{{23,  8}, {0, 10, 1}},
		{{22,  8}, {1, 0, 3}},
		{{21,  8}, {1, 6, 1}},
		{{20,  8}, {1, 7, 1}},
		{{19,  8}, {1, 8, 1}},
		{{24,  9}, {0, 12, 1}},
		{{23,  9}, {1, 0, 4}},
		{{22,  9}, {1, 1, 2}},
		{{21,  9}, {1, 10, 1}},
		{{20,  9}, {1, 11, 1}},
		{{19,  9}, {1, 12, 1}},
		{{18,  9}, {1, 13, 1}},
		{{17,  9}, {1, 14, 1}},
		{{ 7, 10}, {0, 13, 1}},
		{{ 6, 10}, {1, 0, 5}},
		{{ 5, 10}, {1, 1, 3}},
		{{ 4, 10}, {1, 2, 2}},
		{{36, 11}, {1, 3, 2}},
		{{37, 11}, {1, 4, 2}},
		{{38, 11}, {1, 15, 1}},
		{{39, 11}, {1, 16, 1}},
		{{88, 12}, {0, 14, 1}},
		{{89, 12}, {1, 0, 8}},
		{{90, 12}, {1, 5, 2}},
		{{91, 12}, {1, 6, 2}},
		{{92, 12}, {1, 17, 1}},
		{{93, 12}, {1, 18, 1}},
		{{94, 12}, {1, 19, 1}},
		{{95, 12}, {1, 20, 1}}
	}
};

/* constants taken from momusys/vm_common/inlcude/max_level.h */
uint8_t const max_level[2][2][64] = {
	{
		/* intra = 0, last = 0 */
		{
			12, 6, 4, 3, 3, 3, 3, 2,
			2, 2, 2, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0
		},
		/* intra = 0, last = 1 */
		{
			3, 2, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1,
			1, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0
		}
	},
	{
		/* intra = 1, last = 0 */
		{
			27, 10, 5, 4, 3, 3, 3, 3,
			2, 2, 1, 1, 1, 1, 1, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0
		},
		/* intra = 1, last = 1 */
		{
			8, 3, 2, 2, 2, 2, 2, 1,
			1, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0
		}
	}
};

uint8_t const max_run[2][2][64] = {
	{
		/* intra = 0, last = 0 */
		{
			0, 26, 10, 6, 2, 1, 1, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
		},
		/* intra = 0, last = 1 */
		{
			0, 40, 1, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
		}
	},
	{

⌨️ 快捷键说明

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