Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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
21
 * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1
22
 */
23
 
24
#include "libavutil/avassert.h"
25
#include "avcodec.h"
26
#include "error_resilience.h"
27
#include "get_bits.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
    av_assert2(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
    av_assert2(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
 
148
    return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
149
}
150
 
151
#define extra_bits(eb) (eb)
152
#define extra_run   (0xFF<<8)
153
#define extra_level (0x00<<8)
154
#define   run_offset(r)    ((r)<<16)
155
#define level_offset(l)    ((l)<<24)
156
static const uint32_t ac_decode_table[]={
157
    /*46*/ extra_bits(3) |  extra_run  | run_offset(16) | level_offset( 0),
158
    /*47*/ extra_bits(3) |  extra_run  | run_offset(24) | level_offset( 0),
159
    /*48*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
160
    /*49*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
161
 
162
    /*50*/ extra_bits(5) |  extra_run  | run_offset(32) | level_offset( 0),
163
    /*51*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
164
 
165
    /*52*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
166
    /*53*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 8),
167
    /*54*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset(12),
168
    /*55*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(16),
169
    /*56*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset(24),
170
 
171
    /*57*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
172
    /*58*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
173
 
174
    /*59*/ extra_bits(2) |  extra_run  | run_offset(16) | level_offset( 0),
175
    /*60*/ extra_bits(2) |  extra_run  | run_offset(20) | level_offset( 0),
176
    /*61*/ extra_bits(2) |  extra_run  | run_offset(24) | level_offset( 0),
177
    /*62*/ extra_bits(2) |  extra_run  | run_offset(28) | level_offset( 0),
178
    /*63*/ extra_bits(4) |  extra_run  | run_offset(32) | level_offset( 0),
179
    /*64*/ extra_bits(4) |  extra_run  | run_offset(48) | level_offset( 0),
180
 
181
    /*65*/ extra_bits(2) |  extra_run  | run_offset( 4) | level_offset( 1),
182
    /*66*/ extra_bits(3) |  extra_run  | run_offset( 8) | level_offset( 1),
183
    /*67*/ extra_bits(4) |  extra_run  | run_offset(16) | level_offset( 1),
184
 
185
    /*68*/ extra_bits(2) | extra_level | run_offset( 0) | level_offset( 4),
186
    /*69*/ extra_bits(3) | extra_level | run_offset( 0) | level_offset( 8),
187
    /*70*/ extra_bits(4) | extra_level | run_offset( 0) | level_offset(16),
188
 
189
    /*71*/ extra_bits(2) | extra_level | run_offset( 1) | level_offset( 3),
190
    /*72*/ extra_bits(3) | extra_level | run_offset( 1) | level_offset( 7),
191
};
192
//extra_bits = 3bits; extra_run/level = 1 bit; run_offset = 6bits; level_offset = 5 bits;
193
#undef extra_bits
194
#undef extra_run
195
#undef extra_level
196
#undef run_offset
197
#undef level_offset
198
 
199
static void x8_get_ac_rlf(IntraX8Context * const w, const int mode,
200
                     int * const run, int * const level, int * const final){
201
    MpegEncContext *  const s= w->s;
202
    int i,e;
203
 
204
//    x8_select_ac_table(w,mode);
205
    i = get_vlc2(&s->gb, w->j_ac_vlc[mode]->table, AC_VLC_BITS, AC_VLC_MTD);
206
 
207
    if(i<46){ //[0-45]
208
        int t,l;
209
        if(i<0){
210
            (*level)=(*final)=//prevent 'may be used unilitialized'
211
            (*run)=64;//this would cause error exit in the ac loop
212
            return;
213
        }
214
 
215
        (*final) = t = (i>22);
216
        i-=23*t;
217
/*
218
  i== 0-15 r=0-15 l=0 ;r=i& %01111
219
  i==16-19 r=0-3  l=1 ;r=i& %00011
220
  i==20-21 r=0-1  l=2 ;r=i& %00001
221
  i==22    r=0    l=3 ;r=i& %00000
222
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
223
t=lut_mask[l]={0x0f,0x03,0x01,0x00}[l]; as i<256 the higher bits do not matter */
224
        l=(0xE50000>>(i&(0x1E)))&3;/*0x1E or (~1) or ((i>>1)<<1)*/
225
        t=(0x01030F>>(l<<3));
226
 
227
        (*run)   = i&t;
228
        (*level) = l;
229
    }else if(i<73){//[46-72]
230
        uint32_t sm;
231
        uint32_t mask;
232
 
233
        i-=46;
234
        sm=ac_decode_table[i];
235
 
236
        e=get_bits(&s->gb,sm&0xF);sm>>=8;//3bits
237
        mask=sm&0xff;sm>>=8;             //1bit
238
 
239
        (*run)  =(sm&0xff) + (e&( mask));//6bits
240
        (*level)=(sm>>8)   + (e&(~mask));//5bits
241
        (*final)=i>(58-46);
242
    }else if(i<75){//[73-74]
243
        static const uint8_t crazy_mix_runlevel[32]={
244
        0x22,0x32,0x33,0x53,0x23,0x42,0x43,0x63,
245
        0x24,0x52,0x34,0x73,0x25,0x62,0x44,0x83,
246
        0x26,0x72,0x35,0x54,0x27,0x82,0x45,0x64,
247
        0x28,0x92,0x36,0x74,0x29,0xa2,0x46,0x84};
248
 
249
        (*final)=!(i&1);
250
        e=get_bits(&s->gb,5);//get the extra bits
251
        (*run)  =crazy_mix_runlevel[e]>>4;
252
        (*level)=crazy_mix_runlevel[e]&0x0F;
253
    }else{
254
        (*level)=get_bits( &s->gb, 7-3*(i&1));
255
        (*run)  =get_bits( &s->gb, 6);
256
        (*final)=get_bits1(&s->gb);
257
    }
258
    return;
259
}
260
 
261
//static const uint8_t dc_extra_sbits[]   ={0, 1,1, 1,1, 2,2, 3,3,   4,4,   5,5,   6,6,    7,7    };
262
static const uint8_t dc_index_offset[]  ={ 0, 1,2, 3,4, 5,7, 9,13, 17,25, 33,49, 65,97, 129,193};
263
 
264
static int x8_get_dc_rlf(IntraX8Context * const w,int const mode, int * const level, int * const final){
265
    MpegEncContext * const s= w->s;
266
    int i,e,c;
267
 
268
    av_assert2(mode<3);
269
    if( !w->j_dc_vlc[mode] ) {
270
        int table_index;
271
        table_index = get_bits(&s->gb, 3);
272
        //4 modes, same table
273
        w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
274
    }
275
 
276
    i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
277
 
278
    /*(i>=17) {i-=17;final=1;}*/
279
    c= i>16;
280
    (*final)=c;
281
    i-=17*c;
282
 
283
    if(i<=0){
284
        (*level)=0;
285
        return -i;
286
    }
287
    c=(i+1)>>1;//hackish way to calculate dc_extra_sbits[]
288
    c-=c>1;
289
 
290
    e=get_bits(&s->gb,c);//get the extra bits
291
    i=dc_index_offset[i]+(e>>1);
292
 
293
    e= -(e & 1);//0,0xffffff
294
    (*level)= (i ^ e) - e;// (i^0)-0 , (i^0xff)-(-1)
295
    return 0;
296
}
297
//end of huffman
298
 
299
static int x8_setup_spatial_predictor(IntraX8Context * const w, const int chroma){
300
    MpegEncContext * const s= w->s;
301
    int range;
302
    int sum;
303
    int quant;
304
 
305
    w->dsp.setup_spatial_compensation(s->dest[chroma], s->edge_emu_buffer,
306
                                      s->current_picture.f.linesize[chroma>0],
307
                                      &range, &sum, w->edges);
308
    if(chroma){
309
        w->orient=w->chroma_orient;
310
        quant=w->quant_dc_chroma;
311
    }else{
312
        quant=w->quant;
313
    }
314
 
315
    w->flat_dc=0;
316
    if(range < quant || range < 3){
317
        w->orient=0;
318
        if(range < 3){//yep you read right, a +-1 idct error may break decoding!
319
            w->flat_dc=1;
320
            sum+=9;
321
            w->predicted_dc = (sum*6899)>>17;//((1<<17)+9)/(8+8+1+2)=6899
322
        }
323
    }
324
    if(chroma)
325
        return 0;
326
 
327
    av_assert2(w->orient < 3);
328
    if(range < 2*w->quant){
329
        if( (w->edges&3) == 0){
330
            if(w->orient==1) w->orient=11;
331
            if(w->orient==2) w->orient=10;
332
        }else{
333
            w->orient=0;
334
        }
335
        w->raw_orient=0;
336
    }else{
337
        static const uint8_t prediction_table[3][12]={
338
            {0,8,4, 10,11, 2,6,9,1,3,5,7},
339
            {4,0,8, 11,10, 3,5,2,6,9,1,7},
340
            {8,0,4, 10,11, 1,7,2,6,9,3,5}
341
        };
342
        w->raw_orient=x8_get_orient_vlc(w);
343
        if(w->raw_orient<0) return -1;
344
        av_assert2(w->raw_orient < 12 );
345
        av_assert2(w->orient<3);
346
        w->orient=prediction_table[w->orient][w->raw_orient];
347
    }
348
    return 0;
349
}
350
 
351
static void x8_update_predictions(IntraX8Context * const w, const int orient, const int est_run ){
352
    MpegEncContext * const s= w->s;
353
 
354
    w->prediction_table[s->mb_x*2+(s->mb_y&1)] = (est_run<<2) + 1*(orient==4) + 2*(orient==8);
355
/*
356
  y=2n+0 ->//0 2 4
357
  y=2n+1 ->//1 3 5
358
*/
359
}
360
static void x8_get_prediction_chroma(IntraX8Context * const w){
361
    MpegEncContext * const s= w->s;
362
 
363
    w->edges = 1*( !(s->mb_x>>1) );
364
    w->edges|= 2*( !(s->mb_y>>1) );
365
    w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );//mb_x for chroma would always be odd
366
 
367
    w->raw_orient=0;
368
    if(w->edges&3){//lut_co[8]={inv,4,8,8, inv,4,8,8}<- =>{1,1,0,0;1,1,0,0} => 0xCC
369
        w->chroma_orient=4<<((0xCC>>w->edges)&1);
370
        return;
371
    }
372
    w->chroma_orient = (w->prediction_table[2*s->mb_x-2] & 0x03)<<2;//block[x-1][y|1-1)]
373
}
374
 
375
static void x8_get_prediction(IntraX8Context * const w){
376
    MpegEncContext * const s= w->s;
377
    int a,b,c,i;
378
 
379
    w->edges = 1*( !s->mb_x );
380
    w->edges|= 2*( !s->mb_y );
381
    w->edges|= 4*( s->mb_x >= (2*s->mb_width-1) );
382
 
383
    switch(w->edges&3){
384
        case 0:
385
            break;
386
        case 1:
387
            //take the one from the above block[0][y-1]
388
            w->est_run = w->prediction_table[!(s->mb_y&1)]>>2;
389
            w->orient  = 1;
390
            return;
391
        case 2:
392
            //take the one from the previous block[x-1][0]
393
            w->est_run = w->prediction_table[2*s->mb_x-2]>>2;
394
            w->orient  = 2;
395
            return;
396
        case 3:
397
            w->est_run = 16;
398
            w->orient  = 0;
399
            return;
400
    }
401
    //no edge cases
402
    b= w->prediction_table[2*s->mb_x   + !(s->mb_y&1) ];//block[x  ][y-1]
403
    a= w->prediction_table[2*s->mb_x-2 +  (s->mb_y&1) ];//block[x-1][y  ]
404
    c= w->prediction_table[2*s->mb_x-2 + !(s->mb_y&1) ];//block[x-1][y-1]
405
 
406
    w->est_run = FFMIN(b,a);
407
    /* This condition has nothing to do with w->edges, even if it looks
408
       similar it would trigger if e.g. x=3;y=2;
409
       I guess somebody wrote something wrong and it became standard. */
410
    if( (s->mb_x & s->mb_y) != 0 ) w->est_run=FFMIN(c,w->est_run);
411
    w->est_run>>=2;
412
 
413
    a&=3;
414
    b&=3;
415
    c&=3;
416
 
417
    i=( 0xFFEAF4C4>>(2*b+8*a) )&3;
418
    if(i!=3) w->orient=i;
419
    else     w->orient=( 0xFFEAD8>>(2*c+8*(w->quant>12)) )&3;
420
/*
421
lut1[b][a]={
422
->{0, 1, 0, pad},
423
  {0, 1, X, pad},
424
  {2, 2, 2, pad}}
425
   pad 2   2  2; pad X  1  0; pad 0  1  0 <-
426
-> 11 10 '10 10 '11 11'01 00 '11 00'01 00=>0xEAF4C4
427
 
428
lut2[q>12][c]={
429
  ->{0,2,1,pad},
430
    {2,2,2,pad}}
431
   pad 2  2  2; pad 1  2  0 <-
432
-> 11 10'10 10 '11 01'10 00=>0xEAD8
433
*/
434
}
435
 
436
 
437
static void x8_ac_compensation(IntraX8Context * const w, int const direction, int const dc_level){
438
    MpegEncContext * const s= w->s;
439
    int t;
440
#define B(x,y)  s->block[0][w->idct_permutation[(x)+(y)*8]]
441
#define T(x)  ((x) * dc_level + 0x8000) >> 16;
442
    switch(direction){
443
    case 0:
444
        t = T(3811);//h
445
        B(1,0) -= t;
446
        B(0,1) -= t;
447
 
448
        t = T(487);//e
449
        B(2,0) -= t;
450
        B(0,2) -= t;
451
 
452
        t = T(506);//f
453
        B(3,0) -= t;
454
        B(0,3) -= t;
455
 
456
        t = T(135);//c
457
        B(4,0) -= t;
458
        B(0,4) -= t;
459
        B(2,1) += t;
460
        B(1,2) += t;
461
        B(3,1) += t;
462
        B(1,3) += t;
463
 
464
        t = T(173);//d
465
        B(5,0) -= t;
466
        B(0,5) -= t;
467
 
468
        t = T(61);//b
469
        B(6,0) -= t;
470
        B(0,6) -= t;
471
        B(5,1) += t;
472
        B(1,5) += t;
473
 
474
        t = T(42); //a
475
        B(7,0) -= t;
476
        B(0,7) -= t;
477
        B(4,1) += t;
478
        B(1,4) += t;
479
        B(4,4) += t;
480
 
481
        t = T(1084);//g
482
        B(1,1) += t;
483
 
484
        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
485
        break;
486
    case 1:
487
        B(0,1) -= T(6269);
488
        B(0,3) -= T( 708);
489
        B(0,5) -= T( 172);
490
        B(0,7) -= T(  73);
491
 
492
        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7*8);
493
        break;
494
    case 2:
495
        B(1,0) -= T(6269);
496
        B(3,0) -= T( 708);
497
        B(5,0) -= T( 172);
498
        B(7,0) -= T(  73);
499
 
500
        s->block_last_index[0] = FFMAX(s->block_last_index[0], 7);
501
        break;
502
    }
503
#undef B
504
#undef T
505
}
506
 
507
static void dsp_x8_put_solidcolor(uint8_t const pix, uint8_t * dst, int const linesize){
508
    int k;
509
    for(k=0;k<8;k++){
510
        memset(dst,pix,8);
511
        dst+=linesize;
512
    }
513
}
514
 
515
static const int16_t quant_table[64] = {
516
    256, 256, 256, 256,  256, 256, 259, 262,
517
    265, 269, 272, 275,  278, 282, 285, 288,
518
    292, 295, 299, 303,  306, 310, 314, 317,
519
    321, 325, 329, 333,  337, 341, 345, 349,
520
    353, 358, 362, 366,  371, 375, 379, 384,
521
    389, 393, 398, 403,  408, 413, 417, 422,
522
    428, 433, 438, 443,  448, 454, 459, 465,
523
    470, 476, 482, 488,  493, 499, 505, 511
524
};
525
 
526
static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){
527
    MpegEncContext * const s= w->s;
528
 
529
    uint8_t * scantable;
530
    int final,run,level;
531
    int ac_mode,dc_mode,est_run,dc_level;
532
    int pos,n;
533
    int zeros_only;
534
    int use_quant_matrix;
535
    int sign;
536
 
537
    av_assert2(w->orient<12);
538
    s->dsp.clear_block(s->block[0]);
539
 
540
    if(chroma){
541
        dc_mode=2;
542
    }else{
543
        dc_mode=!!w->est_run;//0,1
544
    }
545
 
546
    if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;
547
    n=0;
548
    zeros_only=0;
549
    if(!final){//decode ac
550
        use_quant_matrix=w->use_quant_matrix;
551
        if(chroma){
552
            ac_mode = 1;
553
            est_run = 64;//not used
554
        }else{
555
            if (w->raw_orient < 3){
556
                use_quant_matrix = 0;
557
            }
558
            if(w->raw_orient > 4){
559
                ac_mode = 0;
560
                est_run = 64;
561
            }else{
562
                if(w->est_run > 1){
563
                    ac_mode = 2;
564
                    est_run=w->est_run;
565
                }else{
566
                    ac_mode = 3;
567
                    est_run = 64;
568
                }
569
            }
570
        }
571
        x8_select_ac_table(w,ac_mode);
572
        /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-
573
        -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */
574
        scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;
575
        pos=0;
576
        do {
577
            n++;
578
            if( n >= est_run ){
579
                ac_mode=3;
580
                x8_select_ac_table(w,3);
581
            }
582
 
583
            x8_get_ac_rlf(w,ac_mode,&run,&level,&final);
584
 
585
            pos+=run+1;
586
            if(pos>63){
587
                //this also handles vlc error in x8_get_ac_rlf
588
                return -1;
589
            }
590
            level= (level+1) * w->dquant;
591
            level+= w->qsum;
592
 
593
            sign = - get_bits1(&s->gb);
594
            level = (level ^ sign) - sign;
595
 
596
            if(use_quant_matrix){
597
                level = (level*quant_table[pos])>>8;
598
            }
599
            s->block[0][ scantable[pos] ]=level;
600
        }while(!final);
601
 
602
        s->block_last_index[0]=pos;
603
    }else{//DC only
604
        s->block_last_index[0]=0;
605
        if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]
606
            int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:
607
                                            w->divide_quant_dc_chroma;
608
            int32_t dc_quant    = !chroma ? w->quant:
609
                                            w->quant_dc_chroma;
610
 
611
            //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding
612
            dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;
613
 
614
            dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),
615
                                   s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
616
 
617
            goto block_placed;
618
        }
619
        zeros_only = (dc_level == 0);
620
    }
621
    if(!chroma){
622
        s->block[0][0] = dc_level*w->quant;
623
    }else{
624
        s->block[0][0] = dc_level*w->quant_dc_chroma;
625
    }
626
 
627
    //there is !zero_only check in the original, but dc_level check is enough
628
    if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){
629
        int direction;
630
        /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-
631
        -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */
632
        direction= (0x6A017C>>(w->orient*2))&3;
633
        if (direction != 3){
634
            x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]
635
        }
636
    }
637
 
638
    if(w->flat_dc){
639
        dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);
640
    }else{
641
        w->dsp.spatial_compensation[w->orient]( s->edge_emu_buffer,
642
                                            s->dest[chroma],
643
                                            s->current_picture.f.linesize[!!chroma] );
644
    }
645
    if(!zeros_only)
646
        w->wdsp.idct_add (s->dest[chroma],
647
                          s->current_picture.f.linesize[!!chroma],
648
                          s->block[0] );
649
 
650
block_placed:
651
 
652
    if(!chroma){
653
        x8_update_predictions(w,w->orient,n);
654
    }
655
 
656
    if(s->loop_filter){
657
        uint8_t* ptr = s->dest[chroma];
658
        int linesize = s->current_picture.f.linesize[!!chroma];
659
 
660
        if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){
661
            w->dsp.h_loop_filter(ptr, linesize, w->quant);
662
        }
663
        if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){
664
            w->dsp.v_loop_filter(ptr, linesize, w->quant);
665
        }
666
    }
667
    return 0;
668
}
669
 
670
static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*
671
//not s->linesize as this would be wrong for field pics
672
//not that IntraX8 has interlacing support ;)
673
    const int linesize   = s->current_picture.f.linesize[0];
674
    const int uvlinesize = s->current_picture.f.linesize[1];
675
 
676
    s->dest[0] = s->current_picture.f.data[0];
677
    s->dest[1] = s->current_picture.f.data[1];
678
    s->dest[2] = s->current_picture.f.data[2];
679
 
680
    s->dest[0] +=   s->mb_y        *   linesize << 3;
681
    s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows
682
    s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;
683
}
684
 
685
/**
686
 * Initialize IntraX8 frame decoder.
687
 * Requires valid MpegEncContext with valid s->mb_width before calling.
688
 * @param w pointer to IntraX8Context
689
 * @param s pointer to MpegEncContext of the parent codec
690
 */
691
av_cold void ff_intrax8_common_init(IntraX8Context * w, MpegEncContext * const s){
692
 
693
    w->s=s;
694
    x8_vlc_init();
695
    av_assert0(s->mb_width>0);
696
    w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
697
 
698
    ff_wmv2dsp_init(&w->wdsp);
699
    ff_init_scantable_permutation(w->idct_permutation,
700
                                  w->wdsp.idct_perm);
701
 
702
    ff_init_scantable(w->idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]);
703
    ff_init_scantable(w->idct_permutation, &w->scantable[1], ff_wmv1_scantable[2]);
704
    ff_init_scantable(w->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 MPV_frame_start(), ff_er_frame_start() before calling this function.
722
 * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function.
723
 * This function does not use MPV_decode_mb().
724
 * lowres decoding is theoretically impossible.
725
 * @param w pointer to IntraX8Context
726
 * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
727
 * @param quant_offset offset away from zero
728
 */
729
int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
730
    MpegEncContext * const s= w->s;
731
    int mb_xy;
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
}