📄 vlc.cpp
字号:
/*************************************************************************
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 + -