diff options
Diffstat (limited to 'src/plugins/ffmpeg/libavcodec/intrax8.c')
-rw-r--r-- | src/plugins/ffmpeg/libavcodec/intrax8.c | 764 |
1 files changed, 0 insertions, 764 deletions
diff --git a/src/plugins/ffmpeg/libavcodec/intrax8.c b/src/plugins/ffmpeg/libavcodec/intrax8.c deleted file mode 100644 index 0436deb..0000000 --- a/src/plugins/ffmpeg/libavcodec/intrax8.c +++ /dev/null | |||
@@ -1,764 +0,0 @@ | |||
1 | /* | ||
2 | * This file is part of FFmpeg. | ||
3 | * | ||
4 | * FFmpeg is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * FFmpeg is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with FFmpeg; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @file intrax8.c | ||
21 | * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1 | ||
22 | */ | ||
23 | |||
24 | #include "avcodec.h" | ||
25 | #include "bitstream.h" | ||
26 | #include "mpegvideo.h" | ||
27 | #include "msmpeg4data.h" | ||
28 | #include "intrax8huf.h" | ||
29 | #include "intrax8.h" | ||
30 | |||
31 | #define MAX_TABLE_DEPTH(table_bits, max_bits) ((max_bits+table_bits-1)/table_bits) | ||
32 | |||
33 | #define DC_VLC_BITS 9 | ||
34 | #define AC_VLC_BITS 9 | ||
35 | #define OR_VLC_BITS 7 | ||
36 | |||
37 | #define DC_VLC_MTD MAX_TABLE_DEPTH(DC_VLC_BITS, MAX_DC_VLC_BITS) | ||
38 | #define AC_VLC_MTD MAX_TABLE_DEPTH(AC_VLC_BITS, MAX_AC_VLC_BITS) | ||
39 | #define OR_VLC_MTD MAX_TABLE_DEPTH(OR_VLC_BITS, MAX_OR_VLC_BITS) | ||
40 | |||
41 | static VLC j_ac_vlc[2][2][8]; //[quant<13],[intra/inter],[select] | ||
42 | static VLC j_dc_vlc[2][8]; //[quant], [select] | ||
43 | static VLC j_orient_vlc[2][4]; //[quant], [select] | ||
44 | |||
45 | static void x8_vlc_init(){ | ||
46 | int i; | ||
47 | |||
48 | #define init_ac_vlc(dst,src) \ | ||
49 | init_vlc(&dst, \ | ||
50 | AC_VLC_BITS,77, \ | ||
51 | &src[1],4,2, \ | ||
52 | &src[0],4,2, \ | ||
53 | 1) | ||
54 | //set ac tables | ||
55 | for(i=0;i<8;i++){ | ||
56 | init_ac_vlc( j_ac_vlc[0][0][i], x8_ac0_highquant_table[i][0] ); | ||
57 | init_ac_vlc( j_ac_vlc[0][1][i], x8_ac1_highquant_table[i][0] ); | ||
58 | init_ac_vlc( j_ac_vlc[1][0][i], x8_ac0_lowquant_table [i][0] ); | ||
59 | init_ac_vlc( j_ac_vlc[1][1][i], x8_ac1_lowquant_table [i][0] ); | ||
60 | } | ||
61 | #undef init_ac_vlc | ||
62 | |||
63 | //set dc tables | ||
64 | #define init_dc_vlc(dst,src) \ | ||
65 | init_vlc(&dst, \ | ||
66 | DC_VLC_BITS,34, \ | ||
67 | &src[1],4,2, \ | ||
68 | &src[0],4,2, \ | ||
69 | 1); | ||
70 | for(i=0;i<8;i++){ | ||
71 | init_dc_vlc( j_dc_vlc[0][i], x8_dc_highquant_table[i][0]); | ||
72 | init_dc_vlc( j_dc_vlc[1][i], x8_dc_lowquant_table [i][0]); | ||
73 | } | ||
74 | #undef init_dc_vlc | ||
75 | |||
76 | //set orient tables | ||
77 | #define init_or_vlc(dst,src) \ | ||
78 | init_vlc(&dst, \ | ||
79 | OR_VLC_BITS,12, \ | ||
80 | &src[1],4,2, \ | ||
81 | &src[0],4,2, \ | ||
82 | 1); | ||
83 | for(i=0;i<2;i++){ | ||
84 | init_or_vlc( j_orient_vlc[0][i], x8_orient_highquant_table[i][0]); | ||
85 | } | ||
86 | for(i=0;i<4;i++){ | ||
87 | init_or_vlc( j_orient_vlc[1][i], x8_orient_lowquant_table [i][0]) | ||
88 | } | ||
89 | } | ||
90 | #undef init_or_vlc | ||
91 | |||
92 | static void x8_reset_vlc_tables(IntraX8Context * w){ | ||
93 | memset(w->j_dc_vlc,0,sizeof(w->j_dc_vlc)); | ||
94 | memset(w->j_ac_vlc,0,sizeof(w->j_ac_vlc)); | ||
95 | w->j_orient_vlc=NULL; | ||
96 | } | ||
97 | |||
98 | static inline void x8_select_ac_table(IntraX8Context * const w , int mode){ | ||
99 | MpegEncContext * const s= w->s; | ||
100 | int table_index; | ||
101 | |||
102 | assert(mode<4); | ||
103 | |||
104 | if( w->j_ac_vlc[mode] ) return; | ||
105 | |||
106 | table_index = get_bits(&s->gb, 3); | ||
107 | w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables | ||
108 | assert(w->j_ac_vlc[mode]); | ||
109 | } | ||
110 | |||
111 | static inline int x8_get_orient_vlc(IntraX8Context * w){ | ||
112 | MpegEncContext * const s= w->s; | ||
113 | int table_index; | ||
114 | |||
115 | if(!w->j_orient_vlc ){ | ||
116 | table_index = get_bits(&s->gb, 1+(w->quant<13) ); | ||
117 | w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index]; | ||
118 | } | ||
119 | assert(w->j_orient_vlc); | ||
120 | assert(w->j_orient_vlc->table); | ||
121 | |||
122 | return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD); | ||
123 | } | ||
124 | |||
125 | #define extra_bits(eb) (eb) | ||
126 | #define extra_run (0xFF<<8) | ||
127 | #define extra_level (0x00<<8) | ||
128 | #define run_offset(r) ((r)<<16) | ||
129 | #define level_offset(l) ((l)<<24) | ||
130 | static const uint32_t ac_decode_table[]={ | ||
131 | /*46*/ extra_bits(3) | extra_run | run_offset(16) | level_offset( 0), | ||
132 | /*47*/ extra_bits(3) | extra_run | run_offset(24) | level_offset( 0), | ||
133 | /*48*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), | ||
134 | /*49*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), | ||
135 | |||
136 | /*50*/ extra_bits(5) | extra_run | run_offset(32) | level_offset( 0), | ||
137 | /*51*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), | ||
138 | |||
139 | /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), | ||
140 | /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8), | ||
141 | /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12), | ||
142 | /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16), | ||
143 | /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24), | ||
144 | |||
145 | /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), | ||
146 | /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), | ||
147 | |||
148 | /*59*/ extra_bits(2) | extra_run | run_offset(16) | level_offset( 0), | ||
149 | /*60*/ extra_bits(2) | extra_run | run_offset(20) | level_offset( 0), | ||
150 | /*61*/ extra_bits(2) | extra_run | run_offset(24) | level_offset( 0), | ||
151 | /*62*/ extra_bits(2) | extra_run | run_offset(28) | level_offset( 0), | ||
152 | /*63*/ extra_bits(4) | extra_run | run_offset(32) | level_offset( 0), | ||
153 | /*64*/ extra_bits(4) | extra_run | run_offset(48) | level_offset( 0), | ||
154 | |||
155 | /*65*/ extra_bits(2) | extra_run | run_offset( 4) | level_offset( 1), | ||
156 | /*66*/ extra_bits(3) | extra_run | run_offset( 8) | level_offset( 1), | ||
157 | /*67*/ extra_bits(4) | extra_run | run_offset(16) | level_offset( 1), | ||
158 | |||
159 | /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4), | ||
160 | /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8), | ||
161 | /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16), | ||
162 | |||
163 | /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3), | ||
164 | /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7), | ||
165 | }; | ||
166 | //extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits; | ||
167 | #undef extra_bits | ||
168 | #undef extra_run | ||
169 | #undef extra_level | ||
170 | #undef run_offset | ||
171 | #undef level_offset | ||
172 | |||
173 | static void x8_get_ac_rlf(IntraX8Context * const w, const int mode, | ||
174 | int * const run, int * const level, int * const final){ | ||
175 | MpegEncContext * const s= w->s; | ||
176 | int i,e; | ||
177 | |||
178 | // x8_select_ac_table(w,mode); | ||
179 | i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD); | ||
180 | |||
181 | if(i<46){ //[0-45] | ||
182 | int t,l; | ||
183 | if(i<0){ | ||
184 | (*level)=(*final)=//prevent 'may be used unilitialized' | ||
185 | (*run)=64;//this would cause error exit in the ac loop | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | (*final) = t = (i>22); | ||
190 | i-=23*t; | ||
191 | /* | ||
192 | i== 0-15 r=0-15 l=0 ;r=i& %01111 | ||
193 | i==16-19 r=0-3 l=1 ;r=i& %00011 | ||
194 | i==20-21 r=0-1 l=2 ;r=i& %00001 | ||
195 | i==22 r=0 l=3 ;r=i& %00000 | ||
196 | l=lut_l[i/2]={0,0,0,0,0,0,0,0,1,1,2,3}[i>>1];// 11 10'01 01'00 00'00 00'00 00'00 00 => 0xE50000 | ||
197 | t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */ | ||
198 | l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/ | ||
199 | t=(0x01030F>>(l<<3)); | ||
200 | |||
201 | (*run) = i&t; | ||
202 | (*level) = l; | ||
203 | }else if(i<73){//[46-72] | ||
204 | uint32_t sm; | ||
205 | uint32_t mask; | ||
206 | |||
207 | i-=46; | ||
208 | sm=ac_decode_table[i]; | ||
209 | |||
210 | e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits | ||
211 | mask=sm&0xff;sm>>=8; //1bit | ||
212 | |||
213 | (*run) =(sm&0xff) + (e&( mask));//6bits | ||
214 | (*level)=(sm>>8) + (e&(~mask));//5bits | ||
215 | (*final)=i>(58-46); | ||
216 | }else if(i<75){//[73-74] | ||
217 | static const uint8_t crazy_mix_runlevel[32]={ | ||
218 | 0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63, | ||
219 | 0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83, | ||
220 | 0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64, | ||
221 | 0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84}; | ||
222 | |||
223 | (*final)=!(i&1); | ||
224 | e=get_bits(&s->gb,5);//get the extra bits | ||
225 | (*run) =crazy_mix_runlevel[e]>>4; | ||
226 | (*level)=crazy_mix_runlevel[e]&0x0F; | ||
227 | }else{ | ||
228 | (*level)=get_bits( &s->gb, 7-3*(i&1)); | ||
229 | (*run) =get_bits( &s->gb, 6); | ||
230 | (*final)=get_bits1(&s->gb); | ||
231 | } | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | //static const uint8_t dc_extra_sbits[] ={0, 1,1, 1,1, 2,2, 3,3, 4,4, 5,5, 6,6, 7,7 }; | ||
236 | static const uint8_t dc_index_offset[] ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193}; | ||
237 | |||
238 | static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){ | ||
239 | MpegEncContext * const s= w->s; | ||
240 | int i,e,c; | ||
241 | |||
242 | assert(mode<3); | ||
243 | if( !w->j_dc_vlc[mode] ) { | ||
244 | int table_index; | ||
245 | table_index = get_bits(&s->gb, 3); | ||
246 | //4 modes, same table | ||
247 | w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index]; | ||
248 | } | ||
249 | assert(w->j_dc_vlc); | ||
250 | assert(w->j_dc_vlc[mode]->table); | ||
251 | |||
252 | i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD); | ||
253 | |||
254 | /*(i>=17) {i-=17;final=1;}*/ | ||
255 | c= i>16; | ||
256 | (*final)=c; | ||
257 | i-=17*c; | ||
258 | |||
259 | if(i<=0){ | ||
260 | (*level)=0; | ||
261 | return -i; | ||
262 | } | ||
263 | c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[] | ||
264 | c-=c>1; | ||
265 | |||
266 | e=get_bits(&s->gb,c);//get the extra bits | ||
267 | i=dc_index_offset[i]+(e>>1); | ||
268 | |||
269 | e= -(e & 1);//0,0xffffff | ||
270 | (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1) | ||
271 | return 0; | ||
272 | } | ||
273 | //end of huffman | ||
274 | |||
275 | static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){ | ||
276 | MpegEncContext * const s= w->s; | ||
277 | int range; | ||
278 | int sum; | ||
279 | int quant; | ||
280 | |||
281 | s->dsp.x8_setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer, | ||
282 | s->current_picture.linesize[chroma>0], | ||
283 | &range, &sum, w->edges); | ||
284 | if(chroma){ | ||
285 | w->orient=w->chroma_orient; | ||
286 | quant=w->quant_dc_chroma; | ||
287 | }else{ | ||
288 | quant=w->quant; | ||
289 | } | ||
290 | |||
291 | w->flat_dc=0; | ||
292 | if(range < quant || range < 3){ | ||
293 | w->orient=0; | ||
294 | if(range < 3){//yep you read right, a +-1 idct error may break decoding! | ||
295 | w->flat_dc=1; | ||
296 | sum+=9; | ||
297 | w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899 | ||
298 | } | ||
299 | } | ||
300 | if(chroma) | ||
301 | return 0; | ||
302 | |||
303 | assert(w->orient < 3); | ||
304 | if(range < 2*w->quant){ | ||
305 | if( (w->edges&3) == 0){ | ||
306 | if(w->orient==1) w->orient=11; | ||
307 | if(w->orient==2) w->orient=10; | ||
308 | }else{ | ||
309 | w->orient=0; | ||
310 | } | ||
311 | w->raw_orient=0; | ||
312 | }else{ | ||
313 | static const uint8_t prediction_table[3][12]={ | ||
314 | {0,8,4, 10,11, 2,6,9,1,3,5,7}, | ||
315 | {4,0,8, 11,10, 3,5,2,6,9,1,7}, | ||
316 | {8,0,4, 10,11, 1,7,2,6,9,3,5} | ||
317 | }; | ||
318 | w->raw_orient=x8_get_orient_vlc(w); | ||
319 | if(w->raw_orient<0) return -1; | ||
320 | assert(w->raw_orient < 12 ); | ||
321 | assert(w->orient<3); | ||
322 | w->orient=prediction_table[w->orient][w->raw_orient]; | ||
323 | } | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){ | ||
328 | MpegEncContext * const s= w->s; | ||
329 | |||
330 | w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8); | ||
331 | /* | ||
332 | y=2n+0 ->//0 2 4 | ||
333 | y=2n+1 ->//1 3 5 | ||
334 | */ | ||
335 | } | ||
336 | static void x8_get_prediction_chroma(IntraX8Context * const w){ | ||
337 | MpegEncContext * const s= w->s; | ||
338 | |||
339 | w->edges = 1*( !(s->mb_x>>1) ); | ||
340 | w->edges|= 2*( !(s->mb_y>>1) ); | ||
341 | w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd | ||
342 | |||
343 | w->raw_orient=0; | ||
344 | if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC | ||
345 | w->chroma_orient=4<<((0xCC>>w->edges)&1); | ||
346 | return; | ||
347 | } | ||
348 | w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)] | ||
349 | } | ||
350 | |||
351 | static void x8_get_prediction(IntraX8Context * const w){ | ||
352 | MpegEncContext * const s= w->s; | ||
353 | int a,b,c,i; | ||
354 | |||
355 | w->edges = 1*( !s->mb_x ); | ||
356 | w->edges|= 2*( !s->mb_y ); | ||
357 | w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) ); | ||
358 | |||
359 | switch(w->edges&3){ | ||
360 | case 0: | ||
361 | break; | ||
362 | case 1: | ||
363 | //take the one from the above block[0][y-1] | ||
364 | w->est_run = w->prediction_table[!(s->mb_y&1)]>>2; | ||
365 | w->orient = 1; | ||
366 | return; | ||
367 | case 2: | ||
368 | //take the one from the previous block[x-1][0] | ||
369 | w->est_run = w->prediction_table[2*s->mb_x-2]>>2; | ||
370 | w->orient = 2; | ||
371 | return; | ||
372 | case 3: | ||
373 | w->est_run = 16; | ||
374 | w->orient = 0; | ||
375 | return; | ||
376 | } | ||
377 | //no edge cases | ||
378 | b= w->prediction_table[2*s->mb_x + !(s->mb_y&1) ];//block[x ][y-1] | ||
379 | a= w->prediction_table[2*s->mb_x-2 + (s->mb_y&1) ];//block[x-1][y ] | ||
380 | c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1] | ||
381 | |||
382 | w->est_run = FFMIN(b,a); | ||
383 | /* This condition has nothing to do with w->edges, even if it looks | ||
384 | similar it would trigger if e.g. x=3;y=2; | ||
385 | I guess somebody wrote something wrong and it became standard. */ | ||
386 | if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run); | ||
387 | w->est_run>>=2; | ||
388 | |||
389 | a&=3; | ||
390 | b&=3; | ||
391 | c&=3; | ||
392 | |||
393 | i=( 0xFFEAF4C4>>(2*b+8*a) )&3; | ||
394 | if(i!=3) w->orient=i; | ||
395 | else w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3; | ||
396 | /* | ||
397 | lut1[b][a]={ | ||
398 | ->{0, 1, 0, pad}, | ||
399 | {0, 1, X, pad}, | ||
400 | {2, 2, 2, pad}} | ||
401 | pad 2 2 2; pad X 1 0; pad 0 1 0 <- | ||
402 | -> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4 | ||
403 | |||
404 | lut2[q>12][c]={ | ||
405 | ->{0,2,1,pad}, | ||
406 | {2,2,2,pad}} | ||
407 | pad 2 2 2; pad 1 2 0 <- | ||
408 | -> 11 10'10 10 '11 01'10 00=>0xEAD8 | ||
409 | */ | ||
410 | } | ||
411 | |||
412 | |||
413 | static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){ | ||
414 | MpegEncContext * const s= w->s; | ||
415 | int t; | ||
416 | #define B(x,y) s->block[0][s->dsp.idct_permutation[(x)+(y)*8]] | ||
417 | #define T(x) ((x) * dc_level + 0x8000) >> 16; | ||
418 | switch(direction){ | ||
419 | case 0: | ||
420 | t = T(3811);//h | ||
421 | B(1,0) -= t; | ||
422 | B(0,1) -= t; | ||
423 | |||
424 | t = T(487);//e | ||
425 | B(2,0) -= t; | ||
426 | B(0,2) -= t; | ||
427 | |||
428 | t = T(506);//f | ||
429 | B(3,0) -= t; | ||
430 | B(0,3) -= t; | ||
431 | |||
432 | t = T(135);//c | ||
433 | B(4,0) -= t; | ||
434 | B(0,4) -= t; | ||
435 | B(2,1) += t; | ||
436 | B(1,2) += t; | ||
437 | B(3,1) += t; | ||
438 | B(1,3) += t; | ||
439 | |||
440 | t = T(173);//d | ||
441 | B(5,0) -= t; | ||
442 | B(0,5) -= t; | ||
443 | |||
444 | t = T(61);//b | ||
445 | B(6,0) -= t; | ||
446 | B(0,6) -= t; | ||
447 | B(5,1) += t; | ||
448 | B(1,5) += t; | ||
449 | |||
450 | t = T(42); //a | ||
451 | B(7,0) -= t; | ||
452 | B(0,7) -= t; | ||
453 | B(4,1) += t; | ||
454 | B(1,4) += t; | ||
455 | B(4,4) += t; | ||
456 | |||
457 | t = T(1084);//g | ||
458 | B(1,1) += t; | ||
459 | |||
460 | s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); | ||
461 | break; | ||
462 | case 1: | ||
463 | B(0,1) -= T(6269); | ||
464 | B(0,3) -= T( 708); | ||
465 | B(0,5) -= T( 172); | ||
466 | B(0,7) -= T( 73); | ||
467 | |||
468 | s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8); | ||
469 | break; | ||
470 | case 2: | ||
471 | B(1,0) -= T(6269); | ||
472 | B(3,0) -= T( 708); | ||
473 | B(5,0) -= T( 172); | ||
474 | B(7,0) -= T( 73); | ||
475 | |||
476 | s->block_last_index[0] = FFMAX(s->block_last_index[0], 7); | ||
477 | break; | ||
478 | } | ||
479 | #undef B | ||
480 | #undef T | ||
481 | } | ||
482 | |||
483 | static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){ | ||
484 | int k; | ||
485 | for(k=0;k<8;k++){ | ||
486 | memset(dst,pix,8); | ||
487 | dst+=linesize; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | static const int16_t quant_table[64] = { | ||
492 | 256, 256, 256, 256, 256, 256, 259, 262, | ||
493 | 265, 269, 272, 275, 278, 282, 285, 288, | ||
494 | 292, 295, 299, 303, 306, 310, 314, 317, | ||
495 | 321, 325, 329, 333, 337, 341, 345, 349, | ||
496 | 353, 358, 362, 366, 371, 375, 379, 384, | ||
497 | 389, 393, 398, 403, 408, 413, 417, 422, | ||
498 | 428, 433, 438, 443, 448, 454, 459, 465, | ||
499 | 470, 476, 482, 488, 493, 499, 505, 511 | ||
500 | }; | ||
501 | |||
502 | static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){ | ||
503 | MpegEncContext * const s= w->s; | ||
504 | |||
505 | uint8_t * scantable; | ||
506 | int final,run,level; | ||
507 | int ac_mode,dc_mode,est_run,dc_level; | ||
508 | int pos,n; | ||
509 | int zeros_only; | ||
510 | int use_quant_matrix; | ||
511 | int sign; | ||
512 | |||
513 | assert(w->orient<12); | ||
514 | memset(s->block[0],0x00,64*sizeof(DCTELEM)); | ||
515 | |||
516 | if(chroma){ | ||
517 | dc_mode=2; | ||
518 | }else{ | ||
519 | dc_mode=!!w->est_run;//0,1 | ||
520 | } | ||
521 | |||
522 | if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1; | ||
523 | n=0; | ||
524 | zeros_only=0; | ||
525 | if(!final){//decode ac | ||
526 | use_quant_matrix=w->use_quant_matrix; | ||
527 | if(chroma){ | ||
528 | ac_mode = 1; | ||
529 | est_run = 64;//not used | ||
530 | }else{ | ||
531 | if (w->raw_orient < 3){ | ||
532 | use_quant_matrix = 0; | ||
533 | } | ||
534 | if(w->raw_orient > 4){ | ||
535 | ac_mode = 0; | ||
536 | est_run = 64; | ||
537 | }else{ | ||
538 | if(w->est_run > 1){ | ||
539 | ac_mode = 2; | ||
540 | est_run=w->est_run; | ||
541 | }else{ | ||
542 | ac_mode = 3; | ||
543 | est_run = 64; | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | x8_select_ac_table(w,ac_mode); | ||
548 | /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<- | ||
549 | -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */ | ||
550 | scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated; | ||
551 | pos=0; | ||
552 | do { | ||
553 | n++; | ||
554 | if( n >= est_run ){ | ||
555 | ac_mode=3; | ||
556 | x8_select_ac_table(w,3); | ||
557 | } | ||
558 | |||
559 | x8_get_ac_rlf(w,ac_mode,&run,&level,&final); | ||
560 | |||
561 | pos+=run+1; | ||
562 | if(pos>63){ | ||
563 | //this also handles vlc error in x8_get_ac_rlf | ||
564 | return -1; | ||
565 | } | ||
566 | level= (level+1) * w->dquant; | ||
567 | level+= w->qsum; | ||
568 | |||
569 | sign = - get_bits1(&s->gb); | ||
570 | level = (level ^ sign) - sign; | ||
571 | |||
572 | if(use_quant_matrix){ | ||
573 | level = (level*quant_table[pos])>>8; | ||
574 | } | ||
575 | s->block[0][ scantable[pos] ]=level; | ||
576 | }while(!final); | ||
577 | |||
578 | s->block_last_index[0]=pos; | ||
579 | }else{//DC only | ||
580 | s->block_last_index[0]=0; | ||
581 | if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1] | ||
582 | int32_t divide_quant= !chroma ? w->divide_quant_dc_luma: | ||
583 | w->divide_quant_dc_chroma; | ||
584 | int32_t dc_quant = !chroma ? w->quant: | ||
585 | w->quant_dc_chroma; | ||
586 | |||
587 | //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding | ||
588 | dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13; | ||
589 | |||
590 | dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3), | ||
591 | s->dest[chroma], s->current_picture.linesize[!!chroma]); | ||
592 | |||
593 | goto block_placed; | ||
594 | } | ||
595 | zeros_only = (dc_level == 0); | ||
596 | } | ||
597 | if(!chroma){ | ||
598 | s->block[0][0] = dc_level*w->quant; | ||
599 | }else{ | ||
600 | s->block[0][0] = dc_level*w->quant_dc_chroma; | ||
601 | } | ||
602 | |||
603 | //there is !zero_only check in the original, but dc_level check is enough | ||
604 | if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){ | ||
605 | int direction; | ||
606 | /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<- | ||
607 | -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */ | ||
608 | direction= (0x6A017C>>(w->orient*2))&3; | ||
609 | if (direction != 3){ | ||
610 | x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[] | ||
611 | } | ||
612 | } | ||
613 | |||
614 | if(w->flat_dc){ | ||
615 | dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.linesize[!!chroma]); | ||
616 | }else{ | ||
617 | s->dsp.x8_spatial_compensation[w->orient]( s->edge_emu_buffer, | ||
618 | s->dest[chroma], | ||
619 | s->current_picture.linesize[!!chroma] ); | ||
620 | } | ||
621 | if(!zeros_only) | ||
622 | s->dsp.idct_add ( s->dest[chroma], | ||
623 | s->current_picture.linesize[!!chroma], | ||
624 | s->block[0] ); | ||
625 | |||
626 | block_placed: | ||
627 | |||
628 | if(!chroma){ | ||
629 | x8_update_predictions(w,w->orient,n); | ||
630 | } | ||
631 | |||
632 | if(s->loop_filter){ | ||
633 | uint8_t* ptr = s->dest[chroma]; | ||
634 | int linesize = s->current_picture.linesize[!!chroma]; | ||
635 | |||
636 | if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){ | ||
637 | s->dsp.x8_h_loop_filter(ptr, linesize, w->quant); | ||
638 | } | ||
639 | if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){ | ||
640 | s->dsp.x8_v_loop_filter(ptr, linesize, w->quant); | ||
641 | } | ||
642 | } | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_* | ||
647 | //not s->linesize as this would be wrong for field pics | ||
648 | //not that IntraX8 has interlacing support ;) | ||
649 | const int linesize = s->current_picture.linesize[0]; | ||
650 | const int uvlinesize= s->current_picture.linesize[1]; | ||
651 | |||
652 | s->dest[0] = s->current_picture.data[0]; | ||
653 | s->dest[1] = s->current_picture.data[1]; | ||
654 | s->dest[2] = s->current_picture.data[2]; | ||
655 | |||
656 | s->dest[0] += s->mb_y * linesize << 3; | ||
657 | s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows | ||
658 | s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2; | ||
659 | } | ||
660 | |||
661 | /** | ||
662 | * Initialize IntraX8 frame decoder. | ||
663 | * Requires valid MpegEncContext with valid s->mb_width before calling. | ||
664 | * @param w pointer to IntraX8Context | ||
665 | * @param s pointer to MpegEncContext of the parent codec | ||
666 | */ | ||
667 | void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){ | ||
668 | |||
669 | w->s=s; | ||
670 | x8_vlc_init(); | ||
671 | assert(s->mb_width>0); | ||
672 | w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb | ||
673 | |||
674 | ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], wmv1_scantable[0]); | ||
675 | ff_init_scantable(s->dsp.idct_permutation, &w->scantable[1], wmv1_scantable[2]); | ||
676 | ff_init_scantable(s->dsp.idct_permutation, &w->scantable[2], wmv1_scantable[3]); | ||
677 | } | ||
678 | |||
679 | /** | ||
680 | * Destroy IntraX8 frame structure. | ||
681 | * @param w pointer to IntraX8Context | ||
682 | */ | ||
683 | void ff_intrax8_common_end(IntraX8Context * w) | ||
684 | { | ||
685 | av_freep(&w->prediction_table); | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * Decode single IntraX8 frame. | ||
690 | * The parent codec must fill s->loopfilter and s->gb (bitstream). | ||
691 | * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function. | ||
692 | * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function. | ||
693 | * This function does not use MPV_decode_mb(). | ||
694 | * lowres decoding is theoretically impossible. | ||
695 | * @param w pointer to IntraX8Context | ||
696 | * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1. | ||
697 | * @param quant_offset offset away from zero | ||
698 | */ | ||
699 | //FIXME extern uint8_t wmv3_dc_scale_table[32]; | ||
700 | int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){ | ||
701 | MpegEncContext * const s= w->s; | ||
702 | int mb_xy; | ||
703 | assert(s); | ||
704 | w->use_quant_matrix = get_bits1(&s->gb); | ||
705 | |||
706 | w->dquant = dquant; | ||
707 | w->quant = dquant >> 1; | ||
708 | w->qsum = quant_offset; | ||
709 | |||
710 | w->divide_quant_dc_luma = ((1<<16) + (w->quant>>1)) / w->quant; | ||
711 | if(w->quant < 5){ | ||
712 | w->quant_dc_chroma = w->quant; | ||
713 | w->divide_quant_dc_chroma = w->divide_quant_dc_luma; | ||
714 | }else{ | ||
715 | w->quant_dc_chroma = w->quant+((w->quant+3)>>3); | ||
716 | w->divide_quant_dc_chroma = ((1<<16) + (w->quant_dc_chroma>>1)) / w->quant_dc_chroma; | ||
717 | } | ||
718 | x8_reset_vlc_tables(w); | ||
719 | |||
720 | s->resync_mb_x=0; | ||
721 | s->resync_mb_y=0; | ||
722 | |||
723 | for(s->mb_y=0; s->mb_y < s->mb_height*2; s->mb_y++){ | ||
724 | x8_init_block_index(s); | ||
725 | mb_xy=(s->mb_y>>1)*s->mb_stride; | ||
726 | |||
727 | for(s->mb_x=0; s->mb_x < s->mb_width*2; s->mb_x++){ | ||
728 | x8_get_prediction(w); | ||
729 | if(x8_setup_spatial_predictor(w,0)) goto error; | ||
730 | if(x8_decode_intra_mb(w,0)) goto error; | ||
731 | |||
732 | if( s->mb_x & s->mb_y & 1 ){ | ||
733 | x8_get_prediction_chroma(w); | ||
734 | |||
735 | /*when setting up chroma, no vlc is read, | ||
736 | so no error condition can be reached*/ | ||
737 | x8_setup_spatial_predictor(w,1); | ||
738 | if(x8_decode_intra_mb(w,1)) goto error; | ||
739 | |||
740 | x8_setup_spatial_predictor(w,2); | ||
741 | if(x8_decode_intra_mb(w,2)) goto error; | ||
742 | |||
743 | s->dest[1]+= 8; | ||
744 | s->dest[2]+= 8; | ||
745 | |||
746 | /*emulate MB info in the relevant tables*/ | ||
747 | s->mbskip_table [mb_xy]=0; | ||
748 | s->mbintra_table[mb_xy]=1; | ||
749 | s->current_picture.qscale_table[mb_xy]=w->quant; | ||
750 | mb_xy++; | ||
751 | } | ||
752 | s->dest[0]+= 8; | ||
753 | } | ||
754 | if(s->mb_y&1){ | ||
755 | ff_draw_horiz_band(s, (s->mb_y-1)*8, 16); | ||
756 | } | ||
757 | } | ||
758 | |||
759 | error: | ||
760 | ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, | ||
761 | (s->mb_x>>1)-1, (s->mb_y>>1)-1, | ||
762 | (AC_END|DC_END|MV_END) ); | ||
763 | return 0; | ||
764 | } | ||