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

📄 vlc.cpp

📁 AVS是中国自己推出的视频图像音频编解码标准。包中是AVS 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
 AVS1-P2视频解码器源码
 版权所有:联合信源数字音视频技术(北京)有限公司, (c) 2005-2006 

 AVS1-P2 Video Decoder Source Code
 (c) Copyright, NSCC All Rights Reserved, 2005-2006
 *************************************************************************
 Distributed under the terms of the GNU General Public License as
 published by the Free Software Foundation; either version 2 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*************************************************************************/
/*************************************************************************
  文件名称:	vlc.cpp
  描    述: 变长解码过程相关的函数。
*************************************************************************/
/*************************************************************************
  Revision History
  data          Modification                                    Author
  2005-2-8      Created                                          jthou
 *************************************************************************/

#include "vlc.h"
#include "define.h"
#include "global.h"
#include "assert.h"
#include "memory.h"

char AVS_2DVLC_INTRA_dec[7][64][2]={{{-1,-1}}};
char AVS_2DVLC_INTER_dec[7][64][2]={{{-1,-1}}};
char AVS_2DVLC_CHROMA_dec[5][64][2]={{{-1,-1}}};

/************************************************************************/
/* 函数功能:数码流中1前面有多少个零                                    */
/*         - 用在解哥伦布码中                                           */
/************************************************************************/
AVS_INT PassLeadingZeroBits(const AVS_BYTE* buffer,AVS_DWORD* totbitoffset)
{
	AVS_LONG byteoffset;      // byte from start of buffer
	AVS_INT bitLeft;      // bit from start of byte
	AVS_INT findtag;
	AVS_INT oldbitoffset = *totbitoffset;
	findtag=0;  
	byteoffset= (*totbitoffset)/8;
	bitLeft= 31-((*totbitoffset)&7);
	AVS_INT data = DWORD_SWAP(*(AVS_DWORD*)(buffer+byteoffset));
	
	
	while(!findtag)
	{
		findtag = (data & (0x01<<bitLeft));
		bitLeft--;
		(*totbitoffset) ++;
	}
	
	return *totbitoffset-oldbitoffset-1;
}

/************************************************************************/
/* 函数功能:从当前位置取出numbits位                                    */
/*         - 用在解定长和变长码中                                       */
/************************************************************************/
AVS_INT read_bits(const AVS_BYTE* buffer, AVS_DWORD* totbitoffset, AVS_INT numbits)
{
	if(numbits == 0)
		return 0;
	AVS_INT inf;
	AVS_INT byteoffset = (*totbitoffset)>>3;
	AVS_INT bitoffset = (*totbitoffset)&7;
	AVS_INT bitleft = 31-bitoffset;
	AVS_UINT data = DWORD_SWAP(*(AVS_DWORD*)(buffer+byteoffset));
	
	*totbitoffset += numbits;
	AVS_UINT tmp = data<<bitoffset;
	inf = tmp>>(32-numbits);
	return inf;
}

AVS_INT se(const AVS_BYTE*  buffer,AVS_DWORD* totbitoffset, AVS_INT bytecount)
{
	AVS_INT info = 0;
	AVS_INT value1=0;
	AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);
	info = read_bits(buffer, totbitoffset, len); 
	linfo_se(len,info,&value1);
	
	return value1;  
}

AVS_INT ue(const AVS_BYTE*  buffer,AVS_DWORD* totbitoffset, AVS_INT bytecount)
{
	AVS_INT info = 0;
	AVS_INT value1;
	
	AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);
	info = read_bits(buffer, totbitoffset, len); 
	linfo_ue(len*2+1,info,&value1);
	
	
	return value1;  
}

void linfo_ue(AVS_INT len, AVS_INT info, AVS_INT *value1)
{
	//*value1 = (AVS_INT)pow(2,(len/2))+info-1; 
	AVS_INT n = 1<<(len/2);
	info --;
	*value1 = n + info;
}

void linfo_se(AVS_INT len,  AVS_INT info, AVS_INT *value1)
{
	AVS_INT n;
	n = 1<<len;
	n += info;
	if(n&1)
		*value1 = -(n>>1);
	else
		*value1 = (n>>1);
}

void linfo_cbp_intra(AVS_INT len,AVS_INT info,AVS_INT *cbp)
{
	AVS_INT cbp_idx;
	linfo_ue(len,info,&cbp_idx);
	*cbp=NCBP[cbp_idx][0];
}

void linfo_cbp_inter(AVS_INT len,AVS_INT info,AVS_INT *cbp)
{
	AVS_INT cbp_idx;
	linfo_ue(len,info,&cbp_idx);
	*cbp=NCBP[cbp_idx][1];
}

void linfo_cbp_intra422(AVS_INT len,AVS_INT info,AVS_INT *cbp)
{
	AVS_INT cbp_idx;
	linfo_ue(len,info,&cbp_idx);
	*cbp=NCBP422[cbp_idx][0];
}

void linfo_cbp_inter422(AVS_INT len,AVS_INT info,AVS_INT *cbp)
{
	AVS_INT cbp_idx;
	linfo_ue(len,info,&cbp_idx);
    *cbp=NCBP422[cbp_idx][1];
}

AVS_INT me(const AVS_BYTE* buffer,AVS_DWORD* totbitoffset, AVS_INT bytecount, AVS_DWORD dwMbType)
{
	
	AVS_INT cbp = 0;
	AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);
	AVS_INT info = read_bits(buffer, totbitoffset, len); 
	if(dwMbType == I_8x8)
		linfo_cbp_intra(len*2+1, info, &cbp);
	else
		linfo_cbp_inter(len*2+1, info, &cbp);
	return cbp;
}

AVS_INT me_chroma422(const AVS_BYTE* buffer,AVS_DWORD* totbitoffset, AVS_INT bytecount, AVS_DWORD dwMbType)
{
	AVS_INT cbp = 0;
	AVS_INT len = PassLeadingZeroBits(buffer, totbitoffset);
	AVS_INT info = read_bits(buffer, totbitoffset, len); 
	if(dwMbType == I_8x8)
		linfo_cbp_intra422(len*2+1, info, &cbp);
	else
		linfo_cbp_inter422(len*2+1, info, &cbp);
	return cbp;
}

/************************************************************************/
/* 函数功能:初始化VLC表                                                */
/************************************************************************/
void MakeVlcTable()
{
	AVS_INT level, run, ipos;
	AVS_INT i;
	//make decoder table for 2DVLC_INTRA code
	if(AVS_2DVLC_INTRA_dec[0][0][1]<0)                                                          // Don't need to set this every time. rewrite later.
	{
		memset(AVS_2DVLC_INTRA_dec,-1,sizeof(AVS_2DVLC_INTRA_dec));
		for(i=0;i<7;i++)
		{
			for(run=0;run<26;run++)
				for(level=0;level<27;level++)
				{
					ipos=AVS_2DVLC_INTRA[i][run][level];
					assert(ipos<64);
					if(ipos>=0)
					{
						if(i==0)
						{
							AVS_2DVLC_INTRA_dec[i][ipos][0]=level+1;
							AVS_2DVLC_INTRA_dec[i][ipos][1]=run;
							
							AVS_2DVLC_INTRA_dec[i][ipos+1][0]=-(level+1);
							AVS_2DVLC_INTRA_dec[i][ipos+1][1]=run;
						}
						else
						{
							AVS_2DVLC_INTRA_dec[i][ipos][0]=level;
							AVS_2DVLC_INTRA_dec[i][ipos][1]=run;
							
							if(level)
							{
								AVS_2DVLC_INTRA_dec[i][ipos+1][0]=-(level);
								AVS_2DVLC_INTRA_dec[i][ipos+1][1]=run;
							}
						}
					}
				}
		}
		assert(AVS_2DVLC_INTRA_dec[0][0][1]>=0);        //otherwise, tables are bad.
	}
	
	//make decoder table for 2DVLC_INTER code
	if(AVS_2DVLC_INTER_dec[0][0][1]<0)                                                          // Don't need to set this every time. rewrite later.
	{
		memset(AVS_2DVLC_INTER_dec,-1,sizeof(AVS_2DVLC_INTER_dec));
		for(i=0;i<7;i++)
		{
			for(run=0;run<26;run++)
				for(level=0;level<27;level++)
				{
					ipos=AVS_2DVLC_INTER[i][run][level];
					assert(ipos<64);
					if(ipos>=0)
					{
						if(i==0)
						{
							AVS_2DVLC_INTER_dec[i][ipos][0]=level+1;
							AVS_2DVLC_INTER_dec[i][ipos][1]=run;
							
							AVS_2DVLC_INTER_dec[i][ipos+1][0]=-(level+1);
							AVS_2DVLC_INTER_dec[i][ipos+1][1]=run;
						}
						else
						{
							AVS_2DVLC_INTER_dec[i][ipos][0]=level;
							AVS_2DVLC_INTER_dec[i][ipos][1]=run;
							
							if(level)
							{
								AVS_2DVLC_INTER_dec[i][ipos+1][0]=-(level);
								AVS_2DVLC_INTER_dec[i][ipos+1][1]=run;
							}
						}
					}
				}
		}
		assert(AVS_2DVLC_INTER_dec[0][0][1]>=0);        //otherwise, tables are bad.

⌨️ 快捷键说明

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