Statistics
| Branch: | Revision:

ffmpeg / libavcodec / error_resilience.c @ 3732c483

History | View | Annotate | Download (43.4 KB)

1 4d2858de Michael Niedermayer
/*
2
 * Error resilience / concealment
3
 *
4 8f2ab833 Michael Niedermayer
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5 4d2858de Michael Niedermayer
 *
6 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9 4d2858de Michael Niedermayer
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
12 4d2858de Michael Niedermayer
 *
13 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
14 4d2858de Michael Niedermayer
 * 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 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
20 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 4d2858de Michael Niedermayer
 */
22 115329f1 Diego Biurrun
23 983e3246 Michael Niedermayer
/**
24 ba87f080 Diego Biurrun
 * @file
25 983e3246 Michael Niedermayer
 * Error resilience / concealment.
26
 */
27 4d2858de Michael Niedermayer
28 7bc9090a Michael Niedermayer
#include <limits.h>
29 115329f1 Diego Biurrun
30 4d2858de Michael Niedermayer
#include "avcodec.h"
31
#include "dsputil.h"
32
#include "mpegvideo.h"
33 2c4bc23e Michael Niedermayer
#include "h264.h"
34 e5d2bdec Diego Biurrun
#include "rectangle.h"
35 2c4bc23e Michael Niedermayer
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 4d2858de Michael Niedermayer
42 673fc638 Michael Niedermayer
static void decode_mb(MpegEncContext *s, int ref){
43 7d1c3fc1 Michael Niedermayer
    s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize  ) + s->mb_x * 16;
44 f40a7fd3 Michael Niedermayer
    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 7d1c3fc1 Michael Niedermayer
47 3546fa8d Aurelien Jacobs
    if(CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264){
48 68f0bc7e Michael Niedermayer
        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 673fc638 Michael Niedermayer
        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 68f0bc7e Michael Niedermayer
        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 673fc638 Michael Niedermayer
        assert(ref==0);
61 115329f1 Diego Biurrun
    MPV_decode_mb(s, s->block);
62 68f0bc7e Michael Niedermayer
    }
63 7d1c3fc1 Michael Niedermayer
}
64
65 4d2858de Michael Niedermayer
/**
66 2c4bc23e Michael Niedermayer
 * @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 4d2858de Michael Niedermayer
 * 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 137c8468 Michael Niedermayer
        dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
89 4d2858de Michael Niedermayer
        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 137c8468 Michael Niedermayer
    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 4d2858de Michael Niedermayer
    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 b86216de Måns Rullgård
static void filter181(int16_t *data, int width, int height, int stride){
114 4d2858de Michael Niedermayer
    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 115329f1 Diego Biurrun
123
            dc= - prev_dc
124 4d2858de Michael Niedermayer
                + 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 115329f1 Diego Biurrun
132 4d2858de Michael Niedermayer
    /* 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 115329f1 Diego Biurrun
139
            dc= - prev_dc
140 4d2858de Michael Niedermayer
                + 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 755bfeab Diego Biurrun
 * guess the dc of blocks which do not have an undamaged dc
151 bb270c08 Diego Biurrun
 * @param w     width in 8 pixel blocks
152
 * @param h     height in 8 pixel blocks
153 4d2858de Michael Niedermayer
 */
154 b86216de Måns Rullgård
static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
155 4d2858de Michael Niedermayer
    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 0c1a9eda Zdenek Kabelac
            int64_t guess, weight_sum;
163 115329f1 Diego Biurrun
164 7bc9090a Michael Niedermayer
            mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
165 115329f1 Diego Biurrun
166 4d2858de Michael Niedermayer
            error= s->error_status_table[mb_index];
167 115329f1 Diego Biurrun
168 7bc9090a Michael Niedermayer
            if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
169 4d2858de Michael Niedermayer
            if(!(error&DC_ERROR)) continue;           //dc-ok
170 115329f1 Diego Biurrun
171 4d2858de Michael Niedermayer
            /* right block */
172
            for(j=b_x+1; j<w; j++){
173 7bc9090a Michael Niedermayer
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
174 4d2858de Michael Niedermayer
                int error_j= s->error_status_table[mb_index_j];
175 7bc9090a Michael Niedermayer
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
176 4d2858de Michael Niedermayer
                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 115329f1 Diego Biurrun
183 4d2858de Michael Niedermayer
            /* left block */
184
            for(j=b_x-1; j>=0; j--){
185 7bc9090a Michael Niedermayer
                int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
186 4d2858de Michael Niedermayer
                int error_j= s->error_status_table[mb_index_j];
187 7bc9090a Michael Niedermayer
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
188 4d2858de Michael Niedermayer
                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 7bc9090a Michael Niedermayer
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
198 4d2858de Michael Niedermayer
                int error_j= s->error_status_table[mb_index_j];
199 7bc9090a Michael Niedermayer
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
200 4d2858de Michael Niedermayer
                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 7bc9090a Michael Niedermayer
                int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
210 4d2858de Michael Niedermayer
                int error_j= s->error_status_table[mb_index_j];
211 7bc9090a Michael Niedermayer
                int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
212 4d2858de Michael Niedermayer
                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 115329f1 Diego Biurrun
219 4d2858de Michael Niedermayer
            weight_sum=0;
220
            guess=0;
221
            for(j=0; j<4; j++){
222 0c1a9eda Zdenek Kabelac
                int64_t weight= 256*256*256*16/distance[j];
223
                guess+= weight*(int64_t)color[j];
224 4d2858de Michael Niedermayer
                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 bb270c08 Diego Biurrun
 * @param w     width in 8 pixel blocks
236
 * @param h     height in 8 pixel blocks
237 4d2858de Michael Niedermayer
 */
238 0c1a9eda Zdenek Kabelac
static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
239 bb4fcfa3 Michael Niedermayer
    int b_x, b_y, mvx_stride, mvy_stride;
240 55fde95e Måns Rullgård
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
241 bb4fcfa3 Michael Niedermayer
    set_mv_strides(s, &mvx_stride, &mvy_stride);
242
    mvx_stride >>= is_luma;
243
    mvy_stride *= mvx_stride;
244 4d2858de Michael Niedermayer
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 7bc9090a Michael Niedermayer
            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 4d2858de Michael Niedermayer
            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 bb4fcfa3 Michael Niedermayer
            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 115329f1 Diego Biurrun
258 4d2858de Michael Niedermayer
            if(!(left_damage||right_damage)) continue; // both undamaged
259 115329f1 Diego Biurrun
260
            if(   (!left_intra) && (!right_intra)
261 c26abfa5 Diego Biurrun
               && FFABS(left_mv[0]-right_mv[0]) + FFABS(left_mv[1]+right_mv[1]) < 2) continue;
262 115329f1 Diego Biurrun
263 4d2858de Michael Niedermayer
            for(y=0; y<8; y++){
264
                int a,b,c,d;
265 115329f1 Diego Biurrun
266 4d2858de Michael Niedermayer
                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 115329f1 Diego Biurrun
270 c26abfa5 Diego Biurrun
                d= FFABS(b) - ((FFABS(a) + FFABS(c) + 1)>>1);
271 b8a78f41 Michael Niedermayer
                d= FFMAX(d, 0);
272 4d2858de Michael Niedermayer
                if(b<0) d= -d;
273 115329f1 Diego Biurrun
274 4d2858de Michael Niedermayer
                if(d==0) continue;
275
276
                if(!(left_damage && right_damage))
277
                    d= d*16/9;
278 115329f1 Diego Biurrun
279 4d2858de Michael Niedermayer
                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 bb270c08 Diego Biurrun
 * @param w     width in 8 pixel blocks
299
 * @param h     height in 8 pixel blocks
300 4d2858de Michael Niedermayer
 */
301 0c1a9eda Zdenek Kabelac
static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
302 bb4fcfa3 Michael Niedermayer
    int b_x, b_y, mvx_stride, mvy_stride;
303 55fde95e Måns Rullgård
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
304 bb4fcfa3 Michael Niedermayer
    set_mv_strides(s, &mvx_stride, &mvy_stride);
305
    mvx_stride >>= is_luma;
306
    mvy_stride *= mvx_stride;
307 4d2858de Michael Niedermayer
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 7bc9090a Michael Niedermayer
            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 4d2858de Michael Niedermayer
            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 bb4fcfa3 Michael Niedermayer
            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 115329f1 Diego Biurrun
321 4d2858de Michael Niedermayer
            if(!(top_damage||bottom_damage)) continue; // both undamaged
322 115329f1 Diego Biurrun
323
            if(   (!top_intra) && (!bottom_intra)
324 c26abfa5 Diego Biurrun
               && FFABS(top_mv[0]-bottom_mv[0]) + FFABS(top_mv[1]+bottom_mv[1]) < 2) continue;
325 115329f1 Diego Biurrun
326 4d2858de Michael Niedermayer
            for(x=0; x<8; x++){
327
                int a,b,c,d;
328 115329f1 Diego Biurrun
329 4d2858de Michael Niedermayer
                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 115329f1 Diego Biurrun
333 c26abfa5 Diego Biurrun
                d= FFABS(b) - ((FFABS(a) + FFABS(c)+1)>>1);
334 b8a78f41 Michael Niedermayer
                d= FFMAX(d, 0);
335 4d2858de Michael Niedermayer
                if(b<0) d= -d;
336 115329f1 Diego Biurrun
337 4d2858de Michael Niedermayer
                if(d==0) continue;
338
339
                if(!(top_damage && bottom_damage))
340
                    d= d*16/9;
341 115329f1 Diego Biurrun
342 4d2858de Michael Niedermayer
                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 7bc9090a Michael Niedermayer
    uint8_t fixed[s->mb_stride * s->mb_height];
361 4d2858de Michael Niedermayer
#define MV_FROZEN    3
362
#define MV_CHANGED   2
363
#define MV_UNCHANGED 1
364 7bc9090a Michael Niedermayer
    const int mb_stride = s->mb_stride;
365 4d2858de Michael Niedermayer
    const int mb_width = s->mb_width;
366
    const int mb_height= s->mb_height;
367
    int i, depth, num_avail;
368 2c4bc23e Michael Niedermayer
    int mb_x, mb_y, mot_step, mot_stride;
369
370
    set_mv_strides(s, &mot_step, &mot_stride);
371 115329f1 Diego Biurrun
372 4d2858de Michael Niedermayer
    num_avail=0;
373
    for(i=0; i<s->mb_num; i++){
374 7bc9090a Michael Niedermayer
        const int mb_xy= s->mb_index2xy[ i ];
375 4d2858de Michael Niedermayer
        int f=0;
376 7bc9090a Michael Niedermayer
        int error= s->error_status_table[mb_xy];
377 4d2858de Michael Niedermayer
378 7bc9090a Michael Niedermayer
        if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
379 4d2858de Michael Niedermayer
        if(!(error&MV_ERROR)) f=MV_FROZEN;           //inter with undamaged MV
380 115329f1 Diego Biurrun
381 7bc9090a Michael Niedermayer
        fixed[mb_xy]= f;
382 4d2858de Michael Niedermayer
        if(f==MV_FROZEN)
383
            num_avail++;
384 3732c483 Michael Niedermayer
        else if(s->last_picture.data[0]){
385
            const int mb_y= mb_xy / s->mb_stride;
386
            const int mb_x= mb_xy % s->mb_stride;
387
            const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
388
            s->current_picture.motion_val[0][mot_index][0]= s->last_picture.motion_val[0][mot_index][0];
389
            s->current_picture.motion_val[0][mot_index][1]= s->last_picture.motion_val[0][mot_index][1];
390
            s->current_picture.ref_index[0][4*mb_xy]      = s->last_picture.ref_index[0][4*mb_xy];
391
        }
392 4d2858de Michael Niedermayer
    }
393 115329f1 Diego Biurrun
394 4d2858de Michael Niedermayer
    if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
395
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
396
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
397 7bc9090a Michael Niedermayer
                const int mb_xy= mb_x + mb_y*s->mb_stride;
398 115329f1 Diego Biurrun
399 7bc9090a Michael Niedermayer
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))  continue;
400
                if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
401 4d2858de Michael Niedermayer
402 b6b66760 Reimar Döffinger
                s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
403 4d2858de Michael Niedermayer
                s->mb_intra=0;
404
                s->mv_type = MV_TYPE_16X16;
405 160d679c Mike Melanson
                s->mb_skipped=0;
406 4d2858de Michael Niedermayer
407 bb270c08 Diego Biurrun
                s->dsp.clear_blocks(s->block[0]);
408 4d2858de Michael Niedermayer
409
                s->mb_x= mb_x;
410
                s->mb_y= mb_y;
411
                s->mv[0][0][0]= 0;
412
                s->mv[0][0][1]= 0;
413 673fc638 Michael Niedermayer
                decode_mb(s, 0);
414 4d2858de Michael Niedermayer
            }
415
        }
416
        return;
417
    }
418 115329f1 Diego Biurrun
419 4d2858de Michael Niedermayer
    for(depth=0;; depth++){
420
        int changed, pass, none_left;
421
422
        none_left=1;
423
        changed=1;
424
        for(pass=0; (changed || pass<2) && pass<10; pass++){
425 7bc9090a Michael Niedermayer
            int mb_x, mb_y;
426 4d2858de Michael Niedermayer
int score_sum=0;
427 115329f1 Diego Biurrun
428 4d2858de Michael Niedermayer
            changed=0;
429
            for(mb_y=0; mb_y<s->mb_height; mb_y++){
430
                for(mb_x=0; mb_x<s->mb_width; mb_x++){
431 7bc9090a Michael Niedermayer
                    const int mb_xy= mb_x + mb_y*s->mb_stride;
432 4d2858de Michael Niedermayer
                    int mv_predictor[8][2]={{0}};
433 673fc638 Michael Niedermayer
                    int ref[8]={0};
434 4d2858de Michael Niedermayer
                    int pred_count=0;
435
                    int j;
436
                    int best_score=256*256*256*64;
437
                    int best_pred=0;
438 2c4bc23e Michael Niedermayer
                    const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
439 8d7ec294 Wolfgang Hesseler
                    int prev_x= s->current_picture.motion_val[0][mot_index][0];
440
                    int prev_y= s->current_picture.motion_val[0][mot_index][1];
441 4d2858de Michael Niedermayer
442
                    if((mb_x^mb_y^pass)&1) continue;
443 115329f1 Diego Biurrun
444 7bc9090a Michael Niedermayer
                    if(fixed[mb_xy]==MV_FROZEN) continue;
445
                    assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
446
                    assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
447 115329f1 Diego Biurrun
448 4d2858de Michael Niedermayer
                    j=0;
449 7bc9090a Michael Niedermayer
                    if(mb_x>0           && fixed[mb_xy-1        ]==MV_FROZEN) j=1;
450
                    if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_FROZEN) j=1;
451
                    if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
452
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
453 4d2858de Michael Niedermayer
                    if(j==0) continue;
454
455
                    j=0;
456 7bc9090a Michael Niedermayer
                    if(mb_x>0           && fixed[mb_xy-1        ]==MV_CHANGED) j=1;
457
                    if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_CHANGED) j=1;
458
                    if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
459
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
460 4d2858de Michael Niedermayer
                    if(j==0 && pass>1) continue;
461 115329f1 Diego Biurrun
462 4d2858de Michael Niedermayer
                    none_left=0;
463 115329f1 Diego Biurrun
464 7bc9090a Michael Niedermayer
                    if(mb_x>0 && fixed[mb_xy-1]){
465 2c4bc23e Michael Niedermayer
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
466
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
467 673fc638 Michael Niedermayer
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy-1)];
468 4d2858de Michael Niedermayer
                        pred_count++;
469
                    }
470 7bc9090a Michael Niedermayer
                    if(mb_x+1<mb_width && fixed[mb_xy+1]){
471 2c4bc23e Michael Niedermayer
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
472
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
473 673fc638 Michael Niedermayer
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy+1)];
474 4d2858de Michael Niedermayer
                        pred_count++;
475
                    }
476 7bc9090a Michael Niedermayer
                    if(mb_y>0 && fixed[mb_xy-mb_stride]){
477 2c4bc23e Michael Niedermayer
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
478
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
479 673fc638 Michael Niedermayer
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)];
480 4d2858de Michael Niedermayer
                        pred_count++;
481
                    }
482 7bc9090a Michael Niedermayer
                    if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
483 2c4bc23e Michael Niedermayer
                        mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
484
                        mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
485 673fc638 Michael Niedermayer
                        ref         [pred_count]   = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)];
486 4d2858de Michael Niedermayer
                        pred_count++;
487
                    }
488
                    if(pred_count==0) continue;
489 115329f1 Diego Biurrun
490 4d2858de Michael Niedermayer
                    if(pred_count>1){
491 673fc638 Michael Niedermayer
                        int sum_x=0, sum_y=0, sum_r=0;
492
                        int max_x, max_y, min_x, min_y, max_r, min_r;
493 4d2858de Michael Niedermayer
494
                        for(j=0; j<pred_count; j++){
495
                            sum_x+= mv_predictor[j][0];
496
                            sum_y+= mv_predictor[j][1];
497 673fc638 Michael Niedermayer
                            sum_r+= ref[j];
498 fc4a2d1e Michael Niedermayer
                            if(j && ref[j] != ref[j-1])
499 673fc638 Michael Niedermayer
                                goto skip_mean_and_median;
500 4d2858de Michael Niedermayer
                        }
501 115329f1 Diego Biurrun
502 4d2858de Michael Niedermayer
                        /* mean */
503
                        mv_predictor[pred_count][0] = sum_x/j;
504
                        mv_predictor[pred_count][1] = sum_y/j;
505 673fc638 Michael Niedermayer
                        ref         [pred_count]    = sum_r/j;
506 115329f1 Diego Biurrun
507 4d2858de Michael Niedermayer
                        /* median */
508
                        if(pred_count>=3){
509 673fc638 Michael Niedermayer
                            min_y= min_x= min_r= 99999;
510
                            max_y= max_x= max_r=-99999;
511 4d2858de Michael Niedermayer
                        }else{
512 673fc638 Michael Niedermayer
                            min_x=min_y=max_x=max_y=min_r=max_r=0;
513 4d2858de Michael Niedermayer
                        }
514
                        for(j=0; j<pred_count; j++){
515 b8a78f41 Michael Niedermayer
                            max_x= FFMAX(max_x, mv_predictor[j][0]);
516
                            max_y= FFMAX(max_y, mv_predictor[j][1]);
517 673fc638 Michael Niedermayer
                            max_r= FFMAX(max_r, ref[j]);
518 b8a78f41 Michael Niedermayer
                            min_x= FFMIN(min_x, mv_predictor[j][0]);
519
                            min_y= FFMIN(min_y, mv_predictor[j][1]);
520 673fc638 Michael Niedermayer
                            min_r= FFMIN(min_r, ref[j]);
521 4d2858de Michael Niedermayer
                        }
522
                        mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
523
                        mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
524 673fc638 Michael Niedermayer
                        ref         [pred_count+1]    = sum_r - max_r - min_r;
525 115329f1 Diego Biurrun
526 4d2858de Michael Niedermayer
                        if(pred_count==4){
527
                            mv_predictor[pred_count+1][0] /= 2;
528
                            mv_predictor[pred_count+1][1] /= 2;
529 673fc638 Michael Niedermayer
                            ref         [pred_count+1]    /= 2;
530 4d2858de Michael Niedermayer
                        }
531
                        pred_count+=2;
532
                    }
533 673fc638 Michael Niedermayer
skip_mean_and_median:
534 115329f1 Diego Biurrun
535 4d2858de Michael Niedermayer
                    /* zero MV */
536
                    pred_count++;
537
538
                    /* last MV */
539 8d7ec294 Wolfgang Hesseler
                    mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
540
                    mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
541 673fc638 Michael Niedermayer
                    ref         [pred_count]   = s->current_picture.ref_index[0][4*mb_xy];
542 115329f1 Diego Biurrun
                    pred_count++;
543
544 4d2858de Michael Niedermayer
                    s->mv_dir = MV_DIR_FORWARD;
545
                    s->mb_intra=0;
546
                    s->mv_type = MV_TYPE_16X16;
547 160d679c Mike Melanson
                    s->mb_skipped=0;
548 4d2858de Michael Niedermayer
549 bb270c08 Diego Biurrun
                    s->dsp.clear_blocks(s->block[0]);
550 4d2858de Michael Niedermayer
551
                    s->mb_x= mb_x;
552
                    s->mb_y= mb_y;
553 7bc9090a Michael Niedermayer
554 4d2858de Michael Niedermayer
                    for(j=0; j<pred_count; j++){
555
                        int score=0;
556 0c1a9eda Zdenek Kabelac
                        uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
557 4d2858de Michael Niedermayer
558 8d7ec294 Wolfgang Hesseler
                        s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
559
                        s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
560 7bc9090a Michael Niedermayer
561 fc4a2d1e Michael Niedermayer
                        if(ref[j]<0) //predictor intra or otherwise not available
562 673fc638 Michael Niedermayer
                            continue;
563
564
                        decode_mb(s, ref[j]);
565 115329f1 Diego Biurrun
566 7bc9090a Michael Niedermayer
                        if(mb_x>0 && fixed[mb_xy-1]){
567 4d2858de Michael Niedermayer
                            int k;
568
                            for(k=0; k<16; k++)
569 c26abfa5 Diego Biurrun
                                score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize   ]);
570 4d2858de Michael Niedermayer
                        }
571 7bc9090a Michael Niedermayer
                        if(mb_x+1<mb_width && fixed[mb_xy+1]){
572 4d2858de Michael Niedermayer
                            int k;
573
                            for(k=0; k<16; k++)
574 c26abfa5 Diego Biurrun
                                score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
575 4d2858de Michael Niedermayer
                        }
576 7bc9090a Michael Niedermayer
                        if(mb_y>0 && fixed[mb_xy-mb_stride]){
577 4d2858de Michael Niedermayer
                            int k;
578
                            for(k=0; k<16; k++)
579 c26abfa5 Diego Biurrun
                                score += FFABS(src[k-s->linesize   ]-src[k               ]);
580 4d2858de Michael Niedermayer
                        }
581 7bc9090a Michael Niedermayer
                        if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
582 4d2858de Michael Niedermayer
                            int k;
583
                            for(k=0; k<16; k++)
584 c26abfa5 Diego Biurrun
                                score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
585 4d2858de Michael Niedermayer
                        }
586 115329f1 Diego Biurrun
587 4d2858de Michael Niedermayer
                        if(score <= best_score){ // <= will favor the last MV
588
                            best_score= score;
589
                            best_pred= j;
590
                        }
591
                    }
592
score_sum+= best_score;
593 686c7817 Michael Niedermayer
                    s->mv[0][0][0]= mv_predictor[best_pred][0];
594
                    s->mv[0][0][1]= mv_predictor[best_pred][1];
595
596
                    for(i=0; i<mot_step; i++)
597
                        for(j=0; j<mot_step; j++){
598
                            s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
599
                            s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
600
                        }
601 4d2858de Michael Niedermayer
602 673fc638 Michael Niedermayer
                    decode_mb(s, ref[best_pred]);
603 4d2858de Michael Niedermayer
604 115329f1 Diego Biurrun
605 4d2858de Michael Niedermayer
                    if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
606 7bc9090a Michael Niedermayer
                        fixed[mb_xy]=MV_CHANGED;
607 4d2858de Michael Niedermayer
                        changed++;
608
                    }else
609 7bc9090a Michael Niedermayer
                        fixed[mb_xy]=MV_UNCHANGED;
610 4d2858de Michael Niedermayer
                }
611
            }
612
613
//            printf(".%d/%d", changed, score_sum); fflush(stdout);
614
        }
615 115329f1 Diego Biurrun
616
        if(none_left)
617 4d2858de Michael Niedermayer
            return;
618 115329f1 Diego Biurrun
619 4d2858de Michael Niedermayer
        for(i=0; i<s->mb_num; i++){
620 7bc9090a Michael Niedermayer
            int mb_xy= s->mb_index2xy[i];
621
            if(fixed[mb_xy])
622
                fixed[mb_xy]=MV_FROZEN;
623 4d2858de Michael Niedermayer
        }
624
//        printf(":"); fflush(stdout);
625
    }
626
}
627 115329f1 Diego Biurrun
628 4d2858de Michael Niedermayer
static int is_intra_more_likely(MpegEncContext *s){
629
    int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
630 115329f1 Diego Biurrun
631 68997192 Michael Niedermayer
    if(!s->last_picture_ptr || !s->last_picture_ptr->data[0]) return 1; //no previous frame available -> use spatial prediction
632 4d2858de Michael Niedermayer
633
    undamaged_count=0;
634
    for(i=0; i<s->mb_num; i++){
635 7bc9090a Michael Niedermayer
        const int mb_xy= s->mb_index2xy[i];
636
        const int error= s->error_status_table[mb_xy];
637 4d2858de Michael Niedermayer
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
638
            undamaged_count++;
639
    }
640 115329f1 Diego Biurrun
641 c28112fa Michael Niedermayer
    if(s->codec_id == CODEC_ID_H264){
642
        H264Context *h= (void*)s;
643
        if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0])
644
            return 1;
645
    }
646
647 04932b0d Diego Biurrun
    if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
648 115329f1 Diego Biurrun
649 551109d4 Ivan Kalvachev
    //prevent dsp.sad() check, that requires access to the image
650 ce5e49b0 Stefano Sabatini
    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == AV_PICTURE_TYPE_I)
651 83344066 Diego Biurrun
        return 1;
652 551109d4 Ivan Kalvachev
653 115329f1 Diego Biurrun
    skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
654 4d2858de Michael Niedermayer
    is_intra_likely=0;
655
656
    j=0;
657
    for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
658
        for(mb_x= 0; mb_x<s->mb_width; mb_x++){
659
            int error;
660 7bc9090a Michael Niedermayer
            const int mb_xy= mb_x + mb_y*s->mb_stride;
661 4d2858de Michael Niedermayer
662 7bc9090a Michael Niedermayer
            error= s->error_status_table[mb_xy];
663 4d2858de Michael Niedermayer
            if((error&DC_ERROR) && (error&MV_ERROR))
664
                continue; //skip damaged
665 115329f1 Diego Biurrun
666
            j++;
667 4d2858de Michael Niedermayer
            if((j%skip_amount) != 0) continue; //skip a few to speed things up
668 115329f1 Diego Biurrun
669 ce5e49b0 Stefano Sabatini
            if(s->pict_type==AV_PICTURE_TYPE_I){
670 0c1a9eda Zdenek Kabelac
                uint8_t *mb_ptr     = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
671
                uint8_t *last_mb_ptr= s->last_picture.data   [0] + mb_x*16 + mb_y*16*s->linesize;
672 115329f1 Diego Biurrun
673 bb270c08 Diego Biurrun
                is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);
674 a811ec7c Multiple Authors
                // FIXME need await_progress() here
675 bb198e19 Michael Niedermayer
                is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
676 4d2858de Michael Niedermayer
            }else{
677 7bc9090a Michael Niedermayer
                if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
678 4d2858de Michael Niedermayer
                   is_intra_likely++;
679
                else
680
                   is_intra_likely--;
681
            }
682
        }
683
    }
684
//printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
685 115329f1 Diego Biurrun
    return is_intra_likely > 0;
686 4d2858de Michael Niedermayer
}
687
688 46b4feec Michael Niedermayer
void ff_er_frame_start(MpegEncContext *s){
689 047599a4 Michael Niedermayer
    if(!s->error_recognition) return;
690 46b4feec Michael Niedermayer
691 7bc9090a Michael Niedermayer
    memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
692
    s->error_count= 3*s->mb_num;
693 46b4feec Michael Niedermayer
}
694
695
/**
696
 * adds a slice.
697
 * @param endx x component of the last macroblock, can be -1 for the last of the previous line
698
 * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
699 d9526386 Diego Biurrun
 *               error of the same type occurred
700 46b4feec Michael Niedermayer
 */
701
void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
702 f66e4f5f Reimar Döffinger
    const int start_i= av_clip(startx + starty * s->mb_width    , 0, s->mb_num-1);
703
    const int end_i  = av_clip(endx   + endy   * s->mb_width    , 0, s->mb_num);
704 7bc9090a Michael Niedermayer
    const int start_xy= s->mb_index2xy[start_i];
705
    const int end_xy  = s->mb_index2xy[end_i];
706 46b4feec Michael Niedermayer
    int mask= -1;
707 04cfef21 Michael Niedermayer
708 11647a9f Gwenole Beauchesne
    if(s->avctx->hwaccel)
709
        return;
710
711 04cfef21 Michael Niedermayer
    if(start_i > end_i || start_xy > end_xy){
712
        av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
713
        return;
714
    }
715 115329f1 Diego Biurrun
716 047599a4 Michael Niedermayer
    if(!s->error_recognition) return;
717 46b4feec Michael Niedermayer
718
    mask &= ~VP_START;
719 7bc9090a Michael Niedermayer
    if(status & (AC_ERROR|AC_END)){
720
        mask &= ~(AC_ERROR|AC_END);
721
        s->error_count -= end_i - start_i + 1;
722
    }
723
    if(status & (DC_ERROR|DC_END)){
724
        mask &= ~(DC_ERROR|DC_END);
725
        s->error_count -= end_i - start_i + 1;
726
    }
727
    if(status & (MV_ERROR|MV_END)){
728
        mask &= ~(MV_ERROR|MV_END);
729
        s->error_count -= end_i - start_i + 1;
730
    }
731
732
    if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
733 46b4feec Michael Niedermayer
734
    if(mask == ~0x7F){
735 7bc9090a Michael Niedermayer
        memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
736 46b4feec Michael Niedermayer
    }else{
737
        int i;
738
        for(i=start_xy; i<end_xy; i++){
739 7bc9090a Michael Niedermayer
            s->error_status_table[ i ] &= mask;
740 46b4feec Michael Niedermayer
        }
741
    }
742 7bc9090a Michael Niedermayer
743 115329f1 Diego Biurrun
    if(end_i == s->mb_num)
744 7bc9090a Michael Niedermayer
        s->error_count= INT_MAX;
745
    else{
746 46b4feec Michael Niedermayer
        s->error_status_table[end_xy] &= mask;
747
        s->error_status_table[end_xy] |= status;
748
    }
749 115329f1 Diego Biurrun
750 0aae3f43 Michael Niedermayer
    s->error_status_table[start_xy] |= VP_START;
751 7bc9090a Michael Niedermayer
752 0dfd33c3 Michael Niedermayer
    if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){
753 7bc9090a Michael Niedermayer
        int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
754 115329f1 Diego Biurrun
755 7bc9090a Michael Niedermayer
        prev_status &= ~ VP_START;
756
        if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
757
    }
758 46b4feec Michael Niedermayer
}
759
760
void ff_er_frame_end(MpegEncContext *s){
761 4cfbbbde Michael Niedermayer
    int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
762 4d2858de Michael Niedermayer
    int distance;
763
    int threshold_part[4]= {100,100,100};
764
    int threshold= 50;
765
    int is_intra_likely;
766 ec892563 Michael Niedermayer
    int size = s->b8_stride * 2 * s->mb_height;
767
    Picture *pic= s->current_picture_ptr;
768 115329f1 Diego Biurrun
769 8c07cee9 Michael Niedermayer
    if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
770 40e5d31b Gwenole Beauchesne
       s->avctx->hwaccel ||
771 7eb6ed78 Carl Eugen Hoyos
       s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
772 fd1ef13b Michael Niedermayer
       s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
773 0dfd33c3 Michael Niedermayer
       s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
774 46b4feec Michael Niedermayer
775 8d7ec294 Wolfgang Hesseler
    if(s->current_picture.motion_val[0] == NULL){
776 9b879566 Michel Bardiaux
        av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
777 115329f1 Diego Biurrun
778 967be700 Michael Niedermayer
        for(i=0; i<2; i++){
779 358b5b1a Michael Niedermayer
            pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
780 02dc8983 Michael Niedermayer
            pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
781
            pic->motion_val[i]= pic->motion_val_base[i]+4;
782 967be700 Michael Niedermayer
        }
783
        pic->motion_subsample_log2= 3;
784
        s->current_picture= *s->current_picture_ptr;
785 46b4feec Michael Niedermayer
    }
786 115329f1 Diego Biurrun
787 7bc9090a Michael Niedermayer
    if(s->avctx->debug&FF_DEBUG_ER){
788
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
789
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
790
                int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
791 115329f1 Diego Biurrun
792
                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
793 7bc9090a Michael Niedermayer
            }
794 9b879566 Michel Bardiaux
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
795 46b4feec Michael Niedermayer
        }
796
    }
797 115329f1 Diego Biurrun
798 7b9e9817 Michael Niedermayer
#if 1
799 4d2858de Michael Niedermayer
    /* handle overlapping slices */
800
    for(error_type=1; error_type<=3; error_type++){
801
        int end_ok=0;
802
803
        for(i=s->mb_num-1; i>=0; i--){
804 7bc9090a Michael Niedermayer
            const int mb_xy= s->mb_index2xy[i];
805
            int error= s->error_status_table[mb_xy];
806 115329f1 Diego Biurrun
807 4d2858de Michael Niedermayer
            if(error&(1<<error_type))
808
                end_ok=1;
809
            if(error&(8<<error_type))
810
                end_ok=1;
811
812
            if(!end_ok)
813 7bc9090a Michael Niedermayer
                s->error_status_table[mb_xy]|= 1<<error_type;
814 4d2858de Michael Niedermayer
815
            if(error&VP_START)
816
                end_ok=0;
817
        }
818
    }
819 7b9e9817 Michael Niedermayer
#endif
820
#if 1
821 4d2858de Michael Niedermayer
    /* handle slices with partitions of different length */
822
    if(s->partitioned_frame){
823
        int end_ok=0;
824
825
        for(i=s->mb_num-1; i>=0; i--){
826 7bc9090a Michael Niedermayer
            const int mb_xy= s->mb_index2xy[i];
827
            int error= s->error_status_table[mb_xy];
828 115329f1 Diego Biurrun
829 4d2858de Michael Niedermayer
            if(error&AC_END)
830
                end_ok=0;
831
            if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
832
                end_ok=1;
833
834
            if(!end_ok)
835 7bc9090a Michael Niedermayer
                s->error_status_table[mb_xy]|= AC_ERROR;
836 4d2858de Michael Niedermayer
837
            if(error&VP_START)
838
                end_ok=0;
839
        }
840
    }
841 7b9e9817 Michael Niedermayer
#endif
842 4d2858de Michael Niedermayer
    /* handle missing slices */
843 047599a4 Michael Niedermayer
    if(s->error_recognition>=4){
844 4d2858de Michael Niedermayer
        int end_ok=1;
845 115329f1 Diego Biurrun
846 4d2858de Michael Niedermayer
        for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
847 7bc9090a Michael Niedermayer
            const int mb_xy= s->mb_index2xy[i];
848
            int error1= s->error_status_table[mb_xy  ];
849 db6e7795 Michael Niedermayer
            int error2= s->error_status_table[s->mb_index2xy[i+1]];
850 115329f1 Diego Biurrun
851 4d2858de Michael Niedermayer
            if(error1&VP_START)
852
                end_ok=1;
853 115329f1 Diego Biurrun
854 4d2858de Michael Niedermayer
            if(   error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
855 115329f1 Diego Biurrun
               && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
856 5e534865 Diego Biurrun
               && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
857 4d2858de Michael Niedermayer
                end_ok=0;
858
            }
859 115329f1 Diego Biurrun
860 4d2858de Michael Niedermayer
            if(!end_ok)
861 7bc9090a Michael Niedermayer
                s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
862 4d2858de Michael Niedermayer
        }
863
    }
864 115329f1 Diego Biurrun
865 7b9e9817 Michael Niedermayer
#if 1
866 4d2858de Michael Niedermayer
    /* backward mark errors */
867
    distance=9999999;
868
    for(error_type=1; error_type<=3; error_type++){
869
        for(i=s->mb_num-1; i>=0; i--){
870 7bc9090a Michael Niedermayer
            const int mb_xy= s->mb_index2xy[i];
871
            int error= s->error_status_table[mb_xy];
872 115329f1 Diego Biurrun
873 7bc9090a Michael Niedermayer
            if(!s->mbskip_table[mb_xy]) //FIXME partition specific
874 115329f1 Diego Biurrun
                distance++;
875 4d2858de Michael Niedermayer
            if(error&(1<<error_type))
876
                distance= 0;
877
878
            if(s->partitioned_frame){
879
                if(distance < threshold_part[error_type-1])
880 7bc9090a Michael Niedermayer
                    s->error_status_table[mb_xy]|= 1<<error_type;
881 4d2858de Michael Niedermayer
            }else{
882
                if(distance < threshold)
883 7bc9090a Michael Niedermayer
                    s->error_status_table[mb_xy]|= 1<<error_type;
884 4d2858de Michael Niedermayer
            }
885
886
            if(error&VP_START)
887
                distance= 9999999;
888
        }
889
    }
890 7b9e9817 Michael Niedermayer
#endif
891 4d2858de Michael Niedermayer
892
    /* forward mark errors */
893
    error=0;
894
    for(i=0; i<s->mb_num; i++){
895 7bc9090a Michael Niedermayer
        const int mb_xy= s->mb_index2xy[i];
896
        int old_error= s->error_status_table[mb_xy];
897 115329f1 Diego Biurrun
898 4d2858de Michael Niedermayer
        if(old_error&VP_START)
899
            error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
900
        else{
901
            error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
902 7bc9090a Michael Niedermayer
            s->error_status_table[mb_xy]|= error;
903 4d2858de Michael Niedermayer
        }
904
    }
905 7b9e9817 Michael Niedermayer
#if 1
906 4d2858de Michael Niedermayer
    /* handle not partitioned case */
907
    if(!s->partitioned_frame){
908
        for(i=0; i<s->mb_num; i++){
909 7bc9090a Michael Niedermayer
            const int mb_xy= s->mb_index2xy[i];
910
            error= s->error_status_table[mb_xy];
911 4d2858de Michael Niedermayer
            if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
912
                error|= AC_ERROR|DC_ERROR|MV_ERROR;
913 7bc9090a Michael Niedermayer
            s->error_status_table[mb_xy]= error;
914 4d2858de Michael Niedermayer
        }
915
    }
916 7b9e9817 Michael Niedermayer
#endif
917 4cfbbbde Michael Niedermayer
918
    dc_error= ac_error= mv_error=0;
919
    for(i=0; i<s->mb_num; i++){
920
        const int mb_xy= s->mb_index2xy[i];
921
        error= s->error_status_table[mb_xy];
922
        if(error&DC_ERROR) dc_error ++;
923
        if(error&AC_ERROR) ac_error ++;
924
        if(error&MV_ERROR) mv_error ++;
925
    }
926
    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
927
928 4d2858de Michael Niedermayer
    is_intra_likely= is_intra_more_likely(s);
929
930
    /* set unknown mb-type to most likely */
931
    for(i=0; i<s->mb_num; i++){
932 7bc9090a Michael Niedermayer
        const int mb_xy= s->mb_index2xy[i];
933
        error= s->error_status_table[mb_xy];
934
        if(!((error&DC_ERROR) && (error&MV_ERROR)))
935
            continue;
936 4d2858de Michael Niedermayer
937 7bc9090a Michael Niedermayer
        if(is_intra_likely)
938
            s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
939 4d2858de Michael Niedermayer
        else
940 7bc9090a Michael Niedermayer
            s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
941 4d2858de Michael Niedermayer
    }
942 115329f1 Diego Biurrun
943 b6b66760 Reimar Döffinger
    // change inter to intra blocks if no reference frames are available
944
    if (!s->last_picture.data[0] && !s->next_picture.data[0])
945
        for(i=0; i<s->mb_num; i++){
946
            const int mb_xy= s->mb_index2xy[i];
947
            if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
948
                s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
949
        }
950
951 4d2858de Michael Niedermayer
    /* handle inter blocks with damaged AC */
952
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
953
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
954 7bc9090a Michael Niedermayer
            const int mb_xy= mb_x + mb_y * s->mb_stride;
955
            const int mb_type= s->current_picture.mb_type[mb_xy];
956 b6b66760 Reimar Döffinger
            int dir = !s->last_picture.data[0];
957 7bc9090a Michael Niedermayer
            error= s->error_status_table[mb_xy];
958 4d2858de Michael Niedermayer
959 7bc9090a Michael Niedermayer
            if(IS_INTRA(mb_type)) continue; //intra
960 4d2858de Michael Niedermayer
            if(error&MV_ERROR) continue;              //inter with damaged MV
961
            if(!(error&AC_ERROR)) continue;           //undamaged inter
962 115329f1 Diego Biurrun
963 b6b66760 Reimar Döffinger
            s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
964 4d2858de Michael Niedermayer
            s->mb_intra=0;
965 160d679c Mike Melanson
            s->mb_skipped=0;
966 7bc9090a Michael Niedermayer
            if(IS_8X8(mb_type)){
967 137c8468 Michael Niedermayer
                int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
968 4d2858de Michael Niedermayer
                int j;
969
                s->mv_type = MV_TYPE_8X8;
970
                for(j=0; j<4; j++){
971 b6b66760 Reimar Döffinger
                    s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
972
                    s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
973 4d2858de Michael Niedermayer
                }
974
            }else{
975
                s->mv_type = MV_TYPE_16X16;
976 b6b66760 Reimar Döffinger
                s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
977
                s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
978 4d2858de Michael Niedermayer
            }
979 115329f1 Diego Biurrun
980 bb270c08 Diego Biurrun
            s->dsp.clear_blocks(s->block[0]);
981 4d2858de Michael Niedermayer
982
            s->mb_x= mb_x;
983
            s->mb_y= mb_y;
984 673fc638 Michael Niedermayer
            decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
985 4d2858de Michael Niedermayer
        }
986
    }
987
988
    /* guess MVs */
989 ce5e49b0 Stefano Sabatini
    if(s->pict_type==AV_PICTURE_TYPE_B){
990 4d2858de Michael Niedermayer
        for(mb_y=0; mb_y<s->mb_height; mb_y++){
991
            for(mb_x=0; mb_x<s->mb_width; mb_x++){
992 137c8468 Michael Niedermayer
                int xy= mb_x*2 + mb_y*2*s->b8_stride;
993 7bc9090a Michael Niedermayer
                const int mb_xy= mb_x + mb_y * s->mb_stride;
994
                const int mb_type= s->current_picture.mb_type[mb_xy];
995
                error= s->error_status_table[mb_xy];
996 4d2858de Michael Niedermayer
997 7bc9090a Michael Niedermayer
                if(IS_INTRA(mb_type)) continue;
998 4d2858de Michael Niedermayer
                if(!(error&MV_ERROR)) continue;           //inter with undamaged MV
999
                if(!(error&AC_ERROR)) continue;           //undamaged inter
1000 115329f1 Diego Biurrun
1001 4d2858de Michael Niedermayer
                s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
1002 b6b66760 Reimar Döffinger
                if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
1003
                if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
1004 4d2858de Michael Niedermayer
                s->mb_intra=0;
1005
                s->mv_type = MV_TYPE_16X16;
1006 160d679c Mike Melanson
                s->mb_skipped=0;
1007 115329f1 Diego Biurrun
1008 4d2858de Michael Niedermayer
                if(s->pp_time){
1009
                    int time_pp= s->pp_time;
1010
                    int time_pb= s->pb_time;
1011 115329f1 Diego Biurrun
1012 a811ec7c Multiple Authors
                    // FIXME await_progress here
1013 8d7ec294 Wolfgang Hesseler
                    s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
1014
                    s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
1015
                    s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
1016
                    s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
1017 4d2858de Michael Niedermayer
                }else{
1018
                    s->mv[0][0][0]= 0;
1019
                    s->mv[0][0][1]= 0;
1020
                    s->mv[1][0][0]= 0;
1021
                    s->mv[1][0][1]= 0;
1022
                }
1023 eb4b3dd3 Zdenek Kabelac
1024
                s->dsp.clear_blocks(s->block[0]);
1025 4d2858de Michael Niedermayer
                s->mb_x= mb_x;
1026
                s->mb_y= mb_y;
1027 673fc638 Michael Niedermayer
                decode_mb(s, 0);
1028 4d2858de Michael Niedermayer
            }
1029
        }
1030
    }else
1031
        guess_mv(s);
1032
1033 2e7b4c84 Ivan Kalvachev
    /* the filters below are not XvMC compatible, skip them */
1034 83344066 Diego Biurrun
    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1035
        goto ec_clean;
1036 4d2858de Michael Niedermayer
    /* fill DC for inter blocks */
1037
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
1038
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
1039
            int dc, dcu, dcv, y, n;
1040 b86216de Måns Rullgård
            int16_t *dc_ptr;
1041 0c1a9eda Zdenek Kabelac
            uint8_t *dest_y, *dest_cb, *dest_cr;
1042 7bc9090a Michael Niedermayer
            const int mb_xy= mb_x + mb_y * s->mb_stride;
1043
            const int mb_type= s->current_picture.mb_type[mb_xy];
1044 115329f1 Diego Biurrun
1045 7bc9090a Michael Niedermayer
            error= s->error_status_table[mb_xy];
1046 4d2858de Michael Niedermayer
1047 7bc9090a Michael Niedermayer
            if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1048 4d2858de Michael Niedermayer
//            if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
1049 115329f1 Diego Biurrun
1050 1e491e29 Michael Niedermayer
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1051
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
1052
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
1053 115329f1 Diego Biurrun
1054 137c8468 Michael Niedermayer
            dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1055 4d2858de Michael Niedermayer
            for(n=0; n<4; n++){
1056
                dc=0;
1057
                for(y=0; y<8; y++){
1058
                    int x;
1059
                    for(x=0; x<8; x++){
1060
                       dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1061
                    }
1062
                }
1063 137c8468 Michael Niedermayer
                dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1064 4d2858de Michael Niedermayer
            }
1065
1066
            dcu=dcv=0;
1067
            for(y=0; y<8; y++){
1068
                int x;
1069
                for(x=0; x<8; x++){
1070
                    dcu+=dest_cb[x + y*(s->uvlinesize)];
1071
                    dcv+=dest_cr[x + y*(s->uvlinesize)];
1072
                }
1073
            }
1074 137c8468 Michael Niedermayer
            s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1075 115329f1 Diego Biurrun
            s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1076 4d2858de Michael Niedermayer
        }
1077
    }
1078 7b9e9817 Michael Niedermayer
#if 1
1079 4d2858de Michael Niedermayer
    /* guess DC for damaged blocks */
1080 137c8468 Michael Niedermayer
    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1081
    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1082
    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1083 7b9e9817 Michael Niedermayer
#endif
1084 4d2858de Michael Niedermayer
    /* filter luma DC */
1085 137c8468 Michael Niedermayer
    filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1086 115329f1 Diego Biurrun
1087 7b9e9817 Michael Niedermayer
#if 1
1088 4d2858de Michael Niedermayer
    /* render DC only intra */
1089
    for(mb_y=0; mb_y<s->mb_height; mb_y++){
1090
        for(mb_x=0; mb_x<s->mb_width; mb_x++){
1091 0c1a9eda Zdenek Kabelac
            uint8_t *dest_y, *dest_cb, *dest_cr;
1092 7bc9090a Michael Niedermayer
            const int mb_xy= mb_x + mb_y * s->mb_stride;
1093
            const int mb_type= s->current_picture.mb_type[mb_xy];
1094
1095
            error= s->error_status_table[mb_xy];
1096 4d2858de Michael Niedermayer
1097 7bc9090a Michael Niedermayer
            if(IS_INTER(mb_type)) continue;
1098 4d2858de Michael Niedermayer
            if(!(error&AC_ERROR)) continue;              //undamaged
1099 115329f1 Diego Biurrun
1100 1e491e29 Michael Niedermayer
            dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1101
            dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
1102
            dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
1103 115329f1 Diego Biurrun
1104 4d2858de Michael Niedermayer
            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1105
        }
1106
    }
1107 7b9e9817 Michael Niedermayer
#endif
1108 115329f1 Diego Biurrun
1109 4d2858de Michael Niedermayer
    if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1110
        /* filter horizontal block boundaries */
1111 1e491e29 Michael Niedermayer
        h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1112
        h_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1113
        h_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1114 4d2858de Michael Niedermayer
1115
        /* filter vertical block boundaries */
1116 1e491e29 Michael Niedermayer
        v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1117
        v_block_filter(s, s->current_picture.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1118
        v_block_filter(s, s->current_picture.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1119 4d2858de Michael Niedermayer
    }
1120
1121 2e7b4c84 Ivan Kalvachev
ec_clean:
1122 4d2858de Michael Niedermayer
    /* clean a few tables */
1123
    for(i=0; i<s->mb_num; i++){
1124 7bc9090a Michael Niedermayer
        const int mb_xy= s->mb_index2xy[i];
1125
        int error= s->error_status_table[mb_xy];
1126 115329f1 Diego Biurrun
1127 ce5e49b0 Stefano Sabatini
        if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
1128 7bc9090a Michael Niedermayer
            s->mbskip_table[mb_xy]=0;
1129 4d2858de Michael Niedermayer
        }
1130 7bc9090a Michael Niedermayer
        s->mbintra_table[mb_xy]=1;
1131 115329f1 Diego Biurrun
    }
1132 4d2858de Michael Niedermayer
}