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"
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
43 static void decode_mb(MpegEncContext *s, int ref){
44 s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16;
45 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);
46 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);
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));
53 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
55 fill_rectangle(&s->current_picture.ref_index[0][4*h->mb_xy], 2, 2, 2, ref, 1);
56 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
57 fill_rectangle(h->mv_cache[0][ scan8[0] ], 4, 4, 8, pack16to32(s->mv[0][0][0],s->mv[0][0][1]), 4);
59 ff_h264_hl_decode_mb(h);
62 MPV_decode_mb(s, s->block);
67 * @param stride the number of MVs to get to the next row
68 * @param mv_step the number of MVs per row or column in a macroblock
70 static void set_mv_strides(MpegEncContext *s, int *mv_step, int *stride){
71 if(s->codec_id == CODEC_ID_H264){
72 H264Context *h= (void*)s;
73 assert(s->quarter_sample);
78 *stride= s->b8_stride;
83 * replaces the current MB with a flat dc only version.
85 static void put_dc(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int mb_x, int mb_y)
87 int dc, dcu, dcv, y, i;
89 dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
91 else if(dc>2040) dc=2040;
95 dest_y[x + (i&1)*8 + (y + (i>>1)*8)*s->linesize]= dc/8;
99 dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride];
100 dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride];
102 else if(dcu>2040) dcu=2040;
104 else if(dcv>2040) dcv=2040;
108 dest_cb[x + y*(s->uvlinesize)]= dcu/8;
109 dest_cr[x + y*(s->uvlinesize)]= dcv/8;
114 static void filter181(int16_t *data, int width, int height, int stride){
117 /* horizontal filter */
118 for(y=1; y<height-1; y++){
119 int prev_dc= data[0 + y*stride];
121 for(x=1; x<width-1; x++){
125 + data[x + y*stride]*8
126 - data[x + 1 + y*stride];
127 dc= (dc*10923 + 32768)>>16;
128 prev_dc= data[x + y*stride];
129 data[x + y*stride]= dc;
133 /* vertical filter */
134 for(x=1; x<width-1; x++){
135 int prev_dc= data[x];
137 for(y=1; y<height-1; y++){
141 + data[x + y *stride]*8
142 - data[x + (y+1)*stride];
143 dc= (dc*10923 + 32768)>>16;
144 prev_dc= data[x + y*stride];
145 data[x + y*stride]= dc;
151 * guess the dc of blocks which do not have an undamaged dc
152 * @param w width in 8 pixel blocks
153 * @param h height in 8 pixel blocks
155 static void guess_dc(MpegEncContext *s, int16_t *dc, int w, int h, int stride, int is_luma){
158 for(b_y=0; b_y<h; b_y++){
159 for(b_x=0; b_x<w; b_x++){
160 int color[4]={1024,1024,1024,1024};
161 int distance[4]={9999,9999,9999,9999};
162 int mb_index, error, j;
163 int64_t guess, weight_sum;
165 mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;
167 error= s->error_status_table[mb_index];
169 if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter
170 if(!(error&DC_ERROR)) continue; //dc-ok
173 for(j=b_x+1; j<w; j++){
174 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
175 int error_j= s->error_status_table[mb_index_j];
176 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
177 if(intra_j==0 || !(error_j&DC_ERROR)){
178 color[0]= dc[j + b_y*stride];
185 for(j=b_x-1; j>=0; j--){
186 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride;
187 int error_j= s->error_status_table[mb_index_j];
188 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
189 if(intra_j==0 || !(error_j&DC_ERROR)){
190 color[1]= dc[j + b_y*stride];
197 for(j=b_y+1; j<h; j++){
198 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
199 int error_j= s->error_status_table[mb_index_j];
200 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
201 if(intra_j==0 || !(error_j&DC_ERROR)){
202 color[2]= dc[b_x + j*stride];
209 for(j=b_y-1; j>=0; j--){
210 int mb_index_j= (b_x>>is_luma) + (j>>is_luma)*s->mb_stride;
211 int error_j= s->error_status_table[mb_index_j];
212 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]);
213 if(intra_j==0 || !(error_j&DC_ERROR)){
214 color[3]= dc[b_x + j*stride];
223 int64_t weight= 256*256*256*16/distance[j];
224 guess+= weight*(int64_t)color[j];
227 guess= (guess + weight_sum/2) / weight_sum;
229 dc[b_x + b_y*stride]= guess;
235 * simple horizontal deblocking filter used for error resilience
236 * @param w width in 8 pixel blocks
237 * @param h height in 8 pixel blocks
239 static void h_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
240 int b_x, b_y, mvx_stride, mvy_stride;
241 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
242 set_mv_strides(s, &mvx_stride, &mvy_stride);
243 mvx_stride >>= is_luma;
244 mvy_stride *= mvx_stride;
246 for(b_y=0; b_y<h; b_y++){
247 for(b_x=0; b_x<w-1; b_x++){
249 int left_status = s->error_status_table[( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride];
250 int right_status= s->error_status_table[((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride];
251 int left_intra= IS_INTRA(s->current_picture.mb_type [( b_x >>is_luma) + (b_y>>is_luma)*s->mb_stride]);
252 int right_intra= IS_INTRA(s->current_picture.mb_type [((b_x+1)>>is_luma) + (b_y>>is_luma)*s->mb_stride]);
253 int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
254 int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
255 int offset= b_x*8 + b_y*stride*8;
256 int16_t *left_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride* b_x ];
257 int16_t *right_mv= s->current_picture.motion_val[0][mvy_stride*b_y + mvx_stride*(b_x+1)];
259 if(!(left_damage||right_damage)) continue; // both undamaged
261 if( (!left_intra) && (!right_intra)
262 && FFABS(left_mv[0]-right_mv[0]) + FFABS(left_mv[1]+right_mv[1]) < 2) continue;
267 a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride];
268 b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride];
269 c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride];
271 d= FFABS(b) - ((FFABS(a) + FFABS(c) + 1)>>1);
277 if(!(left_damage && right_damage))
281 dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)];
282 dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)];
283 dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)];
284 dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)];
287 dst[offset + 8 + y*stride] = cm[dst[offset + 8 + y*stride] - ((d*7)>>4)];
288 dst[offset + 9 + y*stride] = cm[dst[offset + 9 + y*stride] - ((d*5)>>4)];
289 dst[offset + 10+ y*stride] = cm[dst[offset +10 + y*stride] - ((d*3)>>4)];
290 dst[offset + 11+ y*stride] = cm[dst[offset +11 + y*stride] - ((d*1)>>4)];
298 * simple vertical deblocking filter used for error resilience
299 * @param w width in 8 pixel blocks
300 * @param h height in 8 pixel blocks
302 static void v_block_filter(MpegEncContext *s, uint8_t *dst, int w, int h, int stride, int is_luma){
303 int b_x, b_y, mvx_stride, mvy_stride;
304 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
305 set_mv_strides(s, &mvx_stride, &mvy_stride);
306 mvx_stride >>= is_luma;
307 mvy_stride *= mvx_stride;
309 for(b_y=0; b_y<h-1; b_y++){
310 for(b_x=0; b_x<w; b_x++){
312 int top_status = s->error_status_table[(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride];
313 int bottom_status= s->error_status_table[(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride];
314 int top_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ( b_y >>is_luma)*s->mb_stride]);
315 int bottom_intra= IS_INTRA(s->current_picture.mb_type [(b_x>>is_luma) + ((b_y+1)>>is_luma)*s->mb_stride]);
316 int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
317 int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
318 int offset= b_x*8 + b_y*stride*8;
319 int16_t *top_mv= s->current_picture.motion_val[0][mvy_stride* b_y + mvx_stride*b_x];
320 int16_t *bottom_mv= s->current_picture.motion_val[0][mvy_stride*(b_y+1) + mvx_stride*b_x];
322 if(!(top_damage||bottom_damage)) continue; // both undamaged
324 if( (!top_intra) && (!bottom_intra)
325 && FFABS(top_mv[0]-bottom_mv[0]) + FFABS(top_mv[1]+bottom_mv[1]) < 2) continue;
330 a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride];
331 b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride];
332 c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride];
334 d= FFABS(b) - ((FFABS(a) + FFABS(c)+1)>>1);
340 if(!(top_damage && bottom_damage))
344 dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)];
345 dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)];
346 dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)];
347 dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)];
350 dst[offset + x + 8*stride] = cm[dst[offset + x + 8*stride] - ((d*7)>>4)];
351 dst[offset + x + 9*stride] = cm[dst[offset + x + 9*stride] - ((d*5)>>4)];
352 dst[offset + x + 10*stride] = cm[dst[offset + x + 10*stride] - ((d*3)>>4)];
353 dst[offset + x + 11*stride] = cm[dst[offset + x + 11*stride] - ((d*1)>>4)];
360 static void guess_mv(MpegEncContext *s){
361 uint8_t fixed[s->mb_stride * s->mb_height];
364 #define MV_UNCHANGED 1
365 const int mb_stride = s->mb_stride;
366 const int mb_width = s->mb_width;
367 const int mb_height= s->mb_height;
368 int i, depth, num_avail;
369 int mb_x, mb_y, mot_step, mot_stride;
371 set_mv_strides(s, &mot_step, &mot_stride);
374 for(i=0; i<s->mb_num; i++){
375 const int mb_xy= s->mb_index2xy[ i ];
377 int error= s->error_status_table[mb_xy];
379 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check
380 if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV
385 else if(s->last_picture.data[0] && s->last_picture.motion_val[0]){
386 const int mb_y= mb_xy / s->mb_stride;
387 const int mb_x= mb_xy % s->mb_stride;
388 const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
389 s->current_picture.motion_val[0][mot_index][0]= s->last_picture.motion_val[0][mot_index][0];
390 s->current_picture.motion_val[0][mot_index][1]= s->last_picture.motion_val[0][mot_index][1];
391 s->current_picture.ref_index[0][4*mb_xy] = s->last_picture.ref_index[0][4*mb_xy];
395 if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){
396 for(mb_y=0; mb_y<s->mb_height; mb_y++){
397 for(mb_x=0; mb_x<s->mb_width; mb_x++){
398 const int mb_xy= mb_x + mb_y*s->mb_stride;
400 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue;
401 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue;
403 s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
405 s->mv_type = MV_TYPE_16X16;
408 s->dsp.clear_blocks(s->block[0]);
420 for(depth=0;; depth++){
421 int changed, pass, none_left;
425 for(pass=0; (changed || pass<2) && pass<10; pass++){
430 for(mb_y=0; mb_y<s->mb_height; mb_y++){
431 for(mb_x=0; mb_x<s->mb_width; mb_x++){
432 const int mb_xy= mb_x + mb_y*s->mb_stride;
433 int mv_predictor[8][2]={{0}};
437 int best_score=256*256*256*64;
439 const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
440 int prev_x, prev_y, prev_ref;
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:
538 if (!fixed[mb_xy] && 0) {
539 if (s->avctx->codec_id == CODEC_ID_H264) {
542 ff_thread_await_progress((AVFrame *) s->last_picture_ptr,
545 prev_x = s->last_picture.motion_val[0][mot_index][0];
546 prev_y = s->last_picture.motion_val[0][mot_index][1];
547 prev_ref = s->last_picture.ref_index[0][4*mb_xy];
549 prev_x = s->current_picture.motion_val[0][mot_index][0];
550 prev_y = s->current_picture.motion_val[0][mot_index][1];
551 prev_ref = s->current_picture.ref_index[0][4*mb_xy];
555 mv_predictor[pred_count][0]= prev_x;
556 mv_predictor[pred_count][1]= prev_y;
557 ref [pred_count] = prev_ref;
560 s->mv_dir = MV_DIR_FORWARD;
562 s->mv_type = MV_TYPE_16X16;
565 s->dsp.clear_blocks(s->block[0]);
570 for(j=0; j<pred_count; j++){
572 uint8_t *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
574 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0];
575 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1];
577 if(ref[j]<0) //predictor intra or otherwise not available
580 decode_mb(s, ref[j]);
582 if(mb_x>0 && fixed[mb_xy-1]){
585 score += FFABS(src[k*s->linesize-1 ]-src[k*s->linesize ]);
587 if(mb_x+1<mb_width && fixed[mb_xy+1]){
590 score += FFABS(src[k*s->linesize+15]-src[k*s->linesize+16]);
592 if(mb_y>0 && fixed[mb_xy-mb_stride]){
595 score += FFABS(src[k-s->linesize ]-src[k ]);
597 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){
600 score += FFABS(src[k+s->linesize*15]-src[k+s->linesize*16]);
603 if(score <= best_score){ // <= will favor the last MV
608 score_sum+= best_score;
609 s->mv[0][0][0]= mv_predictor[best_pred][0];
610 s->mv[0][0][1]= mv_predictor[best_pred][1];
612 for(i=0; i<mot_step; i++)
613 for(j=0; j<mot_step; j++){
614 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][0]= s->mv[0][0][0];
615 s->current_picture.motion_val[0][mot_index+i+j*mot_stride][1]= s->mv[0][0][1];
618 decode_mb(s, ref[best_pred]);
621 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){
622 fixed[mb_xy]=MV_CHANGED;
625 fixed[mb_xy]=MV_UNCHANGED;
629 // printf(".%d/%d", changed, score_sum); fflush(stdout);
635 for(i=0; i<s->mb_num; i++){
636 int mb_xy= s->mb_index2xy[i];
638 fixed[mb_xy]=MV_FROZEN;
640 // printf(":"); fflush(stdout);
644 static int is_intra_more_likely(MpegEncContext *s){
645 int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y;
647 if(!s->last_picture_ptr || !s->last_picture_ptr->data[0]) return 1; //no previous frame available -> use spatial prediction
650 for(i=0; i<s->mb_num; i++){
651 const int mb_xy= s->mb_index2xy[i];
652 const int error= s->error_status_table[mb_xy];
653 if(!((error&DC_ERROR) && (error&MV_ERROR)))
657 if(s->codec_id == CODEC_ID_H264){
658 H264Context *h= (void*)s;
659 if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0])
663 if(undamaged_count < 5) return 0; //almost all MBs damaged -> use temporal prediction
665 //prevent dsp.sad() check, that requires access to the image
666 if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration && s->pict_type == AV_PICTURE_TYPE_I)
669 skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs
673 for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){
674 for(mb_x= 0; mb_x<s->mb_width; mb_x++){
676 const int mb_xy= mb_x + mb_y*s->mb_stride;
678 error= s->error_status_table[mb_xy];
679 if((error&DC_ERROR) && (error&MV_ERROR))
680 continue; //skip damaged
683 if((j%skip_amount) != 0) continue; //skip a few to speed things up
685 if(s->pict_type==AV_PICTURE_TYPE_I){
686 uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
687 uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize;
689 if (s->avctx->codec_id == CODEC_ID_H264) {
692 ff_thread_await_progress((AVFrame *) s->last_picture_ptr,
695 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16);
696 // FIXME need await_progress() here
697 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16);
699 if(IS_INTRA(s->current_picture.mb_type[mb_xy]))
706 //printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
707 return is_intra_likely > 0;
710 void ff_er_frame_start(MpegEncContext *s){
711 if(!s->error_recognition) return;
713 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));
714 s->error_count= 3*s->mb_num;
715 s->error_occurred = 0;
720 * @param endx x component of the last macroblock, can be -1 for the last of the previous line
721 * @param status the status at the end (MV_END, AC_ERROR, ...), it is assumed that no earlier end or
722 * error of the same type occurred
724 void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status){
725 const int start_i= av_clip(startx + starty * s->mb_width , 0, s->mb_num-1);
726 const int end_i = av_clip(endx + endy * s->mb_width , 0, s->mb_num);
727 const int start_xy= s->mb_index2xy[start_i];
728 const int end_xy = s->mb_index2xy[end_i];
731 if(s->avctx->hwaccel)
734 if(start_i > end_i || start_xy > end_xy){
735 av_log(s->avctx, AV_LOG_ERROR, "internal error, slice end before start\n");
739 if(!s->error_recognition) return;
742 if(status & (AC_ERROR|AC_END)){
743 mask &= ~(AC_ERROR|AC_END);
744 s->error_count -= end_i - start_i + 1;
746 if(status & (DC_ERROR|DC_END)){
747 mask &= ~(DC_ERROR|DC_END);
748 s->error_count -= end_i - start_i + 1;
750 if(status & (MV_ERROR|MV_END)){
751 mask &= ~(MV_ERROR|MV_END);
752 s->error_count -= end_i - start_i + 1;
755 if(status & (AC_ERROR|DC_ERROR|MV_ERROR)) {
756 s->error_occurred = 1;
757 s->error_count= INT_MAX;
761 memset(&s->error_status_table[start_xy], 0, (end_xy - start_xy) * sizeof(uint8_t));
764 for(i=start_xy; i<end_xy; i++){
765 s->error_status_table[ i ] &= mask;
769 if(end_i == s->mb_num)
770 s->error_count= INT_MAX;
772 s->error_status_table[end_xy] &= mask;
773 s->error_status_table[end_xy] |= status;
776 s->error_status_table[start_xy] |= VP_START;
778 if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){
779 int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ];
781 prev_status &= ~ VP_START;
782 if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX;
786 void ff_er_frame_end(MpegEncContext *s){
787 int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;
789 int threshold_part[4]= {100,100,100};
792 int size = s->b8_stride * 2 * s->mb_height;
793 Picture *pic= s->current_picture_ptr;
795 if(!s->error_recognition || s->error_count==0 || s->avctx->lowres ||
797 s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU ||
798 s->picture_structure != PICT_FRAME || // we dont support ER of field pictures yet, though it should not crash if enabled
799 s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return;
801 if(s->current_picture.motion_val[0] == NULL){
802 av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
805 pic->ref_index[i]= av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
806 pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t));
807 pic->motion_val[i]= pic->motion_val_base[i]+4;
809 pic->motion_subsample_log2= 3;
810 s->current_picture= *s->current_picture_ptr;
813 if(s->avctx->debug&FF_DEBUG_ER){
814 for(mb_y=0; mb_y<s->mb_height; mb_y++){
815 for(mb_x=0; mb_x<s->mb_width; mb_x++){
816 int status= s->error_status_table[mb_x + mb_y*s->mb_stride];
818 av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);
820 av_log(s->avctx, AV_LOG_DEBUG, "\n");
825 /* handle overlapping slices */
826 for(error_type=1; error_type<=3; error_type++){
829 for(i=s->mb_num-1; i>=0; i--){
830 const int mb_xy= s->mb_index2xy[i];
831 int error= s->error_status_table[mb_xy];
833 if(error&(1<<error_type))
835 if(error&(8<<error_type))
839 s->error_status_table[mb_xy]|= 1<<error_type;
847 /* handle slices with partitions of different length */
848 if(s->partitioned_frame){
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];
857 if((error&MV_END) || (error&DC_END) || (error&AC_ERROR))
861 s->error_status_table[mb_xy]|= AC_ERROR;
868 /* handle missing slices */
869 if(s->error_recognition>=4){
872 for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack
873 const int mb_xy= s->mb_index2xy[i];
874 int error1= s->error_status_table[mb_xy ];
875 int error2= s->error_status_table[s->mb_index2xy[i+1]];
880 if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
881 && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END)
882 && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninit
887 s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR;
892 /* backward mark errors */
894 for(error_type=1; error_type<=3; error_type++){
895 for(i=s->mb_num-1; i>=0; i--){
896 const int mb_xy= s->mb_index2xy[i];
897 int error= s->error_status_table[mb_xy];
899 if(!s->mbskip_table[mb_xy]) //FIXME partition specific
901 if(error&(1<<error_type))
904 if(s->partitioned_frame){
905 if(distance < threshold_part[error_type-1])
906 s->error_status_table[mb_xy]|= 1<<error_type;
908 if(distance < threshold)
909 s->error_status_table[mb_xy]|= 1<<error_type;
918 /* forward mark errors */
920 for(i=0; i<s->mb_num; i++){
921 const int mb_xy= s->mb_index2xy[i];
922 int old_error= s->error_status_table[mb_xy];
924 if(old_error&VP_START)
925 error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
927 error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR);
928 s->error_status_table[mb_xy]|= error;
932 /* handle not partitioned case */
933 if(!s->partitioned_frame){
934 for(i=0; i<s->mb_num; i++){
935 const int mb_xy= s->mb_index2xy[i];
936 error= s->error_status_table[mb_xy];
937 if(error&(AC_ERROR|DC_ERROR|MV_ERROR))
938 error|= AC_ERROR|DC_ERROR|MV_ERROR;
939 s->error_status_table[mb_xy]= error;
944 dc_error= ac_error= mv_error=0;
945 for(i=0; i<s->mb_num; i++){
946 const int mb_xy= s->mb_index2xy[i];
947 error= s->error_status_table[mb_xy];
948 if(error&DC_ERROR) dc_error ++;
949 if(error&AC_ERROR) ac_error ++;
950 if(error&MV_ERROR) mv_error ++;
952 av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n", dc_error, ac_error, mv_error);
954 is_intra_likely= is_intra_more_likely(s);
956 /* set unknown mb-type to most likely */
957 for(i=0; i<s->mb_num; i++){
958 const int mb_xy= s->mb_index2xy[i];
959 error= s->error_status_table[mb_xy];
960 if(!((error&DC_ERROR) && (error&MV_ERROR)))
964 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
966 s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0;
969 // change inter to intra blocks if no reference frames are available
970 if (!s->last_picture.data[0] && !s->next_picture.data[0])
971 for(i=0; i<s->mb_num; i++){
972 const int mb_xy= s->mb_index2xy[i];
973 if(!IS_INTRA(s->current_picture.mb_type[mb_xy]))
974 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4;
977 /* handle inter blocks with damaged AC */
978 for(mb_y=0; mb_y<s->mb_height; mb_y++){
979 for(mb_x=0; mb_x<s->mb_width; mb_x++){
980 const int mb_xy= mb_x + mb_y * s->mb_stride;
981 const int mb_type= s->current_picture.mb_type[mb_xy];
982 int dir = !s->last_picture.data[0];
983 error= s->error_status_table[mb_xy];
985 if(IS_INTRA(mb_type)) continue; //intra
986 if(error&MV_ERROR) continue; //inter with damaged MV
987 if(!(error&AC_ERROR)) continue; //undamaged inter
989 s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
993 int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
995 s->mv_type = MV_TYPE_8X8;
997 s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
998 s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
1001 s->mv_type = MV_TYPE_16X16;
1002 s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0];
1003 s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1];
1006 s->dsp.clear_blocks(s->block[0]);
1010 decode_mb(s, 0/*FIXME h264 partitioned slices need this set*/);
1015 if(s->pict_type==AV_PICTURE_TYPE_B){
1016 for(mb_y=0; mb_y<s->mb_height; mb_y++){
1017 for(mb_x=0; mb_x<s->mb_width; mb_x++){
1018 int xy= mb_x*2 + mb_y*2*s->b8_stride;
1019 const int mb_xy= mb_x + mb_y * s->mb_stride;
1020 const int mb_type= s->current_picture.mb_type[mb_xy];
1021 error= s->error_status_table[mb_xy];
1023 if(IS_INTRA(mb_type)) continue;
1024 if(!(error&MV_ERROR)) continue; //inter with undamaged MV
1025 if(!(error&AC_ERROR)) continue; //undamaged inter
1027 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD;
1028 if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD;
1029 if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD;
1031 s->mv_type = MV_TYPE_16X16;
1035 int time_pp= s->pp_time;
1036 int time_pb= s->pb_time;
1038 if (s->avctx->codec_id == CODEC_ID_H264) {
1041 ff_thread_await_progress((AVFrame *) s->next_picture_ptr,
1044 s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp;
1045 s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp;
1046 s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp;
1047 s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp;
1055 s->dsp.clear_blocks(s->block[0]);
1064 /* the filters below are not XvMC compatible, skip them */
1065 if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
1067 /* fill DC for inter blocks */
1068 for(mb_y=0; mb_y<s->mb_height; mb_y++){
1069 for(mb_x=0; mb_x<s->mb_width; mb_x++){
1070 int dc, dcu, dcv, y, n;
1072 uint8_t *dest_y, *dest_cb, *dest_cr;
1073 const int mb_xy= mb_x + mb_y * s->mb_stride;
1074 const int mb_type= s->current_picture.mb_type[mb_xy];
1076 error= s->error_status_table[mb_xy];
1078 if(IS_INTRA(mb_type) && s->partitioned_frame) continue;
1079 // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good?
1081 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1082 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1083 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1085 dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
1091 dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
1094 dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
1101 dcu+=dest_cb[x + y*(s->uvlinesize)];
1102 dcv+=dest_cr[x + y*(s->uvlinesize)];
1105 s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
1106 s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;
1110 /* guess DC for damaged blocks */
1111 guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
1112 guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0);
1113 guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0);
1115 /* filter luma DC */
1116 filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
1119 /* render DC only intra */
1120 for(mb_y=0; mb_y<s->mb_height; mb_y++){
1121 for(mb_x=0; mb_x<s->mb_width; mb_x++){
1122 uint8_t *dest_y, *dest_cb, *dest_cr;
1123 const int mb_xy= mb_x + mb_y * s->mb_stride;
1124 const int mb_type= s->current_picture.mb_type[mb_xy];
1126 error= s->error_status_table[mb_xy];
1128 if(IS_INTER(mb_type)) continue;
1129 if(!(error&AC_ERROR)) continue; //undamaged
1131 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize;
1132 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize;
1133 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize;
1135 put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
1140 if(s->avctx->error_concealment&FF_EC_DEBLOCK){
1141 /* filter horizontal block boundaries */
1142 h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1143 h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1144 h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1146 /* filter vertical block boundaries */
1147 v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1);
1148 v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0);
1149 v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0);
1153 /* clean a few tables */
1154 for(i=0; i<s->mb_num; i++){
1155 const int mb_xy= s->mb_index2xy[i];
1156 int error= s->error_status_table[mb_xy];
1158 if(s->pict_type!=AV_PICTURE_TYPE_B && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){
1159 s->mbskip_table[mb_xy]=0;
1161 s->mbintra_table[mb_xy]=1;