@ -780,7 +780,6 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
/* mark&release old frames */
if ( s - > pict_type ! = B_TYPE & & s - > last_picture . data [ 0 ] ) {
Picture * pic = NULL ;
for ( i = 0 ; i < MAX_PICTURE_COUNT ; i + + ) {
if ( s - > picture [ i ] . data [ 0 ] = = s - > last_picture . data [ 0 ] ) {
// s->picture[i].reference=0;
@ -898,6 +897,39 @@ void MPV_frame_end(MpegEncContext *s)
}
}
static int get_sae ( uint8_t * src , int ref , int stride ) {
int x , y ;
int acc = 0 ;
for ( y = 0 ; y < 16 ; y + + ) {
for ( x = 0 ; x < 16 ; x + + ) {
acc + = ABS ( src [ x + y * stride ] - ref ) ;
}
}
return acc ;
}
static int get_intra_count ( MpegEncContext * s , uint8_t * src , uint8_t * ref , int stride ) {
int x , y , w , h ;
int acc = 0 ;
w = s - > width & ~ 15 ;
h = s - > height & ~ 15 ;
for ( y = 0 ; y < h ; y + = 16 ) {
for ( x = 0 ; x < w ; x + = 16 ) {
int offset = x + y * stride ;
int sad = s - > dsp . pix_abs16x16 ( src + offset , ref + offset , stride ) ;
int mean = ( s - > dsp . pix_sum ( src + offset , stride ) + 128 ) > > 8 ;
int sae = get_sae ( src + offset , mean , stride ) ;
acc + = sae + 500 < sad ;
}
}
return acc ;
}
static int load_input_picture ( MpegEncContext * s , AVVideoFrame * pic_arg ) {
AVVideoFrame * pic ;
int i , r ;
@ -991,50 +1023,75 @@ static void select_input_picture(MpegEncContext *s){
/* set next picture types & ordering */
if ( s - > reordered_input_picture [ 0 ] = = NULL & & s - > input_picture [ 0 ] ) {
if ( s - > input_picture [ 0 ] - > pict_type ) {
/* user selected pict_type */
if ( s - > input_picture [ 0 ] - > pict_type = = I_TYPE ) {
s - > reordered_input_picture [ 0 ] = s - > input_picture [ 0 ] ;
s - > reordered_input_picture [ 0 ] - > coded_picture_number = coded_pic_num ;
} else {
int b_frames ;
if ( /*s->picture_in_gop_number >= s->gop_size ||*/ s - > next_picture . data [ 0 ] = = NULL | | s - > intra_only ) {
s - > reordered_input_picture [ 0 ] = s - > input_picture [ 0 ] ;
s - > reordered_input_picture [ 0 ] - > pict_type = I_TYPE ;
s - > reordered_input_picture [ 0 ] - > coded_picture_number = coded_pic_num ;
} else {
int b_frames ;
if ( s - > flags & CODEC_FLAG_PASS2 ) {
for ( i = 0 ; i < s - > max_b_frames + 1 ; i + + ) {
int pict_num = s - > input_picture [ 0 ] - > display_picture_number + i ;
int pict_type = s - > rc_context . entry [ pict_num ] . new_pict_type ;
s - > input_picture [ i ] - > pict_type = pict_type ;
if ( i + 1 > = s - > rc_context . num_entries ) break ;
}
}
if ( s - > input_picture [ 0 ] - > pict_type ) {
/* user selected pict_type */
for ( b_frames = 0 ; b_frames < s - > max_b_frames + 1 ; b_frames + + ) {
if ( s - > input_picture [ b_frames ] - > pict_type ! = B_TYPE ) break ;
}
if ( b_frames > s - > max_b_frames ) {
fprintf ( stderr , " warning, too many bframes in a row \n " ) ;
b_frames = s - > max_b_frames ;
s - > input_picture [ b_frames ] - > pict_type = I_TYPE ;
}
} else if ( s - > b_frame_strategy = = 0 ) {
b_frames = s - > max_b_frames ;
} else if ( s - > b_frame_strategy = = 1 ) {
for ( i = 1 ; i < s - > max_b_frames + 1 ; i + + ) {
if ( s - > input_picture [ i ] - > b_frame_score = = 0 ) {
s - > input_picture [ i ] - > b_frame_score =
get_intra_count ( s , s - > input_picture [ i ] - > data [ 0 ] + 16 ,
s - > input_picture [ i - 1 ] - > data [ 0 ] + 16 , s - > linesize ) + 1 ;
}
}
for ( i = 0 ; i < s - > max_b_frames ; i + + ) {
if ( s - > input_picture [ i ] - > b_frame_score - 1 > s - > mb_num / 40 ) break ;
}
b_frames = FFMAX ( 0 , i - 1 ) ;
s - > reordered_input_picture [ 0 ] = s - > input_picture [ b_frames ] ;
s - > reordered_input_picture [ 0 ] - > coded_picture_number = coded_pic_num ;
for ( i = 0 ; i < b_frames ; i + + ) {
coded_pic_num + + ;
s - > reordered_input_picture [ i + 1 ] = s - > input_picture [ i ] ;
s - > reordered_input_picture [ i + 1 ] - > coded_picture_number = coded_pic_num ;
}
/* reset scores */
for ( i = 0 ; i < b_frames + 1 ; i + + ) {
s - > input_picture [ i ] - > b_frame_score = 0 ;
}
} else {
fprintf ( stderr , " illegal b frame strategy \n " ) ;
b_frames = 0 ;
}
} else {
if ( /*s->picture_in_gop_number >= s->gop_size ||*/ s - > next_picture . data [ 0 ] = = NULL | | s - > intra_only ) {
s - > reordered_input_picture [ 0 ] = s - > input_picture [ 0 ] ;
emms_c ( ) ;
//static int b_count=0;
//b_count+= b_frames;
//printf("b_frames: %d\n", b_count);
s - > reordered_input_picture [ 0 ] = s - > input_picture [ b_frames ] ;
if ( s - > picture_in_gop_number + b_frames > = s - > gop_size
| | s - > reordered_input_picture [ 0 ] - > pict_type = = I_TYPE )
s - > reordered_input_picture [ 0 ] - > pict_type = I_TYPE ;
s - > reordered_input_picture [ 0 ] - > coded_picture_number = coded_pic_num ;
} else {
s - > reordered_input_picture [ 0 ] = s - > input_picture [ s - > max_b_frames ] ;
if ( s - > picture_in_gop_number + s - > max_b_frames > = s - > gop_size )
s - > reordered_input_picture [ 0 ] - > pict_type = I_TYPE ;
else
s - > reordered_input_picture [ 0 ] - > pict_type = P_TYPE ;
s - > reordered_input_picture [ 0 ] - > coded_picture_number = coded_pic_num ;
for ( i = 0 ; i < s - > max_b_frames ; i + + ) {
coded_pic_num + + ;
s - > reordered_input_picture [ i + 1 ] = s - > input_picture [ i ] ;
s - > reordered_input_picture [ i + 1 ] - > pict_type = B_TYPE ;
s - > reordered_input_picture [ i + 1 ] - > coded_picture_number = coded_pic_num ;
}
else
s - > reordered_input_picture [ 0 ] - > pict_type = P_TYPE ;
s - > reordered_input_picture [ 0 ] - > coded_picture_number = coded_pic_num ;
for ( i = 0 ; i < b_frames ; i + + ) {
coded_pic_num + + ;
s - > reordered_input_picture [ i + 1 ] = s - > input_picture [ i ] ;
s - > reordered_input_picture [ i + 1 ] - > pict_type = B_TYPE ;
s - > reordered_input_picture [ i + 1 ] - > coded_picture_number = coded_pic_num ;
}
}
}