Statistics
| Branch: | Revision:

ffmpeg / libavcodec / error_resilience.c @ 3732c483

History | View | Annotate | Download (43.4 KB)

1
/*
2
 * Error resilience / concealment
3
 *
4
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22

    
23
/**
24
 * @file
25
 * Error resilience / concealment.
26
 */
27

    
28
#include <limits.h>
29

    
30
#include "avcodec.h"
31
#include "dsputil.h"
32
#include "mpegvideo.h"
33
#include "h264.h"
34
#include "rectangle.h"
35

    
36
/*
37
 * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
38
 * but error concealment must support both h264 and h263 thus we must undo this
39
 */
40
#undef mb_intra
41

    
42
static void decode_mb(MpegEncContext *s, int ref){
43
    s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize  ) + s->mb_x * 16;
44
    s->dest[1] = s->current_picture.data[1] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
45
    s->dest[2] = s->current_picture.data[2] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
46

    
47
    if(CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264){
48
        H264Context *h= (void*)s;
49
        h->mb_xy= s->mb_x + s->mb_y*s->mb_stride;
50
        memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
51
        assert(ref>=0);
52
        if(ref >= h->ref_count[0]) //FIXME it is posible albeit uncommon that slice references differ between slices, we take the easy approuch and ignore it for now. If this turns out to have any relevance in practice then correct remapping should be added
53
            ref=0;
54
        fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
55
        fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
56
        fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
57
        assert(!FRAME_MBAFF);
58
        ff_h264_hl_decode_mb(h);
59
    }else{
60
        assert(ref==0);
61
    MPV_decode_mb(s, s->block);
62
    }
63
}
64

    
65
/**
66
 * @param stride the number of MVs to get to the next row
67
 * @param mv_step the number of MVs per row or column in a macroblock
68
 */
69
static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){
70
    if(s->codec_id == CODEC_ID_H264){
71
        H264Context *h= (void*)s;
72
        assert(s->quarter_sample);
73
        *mv_step= 4;
74
        *stride= h->b_stride;
75
    }else{
76
        *mv_step= 2;
77
        *stride= s->b8_stride;
78
    }
79
}
80

    
81
/**
82
 * replaces the current MB with a flat dc only version.
83
 */
84
static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
85
{
86
    int dc, dcu, dcv, y, i;
87
    for(i=0; i<4; i++){
88
        dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
89
        if(dc<0) dc=0;
90
        else if(dc>2040) dc=2040;
91
        for(y=0; y<8; y++){
92
            int x;
93
            for(x=0; x<8; x++){
94
                dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8;
95
            }
96
        }
97
    }
98
    dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride];
99
    dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride];
100
    if     (dcu<0   ) dcu=0;
101
    else if(dcu>2040) dcu=2040;
102
    if     (dcv<0   ) dcv=0;
103
    else if(dcv>2040) dcv=2040;
104
    for(y=0; y<8; y++){
105
        int x;
106
        for(x=0; x<8; x++){
107
            dest_cb[x + y*(s->uvlinesize)]= dcu/8;
108
            dest_cr[x + y*(s->uvlinesize)]= dcv/8;
109
        }
110
    }
111
}
112

    
113
static void filter181(int16_t *data, int width, int height, int stride){
114
    int x,y;
115

    
116
    /* horizontal filter */
117
    for(y=1; y<height-1; y++){
118
        int prev_dc= data[0 + y*stride];
119

    
120
        for(x=1; x<width-1; x++){
121
            int dc;
122

    
123
            dc= - prev_dc
124
                + data[x     + y*stride]*8
125
                - data[x + 1 + y*stride];
126
            dc= (dc*10923 + 32768)>>16;
127
            prev_dc= data[x + y*stride];
128
            data[x + y*stride]= dc;
129
        }
130
    }
131

    
132
    /* vertical filter */
133
    for(x=1; x<width-1; x++){
134
        int prev_dc= data[x];
135

    
136
        for(y=1; y<height-1; y++){
137
            int dc;
138

    
139
            dc= - prev_dc
140
                + data[x +  y   *stride]*8
141
                - data[x + (y+1)*stride];
142
            dc= (dc*10923 + 32768)>>16;
143
            prev_dc= data[x + y*stride];
144
            data[x + y*stride]= dc;
145
        }
146
    }
147
}
148

    
149
/**
150
 * guess the dc of blocks which do not have an undamaged dc
151
 * @param w     width in 8 pixel blocks
152
 * @param h     height in 8 pixel blocks
153
 */
154
static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
155
    int b_x, b_y;
156

    
157
    for(b_y=0; b_y<h; b_y++){
158
        for(b_x=0; b_x<w; b_x++){
159
            int color[4]={1024,1024,1024,1024};
160
            int distance[4]={9999,9999,9999,9999};
161
            int mb_index, error, j;
162
            int64_t guess, weight_sum;
163

    
164
            mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
165

    
166
            error= s->error_status_table[mb_index];
167

    
168
            if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
169
            if(!(error&DC_ERROR)) continue;           //dc-ok
170

    
171
            /* right block */
172
            for(j=b_x+1; j<w; j++){
173
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
174
                int error_j= s->error_status_table[mb_index_j];
175
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
176
                if(intra_j==0 || !(error_j&DC_ERROR)){
177
                    color[0]= dc[j + b_y*stride];
178
                    distance[0]= j-b_x;
179
                    break;
180
                }
181
            }
182

    
183
            /* left block */
184
            for(j=b_x-1; j>=0; j--){
185
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
186
                int error_j= s->error_status_table[mb_index_j];
187
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
188
                if(intra_j==0 || !(error_j&DC_ERROR)){
189
                    color[1]= dc[j + b_y*stride];
190
                    distance[1]= b_x-j;
191
                    break;
192
                }
193
            }
194

    
195
            /* bottom block */
196
            for(j=b_y+1; j<h; j++){
197
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
198
                int error_j= s->error_status_table[mb_index_j];
199
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
200
                if(intra_j==0 || !(error_j&DC_ERROR)){
201
                    color[2]= dc[b_x + j*stride];
202
                    distance[2]= j-b_y;
203
                    break;
204
                }
205
            }
206

    
207
            /* top block */
208
            for(j=b_y-1; j>=0; j--){
209
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
210
                int error_j= s->error_status_table[mb_index_j];
211
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
212
                if(intra_j==0 || !(error_j&DC_ERROR)){
213
                    color[3]= dc[b_x + j*stride];
214
                    distance[3]= b_y-j;
215
                    break;
216
                }
217
            }
218

    
219
            weight_sum=0;
220
            guess=0;
221
            for(j=0; j<4; j++){
222
                int64_t weight= 256*256*256*16/distance[j];
223
                guess+= weight*(int64_t)color[j];
224
                weight_sum+= weight;
225
            }
226
            guess= (guess + weight_sum/2) / weight_sum;
227

    
228
            dc[b_x + b_y*stride]= guess;
229
        }
230
    }
231
}
232

    
233
/**
234
 * simple horizontal deblocking filter used for error resilience
235
 * @param w     width in 8 pixel blocks
236
 * @param h     height in 8 pixel blocks
237
 */
238
static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
239
    int b_x, b_y, mvx_stride, mvy_stride;
240
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
241
    set_mv_strides(s, &mvx_stride, &mvy_stride);
242
    mvx_stride >>= is_luma;
243
    mvy_stride *= mvx_stride;
244

    
245
    for(b_y=0; b_y<h; b_y++){
246
        for(b_x=0; b_x<w-1; b_x++){
247
            int y;
248
            int left_status = s->error_status_table[( b_x   >>is_luma) + (b_y>>is_luma)*s->mb_stride];
249
            int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
250
            int left_intra=   IS_INTRA(s->current_picture.mb_type      [( b_x   >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
251
            int right_intra=  IS_INTRA(s->current_picture.mb_type      [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
252
            int left_damage =  left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
253
            int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
254
            int offset= b_x*8 + b_y*stride*8;
255
            int16_t *left_mv=  s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride* b_x   ];
256
            int16_t *right_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
257

    
258
            if(!(left_damage||right_damage)) continue; // both undamaged
259

    
260
            if(   (!left_intra) && (!right_intra)
261
               && FFABS(left_mv[0]-right_mv[0]) + FFABS(left_mv[1]+right_mv[1]) < 2) continue;
262

    
263
            for(y=0; y<8; y++){
264
                int a,b,c,d;
265

    
266
                a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride];
267
                b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride];
268
                c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride];
269

    
270
                d= FFABS(b) - ((FFABS(a) + FFABS(c) + 1)>>1);
271
                d= FFMAX(d, 0);
272
                if(b<0) d= -d;
273

    
274
                if(d==0) continue;
275

    
276
                if(!(left_damage && right_damage))
277
                    d= d*16/9;
278

    
279
                if(left_damage){
280
                    dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)];
281
                    dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)];
282
                    dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)];
283
                    dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)];
284
                }
285
                if(right_damage){
286
                    dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)];
287
                    dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)];
288
                    dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)];
289
                    dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)];
290
                }
291
            }
292
        }
293
    }
294
}
295

    
296
/**
297
 * simple vertical deblocking filter used for error resilience
298
 * @param w     width in 8 pixel blocks
299
 * @param h     height in 8 pixel blocks
300
 */
301
static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
302
    int b_x, b_y, mvx_stride, mvy_stride;
303
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
304
    set_mv_strides(s, &mvx_stride, &mvy_stride);
305
    mvx_stride >>= is_luma;
306
    mvy_stride *= mvx_stride;
307

    
308
    for(b_y=0; b_y<h-1; b_y++){
309
        for(b_x=0; b_x<w; b_x++){
310
            int x;
311
            int top_status   = s->error_status_table[(b_x>>is_luma) + ( b_y   >>is_luma)*s->mb_stride];
312
            int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
313
            int top_intra=     IS_INTRA(s->current_picture.mb_type      [(b_x>>is_luma) + ( b_y   >>is_luma)*s->mb_stride]);
314
            int bottom_intra=  IS_INTRA(s->current_picture.mb_type      [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
315
            int top_damage =      top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
316
            int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
317
            int offset= b_x*8 + b_y*stride*8;
318
            int16_t *top_mv=    s->current_picture.motion_val[0][mvy_stride* b_y    + mvx_stride*b_x];
319
            int16_t *bottom_mv= s->current_picture.motion_val[0][mvy_stride*(b_y+1) + mvx_stride*b_x];
320

    
321
            if(!(top_damage||bottom_damage)) continue; // both undamaged
322

    
323
            if(   (!top_intra) && (!bottom_intra)
324
               && FFABS(top_mv[0]-bottom_mv[0]) + FFABS(top_mv[1]+bottom_mv[1]) < 2) continue;
325

    
326
            for(x=0; x<8; x++){
327
                int a,b,c,d;
328

    
329
                a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride];
330
                b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride];
331
                c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride];
332

    
333
                d= FFABS(b) - ((FFABS(a) + FFABS(c)+1)>>1);
334
                d= FFMAX(d, 0);
335
                if(b<0) d= -d;
336

    
337
                if(d==0) continue;
338

    
339
                if(!(top_damage && bottom_damage))
340
                    d= d*16/9;
341

    
342
                if(top_damage){
343
                    dst[offset + x +  7*stride] = cm[dst[offset + x +  7*stride] + ((d*7)>>4)];
344
                    dst[offset + x +  6*stride] = cm[dst[offset + x +  6*stride] + ((d*5)>>4)];
345
                    dst[offset + x +  5*stride] = cm[dst[offset + x +  5*stride] + ((d*3)>>4)];
346
                    dst[offset + x +  4*stride] = cm[dst[offset + x +  4*stride] + ((d*1)>>4)];
347
                }
348
                if(bottom_damage){
349
                    dst[offset + x +  8*stride] = cm[dst[offset + x +  8*stride] - ((d*7)>>4)];
350
                    dst[offset + x +  9*stride] = cm[dst[offset + x +  9*stride] - ((d*5)>>4)];
351
                    dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)];
352
                    dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)];
353
                }
354
            }
355
        }
356
    }
357
}
358

    
359
static void guess_mv(MpegEncContext *s){
360
    uint8_t fixed[s->mb_stride * s->mb_height];
361
#define MV_FROZEN    3
362
#define MV_CHANGED   2
363
#define MV_UNCHANGED 1
364
    const int mb_stride = s->mb_stride;
365
    const int mb_width = s->mb_width;
366
    const int mb_height= s->mb_height;
367
    int i, depth, num_avail;
368
    int mb_x, mb_y, mot_step, mot_stride;
369

    
370
    set_mv_strides(s, &mot_step, &mot_stride);
371

    
372
    num_avail=0;
373
    for(i=0; i<s->mb_num; i++){
374
        const int mb_xy= s->mb_index2xy[ i ];
375
        int f=0;
376
        int error= s->error_status_table[mb_xy];
377

    
378
        if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
379
        if(!(error&MV_ERROR)) f=MV_FROZEN;           //inter with undamaged MV
380

    
381
        fixed[mb_xy]= f;
382
        if(f==MV_FROZEN)
383
            num_avail++;
384
        else if(s->last_picture.data[0]){
385
            const int mb_y= mb_xy / s->mb_stride;
386
            const int mb_x= mb_xy % s->mb_stride;
387
            const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
388
            s->current_picture.motion_val[0][mot_index][0]= s->last_picture.motion_val[0][mot_index][0];
389
            s->current_picture.motion_val[0][mot_index][1]= s->last_picture.motion_val[0][mot_index][1];
390
            s->current_picture.ref_index[0][4*mb_xy]      = s->last_picture.ref_index[0][4*mb_xy];
391
        }
392
    }
393

    
394
    if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
395
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
396
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
397
                const int mb_xy= mb_x + mb_y*s->mb_stride;
398

    
399
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))  continue;
400
                if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
401

    
402
                s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
403
                s->mb_intra=0;
404
                s->mv_type = MV_TYPE_16X16;
405
                s->mb_skipped=0;
406

    
407
                s->dsp.clear_blocks(s->block[0]);
408

    
409
                s->mb_x= mb_x;
410
                s->mb_y= mb_y;
411
                s->mv[0][0][0]= 0;
412
                s->mv[0][0][1]= 0;
413
                decode_mb(s, 0);
414
            }
415
        }
416
        return;
417
    }
418

    
419
    for(depth=0;; depth++){
420
        int changed, pass, none_left;
421

    
422
        none_left=1;
423
        changed=1;
424
        for(pass=0; (changed || pass<2) && pass<10; pass++){
425
            int mb_x, mb_y;
426
int score_sum=0;
427

    
428
            changed=0;
429
            for(mb_y=0; mb_y<s->mb_height; mb_y++){
430
                for(mb_x=0; mb_x<s->mb_width; mb_x++){
431
                    const int mb_xy= mb_x + mb_y*s->mb_stride;
432
                    int mv_predictor[8][2]={{0}};
433
                    int ref[8]={0};
434
                    int pred_count=0;
435
                    int j;
436
                    int best_score=256*256*256*64;
437
                    int best_pred=0;
438
                    const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
439
                    int prev_x= s->current_picture.motion_val[0][mot_index][0];
440
                    int prev_y= s->current_picture.motion_val[0][mot_index][1];
441

    
442
                    if((mb_x^mb_y^pass)&1) continue;
443

    
444
                    if(fixed[mb_xy]==MV_FROZEN) continue;
445
                    assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
446
                    assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
447

    
448
                    j=0;
449
                    if(mb_x>0           && fixed[mb_xy-1        ]==MV_FROZEN) j=1;
450
                    if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_FROZEN) j=1;
451
                    if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
452
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
453
                    if(j==0) continue;
454

    
455
                    j=0;
456
                    if(mb_x>0           && fixed[mb_xy-1        ]==MV_CHANGED) j=1;
457
                    if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_CHANGED) j=1;
458
                    if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
459
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
460
                    if(j==0 && pass>1) continue;
461

    
462
                    none_left=0;
463

    
464
                    if(mb_x>0 && fixed[mb_xy-1]){
465
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
466
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
467
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy-1)];
468
                        pred_count++;
469
                    }
470
                    if(mb_x+1<mb_width && fixed[mb_xy+1]){
471
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
472
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
473
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy+1)];
474
                        pred_count++;
475
                    }
476
                    if(mb_y>0 && fixed[mb_xy-mb_stride]){
477
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
478
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
479
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)];
480
                        pred_count++;
481
                    }
482
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
483
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
484
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
485
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)];
486
                        pred_count++;
487
                    }
488
                    if(pred_count==0) continue;
489

    
490
                    if(pred_count>1){
491
                        int sum_x=0, sum_y=0, sum_r=0;
492
                        int max_x, max_y, min_x, min_y, max_r, min_r;
493

    
494
                        for(j=0; j<pred_count; j++){
495
                            sum_x+= mv_predictor[j][0];
496
                            sum_y+= mv_predictor[j][1];
497
                            sum_r+= ref[j];
498
                            if(j && ref[j] != ref[j-1])
499
                                goto skip_mean_and_median;
500
                        }
501

    
502
                        /* mean */
503
                        mv_predictor[pred_count][0] = sum_x/j;
504
                        mv_predictor[pred_count][1] = sum_y/j;
505
                        ref         [pred_count]    = sum_r/j;
506

    
507
                        /* median */
508
                        if(pred_count>=3){
509
                            min_y= min_x= min_r= 99999;
510
                            max_y= max_x= max_r=-99999;
511
                        }else{
512
                            min_x=min_y=max_x=max_y=min_r=max_r=0;
513
                        }
514
                        for(j=0; j<pred_count; j++){
515
                            max_x= FFMAX(max_x, mv_predictor[j][0]);
516
                            max_y= FFMAX(max_y, mv_predictor[j][1]);
517
                            max_r= FFMAX(max_r, ref[j]);
518
                            min_x= FFMIN(min_x, mv_predictor[j][0]);
519
                            min_y= FFMIN(min_y, mv_predictor[j][1]);
520
                            min_r= FFMIN(min_r, ref[j]);
521
                        }
522
                        mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
523
                        mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
524
                        ref         [pred_count+1]    = sum_r - max_r - min_r;
525

    
526
                        if(pred_count==4){
527
                            mv_predictor[pred_count+1][0] /= 2;
528
                            mv_predictor[pred_count+1][1] /= 2;
529
                            ref         [pred_count+1]    /= 2;
530
                        }
531
                        pred_count+=2;
532
                    }
533
skip_mean_and_median:
534

    
535
                    /* zero MV */
536
                    pred_count++;
537

    
538
                    /* last MV */
539
                    mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
540
                    mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
541
                    ref         [pred_count]   = s->current_picture.ref_index[0][4*mb_xy];
542
                    pred_count++;
543

    
544
                    s->mv_dir = MV_DIR_FORWARD;
545
                    s->mb_intra=0;
546
                    s->mv_type = MV_TYPE_16X16;
547
                    s->mb_skipped=0;
548

    
549
                    s->dsp.clear_blocks(s->block[0]);
550

    
551
                    s->mb_x= mb_x;
552
                    s->mb_y= mb_y;
553

    
554
                    for(j=0; j<pred_count; j++){
555
                        int score=0;
556
                        uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
557

    
558
                        s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
559
                        s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
560

    
561
                        if(ref[j]<0) //predictor intra or otherwise not available
562
                            continue;
563

    
564
                        decode_mb(s, ref[j]);
565

    
566
                        if(mb_x>0 && fixed[mb_xy-1]){
567
                            int k;
568
                            for(k=0; k<16; k++)
569
                                score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize   ]);
570
                        }
571
                        if(mb_x+1<mb_width && fixed[mb_xy+1]){
572
                            int k;
573
                            for(k=0; k<16; k++)
574
                                score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
575
                        }
576
                        if(mb_y>0 && fixed[mb_xy-mb_stride]){
577
                            int k;
578
                            for(k=0; k<16; k++)
579
                                score += FFABS(src[k-s->linesize   ]-src[k               ]);
580
                        }
581
                        if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
582
                            int k;
583
                            for(k=0; k<16; k++)
584
                                score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
585
                        }
586

    
587
                        if(score <= best_score){ // <= will favor the last MV
588
                            best_score= score;
589
                            best_pred= j;
590
                        }
591
                    }
592
score_sum+= best_score;
593
                    s->mv[0][0][0]= mv_predictor[best_pred][0];
594
                    s->mv[0][0][1]= mv_predictor[best_pred][1];
595

    
596
                    for(i=0; i<mot_step; i++)
597
                        for(j=0; j<mot_step; j++){
598
                            s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
599
                            s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
600
                        }
601

    
602
                    decode_mb(s, ref[best_pred]);
603

    
604

    
605
                    if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
606
                        fixed[mb_xy]=MV_CHANGED;
607
                        changed++;
608
                    }else
609
                        fixed[mb_xy]=MV_UNCHANGED;
610
                }
611
            }
612

    
613
//            printf(".%d/%d", changed, score_sum); fflush(stdout);
614
        }
615

    
616
        if(none_left)
617
            return;
618

    
619
        for(i=0; i<s->mb_num; i++){
620
            int mb_xy= s->mb_index2xy[i];
621
            if(fixed[mb_xy])
622
                fixed[mb_xy]=MV_FROZEN;
623
        }
624
//        printf(":"); fflush(stdout);
625
    }
626
}
627

    
628
static int is_intra_more_likely(MpegEncContext *s){
629
    int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
630

    
631
    if(!s->last_picture_ptr || !s->last_picture_ptr->data[0]) return 1; //no previous frame available -> use spatial prediction
632

    
633
    undamaged_count=0;
634
    for(i=0; i<s->mb_num; i++){
635
        const int mb_xy= s->mb_index2xy[i];
636
        const int error= s->error_status_table[mb_xy];
637
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
638
            undamaged_count++;
639
    }
640

    
641
    if(s->codec_id == CODEC_ID_H264){
642
        H264Context *h= (void*)s;
643
        if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0])
644
            return 1;
645
    }
646

    
647
    if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
648

    
649
    //prevent dsp.sad() check, that requires access to the image
650
    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == AV_PICTURE_TYPE_I)
651
        return 1;
652

    
653
    skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
654
    is_intra_likely=0;
655

    
656
    j=0;
657
    for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
658
        for(mb_x= 0; mb_x<s->mb_width; mb_x++){
659
            int error;
660
            const int mb_xy= mb_x + mb_y*s->mb_stride;
661

    
662
            error= s->error_status_table[mb_xy];
663
            if((error&DC_ERROR) && (error&MV_ERROR))
664
                continue; //skip damaged
665

    
666
            j++;
667
            if((j%skip_amount) != 0) continue; //skip a few to speed things up
668

    
669
            if(s->pict_type==AV_PICTURE_TYPE_I){
670
                uint8_t *mb_ptr     = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
671
                uint8_t *last_mb_ptr= s->last_picture.data   [0] + mb_x*16 + mb_y*16*s->linesize;
672

    
673
                is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);
674
                // FIXME need await_progress() here
675
                is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
676
            }else{
677
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
678
                   is_intra_likely++;
679
                else
680
                   is_intra_likely--;
681
            }
682
        }
683
    }
684
//printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
685
    return is_intra_likely > 0;
686
}
687

    
688
void ff_er_frame_start(MpegEncContext *s){
689
    if(!s->error_recognition) return;
690

    
691
    memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
692
    s->error_count= 3*s->mb_num;
693
}
694

    
695
/**
696
 * adds a slice.
697
 * @param endx x component of the last macroblock, can be -1 for the last of the previous line
698
 * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
699
 *               error of the same type occurred
700
 */
701
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
702
    const int start_i= av_clip(startx + starty * s->mb_width    , 0, s->mb_num-1);
703
    const int end_i  = av_clip(endx   + endy   * s->mb_width    , 0, s->mb_num);
704
    const int start_xy= s->mb_index2xy[start_i];
705
    const int end_xy  = s->mb_index2xy[end_i];
706
    int mask= -1;
707

    
708
    if(s->avctx->hwaccel)
709
        return;
710

    
711
    if(start_i > end_i || start_xy > end_xy){
712
        av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
713
        return;
714
    }
715

    
716
    if(!s->error_recognition) return;
717

    
718
    mask &= ~VP_START;
719
    if(status & (AC_ERROR|AC_END)){
720
        mask &= ~(AC_ERROR|AC_END);
721
        s->error_count -= end_i - start_i + 1;
722
    }
723
    if(status & (DC_ERROR|DC_END)){
724
        mask &= ~(DC_ERROR|DC_END);
725
        s->error_count -= end_i - start_i + 1;
726
    }
727
    if(status & (MV_ERROR|MV_END)){
728
        mask &= ~(MV_ERROR|MV_END);
729
        s->error_count -= end_i - start_i + 1;
730
    }
731

    
732
    if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
733

    
734
    if(mask == ~0x7F){
735
        memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
736
    }else{
737
        int i;
738
        for(i=start_xy; i<end_xy; i++){
739
            s->error_status_table[ i ] &= mask;
740
        }
741
    }
742

    
743
    if(end_i == s->mb_num)
744
        s->error_count= INT_MAX;
745
    else{
746
        s->error_status_table[end_xy] &= mask;
747
        s->error_status_table[end_xy] |= status;
748
    }
749

    
750
    s->error_status_table[start_xy] |= VP_START;
751

    
752
    if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){
753
        int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
754

    
755
        prev_status &= ~ VP_START;
756
        if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
757
    }
758
}
759

    
760
void ff_er_frame_end(MpegEncContext *s){
761
    int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
762
    int distance;
763
    int threshold_part[4]= {100,100,100};
764
    int threshold= 50;
765
    int is_intra_likely;
766
    int size = s->b8_stride * 2 * s->mb_height;
767
    Picture *pic= s->current_picture_ptr;
768

    
769
    if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
770
       s->avctx->hwaccel ||
771
       s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
772
       s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
773
       s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
774

    
775
    if(s->current_picture.motion_val[0] == NULL){
776
        av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
777

    
778
        for(i=0; i<2; i++){
779
            pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
780
            pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
781
            pic->motion_val[i]= pic->motion_val_base[i]+4;
782
        }
783
        pic->motion_subsample_log2= 3;
784
        s->current_picture= *s->current_picture_ptr;
785
    }
786

    
787
    if(s->avctx->debug&FF_DEBUG_ER){
788
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
789
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
790
                int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
791

    
792
                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
793
            }
794
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
795
        }
796
    }
797

    
798
#if 1
799
    /* handle overlapping slices */
800
    for(error_type=1; error_type<=3; error_type++){
801
        int end_ok=0;
802

    
803
        for(i=s->mb_num-1; i>=0; i--){
804
            const int mb_xy= s->mb_index2xy[i];
805
            int error= s->error_status_table[mb_xy];
806

    
807
            if(error&(1<<error_type))
808
                end_ok=1;
809
            if(error&(8<<error_type))
810
                end_ok=1;
811

    
812
            if(!end_ok)
813
                s->error_status_table[mb_xy]|= 1<<error_type;
814

    
815
            if(error&VP_START)
816
                end_ok=0;
817
        }
818
    }
819
#endif
820
#if 1
821
    /* handle slices with partitions of different length */
822
    if(s->partitioned_frame){
823
        int end_ok=0;
824

    
825
        for(i=s->mb_num-1; i>=0; i--){
826
            const int mb_xy= s->mb_index2xy[i];
827
            int error= s->error_status_table[mb_xy];
828

    
829
            if(error&AC_END)
830
                end_ok=0;
831
            if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
832
                end_ok=1;
833

    
834
            if(!end_ok)
835
                s->error_status_table[mb_xy]|= AC_ERROR;
836

    
837
            if(error&VP_START)
838
                end_ok=0;
839
        }
840
    }
841
#endif
842
    /* handle missing slices */
843
    if(s->error_recognition>=4){
844
        int end_ok=1;
845

    
846
        for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
847
            const int mb_xy= s->mb_index2xy[i];
848
            int error1= s->error_status_table[mb_xy  ];
849
            int error2= s->error_status_table[s->mb_index2xy[i+1]];
850

    
851
            if(error1&VP_START)
852
                end_ok=1;
853

    
854
            if(   error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
855
               && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
856
               && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
857
                end_ok=0;
858
            }
859

    
860
            if(!end_ok)
861
                s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
862
        }
863
    }
864

    
865
#if 1
866
    /* backward mark errors */
867
    distance=9999999;
868
    for(error_type=1; error_type<=3; error_type++){
869
        for(i=s->mb_num-1; i>=0; i--){
870
            const int mb_xy= s->mb_index2xy[i];
871
            int error= s->error_status_table[mb_xy];
872

    
873
            if(!s->mbskip_table[mb_xy]) //FIXME partition specific
874
                distance++;
875
            if(error&(1<<error_type))
876
                distance= 0;
877

    
878
            if(s->partitioned_frame){
879
                if(distance < threshold_part[error_type-1])
880
                    s->error_status_table[mb_xy]|= 1<<error_type;
881
            }else{
882
                if(distance < threshold)
883
                    s->error_status_table[mb_xy]|= 1<<error_type;
884
            }
885

    
886
            if(error&VP_START)
887
                distance= 9999999;
888
        }
889
    }
890
#endif
891

    
892
    /* forward mark errors */
893
    error=0;
894
    for(i=0; i<s->mb_num; i++){
895
        const int mb_xy= s->mb_index2xy[i];
896
        int old_error= s->error_status_table[mb_xy];
897

    
898
        if(old_error&VP_START)
899
            error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
900
        else{
901
            error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
902
            s->error_status_table[mb_xy]|= error;
903
        }
904
    }
905
#if 1
906
    /* handle not partitioned case */
907
    if(!s->partitioned_frame){
908
        for(i=0; i<s->mb_num; i++){
909
            const int mb_xy= s->mb_index2xy[i];
910
            error= s->error_status_table[mb_xy];
911
            if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
912
                error|= AC_ERROR|DC_ERROR|MV_ERROR;
913
            s->error_status_table[mb_xy]= error;
914
        }
915
    }
916
#endif
917

    
918
    dc_error= ac_error= mv_error=0;
919
    for(i=0; i<s->mb_num; i++){
920
        const int mb_xy= s->mb_index2xy[i];
921
        error= s->error_status_table[mb_xy];
922
        if(error&DC_ERROR) dc_error ++;
923
        if(error&AC_ERROR) ac_error ++;
924
        if(error&MV_ERROR) mv_error ++;
925
    }
926
    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
927

    
928
    is_intra_likely= is_intra_more_likely(s);
929

    
930
    /* set unknown mb-type to most likely */
931
    for(i=0; i<s->mb_num; i++){
932
        const int mb_xy= s->mb_index2xy[i];
933
        error= s->error_status_table[mb_xy];
934
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
935
            continue;
936

    
937
        if(is_intra_likely)
938
            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
939
        else
940
            s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
941
    }
942

    
943
    // change inter to intra blocks if no reference frames are available
944
    if (!s->last_picture.data[0] && !s->next_picture.data[0])
945
        for(i=0; i<s->mb_num; i++){
946
            const int mb_xy= s->mb_index2xy[i];
947
            if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
948
                s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
949
        }
950

    
951
    /* handle inter blocks with damaged AC */
952
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
953
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
954
            const int mb_xy= mb_x + mb_y * s->mb_stride;
955
            const int mb_type= s->current_picture.mb_type[mb_xy];
956
            int dir = !s->last_picture.data[0];
957
            error= s->error_status_table[mb_xy];
958

    
959
            if(IS_INTRA(mb_type)) continue; //intra
960
            if(error&MV_ERROR) continue;              //inter with damaged MV
961
            if(!(error&AC_ERROR)) continue;           //undamaged inter
962

    
963
            s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
964
            s->mb_intra=0;
965
            s->mb_skipped=0;
966
            if(IS_8X8(mb_type)){
967
                int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
968
                int j;
969
                s->mv_type = MV_TYPE_8X8;
970
                for(j=0; j<4; j++){
971
                    s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
972
                    s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
973
                }
974
            }else{
975
                s->mv_type = MV_TYPE_16X16;
976
                s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
977
                s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
978
            }
979

    
980
            s->dsp.clear_blocks(s->block[0]);
981

    
982
            s->mb_x= mb_x;
983
            s->mb_y= mb_y;
984
            decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
985
        }
986
    }
987

    
988
    /* guess MVs */
989
    if(s->pict_type==AV_PICTURE_TYPE_B){
990
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
991
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
992
                int xy= mb_x*2 + mb_y*2*s->b8_stride;
993
                const int mb_xy= mb_x + mb_y * s->mb_stride;
994
                const int mb_type= s->current_picture.mb_type[mb_xy];
995
                error= s->error_status_table[mb_xy];
996

    
997
                if(IS_INTRA(mb_type)) continue;
998
                if(!(error&MV_ERROR)) continue;           //inter with undamaged MV
999
                if(!(error&AC_ERROR)) continue;           //undamaged inter
1000

    
1001
                s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
1002
                if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
1003
                if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
1004
                s->mb_intra=0;
1005
                s->mv_type = MV_TYPE_16X16;
1006
                s->mb_skipped=0;
1007

    
1008
                if(s->pp_time){
1009
                    int time_pp= s->pp_time;
1010
                    int time_pb= s->pb_time;
1011

    
1012
                    // FIXME await_progress here
1013
                    s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
1014
                    s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
1015
                    s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
1016
                    s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
1017
                }else{
1018
                    s->mv[0][0][0]= 0;
1019
                    s->mv[0][0][1]= 0;
1020
                    s->mv[1][0][0]= 0;
1021
                    s->mv[1][0][1]= 0;
1022
                }
1023

    
1024
                s->dsp.clear_blocks(s->block[0]);
1025
                s->mb_x= mb_x;
1026
                s->mb_y= mb_y;
1027
                decode_mb(s, 0);
1028
            }
1029
        }
1030
    }else
1031
        guess_mv(s);
1032

    
1033
    /* the filters below are not XvMC compatible, skip them */
1034
    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1035
        goto ec_clean;
1036
    /* fill DC for inter blocks */
1037
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
1038
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
1039
            int dc, dcu, dcv, y, n;
1040
            int16_t *dc_ptr;
1041
            uint8_t *dest_y, *dest_cb, *dest_cr;
1042
            const int mb_xy= mb_x + mb_y * s->mb_stride;
1043
            const int mb_type= s->current_picture.mb_type[mb_xy];
1044

    
1045
            error= s->error_status_table[mb_xy];
1046

    
1047
            if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1048
//            if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
1049

    
1050
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1051
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
1052
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
1053

    
1054
            dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1055
            for(n=0; n<4; n++){
1056
                dc=0;
1057
                for(y=0; y<8; y++){
1058
                    int x;
1059
                    for(x=0; x<8; x++){
1060
                       dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1061
                    }
1062
                }
1063
                dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1064
            }
1065

    
1066
            dcu=dcv=0;
1067
            for(y=0; y<8; y++){
1068
                int x;
1069
                for(x=0; x<8; x++){
1070
                    dcu+=dest_cb[x + y*(s->uvlinesize)];
1071
                    dcv+=dest_cr[x + y*(s->uvlinesize)];
1072
                }
1073
            }
1074
            s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1075
            s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1076
        }
1077
    }
1078
#if 1
1079
    /* guess DC for damaged blocks */
1080
    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1081
    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1082
    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1083
#endif
1084
    /* filter luma DC */
1085
    filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1086

    
1087
#if 1
1088
    /* render DC only intra */
1089
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
1090
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
1091
            uint8_t *dest_y, *dest_cb, *dest_cr;
1092
            const int mb_xy= mb_x + mb_y * s->mb_stride;
1093
            const int mb_type= s->current_picture.mb_type[mb_xy];
1094

    
1095
            error= s->error_status_table[mb_xy];
1096

    
1097
            if(IS_INTER(mb_type)) continue;
1098
            if(!(error&AC_ERROR)) continue;              //undamaged
1099

    
1100
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1101
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
1102
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
1103

    
1104
            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1105
        }
1106
    }
1107
#endif
1108

    
1109
    if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1110
        /* filter horizontal block boundaries */
1111
        h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1112
        h_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1113
        h_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1114

    
1115
        /* filter vertical block boundaries */
1116
        v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1117
        v_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1118
        v_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1119
    }
1120

    
1121
ec_clean:
1122
    /* clean a few tables */
1123
    for(i=0; i<s->mb_num; i++){
1124
        const int mb_xy= s->mb_index2xy[i];
1125
        int error= s->error_status_table[mb_xy];
1126

    
1127
        if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
1128
            s->mbskip_table[mb_xy]=0;
1129
        }
1130
        s->mbintra_table[mb_xy]=1;
1131
    }
1132
}