summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2002-12-06 13:30:13 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-12-06 13:30:13 +0000
commit0d1e924668b1384ffbf4282e077f262a2c538596 (patch)
tree153573a16989ffab7da464071019365dd05d3428 /libavcodec
parent32db2b1d47804ca0b722449b17868eda723bc822 (diff)
downloadffmpeg-0d1e924668b1384ffbf4282e077f262a2c538596.tar.gz
fixing 2pass assert failure
better dynamic b frame selection, still not very good though allthough it works fine without 2pass now Originally committed as revision 1316 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/mpegvideo.c127
-rw-r--r--libavcodec/mpegvideo.h3
-rw-r--r--libavcodec/ratecontrol.c33
3 files changed, 95 insertions, 68 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;
}
}
}
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 46e19d4b17..fad4f8eaf1 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -38,7 +38,7 @@ enum OutputFormat {
#define MAX_FCODE 7
#define MAX_MV 2048
-#define MAX_PICTURE_COUNT 7
+#define MAX_PICTURE_COUNT 15
#define ME_MAP_SIZE 64
#define ME_MAP_SHIFT 3
@@ -117,6 +117,7 @@ typedef struct Picture{
uint16_t *mb_var; /* Table for MB variances */
uint16_t *mc_mb_var; /* Table for motion compensated MB variances */
uint8_t *mb_mean; /* Table for MB luminance */
+ int b_frame_score; /* */
} Picture;
typedef struct ParseContext{
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index caea09b24b..e4f2340c74 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -714,38 +714,7 @@ static int init_pass2(MpegEncContext *s)
for(i=0; i<rcc->num_entries; i++){
RateControlEntry *rce= &rcc->entry[i];
- if(s->b_frame_strategy==0 || s->max_b_frames==0){
- rce->new_pict_type= rce->pict_type;
- }else{
- int j;
- int next_non_b_type=P_TYPE;
-
- switch(rce->pict_type){
- case I_TYPE:
- if(i-last_i_frame>s->gop_size/2){ //FIXME this is not optimal
- rce->new_pict_type= I_TYPE;
- last_i_frame= i;
- }else{
- rce->new_pict_type= P_TYPE; // will be caught by the scene detection anyway
- }
- break;
- case P_TYPE:
- rce->new_pict_type= P_TYPE;
- break;
- case B_TYPE:
- for(j=i+1; j<i+s->max_b_frames+2 && j<rcc->num_entries; j++){
- if(rcc->entry[j].pict_type != B_TYPE){
- next_non_b_type= rcc->entry[j].pict_type;
- break;
- }
- }
- if(next_non_b_type==I_TYPE)
- rce->new_pict_type= P_TYPE;
- else
- rce->new_pict_type= B_TYPE;
- break;
- }
- }
+ rce->new_pict_type= rce->pict_type;
rcc->i_cplx_sum [rce->pict_type] += rce->i_tex_bits*rce->qscale;
rcc->p_cplx_sum [rce->pict_type] += rce->p_tex_bits*rce->qscale;
rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits;