2 * Error resilience / concealment
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
6 * This file is part of FFmpeg.
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.
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.
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
25 * Error resilience / concealment.
32 #include "mpegvideo.h"
34 #include "rectangle.h"
37 * H264 redefines mb_intra so it is not mistakely used (its uninitialized in h264)
38 * but error concealment must support both h264 and h263 thus we must undo this
42 static void decode_mb(MpegEncContext *s, int ref){
43 s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16;
44 s->dest[1] = s->current_picture.data[1] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
45 s->dest[2] = s->current_picture.data[2] + (s->mb_y * (16>>s->chroma_y_shift) * s->uvlinesize) + s->mb_x * (16>>s->chroma_x_shift);
47 if(CONFIG_H264_DECODER && s->codec_id == CODEC_ID_H264){
48 H264Context *h= (void*)s;
49 h->mb_xy= s->mb_x + s->mb_y*s->mb_stride;
50 memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
52 if(ref >= h->ref_count[0]) //FIXME it is posible albeit uncommon that slice references differ between slices, we take the easy approuch and ignore it for now. If this turns out to have any relevance in practice then correct remapping should be added
54 fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
55 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
56 fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
58 ff_h264_hl_decode_mb(h);
61 MPV_decode_mb(s, s->block);
66 * @param stride the number of MVs to get to the next row
67 * @param mv_step the number of MVs per row or column in a macroblock
69 static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){
70 if(s->codec_id == CODEC_ID_H264){
71 H264Context *h= (void*)s;
72 assert(s->quarter_sample);
77 *stride= s->b8_stride;
82 * replaces the current MB with a flat dc only version.
84 static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
86 int dc, dcu, dcv, y, i;
88 dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
90 else if(dc>2040) dc=2040;
94 dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8;
98 dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride];
99 dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride];
101 else if(dcu>2040) dcu=2040;
103 else if(dcv>2040) dcv=2040;
107 dest_cb[x + y*(s->uvlinesize)]= dcu/8;
108 dest_cr[x + y*(s->uvlinesize)]= dcv/8;
113 static void filter181(int16_t *data, int width, int height, int stride){
116 /* horizontal filter */
117 for(y=1; y<height-1; y++){
118 int prev_dc= data[0 + y*stride];
120 for(x=1; x<width-1; x++){
124 + data[x + y*stride]*8
125 - data[x + 1 + y*stride];
126 dc= (dc*10923 + 32768)>>16;
127 prev_dc= data[x + y*stride];
128 data[x + y*stride]= dc;
132 /* vertical filter */
133 for(x=1; x<width-1; x++){
134 int prev_dc= data[x];
136 for(y=1; y<height-1; y++){
140 + data[x + y *stride]*8
141 - data[x + (y+1)*stride];
142 dc= (dc*10923 + 32768)>>16;
143 prev_dc= data[x + y*stride];
144 data[x + y*stride]= dc;
150 * guess the dc of blocks which do not have an undamaged dc
151 * @param w width in 8 pixel blocks
152 * @param h height in 8 pixel blocks
154 static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
157 for(b_y=0; b_y<h; b_y++){
158 for(b_x=0; b_x<w; b_x++){
159 int color[4]={1024,1024,1024,1024};
160 int distance[4]={9999,9999,9999,9999};
161 int mb_index, error, j;
162 int64_t guess, weight_sum;
164 mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
166 error= s->error_status_table[mb_index];
168 if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
169 if(!(error&DC_ERROR)) continue; //dc-ok
172 for(j=b_x+1; j<w; j++){
173 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
174 int error_j= s->error_status_table[mb_index_j];
175 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
176 if(intra_j==0 || !(error_j&DC_ERROR)){
177 color[0]= dc[j + b_y*stride];
184 for(j=b_x-1; j>=0; j--){
185 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
186 int error_j= s->error_status_table[mb_index_j];
187 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
188 if(intra_j==0 || !(error_j&DC_ERROR)){
189 color[1]= dc[j + b_y*stride];
196 for(j=b_y+1; j<h; j++){
197 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
198 int error_j= s->error_status_table[mb_index_j];
199 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
200 if(intra_j==0 || !(error_j&DC_ERROR)){
201 color[2]= dc[b_x + j*stride];
208 for(j=b_y-1; j>=0; j--){
209 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
210 int error_j= s->error_status_table[mb_index_j];
211 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
212 if(intra_j==0 || !(error_j&DC_ERROR)){
213 color[3]= dc[b_x + j*stride];
222 int64_t weight= 256*256*256*16/distance[j];
223 guess+= weight*(int64_t)color[j];
226 guess= (guess + weight_sum/2) / weight_sum;
228 dc[b_x + b_y*stride]= guess;
234 * simple horizontal deblocking filter used for error resilience
235 * @param w width in 8 pixel blocks
236 * @param h height in 8 pixel blocks
238 static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
239 int b_x, b_y, mvx_stride, mvy_stride;
240 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
241 set_mv_strides(s, &mvx_stride, &mvy_stride);
242 mvx_stride >>= is_luma;
243 mvy_stride *= mvx_stride;
245 for(b_y=0; b_y<h; b_y++){
246 for(b_x=0; b_x<w-1; b_x++){
248 int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride];
249 int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
250 int left_intra= IS_INTRA(s->current_picture.mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
251 int right_intra= IS_INTRA(s->current_picture.mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
252 int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
253 int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
254 int offset= b_x*8 + b_y*stride*8;
255 int16_t *left_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride* b_x ];
256 int16_t *right_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
258 if(!(left_damage||right_damage)) continue; // both undamaged
260 if( (!left_intra) && (!right_intra)
261 && FFABS(left_mv[0]-right_mv[0]) + FFABS(left_mv[1]+right_mv[1]) < 2) continue;
266 a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride];
267 b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride];
268 c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride];
270 d= FFABS(b) - ((FFABS(a) + FFABS(c) + 1)>>1);
276 if(!(left_damage && right_damage))
280 dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)];
281 dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)];
282 dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)];
283 dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)];
286 dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)];
287 dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)];
288 dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)];
289 dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)];
297 * simple vertical deblocking filter used for error resilience
298 * @param w width in 8 pixel blocks
299 * @param h height in 8 pixel blocks
301 static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
302 int b_x, b_y, mvx_stride, mvy_stride;
303 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
304 set_mv_strides(s, &mvx_stride, &mvy_stride);
305 mvx_stride >>= is_luma;
306 mvy_stride *= mvx_stride;
308 for(b_y=0; b_y<h-1; b_y++){
309 for(b_x=0; b_x<w; b_x++){
311 int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride];
312 int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
313 int top_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]);
314 int bottom_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
315 int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
316 int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
317 int offset= b_x*8 + b_y*stride*8;
318 int16_t *top_mv= s->current_picture.motion_val[0][mvy_stride* b_y + mvx_stride*b_x];
319 int16_t *bottom_mv= s->current_picture.motion_val[0][mvy_stride*(b_y+1) + mvx_stride*b_x];
321 if(!(top_damage||bottom_damage)) continue; // both undamaged
323 if( (!top_intra) && (!bottom_intra)
324 && FFABS(top_mv[0]-bottom_mv[0]) + FFABS(top_mv[1]+bottom_mv[1]) < 2) continue;
329 a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride];
330 b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride];
331 c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride];
333 d= FFABS(b) - ((FFABS(a) + FFABS(c)+1)>>1);
339 if(!(top_damage && bottom_damage))
343 dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)];
344 dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)];
345 dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)];
346 dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)];
349 dst[offset + x + 8*stride] = cm[dst[offset + x + 8*stride] - ((d*7)>>4)];
350 dst[offset + x + 9*stride] = cm[dst[offset + x + 9*stride] - ((d*5)>>4)];
351 dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)];
352 dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)];
359 static void guess_mv(MpegEncContext *s){
360 uint8_t fixed[s->mb_stride * s->mb_height];
363 #define MV_UNCHANGED 1
364 const int mb_stride = s->mb_stride;
365 const int mb_width = s->mb_width;
366 const int mb_height= s->mb_height;
367 int i, depth, num_avail;
368 int mb_x, mb_y, mot_step, mot_stride;
370 set_mv_strides(s, &mot_step, &mot_stride);
373 for(i=0; i<s->mb_num; i++){
374 const int mb_xy= s->mb_index2xy[ i ];
376 int error= s->error_status_table[mb_xy];
378 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
379 if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
384 else if(s->last_picture.data[0] && s->last_picture.motion_val[0]){
385 const int mb_y= mb_xy / s->mb_stride;
386 const int mb_x= mb_xy % s->mb_stride;
387 const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
388 s->current_picture.motion_val[0][mot_index][0]= s->last_picture.motion_val[0][mot_index][0];
389 s->current_picture.motion_val[0][mot_index][1]= s->last_picture.motion_val[0][mot_index][1];
390 s->current_picture.ref_index[0][4*mb_xy] = s->last_picture.ref_index[0][4*mb_xy];
394 if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
395 for(mb_y=0; mb_y<s->mb_height; mb_y++){
396 for(mb_x=0; mb_x<s->mb_width; mb_x++){
397 const int mb_xy= mb_x + mb_y*s->mb_stride;
399 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue;
400 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
402 s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
404 s->mv_type = MV_TYPE_16X16;
407 s->dsp.clear_blocks(s->block[0]);
419 for(depth=0;; depth++){
420 int changed, pass, none_left;
424 for(pass=0; (changed || pass<2) && pass<10; pass++){
429 for(mb_y=0; mb_y<s->mb_height; mb_y++){
430 for(mb_x=0; mb_x<s->mb_width; mb_x++){
431 const int mb_xy= mb_x + mb_y*s->mb_stride;
432 int mv_predictor[8][2]={{0}};
436 int best_score=256*256*256*64;
438 const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
439 int prev_x= s->current_picture.motion_val[0][mot_index][0];
440 int prev_y= s->current_picture.motion_val[0][mot_index][1];
442 if((mb_x^mb_y^pass)&1) continue;
444 if(fixed[mb_xy]==MV_FROZEN) continue;
445 assert(!IS_INTRA(s->current_picture.mb_type[mb_xy]));
446 assert(s->last_picture_ptr && s->last_picture_ptr->data[0]);
449 if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1;
450 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_FROZEN) j=1;
451 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1;
452 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1;
456 if(mb_x>0 && fixed[mb_xy-1 ]==MV_CHANGED) j=1;
457 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_CHANGED) j=1;
458 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1;
459 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1;
460 if(j==0 && pass>1) continue;
464 if(mb_x>0 && fixed[mb_xy-1]){
465 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_step][0];
466 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_step][1];
467 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-1)];
470 if(mb_x+1<mb_width && fixed[mb_xy+1]){
471 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_step][0];
472 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_step][1];
473 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+1)];
476 if(mb_y>0 && fixed[mb_xy-mb_stride]){
477 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][0];
478 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - mot_stride*mot_step][1];
479 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy-s->mb_stride)];
482 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
483 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][0];
484 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*mot_step][1];
485 ref [pred_count] = s->current_picture.ref_index[0][4*(mb_xy+s->mb_stride)];
488 if(pred_count==0) continue;
491 int sum_x=0, sum_y=0, sum_r=0;
492 int max_x, max_y, min_x, min_y, max_r, min_r;
494 for(j=0; j<pred_count; j++){
495 sum_x+= mv_predictor[j][0];
496 sum_y+= mv_predictor[j][1];
498 if(j && ref[j] != ref[j-1])
499 goto skip_mean_and_median;
503 mv_predictor[pred_count][0] = sum_x/j;
504 mv_predictor[pred_count][1] = sum_y/j;
505 ref [pred_count] = sum_r/j;
509 min_y= min_x= min_r= 99999;
510 max_y= max_x= max_r=-99999;
512 min_x=min_y=max_x=max_y=min_r=max_r=0;
514 for(j=0; j<pred_count; j++){
515 max_x= FFMAX(max_x, mv_predictor[j][0]);
516 max_y= FFMAX(max_y, mv_predictor[j][1]);
517 max_r= FFMAX(max_r, ref[j]);
518 min_x= FFMIN(min_x, mv_predictor[j][0]);
519 min_y= FFMIN(min_y, mv_predictor[j][1]);
520 min_r= FFMIN(min_r, ref[j]);
522 mv_predictor[pred_count+1][0] = sum_x - max_x - min_x;
523 mv_predictor[pred_count+1][1] = sum_y - max_y - min_y;
524 ref [pred_count+1] = sum_r - max_r - min_r;
527 mv_predictor[pred_count+1][0] /= 2;
528 mv_predictor[pred_count+1][1] /= 2;
529 ref [pred_count+1] /= 2;
533 skip_mean_and_median:
539 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0];
540 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1];
541 ref [pred_count] = s->current_picture.ref_index[0][4*mb_xy];
544 s->mv_dir = MV_DIR_FORWARD;
546 s->mv_type = MV_TYPE_16X16;
549 s->dsp.clear_blocks(s->block[0]);
554 for(j=0; j<pred_count; j++){
556 uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
558 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
559 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
561 if(ref[j]<0) //predictor intra or otherwise not available
564 decode_mb(s, ref[j]);
566 if(mb_x>0 && fixed[mb_xy-1]){
569 score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize ]);
571 if(mb_x+1<mb_width && fixed[mb_xy+1]){
574 score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
576 if(mb_y>0 && fixed[mb_xy-mb_stride]){
579 score += FFABS(src[k-s->linesize ]-src[k ]);
581 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
584 score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
587 if(score <= best_score){ // <= will favor the last MV
592 score_sum+= best_score;
593 s->mv[0][0][0]= mv_predictor[best_pred][0];
594 s->mv[0][0][1]= mv_predictor[best_pred][1];
596 for(i=0; i<mot_step; i++)
597 for(j=0; j<mot_step; j++){
598 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
599 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
602 decode_mb(s, ref[best_pred]);
605 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
606 fixed[mb_xy]=MV_CHANGED;
609 fixed[mb_xy]=MV_UNCHANGED;
613 // printf(".%d/%d", changed, score_sum); fflush(stdout);
619 for(i=0; i<s->mb_num; i++){
620 int mb_xy= s->mb_index2xy[i];
622 fixed[mb_xy]=MV_FROZEN;
624 // printf(":"); fflush(stdout);
628 static int is_intra_more_likely(MpegEncContext *s){
629 int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
631 if(!s->last_picture_ptr || !s->last_picture_ptr->data[0]) return 1; //no previous frame available -> use spatial prediction
634 for(i=0; i<s->mb_num; i++){
635 const int mb_xy= s->mb_index2xy[i];
636 const int error= s->error_status_table[mb_xy];
637 if(!((error&DC_ERROR) && (error&MV_ERROR)))
641 if(s->codec_id == CODEC_ID_H264){
642 H264Context *h= (void*)s;
643 if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0])
647 if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
649 //prevent dsp.sad() check, that requires access to the image
650 if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == AV_PICTURE_TYPE_I)
653 skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
657 for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
658 for(mb_x= 0; mb_x<s->mb_width; mb_x++){
660 const int mb_xy= mb_x + mb_y*s->mb_stride;
662 error= s->error_status_table[mb_xy];
663 if((error&DC_ERROR) && (error&MV_ERROR))
664 continue; //skip damaged
667 if((j%skip_amount) != 0) continue; //skip a few to speed things up
669 if(s->pict_type==AV_PICTURE_TYPE_I){
670 uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
671 uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
673 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16);
674 // FIXME need await_progress() here
675 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
677 if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
684 //printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
685 return is_intra_likely > 0;
688 void ff_er_frame_start(MpegEncContext *s){
689 if(!s->error_recognition) return;
691 memset(s->error_status_table, MV_ERROR|AC_ERROR|DC_ERROR|VP_START|AC_END|DC_END|MV_END, s->mb_stride*s->mb_height*sizeof(uint8_t));
692 s->error_count= 3*s->mb_num;
697 * @param endx x component of the last macroblock, can be -1 for the last of the previous line
698 * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
699 * error of the same type occurred
701 void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
702 const int start_i= av_clip(startx + starty * s->mb_width , 0, s->mb_num-1);
703 const int end_i = av_clip(endx + endy * s->mb_width , 0, s->mb_num);
704 const int start_xy= s->mb_index2xy[start_i];
705 const int end_xy = s->mb_index2xy[end_i];
708 if(s->avctx->hwaccel)
711 if(start_i > end_i || start_xy > end_xy){
712 av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
716 if(!s->error_recognition) return;
719 if(status & (AC_ERROR|AC_END)){
720 mask &= ~(AC_ERROR|AC_END);
721 s->error_count -= end_i - start_i + 1;
723 if(status & (DC_ERROR|DC_END)){
724 mask &= ~(DC_ERROR|DC_END);
725 s->error_count -= end_i - start_i + 1;
727 if(status & (MV_ERROR|MV_END)){
728 mask &= ~(MV_ERROR|MV_END);
729 s->error_count -= end_i - start_i + 1;
732 if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) s->error_count= INT_MAX;
735 memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
738 for(i=start_xy; i<end_xy; i++){
739 s->error_status_table[ i ] &= mask;
743 if(end_i == s->mb_num)
744 s->error_count= INT_MAX;
746 s->error_status_table[end_xy] &= mask;
747 s->error_status_table[end_xy] |= status;
750 s->error_status_table[start_xy] |= VP_START;
752 if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){
753 int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
755 prev_status &= ~ VP_START;
756 if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
760 void ff_er_frame_end(MpegEncContext *s){
761 int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
763 int threshold_part[4]= {100,100,100};
766 int size = s->b8_stride * 2 * s->mb_height;
767 Picture *pic= s->current_picture_ptr;
769 if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
771 s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
772 s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
773 s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
775 if(s->current_picture.motion_val[0] == NULL){
776 av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
779 pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
780 pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
781 pic->motion_val[i]= pic->motion_val_base[i]+4;
783 pic->motion_subsample_log2= 3;
784 s->current_picture= *s->current_picture_ptr;
787 if(s->avctx->debug&FF_DEBUG_ER){
788 for(mb_y=0; mb_y<s->mb_height; mb_y++){
789 for(mb_x=0; mb_x<s->mb_width; mb_x++){
790 int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
792 av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
794 av_log(s->avctx, AV_LOG_DEBUG, "\n");
799 /* handle overlapping slices */
800 for(error_type=1; error_type<=3; error_type++){
803 for(i=s->mb_num-1; i>=0; i--){
804 const int mb_xy= s->mb_index2xy[i];
805 int error= s->error_status_table[mb_xy];
807 if(error&(1<<error_type))
809 if(error&(8<<error_type))
813 s->error_status_table[mb_xy]|= 1<<error_type;
821 /* handle slices with partitions of different length */
822 if(s->partitioned_frame){
825 for(i=s->mb_num-1; i>=0; i--){
826 const int mb_xy= s->mb_index2xy[i];
827 int error= s->error_status_table[mb_xy];
831 if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
835 s->error_status_table[mb_xy]|= AC_ERROR;
842 /* handle missing slices */
843 if(s->error_recognition>=4){
846 for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
847 const int mb_xy= s->mb_index2xy[i];
848 int error1= s->error_status_table[mb_xy ];
849 int error2= s->error_status_table[s->mb_index2xy[i+1]];
854 if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
855 && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
856 && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
861 s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
866 /* backward mark errors */
868 for(error_type=1; error_type<=3; error_type++){
869 for(i=s->mb_num-1; i>=0; i--){
870 const int mb_xy= s->mb_index2xy[i];
871 int error= s->error_status_table[mb_xy];
873 if(!s->mbskip_table[mb_xy]) //FIXME partition specific
875 if(error&(1<<error_type))
878 if(s->partitioned_frame){
879 if(distance < threshold_part[error_type-1])
880 s->error_status_table[mb_xy]|= 1<<error_type;
882 if(distance < threshold)
883 s->error_status_table[mb_xy]|= 1<<error_type;
892 /* forward mark errors */
894 for(i=0; i<s->mb_num; i++){
895 const int mb_xy= s->mb_index2xy[i];
896 int old_error= s->error_status_table[mb_xy];
898 if(old_error&VP_START)
899 error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
901 error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
902 s->error_status_table[mb_xy]|= error;
906 /* handle not partitioned case */
907 if(!s->partitioned_frame){
908 for(i=0; i<s->mb_num; i++){
909 const int mb_xy= s->mb_index2xy[i];
910 error= s->error_status_table[mb_xy];
911 if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
912 error|= AC_ERROR|DC_ERROR|MV_ERROR;
913 s->error_status_table[mb_xy]= error;
918 dc_error= ac_error= mv_error=0;
919 for(i=0; i<s->mb_num; i++){
920 const int mb_xy= s->mb_index2xy[i];
921 error= s->error_status_table[mb_xy];
922 if(error&DC_ERROR) dc_error ++;
923 if(error&AC_ERROR) ac_error ++;
924 if(error&MV_ERROR) mv_error ++;
926 av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
928 is_intra_likely= is_intra_more_likely(s);
930 /* set unknown mb-type to most likely */
931 for(i=0; i<s->mb_num; i++){
932 const int mb_xy= s->mb_index2xy[i];
933 error= s->error_status_table[mb_xy];
934 if(!((error&DC_ERROR) && (error&MV_ERROR)))
938 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
940 s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
943 // change inter to intra blocks if no reference frames are available
944 if (!s->last_picture.data[0] && !s->next_picture.data[0])
945 for(i=0; i<s->mb_num; i++){
946 const int mb_xy= s->mb_index2xy[i];
947 if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
948 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
951 /* handle inter blocks with damaged AC */
952 for(mb_y=0; mb_y<s->mb_height; mb_y++){
953 for(mb_x=0; mb_x<s->mb_width; mb_x++){
954 const int mb_xy= mb_x + mb_y * s->mb_stride;
955 const int mb_type= s->current_picture.mb_type[mb_xy];
956 int dir = !s->last_picture.data[0];
957 error= s->error_status_table[mb_xy];
959 if(IS_INTRA(mb_type)) continue; //intra
960 if(error&MV_ERROR) continue; //inter with damaged MV
961 if(!(error&AC_ERROR)) continue; //undamaged inter
963 s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
967 int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
969 s->mv_type = MV_TYPE_8X8;
971 s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
972 s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
975 s->mv_type = MV_TYPE_16X16;
976 s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
977 s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
980 s->dsp.clear_blocks(s->block[0]);
984 decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
989 if(s->pict_type==AV_PICTURE_TYPE_B){
990 for(mb_y=0; mb_y<s->mb_height; mb_y++){
991 for(mb_x=0; mb_x<s->mb_width; mb_x++){
992 int xy= mb_x*2 + mb_y*2*s->b8_stride;
993 const int mb_xy= mb_x + mb_y * s->mb_stride;
994 const int mb_type= s->current_picture.mb_type[mb_xy];
995 error= s->error_status_table[mb_xy];
997 if(IS_INTRA(mb_type)) continue;
998 if(!(error&MV_ERROR)) continue; //inter with undamaged MV
999 if(!(error&AC_ERROR)) continue; //undamaged inter
1001 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
1002 if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
1003 if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
1005 s->mv_type = MV_TYPE_16X16;
1009 int time_pp= s->pp_time;
1010 int time_pb= s->pb_time;
1012 // FIXME await_progress here
1013 s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
1014 s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
1015 s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
1016 s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
1024 s->dsp.clear_blocks(s->block[0]);
1033 /* the filters below are not XvMC compatible, skip them */
1034 if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1036 /* fill DC for inter blocks */
1037 for(mb_y=0; mb_y<s->mb_height; mb_y++){
1038 for(mb_x=0; mb_x<s->mb_width; mb_x++){
1039 int dc, dcu, dcv, y, n;
1041 uint8_t *dest_y, *dest_cb, *dest_cr;
1042 const int mb_xy= mb_x + mb_y * s->mb_stride;
1043 const int mb_type= s->current_picture.mb_type[mb_xy];
1045 error= s->error_status_table[mb_xy];
1047 if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1048 // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
1050 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1051 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1052 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1054 dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1060 dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1063 dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1070 dcu+=dest_cb[x + y*(s->uvlinesize)];
1071 dcv+=dest_cr[x + y*(s->uvlinesize)];
1074 s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1075 s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1079 /* guess DC for damaged blocks */
1080 guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1081 guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1082 guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1084 /* filter luma DC */
1085 filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1088 /* render DC only intra */
1089 for(mb_y=0; mb_y<s->mb_height; mb_y++){
1090 for(mb_x=0; mb_x<s->mb_width; mb_x++){
1091 uint8_t *dest_y, *dest_cb, *dest_cr;
1092 const int mb_xy= mb_x + mb_y * s->mb_stride;
1093 const int mb_type= s->current_picture.mb_type[mb_xy];
1095 error= s->error_status_table[mb_xy];
1097 if(IS_INTER(mb_type)) continue;
1098 if(!(error&AC_ERROR)) continue; //undamaged
1100 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1101 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1102 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1104 put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1109 if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1110 /* filter horizontal block boundaries */
1111 h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1112 h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1113 h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1115 /* filter vertical block boundaries */
1116 v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1117 v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1118 v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1122 /* clean a few tables */
1123 for(i=0; i<s->mb_num; i++){
1124 const int mb_xy= s->mb_index2xy[i];
1125 int error= s->error_status_table[mb_xy];
1127 if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
1128 s->mbskip_table[mb_xy]=0;
1130 s->mbintra_table[mb_xy]=1;