📄 putvlc.c
字号:
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab3[run - 2].code,
coeff_tab3[run - 2].len);
}
}
}
return length;
}
__inline static int PutLevelCoeff4intra(BitWriter * bitstream, int run, int level, int last)
{
int length = 0;
assert(run >= 0 && run < 64);
assert(level > 0 && level < 128);
if (!last)
{
if (run == 0 && level < 28)
{
length = coeff_tab4[level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab4[level - 1].code,
coeff_tab4[level - 1].len);
}
}
else if (run == 1 && level < 11)
{
length = coeff_tab5[level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab5[level - 1].code,
coeff_tab5[level - 1].len);
}
}
else if (run > 1 && run < 10 && level < 6)
{
length = coeff_tab6[run - 2][level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab6[run - 2][level - 1].code,
coeff_tab6[run - 2][level - 1].len);
}
}
else if (run > 9 && run < 15 && level == 1)
{
length = coeff_tab7[run - 10].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab7[run - 10].code,
coeff_tab7[run - 10].len);
}
}
}
else // last == 1
{
if (run == 0 && level < 9)
{
length = coeff_tab8[level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab8[level - 1].code,
coeff_tab8[level - 1].len);
}
}
else if (run > 0 && run < 7 && level < 4)
{
length = coeff_tab9[run - 1][level - 1].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab9[run - 1][level - 1].code,
coeff_tab9[run - 1][level - 1].len);
}
}
else if (run > 6 && run < 21 && level == 1)
{
length = coeff_tab10[run - 7].len;
if (length != 0)
{
BitstreamPutBits(bitstream, 3L, 7L);
/* boon19970701 */
BitstreamPutBits(bitstream, 0L, 1L);
length += 8; /* boon */
BitstreamPutBits(bitstream,
coeff_tab10[run - 7].code,
coeff_tab10[run - 7].len);
}
}
}
return length;
}
/***********************************************************CommentBegin******
*
* -- PutIntraDC -- DPCM Encoding of INTRADC in case of Intra macroblocks
*
* Purpose :
* DPCM Encoding of INTRADC in case of Intra macroblocks
*
* Arguments in :
* int val : the difference value with respect to the previous
* INTRADC value
* int lum : indicates whether the block is a luminance block (lum=1) or
* a chrominance block ( lum = 0)
*
* Arguments out :
* BitWriter* bitstream : a pointer to the output bitstream
*
***********************************************************CommentEnd********/
int PutIntraDC(BitWriter * bitstream, int val, bool lum)
{
int n_bits;
int absval, size = 0;
absval = (val < 0) ? -val : val;
// dct_dc_size
size = 0;
while (absval)
{
absval >>= 1;
size++;
}
if (lum)
n_bits = PutDCsize4lum(bitstream, size);
else
n_bits = PutDCsize4chrom(bitstream, size);
if (size != 0)
{
if (val < 0)
{
absval = -val;
val = absval ^ ((1 << size) - 1);
}
BitstreamPutBits(bitstream, (long) (val), (long) (size));
n_bits += size;
if (size > 8)
BitstreamPutBits(bitstream, (long) 1, (long) 1);
}
return n_bits; // bits for intra_dc dpcm
}
static int intra_max_run0[28] = {
0, 14, 9, 7, 3, 2, 1,
1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
};
static int intra_max_run1[9] = {
0, 20, 6,
1, 0, 0,
0, 0, 0
};
static int inter_max_run0[13] = {
0,
26, 10, 6, 2, 1, 1,
0, 0, 0, 0, 0, 0
};
static int inter_max_run1[4] = {
0, 40, 1, 0
};
static __declspec(align(16)) int intra_max_level[2][64] = {
{
27, 10, 5, 4, 3, 3, 3, 3,
2, 2, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
},
{
8, 3, 2, 2, 2, 2, 2, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0}
};
static __declspec(align(16)) int inter_max_level[2][64] = {
{
12, 6, 4, 3, 3, 3, 3, 2,
2, 2, 2, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
},
{
3, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0}
};
__inline static int PutCoeff_Last(BitWriter * bitstream, int run, int level, int Mode)
{
int s = 0;
bool intra = 0;
int length = 0;
assert(level != 0);
assert(bitstream);
assert(run < 64);
assert(run >= 0);
if (level < 0)
{
s = 1;
level = -level;
}
if ((Mode == MODE_INTRA) || (Mode == MODE_INTRA_Q))
intra = 1;
if ((run < 64) && (((level < 4) && !intra) || ((level < 9) && intra)))
{
// Separate tables for Intra luminance blocks
if (intra)
length = PutCoeff4intra(bitstream, run, level, 1);
else
length = PutCoeff4inter(bitstream, run, level, 1);
}
// First escape mode. Level offset
if (length == 0)
{
/* subtraction of Max level, last = 0 */
int level_minus_max;
if (intra)
level_minus_max = level - intra_max_level[1][run];
else
level_minus_max = level - inter_max_level[1][run];
if (((level_minus_max < 4) && (!intra)) ||
((level_minus_max < 9) && intra))
{
/* Separate tables for Intra luminance blocks */
if (intra)
length = PutLevelCoeff4intra(bitstream, run, level_minus_max, 1);
else
length = PutLevelCoeff4inter(bitstream, run, level_minus_max, 1);
}
}
// Second escape mode. Run offset
if (length == 0)
{
if (((level < 4) && (!intra)) || ((level < 9) && intra))
{
/* subtraction of Max Run, last = 1 */
int run_minus_max;
assert(level);
if (intra)
run_minus_max = run - (intra_max_run1[level] + 1);
else
run_minus_max = run - (inter_max_run1[level] + 1);
/* Separate tables for Intra luminance blocks */
if (intra)
length = PutRunCoeff4intra(bitstream, run_minus_max, level, 1);
else
length = PutRunCoeff4inter(bitstream, run_minus_max, level, 1);
}
}
// Third escape mode.
if (length == 0)
{ /* Escape coding */
if (s == 1)
level = (level ^ 0xfff) + 1;
BitstreamPutBits(bitstream, 3, 7);
BitstreamPutBits(bitstream, 3, 2);
BitstreamPutBits(bitstream, 1, 1);
BitstreamPutBits(bitstream, run, 6);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
BitstreamPutBits(bitstream, level, 12);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
return 30;
}
else
{
BitstreamPutBits(bitstream, s, 1);
return length + 1;
}
}
__inline static int PutCoeff_NotLast(BitWriter * bitstream, int run, int level,
int Mode)
{
int s = 0;
bool intra = 0;
int length = 0;
if (level < 0)
{
s = 1;
level = -level;
}
if ((Mode == MODE_INTRA) || (Mode == MODE_INTRA_Q))
intra = 1;
if ((run < 64) &&
((((level < 13) && (!intra))) || ((level < 28) && intra)))
{
if (intra)
length = PutCoeff4intra(bitstream, run, level, 0);
else
length = PutCoeff4inter(bitstream, run, level, 0);
}
/* First escape mode. Level offset */
if (length == 0)
{
if (run < 64)
{
/* subtraction of Max level, last = 0 */
int level_minus_max;
if (intra)
level_minus_max = level - intra_max_level[0][run];
else
level_minus_max = level - inter_max_level[0][run];
if (((level_minus_max < 13) && (!intra)) ||
((level_minus_max < 28) && intra))
{
/* Separate tables for Intra luminance blocks */
if (intra)
length = PutLevelCoeff4intra(bitstream, run, level_minus_max, 0);
else
length = PutLevelCoeff4inter(bitstream, run, level_minus_max, 0);
}
}
}
// Second escape mode.
if (length == 0)
{
if (((level < 13) && (!intra)) || ((level < 28) && intra))
{
/* subtraction of Max Run, last = 0 */
int run_minus_max;
assert(level);
if (intra)
run_minus_max = run - (intra_max_run0[level] + 1);
else
run_minus_max = run - (inter_max_run0[level] + 1);
/* Separate tables for Intra luminance blocks */
if (intra)
length = PutRunCoeff4intra(bitstream, run_minus_max, level, 0);
else
length = PutRunCoeff4inter(bitstream, run_minus_max, level, 0);
}
}
// Third escape mode
if (length == 0)
{
if (s)
level = (level ^ 0xfff) + 1;
BitstreamPutBits(bitstream, 3, 7);
BitstreamPutBits(bitstream, 3, 2);
BitstreamPutBits(bitstream, 0, 1);
BitstreamPutBits(bitstream, run, 6);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
BitstreamPutBits(bitstream, level, 12);
BitstreamPutBits(bitstream, MARKER_BIT, 1);
return 30;
}
else
{
BitstreamPutBits(bitstream, s, 1);
return length + 1;
}
}
int PutCoeff(BitWriter * bitstream, int run, int level, int last, int Mode)
{
if (last)
return PutCoeff_Last(bitstream, run, level, Mode);
else
return PutCoeff_NotLast(bitstream, run, level, Mode);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -