~gma500/+junk/emgd160

« back to all changes in this revision

Viewing changes to mplayer-vaapi/ffmpeg/libavcodec/error_resilience.c

  • Committer: Luca Forina
  • Date: 2011-05-03 09:34:53 UTC
  • Revision ID: luca.forina@gmail.com-20110503093453-p1l4o1ck3g67vrha
added mplayer-vaapi

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
    }
 
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->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
 
763
       s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
 
764
 
 
765
    if(s->current_picture.motion_val[0] == NULL){
 
766
        av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
 
767
 
 
768
        for(i=0; i<2; i++){
 
769
            pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
 
770
            pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
 
771
            pic->motion_val[i]= pic->motion_val_base[i]+4;
 
772
        }
 
773
        pic->motion_subsample_log2= 3;
 
774
        s->current_picture= *s->current_picture_ptr;
 
775
    }
 
776
 
 
777
    if(s->avctx->debug&FF_DEBUG_ER){
 
778
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
 
779
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
 
780
                int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
 
781
 
 
782
                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
 
783
            }
 
784
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
 
785
        }
 
786
    }
 
787
 
 
788
#if 1
 
789
    /* handle overlapping slices */
 
790
    for(error_type=1; error_type<=3; error_type++){
 
791
        int end_ok=0;
 
792
 
 
793
        for(i=s->mb_num-1; i>=0; i--){
 
794
            const int mb_xy= s->mb_index2xy[i];
 
795
            int error= s->error_status_table[mb_xy];
 
796
 
 
797
            if(error&(1<<error_type))
 
798
                end_ok=1;
 
799
            if(error&(8<<error_type))
 
800
                end_ok=1;
 
801
 
 
802
            if(!end_ok)
 
803
                s->error_status_table[mb_xy]|= 1<<error_type;
 
804
 
 
805
            if(error&VP_START)
 
806
                end_ok=0;
 
807
        }
 
808
    }
 
809
#endif
 
810
#if 1
 
811
    /* handle slices with partitions of different length */
 
812
    if(s->partitioned_frame){
 
813
        int end_ok=0;
 
814
 
 
815
        for(i=s->mb_num-1; i>=0; i--){
 
816
            const int mb_xy= s->mb_index2xy[i];
 
817
            int error= s->error_status_table[mb_xy];
 
818
 
 
819
            if(error&AC_END)
 
820
                end_ok=0;
 
821
            if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
 
822
                end_ok=1;
 
823
 
 
824
            if(!end_ok)
 
825
                s->error_status_table[mb_xy]|= AC_ERROR;
 
826
 
 
827
            if(error&VP_START)
 
828
                end_ok=0;
 
829
        }
 
830
    }
 
831
#endif
 
832
    /* handle missing slices */
 
833
    if(s->error_recognition>=4){
 
834
        int end_ok=1;
 
835
 
 
836
        for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
 
837
            const int mb_xy= s->mb_index2xy[i];
 
838
            int error1= s->error_status_table[mb_xy  ];
 
839
            int error2= s->error_status_table[s->mb_index2xy[i+1]];
 
840
 
 
841
            if(error1&VP_START)
 
842
                end_ok=1;
 
843
 
 
844
            if(   error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
 
845
               && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
 
846
               && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
 
847
                end_ok=0;
 
848
            }
 
849
 
 
850
            if(!end_ok)
 
851
                s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
 
852
        }
 
853
    }
 
854
 
 
855
#if 1
 
856
    /* backward mark errors */
 
857
    distance=9999999;
 
858
    for(error_type=1; error_type<=3; error_type++){
 
859
        for(i=s->mb_num-1; i>=0; i--){
 
860
            const int mb_xy= s->mb_index2xy[i];
 
861
            int error= s->error_status_table[mb_xy];
 
862
 
 
863
            if(!s->mbskip_table[mb_xy]) //FIXME partition specific
 
864
                distance++;
 
865
            if(error&(1<<error_type))
 
866
                distance= 0;
 
867
 
 
868
            if(s->partitioned_frame){
 
869
                if(distance < threshold_part[error_type-1])
 
870
                    s->error_status_table[mb_xy]|= 1<<error_type;
 
871
            }else{
 
872
                if(distance < threshold)
 
873
                    s->error_status_table[mb_xy]|= 1<<error_type;
 
874
            }
 
875
 
 
876
            if(error&VP_START)
 
877
                distance= 9999999;
 
878
        }
 
879
    }
 
880
#endif
 
881
 
 
882
    /* forward mark errors */
 
883
    error=0;
 
884
    for(i=0; i<s->mb_num; i++){
 
885
        const int mb_xy= s->mb_index2xy[i];
 
886
        int old_error= s->error_status_table[mb_xy];
 
887
 
 
888
        if(old_error&VP_START)
 
889
            error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
 
890
        else{
 
891
            error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
 
892
            s->error_status_table[mb_xy]|= error;
 
893
        }
 
894
    }
 
895
#if 1
 
896
    /* handle not partitioned case */
 
897
    if(!s->partitioned_frame){
 
898
        for(i=0; i<s->mb_num; i++){
 
899
            const int mb_xy= s->mb_index2xy[i];
 
900
            error= s->error_status_table[mb_xy];
 
901
            if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
 
902
                error|= AC_ERROR|DC_ERROR|MV_ERROR;
 
903
            s->error_status_table[mb_xy]= error;
 
904
        }
 
905
    }
 
906
#endif
 
907
 
 
908
    dc_error= ac_error= mv_error=0;
 
909
    for(i=0; i<s->mb_num; i++){
 
910
        const int mb_xy= s->mb_index2xy[i];
 
911
        error= s->error_status_table[mb_xy];
 
912
        if(error&DC_ERROR) dc_error ++;
 
913
        if(error&AC_ERROR) ac_error ++;
 
914
        if(error&MV_ERROR) mv_error ++;
 
915
    }
 
916
    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
 
917
 
 
918
    is_intra_likely= is_intra_more_likely(s);
 
919
 
 
920
    /* set unknown mb-type to most likely */
 
921
    for(i=0; i<s->mb_num; i++){
 
922
        const int mb_xy= s->mb_index2xy[i];
 
923
        error= s->error_status_table[mb_xy];
 
924
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
 
925
            continue;
 
926
 
 
927
        if(is_intra_likely)
 
928
            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
 
929
        else
 
930
            s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
 
931
    }
 
932
 
 
933
    // change inter to intra blocks if no reference frames are available
 
934
    if (!s->last_picture.data[0] && !s->next_picture.data[0])
 
935
        for(i=0; i<s->mb_num; i++){
 
936
            const int mb_xy= s->mb_index2xy[i];
 
937
            if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
 
938
                s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
 
939
        }
 
940
 
 
941
    /* handle inter blocks with damaged AC */
 
942
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
 
943
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
 
944
            const int mb_xy= mb_x + mb_y * s->mb_stride;
 
945
            const int mb_type= s->current_picture.mb_type[mb_xy];
 
946
            int dir = !s->last_picture.data[0];
 
947
            error= s->error_status_table[mb_xy];
 
948
 
 
949
            if(IS_INTRA(mb_type)) continue; //intra
 
950
            if(error&MV_ERROR) continue;              //inter with damaged MV
 
951
            if(!(error&AC_ERROR)) continue;           //undamaged inter
 
952
 
 
953
            s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
 
954
            s->mb_intra=0;
 
955
            s->mb_skipped=0;
 
956
            if(IS_8X8(mb_type)){
 
957
                int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
 
958
                int j;
 
959
                s->mv_type = MV_TYPE_8X8;
 
960
                for(j=0; j<4; j++){
 
961
                    s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
 
962
                    s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
 
963
                }
 
964
            }else{
 
965
                s->mv_type = MV_TYPE_16X16;
 
966
                s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
 
967
                s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
 
968
            }
 
969
 
 
970
            s->dsp.clear_blocks(s->block[0]);
 
971
 
 
972
            s->mb_x= mb_x;
 
973
            s->mb_y= mb_y;
 
974
            decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
 
975
        }
 
976
    }
 
977
 
 
978
    /* guess MVs */
 
979
    if(s->pict_type==FF_B_TYPE){
 
980
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
 
981
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
 
982
                int xy= mb_x*2 + mb_y*2*s->b8_stride;
 
983
                const int mb_xy= mb_x + mb_y * s->mb_stride;
 
984
                const int mb_type= s->current_picture.mb_type[mb_xy];
 
985
                error= s->error_status_table[mb_xy];
 
986
 
 
987
                if(IS_INTRA(mb_type)) continue;
 
988
                if(!(error&MV_ERROR)) continue;           //inter with undamaged MV
 
989
                if(!(error&AC_ERROR)) continue;           //undamaged inter
 
990
 
 
991
                s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
 
992
                if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
 
993
                if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
 
994
                s->mb_intra=0;
 
995
                s->mv_type = MV_TYPE_16X16;
 
996
                s->mb_skipped=0;
 
997
 
 
998
                if(s->pp_time){
 
999
                    int time_pp= s->pp_time;
 
1000
                    int time_pb= s->pb_time;
 
1001
 
 
1002
                    s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
 
1003
                    s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
 
1004
                    s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
 
1005
                    s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
 
1006
                }else{
 
1007
                    s->mv[0][0][0]= 0;
 
1008
                    s->mv[0][0][1]= 0;
 
1009
                    s->mv[1][0][0]= 0;
 
1010
                    s->mv[1][0][1]= 0;
 
1011
                }
 
1012
 
 
1013
                s->dsp.clear_blocks(s->block[0]);
 
1014
                s->mb_x= mb_x;
 
1015
                s->mb_y= mb_y;
 
1016
                decode_mb(s, 0);
 
1017
            }
 
1018
        }
 
1019
    }else
 
1020
        guess_mv(s);
 
1021
 
 
1022
    /* the filters below are not XvMC compatible, skip them */
 
1023
    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
 
1024
        goto ec_clean;
 
1025
    /* fill DC for inter blocks */
 
1026
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
 
1027
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
 
1028
            int dc, dcu, dcv, y, n;
 
1029
            int16_t *dc_ptr;
 
1030
            uint8_t *dest_y, *dest_cb, *dest_cr;
 
1031
            const int mb_xy= mb_x + mb_y * s->mb_stride;
 
1032
            const int mb_type= s->current_picture.mb_type[mb_xy];
 
1033
 
 
1034
            error= s->error_status_table[mb_xy];
 
1035
 
 
1036
            if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
 
1037
//            if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
 
1038
 
 
1039
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
 
1040
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
 
1041
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
 
1042
 
 
1043
            dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
 
1044
            for(n=0; n<4; n++){
 
1045
                dc=0;
 
1046
                for(y=0; y<8; y++){
 
1047
                    int x;
 
1048
                    for(x=0; x<8; x++){
 
1049
                       dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
 
1050
                    }
 
1051
                }
 
1052
                dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
 
1053
            }
 
1054
 
 
1055
            dcu=dcv=0;
 
1056
            for(y=0; y<8; y++){
 
1057
                int x;
 
1058
                for(x=0; x<8; x++){
 
1059
                    dcu+=dest_cb[x + y*(s->uvlinesize)];
 
1060
                    dcv+=dest_cr[x + y*(s->uvlinesize)];
 
1061
                }
 
1062
            }
 
1063
            s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
 
1064
            s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
 
1065
        }
 
1066
    }
 
1067
#if 1
 
1068
    /* guess DC for damaged blocks */
 
1069
    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
 
1070
    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
 
1071
    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
 
1072
#endif
 
1073
    /* filter luma DC */
 
1074
    filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
 
1075
 
 
1076
#if 1
 
1077
    /* render DC only intra */
 
1078
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
 
1079
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
 
1080
            uint8_t *dest_y, *dest_cb, *dest_cr;
 
1081
            const int mb_xy= mb_x + mb_y * s->mb_stride;
 
1082
            const int mb_type= s->current_picture.mb_type[mb_xy];
 
1083
 
 
1084
            error= s->error_status_table[mb_xy];
 
1085
 
 
1086
            if(IS_INTER(mb_type)) continue;
 
1087
            if(!(error&AC_ERROR)) continue;              //undamaged
 
1088
 
 
1089
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
 
1090
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
 
1091
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
 
1092
 
 
1093
            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
 
1094
        }
 
1095
    }
 
1096
#endif
 
1097
 
 
1098
    if(s->avctx->error_concealment&FF_EC_DEBLOCK){
 
1099
        /* filter horizontal block boundaries */
 
1100
        h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
 
1101
        h_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
 
1102
        h_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
 
1103
 
 
1104
        /* filter vertical block boundaries */
 
1105
        v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
 
1106
        v_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
 
1107
        v_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
 
1108
    }
 
1109
 
 
1110
ec_clean:
 
1111
    /* clean a few tables */
 
1112
    for(i=0; i<s->mb_num; i++){
 
1113
        const int mb_xy= s->mb_index2xy[i];
 
1114
        int error= s->error_status_table[mb_xy];
 
1115
 
 
1116
        if(s->pict_type!=FF_B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
 
1117
            s->mbskip_table[mb_xy]=0;
 
1118
        }
 
1119
        s->mbintra_table[mb_xy]=1;
 
1120
    }
 
1121
}