Mercurial > libavcodec.hg
comparison h264_direct.c @ 11139:d988e0a6f391 libavcodec
Split spatial and temporal direct MV generation.
A little faster and needed for future optimizations.
This sadly leads to some code duplication (which i hope i can factor out
again after the optimizations on the direcr mv code are done)
author | michael |
---|---|
date | Sat, 13 Feb 2010 03:46:51 +0000 |
parents | 510950eafba5 |
children | 9004c61e3aa0 |
comparison
equal
deleted
inserted
replaced
11138:76b57b8e2a9a | 11139:d988e0a6f391 |
---|---|
138 for(field=0; field<2; field++) | 138 for(field=0; field<2; field++) |
139 fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1); | 139 fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1); |
140 } | 140 } |
141 } | 141 } |
142 | 142 |
143 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){ | 143 static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ |
144 MpegEncContext * const s = &h->s; | 144 MpegEncContext * const s = &h->s; |
145 int b8_stride = h->b8_stride; | 145 int b8_stride = h->b8_stride; |
146 int b4_stride = h->b_stride; | 146 int b4_stride = h->b_stride; |
147 int mb_xy = h->mb_xy; | 147 int mb_xy = h->mb_xy; |
148 int mb_type_col[2]; | 148 int mb_type_col[2]; |
212 l1mv0 += 2*b4_stride; | 212 l1mv0 += 2*b4_stride; |
213 l1mv1 += 2*b4_stride; | 213 l1mv1 += 2*b4_stride; |
214 } | 214 } |
215 } | 215 } |
216 | 216 |
217 if(h->direct_spatial_mv_pred){ | 217 { |
218 int ref[2]; | 218 int ref[2]; |
219 int mv[2]; | 219 int mv[2]; |
220 int list; | 220 int list; |
221 | 221 |
222 /* ref = min(neighbors) */ | 222 /* ref = min(neighbors) */ |
372 } | 372 } |
373 } | 373 } |
374 if(!is_b8x8 && !(n&15)) | 374 if(!is_b8x8 && !(n&15)) |
375 *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; | 375 *mb_type= (*mb_type & ~(MB_TYPE_8x8|MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_P1L0|MB_TYPE_P1L1))|MB_TYPE_16x16|MB_TYPE_DIRECT2; |
376 } | 376 } |
377 }else{ /* direct temporal mv pred */ | 377 } |
378 } | |
379 | |
380 static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ | |
381 MpegEncContext * const s = &h->s; | |
382 int b8_stride = h->b8_stride; | |
383 int b4_stride = h->b_stride; | |
384 int mb_xy = h->mb_xy; | |
385 int mb_type_col[2]; | |
386 const int16_t (*l1mv0)[2], (*l1mv1)[2]; | |
387 const int8_t *l1ref0, *l1ref1; | |
388 const int is_b8x8 = IS_8X8(*mb_type); | |
389 unsigned int sub_mb_type; | |
390 int i8, i4; | |
391 | |
392 assert(h->ref_list[1][0].reference&3); | |
393 | |
394 if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL | |
395 if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL | |
396 mb_xy= s->mb_x + ((s->mb_y&~1) + h->col_parity)*s->mb_stride; | |
397 b8_stride = 0; | |
398 }else{ | |
399 mb_xy += h->col_fieldoff; // non zero for FL -> FL & differ parity | |
400 } | |
401 goto single_col; | |
402 }else{ // AFL/AFR/FR/FL -> AFR/FR | |
403 if(IS_INTERLACED(*mb_type)){ // AFL /FL -> AFR/FR | |
404 mb_xy= s->mb_x + (s->mb_y&~1)*s->mb_stride; | |
405 mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy]; | |
406 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + s->mb_stride]; | |
407 b8_stride *= 3; | |
408 b4_stride *= 6; | |
409 | |
410 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ | |
411 | |
412 if( (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) | |
413 && (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) | |
414 && !is_b8x8){ | |
415 *mb_type |= MB_TYPE_16x8 |MB_TYPE_L0L1|MB_TYPE_DIRECT2; /* B_16x8 */ | |
416 }else{ | |
417 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | |
418 } | |
419 }else{ // AFR/FR -> AFR/FR | |
420 single_col: | |
421 mb_type_col[0] = | |
422 mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy]; | |
423 | |
424 sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ | |
425 if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){ | |
426 *mb_type |= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */ | |
427 }else if(!is_b8x8 && (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16))){ | |
428 *mb_type |= MB_TYPE_L0L1|MB_TYPE_DIRECT2 | (mb_type_col[0] & (MB_TYPE_16x8|MB_TYPE_8x16)); | |
429 }else{ | |
430 if(!h->sps.direct_8x8_inference_flag){ | |
431 /* FIXME save sub mb types from previous frames (or derive from MVs) | |
432 * so we know exactly what block size to use */ | |
433 sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */ | |
434 } | |
435 *mb_type |= MB_TYPE_8x8|MB_TYPE_L0L1; | |
436 } | |
437 } | |
438 } | |
439 | |
440 l1mv0 = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]]; | |
441 l1mv1 = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]]; | |
442 l1ref0 = &h->ref_list[1][0].ref_index [0][h->mb2b8_xy[mb_xy]]; | |
443 l1ref1 = &h->ref_list[1][0].ref_index [1][h->mb2b8_xy[mb_xy]]; | |
444 if(!b8_stride){ | |
445 if(s->mb_y&1){ | |
446 l1ref0 += h->b8_stride; | |
447 l1ref1 += h->b8_stride; | |
448 l1mv0 += 2*b4_stride; | |
449 l1mv1 += 2*b4_stride; | |
450 } | |
451 } | |
452 | |
453 { | |
378 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; | 454 const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]}; |
379 const int *dist_scale_factor = h->dist_scale_factor; | 455 const int *dist_scale_factor = h->dist_scale_factor; |
380 int ref_offset; | 456 int ref_offset; |
381 | 457 |
382 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ | 458 if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){ |
498 } | 574 } |
499 } | 575 } |
500 } | 576 } |
501 } | 577 } |
502 } | 578 } |
579 | |
580 void ff_h264_pred_direct_motion(H264Context * const h, int *mb_type){ | |
581 if(h->direct_spatial_mv_pred){ | |
582 pred_spatial_direct_motion(h, mb_type); | |
583 }else{ | |
584 pred_temp_direct_motion(h, mb_type); | |
585 } | |
586 } |