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

📄 mpeg4vlc.c

📁 DM642的mpeg4编码
💻 C
字号:
#include "mpeg4vlc.h"

#define LEVELOFFSET 32

static reveserStruct Dctcoeff[2][4096];
static vlcStuct coeff_VLC[2][2][64][64];

short GetDcScaler(short iQuant, short iFlag)
{
	if (iQuant < 5)
	{
		return 8;
	}
	if (iQuant < 25 && !iFlag)
	{
		return (iQuant + 13) >> 1;
	}
	if (iQuant < 9)
	{
		return  (iQuant << 1);
	}
	if (iQuant < 25)
	{
		return iQuant + 8;
	}
	
	if (iFlag)
	{
		return  (iQuant << 1) - 16;
	}
	else
	{
		return iQuant - 6;
	}
}
//***********************************************************************************************
//函 数 名:CodeIntraMB
//函数功能:宏块编码类型
//形式参数:codes:6×64个系数块
//		  :iMBMode:宏块类型
//返 回 值:void
//***********************************************************************************************
short GetMBlockCBP(short* codes, short iMBMode)
{
	unsigned int i = 6;
	unsigned int cbp = 0;

	if (iMBMode == MB_INTRA || iMBMode == MB_INTRA_Q)
	{
			do  
			{
				unsigned long *codes64 = (unsigned long*)codes;	/* the compiler doesn't really make this */
				unsigned int *codes32 = (unsigned int*)codes;	/* variables, just "addressing modes" */

				cbp += cbp;
				if (codes[1] || codes32[1]) 
				{
					cbp++;
				}
				else if (codes64[1] | codes64[2] | codes64[3])
				{
					cbp++;
				}
				else if (codes64[4] | codes64[5] | codes64[6] | codes64[7]) 
				{
					cbp++;
				}
				else if (codes64[8] | codes64[9] | codes64[10] | codes64[11])
				{
					cbp++;
				}
				else if (codes64[12] | codes64[13] | codes64[14] | codes64[15])
				{
					cbp++;
				}
				codes += 64;
				i--;
			} while (i != 0);
	}
	else 
	{
          do  
			{
				unsigned long *codes64 = (unsigned long*)codes;	/* the compiler doesn't really make this */
				unsigned int *codes32 = (unsigned int*)codes;	/* variables, just "addressing modes" */

				cbp += cbp;
				if (codes[0] || codes[1] || codes32[1]) 
				{
					cbp++;
				}
				else if (codes64[1] | codes64[2] | codes64[3])
				{
					cbp++;
				}
				else if (codes64[4] | codes64[5] | codes64[6] | codes64[7]) 
				{
					cbp++;
				}
				else if (codes64[8] | codes64[9] | codes64[10] | codes64[11])
				{
					cbp++;
				}
				else if (codes64[12] | codes64[13] | codes64[14] | codes64[15])
				{
					cbp++;
				}
				codes += 64;
				i--;
			} while (i != 0);
	}

	return cbp;
}

void InitCodeTable(void)
{
    unsigned int i, j, intra, last, run,  run_esc, level, level_esc, escape, escape_len, offset;

	for (intra = 0; intra < 2; intra++)
	{  
		for (i = 0; i < 4096; i++)
		{
			Dctcoeff[intra][i].event.level = 0;
		}
	}

	for (intra = 0; intra < 2; intra++) 
	{
		for (last = 0; last < 2; last++) 
		{
			for (run = 0; run < 63 + last; run++) 
			{
				for (level = 0; level < (unsigned int)(32 << intra); level++) 
				{
					offset = !intra * LEVELOFFSET;
					coeff_VLC[intra][last][level + offset][run].len = 128;
				}
			}
		}
	}

	for (intra = 0; intra < 2; intra++) 
	{
		for (i = 0; i < 102; i++) 
		{
			offset = !intra * LEVELOFFSET;

			for (j = 0; j < (unsigned int)(1 << (12 - CoeffTable[intra][i].vlc.len)); j++) 
			{
				Dctcoeff[intra][(CoeffTable[intra][i].vlc.code << (12 - CoeffTable[intra][i].vlc.len)) | j].len	 = CoeffTable[intra][i].vlc.len;
				Dctcoeff[intra][(CoeffTable[intra][i].vlc.code << (12 - CoeffTable[intra][i].vlc.len)) | j].event = CoeffTable[intra][i].event;
			}

			coeff_VLC[intra][CoeffTable[intra][i].event.last][CoeffTable[intra][i].event.level + offset][CoeffTable[intra][i].event.run].code
				= CoeffTable[intra][i].vlc.code << 1;
			coeff_VLC[intra][CoeffTable[intra][i].event.last][CoeffTable[intra][i].event.level + offset][CoeffTable[intra][i].event.run].len
				= CoeffTable[intra][i].vlc.len + 1;

			if (!intra) 
			{
				coeff_VLC[intra][CoeffTable[intra][i].event.last][offset - CoeffTable[intra][i].event.level][CoeffTable[intra][i].event.run].code
					= (CoeffTable[intra][i].vlc.code << 1) | 1;
				coeff_VLC[intra][CoeffTable[intra][i].event.last][offset - CoeffTable[intra][i].event.level][CoeffTable[intra][i].event.run].len
					= CoeffTable[intra][i].vlc.len + 1;
			}
		}
	}

	for (intra = 0; intra < 2; intra++)
	{
		for (last = 0; last < 2; last++)
		{
			for (run = 0; run < 63 + last; run++) 
			{
				for (level = 1; level < (unsigned int)(32 << intra); level++) 
				{

					if (level <= MaxLevel[intra][last][run] && run <= MaxRun[intra][last][level])
					{
						continue;
					}

					offset = !intra * LEVELOFFSET;
                    level_esc = level - MaxLevel[intra][last][run];
					run_esc = run - 1 - MaxRun[intra][last][level];

					if (level_esc <= MaxLevel[intra][last][run] && run <= MaxRun[intra][last][level_esc]) 
					{
						escape     = ESCAPE1;
						escape_len = 7 + 1;
						run_esc    = run;
					}
					else 
					{
						if (run_esc <= MaxRun[intra][last][level] && level <= MaxLevel[intra][last][run_esc])
						{
							escape     = ESCAPE2;
							escape_len = 7 + 2;
							level_esc  = level;
						} 
						else
						{
							if (!intra)
							{
								coeff_VLC[intra][last][level + offset][run].code
									= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1;
								coeff_VLC[intra][last][level + offset][run].len = 30;
									coeff_VLC[intra][last][offset - level][run].code
									= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-(int)level & 0xfff) << 1) | 1;
								coeff_VLC[intra][last][offset - level][run].len = 30;
							}
							continue;
						}
					}

					coeff_VLC[intra][last][level + offset][run].code
						= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len)
						|  coeff_VLC[intra][last][level_esc + offset][run_esc].code;
					coeff_VLC[intra][last][level + offset][run].len
						= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len;

					if (!intra)
					{
						coeff_VLC[intra][last][offset - level][run].code
							= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len)
							|  coeff_VLC[intra][last][level_esc + offset][run_esc].code | 1;
						coeff_VLC[intra][last][offset - level][run].len
							= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len;
					}
				}

				if (!intra)
				{
					coeff_VLC[intra][last][0][run].code
						= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-32 & 0xfff) << 1) | 1;
					coeff_VLC[intra][last][0][run].len = 30;
				}
			}
		}
	}


}

void CodeCoeffIntra(Stream* bs, short* data , unsigned short* zigzag)
{
   	unsigned int i, abs_level, run, prev_run, code, len;
	int level, prev_level;

	i	= 1;
	run = 0;

	while (i<64 && !(level = data[zigzag[i++]]))
	{
		run++;
	}

	prev_level = level;
	prev_run   = run;
	run = 0;

	while (i < 64)
	{
		if ((level = data[zigzag[i++]]) != 0)
		{
			abs_level = abs(prev_level);
			abs_level = abs_level < 64 ? abs_level : 0;
			code	  = coeff_VLC[1][0][abs_level][prev_run].code;
			len		  = coeff_VLC[1][0][abs_level][prev_run].len;
			if (len != 128)
			{
				code |= (prev_level < 0);
			}
			else
			{
		        code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
				len  = 30;
			}
			StreamPutBits(bs, code, len);
			prev_level = level;
			prev_run   = run;
			run = 0;
		}
		else
		{
			run++;
		}
	}

	abs_level = abs(prev_level);
	abs_level = abs_level < 64 ? abs_level : 0;
	code	  = coeff_VLC[1][1][abs_level][prev_run].code;
	len		  = coeff_VLC[1][1][abs_level][prev_run].len;
	if (len != 128)
	{	
		code |= (prev_level < 0);
	}
	else
	{
		code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
		len  = 30;
	}

	StreamPutBits(bs, code, len);
}

void CodeCoeffInter(Stream* bs, short qcoeff[64], unsigned short * zigzag)
{
	unsigned int i, run, prev_run, code, len;
	int level, prev_level, level_shifted;

	i	= 0;
	run = 0;

	while (!(level = qcoeff[zigzag[i++]]))
	{
		run++;
	}

	prev_level = level;
	prev_run   = run;
	run = 0;

	while (i < 64)
	{
		if ((level = qcoeff[zigzag[i++]]) != 0)
		{
			level_shifted = prev_level + 32;
			if (!(level_shifted & -64))
			{
				code = coeff_VLC[0][0][level_shifted][prev_run].code;
				len	 = coeff_VLC[0][0][level_shifted][prev_run].len;
			}
			else
			{
				code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
				len  = 30;
			}

			StreamPutBits(bs, code, len);
			prev_level = level;
			prev_run   = run;
			run = 0;
		}
		else
		{
			run++;
		}
	}

	level_shifted = prev_level + 32;
	if (!(level_shifted & -64))
	{
		code = coeff_VLC[0][1][level_shifted][prev_run].code;
		len	 = coeff_VLC[0][1][level_shifted][prev_run].len;
	}
	else
	{
		code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;
		len  = 30;
	}
	StreamPutBits(bs, code, len);
}

⌨️ 快捷键说明

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