📄 vlc.cpp
字号:
*
*******************************************************************************/
int EncCoeff(putstrm *putstrmctrl, int intra, int CBP, INT16 *qcoeff, int ncoeffs)
{
int bits = 0;
int i, j;
if (!intra)
{
for (i = 0; i < 6; i++)
{
if ((i==0 && CBP&32) ||
(i==1 && CBP&16) ||
(i==2 && CBP&8) ||
(i==3 && CBP&4) ||
(i==4 && CBP&2) ||
(i==5 && CBP&1))
{
bits += CodeCoeff(putstrmctrl, intra, qcoeff, i, ncoeffs);
}
}
}
else if (2 == intra)
{
for (i = 0; i < 6; i++)
{
if ((i==0 && CBP&32) ||
(i==1 && CBP&16) ||
(i==2 && CBP&8) ||
(i==3 && CBP&4) ||
(i==4 && CBP&2) ||
(i==5 && CBP&1))
{
bits += CodeCoeff_AIC(putstrmctrl, qcoeff, i, ncoeffs);
}
}
}
else
{
for (i = 0; i < 6; i++)
{
bits += CodeCoeff(putstrmctrl, intra, qcoeff, i, ncoeffs);
}
}
return bits;
}
//Name : vlcmcbpcI;
//Input : CBP & mode of a MB, CBP & mode;
//Output : number of bits put into bitstream;
//Discription : this function is for INTRA MB
// usage: vlcstr * cbpcI = vlcmcbpcI (CBP, mode);
int vlcmcbpcI (putstrm *putstrmctrl, int CBP, int mode)
{
int CBPC = CBP & 3;
int index = (mode == MODE_INTRA) ? CBPC : (CBPC & 4);
if ((index <8) && (index >= 0))
{
putbits (putstrmctrl, mcbpctabI[index].cdwd, mcbpctabI[index].len);
return mcbpctabI[index].len;
}
else //!< ??should be considered carefully later
{
putbits (putstrmctrl, mcbpctabI[8].cdwd, mcbpctabI[8].len);
return mcbpctabI[8].len;
}
}
//Name : vlcmcbpcP;
//Input : CBP & mode of a MB, CBP & mode;
//Output : number of bits put into bitstream;
//Discription : this function is for INTER MB
// usage: vlcstr * cbpcI = vlcmcbpcI (CBP, mode);
int vlcmcbpcP(putstrm *putstrmctrl, int CBP, int mode)
{
int CBPC = CBP & 3;
int index = CBPC | (mode << 2);
if ((index < 20) && (index >= 0))
{
putbits (putstrmctrl, mcbpctabP[index].cdwd, mcbpctabP[index].len);
return mcbpctabP[index].len;
}
else //!< ??should be considered carefully later
{
putbits (putstrmctrl, mcbpctabP[20].cdwd, mcbpctabP[20].len);
return mcbpctabP[20].len;
}
}
//Name : vlccbpy;
//Input : CBP & mode of a MB, CBP & mode;
//Output : a vlcstr type pointer, pointing to the position in cbpytab, which is determined
// by CBPY & mode;
//Discription :
// usage: vlcstr * cbpcI = vlcmcbpcI (CBP, mode);
int vlccbpy (putstrm *putstrmctrl, int CBP, int mode)
{
int CBPY = CBP >> 2;
int index = (mode == MODE_INTRA)||(mode == MODE_INTRA_Q) ? CBPY : CBPY ^ 15;
putbits (putstrmctrl, cbpytab [index].cdwd, cbpytab[index].len);
return cbpytab[index].len;
}
//Name : vlcmv;
//Input : difference of mv and pmv
//Output : number of bits of vlc-encoded mv
//Discription : put vlc-codeword of mv into bitstream. for mv should return two parameter
// vlcstr, and sign, this function will put bits into bitstream to avoid return
// so many parameters;
int vlcmv (putstrm *putstrmctrl, int dmv)
{
int index,sign = 0;
if(dmv)
{
if (dmv >= 0)
{
if (dmv < 32)
index = dmv;
else if (dmv <= 63)
{
index = 64 - dmv;
sign = 1;
}
else
{
printf ("ERROR HAPPENED IN VLC-ENCODE OF MV! MV>63.\n");
exit (0);
}
}
else
{
if (dmv >= -32)
{
index = -dmv;
sign = 1;
}
else if (dmv >= -63)
index = 64 + dmv;
else
{
printf ("ERROR HAPPENED IN VLC-ENCODE OF MV! MV<-63.\n");
exit (0);
}
}
/*
if (dmv >= 0 && dmv <= 32)
index = dmv;
else if (dmv < 0 && dmv >= -32)
{
index = -dmv;
sign = 1;
}
else if (dmv < -32 && dmv >= -63)
index = 64 + dmv;
else if (dmv > 32 && dmv <= 63)
{
index = 64 - dmv;
sign = 1;
}
else
{
printf ("ERROR HAPPENED WHEN VLCMV.\n");
exit (0);
}
*/
putbits (putstrmctrl, mvtab[index].cdwd, mvtab[index].len);
putbits (putstrmctrl, sign, 1);
return mvtab[index].len + 1;
}
else
{
putbits (putstrmctrl, 1,1);
return 1;
}
}
/*!
*******************************************************************************
*
* Name:
* Description:
* Input:
* Output:
* Last modified:
*
*******************************************************************************/
int CodeCoeff(putstrm *putstrmctrl, int intra, INT16 *qcoeff, int block, int ncoeffs)
{
int j, bits;
int prev_run, run, prev_level, level, first;
int prev_s, s, length;
run = bits = 0;
first = 1;
prev_run = prev_level = level = s = prev_s = 0;
for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++)
{
/* Do this block's DC-coefficient first */
if (!(j%ncoeffs) && intra)
{
/* DC coeff */
if (qcoeff[block*ncoeffs] != 128)
putbits(putstrmctrl, qcoeff[block*ncoeffs], 8);
else
putbits(putstrmctrl, 255, 8);
bits += 8;
}
else {
/* AC coeff */
s = 0;
/* Increment run if coeff is zero */
if ((level = qcoeff[j]) == 0)
{
run++;
}
else
{
/* code run & level and count bits */
if (level < 0)
{
s = 1;
level = -level;
}
if (!first)
{
/* Encode the previous coefficient */
if (prev_level < 13 && prev_run < 64)
length = put_coeff (putstrmctrl, prev_run, prev_level, 0);
else
length = 0;
if (length == 0)
{ /* Escape coding */
if (prev_s == 1)
{
prev_level = (prev_level^0xff)+1;
}
putbits(putstrmctrl, 3, 7); /* Escape code */
putbits(putstrmctrl, 0, 1);
putbits(putstrmctrl, prev_run, 6);
putbits(putstrmctrl, prev_level, 8);
bits += 22;
}
else
{
putbits(putstrmctrl, prev_s, 1);
bits += length + 1;
}
}
prev_run = run; prev_s = s;
prev_level = level;
run = first = 0;
}
}
}
/* Encode the last coeff */
if (!first)
{
if (prev_level < 13 && prev_run < 64)
length = put_coeff (putstrmctrl, prev_run, prev_level, 1);
else
length = 0;
if (length == 0)
{ /* Escape coding */
if (prev_s == 1)
{
prev_level = (prev_level^0xff)+1;
}
putbits (putstrmctrl, 3, 7); /* Escape code */
putbits(putstrmctrl, 1, 1);
putbits(putstrmctrl, prev_run, 6);
putbits(putstrmctrl, prev_level, 8);
bits += 22;
}
else {
putbits(putstrmctrl, prev_s, 1);
bits += length + 1;
}
}
return bits;
}
/*!
*******************************************************************************
*
* Name:
* Description:
* Input:
* Output:
* Last modified:
*
*******************************************************************************/
int put_coeff (putstrm *putstrmctrl, int run, int level, int last)
{
int length = 0;
assert (last >= 0 && last < 2);
assert (run >= 0 && run < 64);
assert (level > 0 && level < 128);
if (last == 0)
{
if (run < 2 && level < 13 )
{
putbits (putstrmctrl, coeff_tab0[run][level-1].cdwd, coeff_tab0[run][level-1].len);
length = coeff_tab0[run][level-1].len;
}
else if (run > 1 && run < 27 && level < 5)
{
putbits (putstrmctrl, coeff_tab1[run-2][level-1].cdwd, coeff_tab1[run-2][level-1].len);
length = coeff_tab1[run-2][level-1].len;
}
}
else if (last == 1)
{
if (run < 2 && level < 4)
{
putbits (putstrmctrl, coeff_tab2[run][level-1].cdwd, coeff_tab2[run][level-1].len);
length = coeff_tab2[run][level-1].len;
}
else if (run > 1 && run < 42 && level == 1)
{
putbits (putstrmctrl, coeff_tab3[run-2].cdwd, coeff_tab3[run-2].len);
length = coeff_tab3[run-2].len;
}
}
return length;
}
int put_intra_coeff (putstrm *putstrmctrl, int run, int level, int last)
{
int length = 0;
assert (last >= 0 && last < 2);
assert (run >= 0 && run < 64);
assert (level > 0 && level < 128);
if (last == 0)
{
if (run < 2 && level < 26)
{
putbits (putstrmctrl, intra_coeff_tab0[run][level - 1].cdwd, intra_coeff_tab0[run][level - 1].len);
length = intra_coeff_tab0[run][level - 1].len;
}
else if (run > 1 && run < 14 && level < 5)
{
putbits (putstrmctrl, intra_coeff_tab1[run - 2][level - 1].cdwd, intra_coeff_tab1[run - 2][level - 1].len);
length = intra_coeff_tab1[run - 2][level - 1].len;
}
}
else if (last == 1)
{
if (run < 2 && level < 11)
{
putbits (putstrmctrl, intra_coeff_tab2[run][level - 1].cdwd, intra_coeff_tab2[run][level - 1].len);
length = intra_coeff_tab2[run][level - 1].len;
}
else if (run > 1 && run < 24 && level < 4)
{
putbits (putstrmctrl, intra_coeff_tab3[run - 2][level - 1].cdwd, intra_coeff_tab3[run - 2][level - 1].len);
length = intra_coeff_tab3[run - 2][level - 1].len;
}
}
return length;
}
int CodeCoeff_AIC(putstrm *putstrmctrl, INT16 *qcoeff, int block, int ncoeffs)
{
int bits = 0;
int run = 0;
int first = 1;
int prev_level = 0;
int prev_run = 0;
int level = 0;
int s = 0;
int prev_s = 0;
int length;
int j;
for (j = block * ncoeffs; j < (block + 1) * ncoeffs; j++)
{
/* DC/AC in advanced intra coding mode */
s = 0;
/* Increment run if coeff is zero */
if ((level = qcoeff[j]) == 0)
{
run++;
}
else
{
/* code run & level and count bits */
if (-127 <= level && level < 0)
{
s = 1;
level = -level;
}
if (!first)
{
/* Encode the previous coefficient */
if (prev_level >= 0 && prev_level < 26 && prev_run < 64)
{
length = put_intra_coeff (putstrmctrl, prev_run, prev_level, 0);
}
else
{
length = 0;
}
if (length == 0)
{ /* Escape coding */
if (prev_s == 1)
{
prev_level = (prev_level ^ 0xffff) + 1;
}
putbits (putstrmctrl, 3, 7); /* Escape code */
putbits (putstrmctrl, 0, 1);
putbits (putstrmctrl, prev_run, 6);
putbits (putstrmctrl, prev_level, 8);
bits += 22;
}
else
{
putbits (putstrmctrl, prev_s, 1);
bits += length + 1;
}
}
prev_run = run;
prev_s = s;
prev_level = level;
run = first = 0;
}
}
/* Encode the last coeff */
if (!first)
{
if (prev_level >= 0 && prev_level < 26 && prev_run < 64)
{
length = put_intra_coeff (putstrmctrl, prev_run, prev_level, 1);
}
else
length = 0;
if (length == 0)
{ /* Escape coding */
if (prev_s == 1)
{
prev_level = (prev_level ^ 0xffff) + 1;
}
putbits (putstrmctrl, 3, 7); /* Escape code */
putbits (putstrmctrl, 1, 1);
putbits (putstrmctrl, prev_run, 6);
putbits (putstrmctrl, prev_level, 8);
bits += 22;
} else
{
putbits (putstrmctrl, prev_s, 1);
bits += length + 1;
}
}
return bits;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -