@ -6241,126 +6241,9 @@ static void filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y,
}
}
}
}
static void filter_mb ( H264Context * h , int mb_x , int mb_y , uint8_t * img_y , uint8_t * img_cb , uint8_t * img_cr , unsigned int linesize , unsigned int uvlinesize ) {
MpegEncContext * const s = & h - > s ;
const int mb_xy = mb_x + mb_y * s - > mb_stride ;
const int mb_type = s - > current_picture . mb_type [ mb_xy ] ;
const int mvy_limit = IS_INTERLACED ( mb_type ) ? 2 : 4 ;
int first_vertical_edge_done = 0 ;
int dir ;
//for sufficiently low qp, filtering wouldn't do anything
static void av_always_inline filter_mb_dir ( H264Context * h , int mb_x , int mb_y , uint8_t * img_y , uint8_t * img_cb , uint8_t * img_cr , unsigned int linesize , unsigned int uvlinesize , int mb_xy , int mb_type , int mvy_limit , int first_vertical_edge_done , int dir ) {
//this is a conservative estimate: could also check beta_offset and more accurate chroma_qp
MpegEncContext * const s = & h - > s ;
if ( ! FRAME_MBAFF ) {
int qp_thresh = 15 - h - > slice_alpha_c0_offset - FFMAX3 ( 0 , h - > pps . chroma_qp_index_offset [ 0 ] , h - > pps . chroma_qp_index_offset [ 1 ] ) ;
int qp = s - > current_picture . qscale_table [ mb_xy ] ;
if ( qp < = qp_thresh
& & ( mb_x = = 0 | | ( ( qp + s - > current_picture . qscale_table [ mb_xy - 1 ] + 1 ) > > 1 ) < = qp_thresh )
& & ( mb_y = = 0 | | ( ( qp + s - > current_picture . qscale_table [ h - > top_mb_xy ] + 1 ) > > 1 ) < = qp_thresh ) ) {
return ;
}
}
// CAVLC 8x8dct requires NNZ values for residual decoding that differ from what the loop filter needs
if ( ! h - > pps . cabac & & h - > pps . transform_8x8_mode ) {
int top_type , left_type [ 2 ] ;
top_type = s - > current_picture . mb_type [ h - > top_mb_xy ] ;
left_type [ 0 ] = s - > current_picture . mb_type [ h - > left_mb_xy [ 0 ] ] ;
left_type [ 1 ] = s - > current_picture . mb_type [ h - > left_mb_xy [ 1 ] ] ;
if ( IS_8x8DCT ( top_type ) ) {
h - > non_zero_count_cache [ 4 + 8 * 0 ] =
h - > non_zero_count_cache [ 5 + 8 * 0 ] = h - > cbp_table [ h - > top_mb_xy ] & 4 ;
h - > non_zero_count_cache [ 6 + 8 * 0 ] =
h - > non_zero_count_cache [ 7 + 8 * 0 ] = h - > cbp_table [ h - > top_mb_xy ] & 8 ;
}
if ( IS_8x8DCT ( left_type [ 0 ] ) ) {
h - > non_zero_count_cache [ 3 + 8 * 1 ] =
h - > non_zero_count_cache [ 3 + 8 * 2 ] = h - > cbp_table [ h - > left_mb_xy [ 0 ] ] & 2 ; //FIXME check MBAFF
}
if ( IS_8x8DCT ( left_type [ 1 ] ) ) {
h - > non_zero_count_cache [ 3 + 8 * 3 ] =
h - > non_zero_count_cache [ 3 + 8 * 4 ] = h - > cbp_table [ h - > left_mb_xy [ 1 ] ] & 8 ; //FIXME check MBAFF
}
if ( IS_8x8DCT ( mb_type ) ) {
h - > non_zero_count_cache [ scan8 [ 0 ] ] = h - > non_zero_count_cache [ scan8 [ 1 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 ] ] = h - > non_zero_count_cache [ scan8 [ 3 ] ] = h - > cbp_table [ mb_xy ] & 1 ;
h - > non_zero_count_cache [ scan8 [ 0 + 4 ] ] = h - > non_zero_count_cache [ scan8 [ 1 + 4 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 + 4 ] ] = h - > non_zero_count_cache [ scan8 [ 3 + 4 ] ] = h - > cbp_table [ mb_xy ] & 2 ;
h - > non_zero_count_cache [ scan8 [ 0 + 8 ] ] = h - > non_zero_count_cache [ scan8 [ 1 + 8 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 + 8 ] ] = h - > non_zero_count_cache [ scan8 [ 3 + 8 ] ] = h - > cbp_table [ mb_xy ] & 4 ;
h - > non_zero_count_cache [ scan8 [ 0 + 12 ] ] = h - > non_zero_count_cache [ scan8 [ 1 + 12 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 + 12 ] ] = h - > non_zero_count_cache [ scan8 [ 3 + 12 ] ] = h - > cbp_table [ mb_xy ] & 8 ;
}
}
if ( FRAME_MBAFF
// left mb is in picture
& & h - > slice_table [ mb_xy - 1 ] ! = 0xFFFF
// and current and left pair do not have the same interlaced type
& & ( IS_INTERLACED ( mb_type ) ! = IS_INTERLACED ( s - > current_picture . mb_type [ mb_xy - 1 ] ) )
// and left mb is in the same slice if deblocking_filter == 2
& & ( h - > deblocking_filter ! = 2 | | h - > slice_table [ mb_xy - 1 ] = = h - > slice_table [ mb_xy ] ) ) {
/* First vertical edge is different in MBAFF frames
* There are 8 different bS to compute and 2 different Qp
*/
const int pair_xy = mb_x + ( mb_y & ~ 1 ) * s - > mb_stride ;
const int left_mb_xy [ 2 ] = { pair_xy - 1 , pair_xy - 1 + s - > mb_stride } ;
int16_t bS [ 8 ] ;
int qp [ 2 ] ;
int bqp [ 2 ] ;
int rqp [ 2 ] ;
int mb_qp , mbn0_qp , mbn1_qp ;
int i ;
first_vertical_edge_done = 1 ;
if ( IS_INTRA ( mb_type ) )
bS [ 0 ] = bS [ 1 ] = bS [ 2 ] = bS [ 3 ] = bS [ 4 ] = bS [ 5 ] = bS [ 6 ] = bS [ 7 ] = 4 ;
else {
for ( i = 0 ; i < 8 ; i + + ) {
int mbn_xy = MB_FIELD ? left_mb_xy [ i > > 2 ] : left_mb_xy [ i & 1 ] ;
if ( IS_INTRA ( s - > current_picture . mb_type [ mbn_xy ] ) )
bS [ i ] = 4 ;
else if ( h - > non_zero_count_cache [ 12 + 8 * ( i > > 1 ) ] ! = 0 | |
( ( ! h - > pps . cabac & & IS_8x8DCT ( s - > current_picture . mb_type [ mbn_xy ] ) ) ?
( h - > cbp_table [ mbn_xy ] & ( ( MB_FIELD ? ( i & 2 ) : ( mb_y & 1 ) ) ? 8 : 2 ) )
:
h - > non_zero_count [ mbn_xy ] [ MB_FIELD ? i & 3 : ( i > > 2 ) + ( mb_y & 1 ) * 2 ] ) )
bS [ i ] = 2 ;
else
bS [ i ] = 1 ;
}
}
mb_qp = s - > current_picture . qscale_table [ mb_xy ] ;
mbn0_qp = s - > current_picture . qscale_table [ left_mb_xy [ 0 ] ] ;
mbn1_qp = s - > current_picture . qscale_table [ left_mb_xy [ 1 ] ] ;
qp [ 0 ] = ( mb_qp + mbn0_qp + 1 ) > > 1 ;
bqp [ 0 ] = ( get_chroma_qp ( h , 0 , mb_qp ) +
get_chroma_qp ( h , 0 , mbn0_qp ) + 1 ) > > 1 ;
rqp [ 0 ] = ( get_chroma_qp ( h , 1 , mb_qp ) +
get_chroma_qp ( h , 1 , mbn0_qp ) + 1 ) > > 1 ;
qp [ 1 ] = ( mb_qp + mbn1_qp + 1 ) > > 1 ;
bqp [ 1 ] = ( get_chroma_qp ( h , 0 , mb_qp ) +
get_chroma_qp ( h , 0 , mbn1_qp ) + 1 ) > > 1 ;
rqp [ 1 ] = ( get_chroma_qp ( h , 1 , mb_qp ) +
get_chroma_qp ( h , 1 , mbn1_qp ) + 1 ) > > 1 ;
/* Filter edge */
tprintf ( s - > avctx , " filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d " , mb_x , mb_y , qp [ 0 ] , qp [ 1 ] , bqp [ 0 ] , bqp [ 1 ] , rqp [ 0 ] , rqp [ 1 ] , linesize , uvlinesize ) ;
{ int i ; for ( i = 0 ; i < 8 ; i + + ) tprintf ( s - > avctx , " bS[%d]:%d " , i , bS [ i ] ) ; tprintf ( s - > avctx , " \n " ) ; }
filter_mb_mbaff_edgev ( h , & img_y [ 0 ] , linesize , bS , qp ) ;
filter_mb_mbaff_edgecv ( h , & img_cb [ 0 ] , uvlinesize , bS , bqp ) ;
filter_mb_mbaff_edgecv ( h , & img_cr [ 0 ] , uvlinesize , bS , rqp ) ;
}
/* dir : 0 -> vertical edge, 1 -> horizontal edge */
for ( dir = 0 ; dir < 2 ; dir + + )
{
int edge ;
int edge ;
const int mbm_xy = dir = = 0 ? mb_xy - 1 : h - > top_mb_xy ;
const int mbm_xy = dir = = 0 ? mb_xy - 1 : h - > top_mb_xy ;
const int mbm_type = s - > current_picture . mb_type [ mbm_xy ] ;
const int mbm_type = s - > current_picture . mb_type [ mbm_xy ] ;
@ -6378,7 +6261,6 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
if ( first_vertical_edge_done ) {
if ( first_vertical_edge_done ) {
start = 1 ;
start = 1 ;
first_vertical_edge_done = 0 ;
}
}
if ( h - > deblocking_filter = = 2 & & h - > slice_table [ mbm_xy ] ! = h - > slice_table [ mb_xy ] )
if ( h - > deblocking_filter = = 2 & & h - > slice_table [ mbm_xy ] ! = h - > slice_table [ mb_xy ] )
@ -6561,7 +6443,133 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
}
}
}
}
}
}
}
static void filter_mb ( H264Context * h , int mb_x , int mb_y , uint8_t * img_y , uint8_t * img_cb , uint8_t * img_cr , unsigned int linesize , unsigned int uvlinesize ) {
MpegEncContext * const s = & h - > s ;
const int mb_xy = mb_x + mb_y * s - > mb_stride ;
const int mb_type = s - > current_picture . mb_type [ mb_xy ] ;
const int mvy_limit = IS_INTERLACED ( mb_type ) ? 2 : 4 ;
int first_vertical_edge_done = 0 ;
int dir ;
//for sufficiently low qp, filtering wouldn't do anything
//this is a conservative estimate: could also check beta_offset and more accurate chroma_qp
if ( ! FRAME_MBAFF ) {
int qp_thresh = 15 - h - > slice_alpha_c0_offset - FFMAX3 ( 0 , h - > pps . chroma_qp_index_offset [ 0 ] , h - > pps . chroma_qp_index_offset [ 1 ] ) ;
int qp = s - > current_picture . qscale_table [ mb_xy ] ;
if ( qp < = qp_thresh
& & ( mb_x = = 0 | | ( ( qp + s - > current_picture . qscale_table [ mb_xy - 1 ] + 1 ) > > 1 ) < = qp_thresh )
& & ( mb_y = = 0 | | ( ( qp + s - > current_picture . qscale_table [ h - > top_mb_xy ] + 1 ) > > 1 ) < = qp_thresh ) ) {
return ;
}
}
// CAVLC 8x8dct requires NNZ values for residual decoding that differ from what the loop filter needs
if ( ! h - > pps . cabac & & h - > pps . transform_8x8_mode ) {
int top_type , left_type [ 2 ] ;
top_type = s - > current_picture . mb_type [ h - > top_mb_xy ] ;
left_type [ 0 ] = s - > current_picture . mb_type [ h - > left_mb_xy [ 0 ] ] ;
left_type [ 1 ] = s - > current_picture . mb_type [ h - > left_mb_xy [ 1 ] ] ;
if ( IS_8x8DCT ( top_type ) ) {
h - > non_zero_count_cache [ 4 + 8 * 0 ] =
h - > non_zero_count_cache [ 5 + 8 * 0 ] = h - > cbp_table [ h - > top_mb_xy ] & 4 ;
h - > non_zero_count_cache [ 6 + 8 * 0 ] =
h - > non_zero_count_cache [ 7 + 8 * 0 ] = h - > cbp_table [ h - > top_mb_xy ] & 8 ;
}
if ( IS_8x8DCT ( left_type [ 0 ] ) ) {
h - > non_zero_count_cache [ 3 + 8 * 1 ] =
h - > non_zero_count_cache [ 3 + 8 * 2 ] = h - > cbp_table [ h - > left_mb_xy [ 0 ] ] & 2 ; //FIXME check MBAFF
}
if ( IS_8x8DCT ( left_type [ 1 ] ) ) {
h - > non_zero_count_cache [ 3 + 8 * 3 ] =
h - > non_zero_count_cache [ 3 + 8 * 4 ] = h - > cbp_table [ h - > left_mb_xy [ 1 ] ] & 8 ; //FIXME check MBAFF
}
if ( IS_8x8DCT ( mb_type ) ) {
h - > non_zero_count_cache [ scan8 [ 0 ] ] = h - > non_zero_count_cache [ scan8 [ 1 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 ] ] = h - > non_zero_count_cache [ scan8 [ 3 ] ] = h - > cbp_table [ mb_xy ] & 1 ;
h - > non_zero_count_cache [ scan8 [ 0 + 4 ] ] = h - > non_zero_count_cache [ scan8 [ 1 + 4 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 + 4 ] ] = h - > non_zero_count_cache [ scan8 [ 3 + 4 ] ] = h - > cbp_table [ mb_xy ] & 2 ;
h - > non_zero_count_cache [ scan8 [ 0 + 8 ] ] = h - > non_zero_count_cache [ scan8 [ 1 + 8 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 + 8 ] ] = h - > non_zero_count_cache [ scan8 [ 3 + 8 ] ] = h - > cbp_table [ mb_xy ] & 4 ;
h - > non_zero_count_cache [ scan8 [ 0 + 12 ] ] = h - > non_zero_count_cache [ scan8 [ 1 + 12 ] ] =
h - > non_zero_count_cache [ scan8 [ 2 + 12 ] ] = h - > non_zero_count_cache [ scan8 [ 3 + 12 ] ] = h - > cbp_table [ mb_xy ] & 8 ;
}
}
}
if ( FRAME_MBAFF
// left mb is in picture
& & h - > slice_table [ mb_xy - 1 ] ! = 0xFFFF
// and current and left pair do not have the same interlaced type
& & ( IS_INTERLACED ( mb_type ) ! = IS_INTERLACED ( s - > current_picture . mb_type [ mb_xy - 1 ] ) )
// and left mb is in the same slice if deblocking_filter == 2
& & ( h - > deblocking_filter ! = 2 | | h - > slice_table [ mb_xy - 1 ] = = h - > slice_table [ mb_xy ] ) ) {
/* First vertical edge is different in MBAFF frames
* There are 8 different bS to compute and 2 different Qp
*/
const int pair_xy = mb_x + ( mb_y & ~ 1 ) * s - > mb_stride ;
const int left_mb_xy [ 2 ] = { pair_xy - 1 , pair_xy - 1 + s - > mb_stride } ;
int16_t bS [ 8 ] ;
int qp [ 2 ] ;
int bqp [ 2 ] ;
int rqp [ 2 ] ;
int mb_qp , mbn0_qp , mbn1_qp ;
int i ;
first_vertical_edge_done = 1 ;
if ( IS_INTRA ( mb_type ) )
bS [ 0 ] = bS [ 1 ] = bS [ 2 ] = bS [ 3 ] = bS [ 4 ] = bS [ 5 ] = bS [ 6 ] = bS [ 7 ] = 4 ;
else {
for ( i = 0 ; i < 8 ; i + + ) {
int mbn_xy = MB_FIELD ? left_mb_xy [ i > > 2 ] : left_mb_xy [ i & 1 ] ;
if ( IS_INTRA ( s - > current_picture . mb_type [ mbn_xy ] ) )
bS [ i ] = 4 ;
else if ( h - > non_zero_count_cache [ 12 + 8 * ( i > > 1 ) ] ! = 0 | |
( ( ! h - > pps . cabac & & IS_8x8DCT ( s - > current_picture . mb_type [ mbn_xy ] ) ) ?
( h - > cbp_table [ mbn_xy ] & ( ( MB_FIELD ? ( i & 2 ) : ( mb_y & 1 ) ) ? 8 : 2 ) )
:
h - > non_zero_count [ mbn_xy ] [ MB_FIELD ? i & 3 : ( i > > 2 ) + ( mb_y & 1 ) * 2 ] ) )
bS [ i ] = 2 ;
else
bS [ i ] = 1 ;
}
}
mb_qp = s - > current_picture . qscale_table [ mb_xy ] ;
mbn0_qp = s - > current_picture . qscale_table [ left_mb_xy [ 0 ] ] ;
mbn1_qp = s - > current_picture . qscale_table [ left_mb_xy [ 1 ] ] ;
qp [ 0 ] = ( mb_qp + mbn0_qp + 1 ) > > 1 ;
bqp [ 0 ] = ( get_chroma_qp ( h , 0 , mb_qp ) +
get_chroma_qp ( h , 0 , mbn0_qp ) + 1 ) > > 1 ;
rqp [ 0 ] = ( get_chroma_qp ( h , 1 , mb_qp ) +
get_chroma_qp ( h , 1 , mbn0_qp ) + 1 ) > > 1 ;
qp [ 1 ] = ( mb_qp + mbn1_qp + 1 ) > > 1 ;
bqp [ 1 ] = ( get_chroma_qp ( h , 0 , mb_qp ) +
get_chroma_qp ( h , 0 , mbn1_qp ) + 1 ) > > 1 ;
rqp [ 1 ] = ( get_chroma_qp ( h , 1 , mb_qp ) +
get_chroma_qp ( h , 1 , mbn1_qp ) + 1 ) > > 1 ;
/* Filter edge */
tprintf ( s - > avctx , " filter mb:%d/%d MBAFF, QPy:%d/%d, QPb:%d/%d QPr:%d/%d ls:%d uvls:%d " , mb_x , mb_y , qp [ 0 ] , qp [ 1 ] , bqp [ 0 ] , bqp [ 1 ] , rqp [ 0 ] , rqp [ 1 ] , linesize , uvlinesize ) ;
{ int i ; for ( i = 0 ; i < 8 ; i + + ) tprintf ( s - > avctx , " bS[%d]:%d " , i , bS [ i ] ) ; tprintf ( s - > avctx , " \n " ) ; }
filter_mb_mbaff_edgev ( h , & img_y [ 0 ] , linesize , bS , qp ) ;
filter_mb_mbaff_edgecv ( h , & img_cb [ 0 ] , uvlinesize , bS , bqp ) ;
filter_mb_mbaff_edgecv ( h , & img_cr [ 0 ] , uvlinesize , bS , rqp ) ;
}
# ifdef CONFIG_SMALL
for ( dir = 0 ; dir < 2 ; dir + + )
filter_mb_dir ( h , mb_x , mb_y , img_y , img_cb , img_cr , linesize , uvlinesize , mb_xy , mb_type , mvy_limit , dir ? 0 : first_vertical_edge_done , dir ) ;
# else
filter_mb_dir ( h , mb_x , mb_y , img_y , img_cb , img_cr , linesize , uvlinesize , mb_xy , mb_type , mvy_limit , first_vertical_edge_done , 0 ) ;
filter_mb_dir ( h , mb_x , mb_y , img_y , img_cb , img_cr , linesize , uvlinesize , mb_xy , mb_type , mvy_limit , 0 , 1 ) ;
# endif
}
}
static int decode_slice ( struct AVCodecContext * avctx , void * arg ) {
static int decode_slice ( struct AVCodecContext * avctx , void * arg ) {