diff options
-rw-r--r-- | output_example.c | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/output_example.c b/output_example.c index beef610904..ca47a888f1 100644 --- a/output_example.c +++ b/output_example.c @@ -33,8 +33,9 @@ #include "avformat.h" /* 5 seconds stream duration */ -#define STREAM_DURATION 5.0 - +#define STREAM_DURATION 5.0 +#define STREAM_FRAME_RATE 25 /* 25 images/s */ +#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE)) /**************************************************************/ /* audio output */ @@ -192,10 +193,14 @@ AVStream *add_video_stream(AVFormatContext *oc, int codec_id) c->width = 352; c->height = 288; /* frames per second */ - c->frame_rate = 25; - c->frame_rate_base= 1; - c->gop_size = 12; /* emit one intra frame every twelve frames */ - + c->frame_rate = STREAM_FRAME_RATE; + c->frame_rate_base = 1; + c->gop_size = 12; /* emit one intra frame every twelve frames at most */ + if (c->codec_id == CODEC_ID_MPEG1VIDEO || + c->codec_id == CODEC_ID_MPEG2VIDEO) { + /* just for testing, we also add B frames */ + c->max_b_frames = 2; + } return st; } @@ -294,18 +299,27 @@ void write_video_frame(AVFormatContext *oc, AVStream *st) { int out_size, ret; AVCodecContext *c; - + AVFrame *picture_ptr; + c = &st->codec; - if (c->pix_fmt != PIX_FMT_YUV420P) { - /* as we only generate a YUV420P picture, we must convert it - to the codec pixel format if needed */ - fill_yuv_image(tmp_picture, frame_count, c->width, c->height); - img_convert((AVPicture *)picture, c->pix_fmt, - (AVPicture *)tmp_picture, PIX_FMT_YUV420P, - c->width, c->height); + if (frame_count >= STREAM_NB_FRAMES) { + /* no more frame to compress. The codec has a latency of a few + frames if using B frames, so we get the last frames by + passing a NULL picture */ + picture_ptr = NULL; } else { - fill_yuv_image(picture, frame_count, c->width, c->height); + if (c->pix_fmt != PIX_FMT_YUV420P) { + /* as we only generate a YUV420P picture, we must convert it + to the codec pixel format if needed */ + fill_yuv_image(tmp_picture, frame_count, c->width, c->height); + img_convert((AVPicture *)picture, c->pix_fmt, + (AVPicture *)tmp_picture, PIX_FMT_YUV420P, + c->width, c->height); + } else { + fill_yuv_image(picture, frame_count, c->width, c->height); + } + picture_ptr = picture; } @@ -313,13 +327,18 @@ void write_video_frame(AVFormatContext *oc, AVStream *st) /* raw video case. The API will change slightly in the near futur for that */ ret = av_write_frame(oc, st->index, - (uint8_t *)picture, sizeof(AVPicture)); + (uint8_t *)picture_ptr, sizeof(AVPicture)); } else { /* encode the image */ - out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture); - - /* write the compressed frame in the media file */ - ret = av_write_frame(oc, st->index, video_outbuf, out_size); + out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture_ptr); + /* if zero size, it means the image was buffered */ + if (out_size != 0) { + /* write the compressed frame in the media file */ + /* XXX: in case of B frames, the pts is not yet valid */ + ret = av_write_frame(oc, st->index, video_outbuf, out_size); + } else { + ret = 0; + } } if (ret != 0) { fprintf(stderr, "Error while writing video frame\n"); |