mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-06-28 03:18:55 +08:00
last frames & b frames encoding fix
Originally committed as revision 2075 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
@ -195,6 +195,7 @@ void video_encode_example(const char *filename)
|
|||||||
c->frame_rate = 25;
|
c->frame_rate = 25;
|
||||||
c->frame_rate_base= 1;
|
c->frame_rate_base= 1;
|
||||||
c->gop_size = 10; /* emit one intra frame every ten frames */
|
c->gop_size = 10; /* emit one intra frame every ten frames */
|
||||||
|
c->max_b_frames=1;
|
||||||
|
|
||||||
/* open it */
|
/* open it */
|
||||||
if (avcodec_open(c, codec) < 0) {
|
if (avcodec_open(c, codec) < 0) {
|
||||||
@ -225,7 +226,6 @@ void video_encode_example(const char *filename)
|
|||||||
|
|
||||||
/* encode 1 second of video */
|
/* encode 1 second of video */
|
||||||
for(i=0;i<25;i++) {
|
for(i=0;i<25;i++) {
|
||||||
printf("encoding frame %3d\r", i);
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
/* prepare a dummy image */
|
/* prepare a dummy image */
|
||||||
/* Y */
|
/* Y */
|
||||||
@ -245,6 +245,16 @@ void video_encode_example(const char *filename)
|
|||||||
|
|
||||||
/* encode the image */
|
/* encode the image */
|
||||||
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
|
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
|
||||||
|
printf("encoding frame %3d (size=%5d)\n", i, out_size);
|
||||||
|
fwrite(outbuf, 1, out_size, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the delayed frames */
|
||||||
|
for(; out_size; i++) {
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
|
||||||
|
printf("write frame %3d (size=%5d)\n", i, out_size);
|
||||||
fwrite(outbuf, 1, out_size, f);
|
fwrite(outbuf, 1, out_size, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +363,7 @@ void video_decode_example(const char *outfilename, const char *filename)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (got_picture) {
|
if (got_picture) {
|
||||||
printf("saving frame %3d\r", frame);
|
printf("saving frame %3d\n", frame);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
/* the picture is allocated by the decoder. no need to
|
/* the picture is allocated by the decoder. no need to
|
||||||
@ -374,7 +384,7 @@ void video_decode_example(const char *outfilename, const char *filename)
|
|||||||
len = avcodec_decode_video(c, picture, &got_picture,
|
len = avcodec_decode_video(c, picture, &got_picture,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
if (got_picture) {
|
if (got_picture) {
|
||||||
printf("saving frame %3d\r", frame);
|
printf("saving last frame %3d\n", frame);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
/* the picture is allocated by the decoder. no need to
|
/* the picture is allocated by the decoder. no need to
|
||||||
|
@ -1300,11 +1300,12 @@ static int get_intra_count(MpegEncContext *s, uint8_t *src, uint8_t *ref, int st
|
|||||||
|
|
||||||
|
|
||||||
static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
|
static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
|
||||||
AVFrame *pic;
|
AVFrame *pic=NULL;
|
||||||
int i;
|
int i;
|
||||||
const int encoding_delay= s->max_b_frames;
|
const int encoding_delay= s->max_b_frames;
|
||||||
int direct=1;
|
int direct=1;
|
||||||
|
|
||||||
|
if(pic_arg){
|
||||||
if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0;
|
if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0;
|
||||||
if(pic_arg->linesize[0] != s->linesize) direct=0;
|
if(pic_arg->linesize[0] != s->linesize) direct=0;
|
||||||
if(pic_arg->linesize[1] != s->uvlinesize) direct=0;
|
if(pic_arg->linesize[1] != s->uvlinesize) direct=0;
|
||||||
@ -1375,6 +1376,8 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
|
|||||||
if(s->input_picture[encoding_delay])
|
if(s->input_picture[encoding_delay])
|
||||||
pic->display_picture_number= s->input_picture[encoding_delay]->display_picture_number + 1;
|
pic->display_picture_number= s->input_picture[encoding_delay]->display_picture_number + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* shift buffer entries */
|
/* shift buffer entries */
|
||||||
for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++)
|
for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++)
|
||||||
s->input_picture[i-1]= s->input_picture[i];
|
s->input_picture[i-1]= s->input_picture[i];
|
||||||
@ -1427,16 +1430,17 @@ static void select_input_picture(MpegEncContext *s){
|
|||||||
}
|
}
|
||||||
}else if(s->b_frame_strategy==0){
|
}else if(s->b_frame_strategy==0){
|
||||||
b_frames= s->max_b_frames;
|
b_frames= s->max_b_frames;
|
||||||
|
while(b_frames && !s->input_picture[b_frames]) b_frames--;
|
||||||
}else if(s->b_frame_strategy==1){
|
}else if(s->b_frame_strategy==1){
|
||||||
for(i=1; i<s->max_b_frames+1; i++){
|
for(i=1; i<s->max_b_frames+1; i++){
|
||||||
if(s->input_picture[i]->b_frame_score==0){
|
if(s->input_picture[i] && s->input_picture[i]->b_frame_score==0){
|
||||||
s->input_picture[i]->b_frame_score=
|
s->input_picture[i]->b_frame_score=
|
||||||
get_intra_count(s, s->input_picture[i ]->data[0],
|
get_intra_count(s, s->input_picture[i ]->data[0],
|
||||||
s->input_picture[i-1]->data[0], s->linesize) + 1;
|
s->input_picture[i-1]->data[0], s->linesize) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i=0; i<s->max_b_frames; i++){
|
for(i=0; i<s->max_b_frames; i++){
|
||||||
if(s->input_picture[i]->b_frame_score - 1 > s->mb_num/40) break;
|
if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/40) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_frames= FFMAX(0, i-1);
|
b_frames= FFMAX(0, i-1);
|
||||||
|
Reference in New Issue
Block a user