Mercurial > libavcodec.hg
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 |