comparison h264.c @ 1897:4e8ed93524f6 libavcodec

h264 loop filter for progressive I&P frames by (Laurent Aimar <fenrir at via dot ecp dot fr>)
author michael
date Fri, 19 Mar 2004 21:21:17 +0000
parents 5ac49e7a1b8f
children 7d2907127da3
comparison
equal deleted inserted replaced
1896:ef87d53ca87a 1897:4e8ed93524f6
166 /** 166 /**
167 * non zero coeff count cache. 167 * non zero coeff count cache.
168 * is 64 if not available. 168 * is 64 if not available.
169 */ 169 */
170 uint8_t non_zero_count_cache[6*8]; 170 uint8_t non_zero_count_cache[6*8];
171 uint8_t (*non_zero_count)[16]; 171 uint8_t (*non_zero_count)[16+4+4]; /* store all values for deblocking filter */
172 172
173 /** 173 /**
174 * Motion vector cache. 174 * Motion vector cache.
175 */ 175 */
176 int16_t mv_cache[2][5*8][2]; 176 int16_t mv_cache[2][5*8][2];
247 int chroma_weight[2][16][2]; 247 int chroma_weight[2][16][2];
248 int chroma_offset[2][16][2]; 248 int chroma_offset[2][16][2];
249 249
250 //deblock 250 //deblock
251 int disable_deblocking_filter_idc; 251 int disable_deblocking_filter_idc;
252 int slice_alpha_c0_offset_div2; 252 int slice_alpha_c0_offset;
253 int slice_beta_offset_div2; 253 int slice_beta_offset;
254 254
255 int redundant_pic_count; 255 int redundant_pic_count;
256 256
257 int direct_spatial_mv_pred; 257 int direct_spatial_mv_pred;
258 258
469 4 L . .L . . . . 469 4 L . .L . . . .
470 5 L . .. . . . . 470 5 L . .. . . . .
471 */ 471 */
472 //FIXME constraint_intra_pred & partitioning & nnz (lets hope this is just a typo in the spec) 472 //FIXME constraint_intra_pred & partitioning & nnz (lets hope this is just a typo in the spec)
473 if(top_type){ 473 if(top_type){
474 h->non_zero_count_cache[4+8*0]= h->non_zero_count[top_xy][0]; 474 h->non_zero_count_cache[4+8*0]= h->non_zero_count[top_xy][10];
475 h->non_zero_count_cache[5+8*0]= h->non_zero_count[top_xy][1]; 475 h->non_zero_count_cache[5+8*0]= h->non_zero_count[top_xy][11];
476 h->non_zero_count_cache[6+8*0]= h->non_zero_count[top_xy][2]; 476 h->non_zero_count_cache[6+8*0]= h->non_zero_count[top_xy][14];
477 h->non_zero_count_cache[7+8*0]= h->non_zero_count[top_xy][3]; 477 h->non_zero_count_cache[7+8*0]= h->non_zero_count[top_xy][15];
478 478
479 h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][7]; 479 h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][18];
480 h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][8]; 480 h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][19];
481 481
482 h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][10]; 482 h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][22];
483 h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][11]; 483 h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][23];
484 }else{ 484 }else{
485 h->non_zero_count_cache[4+8*0]= 485 h->non_zero_count_cache[4+8*0]=
486 h->non_zero_count_cache[5+8*0]= 486 h->non_zero_count_cache[5+8*0]=
487 h->non_zero_count_cache[6+8*0]= 487 h->non_zero_count_cache[6+8*0]=
488 h->non_zero_count_cache[7+8*0]= 488 h->non_zero_count_cache[7+8*0]=
493 h->non_zero_count_cache[1+8*3]= 493 h->non_zero_count_cache[1+8*3]=
494 h->non_zero_count_cache[2+8*3]= 64; 494 h->non_zero_count_cache[2+8*3]= 64;
495 } 495 }
496 496
497 if(left_type[0]){ 497 if(left_type[0]){
498 h->non_zero_count_cache[3+8*1]= h->non_zero_count[left_xy[0]][6]; 498 h->non_zero_count_cache[3+8*1]= h->non_zero_count[left_xy[0]][5];
499 h->non_zero_count_cache[3+8*2]= h->non_zero_count[left_xy[0]][5]; 499 h->non_zero_count_cache[3+8*2]= h->non_zero_count[left_xy[0]][7];
500 h->non_zero_count_cache[0+8*1]= h->non_zero_count[left_xy[0]][9]; //FIXME left_block 500 h->non_zero_count_cache[0+8*1]= h->non_zero_count[left_xy[0]][17]; //FIXME left_block
501 h->non_zero_count_cache[0+8*4]= h->non_zero_count[left_xy[0]][12]; 501 h->non_zero_count_cache[0+8*4]= h->non_zero_count[left_xy[0]][21];
502 }else{ 502 }else{
503 h->non_zero_count_cache[3+8*1]= 503 h->non_zero_count_cache[3+8*1]=
504 h->non_zero_count_cache[3+8*2]= 504 h->non_zero_count_cache[3+8*2]=
505 h->non_zero_count_cache[0+8*1]= 505 h->non_zero_count_cache[0+8*1]=
506 h->non_zero_count_cache[0+8*4]= 64; 506 h->non_zero_count_cache[0+8*4]= 64;
507 } 507 }
508 508
509 if(left_type[1]){ 509 if(left_type[1]){
510 h->non_zero_count_cache[3+8*3]= h->non_zero_count[left_xy[1]][4]; 510 h->non_zero_count_cache[3+8*3]= h->non_zero_count[left_xy[1]][13];
511 h->non_zero_count_cache[3+8*4]= h->non_zero_count[left_xy[1]][3]; 511 h->non_zero_count_cache[3+8*4]= h->non_zero_count[left_xy[1]][15];
512 h->non_zero_count_cache[0+8*2]= h->non_zero_count[left_xy[1]][8]; 512 h->non_zero_count_cache[0+8*2]= h->non_zero_count[left_xy[1]][19];
513 h->non_zero_count_cache[0+8*5]= h->non_zero_count[left_xy[1]][11]; 513 h->non_zero_count_cache[0+8*5]= h->non_zero_count[left_xy[1]][23];
514 }else{ 514 }else{
515 h->non_zero_count_cache[3+8*3]= 515 h->non_zero_count_cache[3+8*3]=
516 h->non_zero_count_cache[3+8*4]= 516 h->non_zero_count_cache[3+8*4]=
517 h->non_zero_count_cache[0+8*2]= 517 h->non_zero_count_cache[0+8*2]=
518 h->non_zero_count_cache[0+8*5]= 64; 518 h->non_zero_count_cache[0+8*5]= 64;
709 } 709 }
710 710
711 static inline void write_back_non_zero_count(H264Context *h){ 711 static inline void write_back_non_zero_count(H264Context *h){
712 MpegEncContext * const s = &h->s; 712 MpegEncContext * const s = &h->s;
713 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride; 713 const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;
714 714 int n;
715 h->non_zero_count[mb_xy][0]= h->non_zero_count_cache[4+8*4]; 715
716 h->non_zero_count[mb_xy][1]= h->non_zero_count_cache[5+8*4]; 716 for( n = 0; n < 16+4+4; n++ )
717 h->non_zero_count[mb_xy][2]= h->non_zero_count_cache[6+8*4]; 717 h->non_zero_count[mb_xy][n] = h->non_zero_count_cache[scan8[n]];
718 h->non_zero_count[mb_xy][3]= h->non_zero_count_cache[7+8*4];
719 h->non_zero_count[mb_xy][4]= h->non_zero_count_cache[7+8*3];
720 h->non_zero_count[mb_xy][5]= h->non_zero_count_cache[7+8*2];
721 h->non_zero_count[mb_xy][6]= h->non_zero_count_cache[7+8*1];
722
723 h->non_zero_count[mb_xy][7]= h->non_zero_count_cache[1+8*2];
724 h->non_zero_count[mb_xy][8]= h->non_zero_count_cache[2+8*2];
725 h->non_zero_count[mb_xy][9]= h->non_zero_count_cache[2+8*1];
726
727 h->non_zero_count[mb_xy][10]=h->non_zero_count_cache[1+8*5];
728 h->non_zero_count[mb_xy][11]=h->non_zero_count_cache[2+8*5];
729 h->non_zero_count[mb_xy][12]=h->non_zero_count_cache[2+8*4];
730 } 718 }
731 719
732 /** 720 /**
733 * gets the predicted number of non zero coefficients. 721 * gets the predicted number of non zero coefficients.
734 * @param n block index 722 * @param n block index
2122 MpegEncContext * const s = &h->s; 2110 MpegEncContext * const s = &h->s;
2123 const int big_mb_num= s->mb_stride * (s->mb_height+1); 2111 const int big_mb_num= s->mb_stride * (s->mb_height+1);
2124 int x,y; 2112 int x,y;
2125 2113
2126 CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t)) 2114 CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t))
2127 CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t)) 2115 CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * (16+4+4) * sizeof(uint8_t))
2128 CHECKED_ALLOCZ(h->slice_table_base , big_mb_num * sizeof(uint8_t)) 2116 CHECKED_ALLOCZ(h->slice_table_base , big_mb_num * sizeof(uint8_t))
2129 2117
2130 memset(h->slice_table_base, -1, big_mb_num * sizeof(uint8_t)); 2118 memset(h->slice_table_base, -1, big_mb_num * sizeof(uint8_t));
2131 h->slice_table= h->slice_table_base + s->mb_stride + 1; 2119 h->slice_table= h->slice_table_base + s->mb_stride + 1;
2132 2120
2992 } 2980 }
2993 2981
2994 if( h->pps.deblocking_filter_parameters_present ) { 2982 if( h->pps.deblocking_filter_parameters_present ) {
2995 h->disable_deblocking_filter_idc= get_ue_golomb(&s->gb); 2983 h->disable_deblocking_filter_idc= get_ue_golomb(&s->gb);
2996 if( h->disable_deblocking_filter_idc != 1 ) { 2984 if( h->disable_deblocking_filter_idc != 1 ) {
2997 h->slice_alpha_c0_offset_div2= get_se_golomb(&s->gb); 2985 h->slice_alpha_c0_offset = get_se_golomb(&s->gb) << 1;
2998 h->slice_beta_offset_div2= get_se_golomb(&s->gb); 2986 h->slice_beta_offset = get_se_golomb(&s->gb) << 1;
2999 } 2987 } else {
3000 }else 2988 h->slice_alpha_c0_offset = 0;
3001 h->disable_deblocking_filter_idc= 0; 2989 h->slice_beta_offset = 0;
2990 }
2991 } else {
2992 h->disable_deblocking_filter_idc = 0;
2993 h->slice_alpha_c0_offset = 0;
2994 h->slice_beta_offset = 0;
2995 }
3002 2996
3003 #if 0 //FMO 2997 #if 0 //FMO
3004 if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5) 2998 if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5)
3005 slice_group_change_cycle= get_bits(&s->gb, ?); 2999 slice_group_change_cycle= get_bits(&s->gb, ?);
3006 #endif 3000 #endif
3121 3115
3122 #if 1 3116 #if 1
3123 if(ABS(level[i]) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++; 3117 if(ABS(level[i]) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++;
3124 #else 3118 #else
3125 if((2+level_code)>>1) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++; 3119 if((2+level_code)>>1) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++;
3126 ? == prefix > 2 or sth 3120 /* ? == prefix > 2 or sth */
3127 #endif 3121 #endif
3128 tprintf("level: %d suffix_length:%d\n", level[i], suffix_length); 3122 tprintf("level: %d suffix_length:%d\n", level[i], suffix_length);
3129 } 3123 }
3130 3124
3131 if(total_coeff == max_coeff) 3125 if(total_coeff == max_coeff)
3205 int mx, my; 3199 int mx, my;
3206 /* skip mb */ 3200 /* skip mb */
3207 //FIXME b frame 3201 //FIXME b frame
3208 mb_type= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0; 3202 mb_type= MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P1L0;
3209 3203
3210 memset(h->non_zero_count[mb_xy], 0, 16); 3204 memset(h->non_zero_count[mb_xy], 0, 16+4+4);
3211 memset(h->non_zero_count_cache + 8, 0, 8*5); //FIXME ugly, remove pfui 3205 memset(h->non_zero_count_cache + 8, 0, 8*5); //FIXME ugly, remove pfui
3212 3206
3213 if(h->sps.mb_aff && s->mb_skip_run==0 && (s->mb_y&1)==0){ 3207 if(h->sps.mb_aff && s->mb_skip_run==0 && (s->mb_y&1)==0){
3214 h->mb_field_decoding_flag= get_bits1(&s->gb); 3208 h->mb_field_decoding_flag= get_bits1(&s->gb);
3215 } 3209 }
3222 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); 3216 fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
3223 fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4); 3217 fill_rectangle( h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4);
3224 write_back_motion(h, mb_type); 3218 write_back_motion(h, mb_type);
3225 3219
3226 s->current_picture.mb_type[mb_xy]= mb_type; //FIXME SKIP type 3220 s->current_picture.mb_type[mb_xy]= mb_type; //FIXME SKIP type
3221 s->current_picture.qscale_table[mb_xy]= s->qscale;
3227 h->slice_table[ mb_xy ]= h->slice_num; 3222 h->slice_table[ mb_xy ]= h->slice_num;
3228 3223
3229 h->prev_mb_skiped= 1; 3224 h->prev_mb_skiped= 1;
3230 return 0; 3225 return 0;
3231 } 3226 }
3302 } 3297 }
3303 } 3298 }
3304 3299
3305 skip_bits(&s->gb, 384); //FIXME check /fix the bitstream readers 3300 skip_bits(&s->gb, 384); //FIXME check /fix the bitstream readers
3306 3301
3307 memset(h->non_zero_count[mb_xy], 16, 16); 3302 memset(h->non_zero_count[mb_xy], 16, 16+4+4);
3303 s->current_picture.qscale_table[mb_xy]= s->qscale;
3308 3304
3309 return 0; 3305 return 0;
3310 } 3306 }
3311 3307
3312 fill_caches(h, mb_type); 3308 fill_caches(h, mb_type);
3608 nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0; 3604 nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;
3609 } 3605 }
3610 }else{ 3606 }else{
3611 memset(&h->non_zero_count_cache[8], 0, 8*5); 3607 memset(&h->non_zero_count_cache[8], 0, 8*5);
3612 } 3608 }
3609 s->current_picture.qscale_table[mb_xy]= s->qscale;
3613 write_back_non_zero_count(h); 3610 write_back_non_zero_count(h);
3614 3611
3615 return 0; 3612 return 0;
3613 }
3614
3615 static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) {
3616 int i, d;
3617 const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 );
3618 const int alpha = alpha_table[index_a];
3619 const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )];
3620
3621 for( i = 0; i < 4; i++ ) {
3622 if( bS[i] == 0 ) {
3623 pix += 4 * stride;
3624 continue;
3625 }
3626
3627 /* 4px edge length */
3628 for( d = 0; d < 4; d++ ) {
3629 const uint8_t p0 = pix[-1];
3630 const uint8_t p1 = pix[-2];
3631 const uint8_t p2 = pix[-3];
3632
3633 const uint8_t q0 = pix[0];
3634 const uint8_t q1 = pix[1];
3635 const uint8_t q2 = pix[2];
3636
3637 if( abs( p0 - q0 ) >= alpha ||
3638 abs( p1 - p0 ) >= beta ||
3639 abs( q1 - q0 ) >= beta ) {
3640 pix += stride;
3641 continue;
3642 }
3643
3644 if( bS[i] < 4 ) {
3645 const int tc0 = tc0_table[index_a][bS[i] - 1];
3646 int tc = tc0;
3647 int i_delta;
3648
3649 if( abs( p2 - p0 ) < beta ) {
3650 pix[-2] = p1 + clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 );
3651 tc++;
3652 }
3653 if( abs( q2 - q0 ) < beta ) {
3654 pix[1] = q1 + clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 );
3655 tc++;
3656 }
3657
3658 i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
3659 pix[-1] = clip( p0 + i_delta, 0, 255 ); /* p0' */
3660 pix[0] = clip( q0 - i_delta, 0, 255 ); /* q0' */
3661 }
3662 else
3663 {
3664 const int c = abs( p0 - q0 ) < (( alpha >> 2 ) + 2 );
3665
3666 if( abs( p2 - p0 ) < beta && c )
3667 {
3668 const uint8_t p3 = pix[-4];
3669 /* p0', p1', p2' */
3670 pix[-1] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
3671 pix[-2] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
3672 pix[-3] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
3673 } else {
3674 /* p0' */
3675 pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
3676 }
3677 if( abs( q2 - q0 ) < beta && c )
3678 {
3679 const uint8_t q3 = pix[3];
3680 /* q0', q1', q2' */
3681 pix[0] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
3682 pix[1] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
3683 pix[2] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
3684 } else {
3685 /* q0' */
3686 pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
3687 }
3688 }
3689 pix += stride;
3690 }
3691 }
3692 }
3693 static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) {
3694 int i, d;
3695 const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 );
3696 const int alpha = alpha_table[index_a];
3697 const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )];
3698
3699 for( i = 0; i < 4; i++ ) {
3700 if( bS[i] == 0 ) {
3701 pix += 2 * stride;
3702 continue;
3703 }
3704
3705 /* 2px edge length (because we use same bS than the one for luma) */
3706 for( d = 0; d < 2; d++ )
3707 {
3708 const uint8_t p0 = pix[-1];
3709 const uint8_t p1 = pix[-2];
3710 const uint8_t q0 = pix[0];
3711 const uint8_t q1 = pix[1];
3712
3713 if( abs( p0 - q0 ) >= alpha ||
3714 abs( p1 - p0 ) >= beta ||
3715 abs( q1 - q0 ) >= beta ) {
3716 pix += stride;
3717 continue;
3718 }
3719
3720 if( bS[i] < 4 ) {
3721 const int tc = tc0_table[index_a][bS[i] - 1] + 1;
3722 const int i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
3723
3724 pix[-1] = clip( p0 + i_delta, 0, 255 ); /* p0' */
3725 pix[0] = clip( q0 - i_delta, 0, 255 ); /* q0' */
3726 } else {
3727 pix[-1] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */
3728 pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */
3729 }
3730 pix += stride;
3731 }
3732 }
3733 }
3734
3735 static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) {
3736 int i, d;
3737 const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 );
3738 const int alpha = alpha_table[index_a];
3739 const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )];
3740 const int pix_next = stride;
3741
3742 for( i = 0; i < 4; i++ ) {
3743 if( bS[i] == 0 ) {
3744 pix += 4;
3745 continue;
3746 }
3747
3748 /* 4px edge length */
3749 for( d = 0; d < 4; d++ ) {
3750 const uint8_t p0 = pix[-1*pix_next];
3751 const uint8_t p1 = pix[-2*pix_next];
3752 const uint8_t p2 = pix[-3*pix_next];
3753 const uint8_t q0 = pix[0];
3754 const uint8_t q1 = pix[1*pix_next];
3755 const uint8_t q2 = pix[2*pix_next];
3756
3757 if( abs( p0 - q0 ) >= alpha ||
3758 abs( p1 - p0 ) >= beta ||
3759 abs( q1 - q0 ) >= beta ) {
3760 pix++;
3761 continue;
3762 }
3763
3764 if( bS[i] < 4 ) {
3765 const int tc0 = tc0_table[index_a][bS[i] - 1];
3766 int tc = tc0;
3767 int i_delta;
3768
3769 if( abs( p2 - p0 ) < beta ) {
3770 pix[-2*pix_next] = p1 + clip( ( p2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( p1 << 1 ) ) >> 1, -tc0, tc0 );
3771 tc++;
3772 }
3773 if( abs( q2 - q0 ) < beta ) {
3774 pix[pix_next] = q1 + clip( ( q2 + ( ( p0 + q0 + 1 ) >> 1 ) - ( q1 << 1 ) ) >> 1, -tc0, tc0 );
3775 tc++;
3776 }
3777
3778 i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
3779 pix[-pix_next] = clip( p0 + i_delta, 0, 255 ); /* p0' */
3780 pix[0] = clip( q0 - i_delta, 0, 255 ); /* q0' */
3781 }
3782 else
3783 {
3784 const uint8_t p3 = pix[-4*pix_next];
3785 const uint8_t q3 = pix[ 3*pix_next];
3786 const int c = abs( p0 - q0 ) < (( alpha >> 2 ) + 2 );
3787
3788 if( abs( p2 - p0 ) < beta && c ) {
3789 /* p0', p1', p2' */
3790 pix[-1*pix_next] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3;
3791 pix[-2*pix_next] = ( p2 + p1 + p0 + q0 + 2 ) >> 2;
3792 pix[-3*pix_next] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3;
3793 } else {
3794 /* p0' */
3795 pix[-1*pix_next] = ( 2*p1 + p0 + q1 + 2 ) >> 2;
3796 }
3797 if( abs( q2 - q0 ) < beta && c ) {
3798 /* q0', q1', q2' */
3799 pix[0*pix_next] = ( p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 ) >> 3;
3800 pix[1*pix_next] = ( p0 + q0 + q1 + q2 + 2 ) >> 2;
3801 pix[2*pix_next] = ( 2*q3 + 3*q2 + q1 + q0 + p0 + 4 ) >> 3;
3802 } else {
3803 /* q0' */
3804 pix[0*pix_next] = ( 2*q1 + q0 + p1 + 2 ) >> 2;
3805 }
3806 }
3807 pix++;
3808 }
3809 }
3810 }
3811
3812 static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) {
3813 int i, d;
3814 const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 );
3815 const int alpha = alpha_table[index_a];
3816 const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )];
3817 const int pix_next = stride;
3818
3819 for( i = 0; i < 4; i++ )
3820 {
3821 if( bS[i] == 0 ) {
3822 pix += 2;
3823 continue;
3824 }
3825
3826 /* 2px edge length (see deblocking_filter_edgecv) */
3827 for( d = 0; d < 2; d++ ) {
3828 const uint8_t p0 = pix[-1*pix_next];
3829 const uint8_t p1 = pix[-2*pix_next];
3830 const uint8_t q0 = pix[0];
3831 const uint8_t q1 = pix[1*pix_next];
3832
3833 if( abs( p0 - q0 ) >= alpha ||
3834 abs( p1 - p0 ) >= beta ||
3835 abs( q1 - q0 ) >= beta ) {
3836 pix++;
3837 continue;
3838 }
3839
3840 if( bS[i] < 4 ) {
3841 int tc = tc0_table[index_a][bS[i] - 1] + 1;
3842 int i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
3843
3844 pix[-pix_next] = clip( p0 + i_delta, 0, 255 ); /* p0' */
3845 pix[0] = clip( q0 - i_delta, 0, 255 ); /* q0' */
3846 }
3847 else
3848 {
3849 pix[-pix_next] = ( 2*p1 + p0 + q1 + 2 ) >> 2; /* p0' */
3850 pix[0] = ( 2*q1 + q0 + p1 + 2 ) >> 2; /* q0' */
3851 }
3852 pix++;
3853 }
3854 }
3855 }
3856
3857 static void filter_mb( H264Context *h, int mb_x, int mb_y ) {
3858 MpegEncContext * const s = &h->s;
3859 const int mb_xy= mb_x + mb_y*s->mb_stride;
3860 uint8_t *img_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16;
3861 uint8_t *img_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
3862 uint8_t *img_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
3863 int linesize, uvlinesize;
3864 int dir;
3865 #if 0
3866 /* FIXME what's that ? */
3867 if( !s->decode )
3868 return;
3869 #endif
3870
3871 /* FIXME Implement deblocking filter for field MB */
3872 if( h->sps.mb_aff ) {
3873 return;
3874 }
3875 linesize = s->linesize;
3876 uvlinesize = s->uvlinesize;
3877
3878 /* dir : 0 -> vertical edge, 1 -> horizontal edge */
3879 for( dir = 0; dir < 2; dir++ )
3880 {
3881 int start = 0;
3882 int edge;
3883
3884 /* test picture boundary */
3885 if( ( dir == 0 && mb_x == 0 ) || ( dir == 1 && mb_y == 0 ) ) {
3886 start = 1;
3887 }
3888 /* FIXME test slice boundary */
3889 if( h->disable_deblocking_filter_idc == 2 ) {
3890 }
3891
3892 /* Calculate bS */
3893 for( edge = start; edge < 4; edge++ ) {
3894 /* mbn_xy: neighbour macroblock (how that works for field ?) */
3895 int mbn_xy = edge > 0 ? mb_xy : ( dir == 0 ? mb_xy -1 : mb_xy - s->mb_stride );
3896 int bS[4];
3897 int qp;
3898
3899 if( IS_INTRA( s->current_picture.mb_type[mb_xy] ) ||
3900 IS_INTRA( s->current_picture.mb_type[mbn_xy] ) ) {
3901 bS[0] = bS[1] = bS[2] = bS[3] = ( edge == 0 ? 4 : 3 );
3902 } else {
3903 int i;
3904 for( i = 0; i < 4; i++ ) {
3905 static const uint8_t block_idx_xy[4][4] = {
3906 { 0, 2, 8, 10}, { 1, 3, 9, 11},
3907 { 4, 6, 12, 14}, { 5, 7, 13, 15}
3908 };
3909
3910 int x = dir == 0 ? edge : i;
3911 int y = dir == 0 ? i : edge;
3912 int xn = (x - (dir == 0 ? 1 : 0 ))&0x03;
3913 int yn = (y - (dir == 0 ? 0 : 1 ))&0x03;
3914
3915 if( h->non_zero_count[mb_xy][block_idx_xy[x][y]] != 0 ||
3916 h->non_zero_count[mbn_xy][block_idx_xy[xn][yn]] != 0 ) {
3917 bS[i] = 2;
3918 }
3919 else if( h->slice_type == P_TYPE ) {
3920 const int b8_xy = h->mb2b8_xy[mb_xy]+(y/2)*h->b8_stride+(x/2);
3921 const int b8n_xy= h->mb2b8_xy[mbn_xy]+(yn/2)*h->b8_stride+(xn/2);
3922 const int b_xy = h->mb2b_xy[mb_xy]+y*h->b_stride+x;
3923 const int bn_xy = h->mb2b_xy[mbn_xy]+yn*h->b_stride+xn;
3924 if( s->current_picture.ref_index[0][b8_xy] != s->current_picture.ref_index[0][b8n_xy] ||
3925 abs( s->current_picture.motion_val[0][b_xy][0] - s->current_picture.motion_val[0][bn_xy][0] ) >= 4 ||
3926 abs( s->current_picture.motion_val[0][b_xy][1] - s->current_picture.motion_val[0][bn_xy][1] ) >= 4 )
3927 bS[i] = 1;
3928 else
3929 bS[i] = 0;
3930 }
3931 else {
3932 /* FIXME Add support for B frame */
3933 return;
3934 }
3935 }
3936 }
3937
3938 /* Filter edge */
3939 qp = ( s->current_picture.qscale_table[mb_xy] + s->current_picture.qscale_table[mbn_xy] + 1 ) >> 1;
3940 if( dir == 0 ) {
3941 filter_mb_edgev( h, &img_y[4*edge], linesize, bS, qp );
3942 if( edge%2 == 0 ) {
3943 int chroma_qp = ( get_chroma_qp( h, s->current_picture.qscale_table[mb_xy] ) +
3944 get_chroma_qp( h, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;
3945 filter_mb_edgecv( h, &img_cb[2*edge], uvlinesize, bS, chroma_qp );
3946 filter_mb_edgecv( h, &img_cr[2*edge], uvlinesize, bS, chroma_qp );
3947 }
3948 } else {
3949 filter_mb_edgeh( h, &img_y[4*edge*linesize], linesize, bS, qp );
3950 if( edge%2 == 0 ) {
3951 int chroma_qp = ( get_chroma_qp( h, s->current_picture.qscale_table[mb_xy] ) +
3952 get_chroma_qp( h, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;
3953 filter_mb_edgech( h, &img_cb[2*edge*uvlinesize], uvlinesize, bS, chroma_qp );
3954 filter_mb_edgech( h, &img_cr[2*edge*uvlinesize], uvlinesize, bS, chroma_qp );
3955 }
3956 }
3957 }
3958 }
3616 } 3959 }
3617 3960
3618 static int decode_slice(H264Context *h){ 3961 static int decode_slice(H264Context *h){
3619 MpegEncContext * const s = &h->s; 3962 MpegEncContext * const s = &h->s;
3620 const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F; 3963 const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
3717 s->mb_x=0; 4060 s->mb_x=0;
3718 ff_draw_horiz_band(s, 16*s->mb_y, 16); 4061 ff_draw_horiz_band(s, 16*s->mb_y, 16);
3719 } 4062 }
3720 #endif 4063 #endif
3721 return -1; //not reached 4064 return -1; //not reached
4065 }
4066
4067 static void filter_frame(H264Context *h) {
4068 int mb_x = 0;
4069 int mb_y = 0;
4070
4071 for( mb_y = 0; mb_y < h->s.mb_height; mb_y++ ) {
4072 for( mb_x = 0; mb_x < h->s.mb_width; mb_x++ ) {
4073 filter_mb( h, mb_x, mb_y );
4074 }
4075 }
3722 } 4076 }
3723 4077
3724 static inline int decode_vui_parameters(H264Context *h, SPS *sps){ 4078 static inline int decode_vui_parameters(H264Context *h, SPS *sps){
3725 MpegEncContext * const s = &h->s; 4079 MpegEncContext * const s = &h->s;
3726 int aspect_ratio_info_present_flag, aspect_ratio_idc; 4080 int aspect_ratio_info_present_flag, aspect_ratio_idc;
4098 execute_ref_pic_marking(h, h->mmco, h->mmco_index); 4452 execute_ref_pic_marking(h, h->mmco, h->mmco_index);
4099 else 4453 else
4100 assert(h->mmco_index==0); 4454 assert(h->mmco_index==0);
4101 4455
4102 ff_er_frame_end(s); 4456 ff_er_frame_end(s);
4457
4458 if( h->disable_deblocking_filter_idc != 1 ) {
4459 filter_frame( h );
4460 }
4461
4103 MPV_frame_end(s); 4462 MPV_frame_end(s);
4104 4463
4105 return buf_index; 4464 return buf_index;
4106 } 4465 }
4107 4466