Mercurial > libavcodec.hg
comparison error_resilience.c @ 2967:ef2149182f1c libavcodec
COSMETICS: Remove all trailing whitespace.
| author | diego |
|---|---|
| date | Sat, 17 Dec 2005 18:14:38 +0000 |
| parents | 511e3afc43e1 |
| children | bfabfdf9ce55 |
comparison
equal
deleted
inserted
replaced
| 2966:564788471dd4 | 2967:ef2149182f1c |
|---|---|
| 15 * | 15 * |
| 16 * You should have received a copy of the GNU Lesser General Public | 16 * You should have received a copy of the GNU Lesser General Public |
| 17 * License along with this library; if not, write to the Free Software | 17 * License along with this library; if not, write to the Free Software |
| 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 /** | 21 /** |
| 22 * @file error_resilience.c | 22 * @file error_resilience.c |
| 23 * Error resilience / concealment. | 23 * Error resilience / concealment. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include <limits.h> | 26 #include <limits.h> |
| 27 | 27 |
| 28 #include "avcodec.h" | 28 #include "avcodec.h" |
| 29 #include "dsputil.h" | 29 #include "dsputil.h" |
| 30 #include "mpegvideo.h" | 30 #include "mpegvideo.h" |
| 31 #include "common.h" | 31 #include "common.h" |
| 32 | 32 |
| 33 static void decode_mb(MpegEncContext *s){ | 33 static void decode_mb(MpegEncContext *s){ |
| 34 s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16; | 34 s->dest[0] = s->current_picture.data[0] + (s->mb_y * 16* s->linesize ) + s->mb_x * 16; |
| 35 s->dest[1] = s->current_picture.data[1] + (s->mb_y * 8 * s->uvlinesize) + s->mb_x * 8; | 35 s->dest[1] = s->current_picture.data[1] + (s->mb_y * 8 * s->uvlinesize) + s->mb_x * 8; |
| 36 s->dest[2] = s->current_picture.data[2] + (s->mb_y * 8 * s->uvlinesize) + s->mb_x * 8; | 36 s->dest[2] = s->current_picture.data[2] + (s->mb_y * 8 * s->uvlinesize) + s->mb_x * 8; |
| 37 | 37 |
| 38 MPV_decode_mb(s, s->block); | 38 MPV_decode_mb(s, s->block); |
| 39 } | 39 } |
| 40 | 40 |
| 41 /** | 41 /** |
| 42 * replaces the current MB with a flat dc only version. | 42 * replaces the current MB with a flat dc only version. |
| 43 */ | 43 */ |
| 77 for(y=1; y<height-1; y++){ | 77 for(y=1; y<height-1; y++){ |
| 78 int prev_dc= data[0 + y*stride]; | 78 int prev_dc= data[0 + y*stride]; |
| 79 | 79 |
| 80 for(x=1; x<width-1; x++){ | 80 for(x=1; x<width-1; x++){ |
| 81 int dc; | 81 int dc; |
| 82 | 82 |
| 83 dc= - prev_dc | 83 dc= - prev_dc |
| 84 + data[x + y*stride]*8 | 84 + data[x + y*stride]*8 |
| 85 - data[x + 1 + y*stride]; | 85 - data[x + 1 + y*stride]; |
| 86 dc= (dc*10923 + 32768)>>16; | 86 dc= (dc*10923 + 32768)>>16; |
| 87 prev_dc= data[x + y*stride]; | 87 prev_dc= data[x + y*stride]; |
| 88 data[x + y*stride]= dc; | 88 data[x + y*stride]= dc; |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 | 91 |
| 92 /* vertical filter */ | 92 /* vertical filter */ |
| 93 for(x=1; x<width-1; x++){ | 93 for(x=1; x<width-1; x++){ |
| 94 int prev_dc= data[x]; | 94 int prev_dc= data[x]; |
| 95 | 95 |
| 96 for(y=1; y<height-1; y++){ | 96 for(y=1; y<height-1; y++){ |
| 97 int dc; | 97 int dc; |
| 98 | 98 |
| 99 dc= - prev_dc | 99 dc= - prev_dc |
| 100 + data[x + y *stride]*8 | 100 + data[x + y *stride]*8 |
| 101 - data[x + (y+1)*stride]; | 101 - data[x + (y+1)*stride]; |
| 102 dc= (dc*10923 + 32768)>>16; | 102 dc= (dc*10923 + 32768)>>16; |
| 103 prev_dc= data[x + y*stride]; | 103 prev_dc= data[x + y*stride]; |
| 104 data[x + y*stride]= dc; | 104 data[x + y*stride]= dc; |
| 118 for(b_x=0; b_x<w; b_x++){ | 118 for(b_x=0; b_x<w; b_x++){ |
| 119 int color[4]={1024,1024,1024,1024}; | 119 int color[4]={1024,1024,1024,1024}; |
| 120 int distance[4]={9999,9999,9999,9999}; | 120 int distance[4]={9999,9999,9999,9999}; |
| 121 int mb_index, error, j; | 121 int mb_index, error, j; |
| 122 int64_t guess, weight_sum; | 122 int64_t guess, weight_sum; |
| 123 | 123 |
| 124 mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; | 124 mb_index= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride; |
| 125 | 125 |
| 126 error= s->error_status_table[mb_index]; | 126 error= s->error_status_table[mb_index]; |
| 127 | 127 |
| 128 if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter | 128 if(IS_INTER(s->current_picture.mb_type[mb_index])) continue; //inter |
| 129 if(!(error&DC_ERROR)) continue; //dc-ok | 129 if(!(error&DC_ERROR)) continue; //dc-ok |
| 130 | 130 |
| 131 /* right block */ | 131 /* right block */ |
| 132 for(j=b_x+1; j<w; j++){ | 132 for(j=b_x+1; j<w; j++){ |
| 133 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride; | 133 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride; |
| 134 int error_j= s->error_status_table[mb_index_j]; | 134 int error_j= s->error_status_table[mb_index_j]; |
| 135 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); | 135 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); |
| 137 color[0]= dc[j + b_y*stride]; | 137 color[0]= dc[j + b_y*stride]; |
| 138 distance[0]= j-b_x; | 138 distance[0]= j-b_x; |
| 139 break; | 139 break; |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 | 142 |
| 143 /* left block */ | 143 /* left block */ |
| 144 for(j=b_x-1; j>=0; j--){ | 144 for(j=b_x-1; j>=0; j--){ |
| 145 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride; | 145 int mb_index_j= (j>>is_luma) + (b_y>>is_luma)*s->mb_stride; |
| 146 int error_j= s->error_status_table[mb_index_j]; | 146 int error_j= s->error_status_table[mb_index_j]; |
| 147 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); | 147 int intra_j= IS_INTRA(s->current_picture.mb_type[mb_index_j]); |
| 173 color[3]= dc[b_x + j*stride]; | 173 color[3]= dc[b_x + j*stride]; |
| 174 distance[3]= b_y-j; | 174 distance[3]= b_y-j; |
| 175 break; | 175 break; |
| 176 } | 176 } |
| 177 } | 177 } |
| 178 | 178 |
| 179 weight_sum=0; | 179 weight_sum=0; |
| 180 guess=0; | 180 guess=0; |
| 181 for(j=0; j<4; j++){ | 181 for(j=0; j<4; j++){ |
| 182 int64_t weight= 256*256*256*16/distance[j]; | 182 int64_t weight= 256*256*256*16/distance[j]; |
| 183 guess+= weight*(int64_t)color[j]; | 183 guess+= weight*(int64_t)color[j]; |
| 209 int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR); | 209 int left_damage = left_status&(DC_ERROR|AC_ERROR|MV_ERROR); |
| 210 int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR); | 210 int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR); |
| 211 int offset= b_x*8 + b_y*stride*8; | 211 int offset= b_x*8 + b_y*stride*8; |
| 212 int16_t *left_mv= s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ( b_x <<(1-is_luma))]; | 212 int16_t *left_mv= s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ( b_x <<(1-is_luma))]; |
| 213 int16_t *right_mv= s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ((b_x+1)<<(1-is_luma))]; | 213 int16_t *right_mv= s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ((b_x+1)<<(1-is_luma))]; |
| 214 | 214 |
| 215 if(!(left_damage||right_damage)) continue; // both undamaged | 215 if(!(left_damage||right_damage)) continue; // both undamaged |
| 216 | 216 |
| 217 if( (!left_intra) && (!right_intra) | 217 if( (!left_intra) && (!right_intra) |
| 218 && ABS(left_mv[0]-right_mv[0]) + ABS(left_mv[1]+right_mv[1]) < 2) continue; | 218 && ABS(left_mv[0]-right_mv[0]) + ABS(left_mv[1]+right_mv[1]) < 2) continue; |
| 219 | 219 |
| 220 for(y=0; y<8; y++){ | 220 for(y=0; y<8; y++){ |
| 221 int a,b,c,d; | 221 int a,b,c,d; |
| 222 | 222 |
| 223 a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride]; | 223 a= dst[offset + 7 + y*stride] - dst[offset + 6 + y*stride]; |
| 224 b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride]; | 224 b= dst[offset + 8 + y*stride] - dst[offset + 7 + y*stride]; |
| 225 c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride]; | 225 c= dst[offset + 9 + y*stride] - dst[offset + 8 + y*stride]; |
| 226 | 226 |
| 227 d= ABS(b) - ((ABS(a) + ABS(c) + 1)>>1); | 227 d= ABS(b) - ((ABS(a) + ABS(c) + 1)>>1); |
| 228 d= FFMAX(d, 0); | 228 d= FFMAX(d, 0); |
| 229 if(b<0) d= -d; | 229 if(b<0) d= -d; |
| 230 | 230 |
| 231 if(d==0) continue; | 231 if(d==0) continue; |
| 232 | 232 |
| 233 if(!(left_damage && right_damage)) | 233 if(!(left_damage && right_damage)) |
| 234 d= d*16/9; | 234 d= d*16/9; |
| 235 | 235 |
| 236 if(left_damage){ | 236 if(left_damage){ |
| 237 dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)]; | 237 dst[offset + 7 + y*stride] = cm[dst[offset + 7 + y*stride] + ((d*7)>>4)]; |
| 238 dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)]; | 238 dst[offset + 6 + y*stride] = cm[dst[offset + 6 + y*stride] + ((d*5)>>4)]; |
| 239 dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)]; | 239 dst[offset + 5 + y*stride] = cm[dst[offset + 5 + y*stride] + ((d*3)>>4)]; |
| 240 dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)]; | 240 dst[offset + 4 + y*stride] = cm[dst[offset + 4 + y*stride] + ((d*1)>>4)]; |
| 269 int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR); | 269 int top_damage = top_status&(DC_ERROR|AC_ERROR|MV_ERROR); |
| 270 int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR); | 270 int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR); |
| 271 int offset= b_x*8 + b_y*stride*8; | 271 int offset= b_x*8 + b_y*stride*8; |
| 272 int16_t *top_mv= s->current_picture.motion_val[0][s->b8_stride*( b_y <<(1-is_luma)) + (b_x<<(1-is_luma))]; | 272 int16_t *top_mv= s->current_picture.motion_val[0][s->b8_stride*( b_y <<(1-is_luma)) + (b_x<<(1-is_luma))]; |
| 273 int16_t *bottom_mv= s->current_picture.motion_val[0][s->b8_stride*((b_y+1)<<(1-is_luma)) + (b_x<<(1-is_luma))]; | 273 int16_t *bottom_mv= s->current_picture.motion_val[0][s->b8_stride*((b_y+1)<<(1-is_luma)) + (b_x<<(1-is_luma))]; |
| 274 | 274 |
| 275 if(!(top_damage||bottom_damage)) continue; // both undamaged | 275 if(!(top_damage||bottom_damage)) continue; // both undamaged |
| 276 | 276 |
| 277 if( (!top_intra) && (!bottom_intra) | 277 if( (!top_intra) && (!bottom_intra) |
| 278 && ABS(top_mv[0]-bottom_mv[0]) + ABS(top_mv[1]+bottom_mv[1]) < 2) continue; | 278 && ABS(top_mv[0]-bottom_mv[0]) + ABS(top_mv[1]+bottom_mv[1]) < 2) continue; |
| 279 | 279 |
| 280 for(x=0; x<8; x++){ | 280 for(x=0; x<8; x++){ |
| 281 int a,b,c,d; | 281 int a,b,c,d; |
| 282 | 282 |
| 283 a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride]; | 283 a= dst[offset + x + 7*stride] - dst[offset + x + 6*stride]; |
| 284 b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride]; | 284 b= dst[offset + x + 8*stride] - dst[offset + x + 7*stride]; |
| 285 c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride]; | 285 c= dst[offset + x + 9*stride] - dst[offset + x + 8*stride]; |
| 286 | 286 |
| 287 d= ABS(b) - ((ABS(a) + ABS(c)+1)>>1); | 287 d= ABS(b) - ((ABS(a) + ABS(c)+1)>>1); |
| 288 d= FFMAX(d, 0); | 288 d= FFMAX(d, 0); |
| 289 if(b<0) d= -d; | 289 if(b<0) d= -d; |
| 290 | 290 |
| 291 if(d==0) continue; | 291 if(d==0) continue; |
| 292 | 292 |
| 293 if(!(top_damage && bottom_damage)) | 293 if(!(top_damage && bottom_damage)) |
| 294 d= d*16/9; | 294 d= d*16/9; |
| 295 | 295 |
| 296 if(top_damage){ | 296 if(top_damage){ |
| 297 dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)]; | 297 dst[offset + x + 7*stride] = cm[dst[offset + x + 7*stride] + ((d*7)>>4)]; |
| 298 dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)]; | 298 dst[offset + x + 6*stride] = cm[dst[offset + x + 6*stride] + ((d*5)>>4)]; |
| 299 dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)]; | 299 dst[offset + x + 5*stride] = cm[dst[offset + x + 5*stride] + ((d*3)>>4)]; |
| 300 dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)]; | 300 dst[offset + x + 4*stride] = cm[dst[offset + x + 4*stride] + ((d*1)>>4)]; |
| 318 const int mb_stride = s->mb_stride; | 318 const int mb_stride = s->mb_stride; |
| 319 const int mb_width = s->mb_width; | 319 const int mb_width = s->mb_width; |
| 320 const int mb_height= s->mb_height; | 320 const int mb_height= s->mb_height; |
| 321 int i, depth, num_avail; | 321 int i, depth, num_avail; |
| 322 int mb_x, mb_y; | 322 int mb_x, mb_y; |
| 323 | 323 |
| 324 num_avail=0; | 324 num_avail=0; |
| 325 for(i=0; i<s->mb_num; i++){ | 325 for(i=0; i<s->mb_num; i++){ |
| 326 const int mb_xy= s->mb_index2xy[ i ]; | 326 const int mb_xy= s->mb_index2xy[ i ]; |
| 327 int f=0; | 327 int f=0; |
| 328 int error= s->error_status_table[mb_xy]; | 328 int error= s->error_status_table[mb_xy]; |
| 329 | 329 |
| 330 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check | 330 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) f=MV_FROZEN; //intra //FIXME check |
| 331 if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV | 331 if(!(error&MV_ERROR)) f=MV_FROZEN; //inter with undamaged MV |
| 332 | 332 |
| 333 fixed[mb_xy]= f; | 333 fixed[mb_xy]= f; |
| 334 if(f==MV_FROZEN) | 334 if(f==MV_FROZEN) |
| 335 num_avail++; | 335 num_avail++; |
| 336 } | 336 } |
| 337 | 337 |
| 338 if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){ | 338 if((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width/2){ |
| 339 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | 339 for(mb_y=0; mb_y<s->mb_height; mb_y++){ |
| 340 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | 340 for(mb_x=0; mb_x<s->mb_width; mb_x++){ |
| 341 const int mb_xy= mb_x + mb_y*s->mb_stride; | 341 const int mb_xy= mb_x + mb_y*s->mb_stride; |
| 342 | 342 |
| 343 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue; | 343 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue; |
| 344 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue; | 344 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue; |
| 345 | 345 |
| 346 s->mv_dir = MV_DIR_FORWARD; | 346 s->mv_dir = MV_DIR_FORWARD; |
| 347 s->mb_intra=0; | 347 s->mb_intra=0; |
| 357 decode_mb(s); | 357 decode_mb(s); |
| 358 } | 358 } |
| 359 } | 359 } |
| 360 return; | 360 return; |
| 361 } | 361 } |
| 362 | 362 |
| 363 for(depth=0;; depth++){ | 363 for(depth=0;; depth++){ |
| 364 int changed, pass, none_left; | 364 int changed, pass, none_left; |
| 365 | 365 |
| 366 none_left=1; | 366 none_left=1; |
| 367 changed=1; | 367 changed=1; |
| 368 for(pass=0; (changed || pass<2) && pass<10; pass++){ | 368 for(pass=0; (changed || pass<2) && pass<10; pass++){ |
| 369 int mb_x, mb_y; | 369 int mb_x, mb_y; |
| 370 int score_sum=0; | 370 int score_sum=0; |
| 371 | 371 |
| 372 changed=0; | 372 changed=0; |
| 373 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | 373 for(mb_y=0; mb_y<s->mb_height; mb_y++){ |
| 374 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | 374 for(mb_x=0; mb_x<s->mb_width; mb_x++){ |
| 375 const int mb_xy= mb_x + mb_y*s->mb_stride; | 375 const int mb_xy= mb_x + mb_y*s->mb_stride; |
| 376 int mv_predictor[8][2]={{0}}; | 376 int mv_predictor[8][2]={{0}}; |
| 382 const int mot_index= mb_x*2 + mb_y*2*mot_stride; | 382 const int mot_index= mb_x*2 + mb_y*2*mot_stride; |
| 383 int prev_x= s->current_picture.motion_val[0][mot_index][0]; | 383 int prev_x= s->current_picture.motion_val[0][mot_index][0]; |
| 384 int prev_y= s->current_picture.motion_val[0][mot_index][1]; | 384 int prev_y= s->current_picture.motion_val[0][mot_index][1]; |
| 385 | 385 |
| 386 if((mb_x^mb_y^pass)&1) continue; | 386 if((mb_x^mb_y^pass)&1) continue; |
| 387 | 387 |
| 388 if(fixed[mb_xy]==MV_FROZEN) continue; | 388 if(fixed[mb_xy]==MV_FROZEN) continue; |
| 389 assert(!IS_INTRA(s->current_picture.mb_type[mb_xy])); | 389 assert(!IS_INTRA(s->current_picture.mb_type[mb_xy])); |
| 390 assert(s->last_picture_ptr && s->last_picture_ptr->data[0]); | 390 assert(s->last_picture_ptr && s->last_picture_ptr->data[0]); |
| 391 | 391 |
| 392 j=0; | 392 j=0; |
| 393 if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1; | 393 if(mb_x>0 && fixed[mb_xy-1 ]==MV_FROZEN) j=1; |
| 394 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_FROZEN) j=1; | 394 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_FROZEN) j=1; |
| 395 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1; | 395 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_FROZEN) j=1; |
| 396 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1; | 396 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_FROZEN) j=1; |
| 400 if(mb_x>0 && fixed[mb_xy-1 ]==MV_CHANGED) j=1; | 400 if(mb_x>0 && fixed[mb_xy-1 ]==MV_CHANGED) j=1; |
| 401 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_CHANGED) j=1; | 401 if(mb_x+1<mb_width && fixed[mb_xy+1 ]==MV_CHANGED) j=1; |
| 402 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1; | 402 if(mb_y>0 && fixed[mb_xy-mb_stride]==MV_CHANGED) j=1; |
| 403 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1; | 403 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]==MV_CHANGED) j=1; |
| 404 if(j==0 && pass>1) continue; | 404 if(j==0 && pass>1) continue; |
| 405 | 405 |
| 406 none_left=0; | 406 none_left=0; |
| 407 | 407 |
| 408 if(mb_x>0 && fixed[mb_xy-1]){ | 408 if(mb_x>0 && fixed[mb_xy-1]){ |
| 409 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - 2][0]; | 409 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index - 2][0]; |
| 410 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - 2][1]; | 410 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index - 2][1]; |
| 411 pred_count++; | 411 pred_count++; |
| 412 } | 412 } |
| 424 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*2][0]; | 424 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index + mot_stride*2][0]; |
| 425 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*2][1]; | 425 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index + mot_stride*2][1]; |
| 426 pred_count++; | 426 pred_count++; |
| 427 } | 427 } |
| 428 if(pred_count==0) continue; | 428 if(pred_count==0) continue; |
| 429 | 429 |
| 430 if(pred_count>1){ | 430 if(pred_count>1){ |
| 431 int sum_x=0, sum_y=0; | 431 int sum_x=0, sum_y=0; |
| 432 int max_x, max_y, min_x, min_y; | 432 int max_x, max_y, min_x, min_y; |
| 433 | 433 |
| 434 for(j=0; j<pred_count; j++){ | 434 for(j=0; j<pred_count; j++){ |
| 435 sum_x+= mv_predictor[j][0]; | 435 sum_x+= mv_predictor[j][0]; |
| 436 sum_y+= mv_predictor[j][1]; | 436 sum_y+= mv_predictor[j][1]; |
| 437 } | 437 } |
| 438 | 438 |
| 439 /* mean */ | 439 /* mean */ |
| 440 mv_predictor[pred_count][0] = sum_x/j; | 440 mv_predictor[pred_count][0] = sum_x/j; |
| 441 mv_predictor[pred_count][1] = sum_y/j; | 441 mv_predictor[pred_count][1] = sum_y/j; |
| 442 | 442 |
| 443 /* median */ | 443 /* median */ |
| 444 if(pred_count>=3){ | 444 if(pred_count>=3){ |
| 445 min_y= min_x= 99999; | 445 min_y= min_x= 99999; |
| 446 max_y= max_x=-99999; | 446 max_y= max_x=-99999; |
| 447 }else{ | 447 }else{ |
| 453 min_x= FFMIN(min_x, mv_predictor[j][0]); | 453 min_x= FFMIN(min_x, mv_predictor[j][0]); |
| 454 min_y= FFMIN(min_y, mv_predictor[j][1]); | 454 min_y= FFMIN(min_y, mv_predictor[j][1]); |
| 455 } | 455 } |
| 456 mv_predictor[pred_count+1][0] = sum_x - max_x - min_x; | 456 mv_predictor[pred_count+1][0] = sum_x - max_x - min_x; |
| 457 mv_predictor[pred_count+1][1] = sum_y - max_y - min_y; | 457 mv_predictor[pred_count+1][1] = sum_y - max_y - min_y; |
| 458 | 458 |
| 459 if(pred_count==4){ | 459 if(pred_count==4){ |
| 460 mv_predictor[pred_count+1][0] /= 2; | 460 mv_predictor[pred_count+1][0] /= 2; |
| 461 mv_predictor[pred_count+1][1] /= 2; | 461 mv_predictor[pred_count+1][1] /= 2; |
| 462 } | 462 } |
| 463 pred_count+=2; | 463 pred_count+=2; |
| 464 } | 464 } |
| 465 | 465 |
| 466 /* zero MV */ | 466 /* zero MV */ |
| 467 pred_count++; | 467 pred_count++; |
| 468 | 468 |
| 469 /* last MV */ | 469 /* last MV */ |
| 470 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0]; | 470 mv_predictor[pred_count][0]= s->current_picture.motion_val[0][mot_index][0]; |
| 471 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1]; | 471 mv_predictor[pred_count][1]= s->current_picture.motion_val[0][mot_index][1]; |
| 472 pred_count++; | 472 pred_count++; |
| 473 | 473 |
| 474 s->mv_dir = MV_DIR_FORWARD; | 474 s->mv_dir = MV_DIR_FORWARD; |
| 475 s->mb_intra=0; | 475 s->mb_intra=0; |
| 476 s->mv_type = MV_TYPE_16X16; | 476 s->mv_type = MV_TYPE_16X16; |
| 477 s->mb_skipped=0; | 477 s->mb_skipped=0; |
| 478 | 478 |
| 487 | 487 |
| 488 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0]; | 488 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0]; |
| 489 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1]; | 489 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1]; |
| 490 | 490 |
| 491 decode_mb(s); | 491 decode_mb(s); |
| 492 | 492 |
| 493 if(mb_x>0 && fixed[mb_xy-1]){ | 493 if(mb_x>0 && fixed[mb_xy-1]){ |
| 494 int k; | 494 int k; |
| 495 for(k=0; k<16; k++) | 495 for(k=0; k<16; k++) |
| 496 score += ABS(src[k*s->linesize-1 ]-src[k*s->linesize ]); | 496 score += ABS(src[k*s->linesize-1 ]-src[k*s->linesize ]); |
| 497 } | 497 } |
| 508 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){ | 508 if(mb_y+1<mb_height && fixed[mb_xy+mb_stride]){ |
| 509 int k; | 509 int k; |
| 510 for(k=0; k<16; k++) | 510 for(k=0; k<16; k++) |
| 511 score += ABS(src[k+s->linesize*15]-src[k+s->linesize*16]); | 511 score += ABS(src[k+s->linesize*15]-src[k+s->linesize*16]); |
| 512 } | 512 } |
| 513 | 513 |
| 514 if(score <= best_score){ // <= will favor the last MV | 514 if(score <= best_score){ // <= will favor the last MV |
| 515 best_score= score; | 515 best_score= score; |
| 516 best_pred= j; | 516 best_pred= j; |
| 517 } | 517 } |
| 518 } | 518 } |
| 521 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[best_pred][0]; | 521 s->current_picture.motion_val[0][mot_index][0]= s->mv[0][0][0]= mv_predictor[best_pred][0]; |
| 522 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[best_pred][1]; | 522 s->current_picture.motion_val[0][mot_index][1]= s->mv[0][0][1]= mv_predictor[best_pred][1]; |
| 523 | 523 |
| 524 decode_mb(s); | 524 decode_mb(s); |
| 525 | 525 |
| 526 | 526 |
| 527 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){ | 527 if(s->mv[0][0][0] != prev_x || s->mv[0][0][1] != prev_y){ |
| 528 fixed[mb_xy]=MV_CHANGED; | 528 fixed[mb_xy]=MV_CHANGED; |
| 529 changed++; | 529 changed++; |
| 530 }else | 530 }else |
| 531 fixed[mb_xy]=MV_UNCHANGED; | 531 fixed[mb_xy]=MV_UNCHANGED; |
| 532 } | 532 } |
| 533 } | 533 } |
| 534 | 534 |
| 535 // printf(".%d/%d", changed, score_sum); fflush(stdout); | 535 // printf(".%d/%d", changed, score_sum); fflush(stdout); |
| 536 } | 536 } |
| 537 | 537 |
| 538 if(none_left) | 538 if(none_left) |
| 539 return; | 539 return; |
| 540 | 540 |
| 541 for(i=0; i<s->mb_num; i++){ | 541 for(i=0; i<s->mb_num; i++){ |
| 542 int mb_xy= s->mb_index2xy[i]; | 542 int mb_xy= s->mb_index2xy[i]; |
| 543 if(fixed[mb_xy]) | 543 if(fixed[mb_xy]) |
| 544 fixed[mb_xy]=MV_FROZEN; | 544 fixed[mb_xy]=MV_FROZEN; |
| 545 } | 545 } |
| 546 // printf(":"); fflush(stdout); | 546 // printf(":"); fflush(stdout); |
| 547 } | 547 } |
| 548 } | 548 } |
| 549 | 549 |
| 550 static int is_intra_more_likely(MpegEncContext *s){ | 550 static int is_intra_more_likely(MpegEncContext *s){ |
| 551 int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y; | 551 int is_intra_likely, i, j, undamaged_count, skip_amount, mb_x, mb_y; |
| 552 | 552 |
| 553 if(s->last_picture_ptr==NULL) return 1; //no previous frame available -> use spatial prediction | 553 if(s->last_picture_ptr==NULL) return 1; //no previous frame available -> use spatial prediction |
| 554 | 554 |
| 555 undamaged_count=0; | 555 undamaged_count=0; |
| 556 for(i=0; i<s->mb_num; i++){ | 556 for(i=0; i<s->mb_num; i++){ |
| 557 const int mb_xy= s->mb_index2xy[i]; | 557 const int mb_xy= s->mb_index2xy[i]; |
| 558 const int error= s->error_status_table[mb_xy]; | 558 const int error= s->error_status_table[mb_xy]; |
| 559 if(!((error&DC_ERROR) && (error&MV_ERROR))) | 559 if(!((error&DC_ERROR) && (error&MV_ERROR))) |
| 560 undamaged_count++; | 560 undamaged_count++; |
| 561 } | 561 } |
| 562 | 562 |
| 563 if(undamaged_count < 5) return 0; //allmost all MBs damaged -> use temporal prediction | 563 if(undamaged_count < 5) return 0; //allmost all MBs damaged -> use temporal prediction |
| 564 | 564 |
| 565 skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs | 565 skip_amount= FFMAX(undamaged_count/50, 1); //check only upto 50 MBs |
| 566 is_intra_likely=0; | 566 is_intra_likely=0; |
| 567 | 567 |
| 568 j=0; | 568 j=0; |
| 569 for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){ | 569 for(mb_y= 0; mb_y<s->mb_height-1; mb_y++){ |
| 570 for(mb_x= 0; mb_x<s->mb_width; mb_x++){ | 570 for(mb_x= 0; mb_x<s->mb_width; mb_x++){ |
| 572 const int mb_xy= mb_x + mb_y*s->mb_stride; | 572 const int mb_xy= mb_x + mb_y*s->mb_stride; |
| 573 | 573 |
| 574 error= s->error_status_table[mb_xy]; | 574 error= s->error_status_table[mb_xy]; |
| 575 if((error&DC_ERROR) && (error&MV_ERROR)) | 575 if((error&DC_ERROR) && (error&MV_ERROR)) |
| 576 continue; //skip damaged | 576 continue; //skip damaged |
| 577 | 577 |
| 578 j++; | 578 j++; |
| 579 if((j%skip_amount) != 0) continue; //skip a few to speed things up | 579 if((j%skip_amount) != 0) continue; //skip a few to speed things up |
| 580 | 580 |
| 581 if(s->pict_type==I_TYPE){ | 581 if(s->pict_type==I_TYPE){ |
| 582 uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | 582 uint8_t *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; |
| 583 uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize; | 583 uint8_t *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize; |
| 584 | 584 |
| 585 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16); | 585 is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr , s->linesize, 16); |
| 586 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16); | 586 is_intra_likely -= s->dsp.sad[0](NULL, last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize, 16); |
| 587 }else{ | 587 }else{ |
| 588 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) | 588 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) |
| 589 is_intra_likely++; | 589 is_intra_likely++; |
| 591 is_intra_likely--; | 591 is_intra_likely--; |
| 592 } | 592 } |
| 593 } | 593 } |
| 594 } | 594 } |
| 595 //printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); | 595 //printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type); |
| 596 return is_intra_likely > 0; | 596 return is_intra_likely > 0; |
| 597 } | 597 } |
| 598 | 598 |
| 599 void ff_er_frame_start(MpegEncContext *s){ | 599 void ff_er_frame_start(MpegEncContext *s){ |
| 600 if(!s->error_resilience) return; | 600 if(!s->error_resilience) return; |
| 601 | 601 |
| 613 const int start_i= clip(startx + starty * s->mb_width , 0, s->mb_num-1); | 613 const int start_i= clip(startx + starty * s->mb_width , 0, s->mb_num-1); |
| 614 const int end_i = clip(endx + endy * s->mb_width , 0, s->mb_num); | 614 const int end_i = clip(endx + endy * s->mb_width , 0, s->mb_num); |
| 615 const int start_xy= s->mb_index2xy[start_i]; | 615 const int start_xy= s->mb_index2xy[start_i]; |
| 616 const int end_xy = s->mb_index2xy[end_i]; | 616 const int end_xy = s->mb_index2xy[end_i]; |
| 617 int mask= -1; | 617 int mask= -1; |
| 618 | 618 |
| 619 if(!s->error_resilience) return; | 619 if(!s->error_resilience) return; |
| 620 | 620 |
| 621 mask &= ~VP_START; | 621 mask &= ~VP_START; |
| 622 if(status & (AC_ERROR|AC_END)){ | 622 if(status & (AC_ERROR|AC_END)){ |
| 623 mask &= ~(AC_ERROR|AC_END); | 623 mask &= ~(AC_ERROR|AC_END); |
| 641 for(i=start_xy; i<end_xy; i++){ | 641 for(i=start_xy; i<end_xy; i++){ |
| 642 s->error_status_table[ i ] &= mask; | 642 s->error_status_table[ i ] &= mask; |
| 643 } | 643 } |
| 644 } | 644 } |
| 645 | 645 |
| 646 if(end_i == s->mb_num) | 646 if(end_i == s->mb_num) |
| 647 s->error_count= INT_MAX; | 647 s->error_count= INT_MAX; |
| 648 else{ | 648 else{ |
| 649 s->error_status_table[end_xy] &= mask; | 649 s->error_status_table[end_xy] &= mask; |
| 650 s->error_status_table[end_xy] |= status; | 650 s->error_status_table[end_xy] |= status; |
| 651 } | 651 } |
| 652 | 652 |
| 653 s->error_status_table[start_xy] |= VP_START; | 653 s->error_status_table[start_xy] |= VP_START; |
| 654 | 654 |
| 655 if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){ | 655 if(start_xy > 0 && s->avctx->thread_count <= 1 && s->avctx->skip_top*s->mb_width < start_i){ |
| 656 int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ]; | 656 int prev_status= s->error_status_table[ s->mb_index2xy[start_i - 1] ]; |
| 657 | 657 |
| 658 prev_status &= ~ VP_START; | 658 prev_status &= ~ VP_START; |
| 659 if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX; | 659 if(prev_status != (MV_END|DC_END|AC_END)) s->error_count= INT_MAX; |
| 660 } | 660 } |
| 661 } | 661 } |
| 662 | 662 |
| 666 int threshold_part[4]= {100,100,100}; | 666 int threshold_part[4]= {100,100,100}; |
| 667 int threshold= 50; | 667 int threshold= 50; |
| 668 int is_intra_likely; | 668 int is_intra_likely; |
| 669 int size = s->b8_stride * 2 * s->mb_height; | 669 int size = s->b8_stride * 2 * s->mb_height; |
| 670 Picture *pic= s->current_picture_ptr; | 670 Picture *pic= s->current_picture_ptr; |
| 671 | 671 |
| 672 if(!s->error_resilience || s->error_count==0 || | 672 if(!s->error_resilience || s->error_count==0 || |
| 673 s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return; | 673 s->error_count==3*s->mb_width*(s->avctx->skip_top + s->avctx->skip_bottom)) return; |
| 674 | 674 |
| 675 if(s->current_picture.motion_val[0] == NULL){ | 675 if(s->current_picture.motion_val[0] == NULL){ |
| 676 av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n"); | 676 av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n"); |
| 677 | 677 |
| 678 for(i=0; i<2; i++){ | 678 for(i=0; i<2; i++){ |
| 679 pic->ref_index[i]= av_mallocz(size * sizeof(uint8_t)); | 679 pic->ref_index[i]= av_mallocz(size * sizeof(uint8_t)); |
| 680 pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t)); | 680 pic->motion_val_base[i]= av_mallocz((size+4) * 2 * sizeof(uint16_t)); |
| 681 pic->motion_val[i]= pic->motion_val_base[i]+4; | 681 pic->motion_val[i]= pic->motion_val_base[i]+4; |
| 682 } | 682 } |
| 683 pic->motion_subsample_log2= 3; | 683 pic->motion_subsample_log2= 3; |
| 684 s->current_picture= *s->current_picture_ptr; | 684 s->current_picture= *s->current_picture_ptr; |
| 685 } | 685 } |
| 686 | 686 |
| 687 for(i=0; i<2; i++){ | 687 for(i=0; i<2; i++){ |
| 688 if(pic->ref_index[i]) | 688 if(pic->ref_index[i]) |
| 689 memset(pic->ref_index[i], 0, size * sizeof(uint8_t)); | 689 memset(pic->ref_index[i], 0, size * sizeof(uint8_t)); |
| 690 } | 690 } |
| 691 | 691 |
| 692 if(s->avctx->debug&FF_DEBUG_ER){ | 692 if(s->avctx->debug&FF_DEBUG_ER){ |
| 693 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | 693 for(mb_y=0; mb_y<s->mb_height; mb_y++){ |
| 694 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | 694 for(mb_x=0; mb_x<s->mb_width; mb_x++){ |
| 695 int status= s->error_status_table[mb_x + mb_y*s->mb_stride]; | 695 int status= s->error_status_table[mb_x + mb_y*s->mb_stride]; |
| 696 | 696 |
| 697 av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status); | 697 av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status); |
| 698 } | 698 } |
| 699 av_log(s->avctx, AV_LOG_DEBUG, "\n"); | 699 av_log(s->avctx, AV_LOG_DEBUG, "\n"); |
| 700 } | 700 } |
| 701 } | 701 } |
| 702 | 702 |
| 703 #if 1 | 703 #if 1 |
| 704 /* handle overlapping slices */ | 704 /* handle overlapping slices */ |
| 705 for(error_type=1; error_type<=3; error_type++){ | 705 for(error_type=1; error_type<=3; error_type++){ |
| 706 int end_ok=0; | 706 int end_ok=0; |
| 707 | 707 |
| 708 for(i=s->mb_num-1; i>=0; i--){ | 708 for(i=s->mb_num-1; i>=0; i--){ |
| 709 const int mb_xy= s->mb_index2xy[i]; | 709 const int mb_xy= s->mb_index2xy[i]; |
| 710 int error= s->error_status_table[mb_xy]; | 710 int error= s->error_status_table[mb_xy]; |
| 711 | 711 |
| 712 if(error&(1<<error_type)) | 712 if(error&(1<<error_type)) |
| 713 end_ok=1; | 713 end_ok=1; |
| 714 if(error&(8<<error_type)) | 714 if(error&(8<<error_type)) |
| 715 end_ok=1; | 715 end_ok=1; |
| 716 | 716 |
| 728 int end_ok=0; | 728 int end_ok=0; |
| 729 | 729 |
| 730 for(i=s->mb_num-1; i>=0; i--){ | 730 for(i=s->mb_num-1; i>=0; i--){ |
| 731 const int mb_xy= s->mb_index2xy[i]; | 731 const int mb_xy= s->mb_index2xy[i]; |
| 732 int error= s->error_status_table[mb_xy]; | 732 int error= s->error_status_table[mb_xy]; |
| 733 | 733 |
| 734 if(error&AC_END) | 734 if(error&AC_END) |
| 735 end_ok=0; | 735 end_ok=0; |
| 736 if((error&MV_END) || (error&DC_END) || (error&AC_ERROR)) | 736 if((error&MV_END) || (error&DC_END) || (error&AC_ERROR)) |
| 737 end_ok=1; | 737 end_ok=1; |
| 738 | 738 |
| 745 } | 745 } |
| 746 #endif | 746 #endif |
| 747 /* handle missing slices */ | 747 /* handle missing slices */ |
| 748 if(s->error_resilience>=4){ | 748 if(s->error_resilience>=4){ |
| 749 int end_ok=1; | 749 int end_ok=1; |
| 750 | 750 |
| 751 for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack | 751 for(i=s->mb_num-2; i>=s->mb_width+100; i--){ //FIXME +100 hack |
| 752 const int mb_xy= s->mb_index2xy[i]; | 752 const int mb_xy= s->mb_index2xy[i]; |
| 753 int error1= s->error_status_table[mb_xy ]; | 753 int error1= s->error_status_table[mb_xy ]; |
| 754 int error2= s->error_status_table[s->mb_index2xy[i+1]]; | 754 int error2= s->error_status_table[s->mb_index2xy[i+1]]; |
| 755 | 755 |
| 756 if(error1&VP_START) | 756 if(error1&VP_START) |
| 757 end_ok=1; | 757 end_ok=1; |
| 758 | 758 |
| 759 if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) | 759 if( error2==(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) |
| 760 && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) | 760 && error1!=(VP_START|DC_ERROR|AC_ERROR|MV_ERROR|AC_END|DC_END|MV_END) |
| 761 && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninited | 761 && ((error1&AC_END) || (error1&DC_END) || (error1&MV_END))){ //end & uninited |
| 762 end_ok=0; | 762 end_ok=0; |
| 763 } | 763 } |
| 764 | 764 |
| 765 if(!end_ok) | 765 if(!end_ok) |
| 766 s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR; | 766 s->error_status_table[mb_xy]|= DC_ERROR|AC_ERROR|MV_ERROR; |
| 767 } | 767 } |
| 768 } | 768 } |
| 769 | 769 |
| 770 #if 1 | 770 #if 1 |
| 771 /* backward mark errors */ | 771 /* backward mark errors */ |
| 772 distance=9999999; | 772 distance=9999999; |
| 773 for(error_type=1; error_type<=3; error_type++){ | 773 for(error_type=1; error_type<=3; error_type++){ |
| 774 for(i=s->mb_num-1; i>=0; i--){ | 774 for(i=s->mb_num-1; i>=0; i--){ |
| 775 const int mb_xy= s->mb_index2xy[i]; | 775 const int mb_xy= s->mb_index2xy[i]; |
| 776 int error= s->error_status_table[mb_xy]; | 776 int error= s->error_status_table[mb_xy]; |
| 777 | 777 |
| 778 if(!s->mbskip_table[mb_xy]) //FIXME partition specific | 778 if(!s->mbskip_table[mb_xy]) //FIXME partition specific |
| 779 distance++; | 779 distance++; |
| 780 if(error&(1<<error_type)) | 780 if(error&(1<<error_type)) |
| 781 distance= 0; | 781 distance= 0; |
| 782 | 782 |
| 783 if(s->partitioned_frame){ | 783 if(s->partitioned_frame){ |
| 784 if(distance < threshold_part[error_type-1]) | 784 if(distance < threshold_part[error_type-1]) |
| 797 /* forward mark errors */ | 797 /* forward mark errors */ |
| 798 error=0; | 798 error=0; |
| 799 for(i=0; i<s->mb_num; i++){ | 799 for(i=0; i<s->mb_num; i++){ |
| 800 const int mb_xy= s->mb_index2xy[i]; | 800 const int mb_xy= s->mb_index2xy[i]; |
| 801 int old_error= s->error_status_table[mb_xy]; | 801 int old_error= s->error_status_table[mb_xy]; |
| 802 | 802 |
| 803 if(old_error&VP_START) | 803 if(old_error&VP_START) |
| 804 error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR); | 804 error= old_error& (DC_ERROR|AC_ERROR|MV_ERROR); |
| 805 else{ | 805 else{ |
| 806 error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR); | 806 error|= old_error& (DC_ERROR|AC_ERROR|MV_ERROR); |
| 807 s->error_status_table[mb_xy]|= error; | 807 s->error_status_table[mb_xy]|= error; |
| 842 if(is_intra_likely) | 842 if(is_intra_likely) |
| 843 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4; | 843 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4; |
| 844 else | 844 else |
| 845 s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0; | 845 s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0; |
| 846 } | 846 } |
| 847 | 847 |
| 848 /* handle inter blocks with damaged AC */ | 848 /* handle inter blocks with damaged AC */ |
| 849 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | 849 for(mb_y=0; mb_y<s->mb_height; mb_y++){ |
| 850 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | 850 for(mb_x=0; mb_x<s->mb_width; mb_x++){ |
| 851 const int mb_xy= mb_x + mb_y * s->mb_stride; | 851 const int mb_xy= mb_x + mb_y * s->mb_stride; |
| 852 const int mb_type= s->current_picture.mb_type[mb_xy]; | 852 const int mb_type= s->current_picture.mb_type[mb_xy]; |
| 853 error= s->error_status_table[mb_xy]; | 853 error= s->error_status_table[mb_xy]; |
| 854 | 854 |
| 855 if(IS_INTRA(mb_type)) continue; //intra | 855 if(IS_INTRA(mb_type)) continue; //intra |
| 856 if(error&MV_ERROR) continue; //inter with damaged MV | 856 if(error&MV_ERROR) continue; //inter with damaged MV |
| 857 if(!(error&AC_ERROR)) continue; //undamaged inter | 857 if(!(error&AC_ERROR)) continue; //undamaged inter |
| 858 | 858 |
| 859 s->mv_dir = MV_DIR_FORWARD; | 859 s->mv_dir = MV_DIR_FORWARD; |
| 860 s->mb_intra=0; | 860 s->mb_intra=0; |
| 861 s->mb_skipped=0; | 861 s->mb_skipped=0; |
| 862 if(IS_8X8(mb_type)){ | 862 if(IS_8X8(mb_type)){ |
| 863 int mb_index= mb_x*2 + mb_y*2*s->b8_stride; | 863 int mb_index= mb_x*2 + mb_y*2*s->b8_stride; |
| 870 }else{ | 870 }else{ |
| 871 s->mv_type = MV_TYPE_16X16; | 871 s->mv_type = MV_TYPE_16X16; |
| 872 s->mv[0][0][0] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][0]; | 872 s->mv[0][0][0] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][0]; |
| 873 s->mv[0][0][1] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][1]; | 873 s->mv[0][0][1] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][1]; |
| 874 } | 874 } |
| 875 | 875 |
| 876 s->dsp.clear_blocks(s->block[0]); | 876 s->dsp.clear_blocks(s->block[0]); |
| 877 | 877 |
| 878 s->mb_x= mb_x; | 878 s->mb_x= mb_x; |
| 879 s->mb_y= mb_y; | 879 s->mb_y= mb_y; |
| 880 decode_mb(s); | 880 decode_mb(s); |
| 891 error= s->error_status_table[mb_xy]; | 891 error= s->error_status_table[mb_xy]; |
| 892 | 892 |
| 893 if(IS_INTRA(mb_type)) continue; | 893 if(IS_INTRA(mb_type)) continue; |
| 894 if(!(error&MV_ERROR)) continue; //inter with undamaged MV | 894 if(!(error&MV_ERROR)) continue; //inter with undamaged MV |
| 895 if(!(error&AC_ERROR)) continue; //undamaged inter | 895 if(!(error&AC_ERROR)) continue; //undamaged inter |
| 896 | 896 |
| 897 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD; | 897 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD; |
| 898 s->mb_intra=0; | 898 s->mb_intra=0; |
| 899 s->mv_type = MV_TYPE_16X16; | 899 s->mv_type = MV_TYPE_16X16; |
| 900 s->mb_skipped=0; | 900 s->mb_skipped=0; |
| 901 | 901 |
| 902 if(s->pp_time){ | 902 if(s->pp_time){ |
| 903 int time_pp= s->pp_time; | 903 int time_pp= s->pp_time; |
| 904 int time_pb= s->pb_time; | 904 int time_pb= s->pb_time; |
| 905 | 905 |
| 906 s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp; | 906 s->mv[0][0][0] = s->next_picture.motion_val[0][xy][0]*time_pb/time_pp; |
| 907 s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp; | 907 s->mv[0][0][1] = s->next_picture.motion_val[0][xy][1]*time_pb/time_pp; |
| 908 s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp; | 908 s->mv[1][0][0] = s->next_picture.motion_val[0][xy][0]*(time_pb - time_pp)/time_pp; |
| 909 s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp; | 909 s->mv[1][0][1] = s->next_picture.motion_val[0][xy][1]*(time_pb - time_pp)/time_pp; |
| 910 }else{ | 910 }else{ |
| 933 int dc, dcu, dcv, y, n; | 933 int dc, dcu, dcv, y, n; |
| 934 int16_t *dc_ptr; | 934 int16_t *dc_ptr; |
| 935 uint8_t *dest_y, *dest_cb, *dest_cr; | 935 uint8_t *dest_y, *dest_cb, *dest_cr; |
| 936 const int mb_xy= mb_x + mb_y * s->mb_stride; | 936 const int mb_xy= mb_x + mb_y * s->mb_stride; |
| 937 const int mb_type= s->current_picture.mb_type[mb_xy]; | 937 const int mb_type= s->current_picture.mb_type[mb_xy]; |
| 938 | 938 |
| 939 error= s->error_status_table[mb_xy]; | 939 error= s->error_status_table[mb_xy]; |
| 940 | 940 |
| 941 if(IS_INTRA(mb_type) && s->partitioned_frame) continue; | 941 if(IS_INTRA(mb_type) && s->partitioned_frame) continue; |
| 942 // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good? | 942 // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good? |
| 943 | 943 |
| 944 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | 944 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; |
| 945 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | 945 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; |
| 946 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | 946 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; |
| 947 | 947 |
| 948 dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride]; | 948 dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride]; |
| 949 for(n=0; n<4; n++){ | 949 for(n=0; n<4; n++){ |
| 950 dc=0; | 950 dc=0; |
| 951 for(y=0; y<8; y++){ | 951 for(y=0; y<8; y++){ |
| 952 int x; | 952 int x; |
| 964 dcu+=dest_cb[x + y*(s->uvlinesize)]; | 964 dcu+=dest_cb[x + y*(s->uvlinesize)]; |
| 965 dcv+=dest_cr[x + y*(s->uvlinesize)]; | 965 dcv+=dest_cr[x + y*(s->uvlinesize)]; |
| 966 } | 966 } |
| 967 } | 967 } |
| 968 s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3; | 968 s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3; |
| 969 s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3; | 969 s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3; |
| 970 } | 970 } |
| 971 } | 971 } |
| 972 #if 1 | 972 #if 1 |
| 973 /* guess DC for damaged blocks */ | 973 /* guess DC for damaged blocks */ |
| 974 guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1); | 974 guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1); |
| 975 guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0); | 975 guess_dc(s, s->dc_val[1], s->mb_width , s->mb_height , s->mb_stride, 0); |
| 976 guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0); | 976 guess_dc(s, s->dc_val[2], s->mb_width , s->mb_height , s->mb_stride, 0); |
| 977 #endif | 977 #endif |
| 978 /* filter luma DC */ | 978 /* filter luma DC */ |
| 979 filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride); | 979 filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride); |
| 980 | 980 |
| 981 #if 1 | 981 #if 1 |
| 982 /* render DC only intra */ | 982 /* render DC only intra */ |
| 983 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | 983 for(mb_y=0; mb_y<s->mb_height; mb_y++){ |
| 984 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | 984 for(mb_x=0; mb_x<s->mb_width; mb_x++){ |
| 985 uint8_t *dest_y, *dest_cb, *dest_cr; | 985 uint8_t *dest_y, *dest_cb, *dest_cr; |
| 988 | 988 |
| 989 error= s->error_status_table[mb_xy]; | 989 error= s->error_status_table[mb_xy]; |
| 990 | 990 |
| 991 if(IS_INTER(mb_type)) continue; | 991 if(IS_INTER(mb_type)) continue; |
| 992 if(!(error&AC_ERROR)) continue; //undamaged | 992 if(!(error&AC_ERROR)) continue; //undamaged |
| 993 | 993 |
| 994 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | 994 dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; |
| 995 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | 995 dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; |
| 996 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | 996 dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; |
| 997 | 997 |
| 998 put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y); | 998 put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y); |
| 999 } | 999 } |
| 1000 } | 1000 } |
| 1001 #endif | 1001 #endif |
| 1002 | 1002 |
| 1003 if(s->avctx->error_concealment&FF_EC_DEBLOCK){ | 1003 if(s->avctx->error_concealment&FF_EC_DEBLOCK){ |
| 1004 /* filter horizontal block boundaries */ | 1004 /* filter horizontal block boundaries */ |
| 1005 h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); | 1005 h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); |
| 1006 h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0); | 1006 h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0); |
| 1007 h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); | 1007 h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); |
| 1017 #endif | 1017 #endif |
| 1018 /* clean a few tables */ | 1018 /* clean a few tables */ |
| 1019 for(i=0; i<s->mb_num; i++){ | 1019 for(i=0; i<s->mb_num; i++){ |
| 1020 const int mb_xy= s->mb_index2xy[i]; | 1020 const int mb_xy= s->mb_index2xy[i]; |
| 1021 int error= s->error_status_table[mb_xy]; | 1021 int error= s->error_status_table[mb_xy]; |
| 1022 | 1022 |
| 1023 if(s->pict_type!=B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){ | 1023 if(s->pict_type!=B_TYPE && (error&(DC_ERROR|MV_ERROR|AC_ERROR))){ |
| 1024 s->mbskip_table[mb_xy]=0; | 1024 s->mbskip_table[mb_xy]=0; |
| 1025 } | 1025 } |
| 1026 s->mbintra_table[mb_xy]=1; | 1026 s->mbintra_table[mb_xy]=1; |
| 1027 } | 1027 } |
| 1028 } | 1028 } |
