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 }