00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00028 #include <limits.h>
00029 
00030 #include "avcodec.h"
00031 #include "dsputil.h"
00032 #include "mpegvideo.h"
00033 #include "h264.h"
00034 #include "rectangle.h"
00035 #include "thread.h"
00036 
00037 
00038 
00039 
00040 
00041 #undef mb_intra
00042 
00043 static void decode_mb(MpegEncContext *s, int ref)
00044 {
00045     s->dest[0] = s->current_picture.f.data[0] + (s->mb_y *  16                       * s->linesize)   + s->mb_x *  16;
00046     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);
00047     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);
00048 
00049     ff_init_block_index(s);
00050     ff_update_block_index(s);
00051     s->dest[1] += (16 >> s->chroma_x_shift) - 8;
00052     s->dest[2] += (16 >> s->chroma_x_shift) - 8;
00053 
00054     if (CONFIG_H264_DECODER && s->codec_id == AV_CODEC_ID_H264) {
00055         H264Context *h = (void*)s;
00056         h->mb_xy = s->mb_x + s->mb_y * s->mb_stride;
00057         memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
00058         av_assert1(ref >= 0);
00059         
00060 
00061 
00062 
00063         if (ref >= h->ref_count[0])
00064             ref = 0;
00065         if (!h->ref_list[0][ref].f.data[0]) {
00066             av_log(s->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
00067             ref = 0;
00068         }
00069         fill_rectangle(&s->current_picture.f.ref_index[0][4 * h->mb_xy],
00070                        2, 2, 2, ref, 1);
00071         fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
00072         fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
00073                        pack16to32(s->mv[0][0][0], s->mv[0][0][1]), 4);
00074         h->mb_mbaff =
00075         h->mb_field_decoding_flag = 0;
00076         ff_h264_hl_decode_mb(h);
00077     } else {
00078         assert(ref == 0);
00079         ff_MPV_decode_mb(s, s->block);
00080     }
00081 }
00082 
00087 static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride)
00088 {
00089     if (s->codec_id == AV_CODEC_ID_H264) {
00090         H264Context *h = (void*)s;
00091         av_assert0(s->quarter_sample);
00092         *mv_step = 4;
00093         *stride  = h->b_stride;
00094     } else {
00095         *mv_step = 2;
00096         *stride  = s->b8_stride;
00097     }
00098 }
00099 
00103 static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb,
00104                    uint8_t *dest_cr, int mb_x, int mb_y)
00105 {
00106     int dc, dcu, dcv, y, i;
00107     for (i = 0; i < 4; i++) {
00108         dc = s->dc_val[0][mb_x * 2 + (i &  1) + (mb_y * 2 + (i >> 1)) * s->b8_stride];
00109         if (dc < 0)
00110             dc = 0;
00111         else if (dc > 2040)
00112             dc = 2040;
00113         for (y = 0; y < 8; y++) {
00114             int x;
00115             for (x = 0; x < 8; x++)
00116                 dest_y[x + (i &  1) * 8 + (y + (i >> 1) * 8) * s->linesize] = dc / 8;
00117         }
00118     }
00119     dcu = s->dc_val[1][mb_x + mb_y * s->mb_stride];
00120     dcv = s->dc_val[2][mb_x + mb_y * s->mb_stride];
00121     if (dcu < 0)
00122         dcu = 0;
00123     else if (dcu > 2040)
00124         dcu = 2040;
00125     if (dcv < 0)
00126         dcv = 0;
00127     else if (dcv > 2040)
00128         dcv = 2040;
00129     for (y = 0; y < 8; y++) {
00130         int x;
00131         for (x = 0; x < 8; x++) {
00132             dest_cb[x + y * s->uvlinesize] = dcu / 8;
00133             dest_cr[x + y * s->uvlinesize] = dcv / 8;
00134         }
00135     }
00136 }
00137 
00138 static void filter181(int16_t *data, int width, int height, int stride)
00139 {
00140     int x, y;
00141 
00142     
00143     for (y = 1; y < height - 1; y++) {
00144         int prev_dc = data[0 + y * stride];
00145 
00146         for (x = 1; x < width - 1; x++) {
00147             int dc;
00148             dc = -prev_dc +
00149                  data[x     + y * stride] * 8 -
00150                  data[x + 1 + y * stride];
00151             dc = (dc * 10923 + 32768) >> 16;
00152             prev_dc = data[x + y * stride];
00153             data[x + y * stride] = dc;
00154         }
00155     }
00156 
00157     
00158     for (x = 1; x < width - 1; x++) {
00159         int prev_dc = data[x];
00160 
00161         for (y = 1; y < height - 1; y++) {
00162             int dc;
00163 
00164             dc = -prev_dc +
00165                  data[x +  y      * stride] * 8 -
00166                  data[x + (y + 1) * stride];
00167             dc = (dc * 10923 + 32768) >> 16;
00168             prev_dc = data[x + y * stride];
00169             data[x + y * stride] = dc;
00170         }
00171     }
00172 }
00173 
00179 static void guess_dc(MpegEncContext *s, int16_t *dc, int w,
00180                      int h, int stride, int is_luma)
00181 {
00182     int b_x, b_y;
00183     int16_t  (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4);
00184     uint32_t (*dist)[4] = av_malloc(stride*h*sizeof(uint32_t)*4);
00185 
00186     if(!col || !dist) {
00187         av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
00188         goto fail;
00189     }
00190 
00191     for(b_y=0; b_y<h; b_y++){
00192         int color= 1024;
00193         int distance= -1;
00194         for(b_x=0; b_x<w; b_x++){
00195             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
00196             int error_j= s->error_status_table[mb_index_j];
00197             int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
00198             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
00199                 color= dc[b_x + b_y*stride];
00200                 distance= b_x;
00201             }
00202             col [b_x + b_y*stride][1]= color;
00203             dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
00204         }
00205         color= 1024;
00206         distance= -1;
00207         for(b_x=w-1; b_x>=0; b_x--){
00208             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
00209             int error_j= s->error_status_table[mb_index_j];
00210             int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
00211             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
00212                 color= dc[b_x + b_y*stride];
00213                 distance= b_x;
00214             }
00215             col [b_x + b_y*stride][0]= color;
00216             dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
00217         }
00218     }
00219     for(b_x=0; b_x<w; b_x++){
00220         int color= 1024;
00221         int distance= -1;
00222         for(b_y=0; b_y<h; b_y++){
00223             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
00224             int error_j= s->error_status_table[mb_index_j];
00225             int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
00226             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
00227                 color= dc[b_x + b_y*stride];
00228                 distance= b_y;
00229             }
00230             col [b_x + b_y*stride][3]= color;
00231             dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
00232         }
00233         color= 1024;
00234         distance= -1;
00235         for(b_y=h-1; b_y>=0; b_y--){
00236             int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
00237             int error_j= s->error_status_table[mb_index_j];
00238             int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);
00239             if(intra_j==0 || !(error_j&ER_DC_ERROR)){
00240                 color= dc[b_x + b_y*stride];
00241                 distance= b_y;
00242             }
00243             col [b_x + b_y*stride][2]= color;
00244             dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
00245         }
00246     }
00247 
00248     for (b_y = 0; b_y < h; b_y++) {
00249         for (b_x = 0; b_x < w; b_x++) {
00250             int mb_index, error, j;
00251             int64_t guess, weight_sum;
00252             mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
00253             error    = s->error_status_table[mb_index];
00254 
00255             if (IS_INTER(s->current_picture.f.mb_type[mb_index]))
00256                 continue; 
00257             if (!(error & ER_DC_ERROR))
00258                 continue; 
00259 
00260             weight_sum = 0;
00261             guess      = 0;
00262             for (j = 0; j < 4; j++) {
00263                 int64_t weight  = 256 * 256 * 256 * 16 / FFMAX(dist[b_x + b_y*stride][j], 1);
00264                 guess          += weight*(int64_t)col[b_x + b_y*stride][j];
00265                 weight_sum     += weight;
00266             }
00267             guess = (guess + weight_sum / 2) / weight_sum;
00268             dc[b_x + b_y * stride] = guess;
00269         }
00270     }
00271 
00272 fail:
00273     av_freep(&col);
00274     av_freep(&dist);
00275 }
00276 
00282 static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w,
00283                            int h, int stride, int is_luma)
00284 {
00285     int b_x, b_y, mvx_stride, mvy_stride;
00286     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00287     set_mv_strides(s, &mvx_stride, &mvy_stride);
00288     mvx_stride >>= is_luma;
00289     mvy_stride *= mvx_stride;
00290 
00291     for (b_y = 0; b_y < h; b_y++) {
00292         for (b_x = 0; b_x < w - 1; b_x++) {
00293             int y;
00294             int left_status  = s->error_status_table[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride];
00295             int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
00296             int left_intra   = IS_INTRA(s->current_picture.f.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
00297             int right_intra  = IS_INTRA(s->current_picture.f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
00298             int left_damage  = left_status & ER_MB_ERROR;
00299             int right_damage = right_status & ER_MB_ERROR;
00300             int offset       = b_x * 8 + b_y * stride * 8;
00301             int16_t *left_mv  = s->current_picture.f.motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
00302             int16_t *right_mv = s->current_picture.f.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
00303             if (!(left_damage || right_damage))
00304                 continue; 
00305             if ((!left_intra) && (!right_intra) &&
00306                 FFABS(left_mv[0] - right_mv[0]) +
00307                 FFABS(left_mv[1] + right_mv[1]) < 2)
00308                 continue;
00309 
00310             for (y = 0; y < 8; y++) {
00311                 int a, b, c, d;
00312 
00313                 a = dst[offset + 7 + y * stride] - dst[offset + 6 + y * stride];
00314                 b = dst[offset + 8 + y * stride] - dst[offset + 7 + y * stride];
00315                 c = dst[offset + 9 + y * stride] - dst[offset + 8 + y * stride];
00316 
00317                 d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
00318                 d = FFMAX(d, 0);
00319                 if (b < 0)
00320                     d = -d;
00321 
00322                 if (d == 0)
00323                     continue;
00324 
00325                 if (!(left_damage && right_damage))
00326                     d = d * 16 / 9;
00327 
00328                 if (left_damage) {
00329                     dst[offset + 7 + y * stride] = cm[dst[offset + 7 + y * stride] + ((d * 7) >> 4)];
00330                     dst[offset + 6 + y * stride] = cm[dst[offset + 6 + y * stride] + ((d * 5) >> 4)];
00331                     dst[offset + 5 + y * stride] = cm[dst[offset + 5 + y * stride] + ((d * 3) >> 4)];
00332                     dst[offset + 4 + y * stride] = cm[dst[offset + 4 + y * stride] + ((d * 1) >> 4)];
00333                 }
00334                 if (right_damage) {
00335                     dst[offset + 8 + y * stride] = cm[dst[offset +  8 + y * stride] - ((d * 7) >> 4)];
00336                     dst[offset + 9 + y * stride] = cm[dst[offset +  9 + y * stride] - ((d * 5) >> 4)];
00337                     dst[offset + 10+ y * stride] = cm[dst[offset + 10 + y * stride] - ((d * 3) >> 4)];
00338                     dst[offset + 11+ y * stride] = cm[dst[offset + 11 + y * stride] - ((d * 1) >> 4)];
00339                 }
00340             }
00341         }
00342     }
00343 }
00344 
00350 static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h,
00351                            int stride, int is_luma)
00352 {
00353     int b_x, b_y, mvx_stride, mvy_stride;
00354     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
00355     set_mv_strides(s, &mvx_stride, &mvy_stride);
00356     mvx_stride >>= is_luma;
00357     mvy_stride *= mvx_stride;
00358 
00359     for (b_y = 0; b_y < h - 1; b_y++) {
00360         for (b_x = 0; b_x < w; b_x++) {
00361             int x;
00362             int top_status    = s->error_status_table[(b_x >> is_luma) +  (b_y      >> is_luma) * s->mb_stride];
00363             int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
00364             int top_intra     = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
00365             int bottom_intra  = IS_INTRA(s->current_picture.f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
00366             int top_damage    = top_status & ER_MB_ERROR;
00367             int bottom_damage = bottom_status & ER_MB_ERROR;
00368             int offset        = b_x * 8 + b_y * stride * 8;
00369 
00370             int16_t *top_mv    = s->current_picture.f.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
00371             int16_t *bottom_mv = s->current_picture.f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
00372 
00373             if (!(top_damage || bottom_damage))
00374                 continue; 
00375 
00376             if ((!top_intra) && (!bottom_intra) &&
00377                 FFABS(top_mv[0] - bottom_mv[0]) +
00378                 FFABS(top_mv[1] + bottom_mv[1]) < 2)
00379                 continue;
00380 
00381             for (x = 0; x < 8; x++) {
00382                 int a, b, c, d;
00383 
00384                 a = dst[offset + x + 7 * stride] - dst[offset + x + 6 * stride];
00385                 b = dst[offset + x + 8 * stride] - dst[offset + x + 7 * stride];
00386                 c = dst[offset + x + 9 * stride] - dst[offset + x + 8 * stride];
00387 
00388                 d = FFABS(b) - ((FFABS(a) + FFABS(c) + 1) >> 1);
00389                 d = FFMAX(d, 0);
00390                 if (b < 0)
00391                     d = -d;
00392 
00393                 if (d == 0)
00394                     continue;
00395 
00396                 if (!(top_damage && bottom_damage))
00397                     d = d * 16 / 9;
00398 
00399                 if (top_damage) {
00400                     dst[offset + x +  7 * stride] = cm[dst[offset + x +  7 * stride] + ((d * 7) >> 4)];
00401                     dst[offset + x +  6 * stride] = cm[dst[offset + x +  6 * stride] + ((d * 5) >> 4)];
00402                     dst[offset + x +  5 * stride] = cm[dst[offset + x +  5 * stride] + ((d * 3) >> 4)];
00403                     dst[offset + x +  4 * stride] = cm[dst[offset + x +  4 * stride] + ((d * 1) >> 4)];
00404                 }
00405                 if (bottom_damage) {
00406                     dst[offset + x +  8 * stride] = cm[dst[offset + x +  8 * stride] - ((d * 7) >> 4)];
00407                     dst[offset + x +  9 * stride] = cm[dst[offset + x +  9 * stride] - ((d * 5) >> 4)];
00408                     dst[offset + x + 10 * stride] = cm[dst[offset + x + 10 * stride] - ((d * 3) >> 4)];
00409                     dst[offset + x + 11 * stride] = cm[dst[offset + x + 11 * stride] - ((d * 1) >> 4)];
00410                 }
00411             }
00412         }
00413     }
00414 }
00415 
00416 static void guess_mv(MpegEncContext *s)
00417 {
00418     uint8_t *fixed = s->er_temp_buffer;
00419 #define MV_FROZEN    3
00420 #define MV_CHANGED   2
00421 #define MV_UNCHANGED 1
00422     const int mb_stride = s->mb_stride;
00423     const int mb_width  = s->mb_width;
00424     const int mb_height = s->mb_height;
00425     int i, depth, num_avail;
00426     int mb_x, mb_y, mot_step, mot_stride;
00427 
00428     set_mv_strides(s, &mot_step, &mot_stride);
00429 
00430     num_avail = 0;
00431     for (i = 0; i < s->mb_num; i++) {
00432         const int mb_xy = s->mb_index2xy[i];
00433         int f = 0;
00434         int error = s->error_status_table[mb_xy];
00435 
00436         if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
00437             f = MV_FROZEN; 
00438         if (!(error & ER_MV_ERROR))
00439             f = MV_FROZEN; 
00440 
00441         fixed[mb_xy] = f;
00442         if (f == MV_FROZEN)
00443             num_avail++;
00444         else if(s->last_picture.f.data[0] && s->last_picture.f.motion_val[0]){
00445             const int mb_y= mb_xy / s->mb_stride;
00446             const int mb_x= mb_xy % s->mb_stride;
00447             const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
00448             s->current_picture.f.motion_val[0][mot_index][0]= s->last_picture.f.motion_val[0][mot_index][0];
00449             s->current_picture.f.motion_val[0][mot_index][1]= s->last_picture.f.motion_val[0][mot_index][1];
00450             s->current_picture.f.ref_index[0][4*mb_xy]      = s->last_picture.f.ref_index[0][4*mb_xy];
00451         }
00452     }
00453 
00454     if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
00455         num_avail <= mb_width / 2) {
00456         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
00457             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
00458                 const int mb_xy = mb_x + mb_y * s->mb_stride;
00459 
00460                 if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
00461                     continue;
00462                 if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
00463                     continue;
00464 
00465                 s->mv_dir     = s->last_picture.f.data[0] ? MV_DIR_FORWARD
00466                                                           : MV_DIR_BACKWARD;
00467                 s->mb_intra   = 0;
00468                 s->mv_type    = MV_TYPE_16X16;
00469                 s->mb_skipped = 0;
00470 
00471                 s->dsp.clear_blocks(s->block[0]);
00472 
00473                 s->mb_x        = mb_x;
00474                 s->mb_y        = mb_y;
00475                 s->mv[0][0][0] = 0;
00476                 s->mv[0][0][1] = 0;
00477                 decode_mb(s, 0);
00478             }
00479         }
00480         return;
00481     }
00482 
00483     for (depth = 0; ; depth++) {
00484         int changed, pass, none_left;
00485 
00486         none_left = 1;
00487         changed   = 1;
00488         for (pass = 0; (changed || pass < 2) && pass < 10; pass++) {
00489             int mb_x, mb_y;
00490             int score_sum = 0;
00491 
00492             changed = 0;
00493             for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
00494                 for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
00495                     const int mb_xy        = mb_x + mb_y * s->mb_stride;
00496                     int mv_predictor[8][2] = { { 0 } };
00497                     int ref[8]             = { 0 };
00498                     int pred_count         = 0;
00499                     int j;
00500                     int best_score         = 256 * 256 * 256 * 64;
00501                     int best_pred          = 0;
00502                     const int mot_index    = (mb_x + mb_y * mot_stride) * mot_step;
00503                     int prev_x, prev_y, prev_ref;
00504 
00505                     if ((mb_x ^ mb_y ^ pass) & 1)
00506                         continue;
00507 
00508                     if (fixed[mb_xy] == MV_FROZEN)
00509                         continue;
00510                     av_assert1(!IS_INTRA(s->current_picture.f.mb_type[mb_xy]));
00511                     av_assert1(s->last_picture_ptr && s->last_picture_ptr->f.data[0]);
00512 
00513                     j = 0;
00514                     if (mb_x > 0             && fixed[mb_xy - 1]         == MV_FROZEN)
00515                         j = 1;
00516                     if (mb_x + 1 < mb_width  && fixed[mb_xy + 1]         == MV_FROZEN)
00517                         j = 1;
00518                     if (mb_y > 0             && fixed[mb_xy - mb_stride] == MV_FROZEN)
00519                         j = 1;
00520                     if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_FROZEN)
00521                         j = 1;
00522                     if (j == 0)
00523                         continue;
00524 
00525                     j = 0;
00526                     if (mb_x > 0             && fixed[mb_xy - 1        ] == MV_CHANGED)
00527                         j = 1;
00528                     if (mb_x + 1 < mb_width  && fixed[mb_xy + 1        ] == MV_CHANGED)
00529                         j = 1;
00530                     if (mb_y > 0             && fixed[mb_xy - mb_stride] == MV_CHANGED)
00531                         j = 1;
00532                     if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride] == MV_CHANGED)
00533                         j = 1;
00534                     if (j == 0 && pass > 1)
00535                         continue;
00536 
00537                     none_left = 0;
00538 
00539                     if (mb_x > 0 && fixed[mb_xy - 1]) {
00540                         mv_predictor[pred_count][0] =
00541                             s->current_picture.f.motion_val[0][mot_index - mot_step][0];
00542                         mv_predictor[pred_count][1] =
00543                             s->current_picture.f.motion_val[0][mot_index - mot_step][1];
00544                         ref[pred_count] =
00545                             s->current_picture.f.ref_index[0][4 * (mb_xy - 1)];
00546                         pred_count++;
00547                     }
00548                     if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
00549                         mv_predictor[pred_count][0] =
00550                             s->current_picture.f.motion_val[0][mot_index + mot_step][0];
00551                         mv_predictor[pred_count][1] =
00552                             s->current_picture.f.motion_val[0][mot_index + mot_step][1];
00553                         ref[pred_count] =
00554                             s->current_picture.f.ref_index[0][4 * (mb_xy + 1)];
00555                         pred_count++;
00556                     }
00557                     if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
00558                         mv_predictor[pred_count][0] =
00559                             s->current_picture.f.motion_val[0][mot_index - mot_stride * mot_step][0];
00560                         mv_predictor[pred_count][1] =
00561                             s->current_picture.f.motion_val[0][mot_index - mot_stride * mot_step][1];
00562                         ref[pred_count] =
00563                             s->current_picture.f.ref_index[0][4 * (mb_xy - s->mb_stride)];
00564                         pred_count++;
00565                     }
00566                     if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {
00567                         mv_predictor[pred_count][0] =
00568                             s->current_picture.f.motion_val[0][mot_index + mot_stride * mot_step][0];
00569                         mv_predictor[pred_count][1] =
00570                             s->current_picture.f.motion_val[0][mot_index + mot_stride * mot_step][1];
00571                         ref[pred_count] =
00572                             s->current_picture.f.ref_index[0][4 * (mb_xy + s->mb_stride)];
00573                         pred_count++;
00574                     }
00575                     if (pred_count == 0)
00576                         continue;
00577 
00578                     if (pred_count > 1) {
00579                         int sum_x = 0, sum_y = 0, sum_r = 0;
00580                         int max_x, max_y, min_x, min_y, max_r, min_r;
00581 
00582                         for (j = 0; j < pred_count; j++) {
00583                             sum_x += mv_predictor[j][0];
00584                             sum_y += mv_predictor[j][1];
00585                             sum_r += ref[j];
00586                             if (j && ref[j] != ref[j - 1])
00587                                 goto skip_mean_and_median;
00588                         }
00589 
00590                         
00591                         mv_predictor[pred_count][0] = sum_x / j;
00592                         mv_predictor[pred_count][1] = sum_y / j;
00593                                  ref[pred_count]    = sum_r / j;
00594 
00595                         
00596                         if (pred_count >= 3) {
00597                             min_y = min_x = min_r =  99999;
00598                             max_y = max_x = max_r = -99999;
00599                         } else {
00600                             min_x = min_y = max_x = max_y = min_r = max_r = 0;
00601                         }
00602                         for (j = 0; j < pred_count; j++) {
00603                             max_x = FFMAX(max_x, mv_predictor[j][0]);
00604                             max_y = FFMAX(max_y, mv_predictor[j][1]);
00605                             max_r = FFMAX(max_r, ref[j]);
00606                             min_x = FFMIN(min_x, mv_predictor[j][0]);
00607                             min_y = FFMIN(min_y, mv_predictor[j][1]);
00608                             min_r = FFMIN(min_r, ref[j]);
00609                         }
00610                         mv_predictor[pred_count + 1][0] = sum_x - max_x - min_x;
00611                         mv_predictor[pred_count + 1][1] = sum_y - max_y - min_y;
00612                                  ref[pred_count + 1]    = sum_r - max_r - min_r;
00613 
00614                         if (pred_count == 4) {
00615                             mv_predictor[pred_count + 1][0] /= 2;
00616                             mv_predictor[pred_count + 1][1] /= 2;
00617                                      ref[pred_count + 1]    /= 2;
00618                         }
00619                         pred_count += 2;
00620                     }
00621 
00622 skip_mean_and_median:
00623                     
00624                     pred_count++;
00625 
00626                     if (!fixed[mb_xy] && 0) {
00627                         if (s->avctx->codec_id == AV_CODEC_ID_H264) {
00628                             
00629                         } else {
00630                             ff_thread_await_progress(&s->last_picture_ptr->f,
00631                                                      mb_y, 0);
00632                         }
00633                         if (!s->last_picture.f.motion_val[0] ||
00634                             !s->last_picture.f.ref_index[0])
00635                             goto skip_last_mv;
00636                         prev_x   = s->last_picture.f.motion_val[0][mot_index][0];
00637                         prev_y   = s->last_picture.f.motion_val[0][mot_index][1];
00638                         prev_ref = s->last_picture.f.ref_index[0][4 * mb_xy];
00639                     } else {
00640                         prev_x   = s->current_picture.f.motion_val[0][mot_index][0];
00641                         prev_y   = s->current_picture.f.motion_val[0][mot_index][1];
00642                         prev_ref = s->current_picture.f.ref_index[0][4 * mb_xy];
00643                     }
00644 
00645                     
00646                     mv_predictor[pred_count][0] = prev_x;
00647                     mv_predictor[pred_count][1] = prev_y;
00648                              ref[pred_count]    = prev_ref;
00649                     pred_count++;
00650 
00651 skip_last_mv:
00652                     s->mv_dir     = MV_DIR_FORWARD;
00653                     s->mb_intra   = 0;
00654                     s->mv_type    = MV_TYPE_16X16;
00655                     s->mb_skipped = 0;
00656 
00657                     s->dsp.clear_blocks(s->block[0]);
00658 
00659                     s->mb_x = mb_x;
00660                     s->mb_y = mb_y;
00661 
00662                     for (j = 0; j < pred_count; j++) {
00663                         int score = 0;
00664                         uint8_t *src = s->current_picture.f.data[0] +
00665                                        mb_x * 16 + mb_y * 16 * s->linesize;
00666 
00667                         s->current_picture.f.motion_val[0][mot_index][0] =
00668                             s->mv[0][0][0] = mv_predictor[j][0];
00669                         s->current_picture.f.motion_val[0][mot_index][1] =
00670                             s->mv[0][0][1] = mv_predictor[j][1];
00671 
00672                         
00673                         if (ref[j] < 0)
00674                             continue;
00675 
00676                         decode_mb(s, ref[j]);
00677 
00678                         if (mb_x > 0 && fixed[mb_xy - 1]) {
00679                             int k;
00680                             for (k = 0; k < 16; k++)
00681                                 score += FFABS(src[k * s->linesize - 1] -
00682                                                src[k * s->linesize]);
00683                         }
00684                         if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
00685                             int k;
00686                             for (k = 0; k < 16; k++)
00687                                 score += FFABS(src[k * s->linesize + 15] -
00688                                                src[k * s->linesize + 16]);
00689                         }
00690                         if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
00691                             int k;
00692                             for (k = 0; k < 16; k++)
00693                                 score += FFABS(src[k - s->linesize] - src[k]);
00694                         }
00695                         if (mb_y + 1 < mb_height && fixed[mb_xy + mb_stride]) {
00696                             int k;
00697                             for (k = 0; k < 16; k++)
00698                                 score += FFABS(src[k + s->linesize * 15] -
00699                                                src[k + s->linesize * 16]);
00700                         }
00701 
00702                         if (score <= best_score) { 
00703                             best_score = score;
00704                             best_pred  = j;
00705                         }
00706                     }
00707                     score_sum += best_score;
00708                     s->mv[0][0][0] = mv_predictor[best_pred][0];
00709                     s->mv[0][0][1] = mv_predictor[best_pred][1];
00710 
00711                     for (i = 0; i < mot_step; i++)
00712                         for (j = 0; j < mot_step; j++) {
00713                             s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
00714                             s->current_picture.f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
00715                         }
00716 
00717                     decode_mb(s, ref[best_pred]);
00718 
00719 
00720                     if (s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y) {
00721                         fixed[mb_xy] = MV_CHANGED;
00722                         changed++;
00723                     } else
00724                         fixed[mb_xy] = MV_UNCHANGED;
00725                 }
00726             }
00727 
00728             
00729         }
00730 
00731         if (none_left)
00732             return;
00733 
00734         for (i = 0; i < s->mb_num; i++) {
00735             int mb_xy = s->mb_index2xy[i];
00736             if (fixed[mb_xy])
00737                 fixed[mb_xy] = MV_FROZEN;
00738         }
00739         
00740     }
00741 }
00742 
00743 static int is_intra_more_likely(MpegEncContext *s)
00744 {
00745     int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
00746 
00747     if (!s->last_picture_ptr || !s->last_picture_ptr->f.data[0])
00748         return 1; 
00749 
00750     undamaged_count = 0;
00751     for (i = 0; i < s->mb_num; i++) {
00752         const int mb_xy = s->mb_index2xy[i];
00753         const int error = s->error_status_table[mb_xy];
00754         if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
00755             undamaged_count++;
00756     }
00757 
00758     if (s->codec_id == AV_CODEC_ID_H264) {
00759         H264Context *h = (void*) s;
00760         if (h->list_count <= 0 || h->ref_count[0] <= 0 ||
00761             !h->ref_list[0][0].f.data[0])
00762             return 1;
00763     }
00764 
00765     if (undamaged_count < 5)
00766         return 0; 
00767 
00768     
00769     if (CONFIG_MPEG_XVMC_DECODER    &&
00770         s->avctx->xvmc_acceleration &&
00771         s->pict_type == AV_PICTURE_TYPE_I)
00772         return 1;
00773 
00774     skip_amount     = FFMAX(undamaged_count / 50, 1); 
00775     is_intra_likely = 0;
00776 
00777     j = 0;
00778     for (mb_y = 0; mb_y < s->mb_height - 1; mb_y++) {
00779         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
00780             int error;
00781             const int mb_xy = mb_x + mb_y * s->mb_stride;
00782 
00783             error = s->error_status_table[mb_xy];
00784             if ((error & ER_DC_ERROR) && (error & ER_MV_ERROR))
00785                 continue; 
00786 
00787             j++;
00788             
00789             if ((j % skip_amount) != 0)
00790                 continue;
00791 
00792             if (s->pict_type == AV_PICTURE_TYPE_I) {
00793                 uint8_t *mb_ptr      = s->current_picture.f.data[0] +
00794                                        mb_x * 16 + mb_y * 16 * s->linesize;
00795                 uint8_t *last_mb_ptr = s->last_picture.f.data[0] +
00796                                        mb_x * 16 + mb_y * 16 * s->linesize;
00797 
00798                 if (s->avctx->codec_id == AV_CODEC_ID_H264) {
00799                     
00800                 } else {
00801                     ff_thread_await_progress(&s->last_picture_ptr->f,
00802                                              mb_y, 0);
00803                 }
00804                 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 16);
00805                 
00806                 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
00807             } else {
00808                 if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
00809                    is_intra_likely++;
00810                 else
00811                    is_intra_likely--;
00812             }
00813         }
00814     }
00815     
00816     return is_intra_likely > 0;
00817 }
00818 
00819 void ff_er_frame_start(MpegEncContext *s)
00820 {
00821     if (!s->err_recognition)
00822         return;
00823 
00824     memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
00825            s->mb_stride * s->mb_height * sizeof(uint8_t));
00826     s->error_count    = 3 * s->mb_num;
00827     s->error_occurred = 0;
00828 }
00829 
00837 void ff_er_add_slice(MpegEncContext *s, int startx, int starty,
00838                      int endx, int endy, int status)
00839 {
00840     const int start_i  = av_clip(startx + starty * s->mb_width, 0, s->mb_num - 1);
00841     const int end_i    = av_clip(endx   + endy   * s->mb_width, 0, s->mb_num);
00842     const int start_xy = s->mb_index2xy[start_i];
00843     const int end_xy   = s->mb_index2xy[end_i];
00844     int mask           = -1;
00845 
00846     if (s->avctx->hwaccel)
00847         return;
00848 
00849     if (start_i > end_i || start_xy > end_xy) {
00850         av_log(s->avctx, AV_LOG_ERROR,
00851                "internal error, slice end before start\n");
00852         return;
00853     }
00854 
00855     if (!s->err_recognition)
00856         return;
00857 
00858     mask &= ~VP_START;
00859     if (status & (ER_AC_ERROR | ER_AC_END)) {
00860         mask           &= ~(ER_AC_ERROR | ER_AC_END);
00861         s->error_count -= end_i - start_i + 1;
00862     }
00863     if (status & (ER_DC_ERROR | ER_DC_END)) {
00864         mask           &= ~(ER_DC_ERROR | ER_DC_END);
00865         s->error_count -= end_i - start_i + 1;
00866     }
00867     if (status & (ER_MV_ERROR | ER_MV_END)) {
00868         mask           &= ~(ER_MV_ERROR | ER_MV_END);
00869         s->error_count -= end_i - start_i + 1;
00870     }
00871 
00872     if (status & ER_MB_ERROR) {
00873         s->error_occurred = 1;
00874         s->error_count    = INT_MAX;
00875     }
00876 
00877     if (mask == ~0x7F) {
00878         memset(&s->error_status_table[start_xy], 0,
00879                (end_xy - start_xy) * sizeof(uint8_t));
00880     } else {
00881         int i;
00882         for (i = start_xy; i < end_xy; i++)
00883             s->error_status_table[i] &= mask;
00884     }
00885 
00886     if (end_i == s->mb_num)
00887         s->error_count = INT_MAX;
00888     else {
00889         s->error_status_table[end_xy] &= mask;
00890         s->error_status_table[end_xy] |= status;
00891     }
00892 
00893     s->error_status_table[start_xy] |= VP_START;
00894 
00895     if (start_xy > 0 && s->avctx->thread_count <= 1 &&
00896         s->avctx->skip_top * s->mb_width < start_i) {
00897         int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]];
00898 
00899         prev_status &= ~ VP_START;
00900         if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END))
00901             s->error_count = INT_MAX;
00902     }
00903 }
00904 
00905 void ff_er_frame_end(MpegEncContext *s)
00906 {
00907     int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
00908     int distance;
00909     int threshold_part[4] = { 100, 100, 100 };
00910     int threshold = 50;
00911     int is_intra_likely;
00912     int size = s->b8_stride * 2 * s->mb_height;
00913     Picture *pic = s->current_picture_ptr;
00914 
00915     
00916 
00917     if (!s->err_recognition || s->error_count == 0 || s->avctx->lowres ||
00918         s->avctx->hwaccel                                              ||
00919         s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU          ||
00920         s->picture_structure != PICT_FRAME                             ||
00921         s->error_count == 3 * s->mb_width *
00922                           (s->avctx->skip_top + s->avctx->skip_bottom)) {
00923         return;
00924     };
00925 
00926     if (s->current_picture.f.motion_val[0] == NULL) {
00927         av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
00928 
00929         for (i = 0; i < 2; i++) {
00930             pic->f.ref_index[i]     = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
00931             pic->motion_val_base[i] = av_mallocz((size + 4) * 2 * sizeof(uint16_t));
00932             pic->f.motion_val[i]    = pic->motion_val_base[i] + 4;
00933         }
00934         pic->f.motion_subsample_log2 = 3;
00935         s->current_picture = *s->current_picture_ptr;
00936     }
00937 
00938     if (s->avctx->debug & FF_DEBUG_ER) {
00939         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
00940             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
00941                 int status = s->error_status_table[mb_x + mb_y * s->mb_stride];
00942 
00943                 av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
00944             }
00945             av_log(s->avctx, AV_LOG_DEBUG, "\n");
00946         }
00947     }
00948 
00949 #if 1
00950     
00951     for (error_type = 1; error_type <= 3; error_type++) {
00952         int end_ok = 0;
00953 
00954         for (i = s->mb_num - 1; i >= 0; i--) {
00955             const int mb_xy = s->mb_index2xy[i];
00956             int error       = s->error_status_table[mb_xy];
00957 
00958             if (error & (1 << error_type))
00959                 end_ok = 1;
00960             if (error & (8 << error_type))
00961                 end_ok = 1;
00962 
00963             if (!end_ok)
00964                 s->error_status_table[mb_xy] |= 1 << error_type;
00965 
00966             if (error & VP_START)
00967                 end_ok = 0;
00968         }
00969     }
00970 #endif
00971 #if 1
00972     
00973     if (s->partitioned_frame) {
00974         int end_ok = 0;
00975 
00976         for (i = s->mb_num - 1; i >= 0; i--) {
00977             const int mb_xy = s->mb_index2xy[i];
00978             int error       = s->error_status_table[mb_xy];
00979 
00980             if (error & ER_AC_END)
00981                 end_ok = 0;
00982             if ((error & ER_MV_END) ||
00983                 (error & ER_DC_END) ||
00984                 (error & ER_AC_ERROR))
00985                 end_ok = 1;
00986 
00987             if (!end_ok)
00988                 s->error_status_table[mb_xy]|= ER_AC_ERROR;
00989 
00990             if (error & VP_START)
00991                 end_ok = 0;
00992         }
00993     }
00994 #endif
00995     
00996     if (s->err_recognition & AV_EF_EXPLODE) {
00997         int end_ok = 1;
00998 
00999         
01000         for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {
01001             const int mb_xy = s->mb_index2xy[i];
01002             int error1 = s->error_status_table[mb_xy];
01003             int error2 = s->error_status_table[s->mb_index2xy[i + 1]];
01004 
01005             if (error1 & VP_START)
01006                 end_ok = 1;
01007 
01008             if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&
01009                 error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&
01010                 ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||
01011                 (error1 & ER_MV_END))) {
01012                 
01013                 end_ok = 0;
01014             }
01015 
01016             if (!end_ok)
01017                 s->error_status_table[mb_xy] |= ER_MB_ERROR;
01018         }
01019     }
01020 
01021 #if 1
01022     
01023     distance = 9999999;
01024     for (error_type = 1; error_type <= 3; error_type++) {
01025         for (i = s->mb_num - 1; i >= 0; i--) {
01026             const int mb_xy = s->mb_index2xy[i];
01027             int       error = s->error_status_table[mb_xy];
01028 
01029             if (!s->mbskip_table[mb_xy]) 
01030                 distance++;
01031             if (error & (1 << error_type))
01032                 distance = 0;
01033 
01034             if (s->partitioned_frame) {
01035                 if (distance < threshold_part[error_type - 1])
01036                     s->error_status_table[mb_xy] |= 1 << error_type;
01037             } else {
01038                 if (distance < threshold)
01039                     s->error_status_table[mb_xy] |= 1 << error_type;
01040             }
01041 
01042             if (error & VP_START)
01043                 distance = 9999999;
01044         }
01045     }
01046 #endif
01047 
01048     
01049     error = 0;
01050     for (i = 0; i < s->mb_num; i++) {
01051         const int mb_xy = s->mb_index2xy[i];
01052         int old_error   = s->error_status_table[mb_xy];
01053 
01054         if (old_error & VP_START) {
01055             error = old_error & ER_MB_ERROR;
01056         } else {
01057             error |= old_error & ER_MB_ERROR;
01058             s->error_status_table[mb_xy] |= error;
01059         }
01060     }
01061 #if 1
01062     
01063     if (!s->partitioned_frame) {
01064         for (i = 0; i < s->mb_num; i++) {
01065             const int mb_xy = s->mb_index2xy[i];
01066             error = s->error_status_table[mb_xy];
01067             if (error & ER_MB_ERROR)
01068                 error |= ER_MB_ERROR;
01069             s->error_status_table[mb_xy] = error;
01070         }
01071     }
01072 #endif
01073 
01074     dc_error = ac_error = mv_error = 0;
01075     for (i = 0; i < s->mb_num; i++) {
01076         const int mb_xy = s->mb_index2xy[i];
01077         error = s->error_status_table[mb_xy];
01078         if (error & ER_DC_ERROR)
01079             dc_error++;
01080         if (error & ER_AC_ERROR)
01081             ac_error++;
01082         if (error & ER_MV_ERROR)
01083             mv_error++;
01084     }
01085     av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",
01086            dc_error, ac_error, mv_error, av_get_picture_type_char(s->pict_type));
01087 
01088     is_intra_likely = is_intra_more_likely(s);
01089 
01090     
01091     for (i = 0; i < s->mb_num; i++) {
01092         const int mb_xy = s->mb_index2xy[i];
01093         error = s->error_status_table[mb_xy];
01094         if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))
01095             continue;
01096 
01097         if (is_intra_likely)
01098             s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
01099         else
01100             s->current_picture.f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
01101     }
01102 
01103     
01104     if (!s->last_picture.f.data[0] && !s->next_picture.f.data[0])
01105         for (i = 0; i < s->mb_num; i++) {
01106             const int mb_xy = s->mb_index2xy[i];
01107             if (!IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
01108                 s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
01109         }
01110 
01111     
01112     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
01113         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
01114             const int mb_xy   = mb_x + mb_y * s->mb_stride;
01115             const int mb_type = s->current_picture.f.mb_type[mb_xy];
01116             int dir           = !s->last_picture.f.data[0];
01117 
01118             error = s->error_status_table[mb_xy];
01119 
01120             if (IS_INTRA(mb_type))
01121                 continue; 
01122             if (error & ER_MV_ERROR)
01123                 continue; 
01124             if (!(error & ER_AC_ERROR))
01125                 continue; 
01126 
01127             s->mv_dir     = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
01128             s->mb_intra   = 0;
01129             s->mb_skipped = 0;
01130             if (IS_8X8(mb_type)) {
01131                 int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;
01132                 int j;
01133                 s->mv_type = MV_TYPE_8X8;
01134                 for (j = 0; j < 4; j++) {
01135                     s->mv[0][j][0] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
01136                     s->mv[0][j][1] = s->current_picture.f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
01137                 }
01138             } else {
01139                 s->mv_type     = MV_TYPE_16X16;
01140                 s->mv[0][0][0] = s->current_picture.f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
01141                 s->mv[0][0][1] = s->current_picture.f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
01142             }
01143 
01144             s->dsp.clear_blocks(s->block[0]);
01145 
01146             s->mb_x = mb_x;
01147             s->mb_y = mb_y;
01148             decode_mb(s, 0 );
01149         }
01150     }
01151 
01152     
01153     if (s->pict_type == AV_PICTURE_TYPE_B) {
01154         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
01155             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
01156                 int       xy      = mb_x * 2 + mb_y * 2 * s->b8_stride;
01157                 const int mb_xy   = mb_x + mb_y * s->mb_stride;
01158                 const int mb_type = s->current_picture.f.mb_type[mb_xy];
01159 
01160                 error = s->error_status_table[mb_xy];
01161 
01162                 if (IS_INTRA(mb_type))
01163                     continue;
01164                 if (!(error & ER_MV_ERROR))
01165                     continue; 
01166                 if (!(error & ER_AC_ERROR))
01167                     continue; 
01168 
01169                 s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
01170                 if (!s->last_picture.f.data[0])
01171                     s->mv_dir &= ~MV_DIR_FORWARD;
01172                 if (!s->next_picture.f.data[0])
01173                     s->mv_dir &= ~MV_DIR_BACKWARD;
01174                 s->mb_intra   = 0;
01175                 s->mv_type    = MV_TYPE_16X16;
01176                 s->mb_skipped = 0;
01177 
01178                 if (s->pp_time) {
01179                     int time_pp = s->pp_time;
01180                     int time_pb = s->pb_time;
01181 
01182                     if (s->avctx->codec_id == AV_CODEC_ID_H264) {
01183                         
01184                     } else {
01185                         ff_thread_await_progress(&s->next_picture_ptr->f, mb_y, 0);
01186                     }
01187                     s->mv[0][0][0] = s->next_picture.f.motion_val[0][xy][0] *  time_pb            / time_pp;
01188                     s->mv[0][0][1] = s->next_picture.f.motion_val[0][xy][1] *  time_pb            / time_pp;
01189                     s->mv[1][0][0] = s->next_picture.f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
01190                     s->mv[1][0][1] = s->next_picture.f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
01191                 } else {
01192                     s->mv[0][0][0] = 0;
01193                     s->mv[0][0][1] = 0;
01194                     s->mv[1][0][0] = 0;
01195                     s->mv[1][0][1] = 0;
01196                 }
01197 
01198                 s->dsp.clear_blocks(s->block[0]);
01199                 s->mb_x = mb_x;
01200                 s->mb_y = mb_y;
01201                 decode_mb(s, 0);
01202             }
01203         }
01204     } else
01205         guess_mv(s);
01206 
01207     
01208     if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
01209         goto ec_clean;
01210     
01211     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
01212         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
01213             int dc, dcu, dcv, y, n;
01214             int16_t *dc_ptr;
01215             uint8_t *dest_y, *dest_cb, *dest_cr;
01216             const int mb_xy   = mb_x + mb_y * s->mb_stride;
01217             const int mb_type = s->current_picture.f.mb_type[mb_xy];
01218 
01219             error = s->error_status_table[mb_xy];
01220 
01221             if (IS_INTRA(mb_type) && s->partitioned_frame)
01222                 continue;
01223             
01224             
01225 
01226             dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
01227             dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
01228             dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
01229 
01230             dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];
01231             for (n = 0; n < 4; n++) {
01232                 dc = 0;
01233                 for (y = 0; y < 8; y++) {
01234                     int x;
01235                     for (x = 0; x < 8; x++)
01236                        dc += dest_y[x + (n & 1) * 8 +
01237                              (y + (n >> 1) * 8) * s->linesize];
01238                 }
01239                 dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;
01240             }
01241 
01242             dcu = dcv = 0;
01243             for (y = 0; y < 8; y++) {
01244                 int x;
01245                 for (x = 0; x < 8; x++) {
01246                     dcu += dest_cb[x + y * s->uvlinesize];
01247                     dcv += dest_cr[x + y * s->uvlinesize];
01248                 }
01249             }
01250             s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;
01251             s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
01252         }
01253     }
01254 #if 1
01255     
01256     guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
01257     guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
01258     guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
01259 #endif
01260 
01261     
01262     filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
01263 
01264 #if 1
01265     
01266     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
01267         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
01268             uint8_t *dest_y, *dest_cb, *dest_cr;
01269             const int mb_xy   = mb_x + mb_y * s->mb_stride;
01270             const int mb_type = s->current_picture.f.mb_type[mb_xy];
01271 
01272             error = s->error_status_table[mb_xy];
01273 
01274             if (IS_INTER(mb_type))
01275                 continue;
01276             if (!(error & ER_AC_ERROR))
01277                 continue; 
01278 
01279             dest_y  = s->current_picture.f.data[0] + mb_x * 16 + mb_y * 16 * s->linesize;
01280             dest_cb = s->current_picture.f.data[1] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
01281             dest_cr = s->current_picture.f.data[2] + mb_x *  8 + mb_y *  8 * s->uvlinesize;
01282 
01283             put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
01284         }
01285     }
01286 #endif
01287 
01288     if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
01289         
01290         h_block_filter(s, s->current_picture.f.data[0], s->mb_width * 2,
01291                        s->mb_height * 2, s->linesize, 1);
01292         h_block_filter(s, s->current_picture.f.data[1], s->mb_width,
01293                        s->mb_height  , s->uvlinesize, 0);
01294         h_block_filter(s, s->current_picture.f.data[2], s->mb_width,
01295                        s->mb_height  , s->uvlinesize, 0);
01296 
01297         
01298         v_block_filter(s, s->current_picture.f.data[0], s->mb_width * 2,
01299                        s->mb_height * 2, s->linesize, 1);
01300         v_block_filter(s, s->current_picture.f.data[1], s->mb_width,
01301                        s->mb_height  , s->uvlinesize, 0);
01302         v_block_filter(s, s->current_picture.f.data[2], s->mb_width,
01303                        s->mb_height  , s->uvlinesize, 0);
01304     }
01305 
01306 ec_clean:
01307     
01308     for (i = 0; i < s->mb_num; i++) {
01309         const int mb_xy = s->mb_index2xy[i];
01310         int       error = s->error_status_table[mb_xy];
01311 
01312         if (s->pict_type != AV_PICTURE_TYPE_B &&
01313             (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {
01314             s->mbskip_table[mb_xy] = 0;
01315         }
01316         s->mbintra_table[mb_xy] = 1;
01317     }
01318 }