Statistics
| Branch: | Revision:

ffmpeg / libavcodec / error_resilience.c @ 2912e87a

History | View | Annotate | Download (42.8 KB)

1
/*
2
 * Error resilience / concealment
3
 *
4
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5
 *
6
 * This file is part of Libav.
7
 *
8
 * Libav 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
 * Libav 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 Libav; 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
    }
385

    
386
    if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
387
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
388
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
389
                const int mb_xy= mb_x + mb_y*s->mb_stride;
390

    
391
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))  continue;
392
                if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
393

    
394
                s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
395
                s->mb_intra=0;
396
                s->mv_type = MV_TYPE_16X16;
397
                s->mb_skipped=0;
398

    
399
                s->dsp.clear_blocks(s->block[0]);
400

    
401
                s->mb_x= mb_x;
402
                s->mb_y= mb_y;
403
                s->mv[0][0][0]= 0;
404
                s->mv[0][0][1]= 0;
405
                decode_mb(s, 0);
406
            }
407
        }
408
        return;
409
    }
410

    
411
    for(depth=0;; depth++){
412
        int changed, pass, none_left;
413

    
414
        none_left=1;
415
        changed=1;
416
        for(pass=0; (changed || pass<2) && pass<10; pass++){
417
            int mb_x, mb_y;
418
int score_sum=0;
419

    
420
            changed=0;
421
            for(mb_y=0; mb_y<s->mb_height; mb_y++){
422
                for(mb_x=0; mb_x<s->mb_width; mb_x++){
423
                    const int mb_xy= mb_x + mb_y*s->mb_stride;
424
                    int mv_predictor[8][2]={{0}};
425
                    int ref[8]={0};
426
                    int pred_count=0;
427
                    int j;
428
                    int best_score=256*256*256*64;
429
                    int best_pred=0;
430
                    const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
431
                    int prev_x= s->current_picture.motion_val[0][mot_index][0];
432
                    int prev_y= s->current_picture.motion_val[0][mot_index][1];
433

    
434
                    if((mb_x^mb_y^pass)&1) continue;
435

    
436
                    if(fixed[mb_xy]==MV_FROZEN) continue;
437
                    assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
438
                    assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
439

    
440
                    j=0;
441
                    if(mb_x>0           && fixed[mb_xy-1        ]==MV_FROZEN) j=1;
442
                    if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_FROZEN) j=1;
443
                    if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
444
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
445
                    if(j==0) continue;
446

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

    
454
                    none_left=0;
455

    
456
                    if(mb_x>0 && fixed[mb_xy-1]){
457
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
458
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
459
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy-1)];
460
                        pred_count++;
461
                    }
462
                    if(mb_x+1<mb_width && fixed[mb_xy+1]){
463
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
464
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
465
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy+1)];
466
                        pred_count++;
467
                    }
468
                    if(mb_y>0 && fixed[mb_xy-mb_stride]){
469
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
470
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
471
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)];
472
                        pred_count++;
473
                    }
474
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
475
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
476
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
477
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)];
478
                        pred_count++;
479
                    }
480
                    if(pred_count==0) continue;
481

    
482
                    if(pred_count>1){
483
                        int sum_x=0, sum_y=0, sum_r=0;
484
                        int max_x, max_y, min_x, min_y, max_r, min_r;
485

    
486
                        for(j=0; j<pred_count; j++){
487
                            sum_x+= mv_predictor[j][0];
488
                            sum_y+= mv_predictor[j][1];
489
                            sum_r+= ref[j];
490
                            if(j && ref[j] != ref[j-1])
491
                                goto skip_mean_and_median;
492
                        }
493

    
494
                        /* mean */
495
                        mv_predictor[pred_count][0] = sum_x/j;
496
                        mv_predictor[pred_count][1] = sum_y/j;
497
                        ref         [pred_count]    = sum_r/j;
498

    
499
                        /* median */
500
                        if(pred_count>=3){
501
                            min_y= min_x= min_r= 99999;
502
                            max_y= max_x= max_r=-99999;
503
                        }else{
504
                            min_x=min_y=max_x=max_y=min_r=max_r=0;
505
                        }
506
                        for(j=0; j<pred_count; j++){
507
                            max_x= FFMAX(max_x, mv_predictor[j][0]);
508
                            max_y= FFMAX(max_y, mv_predictor[j][1]);
509
                            max_r= FFMAX(max_r, ref[j]);
510
                            min_x= FFMIN(min_x, mv_predictor[j][0]);
511
                            min_y= FFMIN(min_y, mv_predictor[j][1]);
512
                            min_r= FFMIN(min_r, ref[j]);
513
                        }
514
                        mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
515
                        mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
516
                        ref         [pred_count+1]    = sum_r - max_r - min_r;
517

    
518
                        if(pred_count==4){
519
                            mv_predictor[pred_count+1][0] /= 2;
520
                            mv_predictor[pred_count+1][1] /= 2;
521
                            ref         [pred_count+1]    /= 2;
522
                        }
523
                        pred_count+=2;
524
                    }
525
skip_mean_and_median:
526

    
527
                    /* zero MV */
528
                    pred_count++;
529

    
530
                    /* last MV */
531
                    mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
532
                    mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
533
                    ref         [pred_count]   = s->current_picture.ref_index[0][4*mb_xy];
534
                    pred_count++;
535

    
536
                    s->mv_dir = MV_DIR_FORWARD;
537
                    s->mb_intra=0;
538
                    s->mv_type = MV_TYPE_16X16;
539
                    s->mb_skipped=0;
540

    
541
                    s->dsp.clear_blocks(s->block[0]);
542

    
543
                    s->mb_x= mb_x;
544
                    s->mb_y= mb_y;
545

    
546
                    for(j=0; j<pred_count; j++){
547
                        int score=0;
548
                        uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
549

    
550
                        s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
551
                        s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
552

    
553
                        if(ref[j]<0) //predictor intra or otherwise not available
554
                            continue;
555

    
556
                        decode_mb(s, ref[j]);
557

    
558
                        if(mb_x>0 && fixed[mb_xy-1]){
559
                            int k;
560
                            for(k=0; k<16; k++)
561
                                score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize   ]);
562
                        }
563
                        if(mb_x+1<mb_width && fixed[mb_xy+1]){
564
                            int k;
565
                            for(k=0; k<16; k++)
566
                                score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
567
                        }
568
                        if(mb_y>0 && fixed[mb_xy-mb_stride]){
569
                            int k;
570
                            for(k=0; k<16; k++)
571
                                score += FFABS(src[k-s->linesize   ]-src[k               ]);
572
                        }
573
                        if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
574
                            int k;
575
                            for(k=0; k<16; k++)
576
                                score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
577
                        }
578

    
579
                        if(score <= best_score){ // <= will favor the last MV
580
                            best_score= score;
581
                            best_pred= j;
582
                        }
583
                    }
584
score_sum+= best_score;
585
                    s->mv[0][0][0]= mv_predictor[best_pred][0];
586
                    s->mv[0][0][1]= mv_predictor[best_pred][1];
587

    
588
                    for(i=0; i<mot_step; i++)
589
                        for(j=0; j<mot_step; j++){
590
                            s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
591
                            s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
592
                        }
593

    
594
                    decode_mb(s, ref[best_pred]);
595

    
596

    
597
                    if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
598
                        fixed[mb_xy]=MV_CHANGED;
599
                        changed++;
600
                    }else
601
                        fixed[mb_xy]=MV_UNCHANGED;
602
                }
603
            }
604

    
605
//            printf(".%d/%d", changed, score_sum); fflush(stdout);
606
        }
607

    
608
        if(none_left)
609
            return;
610

    
611
        for(i=0; i<s->mb_num; i++){
612
            int mb_xy= s->mb_index2xy[i];
613
            if(fixed[mb_xy])
614
                fixed[mb_xy]=MV_FROZEN;
615
        }
616
//        printf(":"); fflush(stdout);
617
    }
618
}
619

    
620
static int is_intra_more_likely(MpegEncContext *s){
621
    int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
622

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

    
625
    undamaged_count=0;
626
    for(i=0; i<s->mb_num; i++){
627
        const int mb_xy= s->mb_index2xy[i];
628
        const int error= s->error_status_table[mb_xy];
629
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
630
            undamaged_count++;
631
    }
632

    
633
    if(s->codec_id == CODEC_ID_H264){
634
        H264Context *h= (void*)s;
635
        if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0])
636
            return 1;
637
    }
638

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

    
641
    //prevent dsp.sad() check, that requires access to the image
642
    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == FF_I_TYPE)
643
        return 1;
644

    
645
    skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
646
    is_intra_likely=0;
647

    
648
    j=0;
649
    for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
650
        for(mb_x= 0; mb_x<s->mb_width; mb_x++){
651
            int error;
652
            const int mb_xy= mb_x + mb_y*s->mb_stride;
653

    
654
            error= s->error_status_table[mb_xy];
655
            if((error&DC_ERROR) && (error&MV_ERROR))
656
                continue; //skip damaged
657

    
658
            j++;
659
            if((j%skip_amount) != 0) continue; //skip a few to speed things up
660

    
661
            if(s->pict_type==FF_I_TYPE){
662
                uint8_t *mb_ptr     = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
663
                uint8_t *last_mb_ptr= s->last_picture.data   [0] + mb_x*16 + mb_y*16*s->linesize;
664

    
665
                is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);
666
                is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
667
            }else{
668
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
669
                   is_intra_likely++;
670
                else
671
                   is_intra_likely--;
672
            }
673
        }
674
    }
675
//printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
676
    return is_intra_likely > 0;
677
}
678

    
679
void ff_er_frame_start(MpegEncContext *s){
680
    if(!s->error_recognition) return;
681

    
682
    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));
683
    s->error_count= 3*s->mb_num;
684
}
685

    
686
/**
687
 * adds a slice.
688
 * @param endx x component of the last macroblock, can be -1 for the last of the previous line
689
 * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
690
 *               error of the same type occurred
691
 */
692
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
693
    const int start_i= av_clip(startx + starty * s->mb_width    , 0, s->mb_num-1);
694
    const int end_i  = av_clip(endx   + endy   * s->mb_width    , 0, s->mb_num);
695
    const int start_xy= s->mb_index2xy[start_i];
696
    const int end_xy  = s->mb_index2xy[end_i];
697
    int mask= -1;
698

    
699
    if(s->avctx->hwaccel)
700
        return;
701

    
702
    if(start_i > end_i || start_xy > end_xy){
703
        av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
704
        return;
705
    }
706

    
707
    if(!s->error_recognition) return;
708

    
709
    mask &= ~VP_START;
710
    if(status & (AC_ERROR|AC_END)){
711
        mask &= ~(AC_ERROR|AC_END);
712
        s->error_count -= end_i - start_i + 1;
713
    }
714
    if(status & (DC_ERROR|DC_END)){
715
        mask &= ~(DC_ERROR|DC_END);
716
        s->error_count -= end_i - start_i + 1;
717
    }
718
    if(status & (MV_ERROR|MV_END)){
719
        mask &= ~(MV_ERROR|MV_END);
720
        s->error_count -= end_i - start_i + 1;
721
    }
722

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

    
725
    if(mask == ~0x7F){
726
        memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
727
    }else{
728
        int i;
729
        for(i=start_xy; i<end_xy; i++){
730
            s->error_status_table[ i ] &= mask;
731
        }
732
    }
733

    
734
    if(end_i == s->mb_num)
735
        s->error_count= INT_MAX;
736
    else{
737
        s->error_status_table[end_xy] &= mask;
738
        s->error_status_table[end_xy] |= status;
739
    }
740

    
741
    s->error_status_table[start_xy] |= VP_START;
742

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

    
746
        prev_status &= ~ VP_START;
747
        if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
748
    }
749
}
750

    
751
void ff_er_frame_end(MpegEncContext *s){
752
    int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
753
    int distance;
754
    int threshold_part[4]= {100,100,100};
755
    int threshold= 50;
756
    int is_intra_likely;
757
    int size = s->b8_stride * 2 * s->mb_height;
758
    Picture *pic= s->current_picture_ptr;
759

    
760
    if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
761
       s->avctx->hwaccel ||
762
       s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
763
       s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
764
       s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
765

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

    
769
        for(i=0; i<2; i++){
770
            pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
771
            pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
772
            pic->motion_val[i]= pic->motion_val_base[i]+4;
773
        }
774
        pic->motion_subsample_log2= 3;
775
        s->current_picture= *s->current_picture_ptr;
776
    }
777

    
778
    if(s->avctx->debug&FF_DEBUG_ER){
779
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
780
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
781
                int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
782

    
783
                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
784
            }
785
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
786
        }
787
    }
788

    
789
#if 1
790
    /* handle overlapping slices */
791
    for(error_type=1; error_type<=3; error_type++){
792
        int end_ok=0;
793

    
794
        for(i=s->mb_num-1; i>=0; i--){
795
            const int mb_xy= s->mb_index2xy[i];
796
            int error= s->error_status_table[mb_xy];
797

    
798
            if(error&(1<<error_type))
799
                end_ok=1;
800
            if(error&(8<<error_type))
801
                end_ok=1;
802

    
803
            if(!end_ok)
804
                s->error_status_table[mb_xy]|= 1<<error_type;
805

    
806
            if(error&VP_START)
807
                end_ok=0;
808
        }
809
    }
810
#endif
811
#if 1
812
    /* handle slices with partitions of different length */
813
    if(s->partitioned_frame){
814
        int end_ok=0;
815

    
816
        for(i=s->mb_num-1; i>=0; i--){
817
            const int mb_xy= s->mb_index2xy[i];
818
            int error= s->error_status_table[mb_xy];
819

    
820
            if(error&AC_END)
821
                end_ok=0;
822
            if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
823
                end_ok=1;
824

    
825
            if(!end_ok)
826
                s->error_status_table[mb_xy]|= AC_ERROR;
827

    
828
            if(error&VP_START)
829
                end_ok=0;
830
        }
831
    }
832
#endif
833
    /* handle missing slices */
834
    if(s->error_recognition>=4){
835
        int end_ok=1;
836

    
837
        for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
838
            const int mb_xy= s->mb_index2xy[i];
839
            int error1= s->error_status_table[mb_xy  ];
840
            int error2= s->error_status_table[s->mb_index2xy[i+1]];
841

    
842
            if(error1&VP_START)
843
                end_ok=1;
844

    
845
            if(   error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
846
               && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
847
               && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
848
                end_ok=0;
849
            }
850

    
851
            if(!end_ok)
852
                s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
853
        }
854
    }
855

    
856
#if 1
857
    /* backward mark errors */
858
    distance=9999999;
859
    for(error_type=1; error_type<=3; error_type++){
860
        for(i=s->mb_num-1; i>=0; i--){
861
            const int mb_xy= s->mb_index2xy[i];
862
            int error= s->error_status_table[mb_xy];
863

    
864
            if(!s->mbskip_table[mb_xy]) //FIXME partition specific
865
                distance++;
866
            if(error&(1<<error_type))
867
                distance= 0;
868

    
869
            if(s->partitioned_frame){
870
                if(distance < threshold_part[error_type-1])
871
                    s->error_status_table[mb_xy]|= 1<<error_type;
872
            }else{
873
                if(distance < threshold)
874
                    s->error_status_table[mb_xy]|= 1<<error_type;
875
            }
876

    
877
            if(error&VP_START)
878
                distance= 9999999;
879
        }
880
    }
881
#endif
882

    
883
    /* forward mark errors */
884
    error=0;
885
    for(i=0; i<s->mb_num; i++){
886
        const int mb_xy= s->mb_index2xy[i];
887
        int old_error= s->error_status_table[mb_xy];
888

    
889
        if(old_error&VP_START)
890
            error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
891
        else{
892
            error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
893
            s->error_status_table[mb_xy]|= error;
894
        }
895
    }
896
#if 1
897
    /* handle not partitioned case */
898
    if(!s->partitioned_frame){
899
        for(i=0; i<s->mb_num; i++){
900
            const int mb_xy= s->mb_index2xy[i];
901
            error= s->error_status_table[mb_xy];
902
            if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
903
                error|= AC_ERROR|DC_ERROR|MV_ERROR;
904
            s->error_status_table[mb_xy]= error;
905
        }
906
    }
907
#endif
908

    
909
    dc_error= ac_error= mv_error=0;
910
    for(i=0; i<s->mb_num; i++){
911
        const int mb_xy= s->mb_index2xy[i];
912
        error= s->error_status_table[mb_xy];
913
        if(error&DC_ERROR) dc_error ++;
914
        if(error&AC_ERROR) ac_error ++;
915
        if(error&MV_ERROR) mv_error ++;
916
    }
917
    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
918

    
919
    is_intra_likely= is_intra_more_likely(s);
920

    
921
    /* set unknown mb-type to most likely */
922
    for(i=0; i<s->mb_num; i++){
923
        const int mb_xy= s->mb_index2xy[i];
924
        error= s->error_status_table[mb_xy];
925
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
926
            continue;
927

    
928
        if(is_intra_likely)
929
            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
930
        else
931
            s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
932
    }
933

    
934
    // change inter to intra blocks if no reference frames are available
935
    if (!s->last_picture.data[0] && !s->next_picture.data[0])
936
        for(i=0; i<s->mb_num; i++){
937
            const int mb_xy= s->mb_index2xy[i];
938
            if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
939
                s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
940
        }
941

    
942
    /* handle inter blocks with damaged AC */
943
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
944
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
945
            const int mb_xy= mb_x + mb_y * s->mb_stride;
946
            const int mb_type= s->current_picture.mb_type[mb_xy];
947
            int dir = !s->last_picture.data[0];
948
            error= s->error_status_table[mb_xy];
949

    
950
            if(IS_INTRA(mb_type)) continue; //intra
951
            if(error&MV_ERROR) continue;              //inter with damaged MV
952
            if(!(error&AC_ERROR)) continue;           //undamaged inter
953

    
954
            s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
955
            s->mb_intra=0;
956
            s->mb_skipped=0;
957
            if(IS_8X8(mb_type)){
958
                int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
959
                int j;
960
                s->mv_type = MV_TYPE_8X8;
961
                for(j=0; j<4; j++){
962
                    s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
963
                    s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
964
                }
965
            }else{
966
                s->mv_type = MV_TYPE_16X16;
967
                s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
968
                s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
969
            }
970

    
971
            s->dsp.clear_blocks(s->block[0]);
972

    
973
            s->mb_x= mb_x;
974
            s->mb_y= mb_y;
975
            decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
976
        }
977
    }
978

    
979
    /* guess MVs */
980
    if(s->pict_type==FF_B_TYPE){
981
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
982
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
983
                int xy= mb_x*2 + mb_y*2*s->b8_stride;
984
                const int mb_xy= mb_x + mb_y * s->mb_stride;
985
                const int mb_type= s->current_picture.mb_type[mb_xy];
986
                error= s->error_status_table[mb_xy];
987

    
988
                if(IS_INTRA(mb_type)) continue;
989
                if(!(error&MV_ERROR)) continue;           //inter with undamaged MV
990
                if(!(error&AC_ERROR)) continue;           //undamaged inter
991

    
992
                s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
993
                if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
994
                if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
995
                s->mb_intra=0;
996
                s->mv_type = MV_TYPE_16X16;
997
                s->mb_skipped=0;
998

    
999
                if(s->pp_time){
1000
                    int time_pp= s->pp_time;
1001
                    int time_pb= s->pb_time;
1002

    
1003
                    s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
1004
                    s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
1005
                    s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
1006
                    s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
1007
                }else{
1008
                    s->mv[0][0][0]= 0;
1009
                    s->mv[0][0][1]= 0;
1010
                    s->mv[1][0][0]= 0;
1011
                    s->mv[1][0][1]= 0;
1012
                }
1013

    
1014
                s->dsp.clear_blocks(s->block[0]);
1015
                s->mb_x= mb_x;
1016
                s->mb_y= mb_y;
1017
                decode_mb(s, 0);
1018
            }
1019
        }
1020
    }else
1021
        guess_mv(s);
1022

    
1023
    /* the filters below are not XvMC compatible, skip them */
1024
    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1025
        goto ec_clean;
1026
    /* fill DC for inter blocks */
1027
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
1028
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
1029
            int dc, dcu, dcv, y, n;
1030
            int16_t *dc_ptr;
1031
            uint8_t *dest_y, *dest_cb, *dest_cr;
1032
            const int mb_xy= mb_x + mb_y * s->mb_stride;
1033
            const int mb_type= s->current_picture.mb_type[mb_xy];
1034

    
1035
            error= s->error_status_table[mb_xy];
1036

    
1037
            if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1038
//            if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
1039

    
1040
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1041
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
1042
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
1043

    
1044
            dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1045
            for(n=0; n<4; n++){
1046
                dc=0;
1047
                for(y=0; y<8; y++){
1048
                    int x;
1049
                    for(x=0; x<8; x++){
1050
                       dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1051
                    }
1052
                }
1053
                dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1054
            }
1055

    
1056
            dcu=dcv=0;
1057
            for(y=0; y<8; y++){
1058
                int x;
1059
                for(x=0; x<8; x++){
1060
                    dcu+=dest_cb[x + y*(s->uvlinesize)];
1061
                    dcv+=dest_cr[x + y*(s->uvlinesize)];
1062
                }
1063
            }
1064
            s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1065
            s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1066
        }
1067
    }
1068
#if 1
1069
    /* guess DC for damaged blocks */
1070
    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1071
    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1072
    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1073
#endif
1074
    /* filter luma DC */
1075
    filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1076

    
1077
#if 1
1078
    /* render DC only intra */
1079
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
1080
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
1081
            uint8_t *dest_y, *dest_cb, *dest_cr;
1082
            const int mb_xy= mb_x + mb_y * s->mb_stride;
1083
            const int mb_type= s->current_picture.mb_type[mb_xy];
1084

    
1085
            error= s->error_status_table[mb_xy];
1086

    
1087
            if(IS_INTER(mb_type)) continue;
1088
            if(!(error&AC_ERROR)) continue;              //undamaged
1089

    
1090
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1091
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
1092
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
1093

    
1094
            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1095
        }
1096
    }
1097
#endif
1098

    
1099
    if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1100
        /* filter horizontal block boundaries */
1101
        h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1102
        h_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1103
        h_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1104

    
1105
        /* filter vertical block boundaries */
1106
        v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1107
        v_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1108
        v_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1109
    }
1110

    
1111
ec_clean:
1112
    /* clean a few tables */
1113
    for(i=0; i<s->mb_num; i++){
1114
        const int mb_xy= s->mb_index2xy[i];
1115
        int error= s->error_status_table[mb_xy];
1116

    
1117
        if(s->pict_type!=FF_B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
1118
            s->mbskip_table[mb_xy]=0;
1119
        }
1120
        s->mbintra_table[mb_xy]=1;
1121
    }
1122
}