Mercurial > libavcodec.hg
comparison error_resilience.c @ 9381:7dfbd59b04e5 libavcodec
Make sure error resilience does not try to use unavailable reference frames.
Fixes the crash described in issue 706.
author | reimar |
---|---|
date | Fri, 10 Apr 2009 07:17:30 +0000 |
parents | 2767eb8c227d |
children | 2c2827f792a1 |
comparison
equal
deleted
inserted
replaced
9380:54e650136c87 | 9381:7dfbd59b04e5 |
---|---|
342 const int mb_xy= mb_x + mb_y*s->mb_stride; | 342 const int mb_xy= mb_x + mb_y*s->mb_stride; |
343 | 343 |
344 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue; | 344 if(IS_INTRA(s->current_picture.mb_type[mb_xy])) continue; |
345 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue; | 345 if(!(s->error_status_table[mb_xy]&MV_ERROR)) continue; |
346 | 346 |
347 s->mv_dir = MV_DIR_FORWARD; | 347 s->mv_dir = s->last_picture.data[0] ? MV_DIR_FORWARD : MV_DIR_BACKWARD; |
348 s->mb_intra=0; | 348 s->mb_intra=0; |
349 s->mv_type = MV_TYPE_16X16; | 349 s->mv_type = MV_TYPE_16X16; |
350 s->mb_skipped=0; | 350 s->mb_skipped=0; |
351 | 351 |
352 s->dsp.clear_blocks(s->block[0]); | 352 s->dsp.clear_blocks(s->block[0]); |
858 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4; | 858 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4; |
859 else | 859 else |
860 s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0; | 860 s->current_picture.mb_type[mb_xy]= MB_TYPE_16x16 | MB_TYPE_L0; |
861 } | 861 } |
862 | 862 |
863 // change inter to intra blocks if no reference frames are available | |
864 if (!s->last_picture.data[0] && !s->next_picture.data[0]) | |
865 for(i=0; i<s->mb_num; i++){ | |
866 const int mb_xy= s->mb_index2xy[i]; | |
867 if(!IS_INTRA(s->current_picture.mb_type[mb_xy])) | |
868 s->current_picture.mb_type[mb_xy]= MB_TYPE_INTRA4x4; | |
869 } | |
870 | |
863 /* handle inter blocks with damaged AC */ | 871 /* handle inter blocks with damaged AC */ |
864 for(mb_y=0; mb_y<s->mb_height; mb_y++){ | 872 for(mb_y=0; mb_y<s->mb_height; mb_y++){ |
865 for(mb_x=0; mb_x<s->mb_width; mb_x++){ | 873 for(mb_x=0; mb_x<s->mb_width; mb_x++){ |
866 const int mb_xy= mb_x + mb_y * s->mb_stride; | 874 const int mb_xy= mb_x + mb_y * s->mb_stride; |
867 const int mb_type= s->current_picture.mb_type[mb_xy]; | 875 const int mb_type= s->current_picture.mb_type[mb_xy]; |
876 int dir = !s->last_picture.data[0]; | |
868 error= s->error_status_table[mb_xy]; | 877 error= s->error_status_table[mb_xy]; |
869 | 878 |
870 if(IS_INTRA(mb_type)) continue; //intra | 879 if(IS_INTRA(mb_type)) continue; //intra |
871 if(error&MV_ERROR) continue; //inter with damaged MV | 880 if(error&MV_ERROR) continue; //inter with damaged MV |
872 if(!(error&AC_ERROR)) continue; //undamaged inter | 881 if(!(error&AC_ERROR)) continue; //undamaged inter |
873 | 882 |
874 s->mv_dir = MV_DIR_FORWARD; | 883 s->mv_dir = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD; |
875 s->mb_intra=0; | 884 s->mb_intra=0; |
876 s->mb_skipped=0; | 885 s->mb_skipped=0; |
877 if(IS_8X8(mb_type)){ | 886 if(IS_8X8(mb_type)){ |
878 int mb_index= mb_x*2 + mb_y*2*s->b8_stride; | 887 int mb_index= mb_x*2 + mb_y*2*s->b8_stride; |
879 int j; | 888 int j; |
880 s->mv_type = MV_TYPE_8X8; | 889 s->mv_type = MV_TYPE_8X8; |
881 for(j=0; j<4; j++){ | 890 for(j=0; j<4; j++){ |
882 s->mv[0][j][0] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0]; | 891 s->mv[0][j][0] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0]; |
883 s->mv[0][j][1] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1]; | 892 s->mv[0][j][1] = s->current_picture.motion_val[dir][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1]; |
884 } | 893 } |
885 }else{ | 894 }else{ |
886 s->mv_type = MV_TYPE_16X16; | 895 s->mv_type = MV_TYPE_16X16; |
887 s->mv[0][0][0] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][0]; | 896 s->mv[0][0][0] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][0]; |
888 s->mv[0][0][1] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][1]; | 897 s->mv[0][0][1] = s->current_picture.motion_val[dir][ mb_x*2 + mb_y*2*s->b8_stride ][1]; |
889 } | 898 } |
890 | 899 |
891 s->dsp.clear_blocks(s->block[0]); | 900 s->dsp.clear_blocks(s->block[0]); |
892 | 901 |
893 s->mb_x= mb_x; | 902 s->mb_x= mb_x; |
908 if(IS_INTRA(mb_type)) continue; | 917 if(IS_INTRA(mb_type)) continue; |
909 if(!(error&MV_ERROR)) continue; //inter with undamaged MV | 918 if(!(error&MV_ERROR)) continue; //inter with undamaged MV |
910 if(!(error&AC_ERROR)) continue; //undamaged inter | 919 if(!(error&AC_ERROR)) continue; //undamaged inter |
911 | 920 |
912 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD; | 921 s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD; |
922 if(!s->last_picture.data[0]) s->mv_dir &= ~MV_DIR_FORWARD; | |
923 if(!s->next_picture.data[0]) s->mv_dir &= ~MV_DIR_BACKWARD; | |
913 s->mb_intra=0; | 924 s->mb_intra=0; |
914 s->mv_type = MV_TYPE_16X16; | 925 s->mv_type = MV_TYPE_16X16; |
915 s->mb_skipped=0; | 926 s->mb_skipped=0; |
916 | 927 |
917 if(s->pp_time){ | 928 if(s->pp_time){ |