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);