@ -2770,87 +2770,57 @@ static int split_field_copy(Picture *dest, Picture *src,
if ( match ) {
* dest = * src ;
if ( parity ! = PICT_FRAME ) {
pic_as_field ( dest , parity ) ;
dest - > pic_id * = 2 ;
dest - > pic_id + = id_add ;
}
}
return match ;
}
/**
* Split one reference list into field parts , interleaving by parity
* as per H .264 spec section 8.2 .4 .2 .5 . Output fields have their data pointers
* set to look at the actual start of data for that field .
*
* @ param dest output list
* @ param dest_len maximum number of fields to put in dest
* @ param src the source reference list containing fields and / or field pairs
* ( aka short_ref / long_ref , or
* refFrameListXShortTerm / refFrameListLongTerm in spec - speak )
* @ param src_len number of Picture ' s in source ( pairs and unmatched fields )
* @ param parity the parity of the picture being decoded / needing
* these ref pics ( PICT_ { TOP , BOTTOM } _FIELD )
* @ return number of fields placed in dest
*/
static int split_field_half_ref_list ( Picture * dest , int dest_len ,
Picture * src , int src_len , int parity ) {
int same_parity = 1 ;
int same_i = 0 ;
int opp_i = 0 ;
int out_i ;
int field_output ;
for ( out_i = 0 ; out_i < dest_len ; out_i + = field_output ) {
if ( same_parity & & same_i < src_len ) {
field_output = split_field_copy ( dest + out_i , src + same_i ,
parity , 1 ) ;
same_parity = ! field_output ;
same_i + + ;
} else if ( opp_i < src_len ) {
field_output = split_field_copy ( dest + out_i , src + opp_i ,
PICT_FRAME - parity , 0 ) ;
same_parity = field_output ;
opp_i + + ;
static int build_def_list ( Picture * def , Picture * * in , int len , int is_long , int sel ) {
int i [ 2 ] = { 0 } ;
int index = 0 ;
} else {
break ;
while ( i [ 0 ] < len | | i [ 1 ] < len ) {
while ( i [ 0 ] < len & & ! ( in [ i [ 0 ] ] & & ( in [ i [ 0 ] ] - > reference & sel ) ) )
i [ 0 ] + + ;
while ( i [ 1 ] < len & & ! ( in [ i [ 1 ] ] & & ( in [ i [ 1 ] ] - > reference & ( sel ^ 3 ) ) ) )
i [ 1 ] + + ;
if ( i [ 0 ] < len ) {
in [ i [ 0 ] ] - > pic_id = is_long ? i [ 0 ] : in [ i [ 0 ] ] - > frame_num ;
split_field_copy ( & def [ index + + ] , in [ i [ 0 ] + + ] , sel , 1 ) ;
}
if ( i [ 1 ] < len ) {
in [ i [ 1 ] ] - > pic_id = is_long ? i [ 1 ] : in [ i [ 1 ] ] - > frame_num ;
split_field_copy ( & def [ index + + ] , in [ i [ 1 ] + + ] , sel ^ 3 , 0 ) ;
}
}
return out_i ;
return index ;
}
/**
* Split the reference frame list into a reference field list .
* This implements H .264 spec 8.2 .4 .2 .5 for a combined input list .
* The input list contains both reference field pairs and
* unmatched reference fields ; it is ordered as spec describes
* RefPicListX for frames in 8.2 .4 .2 .1 and 8.2 .4 .2 .3 , except that
* unmatched field pairs are also present . Conceptually this is equivalent
* to concatenation of refFrameListXShortTerm with refFrameListLongTerm .
*
* @ param dest output reference list where ordered fields are to be placed
* @ param dest_len max number of fields to place at dest
* @ param src source reference list , as described above
* @ param src_len number of pictures ( pairs and unmatched fields ) in src
* @ param parity parity of field being currently decoded
* ( one of PICT_ { TOP , BOTTOM } _FIELD )
* @ param long_i index into src array that holds first long reference picture ,
* or src_len if no long refs present .
*/
static int split_field_ref_list ( Picture * dest , int dest_len ,
Picture * src , int src_len ,
int parity , int long_i ) {
static int add_sorted ( Picture * * sorted , Picture * * src , int len , int limit , int dir ) {
int i , best_poc ;
int out_i = 0 ;
int i = split_field_half_ref_list ( dest , dest_len , src , long_i , parity ) ;
dest + = i ;
dest_len - = i ;
for ( ; ; ) {
best_poc = dir ? INT_MIN : INT_MAX ;
i + = split_field_half_ref_list ( dest , dest_len , src + long_i ,
src_len - long_i , parity ) ;
return i ;
for ( i = 0 ; i < len ; i + + ) {
const int poc = src [ i ] - > poc ;
if ( ( ( poc > limit ) ^ dir ) & & ( ( poc < best_poc ) ^ dir ) ) {
best_poc = poc ;
sorted [ out_i ] = src [ i ] ;
}
}
if ( best_poc = = ( dir ? INT_MIN : INT_MAX ) )
break ;
limit = sorted [ out_i + + ] - > poc - dir ;
}
return out_i ;
}
/**
@ -2858,140 +2828,42 @@ static int split_field_ref_list(Picture *dest, int dest_len,
*/
static int fill_default_ref_list ( H264Context * h ) {
MpegEncContext * const s = & h - > s ;
int i ;
int smallest_poc_greater_than_current = - 1 ;
int structure_sel ;
Picture sorted_short_ref [ 32 ] ;
Picture field_entry_list [ 2 ] [ 32 ] ;
Picture * frame_list [ 2 ] ;
if ( FIELD_PICTURE ) {
structure_sel = PICT_FRAME ;
frame_list [ 0 ] = field_entry_list [ 0 ] ;
frame_list [ 1 ] = field_entry_list [ 1 ] ;
} else {
structure_sel = 0 ;
frame_list [ 0 ] = h - > default_ref_list [ 0 ] ;
frame_list [ 1 ] = h - > default_ref_list [ 1 ] ;
}
int i , len ;
if ( h - > slice_type_nos = = FF_B_TYPE ) {
int list ;
int len [ 2 ] ;
int short_len [ 2 ] ;
int out_i ;
int limit = INT_MIN ;
/* sort frame according to POC in B slice */
for ( out_i = 0 ; out_i < h - > short_ref_count ; out_i + + ) {
int best_i = INT_MIN ;
int best_poc = INT_MAX ;
for ( i = 0 ; i < h - > short_ref_count ; i + + ) {
const int poc = h - > short_ref [ i ] - > poc ;
if ( poc > limit & & poc < best_poc ) {
best_poc = poc ;
best_i = i ;
}
}
assert ( best_i ! = INT_MIN ) ;
limit = best_poc ;
sorted_short_ref [ out_i ] = * h - > short_ref [ best_i ] ;
tprintf ( h - > s . avctx , " sorted poc: %d->%d poc:%d fn:%d \n " , best_i , out_i , sorted_short_ref [ out_i ] . poc , sorted_short_ref [ out_i ] . frame_num ) ;
if ( - 1 = = smallest_poc_greater_than_current ) {
if ( h - > short_ref [ best_i ] - > poc > = s - > current_picture_ptr - > poc ) {
smallest_poc_greater_than_current = out_i ;
}
}
}
Picture * sorted [ 32 ] ;
int cur_poc , list ;
int lens [ 2 ] ;
tprintf ( h - > s . avctx , " current poc: %d, smallest_poc_greater_than_current: %d \n " , s - > current_picture_ptr - > poc , smallest_poc_greater_than_current ) ;
// find the largest POC
for ( list = 0 ; list < 2 ; list + + ) {
int index = 0 ;
int j = - 99 ;
int step = list ? - 1 : 1 ;
for ( i = 0 ; i < h - > short_ref_count & & index < h - > ref_count [ list ] ; i + + , j + = step ) {
int sel ;
while ( j < 0 | | j > = h - > short_ref_count ) {
if ( j ! = - 99 & & step = = ( list ? - 1 : 1 ) )
return - 1 ;
step = - step ;
j = smallest_poc_greater_than_current + ( step > > 1 ) ;
}
sel = sorted_short_ref [ j ] . reference | structure_sel ;
if ( sel ! = PICT_FRAME ) continue ;
frame_list [ list ] [ index ] = sorted_short_ref [ j ] ;
frame_list [ list ] [ index + + ] . pic_id = sorted_short_ref [ j ] . frame_num ;
}
short_len [ list ] = index ;
if ( FIELD_PICTURE )
cur_poc = s - > current_picture_ptr - > field_poc [ s - > picture_structure = = PICT_BOTTOM_FIELD ] ;
else
cur_poc = s - > current_picture_ptr - > poc ;
for ( i = 0 ; i < 16 & & index < h - > ref_count [ list ] ; i + + ) {
int sel ;
if ( h - > long_ref [ i ] = = NULL ) continue ;
sel = h - > long_ref [ i ] - > reference | structure_sel ;
if ( sel ! = PICT_FRAME ) continue ;
for ( list = 0 ; list < 2 ; list + + ) {
len = add_sorted ( sorted , h - > short_ref , h - > short_ref_count , cur_poc , 1 ^ list ) ;
len + = add_sorted ( sorted + len , h - > short_ref , h - > short_ref_count , cur_poc , 0 ^ list ) ;
assert ( len < = 32 ) ;
len = build_def_list ( h - > default_ref_list [ list ] , sorted , len , 0 , s - > picture_structure ) ;
len + = build_def_list ( h - > default_ref_list [ list ] + len , h - > long_ref , 16 , 1 , s - > picture_structure ) ;
assert ( len < = 32 ) ;
frame_list [ list ] [ index ] = * h - > long_ref [ i ] ;
frame_list [ list ] [ index + + ] . pic_id = i ;
}
len [ list ] = index ;
if ( len < h - > ref_count [ list ] )
memset ( & h - > default_ref_list [ list ] [ len ] , 0 , sizeof ( Picture ) * ( h - > ref_count [ list ] - len ) ) ;
lens [ list ] = len ;
}
for ( list = 0 ; list < 2 ; list + + ) {
if ( FIELD_PICTURE )
len [ list ] = split_field_ref_list ( h - > default_ref_list [ list ] ,
h - > ref_count [ list ] ,
frame_list [ list ] ,
len [ list ] ,
s - > picture_structure ,
short_len [ list ] ) ;
// swap the two first elements of L1 when L0 and L1 are identical
if ( list & & len [ 0 ] > 1 & & len [ 0 ] = = len [ 1 ] )
for ( i = 0 ; h - > default_ref_list [ 0 ] [ i ] . data [ 0 ] = = h - > default_ref_list [ 1 ] [ i ] . data [ 0 ] ; i + + )
if ( i = = len [ 0 ] ) {
FFSWAP ( Picture , h - > default_ref_list [ 1 ] [ 0 ] , h - > default_ref_list [ 1 ] [ 1 ] ) ;
break ;
}
if ( len [ list ] < h - > ref_count [ list ] )
memset ( & h - > default_ref_list [ list ] [ len [ list ] ] , 0 , sizeof ( Picture ) * ( h - > ref_count [ list ] - len [ list ] ) ) ;
if ( lens [ 0 ] = = lens [ 1 ] & & lens [ 1 ] > 1 ) {
for ( i = 0 ; h - > default_ref_list [ 0 ] [ i ] . data [ 0 ] = = h - > default_ref_list [ 1 ] [ i ] . data [ 0 ] & & i < lens [ 0 ] ; i + + ) ;
if ( i = = lens [ 0 ] )
FFSWAP ( Picture , h - > default_ref_list [ 1 ] [ 0 ] , h - > default_ref_list [ 1 ] [ 1 ] ) ;
}
} else {
int index = 0 ;
int short_len ;
for ( i = 0 ; i < h - > short_ref_count ; i + + ) {
int sel ;
sel = h - > short_ref [ i ] - > reference | structure_sel ;
if ( sel ! = PICT_FRAME ) continue ;
frame_list [ 0 ] [ index ] = * h - > short_ref [ i ] ;
frame_list [ 0 ] [ index + + ] . pic_id = h - > short_ref [ i ] - > frame_num ;
}
short_len = index ;
for ( i = 0 ; i < 16 ; i + + ) {
int sel ;
if ( h - > long_ref [ i ] = = NULL ) continue ;
sel = h - > long_ref [ i ] - > reference | structure_sel ;
if ( sel ! = PICT_FRAME ) continue ;
frame_list [ 0 ] [ index ] = * h - > long_ref [ i ] ;
frame_list [ 0 ] [ index + + ] . pic_id = i ;
}
if ( FIELD_PICTURE )
index = split_field_ref_list ( h - > default_ref_list [ 0 ] ,
h - > ref_count [ 0 ] , frame_list [ 0 ] ,
index , s - > picture_structure ,
short_len ) ;
if ( index < h - > ref_count [ 0 ] )
memset ( & h - > default_ref_list [ 0 ] [ index ] , 0 , sizeof ( Picture ) * ( h - > ref_count [ 0 ] - index ) ) ;
len = build_def_list ( h - > default_ref_list [ 0 ] , h - > short_ref , h - > short_ref_count , 0 , s - > picture_structure ) ;
len + = build_def_list ( h - > default_ref_list [ 0 ] + len , h - > long_ref , 16 , 1 , s - > picture_structure ) ;
assert ( len < = 32 ) ;
if ( len < h - > ref_count [ 0 ] )
memset ( & h - > default_ref_list [ 0 ] [ len ] , 0 , sizeof ( Picture ) * ( h - > ref_count [ 0 ] - len ) ) ;
}
# ifdef TRACE
for ( i = 0 ; i < h - > ref_count [ 0 ] ; i + + ) {