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