📄 mbcoding.c
字号:
/* value += 2 * length;*/
/* value += length<<1;*/
/*
sign = (value < 0);
if (sign)
code = value ;
else
code = value;
*/
/*
mv_res = value & ((1 << f_code) - 1);
code = ((value - mv_res) >> f_code) + 1;
code = value +1 ;
if (sign)
code = -code;
*/
/*
code =value + 32;
BitstreamPutBits(bs, mb_motion_table[code].code,
mb_motion_table[code].len);
vector_length+=mb_motion_table[code].len;
*/
/*whq,2002.12.25*/
/*
if (f_code){
BitstreamPutBits(bs, mv_res, f_code);
vector_length+=f_code;
}
*/
/* }*/
return vector_length;
}
/*!
************************************************************************
* \brief
* get vlc code for coeff
*
************************************************************************
*/
#ifndef _TRIMEDIA
static __inline void
CodeCoeff(Bitstream * bs, /*<--> bitstream buffer */
const int16_t qcoeff[64], /*<-- 8*8 block coeff value */
VLC * table, /*<-- vlc code table*/
const uint16_t * zigzag, /*<-- scan order */
uint16_t intra) /*<-- intra or inter */
{
uint32_t j,last;
short v;
VLC *vlc,*vlc0;
last = intra;/*记录前一次扫描系数的的位置*/
j = intra;/*记录此次系数的位置,用于求取run值*/
/*====记录下个非零值的位置,用于求出中间零的个数====*/
while (j < 64 && (v = qcoeff[zigzag[j]]) == 0)
j++;
vlc0 = table +131008;
/*====循环求取码字,直到系数都扫描完====*/
do {
/*vlc = table + 64 * 2047 + (v << 6) + j - last;*/
/*decrease multiply by do it by hand,whq ,12-11*/
/*vlc = table + 131008 + (v << 6) + j - last;*/
/*whq,move table+131008 out of loop */
vlc = vlc0 + (v << 6) + j - last;
last = ++j;
/* count zeroes*/
while (j < 64 && (v = qcoeff[zigzag[j]]) == 0)
j++;
/* write code*/
if (j != 64) {
BitstreamPutBits(bs, vlc->code, vlc->len);
} else {
/*vlc += 64 * 4095;*/
vlc += 262080;
BitstreamPutBits(bs, vlc->code, vlc->len);
break;
}
} while (1);
}
#else
int16_t run[64];
int16_t value[64];
/*static __inline void*/
static void
CodeCoeff(Bitstream * bs, /*<--> bitstream buffer */
const int16_t qcoeff[64], /*<-- 8*8 block coeff value */
VLC * table, /*<-- vlc code table*/
const uint16_t * zigzag, /*<-- scan order */
uint16_t intra) /*<-- intra or inter */
{
uint32_t j,i,k,runvalue;
short v;
VLC *vlc,*vlc0;
/*====记录下个非零值的位置,用于求出中间零的个数====*/
runvalue = 0;
i = 0;
if(intra)
{
for (j=1; j<64; j++)
{
v = qcoeff[zigzag[j]];
if (v)
{
run[i]=runvalue;
value[i++]=v;
runvalue = 0;
}
if(!v)
runvalue++;
}
}
if (!intra)
{
#pragma TCS_unroll=8
for (j=0; j<64; j++)
{
v = qcoeff[zigzag[j]];
if (v)
{
run[i]=runvalue;
value[i++]=v;
runvalue = 0;
}
if(!v)
runvalue++;
}
}
vlc0 = table +131008;
for(k=0;k<i-1;k++)
{
vlc = vlc0 + (value[k] << 6) + run[k];
BitstreamPutBits(bs, vlc->code, vlc->len);
}
vlc = vlc0 + (value[k] << 6) + run[k];
vlc += 262080;
BitstreamPutBits(bs, vlc->code, vlc->len);
}
#endif
/*!
************************************************************************
* \brief
* put intra block info and vlc code into bitstream
*
************************************************************************
*/
static void /* ==> return the bits for the macroblock */
CodeBlockIntra(const FRAMEINFO * frame, /*<-- frame info */
const MACROBLOCK * pMB, /*<-- macroblock info */
int16_t qcoeff[6 * 64], /*<-- 8*8 block coeff value */
Bitstream * bs, /*<--> bitstream buffer */
Statistics * pStat /*<--> stat bits */
)
{
uint32_t i, mcbpc, cbpy, bits;
cbpy = pMB->cbp >> 2;
/* write mcbpc*/
if (frame->coding_type == I_VOP) {
mcbpc = ((pMB->mode >> 1) & 3) | ((pMB->cbp & 3) << 2);
BitstreamPutBits(bs, mcbpc_intra_tab[mcbpc].code,
mcbpc_intra_tab[mcbpc].len);
} else {
mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3);
BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code,
mcbpc_inter_tab[mcbpc].len);
}
/* ac prediction flag*/
if (pMB->acpred_directions[0])
BitstreamPutBits(bs, 1, 1);
else
BitstreamPutBits(bs, 0, 1);
/* write cbpy*/
BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len);
/* write dquant*/
if (pMB->mode == MODE_INTRA_Q)
BitstreamPutBits(bs, pMB->dquant, 2);
/* write interlacing*/
/* if (frame->global_flags & XVID_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))) {
bits = BitstreamPos(bs);
CodeCoeff(bs, &qcoeff[i * 64], intra_table,
scan_tables[pMB->acpred_directions[i]], 1);
bits = BitstreamPos(bs) - bits;
pStat->iTextBits += bits;
}
}
}
/*!
************************************************************************
* \brief
* put inter block info and vlc code into bitstream
*
************************************************************************
*/
static int16_t /* ==> return the bits for the macroblock */
CodeBlockInter(const FRAMEINFO * frame, /*<-- frame info */
const MACROBLOCK * pMB, /*<-- macroblock info */
int16_t qcoeff[6 * 64], /*<-- 8*8 block coeff value */
Bitstream * bs, /*<--> bitstream buffer */
Statistics * pStat /*<--> stat bits */
)/*修改此函数使其返回运动向量占的位数 modify by lxq*/
{
int32_t i;
uint32_t bits, mcbpc, cbpy;
int16_t vector_length=0;
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);
/* write cbpy*/
BitstreamPutBits(bs, cbpy_tab[cbpy].code, cbpy_tab[cbpy].len);
/* write dquant*/
if (pMB->mode == MODE_INTER_Q)
BitstreamPutBits(bs, pMB->dquant, 2);
/* interlacing*/
/* if (frame->global_flags & XVID_INTERLACING) {
BitstreamPutBit(bs, pMB->field_dct);
DEBUG1("codep: field_dct: ", pMB->field_dct);*/
/* if inter block, write field ME flag*/
/* if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {
BitstreamPutBit(bs, pMB->field_pred);
DEBUG1("codep: field_pred: ", pMB->field_pred);*/
/* write field prediction references*/
/* if (pMB->field_pred) {
BitstreamPutBit(bs, pMB->field_for_top);
BitstreamPutBit(bs, pMB->field_for_bot);
}
}
}*/
/* code motion vector(s)*/
for (i = 0; i < (pMB->mode == MODE_INTER4V ? 4 : 1); i++) {
vector_length+=CodeVector(bs, pMB->pmvs[i].x, frame->fcode, pStat);
vector_length+=CodeVector(bs, pMB->pmvs[i].y, frame->fcode, pStat);
}
bits = BitstreamPos(bs);
/* code block coeffs*/
for (i = 0; i < 6; i++)
if (pMB->cbp & (1 << (5 - i)))
CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0);
bits = BitstreamPos(bs) - bits;
pStat->iTextBits += bits;
return vector_length;
}
/*!
************************************************************************
* \brief
* Coding a frame (I or P)
*
************************************************************************
*/
int16_t /* ==> return the bits for the vector */
MBCoding(const FRAMEINFO * frame, /*<-- frame info */
MACROBLOCK * pMB, /*<-- macroblock info */
int16_t qcoeff[6 * 64], /*<-- 8*8 block coeff value */
Bitstream * bs, /*<--> bitstream buffer */
Statistics * pStat /*<--> stat bits */
)/*修改此函数使其返回运动向量占的位数 modify by lxq*/
{
int16_t vector_length=0;/*用于计算运动向量的长度*/
int intra = (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q);
/*====code P frame,judge whether the macroblock need coding ====*/
if (frame->coding_type == P_VOP) {
if (pMB->cbp == 0 && pMB->mode == MODE_INTER && pMB->mvs[0].x == 0 &&
pMB->mvs[0].y == 0) {
BitstreamPutBit(bs, 1); /* not_coded*/
return 0;
} else
BitstreamPutBit(bs, 0); /* coded*/
}
/*====code intra macroblock====*/
if (intra)
CodeBlockIntra(frame, pMB, qcoeff, bs, pStat);
else
/*====code inter macroblock====*/
vector_length=CodeBlockInter(frame, pMB, qcoeff, bs, pStat);
return vector_length;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -