@ -168,6 +168,9 @@ typedef struct H264Context{
int chroma_pred_mode ;
int intra16x16_pred_mode ;
int top_mb_xy ;
int left_mb_xy [ 2 ] ;
int8_t intra4x4_pred_mode_cache [ 5 * 8 ] ;
int8_t ( * intra4x4_pred_mode ) [ 8 ] ;
void ( * pred4x4 [ 9 + 3 ] ) ( uint8_t * src , uint8_t * topright , int stride ) ; //FIXME move to dsp?
@ -177,8 +180,8 @@ typedef struct H264Context{
unsigned int top_samples_available ;
unsigned int topright_samples_available ;
unsigned int left_samples_available ;
uint8_t ( * top_border ) [ 16 + 2 * 8 ] ;
uint8_t left_border [ 17 + 2 * 9 ] ;
uint8_t ( * top_borders [ 2 ] ) [ 16 + 2 * 8 ] ;
uint8_t left_border [ 2 * ( 17 + 2 * 9 ) ] ;
/**
* non zero coeff count cache .
@ -233,6 +236,7 @@ typedef struct H264Context{
int slice_type_fixed ;
//interlacing specific flags
int mb_aff_frame ;
int mb_field_decoding_flag ;
int sub_mb_type [ 4 ] ;
@ -342,7 +346,7 @@ static VLC run7_vlc;
static void svq3_luma_dc_dequant_idct_c ( DCTELEM * block , int qp ) ;
static void svq3_add_idct_c ( uint8_t * dst , DCTELEM * block , int stride , int qp , int dc ) ;
static void filter_mb ( H264Context * h , int mb_x , int mb_y , uint8_t * img_y , uint8_t * img_cb , uint8_t * img_cr ) ;
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 ) ;
static inline uint32_t pack16to32 ( int a , int b ) {
# ifdef WORDS_BIGENDIAN
@ -438,7 +442,7 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){
left_block [ 5 ] = 10 ;
left_block [ 6 ] = 8 ;
left_block [ 7 ] = 11 ;
if ( h - > sps . mb_aff ) {
if ( h - > mb_aff_frame ) {
const int pair_xy = s - > mb_x + ( s - > mb_y & ~ 1 ) * s - > mb_stride ;
const int top_pair_xy = pair_xy - s - > mb_stride ;
const int topleft_pair_xy = top_pair_xy - 1 ;
@ -504,6 +508,11 @@ static inline void fill_caches(H264Context *h, int mb_type, int for_deblock){
}
}
if ( for_deblock ) {
h - > top_mb_xy = top_xy ;
h - > left_mb_xy [ 0 ] = left_xy [ 0 ] ;
h - > left_mb_xy [ 1 ] = left_xy [ 1 ] ;
}
if ( for_deblock ) {
topleft_type = h - > slice_table [ topleft_xy ] < 255 ? s - > current_picture . mb_type [ topleft_xy ] : 0 ;
top_type = h - > slice_table [ top_xy ] < 255 ? s - > current_picture . mb_type [ top_xy ] : 0 ;
@ -1663,9 +1672,9 @@ static void chroma_dc_dct_c(DCTELEM *block){
/**
* gets the chroma qp .
*/
static inline int get_chroma_qp ( H264Context * h , int qscale ) {
static inline int get_chroma_qp ( int chroma_qp_index_offset , int qscale ) {
return chroma_qp [ clip ( qscale + h - > pps . chroma_qp_index_offset , 0 , 51 ) ] ;
return chroma_qp [ clip ( qscale + chroma_qp_index_offset , 0 , 51 ) ] ;
}
@ -2598,7 +2607,8 @@ static void free_tables(H264Context *h){
av_freep ( & h - > direct_table ) ;
av_freep ( & h - > non_zero_count ) ;
av_freep ( & h - > slice_table_base ) ;
av_freep ( & h - > top_border ) ;
av_freep ( & h - > top_borders [ 1 ] ) ;
av_freep ( & h - > top_borders [ 0 ] ) ;
h - > slice_table = NULL ;
av_freep ( & h - > mb2b_xy ) ;
@ -2620,7 +2630,8 @@ static int alloc_tables(H264Context *h){
CHECKED_ALLOCZ ( h - > non_zero_count , big_mb_num * 16 * sizeof ( uint8_t ) )
CHECKED_ALLOCZ ( h - > slice_table_base , big_mb_num * sizeof ( uint8_t ) )
CHECKED_ALLOCZ ( h - > top_border , s - > mb_width * ( 16 + 8 + 8 ) * sizeof ( uint8_t ) )
CHECKED_ALLOCZ ( h - > top_borders [ 0 ] , s - > mb_width * ( 16 + 8 + 8 ) * sizeof ( uint8_t ) )
CHECKED_ALLOCZ ( h - > top_borders [ 1 ] , s - > mb_width * ( 16 + 8 + 8 ) * sizeof ( uint8_t ) )
CHECKED_ALLOCZ ( h - > cbp_table , big_mb_num * sizeof ( uint16_t ) )
if ( h - > pps . cabac ) {
@ -2735,23 +2746,23 @@ static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src
// There is two lines saved, the line above the the top macroblock of a pair,
// and the line above the bottom macroblock
h - > left_border [ 0 ] = h - > top_border [ s - > mb_x ] [ 15 ] ;
h - > left_border [ 0 ] = h - > top_borders [ 0 ] [ s - > mb_x ] [ 15 ] ;
for ( i = 1 ; i < 17 ; i + + ) {
h - > left_border [ i ] = src_y [ 15 + i * linesize ] ;
}
* ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 0 ) = * ( uint64_t * ) ( src_y + 16 * linesize ) ;
* ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 8 ) = * ( uint64_t * ) ( src_y + 8 + 16 * linesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 0 ) = * ( uint64_t * ) ( src_y + 16 * linesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 8 ) = * ( uint64_t * ) ( src_y + 8 + 16 * linesize ) ;
if ( ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
h - > left_border [ 17 ] = h - > top_border [ s - > mb_x ] [ 16 + 7 ] ;
h - > left_border [ 17 + 9 ] = h - > top_border [ s - > mb_x ] [ 24 + 7 ] ;
h - > left_border [ 17 ] = h - > top_borders [ 0 ] [ s - > mb_x ] [ 16 + 7 ] ;
h - > left_border [ 17 + 9 ] = h - > top_borders [ 0 ] [ s - > mb_x ] [ 24 + 7 ] ;
for ( i = 1 ; i < 9 ; i + + ) {
h - > left_border [ i + 17 ] = src_cb [ 7 + i * uvlinesize ] ;
h - > left_border [ i + 17 + 9 ] = src_cr [ 7 + i * uvlinesize ] ;
}
* ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 16 ) = * ( uint64_t * ) ( src_cb + 8 * uvlinesize ) ;
* ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 24 ) = * ( uint64_t * ) ( src_cr + 8 * uvlinesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 16 ) = * ( uint64_t * ) ( src_cb + 8 * uvlinesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 24 ) = * ( uint64_t * ) ( src_cr + 8 * uvlinesize ) ;
}
}
@ -2779,8 +2790,8 @@ b= t;
}
if ( deblock_top ) {
XCHG ( * ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 0 ) , * ( uint64_t * ) ( src_y + 1 ) , temp64 , xchg ) ;
XCHG ( * ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 8 ) , * ( uint64_t * ) ( src_y + 9 ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 0 ) , * ( uint64_t * ) ( src_y + 1 ) , temp64 , xchg ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 8 ) , * ( uint64_t * ) ( src_y + 9 ) , temp64 , 1 ) ;
}
if ( ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
@ -2791,8 +2802,93 @@ b= t;
}
}
if ( deblock_top ) {
XCHG ( * ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 16 ) , * ( uint64_t * ) ( src_cb + 1 ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_border [ s - > mb_x ] + 24 ) , * ( uint64_t * ) ( src_cr + 1 ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 16 ) , * ( uint64_t * ) ( src_cb + 1 ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 24 ) , * ( uint64_t * ) ( src_cr + 1 ) , temp64 , 1 ) ;
}
}
}
static inline void backup_pair_border ( H264Context * h , uint8_t * src_y , uint8_t * src_cb , uint8_t * src_cr , int linesize , int uvlinesize ) {
MpegEncContext * const s = & h - > s ;
int i ;
src_y - = 2 * linesize ;
src_cb - = 2 * uvlinesize ;
src_cr - = 2 * uvlinesize ;
// There is two lines saved, the line above the the top macroblock of a pair,
// and the line above the bottom macroblock
h - > left_border [ 0 ] = h - > top_borders [ 0 ] [ s - > mb_x ] [ 15 ] ;
h - > left_border [ 1 ] = h - > top_borders [ 1 ] [ s - > mb_x ] [ 15 ] ;
for ( i = 2 ; i < 34 ; i + + ) {
h - > left_border [ i ] = src_y [ 15 + i * linesize ] ;
}
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 0 ) = * ( uint64_t * ) ( src_y + 32 * linesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 8 ) = * ( uint64_t * ) ( src_y + 8 + 32 * linesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 0 ) = * ( uint64_t * ) ( src_y + 33 * linesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 8 ) = * ( uint64_t * ) ( src_y + 8 + 33 * linesize ) ;
if ( ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
h - > left_border [ 34 ] = h - > top_borders [ 0 ] [ s - > mb_x ] [ 16 + 7 ] ;
h - > left_border [ 34 + 1 ] = h - > top_borders [ 1 ] [ s - > mb_x ] [ 16 + 7 ] ;
h - > left_border [ 34 + 18 ] = h - > top_borders [ 0 ] [ s - > mb_x ] [ 24 + 7 ] ;
h - > left_border [ 34 + 18 + 1 ] = h - > top_borders [ 1 ] [ s - > mb_x ] [ 24 + 7 ] ;
for ( i = 2 ; i < 18 ; i + + ) {
h - > left_border [ i + 34 ] = src_cb [ 7 + i * uvlinesize ] ;
h - > left_border [ i + 34 + 18 ] = src_cr [ 7 + i * uvlinesize ] ;
}
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 16 ) = * ( uint64_t * ) ( src_cb + 16 * uvlinesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 24 ) = * ( uint64_t * ) ( src_cr + 16 * uvlinesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 16 ) = * ( uint64_t * ) ( src_cb + 17 * uvlinesize ) ;
* ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 24 ) = * ( uint64_t * ) ( src_cr + 17 * uvlinesize ) ;
}
}
static inline void xchg_pair_border ( H264Context * h , uint8_t * src_y , uint8_t * src_cb , uint8_t * src_cr , int linesize , int uvlinesize , int xchg ) {
MpegEncContext * const s = & h - > s ;
int temp8 , i ;
uint64_t temp64 ;
int deblock_left = ( s - > mb_x > 0 ) ;
int deblock_top = ( s - > mb_y > 0 ) ;
tprintf ( " xchg_pair_border: src_y:%p src_cb:%p src_cr:%p ls:%d uvls:%d \n " , src_y , src_cb , src_cr , linesize , uvlinesize ) ;
src_y - = 2 * linesize + 1 ;
src_cb - = 2 * uvlinesize + 1 ;
src_cr - = 2 * uvlinesize + 1 ;
# define XCHG(a,b,t,xchg)\
t = a ; \
if ( xchg ) \
a = b ; \
b = t ;
if ( deblock_left ) {
for ( i = ( ! deblock_top ) < < 1 ; i < 34 ; i + + ) {
XCHG ( h - > left_border [ i ] , src_y [ i * linesize ] , temp8 , xchg ) ;
}
}
if ( deblock_top ) {
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 0 ) , * ( uint64_t * ) ( src_y + 1 ) , temp64 , xchg ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 8 ) , * ( uint64_t * ) ( src_y + 9 ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 0 ) , * ( uint64_t * ) ( src_y + 1 + linesize ) , temp64 , xchg ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 8 ) , * ( uint64_t * ) ( src_y + 9 + linesize ) , temp64 , 1 ) ;
}
if ( ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
if ( deblock_left ) {
for ( i = ( ! deblock_top ) < < 1 ; i < 18 ; i + + ) {
XCHG ( h - > left_border [ i + 34 ] , src_cb [ i * uvlinesize ] , temp8 , xchg ) ;
XCHG ( h - > left_border [ i + 34 + 18 ] , src_cr [ i * uvlinesize ] , temp8 , xchg ) ;
}
}
if ( deblock_top ) {
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 16 ) , * ( uint64_t * ) ( src_cb + 1 ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 0 ] [ s - > mb_x ] + 24 ) , * ( uint64_t * ) ( src_cr + 1 ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 16 ) , * ( uint64_t * ) ( src_cb + 1 + uvlinesize ) , temp64 , 1 ) ;
XCHG ( * ( uint64_t * ) ( h - > top_borders [ 1 ] [ s - > mb_x ] + 24 ) , * ( uint64_t * ) ( src_cr + 1 + uvlinesize ) , temp64 , 1 ) ;
}
}
}
@ -2807,6 +2903,7 @@ static void hl_decode_mb(H264Context *h){
int linesize , uvlinesize /*dct_offset*/ ;
int i ;
int * block_offset = & h - > block_offset [ 0 ] ;
const unsigned int bottom = mb_y & 1 ;
if ( ! s - > decode )
return ;
@ -2858,8 +2955,14 @@ static void hl_decode_mb(H264Context *h){
}
} else {
if ( IS_INTRA ( mb_type ) ) {
if ( h - > deblocking_filter )
if ( h - > deblocking_filter ) {
if ( h - > mb_aff_frame ) {
if ( ! bottom )
xchg_pair_border ( h , dest_y , dest_cb , dest_cr , s - > linesize , s - > uvlinesize , 1 ) ;
} else {
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize , uvlinesize , 1 ) ;
}
}
if ( ! ( s - > flags & CODEC_FLAG_GRAY ) ) {
h - > pred8x8 [ h - > chroma_pred_mode ] ( dest_cb , uvlinesize ) ;
@ -2881,7 +2984,7 @@ static void hl_decode_mb(H264Context *h){
tr = ptr [ 3 - linesize ] * 0x01010101 ;
topright = ( uint8_t * ) & tr ;
} else if ( i = = 5 & & h - > deblocking_filter ) {
tr = * ( uint32_t * ) h - > top_border [ mb_x + 1 ] ;
tr = * ( uint32_t * ) h - > top_borders [ h - > mb_aff_frame ? IS_INTERLACED ( mb_type ) ? bottom : 1 : 0 ] [ mb_x + 1 ] ;
topright = ( uint8_t * ) & tr ;
} else
topright = ptr + 4 - linesize ;
@ -2904,8 +3007,20 @@ static void hl_decode_mb(H264Context *h){
else
svq3_luma_dc_dequant_idct_c ( h - > mb , s - > qscale ) ;
}
if ( h - > deblocking_filter )
if ( h - > deblocking_filter ) {
if ( h - > mb_aff_frame ) {
if ( bottom ) {
uint8_t * pair_dest_y = s - > current_picture . data [ 0 ] + ( ( mb_y - 1 ) * 16 * s - > linesize ) + mb_x * 16 ;
uint8_t * pair_dest_cb = s - > current_picture . data [ 1 ] + ( ( mb_y - 1 ) * 8 * s - > uvlinesize ) + mb_x * 8 ;
uint8_t * pair_dest_cr = s - > current_picture . data [ 2 ] + ( ( mb_y - 1 ) * 8 * s - > uvlinesize ) + mb_x * 8 ;
s - > mb_y - - ;
xchg_pair_border ( h , pair_dest_y , pair_dest_cb , pair_dest_cr , s - > linesize , s - > uvlinesize , 0 ) ;
s - > mb_y + + ;
}
} else {
xchg_mb_border ( h , dest_y , dest_cb , dest_cr , linesize , uvlinesize , 0 ) ;
}
}
} else if ( s - > codec_id = = CODEC_ID_H264 ) {
hl_motion ( h , dest_y , dest_cb , dest_cr ,
s - > dsp . put_h264_qpel_pixels_tab , s - > dsp . put_h264_chroma_pixels_tab ,
@ -2965,9 +3080,42 @@ static void hl_decode_mb(H264Context *h){
}
}
if ( h - > deblocking_filter ) {
if ( h - > mb_aff_frame ) {
const int mb_y = s - > mb_y - 1 ;
uint8_t * pair_dest_y , * pair_dest_cb , * pair_dest_cr ;
const int mb_xy = mb_x + mb_y * s - > mb_stride ;
const int mb_type_top = s - > current_picture . mb_type [ mb_xy ] ;
const int mb_type_bottom = s - > current_picture . mb_type [ mb_xy + s - > mb_stride ] ;
uint8_t tmp = s - > current_picture . data [ 1 ] [ 384 ] ;
if ( ! bottom ) return ;
pair_dest_y = s - > current_picture . data [ 0 ] + ( mb_y * 16 * s - > linesize ) + mb_x * 16 ;
pair_dest_cb = s - > current_picture . data [ 1 ] + ( mb_y * 8 * s - > uvlinesize ) + mb_x * 8 ;
pair_dest_cr = s - > current_picture . data [ 2 ] + ( mb_y * 8 * s - > uvlinesize ) + mb_x * 8 ;
backup_pair_border ( h , pair_dest_y , pair_dest_cb , pair_dest_cr , s - > linesize , s - > uvlinesize ) ;
// TODO deblock a pair
// top
s - > mb_y - - ;
tprintf ( " call mbaff filter_mb mb_x:%d mb_y:%d pair_dest_y = %p, dest_y = %p \n " , mb_x , mb_y , pair_dest_y , dest_y ) ;
fill_caches ( h , mb_type_top , 1 ) ; //FIXME dont fill stuff which isnt used by filter_mb
filter_mb ( h , mb_x , mb_y , pair_dest_y , pair_dest_cb , pair_dest_cr , linesize , uvlinesize ) ;
if ( tmp ! = s - > current_picture . data [ 1 ] [ 384 ] ) {
tprintf ( " modified pixel 8,1 (1) \n " ) ;
}
// bottom
s - > mb_y + + ;
tprintf ( " call mbaff filter_mb \n " ) ;
fill_caches ( h , mb_type_bottom , 1 ) ; //FIXME dont fill stuff which isnt used by filter_mb
filter_mb ( h , mb_x , mb_y + 1 , dest_y , dest_cb , dest_cr , linesize , uvlinesize ) ;
if ( tmp ! = s - > current_picture . data [ 1 ] [ 384 ] ) {
tprintf ( " modified pixel 8,1 (2) \n " ) ;
}
} else {
tprintf ( " call filter_mb \n " ) ;
backup_mb_border ( h , dest_y , dest_cb , dest_cr , linesize , uvlinesize ) ;
fill_caches ( h , mb_type , 1 ) ; //FIXME dont fill stuff which isnt used by filter_mb
filter_mb ( h , mb_x , mb_y , dest_y , dest_cb , dest_cr ) ;
filter_mb ( h , mb_x , mb_y , dest_y , dest_cb , dest_cr , linesize , uvlinesize ) ;
}
}
}
@ -3679,19 +3827,21 @@ static int decode_slice_header(H264Context *h){
s - > current_picture_ptr - > frame_num = //FIXME frame_num cleanup
h - > frame_num = get_bits ( & s - > gb , h - > sps . log2_max_frame_num ) ;
h - > mb_aff_frame = 0 ;
if ( h - > sps . frame_mbs_only_flag ) {
s - > picture_structure = PICT_FRAME ;
} else {
if ( get_bits1 ( & s - > gb ) ) //field_pic_flag
if ( get_bits1 ( & s - > gb ) ) { //field_pic_flag
s - > picture_structure = PICT_TOP_FIELD + get_bits1 ( & s - > gb ) ; //bottom_field_flag
else {
} else {
s - > picture_structure = PICT_FRAME ;
first_mb_in_slice < < = 1 ;
h - > mb_aff_frame = h - > sps . mb_aff ;
}
}
s - > resync_mb_x = s - > mb_x = first_mb_in_slice % s - > mb_width ;
s - > resync_mb_y = s - > mb_y = first_mb_in_slice / s - > mb_width ; //FIXME AFFW
s - > resync_mb_y = s - > mb_y = first_mb_in_slice / s - > mb_width ;
if ( s - > picture_structure = = PICT_FRAME ) {
h - > curr_pic_num = h - > frame_num ;
@ -3774,7 +3924,7 @@ static int decode_slice_header(H264Context *h){
av_log ( s - > avctx , AV_LOG_ERROR , " QP %d out of range \n " , s - > qscale ) ;
return - 1 ;
}
h - > chroma_qp = get_chroma_qp ( h , s - > qscale ) ;
h - > chroma_qp = get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > qscale ) ;
//FIXME qscale / qp ... stuff
if ( h - > slice_type = = SP_TYPE ) {
get_bits1 ( & s - > gb ) ; /* sp_for_switch_flag */
@ -3997,11 +4147,16 @@ static void decode_mb_skip(H264Context *h){
memset ( h - > non_zero_count [ mb_xy ] , 0 , 16 ) ;
memset ( h - > non_zero_count_cache + 8 , 0 , 8 * 5 ) ; //FIXME ugly, remove pfui
if ( h - > mb_aff_frame & & s - > mb_skip_run = = 0 & & ( s - > mb_y & 1 ) = = 0 ) {
h - > mb_field_decoding_flag = get_bits1 ( & s - > gb ) ;
}
if ( h - > mb_field_decoding_flag )
mb_type | = MB_TYPE_INTERLACED ;
if ( h - > slice_type = = B_TYPE )
{
// just for fill_caches. pred_direct_motion will set the real mb_type
mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 | MB_TYPE_DIRECT2 | MB_TYPE_SKIP ;
//FIXME mbaff
fill_caches ( h , mb_type , 0 ) ; //FIXME check what is needed and what not ...
pred_direct_motion ( h , & mb_type ) ;
@ -4015,12 +4170,6 @@ static void decode_mb_skip(H264Context *h){
int mx , my ;
mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_SKIP ;
if ( h - > sps . mb_aff & & s - > mb_skip_run = = 0 & & ( s - > mb_y & 1 ) = = 0 ) {
h - > mb_field_decoding_flag = get_bits1 ( & s - > gb ) ;
}
if ( h - > mb_field_decoding_flag )
mb_type | = MB_TYPE_INTERLACED ;
fill_caches ( h , mb_type , 0 ) ; //FIXME check what is needed and what not ...
pred_pskip_motion ( h , & mx , & my ) ;
fill_rectangle ( & h - > ref_cache [ 0 ] [ scan8 [ 0 ] ] , 4 , 4 , 8 , 0 , 1 ) ;
@ -4059,7 +4208,7 @@ static int decode_mb_cavlc(H264Context *h){
return 0 ;
}
}
if ( h - > sps . mb_aff & & s - > picture_structure = = PICT_FRAME ) {
if ( h - > mb_aff_frame ) {
if ( ( ( s - > mb_y & 1 ) = = 0 ) | | h - > prev_mb_skiped )
h - > mb_field_decoding_flag = get_bits1 ( & s - > gb ) ;
} else
@ -4134,7 +4283,7 @@ decode_intra_mb:
// In deblocking, the quantiser is 0
s - > current_picture . qscale_table [ mb_xy ] = 0 ;
h - > chroma_qp = get_chroma_qp ( h , 0 ) ;
h - > chroma_qp = get_chroma_qp ( h - > pps . chroma_qp_index_offset , 0 ) ;
// All coeffs are presents
memset ( h - > non_zero_count [ mb_xy ] , 16 , 16 ) ;
@ -4395,7 +4544,7 @@ decode_intra_mb:
else s - > qscale - = 52 ;
}
h - > chroma_qp = chroma_qp = get_chroma_qp ( h , s - > qscale ) ;
h - > chroma_qp = chroma_qp = get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > qscale ) ;
if ( IS_INTRA16x16 ( mb_type ) ) {
if ( decode_residual ( h , h - > intra_gb_ptr , h - > mb , LUMA_DC_BLOCK_INDEX , dc_scan , s - > qscale , 16 ) < 0 ) {
return - 1 ; //FIXME continue if partotioned and other retirn -1 too
@ -5082,7 +5231,7 @@ decode_intra_mb:
h - > chroma_pred_mode_table [ mb_xy ] = 0 ;
// In deblocking, the quantiser is 0
s - > current_picture . qscale_table [ mb_xy ] = 0 ;
h - > chroma_qp = get_chroma_qp ( h , 0 ) ;
h - > chroma_qp = get_chroma_qp ( h - > pps . chroma_qp_index_offset , 0 ) ;
// All coeffs are presents
memset ( h - > non_zero_count [ mb_xy ] , 16 , 16 ) ;
return 0 ;
@ -5337,7 +5486,7 @@ decode_intra_mb:
if ( s - > qscale < 0 ) s - > qscale + = 52 ;
else s - > qscale - = 52 ;
}
h - > chroma_qp = get_chroma_qp ( h , s - > qscale ) ;
h - > chroma_qp = get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > qscale ) ;
if ( IS_INTRA16x16 ( mb_type ) ) {
int i ;
@ -5449,6 +5598,7 @@ static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4]
i_delta = clip ( ( ( ( q0 - p0 ) < < 2 ) + ( p1 - q1 ) + 4 ) > > 3 , - tc , tc ) ;
pix [ - 1 ] = clip_uint8 ( p0 + i_delta ) ; /* p0' */
pix [ 0 ] = clip_uint8 ( q0 - i_delta ) ; /* q0' */
tprintf ( " filter_mb_edgev i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , qp , index_a , alpha , beta , tc , bS [ i ] , pix [ - 3 ] , p1 , p0 , q0 , q1 , pix [ 2 ] , pix [ - 2 ] , pix [ - 1 ] , pix [ 0 ] , pix [ 1 ] ) ;
}
pix + = stride ;
}
@ -5495,6 +5645,7 @@ static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4]
pix [ - 1 ] = ( 2 * p1 + p0 + q1 + 2 ) > > 2 ;
pix [ 0 ] = ( 2 * q1 + q0 + p1 + 2 ) > > 2 ;
}
tprintf ( " filter_mb_edgev i:%d d:%d \n # bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , p2 , p1 , p0 , q0 , q1 , q2 , pix [ - 2 ] , pix [ - 1 ] , pix [ 0 ] , pix [ 1 ] ) ;
}
pix + = stride ;
}
@ -5529,7 +5680,7 @@ static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4
pix [ - 1 ] = clip_uint8 ( p0 + i_delta ) ; /* p0' */
pix [ 0 ] = clip_uint8 ( q0 - i_delta ) ; /* q0' */
//tprintf(" filter_mb_edgecv i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d\n# bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, qp, index_a, alpha, beta, tc, bS[i], pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1);
tprintf ( " filter_mb_edgecv i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , qp , index_a , alpha , beta , tc , bS [ i ] , pix [ - 3 ] , p1 , p0 , q0 , q1 , pix [ 2 ] , p1 , pix [ - 1 ] , pix [ 0 ] , q1 ) ;
}
pix + = stride ;
}
@ -5547,7 +5698,7 @@ static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4
pix [ - 1 ] = ( 2 * p1 + p0 + q1 + 2 ) > > 2 ; /* p0' */
pix [ 0 ] = ( 2 * q1 + q0 + p1 + 2 ) > > 2 ; /* q0' */
//tprintf("filter_mb_edgecv i:%d d:%d\n # bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x]\n", i, d, pix[-3], p1, p0, q0, q1, pix[2], p1, pix[-1], pix[0], q1);
tprintf ( " filter_mb_edgecv i:%d d:%d \n # bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , pix [ - 3 ] , p1 , p0 , q0 , q1 , pix [ 2 ] , p1 , pix [ - 1 ] , pix [ 0 ] , q1 ) ;
}
pix + = stride ;
}
@ -5555,6 +5706,160 @@ static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4
}
}
static void filter_mb_mbaff_edgev ( H264Context * h , uint8_t * pix , int stride , int bS [ 8 ] , int qp [ 2 ] ) {
int i ;
for ( i = 0 ; i < 16 ; i + + , pix + = stride ) {
int index_a ;
int alpha ;
int beta ;
int qp_index ;
int bS_index = ( i > > 1 ) ;
if ( h - > mb_field_decoding_flag ) {
bS_index & = ~ 1 ;
bS_index | = ( i & 1 ) ;
}
if ( bS [ bS_index ] = = 0 ) {
continue ;
}
qp_index = h - > mb_field_decoding_flag ? ( i & 1 ) : ( i > > 3 ) ;
index_a = clip ( qp [ qp_index ] + h - > slice_alpha_c0_offset , 0 , 51 ) ;
alpha = alpha_table [ index_a ] ;
beta = beta_table [ clip ( qp [ qp_index ] + h - > slice_beta_offset , 0 , 51 ) ] ;
if ( bS [ bS_index ] < 4 ) {
const int tc0 = tc0_table [ index_a ] [ bS [ bS_index ] - 1 ] ;
/* 4px edge length */
const int p0 = pix [ - 1 ] ;
const int p1 = pix [ - 2 ] ;
const int p2 = pix [ - 3 ] ;
const int q0 = pix [ 0 ] ;
const int q1 = pix [ 1 ] ;
const int q2 = pix [ 2 ] ;
if ( ABS ( p0 - q0 ) < alpha & &
ABS ( p1 - p0 ) < beta & &
ABS ( q1 - q0 ) < beta ) {
int tc = tc0 ;
int i_delta ;
if ( ABS ( p2 - p0 ) < beta ) {
pix [ - 2 ] = p1 + clip ( ( p2 + ( ( p0 + q0 + 1 ) > > 1 ) - ( p1 < < 1 ) ) > > 1 , - tc0 , tc0 ) ;
tc + + ;
}
if ( ABS ( q2 - q0 ) < beta ) {
pix [ 1 ] = q1 + clip ( ( q2 + ( ( p0 + q0 + 1 ) > > 1 ) - ( q1 < < 1 ) ) > > 1 , - tc0 , tc0 ) ;
tc + + ;
}
i_delta = clip ( ( ( ( q0 - p0 ) < < 2 ) + ( p1 - q1 ) + 4 ) > > 3 , - tc , tc ) ;
pix [ - 1 ] = clip_uint8 ( p0 + i_delta ) ; /* p0' */
pix [ 0 ] = clip_uint8 ( q0 - i_delta ) ; /* q0' */
tprintf ( " filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , qp [ qp_index ] , index_a , alpha , beta , tc , bS [ bS_index ] , pix [ - 3 ] , p1 , p0 , q0 , q1 , pix [ 2 ] , p1 , pix [ - 1 ] , pix [ 0 ] , q1 ) ;
}
} else {
/* 4px edge length */
const int p0 = pix [ - 1 ] ;
const int p1 = pix [ - 2 ] ;
const int p2 = pix [ - 3 ] ;
const int q0 = pix [ 0 ] ;
const int q1 = pix [ 1 ] ;
const int q2 = pix [ 2 ] ;
if ( ABS ( p0 - q0 ) < alpha & &
ABS ( p1 - p0 ) < beta & &
ABS ( q1 - q0 ) < beta ) {
if ( ABS ( p0 - q0 ) < ( ( alpha > > 2 ) + 2 ) ) {
if ( ABS ( p2 - p0 ) < beta )
{
const int p3 = pix [ - 4 ] ;
/* p0', p1', p2' */
pix [ - 1 ] = ( p2 + 2 * p1 + 2 * p0 + 2 * q0 + q1 + 4 ) > > 3 ;
pix [ - 2 ] = ( p2 + p1 + p0 + q0 + 2 ) > > 2 ;
pix [ - 3 ] = ( 2 * p3 + 3 * p2 + p1 + p0 + q0 + 4 ) > > 3 ;
} else {
/* p0' */
pix [ - 1 ] = ( 2 * p1 + p0 + q1 + 2 ) > > 2 ;
}
if ( ABS ( q2 - q0 ) < beta )
{
const int q3 = pix [ 3 ] ;
/* q0', q1', q2' */
pix [ 0 ] = ( p1 + 2 * p0 + 2 * q0 + 2 * q1 + q2 + 4 ) > > 3 ;
pix [ 1 ] = ( p0 + q0 + q1 + q2 + 2 ) > > 2 ;
pix [ 2 ] = ( 2 * q3 + 3 * q2 + q1 + q0 + p0 + 4 ) > > 3 ;
} else {
/* q0' */
pix [ 0 ] = ( 2 * q1 + q0 + p1 + 2 ) > > 2 ;
}
} else {
/* p0', q0' */
pix [ - 1 ] = ( 2 * p1 + p0 + q1 + 2 ) > > 2 ;
pix [ 0 ] = ( 2 * q1 + q0 + p1 + 2 ) > > 2 ;
}
tprintf ( " filter_mb_mbaff_edgev i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d \n # bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x] \n " , i , qp [ qp_index ] , index_a , alpha , beta , p2 , p1 , p0 , q0 , q1 , q2 , pix [ - 3 ] , pix [ - 2 ] , pix [ - 1 ] , pix [ 0 ] , pix [ 1 ] , pix [ 2 ] ) ;
}
}
}
}
static void filter_mb_mbaff_edgecv ( H264Context * h , uint8_t * pix , int stride , int bS [ 4 ] , int qp [ 2 ] ) {
int i ;
for ( i = 0 ; i < 8 ; i + + , pix + = stride ) {
int index_a ;
int alpha ;
int beta ;
int qp_index ;
int bS_index = i ;
if ( bS [ bS_index ] = = 0 ) {
continue ;
}
qp_index = h - > mb_field_decoding_flag ? ( i & 1 ) : ( i > > 3 ) ;
index_a = clip ( qp [ qp_index ] + h - > slice_alpha_c0_offset , 0 , 51 ) ;
alpha = alpha_table [ index_a ] ;
beta = beta_table [ clip ( qp [ qp_index ] + h - > slice_beta_offset , 0 , 51 ) ] ;
if ( bS [ bS_index ] < 4 ) {
const int tc = tc0_table [ index_a ] [ bS [ bS_index ] - 1 ] + 1 ;
/* 2px edge length (because we use same bS than the one for luma) */
const int p0 = pix [ - 1 ] ;
const int p1 = pix [ - 2 ] ;
const int q0 = pix [ 0 ] ;
const int q1 = pix [ 1 ] ;
if ( ABS ( p0 - q0 ) < alpha & &
ABS ( p1 - p0 ) < beta & &
ABS ( q1 - q0 ) < beta ) {
const int i_delta = clip ( ( ( ( q0 - p0 ) < < 2 ) + ( p1 - q1 ) + 4 ) > > 3 , - tc , tc ) ;
pix [ - 1 ] = clip_uint8 ( p0 + i_delta ) ; /* p0' */
pix [ 0 ] = clip_uint8 ( q0 - i_delta ) ; /* q0' */
tprintf ( " filter_mb_mbaff_edgecv i:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , qp [ qp_index ] , index_a , alpha , beta , tc , bS [ bS_index ] , pix [ - 3 ] , p1 , p0 , q0 , q1 , pix [ 2 ] , p1 , pix [ - 1 ] , pix [ 0 ] , q1 ) ;
}
} else {
const int p0 = pix [ - 1 ] ;
const int p1 = pix [ - 2 ] ;
const int q0 = pix [ 0 ] ;
const int q1 = pix [ 1 ] ;
if ( ABS ( p0 - q0 ) < alpha & &
ABS ( p1 - p0 ) < beta & &
ABS ( q1 - q0 ) < beta ) {
pix [ - 1 ] = ( 2 * p1 + p0 + q1 + 2 ) > > 2 ; /* p0' */
pix [ 0 ] = ( 2 * q1 + q0 + p1 + 2 ) > > 2 ; /* q0' */
tprintf ( " filter_mb_mbaff_edgecv i:%d \n # bS:4 -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x, %02x, %02x] \n " , i , pix [ - 3 ] , p1 , p0 , q0 , q1 , pix [ 2 ] , pix [ - 3 ] , pix [ - 2 ] , pix [ - 1 ] , pix [ 0 ] , pix [ 1 ] , pix [ 2 ] ) ;
}
}
}
}
static void filter_mb_edgeh ( H264Context * h , uint8_t * pix , int stride , int bS [ 4 ] , int qp ) {
int i , d ;
const int index_a = clip ( qp + h - > slice_alpha_c0_offset , 0 , 51 ) ;
@ -5598,6 +5903,7 @@ static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4]
i_delta = clip ( ( ( ( q0 - p0 ) < < 2 ) + ( p1 - q1 ) + 4 ) > > 3 , - tc , tc ) ;
pix [ - pix_next ] = clip_uint8 ( p0 + i_delta ) ; /* p0' */
pix [ 0 ] = clip_uint8 ( q0 - i_delta ) ; /* q0' */
tprintf ( " filter_mb_edgeh i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , qp , index_a , alpha , beta , tc , bS [ i ] , p2 , p1 , p0 , q0 , q1 , q2 , pix [ - 2 * pix_next ] , pix [ - pix_next ] , pix [ 0 ] , pix [ pix_next ] ) ;
}
pix + + ;
}
@ -5642,6 +5948,7 @@ static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4]
pix [ - 1 * pix_next ] = ( 2 * p1 + p0 + q1 + 2 ) > > 2 ;
pix [ 0 * pix_next ] = ( 2 * q1 + q0 + p1 + 2 ) > > 2 ;
}
tprintf ( " filter_mb_edgeh i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , qp , index_a , alpha , beta , bS [ i ] , p2 , p1 , p0 , q0 , q1 , q2 , pix [ - 2 * pix_next ] , pix [ - pix_next ] , pix [ 0 ] , pix [ pix_next ] ) ;
}
pix + + ;
}
@ -5680,6 +5987,7 @@ static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4
pix [ - pix_next ] = clip_uint8 ( p0 + i_delta ) ; /* p0' */
pix [ 0 ] = clip_uint8 ( q0 - i_delta ) ; /* q0' */
tprintf ( " filter_mb_edgech i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d, tc:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , qp , index_a , alpha , beta , tc , bS [ i ] , pix [ - 3 * pix_next ] , p1 , p0 , q0 , q1 , pix [ 2 * pix_next ] , pix [ - 2 * pix_next ] , pix [ - pix_next ] , pix [ 0 ] , pix [ pix_next ] ) ;
}
pix + + ;
}
@ -5697,6 +6005,7 @@ static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4
pix [ - pix_next ] = ( 2 * p1 + p0 + q1 + 2 ) > > 2 ; /* p0' */
pix [ 0 ] = ( 2 * q1 + q0 + p1 + 2 ) > > 2 ; /* q0' */
tprintf ( " filter_mb_edgech i:%d d:%d, qp:%d, indexA:%d, alpha:%d, beta:%d \n # bS:%d -> [%02x, %02x, %02x, %02x, %02x, %02x] =>[%02x, %02x, %02x, %02x] \n " , i , d , qp , index_a , alpha , beta , bS [ i ] , pix [ - 3 * pix_next ] , p1 , p0 , q0 , q1 , pix [ 2 * pix_next ] , pix [ - 2 * pix_next ] , pix [ - pix_next ] , pix [ 0 ] , pix [ pix_next ] ) ;
}
pix + + ;
}
@ -5704,39 +6013,167 @@ static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4
}
}
static void filter_mb ( H264Context * h , int mb_x , int mb_y , uint8_t * img_y , uint8_t * img_cb , uint8_t * img_cr ) {
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 ;
int linesize , uvlinesize ;
int first_vertical_edge_done = 0 ;
int dir ;
/* FIXME Implement deblocking filter for field MB */
if ( h - > sps . mb_aff ) {
return ;
if ( h - > mb_aff_frame
// left mb is in picture
& & h - > slice_table [ mb_xy - 1 ] ! = 255
// and current and left pair do not have the same interlaced type
& & ( IS_INTERLACED ( s - > current_picture . mb_type [ mb_xy ] ) ! = 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 differents bS to compute and 2 differents Qp
*/
int bS [ 8 ] ;
int qp [ 2 ] ;
int chroma_qp [ 2 ] ;
int i ;
first_vertical_edge_done = 1 ;
for ( i = 0 ; i < 8 ; i + + ) {
int y = i > > 1 ;
int b_idx = 8 + 4 + 8 * y ;
int bn_idx = b_idx - 1 ;
int mbn_xy = h - > mb_field_decoding_flag ? h - > left_mb_xy [ i > > 2 ] : h - > left_mb_xy [ i & 1 ] ;
if ( IS_INTRA ( s - > current_picture . mb_type [ mb_xy ] ) | |
IS_INTRA ( s - > current_picture . mb_type [ mbn_xy ] ) ) {
bS [ i ] = 4 ;
} else if ( h - > non_zero_count_cache [ b_idx ] ! = 0 | |
h - > non_zero_count_cache [ bn_idx ] ! = 0 ) {
bS [ i ] = 2 ;
} else {
/* FIXME: A given frame may occupy more than one position in
* the reference list . So we should compare the frame numbers ,
* not the indices in the ref list . */
int l ;
bS [ i ] = 0 ;
for ( l = 0 ; l < 1 + ( h - > slice_type = = B_TYPE ) ; l + + ) {
if ( h - > ref_cache [ l ] [ b_idx ] ! = h - > ref_cache [ l ] [ bn_idx ] | |
ABS ( h - > mv_cache [ l ] [ b_idx ] [ 0 ] - h - > mv_cache [ l ] [ bn_idx ] [ 0 ] ) > = 4 | |
ABS ( h - > mv_cache [ l ] [ b_idx ] [ 1 ] - h - > mv_cache [ l ] [ bn_idx ] [ 1 ] ) > = 4 ) {
bS [ i ] = 1 ;
break ;
}
linesize = s - > linesize ;
uvlinesize = s - > uvlinesize ;
}
}
}
if ( bS [ 0 ] + bS [ 1 ] + bS [ 2 ] + bS [ 3 ] ! = 0 ) {
// Do not use s->qscale as luma quantiser because it has not the same
// value in IPCM macroblocks.
qp [ 0 ] = ( s - > current_picture . qscale_table [ mb_xy ] + s - > current_picture . qscale_table [ h - > left_mb_xy [ 0 ] ] + 1 ) > > 1 ;
chroma_qp [ 0 ] = ( get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ mb_xy ] ) +
get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ h - > left_mb_xy [ 0 ] ] ) + 1 ) > > 1 ;
qp [ 1 ] = ( s - > current_picture . qscale_table [ mb_xy ] + s - > current_picture . qscale_table [ h - > left_mb_xy [ 1 ] ] + 1 ) > > 1 ;
chroma_qp [ 1 ] = ( get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ mb_xy ] ) +
get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ h - > left_mb_xy [ 1 ] ] ) + 1 ) > > 1 ;
/* Filter edge */
tprintf ( " filter mb:%d/%d MBAFF, QPy:%d/%d, QPc:%d/%d ls:%d uvls:%d " , mb_x , mb_y , qp [ 0 ] , qp [ 1 ] , chroma_qp [ 0 ] , chroma_qp [ 1 ] , linesize , uvlinesize ) ;
{ int i ; for ( i = 0 ; i < 8 ; i + + ) tprintf ( " bS[%d]:%d " , i , bS [ i ] ) ; tprintf ( " \n " ) ; }
filter_mb_mbaff_edgev ( h , & img_y [ 0 ] , linesize , bS , qp ) ;
filter_mb_mbaff_edgecv ( h , & img_cb [ 0 ] , uvlinesize , bS , chroma_qp ) ;
filter_mb_mbaff_edgecv ( h , & img_cr [ 0 ] , uvlinesize , bS , chroma_qp ) ;
}
}
/* dir : 0 -> vertical edge, 1 -> horizontal edge */
for ( dir = 0 ; dir < 2 ; dir + + )
{
int edge ;
const int mbm_xy = dir = = 0 ? mb_xy - 1 : mb_xy - s - > mb_stride ;
const int mbm_xy = dir = = 0 ? mb_xy - 1 : h - > top_mb_xy ;
int start = h - > slice_table [ mbm_xy ] = = 255 ? 1 : 0 ;
if ( first_vertical_edge_done ) {
start = 1 ;
first_vertical_edge_done = 0 ;
}
if ( h - > deblocking_filter = = 2 & & h - > slice_table [ mbm_xy ] ! = h - > slice_table [ mb_xy ] )
start = 1 ;
/* Calculate bS */
for ( edge = start ; edge < 4 ; edge + + ) {
/* mbn_xy: neighbour macroblock (how that works for field ?) */
/* mbn_xy: neighbour macroblock */
int mbn_xy = edge > 0 ? mb_xy : mbm_xy ;
int bS [ 4 ] ;
int qp ;
if ( h - > mb_aff_frame & & ( dir = = 1 ) & & ( edge = = 0 ) & & ( ( mb_y & 1 ) = = 0 )
& & ! IS_INTERLACED ( s - > current_picture . mb_type [ mb_xy ] )
& & IS_INTERLACED ( s - > current_picture . mb_type [ mbn_xy ] )
) {
// This is a special case in the norm where the filtering must
// be done twice (one each of the field) even if we are in a
// frame macroblock.
//
unsigned int tmp_linesize = 2 * linesize ;
unsigned int tmp_uvlinesize = 2 * uvlinesize ;
int mbn_xy = mb_xy - 2 * s - > mb_stride ;
int qp , chroma_qp ;
// first filtering
if ( IS_INTRA ( s - > current_picture . mb_type [ mb_xy ] ) | |
IS_INTRA ( s - > current_picture . mb_type [ mbn_xy ] ) ) {
bS [ 0 ] = bS [ 1 ] = bS [ 2 ] = bS [ 3 ] = ( edge = = 0 ? 4 : 3 ) ;
bS [ 0 ] = bS [ 1 ] = bS [ 2 ] = bS [ 3 ] = 3 ;
} else {
// TODO
assert ( 0 ) ;
}
/* Filter edge */
// Do not use s->qscale as luma quantiser because it has not the same
// value in IPCM macroblocks.
qp = ( s - > current_picture . qscale_table [ mb_xy ] + s - > current_picture . qscale_table [ mbn_xy ] + 1 ) > > 1 ;
tprintf ( " filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d " , mb_x , mb_y , dir , edge , qp , tmp_linesize , tmp_uvlinesize ) ;
{ int i ; for ( i = 0 ; i < 4 ; i + + ) tprintf ( " bS[%d]:%d " , i , bS [ i ] ) ; tprintf ( " \n " ) ; }
filter_mb_edgeh ( h , & img_y [ 0 ] , tmp_linesize , bS , qp ) ;
chroma_qp = ( h - > chroma_qp +
get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ mbn_xy ] ) + 1 ) > > 1 ;
filter_mb_edgech ( h , & img_cb [ 0 ] , tmp_uvlinesize , bS , chroma_qp ) ;
filter_mb_edgech ( h , & img_cr [ 0 ] , tmp_uvlinesize , bS , chroma_qp ) ;
// second filtering
mbn_xy + = s - > mb_stride ;
if ( IS_INTRA ( s - > current_picture . mb_type [ mb_xy ] ) | |
IS_INTRA ( s - > current_picture . mb_type [ mbn_xy ] ) ) {
bS [ 0 ] = bS [ 1 ] = bS [ 2 ] = bS [ 3 ] = 3 ;
} else {
// TODO
assert ( 0 ) ;
}
/* Filter edge */
// Do not use s->qscale as luma quantiser because it has not the same
// value in IPCM macroblocks.
qp = ( s - > current_picture . qscale_table [ mb_xy ] + s - > current_picture . qscale_table [ mbn_xy ] + 1 ) > > 1 ;
tprintf ( " filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d " , mb_x , mb_y , dir , edge , qp , tmp_linesize , tmp_uvlinesize ) ;
{ int i ; for ( i = 0 ; i < 4 ; i + + ) tprintf ( " bS[%d]:%d " , i , bS [ i ] ) ; tprintf ( " \n " ) ; }
filter_mb_edgeh ( h , & img_y [ linesize ] , tmp_linesize , bS , qp ) ;
chroma_qp = ( h - > chroma_qp +
get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ mbn_xy ] ) + 1 ) > > 1 ;
filter_mb_edgech ( h , & img_cb [ uvlinesize ] , tmp_uvlinesize , bS , chroma_qp ) ;
filter_mb_edgech ( h , & img_cr [ uvlinesize ] , tmp_uvlinesize , bS , chroma_qp ) ;
continue ;
}
if ( IS_INTRA ( s - > current_picture . mb_type [ mb_xy ] ) | |
IS_INTRA ( s - > current_picture . mb_type [ mbn_xy ] ) ) {
int value ;
if ( edge = = 0 ) {
if ( ( ! IS_INTERLACED ( s - > current_picture . mb_type [ mb_xy ] ) & & ! IS_INTERLACED ( s - > current_picture . mb_type [ mbm_xy ] ) )
| | ( ( h - > mb_aff_frame | | ( s - > picture_structure ! = PICT_FRAME ) ) & & ( dir = = 0 ) )
) {
value = 4 ;
} else {
value = 3 ;
}
} else {
value = 3 ;
}
bS [ 0 ] = bS [ 1 ] = bS [ 2 ] = bS [ 3 ] = value ;
} else {
int i ;
for ( i = 0 ; i < 4 ; i + + ) {
@ -5776,11 +6213,13 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
// value in IPCM macroblocks.
qp = ( s - > current_picture . qscale_table [ mb_xy ] + s - > current_picture . qscale_table [ mbn_xy ] + 1 ) > > 1 ;
//tprintf("filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp, s->current_picture.qscale_table[mbn_xy]);
tprintf ( " filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d " , mb_x , mb_y , dir , edge , qp , linesize , uvlinesize ) ;
{ int i ; for ( i = 0 ; i < 4 ; i + + ) tprintf ( " bS[%d]:%d " , i , bS [ i ] ) ; tprintf ( " \n " ) ; }
if ( dir = = 0 ) {
filter_mb_edgev ( h , & img_y [ 4 * edge ] , linesize , bS , qp ) ;
if ( ( edge & 1 ) = = 0 ) {
int chroma_qp = ( h - > chroma_qp +
get_chroma_qp ( h , s - > current_picture . qscale_table [ mbn_xy ] ) + 1 ) > > 1 ;
get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ mbn_xy ] ) + 1 ) > > 1 ;
filter_mb_edgecv ( h , & img_cb [ 2 * edge ] , uvlinesize , bS , chroma_qp ) ;
filter_mb_edgecv ( h , & img_cr [ 2 * edge ] , uvlinesize , bS , chroma_qp ) ;
}
@ -5788,7 +6227,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
filter_mb_edgeh ( h , & img_y [ 4 * edge * linesize ] , linesize , bS , qp ) ;
if ( ( edge & 1 ) = = 0 ) {
int chroma_qp = ( h - > chroma_qp +
get_chroma_qp ( h , s - > current_picture . qscale_table [ mbn_xy ] ) + 1 ) > > 1 ;
get_chroma_qp ( h - > pps . chroma_qp_index_offset , s - > current_picture . qscale_table [ mbn_xy ] ) + 1 ) > > 1 ;
filter_mb_edgech ( h , & img_cb [ 2 * edge * uvlinesize ] , uvlinesize , bS , chroma_qp ) ;
filter_mb_edgech ( h , & img_cr [ 2 * edge * uvlinesize ] , uvlinesize , bS , chroma_qp ) ;
}
@ -5835,7 +6274,7 @@ static int decode_slice(H264Context *h){
if ( ret > = 0 ) hl_decode_mb ( h ) ;
/* XXX: useless as decode_mb_cabac it doesn't support that ... */
if ( ret > = 0 & & h - > sps . mb_aff ) { //FIXME optimal? or let mb_decode decode 16x32 ?
if ( ret > = 0 & & h - > mb_aff_frame ) { //FIXME optimal? or let mb_decode decode 16x32 ?
s - > mb_y + + ;
if ( ret > = 0 ) ret = decode_mb_cabac ( h ) ;
@ -5855,7 +6294,7 @@ static int decode_slice(H264Context *h){
s - > mb_x = 0 ;
ff_draw_horiz_band ( s , 16 * s - > mb_y , 16 ) ;
+ + s - > mb_y ;
if ( h - > sps . mb_aff & & s - > picture_structure = = PICT_FRAME ) {
if ( h - > mb_aff_frame ) {
+ + s - > mb_y ;
}
}
@ -5865,13 +6304,6 @@ static int decode_slice(H264Context *h){
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x - 1 , s - > mb_y , ( AC_END | DC_END | MV_END ) & part_mask ) ;
return 0 ;
}
#if 0
/* TODO test over-reading in cabac code */
else if ( read too much in h - > cabac ) {
ff_er_add_slice ( s , s - > resync_mb_x , s - > resync_mb_y , s - > mb_x , s - > mb_y , ( AC_ERROR | DC_ERROR | MV_ERROR ) & part_mask ) ;
return - 1 ;
}
# endif
}
} else {
@ -5880,7 +6312,7 @@ static int decode_slice(H264Context *h){
if ( ret > = 0 ) hl_decode_mb ( h ) ;
if ( ret > = 0 & & h - > sps . mb_aff ) { //FIXME optimal? or let mb_decode decode 16x32 ?
if ( ret > = 0 & & h - > mb_aff_frame ) { //FIXME optimal? or let mb_decode decode 16x32 ?
s - > mb_y + + ;
ret = decode_mb_cavlc ( h ) ;
@ -5899,7 +6331,7 @@ static int decode_slice(H264Context *h){
s - > mb_x = 0 ;
ff_draw_horiz_band ( s , 16 * s - > mb_y , 16 ) ;
+ + s - > mb_y ;
if ( h - > sps . mb_aff & & s - > picture_structure = = PICT_FRAME ) {
if ( h - > mb_aff_frame ) {
+ + s - > mb_y ;
}
if ( s - > mb_y > = s - > mb_height ) {