Mercurial > libavcodec.hg
comparison h264.c @ 7906:5be944626072 libavcodec
Another try to fix temporal direct mode references.
Fixes at least
CAPAMA3_Sand_F.264
CVMAPAQP3_Sony_E.jsv
author | michael |
---|---|
date | Mon, 22 Sep 2008 20:43:35 +0000 |
parents | 8b8be8f2b647 |
children | 8eb69709a934 |
comparison
equal
deleted
inserted
replaced
7905:ae410599f388 | 7906:5be944626072 |
---|---|
920 | 920 |
921 for(i=0; i<h->ref_count[0]; i++){ | 921 for(i=0; i<h->ref_count[0]; i++){ |
922 h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); | 922 h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i); |
923 } | 923 } |
924 } | 924 } |
925 | |
926 static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){ | |
927 MpegEncContext * const s = &h->s; | |
928 Picture * const ref1 = &h->ref_list[1][0]; | |
929 int j, old_ref, rfield; | |
930 int start= mbafi ? 16 : 0; | |
931 int end = mbafi ? 16+2*h->ref_count[list] : h->ref_count[list]; | |
932 int interl= mbafi || s->picture_structure != PICT_FRAME; | |
933 | |
934 /* bogus; fills in for missing frames */ | |
935 memset(map[list], 0, sizeof(map[list])); | |
936 | |
937 for(rfield=0; rfield<2; rfield++){ | |
938 for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){ | |
939 int poc = ref1->ref_poc[colfield][list][old_ref]; | |
940 | |
941 if (!interl) | |
942 poc |= 3; | |
943 else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed | |
944 poc= (poc&~3) + rfield + 1; | |
945 | |
946 for(j=start; j<end; j++){ | |
947 if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ | |
948 int cur_ref= mbafi ? (j-16)^field : j; | |
949 map[list][2*old_ref + (rfield^field) + 16] = cur_ref; | |
950 if(rfield == field) | |
951 map[list][old_ref] = cur_ref; | |
952 break; | |
953 } | |
954 } | |
955 } | |
956 } | |
957 } | |
958 | |
925 static inline void direct_ref_list_init(H264Context * const h){ | 959 static inline void direct_ref_list_init(H264Context * const h){ |
926 MpegEncContext * const s = &h->s; | 960 MpegEncContext * const s = &h->s; |
927 Picture * const ref1 = &h->ref_list[1][0]; | 961 Picture * const ref1 = &h->ref_list[1][0]; |
928 Picture * const cur = s->current_picture_ptr; | 962 Picture * const cur = s->current_picture_ptr; |
929 int list, i, j, field, rfield; | 963 int list, j, field, rfield; |
930 int sidx= s->picture_structure&1; | 964 int sidx= (s->picture_structure&1)^1; |
931 int ref1sidx= ref1->reference&1; | 965 int ref1sidx= (ref1->reference&1)^1; |
932 for(list=0; list<2; list++){ | 966 for(list=0; list<2; list++){ |
933 cur->ref_count[sidx][list] = h->ref_count[list]; | 967 cur->ref_count[sidx][list] = h->ref_count[list]; |
934 for(j=0; j<h->ref_count[list]; j++) | 968 for(j=0; j<h->ref_count[list]; j++) |
935 cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3); | 969 cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3); |
936 } | 970 } |
937 if(s->picture_structure == PICT_FRAME){ | 971 if(s->picture_structure == PICT_FRAME){ |
938 memcpy(cur->ref_count[0], cur->ref_count[1], sizeof(cur->ref_count[0])); | 972 memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0])); |
939 memcpy(cur->ref_poc [0], cur->ref_poc [1], sizeof(cur->ref_poc [0])); | 973 memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0])); |
940 } | 974 } |
941 cur->mbaff= FRAME_MBAFF; | 975 cur->mbaff= FRAME_MBAFF; |
942 if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) | 976 if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred) |
943 return; | 977 return; |
944 for(list=0; list<2; list++){ | 978 for(list=0; list<2; list++){ |
945 for(field=0; field<2; field++){ | 979 fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0); |
946 for(i=0; i<ref1->ref_count[field][list]; i++){ | 980 for(field=0; field<2; field++) |
947 for(rfield=0; rfield<2; rfield++){ | 981 fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1); |
948 int poc = ref1->ref_poc[field][list][i]; | |
949 if((poc&3) == 3) | |
950 poc= (poc&~3) + rfield + 1; | |
951 | |
952 h->map_col_to_list0_field[field][list][2*i+rfield] = 0; /* bogus; fills in for missing frames */ | |
953 for(j=16; j<16+2*h->ref_count[list]; j++) | |
954 if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ | |
955 h->map_col_to_list0_field[field][list][2*i+rfield] = j-16; | |
956 break; | |
957 } | |
958 } | |
959 } | |
960 } | |
961 | |
962 for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){ | |
963 int poc = ref1->ref_poc[ref1sidx][list][i]; | |
964 if(((poc&3) == 3) != (s->picture_structure == PICT_FRAME)) | |
965 poc= (poc&~3) + s->picture_structure; | |
966 h->map_col_to_list0[list][i] = 0; /* bogus; fills in for missing frames */ | |
967 for(j=0; j<h->ref_count[list]; j++) | |
968 if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){ | |
969 h->map_col_to_list0[list][i] = j; | |
970 break; | |
971 } | |
972 } | |
973 } | 982 } |
974 } | 983 } |
975 | 984 |
976 static inline void pred_direct_motion(H264Context * const h, int *mb_type){ | 985 static inline void pred_direct_motion(H264Context * const h, int *mb_type){ |
977 MpegEncContext * const s = &h->s; | 986 MpegEncContext * const s = &h->s; |
1178 } | 1187 } |
1179 } | 1188 } |
1180 }else{ /* direct temporal mv pred */ | 1189 }else{ /* direct temporal mv pred */ |
1181 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; | 1190 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; |
1182 const int *dist_scale_factor = h->dist_scale_factor; | 1191 const int *dist_scale_factor = h->dist_scale_factor; |
1183 int ref_shift= 1; | 1192 int ref_offset= 0; |
1184 | 1193 |
1185 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ | 1194 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ |
1186 map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; | 1195 map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0]; |
1187 map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; | 1196 map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1]; |
1188 dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; | 1197 dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1]; |
1189 ref_shift--; | |
1190 } | 1198 } |
1191 if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) | 1199 if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) |
1192 ref_shift++; | 1200 ref_offset += 16; |
1193 | 1201 |
1194 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ | 1202 if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){ |
1195 /* FIXME assumes direct_8x8_inference == 1 */ | 1203 /* FIXME assumes direct_8x8_inference == 1 */ |
1196 int y_shift = 2*!IS_INTERLACED(*mb_type); | 1204 int y_shift = 2*!IS_INTERLACED(*mb_type); |
1197 | 1205 |
1213 continue; | 1221 continue; |
1214 } | 1222 } |
1215 | 1223 |
1216 ref0 = l1ref0[x8 + y8*b8_stride]; | 1224 ref0 = l1ref0[x8 + y8*b8_stride]; |
1217 if(ref0 >= 0) | 1225 if(ref0 >= 0) |
1218 ref0 = map_col_to_list0[0][ref0*2>>ref_shift]; | 1226 ref0 = map_col_to_list0[0][ref0 + ref_offset]; |
1219 else{ | 1227 else{ |
1220 ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride]*2>>ref_shift]; | 1228 ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; |
1221 l1mv= l1mv1; | 1229 l1mv= l1mv1; |
1222 } | 1230 } |
1223 scale = dist_scale_factor[ref0]; | 1231 scale = dist_scale_factor[ref0]; |
1224 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); | 1232 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); |
1225 | 1233 |
1242 | 1250 |
1243 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); | 1251 fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); |
1244 if(IS_INTRA(mb_type_col[0])){ | 1252 if(IS_INTRA(mb_type_col[0])){ |
1245 ref=mv0=mv1=0; | 1253 ref=mv0=mv1=0; |
1246 }else{ | 1254 }else{ |
1247 const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][(l1ref0[0]*2)>>ref_shift] | 1255 const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset] |
1248 : map_col_to_list0[1][(l1ref1[0]*2)>>ref_shift]; | 1256 : map_col_to_list0[1][l1ref1[0] + ref_offset]; |
1249 const int scale = dist_scale_factor[ref0]; | 1257 const int scale = dist_scale_factor[ref0]; |
1250 const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; | 1258 const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0]; |
1251 int mv_l0[2]; | 1259 int mv_l0[2]; |
1252 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; | 1260 mv_l0[0] = (scale * mv_col[0] + 128) >> 8; |
1253 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; | 1261 mv_l0[1] = (scale * mv_col[1] + 128) >> 8; |
1274 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); | 1282 fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); |
1275 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); | 1283 fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); |
1276 continue; | 1284 continue; |
1277 } | 1285 } |
1278 | 1286 |
1279 ref0 = (l1ref0[x8 + y8*b8_stride]*2)>>ref_shift; | 1287 ref0 = l1ref0[x8 + y8*b8_stride] + ref_offset; |
1280 if(ref0 >= 0) | 1288 if(ref0 >= 0) |
1281 ref0 = map_col_to_list0[0][ref0]; | 1289 ref0 = map_col_to_list0[0][ref0]; |
1282 else{ | 1290 else{ |
1283 ref0 = map_col_to_list0[1][(l1ref1[x8 + y8*b8_stride]*2)>>ref_shift]; | 1291 ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset]; |
1284 l1mv= l1mv1; | 1292 l1mv= l1mv1; |
1285 } | 1293 } |
1286 scale = dist_scale_factor[ref0]; | 1294 scale = dist_scale_factor[ref0]; |
1287 | 1295 |
1288 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); | 1296 fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); |