mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-06-21 23:00:04 +08:00
example using video encoder latency
Originally committed as revision 2257 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
@ -34,7 +34,8 @@
|
|||||||
|
|
||||||
/* 5 seconds stream duration */
|
/* 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 */
|
/* audio output */
|
||||||
@ -192,10 +193,14 @@ AVStream *add_video_stream(AVFormatContext *oc, int codec_id)
|
|||||||
c->width = 352;
|
c->width = 352;
|
||||||
c->height = 288;
|
c->height = 288;
|
||||||
/* frames per second */
|
/* frames per second */
|
||||||
c->frame_rate = 25;
|
c->frame_rate = STREAM_FRAME_RATE;
|
||||||
c->frame_rate_base = 1;
|
c->frame_rate_base = 1;
|
||||||
c->gop_size = 12; /* emit one intra frame every twelve frames */
|
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;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,9 +299,16 @@ void write_video_frame(AVFormatContext *oc, AVStream *st)
|
|||||||
{
|
{
|
||||||
int out_size, ret;
|
int out_size, ret;
|
||||||
AVCodecContext *c;
|
AVCodecContext *c;
|
||||||
|
AVFrame *picture_ptr;
|
||||||
|
|
||||||
c = &st->codec;
|
c = &st->codec;
|
||||||
|
|
||||||
|
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 {
|
||||||
if (c->pix_fmt != PIX_FMT_YUV420P) {
|
if (c->pix_fmt != PIX_FMT_YUV420P) {
|
||||||
/* as we only generate a YUV420P picture, we must convert it
|
/* as we only generate a YUV420P picture, we must convert it
|
||||||
to the codec pixel format if needed */
|
to the codec pixel format if needed */
|
||||||
@ -307,19 +319,26 @@ void write_video_frame(AVFormatContext *oc, AVStream *st)
|
|||||||
} else {
|
} else {
|
||||||
fill_yuv_image(picture, frame_count, c->width, c->height);
|
fill_yuv_image(picture, frame_count, c->width, c->height);
|
||||||
}
|
}
|
||||||
|
picture_ptr = picture;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
|
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
|
||||||
/* raw video case. The API will change slightly in the near
|
/* raw video case. The API will change slightly in the near
|
||||||
futur for that */
|
futur for that */
|
||||||
ret = av_write_frame(oc, st->index,
|
ret = av_write_frame(oc, st->index,
|
||||||
(uint8_t *)picture, sizeof(AVPicture));
|
(uint8_t *)picture_ptr, sizeof(AVPicture));
|
||||||
} else {
|
} else {
|
||||||
/* encode the image */
|
/* encode the image */
|
||||||
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
|
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 */
|
/* 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);
|
ret = av_write_frame(oc, st->index, video_outbuf, out_size);
|
||||||
|
} else {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf(stderr, "Error while writing video frame\n");
|
fprintf(stderr, "Error while writing video frame\n");
|
||||||
|
Reference in New Issue
Block a user