Mercurial > libavcodec.hg
comparison h264.c @ 7898:a33287a39a55 libavcodec
Make MBAFF temporal direct mode closer to the spec.
Fixes at least:
CAMANL2_TOSHIBA_B
CVMANL2_TOSHIBA_B
camp_mot_mbaff0_full
author | michael |
---|---|
date | Sun, 21 Sep 2008 02:39:09 +0000 |
parents | 004f3c69fe7b |
children | d63895a8eabb |
comparison
equal
deleted
inserted
replaced
7897:004f3c69fe7b | 7898:a33287a39a55 |
---|---|
892 pred_motion(h, 0, 4, 0, 0, mx, my); | 892 pred_motion(h, 0, 4, 0, 0, mx, my); |
893 | 893 |
894 return; | 894 return; |
895 } | 895 } |
896 | 896 |
897 static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){ | |
898 int poc0 = h->ref_list[0][i].poc; | |
899 int td = av_clip(poc1 - poc0, -128, 127); | |
900 if(td == 0 || h->ref_list[0][i].long_ref){ | |
901 return 256; | |
902 }else{ | |
903 int tb = av_clip(poc - poc0, -128, 127); | |
904 int tx = (16384 + (FFABS(td) >> 1)) / td; | |
905 return av_clip((tb*tx + 32) >> 6, -1024, 1023); | |
906 } | |
907 } | |
908 | |
897 static inline void direct_dist_scale_factor(H264Context * const h){ | 909 static inline void direct_dist_scale_factor(H264Context * const h){ |
898 MpegEncContext * const s = &h->s; | 910 MpegEncContext * const s = &h->s; |
899 const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; | 911 const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ]; |
900 const int poc1 = h->ref_list[1][0].poc; | 912 const int poc1 = h->ref_list[1][0].poc; |
901 int i; | 913 int i, field; |
914 for(field=0; field<2; field++){ | |
915 const int poc = h->s.current_picture_ptr->field_poc[field]; | |
916 const int poc1 = h->ref_list[1][0].field_poc[field]; | |
917 for(i=0; i < 2*h->ref_count[0]; i++) | |
918 h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16); | |
919 } | |
920 | |
902 for(i=0; i<h->ref_count[0]; i++){ | 921 for(i=0; i<h->ref_count[0]; i++){ |
903 int poc0 = h->ref_list[0][i].poc; | 922 h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); |
904 int td = av_clip(poc1 - poc0, -128, 127); | |
905 if(td == 0 || h->ref_list[0][i].long_ref){ | |
906 h->dist_scale_factor[i] = 256; | |
907 }else{ | |
908 int tb = av_clip(poc - poc0, -128, 127); | |
909 int tx = (16384 + (FFABS(td) >> 1)) / td; | |
910 h->dist_scale_factor[i] = av_clip((tb*tx + 32) >> 6, -1024, 1023); | |
911 } | |
912 } | |
913 if(FRAME_MBAFF){ | |
914 for(i=0; i<h->ref_count[0]; i++){ | |
915 h->dist_scale_factor_field[2*i] = | |
916 h->dist_scale_factor_field[2*i+1] = h->dist_scale_factor[i]; | |
917 } | |
918 } | 923 } |
919 } | 924 } |
920 static inline void direct_ref_list_init(H264Context * const h){ | 925 static inline void direct_ref_list_init(H264Context * const h){ |
921 MpegEncContext * const s = &h->s; | 926 MpegEncContext * const s = &h->s; |
922 Picture * const ref1 = &h->ref_list[1][0]; | 927 Picture * const ref1 = &h->ref_list[1][0]; |
923 Picture * const cur = s->current_picture_ptr; | 928 Picture * const cur = s->current_picture_ptr; |
924 int list, i, j; | 929 int list, i, j, field, rfield; |
925 int sidx= s->picture_structure&1; | 930 int sidx= s->picture_structure&1; |
926 int ref1sidx= ref1->reference&1; | 931 int ref1sidx= ref1->reference&1; |
927 for(list=0; list<2; list++){ | 932 for(list=0; list<2; list++){ |
928 cur->ref_count[sidx][list] = h->ref_count[list]; | 933 cur->ref_count[sidx][list] = h->ref_count[list]; |
929 for(j=0; j<h->ref_count[list]; j++) | 934 for(j=0; j<h->ref_count[list]; j++) |
934 memcpy(cur->ref_poc [0], cur->ref_poc [1], sizeof(cur->ref_poc [0])); | 939 memcpy(cur->ref_poc [0], cur->ref_poc [1], sizeof(cur->ref_poc [0])); |
935 } | 940 } |
936 if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) | 941 if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) |
937 return; | 942 return; |
938 for(list=0; list<2; list++){ | 943 for(list=0; list<2; list++){ |
944 for(field=0; field<2; field++){ | |
945 for(i=0; i<ref1->ref_count[field][list]; i++){ | |
946 for(rfield=0; rfield<2; rfield++){ | |
947 int poc = ref1->ref_poc[field][list][i]; | |
948 if((poc&3) == 3) | |
949 poc= (poc&~3) + rfield + 1; | |
950 | |
951 h->map_col_to_list0_field[field][list][2*i+rfield] = 0; /* bogus; fills in for missing frames */ | |
952 for(j=16; j<16+2*h->ref_count[list]; j++) | |
953 if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ | |
954 h->map_col_to_list0_field[field][list][2*i+rfield] = j-16; | |
955 break; | |
956 } | |
957 } | |
958 } | |
959 } | |
960 | |
939 for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){ | 961 for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){ |
940 int poc = ref1->ref_poc[ref1sidx][list][i]; | 962 int poc = ref1->ref_poc[ref1sidx][list][i]; |
941 if(((poc&3) == 3) != (s->picture_structure == PICT_FRAME)) | 963 if(((poc&3) == 3) != (s->picture_structure == PICT_FRAME)) |
942 poc= (poc&~3) + s->picture_structure; | 964 poc= (poc&~3) + s->picture_structure; |
943 h->map_col_to_list0[list][i] = 0; /* bogus; fills in for missing frames */ | 965 h->map_col_to_list0[list][i] = 0; /* bogus; fills in for missing frames */ |
944 for(j=0; j<h->ref_count[list]; j++) | 966 for(j=0; j<h->ref_count[list]; j++) |
945 if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ | 967 if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ |
946 h->map_col_to_list0[list][i] = j; | 968 h->map_col_to_list0[list][i] = j; |
947 break; | 969 break; |
948 } | 970 } |
949 } | |
950 } | |
951 if(FRAME_MBAFF){ | |
952 for(list=0; list<2; list++){ | |
953 for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){ | |
954 j = h->map_col_to_list0[list][i]; | |
955 h->map_col_to_list0_field[list][2*i] = 2*j; | |
956 h->map_col_to_list0_field[list][2*i+1] = 2*j+1; | |
957 } | |
958 } | 971 } |
959 } | 972 } |
960 } | 973 } |
961 | 974 |
962 static inline void pred_direct_motion(H264Context * const h, int *mb_type){ | 975 static inline void pred_direct_motion(H264Context * const h, int *mb_type){ |
1168 }else{ /* direct temporal mv pred */ | 1181 }else{ /* direct temporal mv pred */ |
1169 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; | 1182 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; |
1170 const int *dist_scale_factor = h->dist_scale_factor; | 1183 const int *dist_scale_factor = h->dist_scale_factor; |
1171 | 1184 |
1172 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ | 1185 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ |
1173 map_col_to_list0[0] = h->map_col_to_list0_field[0]; | 1186 map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; |
1174 map_col_to_list0[1] = h->map_col_to_list0_field[1]; | 1187 map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; |
1175 dist_scale_factor = h->dist_scale_factor_field; | 1188 dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; |
1176 } | 1189 } |
1177 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ | 1190 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
1178 /* FIXME assumes direct_8x8_inference == 1 */ | 1191 /* FIXME assumes direct_8x8_inference == 1 */ |
1179 int y_shift = 2*!IS_INTERLACED(*mb_type); | 1192 int y_shift = 2*!IS_INTERLACED(*mb_type); |
1180 int ref_shift= FRAME_MBAFF ? y_shift : 1; | 1193 int ref_shift= FRAME_MBAFF ? y_shift : 1; |