]> git.sesse.net Git - ffmpeg/blob - libavcodec/error_resilience.c
lavc: Check CODEC_CAP_VARIABLE_FRAME_SIZE && !frame
[ffmpeg] / libavcodec / error_resilience.c
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 #include "thread.h"
36
37 /*
38  * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
39  * but error concealment must support both h264 and h263 thus we must undo this
40  */
41 #undef mb_intra
42
43 static void decode_mb(MpegEncContext *s, int ref){
44     s->dest[0] = s->current_picture.f.data[0] + (s->mb_y *  16 * s->linesize)                         + s->mb_x *  16;
45     s->dest[1] = s->current_picture.f.data[1] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
46     s->dest[2] = s->current_picture.f.data[2] + (s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16 >> s->chroma_x_shift);
47
48     if(CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264){
49         H264Context *h= (void*)s;
50         h->mb_xy= s->mb_x + s->mb_y*s->mb_stride;
51         memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
52         assert(ref>=0);
53         /* FIXME: It is possible albeit uncommon that slice references
54          * differ between slices. We take the easy approach and ignore
55          * it for now. If this turns out to have any relevance in
56          * practice then correct remapping should be added. */
57         if (ref >= h->ref_count[0])
58             ref=0;
59         fill_rectangle(&s->current_picture.f.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
60         fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
61         fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
62         assert(!FRAME_MBAFF);
63         ff_h264_hl_decode_mb(h);
64     }else{
65         assert(ref==0);
66     MPV_decode_mb(s, s->block);
67     }
68 }
69
70 /**
71  * @param stride the number of MVs to get to the next row
72  * @param mv_step the number of MVs per row or column in a macroblock
73  */
74 static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){
75     if(s->codec_id == CODEC_ID_H264){
76         H264Context *h= (void*)s;
77         assert(s->quarter_sample);
78         *mv_step= 4;
79         *stride= h->b_stride;
80     }else{
81         *mv_step= 2;
82         *stride= s->b8_stride;
83     }
84 }
85
86 /**
87  * Replace the current MB with a flat dc-only version.
88  */
89 static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
90 {
91     int dc, dcu, dcv, y, i;
92     for(i=0; i<4; i++){
93         dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
94         if(dc<0) dc=0;
95         else if(dc>2040) dc=2040;
96         for(y=0; y<8; y++){
97             int x;
98             for(x=0; x<8; x++){
99                 dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8;
100             }
101         }
102     }
103     dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride];
104     dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride];
105     if     (dcu<0   ) dcu=0;
106     else if(dcu>2040) dcu=2040;
107     if     (dcv<0   ) dcv=0;
108     else if(dcv>2040) dcv=2040;
109     for(y=0; y<8; y++){
110         int x;
111         for(x=0; x<8; x++){
112             dest_cb[x + y * s->uvlinesize] = dcu / 8;
113             dest_cr[x + y * s->uvlinesize] = dcv / 8;
114         }
115     }
116 }
117
118 static void filter181(int16_t *data, int width, int height, int stride){
119     int x,y;
120
121     /* horizontal filter */
122     for(y=1; y<height-1; y++){
123         int prev_dc= data[0 + y*stride];
124
125         for(x=1; x<width-1; x++){
126             int dc;
127
128             dc= - prev_dc
129                 + data[x     + y*stride]*8
130                 - data[x + 1 + y*stride];
131             dc= (dc*10923 + 32768)>>16;
132             prev_dc= data[x + y*stride];
133             data[x + y*stride]= dc;
134         }
135     }
136
137     /* vertical filter */
138     for(x=1; x<width-1; x++){
139         int prev_dc= data[x];
140
141         for(y=1; y<height-1; y++){
142             int dc;
143
144             dc= - prev_dc
145                 + data[x +  y   *stride]*8
146                 - data[x + (y+1)*stride];
147             dc= (dc*10923 + 32768)>>16;
148             prev_dc= data[x + y*stride];
149             data[x + y*stride]= dc;
150         }
151     }
152 }
153
154 /**
155  * guess the dc of blocks which do not have an undamaged dc
156  * @param w     width in 8 pixel blocks
157  * @param h     height in 8 pixel blocks
158  */
159 static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
160     int b_x, b_y;
161     int16_t  (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4);
162     uint16_t (*dist)[4] = av_malloc(stride*h*sizeof(uint16_t)*4);
163
164     for(b_y=0; b_y<h; b_y++){
165         int color= 1024;
166         int distance= -1;
167         for(b_x=0; b_x<w; b_x++){
168             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
169             int error_j= s->error_status_table[mb_index_j];
170             int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
171             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
172                 color= dc[b_x + b_y*stride];
173                 distance= b_x;
174             }
175             col [b_x + b_y*stride][1]= color;
176             dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
177         }
178         color= 1024;
179         distance= -1;
180         for(b_x=w-1; b_x>=0; b_x--){
181             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
182             int error_j= s->error_status_table[mb_index_j];
183             int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
184             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
185                 color= dc[b_x + b_y*stride];
186                 distance= b_x;
187             }
188             col [b_x + b_y*stride][0]= color;
189             dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
190         }
191     }
192     for(b_x=0; b_x<w; b_x++){
193         int color= 1024;
194         int distance= -1;
195         for(b_y=0; b_y<h; b_y++){
196             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
197             int error_j= s->error_status_table[mb_index_j];
198             int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
199             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
200                 color= dc[b_x + b_y*stride];
201                 distance= b_y;
202             }
203             col [b_x + b_y*stride][3]= color;
204             dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
205         }
206         color= 1024;
207         distance= -1;
208         for(b_y=h-1; b_y>=0; b_y--){
209             int mb_index_j= (b_x>>is_luma) + (b_y>>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.f.mb_type[mb_index_j]);
212             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
213                 color= dc[b_x + b_y*stride];
214                 distance= b_y;
215             }
216             col [b_x + b_y*stride][2]= color;
217             dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
218         }
219     }
220
221     for(b_y=0; b_y<h; b_y++){
222         for(b_x=0; b_x<w; b_x++){
223             int mb_index, error, j;
224             int64_t guess, weight_sum;
225
226             mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
227
228             error= s->error_status_table[mb_index];
229
230             if(IS_INTER(s->current_picture.f.mb_type[mb_index])) continue; //inter
231             if(!(error&ER_DC_ERROR)) continue;           //dc-ok
232
233
234             weight_sum=0;
235             guess=0;
236             for(j=0; j<4; j++){
237                 int64_t weight= 256*256*256*16/dist[b_x + b_y*stride][j];
238                 guess+= weight*(int64_t)col[b_x + b_y*stride][j];
239                 weight_sum+= weight;
240             }
241             guess= (guess + weight_sum/2) / weight_sum;
242
243             dc[b_x + b_y*stride]= guess;
244         }
245     }
246     av_freep(&col);
247     av_freep(&dist);
248 }
249
250 /**
251  * simple horizontal deblocking filter used for error resilience
252  * @param w     width in 8 pixel blocks
253  * @param h     height in 8 pixel blocks
254  */
255 static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
256     int b_x, b_y, mvx_stride, mvy_stride;
257     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
258     set_mv_strides(s, &mvx_stride, &mvy_stride);
259     mvx_stride >>= is_luma;
260     mvy_stride *= mvx_stride;
261
262     for(b_y=0; b_y<h; b_y++){
263         for(b_x=0; b_x<w-1; b_x++){
264             int y;
265             int left_status = s->error_status_table[( b_x   >>is_luma) + (b_y>>is_luma)*s->mb_stride];
266             int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
267             int left_intra  = IS_INTRA(s->current_picture.f.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
268             int right_intra = IS_INTRA(s->current_picture.f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
269             int left_damage =  left_status&ER_MB_ERROR;
270             int right_damage= right_status&ER_MB_ERROR;
271             int offset= b_x*8 + b_y*stride*8;
272             int16_t *left_mv=  s->current_picture.f.motion_val[0][mvy_stride*b_y + mvx_stride* b_x   ];
273             int16_t *right_mv= s->current_picture.f.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
274
275             if(!(left_damage||right_damage)) continue; // both undamaged
276
277             if(   (!left_intra) && (!right_intra)
278                && FFABS(left_mv[0]-right_mv[0]) + FFABS(left_mv[1]+right_mv[1]) < 2) continue;
279
280             for(y=0; y<8; y++){
281                 int a,b,c,d;
282
283                 a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride];
284                 b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride];
285                 c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride];
286
287                 d= FFABS(b) - ((FFABS(a) + FFABS(c) + 1)>>1);
288                 d= FFMAX(d, 0);
289                 if(b<0) d= -d;
290
291                 if(d==0) continue;
292
293                 if(!(left_damage && right_damage))
294                     d= d*16/9;
295
296                 if(left_damage){
297                     dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)];
298                     dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)];
299                     dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)];
300                     dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)];
301                 }
302                 if(right_damage){
303                     dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)];
304                     dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)];
305                     dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)];
306                     dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)];
307                 }
308             }
309         }
310     }
311 }
312
313 /**
314  * simple vertical deblocking filter used for error resilience
315  * @param w     width in 8 pixel blocks
316  * @param h     height in 8 pixel blocks
317  */
318 static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
319     int b_x, b_y, mvx_stride, mvy_stride;
320     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
321     set_mv_strides(s, &mvx_stride, &mvy_stride);
322     mvx_stride >>= is_luma;
323     mvy_stride *= mvx_stride;
324
325     for(b_y=0; b_y<h-1; b_y++){
326         for(b_x=0; b_x<w; b_x++){
327             int x;
328             int top_status   = s->error_status_table[(b_x>>is_luma) + ( b_y   >>is_luma)*s->mb_stride];
329             int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
330             int top_intra    = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
331             int bottom_intra = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
332             int top_damage =      top_status&ER_MB_ERROR;
333             int bottom_damage= bottom_status&ER_MB_ERROR;
334             int offset= b_x*8 + b_y*stride*8;
335             int16_t *top_mv    = s->current_picture.f.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
336             int16_t *bottom_mv = s->current_picture.f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
337
338             if(!(top_damage||bottom_damage)) continue; // both undamaged
339
340             if(   (!top_intra) && (!bottom_intra)
341                && FFABS(top_mv[0]-bottom_mv[0]) + FFABS(top_mv[1]+bottom_mv[1]) < 2) continue;
342
343             for(x=0; x<8; x++){
344                 int a,b,c,d;
345
346                 a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride];
347                 b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride];
348                 c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride];
349
350                 d= FFABS(b) - ((FFABS(a) + FFABS(c)+1)>>1);
351                 d= FFMAX(d, 0);
352                 if(b<0) d= -d;
353
354                 if(d==0) continue;
355
356                 if(!(top_damage && bottom_damage))
357                     d= d*16/9;
358
359                 if(top_damage){
360                     dst[offset + x +  7*stride] = cm[dst[offset + x +  7*stride] + ((d*7)>>4)];
361                     dst[offset + x +  6*stride] = cm[dst[offset + x +  6*stride] + ((d*5)>>4)];
362                     dst[offset + x +  5*stride] = cm[dst[offset + x +  5*stride] + ((d*3)>>4)];
363                     dst[offset + x +  4*stride] = cm[dst[offset + x +  4*stride] + ((d*1)>>4)];
364                 }
365                 if(bottom_damage){
366                     dst[offset + x +  8*stride] = cm[dst[offset + x +  8*stride] - ((d*7)>>4)];
367                     dst[offset + x +  9*stride] = cm[dst[offset + x +  9*stride] - ((d*5)>>4)];
368                     dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)];
369                     dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)];
370                 }
371             }
372         }
373     }
374 }
375
376 static void guess_mv(MpegEncContext *s){
377     uint8_t *fixed = av_malloc(s->mb_stride * s->mb_height);
378 #define MV_FROZEN    3
379 #define MV_CHANGED   2
380 #define MV_UNCHANGED 1
381     const int mb_stride = s->mb_stride;
382     const int mb_width = s->mb_width;
383     const int mb_height= s->mb_height;
384     int i, depth, num_avail;
385     int mb_x, mb_y, mot_step, mot_stride;
386
387     set_mv_strides(s, &mot_step, &mot_stride);
388
389     num_avail=0;
390     for(i=0; i<s->mb_num; i++){
391         const int mb_xy= s->mb_index2xy[ i ];
392         int f=0;
393         int error= s->error_status_table[mb_xy];
394
395         if(IS_INTRA(s->current_picture.f.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
396         if(!(error&ER_MV_ERROR)) f=MV_FROZEN;           //inter with undamaged MV
397
398         fixed[mb_xy]= f;
399         if(f==MV_FROZEN)
400             num_avail++;
401         else if(s->last_picture.f.data[0] && s->last_picture.f.motion_val[0]){
402             const int mb_y= mb_xy / s->mb_stride;
403             const int mb_x= mb_xy % s->mb_stride;
404             const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
405             s->current_picture.f.motion_val[0][mot_index][0]= s->last_picture.f.motion_val[0][mot_index][0];
406             s->current_picture.f.motion_val[0][mot_index][1]= s->last_picture.f.motion_val[0][mot_index][1];
407             s->current_picture.f.ref_index[0][4*mb_xy]      = s->last_picture.f.ref_index[0][4*mb_xy];
408         }
409     }
410
411     if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
412         for(mb_y=0; mb_y<s->mb_height; mb_y++){
413             for(mb_x=0; mb_x<s->mb_width; mb_x++){
414                 const int mb_xy= mb_x + mb_y*s->mb_stride;
415
416                 if(IS_INTRA(s->current_picture.f.mb_type[mb_xy]))  continue;
417                 if(!(s->error_status_table[mb_xy]&ER_MV_ERROR)) continue;
418
419                 s->mv_dir = s->last_picture.f.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
420                 s->mb_intra=0;
421                 s->mv_type = MV_TYPE_16X16;
422                 s->mb_skipped=0;
423
424                 s->dsp.clear_blocks(s->block[0]);
425
426                 s->mb_x= mb_x;
427                 s->mb_y= mb_y;
428                 s->mv[0][0][0]= 0;
429                 s->mv[0][0][1]= 0;
430                 decode_mb(s, 0);
431             }
432         }
433         goto end;
434     }
435
436     for(depth=0;; depth++){
437         int changed, pass, none_left;
438
439         none_left=1;
440         changed=1;
441         for(pass=0; (changed || pass<2) && pass<10; pass++){
442             int mb_x, mb_y;
443 int score_sum=0;
444
445             changed=0;
446             for(mb_y=0; mb_y<s->mb_height; mb_y++){
447                 for(mb_x=0; mb_x<s->mb_width; mb_x++){
448                     const int mb_xy= mb_x + mb_y*s->mb_stride;
449                     int mv_predictor[8][2]={{0}};
450                     int ref[8]={0};
451                     int pred_count=0;
452                     int j;
453                     int best_score=256*256*256*64;
454                     int best_pred=0;
455                     const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
456                     int prev_x, prev_y, prev_ref;
457
458                     if((mb_x^mb_y^pass)&1) continue;
459
460                     if(fixed[mb_xy]==MV_FROZEN) continue;
461                     assert(!IS_INTRA(s->current_picture.f.mb_type[mb_xy]));
462                     assert(s->last_picture_ptr && s->last_picture_ptr->f.data[0]);
463
464                     j=0;
465                     if(mb_x>0           && fixed[mb_xy-1        ]==MV_FROZEN) j=1;
466                     if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_FROZEN) j=1;
467                     if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
468                     if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
469                     if(j==0) continue;
470
471                     j=0;
472                     if(mb_x>0           && fixed[mb_xy-1        ]==MV_CHANGED) j=1;
473                     if(mb_x+1<mb_width  && fixed[mb_xy+1        ]==MV_CHANGED) j=1;
474                     if(mb_y>0           && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
475                     if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
476                     if(j==0 && pass>1) continue;
477
478                     none_left=0;
479
480                     if(mb_x>0 && fixed[mb_xy-1]){
481                         mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_step][0];
482                         mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_step][1];
483                         ref         [pred_count]   = s->current_picture.f.ref_index[0][4*(mb_xy-1)];
484                         pred_count++;
485                     }
486                     if(mb_x+1<mb_width && fixed[mb_xy+1]){
487                         mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_step][0];
488                         mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_step][1];
489                         ref         [pred_count]   = s->current_picture.f.ref_index[0][4*(mb_xy+1)];
490                         pred_count++;
491                     }
492                     if(mb_y>0 && fixed[mb_xy-mb_stride]){
493                         mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][0];
494                         mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index - mot_stride*mot_step][1];
495                         ref         [pred_count]   = s->current_picture.f.ref_index[0][4*(mb_xy-s->mb_stride)];
496                         pred_count++;
497                     }
498                     if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
499                         mv_predictor[pred_count][0]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][0];
500                         mv_predictor[pred_count][1]= s->current_picture.f.motion_val[0][mot_index + mot_stride*mot_step][1];
501                         ref         [pred_count]   = s->current_picture.f.ref_index[0][4*(mb_xy+s->mb_stride)];
502                         pred_count++;
503                     }
504                     if(pred_count==0) continue;
505
506                     if(pred_count>1){
507                         int sum_x=0, sum_y=0, sum_r=0;
508                         int max_x, max_y, min_x, min_y, max_r, min_r;
509
510                         for(j=0; j<pred_count; j++){
511                             sum_x+= mv_predictor[j][0];
512                             sum_y+= mv_predictor[j][1];
513                             sum_r+= ref[j];
514                             if(j && ref[j] != ref[j-1])
515                                 goto skip_mean_and_median;
516                         }
517
518                         /* mean */
519                         mv_predictor[pred_count][0] = sum_x/j;
520                         mv_predictor[pred_count][1] = sum_y/j;
521                         ref         [pred_count]    = sum_r/j;
522
523                         /* median */
524                         if(pred_count>=3){
525                             min_y= min_x= min_r= 99999;
526                             max_y= max_x= max_r=-99999;
527                         }else{
528                             min_x=min_y=max_x=max_y=min_r=max_r=0;
529                         }
530                         for(j=0; j<pred_count; j++){
531                             max_x= FFMAX(max_x, mv_predictor[j][0]);
532                             max_y= FFMAX(max_y, mv_predictor[j][1]);
533                             max_r= FFMAX(max_r, ref[j]);
534                             min_x= FFMIN(min_x, mv_predictor[j][0]);
535                             min_y= FFMIN(min_y, mv_predictor[j][1]);
536                             min_r= FFMIN(min_r, ref[j]);
537                         }
538                         mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
539                         mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
540                         ref         [pred_count+1]    = sum_r - max_r - min_r;
541
542                         if(pred_count==4){
543                             mv_predictor[pred_count+1][0] /= 2;
544                             mv_predictor[pred_count+1][1] /= 2;
545                             ref         [pred_count+1]    /= 2;
546                         }
547                         pred_count+=2;
548                     }
549 skip_mean_and_median:
550
551                     /* zero MV */
552                     pred_count++;
553
554                     if (!fixed[mb_xy] && 0) {
555                         if (s->avctx->codec_id == CODEC_ID_H264) {
556                             // FIXME
557                         } else {
558                             ff_thread_await_progress((AVFrame *) s->last_picture_ptr,
559                                                      mb_y, 0);
560                         }
561                         if (!s->last_picture.f.motion_val[0] ||
562                             !s->last_picture.f.ref_index[0])
563                             goto skip_last_mv;
564                         prev_x = s->last_picture.f.motion_val[0][mot_index][0];
565                         prev_y = s->last_picture.f.motion_val[0][mot_index][1];
566                         prev_ref = s->last_picture.f.ref_index[0][4*mb_xy];
567                     } else {
568                         prev_x = s->current_picture.f.motion_val[0][mot_index][0];
569                         prev_y = s->current_picture.f.motion_val[0][mot_index][1];
570                         prev_ref = s->current_picture.f.ref_index[0][4*mb_xy];
571                     }
572
573                     /* last MV */
574                     mv_predictor[pred_count][0]= prev_x;
575                     mv_predictor[pred_count][1]= prev_y;
576                     ref         [pred_count]   = prev_ref;
577                     pred_count++;
578                 skip_last_mv:
579
580                     s->mv_dir = MV_DIR_FORWARD;
581                     s->mb_intra=0;
582                     s->mv_type = MV_TYPE_16X16;
583                     s->mb_skipped=0;
584
585                     s->dsp.clear_blocks(s->block[0]);
586
587                     s->mb_x= mb_x;
588                     s->mb_y= mb_y;
589
590                     for(j=0; j<pred_count; j++){
591                         int score=0;
592                         uint8_t *src = s->current_picture.f.data[0] + mb_x*16 + mb_y*16*s->linesize;
593
594                         s->current_picture.f.motion_val[0][mot_index][0] = s->mv[0][0][0] = mv_predictor[j][0];
595                         s->current_picture.f.motion_val[0][mot_index][1] = s->mv[0][0][1] = mv_predictor[j][1];
596
597                         if(ref[j]<0) //predictor intra or otherwise not available
598                             continue;
599
600                         decode_mb(s, ref[j]);
601
602                         if(mb_x>0 && fixed[mb_xy-1]){
603                             int k;
604                             for(k=0; k<16; k++)
605                                 score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize   ]);
606                         }
607                         if(mb_x+1<mb_width && fixed[mb_xy+1]){
608                             int k;
609                             for(k=0; k<16; k++)
610                                 score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
611                         }
612                         if(mb_y>0 && fixed[mb_xy-mb_stride]){
613                             int k;
614                             for(k=0; k<16; k++)
615                                 score += FFABS(src[k-s->linesize   ]-src[k               ]);
616                         }
617                         if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
618                             int k;
619                             for(k=0; k<16; k++)
620                                 score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
621                         }
622
623                         if(score <= best_score){ // <= will favor the last MV
624                             best_score= score;
625                             best_pred= j;
626                         }
627                     }
628 score_sum+= best_score;
629                     s->mv[0][0][0]= mv_predictor[best_pred][0];
630                     s->mv[0][0][1]= mv_predictor[best_pred][1];
631
632                     for(i=0; i<mot_step; i++)
633                         for(j=0; j<mot_step; j++){
634                             s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
635                             s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
636                         }
637
638                     decode_mb(s, ref[best_pred]);
639
640
641                     if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
642                         fixed[mb_xy]=MV_CHANGED;
643                         changed++;
644                     }else
645                         fixed[mb_xy]=MV_UNCHANGED;
646                 }
647             }
648
649 //            printf(".%d/%d", changed, score_sum); fflush(stdout);
650         }
651
652         if(none_left)
653             goto end;
654
655         for(i=0; i<s->mb_num; i++){
656             int mb_xy= s->mb_index2xy[i];
657             if(fixed[mb_xy])
658                 fixed[mb_xy]=MV_FROZEN;
659         }
660 //        printf(":"); fflush(stdout);
661     }
662 end:
663     av_free(fixed);
664 }
665
666 static int is_intra_more_likely(MpegEncContext *s){
667     int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
668
669     if (!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) return 1; //no previous frame available -> use spatial prediction
670
671     undamaged_count=0;
672     for(i=0; i<s->mb_num; i++){
673         const int mb_xy= s->mb_index2xy[i];
674         const int error= s->error_status_table[mb_xy];
675         if(!((error&ER_DC_ERROR) && (error&ER_MV_ERROR)))
676             undamaged_count++;
677     }
678
679     if(s->codec_id == CODEC_ID_H264){
680         H264Context *h= (void*)s;
681         if (h->list_count <= 0 || h->ref_count[0] <= 0 || !h->ref_list[0][0].f.data[0])
682             return 1;
683     }
684
685     if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
686
687     //prevent dsp.sad() check, that requires access to the image
688     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == AV_PICTURE_TYPE_I)
689         return 1;
690
691     skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
692     is_intra_likely=0;
693
694     j=0;
695     for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
696         for(mb_x= 0; mb_x<s->mb_width; mb_x++){
697             int error;
698             const int mb_xy= mb_x + mb_y*s->mb_stride;
699
700             error= s->error_status_table[mb_xy];
701             if((error&ER_DC_ERROR) && (error&ER_MV_ERROR))
702                 continue; //skip damaged
703
704             j++;
705             if((j%skip_amount) != 0) continue; //skip a few to speed things up
706
707             if(s->pict_type==AV_PICTURE_TYPE_I){
708                 uint8_t *mb_ptr     = s->current_picture.f.data[0] + mb_x*16 + mb_y*16*s->linesize;
709                 uint8_t *last_mb_ptr= s->last_picture.f.data   [0] + mb_x*16 + mb_y*16*s->linesize;
710
711                 if (s->avctx->codec_id == CODEC_ID_H264) {
712                     // FIXME
713                 } else {
714                     ff_thread_await_progress((AVFrame *) s->last_picture_ptr,
715                                              mb_y, 0);
716                 }
717                 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);
718                 // FIXME need await_progress() here
719                 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
720             }else{
721                 if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
722                    is_intra_likely++;
723                 else
724                    is_intra_likely--;
725             }
726         }
727     }
728 //printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
729     return is_intra_likely > 0;
730 }
731
732 void ff_er_frame_start(MpegEncContext *s){
733     if(!s->err_recognition) return;
734
735     memset(s->error_status_table, ER_MB_ERROR|VP_START|ER_MB_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
736     s->error_count= 3*s->mb_num;
737     s->error_occurred = 0;
738 }
739
740 /**
741  * Add a slice.
742  * @param endx x component of the last macroblock, can be -1 for the last of the previous line
743  * @param status the status at the end (ER_MV_END, ER_AC_ERROR, ...), it is assumed that no earlier end or
744  *               error of the same type occurred
745  */
746 void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
747     const int start_i= av_clip(startx + starty * s->mb_width    , 0, s->mb_num-1);
748     const int end_i  = av_clip(endx   + endy   * s->mb_width    , 0, s->mb_num);
749     const int start_xy= s->mb_index2xy[start_i];
750     const int end_xy  = s->mb_index2xy[end_i];
751     int mask= -1;
752
753     if(s->avctx->hwaccel)
754         return;
755
756     if(start_i > end_i || start_xy > end_xy){
757         av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
758         return;
759     }
760
761     if(!s->err_recognition) return;
762
763     mask &= ~VP_START;
764     if(status & (ER_AC_ERROR|ER_AC_END)){
765         mask &= ~(ER_AC_ERROR|ER_AC_END);
766         s->error_count -= end_i - start_i + 1;
767     }
768     if(status & (ER_DC_ERROR|ER_DC_END)){
769         mask &= ~(ER_DC_ERROR|ER_DC_END);
770         s->error_count -= end_i - start_i + 1;
771     }
772     if(status & (ER_MV_ERROR|ER_MV_END)){
773         mask &= ~(ER_MV_ERROR|ER_MV_END);
774         s->error_count -= end_i - start_i + 1;
775     }
776
777     if(status & ER_MB_ERROR) {
778         s->error_occurred = 1;
779         s->error_count= INT_MAX;
780     }
781
782     if(mask == ~0x7F){
783         memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
784     }else{
785         int i;
786         for(i=start_xy; i<end_xy; i++){
787             s->error_status_table[ i ] &= mask;
788         }
789     }
790
791     if(end_i == s->mb_num)
792         s->error_count= INT_MAX;
793     else{
794         s->error_status_table[end_xy] &= mask;
795         s->error_status_table[end_xy] |= status;
796     }
797
798     s->error_status_table[start_xy] |= VP_START;
799
800     if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){
801         int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
802
803         prev_status &= ~ VP_START;
804         if(prev_status != (ER_MV_END|ER_DC_END|ER_AC_END)) s->error_count= INT_MAX;
805     }
806 }
807
808 void ff_er_frame_end(MpegEncContext *s){
809     int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
810     int distance;
811     int threshold_part[4]= {100,100,100};
812     int threshold= 50;
813     int is_intra_likely;
814     int size = s->b8_stride * 2 * s->mb_height;
815     Picture *pic= s->current_picture_ptr;
816
817     if(!s->err_recognition || s->error_count==0 || s->avctx->lowres ||
818        s->avctx->hwaccel ||
819        s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
820        s->picture_structure != PICT_FRAME || // we do not support ER of field pictures yet, though it should not crash if enabled
821        s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
822
823     if (s->current_picture.f.motion_val[0] == NULL) {
824         av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
825
826         for(i=0; i<2; i++){
827             pic->f.ref_index[i] = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
828             pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
829             pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
830         }
831         pic->f.motion_subsample_log2 = 3;
832         s->current_picture= *s->current_picture_ptr;
833     }
834
835     if(s->avctx->debug&FF_DEBUG_ER){
836         for(mb_y=0; mb_y<s->mb_height; mb_y++){
837             for(mb_x=0; mb_x<s->mb_width; mb_x++){
838                 int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
839
840                 av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
841             }
842             av_log(s->avctx, AV_LOG_DEBUG, "\n");
843         }
844     }
845
846 #if 1
847     /* handle overlapping slices */
848     for(error_type=1; error_type<=3; error_type++){
849         int end_ok=0;
850
851         for(i=s->mb_num-1; i>=0; i--){
852             const int mb_xy= s->mb_index2xy[i];
853             int error= s->error_status_table[mb_xy];
854
855             if(error&(1<<error_type))
856                 end_ok=1;
857             if(error&(8<<error_type))
858                 end_ok=1;
859
860             if(!end_ok)
861                 s->error_status_table[mb_xy]|= 1<<error_type;
862
863             if(error&VP_START)
864                 end_ok=0;
865         }
866     }
867 #endif
868 #if 1
869     /* handle slices with partitions of different length */
870     if(s->partitioned_frame){
871         int end_ok=0;
872
873         for(i=s->mb_num-1; i>=0; i--){
874             const int mb_xy= s->mb_index2xy[i];
875             int error= s->error_status_table[mb_xy];
876
877             if(error&ER_AC_END)
878                 end_ok=0;
879             if((error&ER_MV_END) || (error&ER_DC_END) || (error&ER_AC_ERROR))
880                 end_ok=1;
881
882             if(!end_ok)
883                 s->error_status_table[mb_xy]|= ER_AC_ERROR;
884
885             if(error&VP_START)
886                 end_ok=0;
887         }
888     }
889 #endif
890     /* handle missing slices */
891     if(s->err_recognition&AV_EF_EXPLODE){
892         int end_ok=1;
893
894         for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
895             const int mb_xy= s->mb_index2xy[i];
896             int error1= s->error_status_table[mb_xy  ];
897             int error2= s->error_status_table[s->mb_index2xy[i+1]];
898
899             if(error1&VP_START)
900                 end_ok=1;
901
902             if(   error2==(VP_START|ER_MB_ERROR|ER_MB_END)
903                && error1!=(VP_START|ER_MB_ERROR|ER_MB_END)
904                && ((error1&ER_AC_END) || (error1&ER_DC_END) || (error1&ER_MV_END))){ //end & uninit
905                 end_ok=0;
906             }
907
908             if(!end_ok)
909                 s->error_status_table[mb_xy]|= ER_MB_ERROR;
910         }
911     }
912
913 #if 1
914     /* backward mark errors */
915     distance=9999999;
916     for(error_type=1; error_type<=3; error_type++){
917         for(i=s->mb_num-1; i>=0; i--){
918             const int mb_xy= s->mb_index2xy[i];
919             int error= s->error_status_table[mb_xy];
920
921             if(!s->mbskip_table[mb_xy]) //FIXME partition specific
922                 distance++;
923             if(error&(1<<error_type))
924                 distance= 0;
925
926             if(s->partitioned_frame){
927                 if(distance < threshold_part[error_type-1])
928                     s->error_status_table[mb_xy]|= 1<<error_type;
929             }else{
930                 if(distance < threshold)
931                     s->error_status_table[mb_xy]|= 1<<error_type;
932             }
933
934             if(error&VP_START)
935                 distance= 9999999;
936         }
937     }
938 #endif
939
940     /* forward mark errors */
941     error=0;
942     for(i=0; i<s->mb_num; i++){
943         const int mb_xy= s->mb_index2xy[i];
944         int old_error= s->error_status_table[mb_xy];
945
946         if(old_error&VP_START)
947             error= old_error& ER_MB_ERROR;
948         else{
949             error|= old_error& ER_MB_ERROR;
950             s->error_status_table[mb_xy]|= error;
951         }
952     }
953 #if 1
954     /* handle not partitioned case */
955     if(!s->partitioned_frame){
956         for(i=0; i<s->mb_num; i++){
957             const int mb_xy= s->mb_index2xy[i];
958             error= s->error_status_table[mb_xy];
959             if(error&ER_MB_ERROR)
960                 error|= ER_MB_ERROR;
961             s->error_status_table[mb_xy]= error;
962         }
963     }
964 #endif
965
966     dc_error= ac_error= mv_error=0;
967     for(i=0; i<s->mb_num; i++){
968         const int mb_xy= s->mb_index2xy[i];
969         error= s->error_status_table[mb_xy];
970         if(error&ER_DC_ERROR) dc_error ++;
971         if(error&ER_AC_ERROR) ac_error ++;
972         if(error&ER_MV_ERROR) mv_error ++;
973     }
974     av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
975
976     is_intra_likely= is_intra_more_likely(s);
977
978     /* set unknown mb-type to most likely */
979     for(i=0; i<s->mb_num; i++){
980         const int mb_xy= s->mb_index2xy[i];
981         error= s->error_status_table[mb_xy];
982         if(!((error&ER_DC_ERROR) && (error&ER_MV_ERROR)))
983             continue;
984
985         if(is_intra_likely)
986             s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
987         else
988             s->current_picture.f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
989     }
990
991     // change inter to intra blocks if no reference frames are available
992     if (!s->last_picture.f.data[0] && !s->next_picture.f.data[0])
993         for(i=0; i<s->mb_num; i++){
994             const int mb_xy= s->mb_index2xy[i];
995             if (!IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
996                 s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
997         }
998
999     /* handle inter blocks with damaged AC */
1000     for(mb_y=0; mb_y<s->mb_height; mb_y++){
1001         for(mb_x=0; mb_x<s->mb_width; mb_x++){
1002             const int mb_xy= mb_x + mb_y * s->mb_stride;
1003             const int mb_type= s->current_picture.f.mb_type[mb_xy];
1004             int dir = !s->last_picture.f.data[0];
1005             error= s->error_status_table[mb_xy];
1006
1007             if(IS_INTRA(mb_type)) continue; //intra
1008             if(error&ER_MV_ERROR) continue;              //inter with damaged MV
1009             if(!(error&ER_AC_ERROR)) continue;           //undamaged inter
1010
1011             s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
1012             s->mb_intra=0;
1013             s->mb_skipped=0;
1014             if(IS_8X8(mb_type)){
1015                 int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
1016                 int j;
1017                 s->mv_type = MV_TYPE_8X8;
1018                 for(j=0; j<4; j++){
1019                     s->mv[0][j][0] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
1020                     s->mv[0][j][1] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
1021                 }
1022             }else{
1023                 s->mv_type = MV_TYPE_16X16;
1024                 s->mv[0][0][0] = s->current_picture.f.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
1025                 s->mv[0][0][1] = s->current_picture.f.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
1026             }
1027
1028             s->dsp.clear_blocks(s->block[0]);
1029
1030             s->mb_x= mb_x;
1031             s->mb_y= mb_y;
1032             decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
1033         }
1034     }
1035
1036     /* guess MVs */
1037     if(s->pict_type==AV_PICTURE_TYPE_B){
1038         for(mb_y=0; mb_y<s->mb_height; mb_y++){
1039             for(mb_x=0; mb_x<s->mb_width; mb_x++){
1040                 int xy= mb_x*2 + mb_y*2*s->b8_stride;
1041                 const int mb_xy= mb_x + mb_y * s->mb_stride;
1042                 const int mb_type= s->current_picture.f.mb_type[mb_xy];
1043                 error= s->error_status_table[mb_xy];
1044
1045                 if(IS_INTRA(mb_type)) continue;
1046                 if(!(error&ER_MV_ERROR)) continue;           //inter with undamaged MV
1047                 if(!(error&ER_AC_ERROR)) continue;           //undamaged inter
1048
1049                 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
1050                 if(!s->last_picture.f.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
1051                 if(!s->next_picture.f.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
1052                 s->mb_intra=0;
1053                 s->mv_type = MV_TYPE_16X16;
1054                 s->mb_skipped=0;
1055
1056                 if(s->pp_time){
1057                     int time_pp= s->pp_time;
1058                     int time_pb= s->pb_time;
1059
1060                     if (s->avctx->codec_id == CODEC_ID_H264) {
1061                         //FIXME
1062                     } else {
1063                         ff_thread_await_progress((AVFrame *) s->next_picture_ptr,
1064                                                  mb_y, 0);
1065                     }
1066                     s->mv[0][0][0] = s->next_picture.f.motion_val[0][xy][0] *            time_pb  / time_pp;
1067                     s->mv[0][0][1] = s->next_picture.f.motion_val[0][xy][1] *            time_pb  / time_pp;
1068                     s->mv[1][0][0] = s->next_picture.f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
1069                     s->mv[1][0][1] = s->next_picture.f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
1070                 }else{
1071                     s->mv[0][0][0]= 0;
1072                     s->mv[0][0][1]= 0;
1073                     s->mv[1][0][0]= 0;
1074                     s->mv[1][0][1]= 0;
1075                 }
1076
1077                 s->dsp.clear_blocks(s->block[0]);
1078                 s->mb_x= mb_x;
1079                 s->mb_y= mb_y;
1080                 decode_mb(s, 0);
1081             }
1082         }
1083     }else
1084         guess_mv(s);
1085
1086     /* the filters below are not XvMC compatible, skip them */
1087     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1088         goto ec_clean;
1089     /* fill DC for inter blocks */
1090     for(mb_y=0; mb_y<s->mb_height; mb_y++){
1091         for(mb_x=0; mb_x<s->mb_width; mb_x++){
1092             int dc, dcu, dcv, y, n;
1093             int16_t *dc_ptr;
1094             uint8_t *dest_y, *dest_cb, *dest_cr;
1095             const int mb_xy= mb_x + mb_y * s->mb_stride;
1096             const int mb_type = s->current_picture.f.mb_type[mb_xy];
1097
1098             error= s->error_status_table[mb_xy];
1099
1100             if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1101 //            if(error&ER_MV_ERROR) continue; //inter data damaged FIXME is this good?
1102
1103             dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
1104             dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
1105             dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
1106
1107             dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1108             for(n=0; n<4; n++){
1109                 dc=0;
1110                 for(y=0; y<8; y++){
1111                     int x;
1112                     for(x=0; x<8; x++){
1113                        dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1114                     }
1115                 }
1116                 dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1117             }
1118
1119             dcu=dcv=0;
1120             for(y=0; y<8; y++){
1121                 int x;
1122                 for(x=0; x<8; x++){
1123                     dcu += dest_cb[x + y * s->uvlinesize];
1124                     dcv += dest_cr[x + y * s->uvlinesize];
1125                 }
1126             }
1127             s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1128             s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1129         }
1130     }
1131 #if 1
1132     /* guess DC for damaged blocks */
1133     guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1134     guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1135     guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
1136 #endif
1137     /* filter luma DC */
1138     filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1139
1140 #if 1
1141     /* render DC only intra */
1142     for(mb_y=0; mb_y<s->mb_height; mb_y++){
1143         for(mb_x=0; mb_x<s->mb_width; mb_x++){
1144             uint8_t *dest_y, *dest_cb, *dest_cr;
1145             const int mb_xy= mb_x + mb_y * s->mb_stride;
1146             const int mb_type = s->current_picture.f.mb_type[mb_xy];
1147
1148             error= s->error_status_table[mb_xy];
1149
1150             if(IS_INTER(mb_type)) continue;
1151             if(!(error&ER_AC_ERROR)) continue;              //undamaged
1152
1153             dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
1154             dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
1155             dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
1156
1157             put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1158         }
1159     }
1160 #endif
1161
1162     if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1163         /* filter horizontal block boundaries */
1164         h_block_filter(s, s->current_picture.f.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1165         h_block_filter(s, s->current_picture.f.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1166         h_block_filter(s, s->current_picture.f.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1167
1168         /* filter vertical block boundaries */
1169         v_block_filter(s, s->current_picture.f.data[0], s->mb_width*2, s->mb_height*2, s->linesize  , 1);
1170         v_block_filter(s, s->current_picture.f.data[1], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1171         v_block_filter(s, s->current_picture.f.data[2], s->mb_width  , s->mb_height  , s->uvlinesize, 0);
1172     }
1173
1174 ec_clean:
1175     /* clean a few tables */
1176     for(i=0; i<s->mb_num; i++){
1177         const int mb_xy= s->mb_index2xy[i];
1178         int error= s->error_status_table[mb_xy];
1179
1180         if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(ER_DC_ERROR|ER_MV_ERROR|ER_AC_ERROR))){
1181             s->mbskip_table[mb_xy]=0;
1182         }
1183         s->mbintra_table[mb_xy]=1;
1184     }
1185 }