diff options
Diffstat (limited to 'libavcodec/mpegvideo.c')
-rw-r--r-- | libavcodec/mpegvideo.c | 127 |
1 files changed, 92 insertions, 35 deletions
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index c1a0b0b55c..63338012ff 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -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; } } } |