36 |
|
|
37 |
#include "../utils/mbfunctions.h" |
#include "../utils/mbfunctions.h" |
38 |
|
|
|
/* #define BIGLUT */ |
|
|
|
|
|
#ifdef BIGLUT |
|
|
#define LEVELOFFSET 2048 |
|
|
#else |
|
39 |
#define LEVELOFFSET 32 |
#define LEVELOFFSET 32 |
|
#endif |
|
40 |
|
|
41 |
static REVERSE_EVENT DCT3D[2][4096]; |
static REVERSE_EVENT DCT3D[2][4096]; |
|
|
|
|
#ifdef BIGLUT |
|
|
static VLC coeff_VLC[2][2][4096][64]; |
|
|
VLC *intra_table; |
|
|
static VLC *inter_table; |
|
|
#else |
|
42 |
static VLC coeff_VLC[2][2][64][64]; |
static VLC coeff_VLC[2][2][64][64]; |
|
#endif |
|
43 |
|
|
44 |
/* not really MB related, but VLCs are only available here */ |
/* not really MB related, but VLCs are only available here */ |
45 |
void bs_put_spritetrajectory(Bitstream * bs, const int val) |
void bs_put_spritetrajectory(Bitstream * bs, const int val) |
78 |
uint32_t i, j, k, intra, last, run, run_esc, level, level_esc, escape, escape_len, offset; |
uint32_t i, j, k, intra, last, run, run_esc, level, level_esc, escape, escape_len, offset; |
79 |
int32_t l; |
int32_t l; |
80 |
|
|
|
#ifdef BIGLUT |
|
|
intra_table = coeff_VLC[1]; |
|
|
inter_table = coeff_VLC[0]; |
|
|
#endif |
|
|
|
|
|
|
|
81 |
for (intra = 0; intra < 2; intra++) |
for (intra = 0; intra < 2; intra++) |
82 |
for (i = 0; i < 4096; i++) |
for (i = 0; i < 4096; i++) |
83 |
DCT3D[intra][i].event.level = 0; |
DCT3D[intra][i].event.level = 0; |
84 |
|
|
85 |
for (intra = 0; intra < 2; intra++) |
for (intra = 0; intra < 2; intra++) { |
86 |
for (last = 0; last < 2; last++) |
for (last = 0; last < 2; last++) { |
87 |
{ |
for (run = 0; run < 63 + last; run++) { |
88 |
for (run = 0; run < 63 + last; run++) |
for (level = 0; level < (uint32_t)(32 << intra); level++) { |
|
for (level = 0; level < (uint32_t)(32 << intra); level++) |
|
|
{ |
|
|
#ifdef BIGLUT |
|
|
offset = LEVELOFFSET; |
|
|
#else |
|
89 |
offset = !intra * LEVELOFFSET; |
offset = !intra * LEVELOFFSET; |
|
#endif |
|
90 |
coeff_VLC[intra][last][level + offset][run].len = 128; |
coeff_VLC[intra][last][level + offset][run].len = 128; |
91 |
} |
} |
92 |
} |
} |
93 |
|
} |
94 |
|
} |
95 |
|
|
96 |
for (intra = 0; intra < 2; intra++) |
for (intra = 0; intra < 2; intra++) { |
97 |
for (i = 0; i < 102; i++) |
for (i = 0; i < 102; i++) { |
|
{ |
|
|
#ifdef BIGLUT |
|
|
offset = LEVELOFFSET; |
|
|
#else |
|
98 |
offset = !intra * LEVELOFFSET; |
offset = !intra * LEVELOFFSET; |
99 |
#endif |
|
100 |
for (j = 0; j < (uint32_t)(1 << (12 - coeff_tab[intra][i].vlc.len)); j++) |
for (j = 0; j < (uint32_t)(1 << (12 - coeff_tab[intra][i].vlc.len)); j++) { |
|
{ |
|
101 |
DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].len = coeff_tab[intra][i].vlc.len; |
DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].len = coeff_tab[intra][i].vlc.len; |
102 |
DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].event = coeff_tab[intra][i].event; |
DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].event = coeff_tab[intra][i].event; |
103 |
} |
} |
106 |
= coeff_tab[intra][i].vlc.code << 1; |
= coeff_tab[intra][i].vlc.code << 1; |
107 |
coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].len |
coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].len |
108 |
= coeff_tab[intra][i].vlc.len + 1; |
= coeff_tab[intra][i].vlc.len + 1; |
109 |
#ifndef BIGLUT |
|
110 |
if (!intra) |
if (!intra) { |
|
#endif |
|
|
{ |
|
111 |
coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].code |
coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].code |
112 |
= (coeff_tab[intra][i].vlc.code << 1) | 1; |
= (coeff_tab[intra][i].vlc.code << 1) | 1; |
113 |
coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].len |
coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].len |
114 |
= coeff_tab[intra][i].vlc.len + 1; |
= coeff_tab[intra][i].vlc.len + 1; |
115 |
} |
} |
116 |
} |
} |
117 |
|
} |
118 |
|
|
119 |
|
for (intra = 0; intra < 2; intra++) { |
120 |
|
for (last = 0; last < 2; last++) { |
121 |
|
for (run = 0; run < 63 + last; run++) { |
122 |
|
for (level = 1; level < (uint32_t)(32 << intra); level++) { |
123 |
|
|
|
for (intra = 0; intra < 2; intra++) |
|
|
for (last = 0; last < 2; last++) |
|
|
for (run = 0; run < 63 + last; run++) |
|
|
{ |
|
|
for (level = 1; level < (uint32_t)(32 << intra); level++) |
|
|
{ |
|
124 |
if (level <= max_level[intra][last][run] && run <= max_run[intra][last][level]) |
if (level <= max_level[intra][last][run] && run <= max_run[intra][last][level]) |
125 |
continue; |
continue; |
126 |
|
|
|
#ifdef BIGLUT |
|
|
offset = LEVELOFFSET; |
|
|
#else |
|
127 |
offset = !intra * LEVELOFFSET; |
offset = !intra * LEVELOFFSET; |
|
#endif |
|
128 |
level_esc = level - max_level[intra][last][run]; |
level_esc = level - max_level[intra][last][run]; |
129 |
run_esc = run - 1 - max_run[intra][last][level]; |
run_esc = run - 1 - max_run[intra][last][level]; |
|
/*use this test to use shorter esc2 codes when possible |
|
|
if (level_esc <= max_level[intra][last][run] && run <= max_run[intra][last][level_esc] |
|
|
&& !(coeff_VLC[intra][last][level_esc + offset][run].len + 7 + 1 |
|
|
> coeff_VLC[intra][last][level + offset][run_esc].code + 7 + 2))*/ |
|
130 |
|
|
131 |
if (level_esc <= max_level[intra][last][run] && run <= max_run[intra][last][level_esc]) |
if (level_esc <= max_level[intra][last][run] && run <= max_run[intra][last][level_esc]) { |
|
{ |
|
132 |
escape = ESCAPE1; |
escape = ESCAPE1; |
133 |
escape_len = 7 + 1; |
escape_len = 7 + 1; |
134 |
run_esc = run; |
run_esc = run; |
135 |
} |
} else { |
136 |
else |
if (run_esc <= max_run[intra][last][level] && level <= max_level[intra][last][run_esc]) { |
|
{ |
|
|
if (run_esc <= max_run[intra][last][level] && level <= max_level[intra][last][run_esc]) |
|
|
{ |
|
137 |
escape = ESCAPE2; |
escape = ESCAPE2; |
138 |
escape_len = 7 + 2; |
escape_len = 7 + 2; |
139 |
level_esc = level; |
level_esc = level; |
140 |
} |
} else { |
141 |
else |
if (!intra) { |
|
{ |
|
|
#ifndef BIGLUT |
|
|
if (!intra) |
|
|
#endif |
|
|
{ |
|
142 |
coeff_VLC[intra][last][level + offset][run].code |
coeff_VLC[intra][last][level + offset][run].code |
143 |
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1; |
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1; |
144 |
coeff_VLC[intra][last][level + offset][run].len = 30; |
coeff_VLC[intra][last][level + offset][run].len = 30; |
155 |
| coeff_VLC[intra][last][level_esc + offset][run_esc].code; |
| coeff_VLC[intra][last][level_esc + offset][run_esc].code; |
156 |
coeff_VLC[intra][last][level + offset][run].len |
coeff_VLC[intra][last][level + offset][run].len |
157 |
= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len; |
= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len; |
158 |
#ifndef BIGLUT |
|
159 |
if (!intra) |
if (!intra) { |
|
#endif |
|
|
{ |
|
160 |
coeff_VLC[intra][last][offset - level][run].code |
coeff_VLC[intra][last][offset - level][run].code |
161 |
= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len) |
= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len) |
162 |
| coeff_VLC[intra][last][level_esc + offset][run_esc].code | 1; |
| coeff_VLC[intra][last][level_esc + offset][run_esc].code | 1; |
165 |
} |
} |
166 |
} |
} |
167 |
|
|
168 |
#ifdef BIGLUT |
if (!intra) { |
|
for (level = 32 << intra; level < 2048; level++) |
|
|
{ |
|
|
coeff_VLC[intra][last][level + offset][run].code |
|
|
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1; |
|
|
coeff_VLC[intra][last][level + offset][run].len = 30; |
|
|
|
|
|
coeff_VLC[intra][last][offset - level][run].code |
|
|
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-level & 0xfff) << 1) | 1; |
|
|
coeff_VLC[intra][last][offset - level][run].len = 30; |
|
|
} |
|
|
#else |
|
|
if (!intra) |
|
|
{ |
|
169 |
coeff_VLC[intra][last][0][run].code |
coeff_VLC[intra][last][0][run].code |
170 |
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-32 & 0xfff) << 1) | 1; |
= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-32 & 0xfff) << 1) | 1; |
171 |
coeff_VLC[intra][last][0][run].len = 30; |
coeff_VLC[intra][last][0][run].len = 30; |
172 |
} |
} |
|
#endif |
|
173 |
} |
} |
174 |
/* init sprite_trajectory tables */ |
} |
175 |
/* even if GMC is not specified (it might be used later...) */ |
} |
176 |
|
|
177 |
|
/* init sprite_trajectory tables |
178 |
|
* even if GMC is not specified (it might be used later...) */ |
179 |
|
|
180 |
sprite_trajectory_code[0+16384].code = 0; |
sprite_trajectory_code[0+16384].code = 0; |
181 |
sprite_trajectory_code[0+16384].len = 0; |
sprite_trajectory_code[0+16384].len = 0; |
182 |
for (k=0;k<14;k++) |
for (k=0;k<14;k++) { |
|
{ |
|
183 |
int limit = (1<<k); |
int limit = (1<<k); |
184 |
|
|
185 |
for (l=-(2*limit-1); l <= -limit; l++) |
for (l=-(2*limit-1); l <= -limit; l++) { |
|
{ |
|
186 |
sprite_trajectory_code[l+16384].code = (2*limit-1)+l; |
sprite_trajectory_code[l+16384].code = (2*limit-1)+l; |
187 |
sprite_trajectory_code[l+16384].len = k+1; |
sprite_trajectory_code[l+16384].len = k+1; |
188 |
} |
} |
189 |
|
|
190 |
for (l=limit; l<= 2*limit-1; l++) |
for (l=limit; l<= 2*limit-1; l++) { |
|
{ |
|
191 |
sprite_trajectory_code[l+16384].code = l; |
sprite_trajectory_code[l+16384].code = l; |
192 |
sprite_trajectory_code[l+16384].len = k+1; |
sprite_trajectory_code[l+16384].len = k+1; |
193 |
} |
} |
249 |
|
|
250 |
} |
} |
251 |
|
|
|
#ifdef BIGLUT |
|
|
|
|
|
static __inline void |
|
|
CodeCoeff(Bitstream * bs, |
|
|
const int16_t qcoeff[64], |
|
|
VLC * table, |
|
|
const uint16_t * zigzag, |
|
|
uint16_t intra) |
|
|
{ |
|
|
|
|
|
uint32_t j, last; |
|
|
short v; |
|
|
VLC *vlc; |
|
|
|
|
|
j = intra; |
|
|
last = intra; |
|
|
|
|
|
while (j < 64 && (v = qcoeff[zigzag[j]]) == 0) |
|
|
j++; |
|
|
|
|
|
do { |
|
|
vlc = table + 64 * 2048 + (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 * 4096; |
|
|
BitstreamPutBits(bs, vlc->code, vlc->len); |
|
|
break; |
|
|
} |
|
|
} while (1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* returns the number of bits required to encode qcoeff */ |
|
|
int |
|
|
CodeCoeff_CalcBits(const int16_t qcoeff[64], |
|
|
VLC * table, |
|
|
const uint16_t * zigzag, |
|
|
uint16_t intra) |
|
|
{ |
|
|
int bits = 0; |
|
|
uint32_t j, last; |
|
|
short v; |
|
|
VLC *vlc; |
|
|
|
|
|
j = intra; |
|
|
last = intra; |
|
|
|
|
|
while (j < 64 && (v = qcoeff[zigzag[j]]) == 0) |
|
|
j++; |
|
|
|
|
|
if (j >= 64) return 0; /* empty block */ |
|
|
|
|
|
do { |
|
|
vlc = table + 64 * 2048 + (v << 6) + j - last; |
|
|
last = ++j; |
|
|
|
|
|
/* count zeroes */ |
|
|
while (j < 64 && (v = qcoeff[zigzag[j]]) == 0) |
|
|
j++; |
|
|
|
|
|
/* write code */ |
|
|
if (j != 64) { |
|
|
bits += vlc->len; |
|
|
} else { |
|
|
vlc += 64 * 4096; |
|
|
bits += vlc->len; |
|
|
break; |
|
|
} |
|
|
} while (1); |
|
|
|
|
|
return bits; |
|
|
} |
|
|
|
|
|
|
|
|
#else |
|
|
|
|
252 |
static __inline void |
static __inline void |
253 |
CodeCoeffInter(Bitstream * bs, |
CodeCoeffInter(Bitstream * bs, |
254 |
const int16_t qcoeff[64], |
const int16_t qcoeff[64], |
453 |
return bits; |
return bits; |
454 |
} |
} |
455 |
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
456 |
static int iDQtab[5] = { |
static int iDQtab[5] = { |
457 |
1, 0, -1 /* no change */, 2, 3 |
1, 0, -1 /* no change */, 2, 3 |
458 |
}; |
}; |
515 |
|
|
516 |
bits = BitstreamPos(bs); |
bits = BitstreamPos(bs); |
517 |
|
|
|
#ifdef BIGLUT |
|
|
CodeCoeff(bs, &qcoeff[i * 64], intra_table, scan_table, 1); |
|
|
#else |
|
518 |
CodeCoeffIntra(bs, &qcoeff[i * 64], scan_table); |
CodeCoeffIntra(bs, &qcoeff[i * 64], scan_table); |
|
#endif |
|
519 |
|
|
520 |
bits = BitstreamPos(bs) - bits; |
bits = BitstreamPos(bs) - bits; |
521 |
pStat->iTextBits += bits; |
pStat->iTextBits += bits; |
561 |
} |
} |
562 |
|
|
563 |
/* if inter block, write field ME flag */ |
/* if inter block, write field ME flag */ |
564 |
if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) { |
if ((pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) && (pMB->mcsel == 0)) { |
565 |
BitstreamPutBit(bs, pMB->field_pred); |
BitstreamPutBit(bs, 0 /*pMB->field_pred*/); /* not implemented yet */ |
566 |
DPRINTF(XVID_DEBUG_MB,"codep: field_pred: %i\n", pMB->field_pred); |
DPRINTF(XVID_DEBUG_MB,"codep: field_pred: %i\n", pMB->field_pred); |
567 |
|
|
568 |
/* write field prediction references */ |
/* write field prediction references */ |
569 |
|
#if 0 /* Remove the #if once field_pred is supported */ |
570 |
if (pMB->field_pred) { |
if (pMB->field_pred) { |
571 |
BitstreamPutBit(bs, pMB->field_for_top); |
BitstreamPutBit(bs, pMB->field_for_top); |
572 |
BitstreamPutBit(bs, pMB->field_for_bot); |
BitstreamPutBit(bs, pMB->field_for_bot); |
573 |
} |
} |
574 |
|
#endif |
575 |
} |
} |
576 |
} |
} |
577 |
/* code motion vector(s) if motion is local */ |
/* code motion vector(s) if motion is local */ |
585 |
|
|
586 |
/* code block coeffs */ |
/* code block coeffs */ |
587 |
for (i = 0; i < 6; i++) |
for (i = 0; i < 6; i++) |
588 |
if (pMB->cbp & (1 << (5 - i))) |
if (pMB->cbp & (1 << (5 - i))) { |
|
{ |
|
589 |
const uint16_t *scan_table = |
const uint16_t *scan_table = |
590 |
frame->vop_flags & XVID_VOP_ALTERNATESCAN ? |
frame->vop_flags & XVID_VOP_ALTERNATESCAN ? |
591 |
scan_tables[2] : scan_tables[0]; |
scan_tables[2] : scan_tables[0]; |
592 |
|
|
|
#ifdef BIGLUT |
|
|
CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_table, 0); |
|
|
#else |
|
593 |
CodeCoeffInter(bs, &qcoeff[i * 64], scan_table); |
CodeCoeffInter(bs, &qcoeff[i * 64], scan_table); |
|
#endif |
|
594 |
} |
} |
595 |
|
|
596 |
bits = BitstreamPos(bs) - bits; |
bits = BitstreamPos(bs) - bits; |
692 |
const uint16_t *scan_table = |
const uint16_t *scan_table = |
693 |
frame->vop_flags & XVID_VOP_ALTERNATESCAN ? |
frame->vop_flags & XVID_VOP_ALTERNATESCAN ? |
694 |
scan_tables[2] : scan_tables[0]; |
scan_tables[2] : scan_tables[0]; |
695 |
|
int bits; |
696 |
|
|
697 |
|
|
698 |
/* ------------------------------------------------------------------ |
/* ------------------------------------------------------------------ |
734 |
BitstreamPutBit(bs, 0 /*mb->field_pred*/); /* field ME not implemented */ |
BitstreamPutBit(bs, 0 /*mb->field_pred*/); /* field ME not implemented */ |
735 |
|
|
736 |
/* write field prediction references */ |
/* write field prediction references */ |
737 |
/* if (mb->field_pred) { |
#if 0 /* Remove the #if once field_pred is supported */ |
738 |
|
if (mb->field_pred) { |
739 |
BitstreamPutBit(bs, mb->field_for_top); |
BitstreamPutBit(bs, mb->field_for_top); |
740 |
BitstreamPutBit(bs, mb->field_for_bot); |
BitstreamPutBit(bs, mb->field_for_bot); |
741 |
}*/ |
} |
742 |
|
#endif |
743 |
} |
} |
744 |
} |
} |
745 |
|
|
760 |
default: break; |
default: break; |
761 |
} |
} |
762 |
|
|
763 |
|
bits = BitstreamPos(bs); |
764 |
for (i = 0; i < 6; i++) { |
for (i = 0; i < 6; i++) { |
765 |
if (mb->cbp & (1 << (5 - i))) { |
if (mb->cbp & (1 << (5 - i))) { |
766 |
#ifdef BIGLUT |
CodeCoeffInter(bs, &qcoeff[i * 64], scan_table); |
|
CodeCoeff(bs, &qcoeff[i * 64], inter_table, scan_tables[0], 0); |
|
|
#else |
|
|
CodeCoeffInter(bs, &qcoeff[i * 64], scan_tables[0]); |
|
|
#endif |
|
767 |
} |
} |
768 |
} |
} |
769 |
|
pStat->iTextBits += BitstreamPos(bs) - bits; |
770 |
} |
} |
771 |
|
|
772 |
|
|