2 * Copyright (c) 2003 Fabrice Bellard
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * libavformat API example.
27 * Output a media file in any supported libavformat format. The default
37 #include <libavutil/avassert.h>
38 #include <libavutil/channel_layout.h>
39 #include <libavutil/opt.h>
40 #include <libavutil/mathematics.h>
41 #include <libavutil/timestamp.h>
42 #include <libavformat/avformat.h>
43 #include <libswscale/swscale.h>
44 #include <libswresample/swresample.h>
46 #define STREAM_DURATION 10.0
47 #define STREAM_FRAME_RATE 25 /* 25 images/s */
48 #define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
50 #define SCALE_FLAGS SWS_BICUBIC
52 // a wrapper around a single output AVStream
53 typedef struct OutputStream
{
56 /* pts of the next frame that will be generated */
63 float t
, tincr
, tincr2
;
65 struct SwsContext
*sws_ctx
;
66 struct SwrContext
*swr_ctx
;
69 static void log_packet(const AVFormatContext
*fmt_ctx
, const AVPacket
*pkt
)
71 AVRational
*time_base
= &fmt_ctx
->streams
[pkt
->stream_index
]->time_base
;
73 printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
74 av_ts2str(pkt
->pts
), av_ts2timestr(pkt
->pts
, time_base
),
75 av_ts2str(pkt
->dts
), av_ts2timestr(pkt
->dts
, time_base
),
76 av_ts2str(pkt
->duration
), av_ts2timestr(pkt
->duration
, time_base
),
80 static int write_frame(AVFormatContext
*fmt_ctx
, const AVRational
*time_base
, AVStream
*st
, AVPacket
*pkt
)
82 /* rescale output packet timestamp values from codec to stream timebase */
83 av_packet_rescale_ts(pkt
, *time_base
, st
->time_base
);
84 pkt
->stream_index
= st
->index
;
86 /* Write the compressed frame to the media file. */
87 log_packet(fmt_ctx
, pkt
);
88 return av_interleaved_write_frame(fmt_ctx
, pkt
);
91 /* Add an output stream. */
92 static void add_stream(OutputStream
*ost
, AVFormatContext
*oc
,
94 enum AVCodecID codec_id
)
99 /* find the encoder */
100 *codec
= avcodec_find_encoder(codec_id
);
102 fprintf(stderr
, "Could not find encoder for '%s'\n",
103 avcodec_get_name(codec_id
));
107 ost
->st
= avformat_new_stream(oc
, *codec
);
109 fprintf(stderr
, "Could not allocate stream\n");
112 ost
->st
->id
= oc
->nb_streams
-1;
115 switch ((*codec
)->type
) {
116 case AVMEDIA_TYPE_AUDIO
:
117 c
->sample_fmt
= (*codec
)->sample_fmts
?
118 (*codec
)->sample_fmts
[0] : AV_SAMPLE_FMT_FLTP
;
120 c
->sample_rate
= 44100;
121 if ((*codec
)->supported_samplerates
) {
122 c
->sample_rate
= (*codec
)->supported_samplerates
[0];
123 for (i
= 0; (*codec
)->supported_samplerates
[i
]; i
++) {
124 if ((*codec
)->supported_samplerates
[i
] == 44100)
125 c
->sample_rate
= 44100;
128 c
->channels
= av_get_channel_layout_nb_channels(c
->channel_layout
);
129 c
->channel_layout
= AV_CH_LAYOUT_STEREO
;
130 if ((*codec
)->channel_layouts
) {
131 c
->channel_layout
= (*codec
)->channel_layouts
[0];
132 for (i
= 0; (*codec
)->channel_layouts
[i
]; i
++) {
133 if ((*codec
)->channel_layouts
[i
] == AV_CH_LAYOUT_STEREO
)
134 c
->channel_layout
= AV_CH_LAYOUT_STEREO
;
137 c
->channels
= av_get_channel_layout_nb_channels(c
->channel_layout
);
138 ost
->st
->time_base
= (AVRational
){ 1, c
->sample_rate
};
141 case AVMEDIA_TYPE_VIDEO
:
142 c
->codec_id
= codec_id
;
144 c
->bit_rate
= 400000;
145 /* Resolution must be a multiple of two. */
148 /* timebase: This is the fundamental unit of time (in seconds) in terms
149 * of which frame timestamps are represented. For fixed-fps content,
150 * timebase should be 1/framerate and timestamp increments should be
152 ost
->st
->time_base
= (AVRational
){ 1, STREAM_FRAME_RATE
};
153 c
->time_base
= ost
->st
->time_base
;
155 c
->gop_size
= 12; /* emit one intra frame every twelve frames at most */
156 c
->pix_fmt
= STREAM_PIX_FMT
;
157 if (c
->codec_id
== AV_CODEC_ID_MPEG2VIDEO
) {
158 /* just for testing, we also add B frames */
161 if (c
->codec_id
== AV_CODEC_ID_MPEG1VIDEO
) {
162 /* Needed to avoid using macroblocks in which some coeffs overflow.
163 * This does not happen with normal video, it just happens here as
164 * the motion of the chroma plane does not match the luma plane. */
173 /* Some formats want stream headers to be separate. */
174 if (oc
->oformat
->flags
& AVFMT_GLOBALHEADER
)
175 c
->flags
|= CODEC_FLAG_GLOBAL_HEADER
;
178 /**************************************************************/
181 static AVFrame
*alloc_audio_frame(enum AVSampleFormat sample_fmt
,
182 uint64_t channel_layout
,
183 int sample_rate
, int nb_samples
)
185 AVFrame
*frame
= av_frame_alloc();
189 fprintf(stderr
, "Error allocating an audio frame\n");
193 frame
->format
= sample_fmt
;
194 frame
->channel_layout
= channel_layout
;
195 frame
->sample_rate
= sample_rate
;
196 frame
->nb_samples
= nb_samples
;
199 ret
= av_frame_get_buffer(frame
, 0);
201 fprintf(stderr
, "Error allocating an audio buffer\n");
209 static void open_audio(AVFormatContext
*oc
, AVCodec
*codec
, OutputStream
*ost
, AVDictionary
*opt_arg
)
214 AVDictionary
*opt
= NULL
;
219 av_dict_copy(&opt
, opt_arg
, 0);
220 ret
= avcodec_open2(c
, codec
, &opt
);
223 fprintf(stderr
, "Could not open audio codec: %s\n", av_err2str(ret
));
227 /* init signal generator */
229 ost
->tincr
= 2 * M_PI
* 110.0 / c
->sample_rate
;
230 /* increment frequency by 110 Hz per second */
231 ost
->tincr2
= 2 * M_PI
* 110.0 / c
->sample_rate
/ c
->sample_rate
;
233 if (c
->codec
->capabilities
& CODEC_CAP_VARIABLE_FRAME_SIZE
)
236 nb_samples
= c
->frame_size
;
238 ost
->frame
= alloc_audio_frame(c
->sample_fmt
, c
->channel_layout
,
239 c
->sample_rate
, nb_samples
);
240 ost
->tmp_frame
= alloc_audio_frame(AV_SAMPLE_FMT_S16
, c
->channel_layout
,
241 c
->sample_rate
, nb_samples
);
243 /* create resampler context */
244 ost
->swr_ctx
= swr_alloc();
246 fprintf(stderr
, "Could not allocate resampler context\n");
251 av_opt_set_int (ost
->swr_ctx
, "in_channel_count", c
->channels
, 0);
252 av_opt_set_int (ost
->swr_ctx
, "in_sample_rate", c
->sample_rate
, 0);
253 av_opt_set_sample_fmt(ost
->swr_ctx
, "in_sample_fmt", AV_SAMPLE_FMT_S16
, 0);
254 av_opt_set_int (ost
->swr_ctx
, "out_channel_count", c
->channels
, 0);
255 av_opt_set_int (ost
->swr_ctx
, "out_sample_rate", c
->sample_rate
, 0);
256 av_opt_set_sample_fmt(ost
->swr_ctx
, "out_sample_fmt", c
->sample_fmt
, 0);
258 /* initialize the resampling context */
259 if ((ret
= swr_init(ost
->swr_ctx
)) < 0) {
260 fprintf(stderr
, "Failed to initialize the resampling context\n");
265 /* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
266 * 'nb_channels' channels. */
267 static AVFrame
*get_audio_frame(OutputStream
*ost
)
269 AVFrame
*frame
= ost
->tmp_frame
;
271 int16_t *q
= (int16_t*)frame
->data
[0];
273 /* check if we want to generate more frames */
274 if (av_compare_ts(ost
->next_pts
, ost
->st
->codec
->time_base
,
275 STREAM_DURATION
, (AVRational
){ 1, 1 }) >= 0)
278 for (j
= 0; j
<frame
->nb_samples
; j
++) {
279 v
= (int)(sin(ost
->t
) * 10000);
280 for (i
= 0; i
< ost
->st
->codec
->channels
; i
++)
282 ost
->t
+= ost
->tincr
;
283 ost
->tincr
+= ost
->tincr2
;
286 frame
->pts
= ost
->next_pts
;
287 ost
->next_pts
+= frame
->nb_samples
;
293 * encode one audio frame and send it to the muxer
294 * return 1 when encoding is finished, 0 otherwise
296 static int write_audio_frame(AVFormatContext
*oc
, OutputStream
*ost
)
299 AVPacket pkt
= { 0 }; // data and size must be 0;
305 av_init_packet(&pkt
);
308 frame
= get_audio_frame(ost
);
311 /* convert samples from native format to destination codec format, using the resampler */
312 /* compute destination number of samples */
313 dst_nb_samples
= av_rescale_rnd(swr_get_delay(ost
->swr_ctx
, c
->sample_rate
) + frame
->nb_samples
,
314 c
->sample_rate
, c
->sample_rate
, AV_ROUND_UP
);
315 av_assert0(dst_nb_samples
== frame
->nb_samples
);
317 /* when we pass a frame to the encoder, it may keep a reference to it
319 * make sure we do not overwrite it here
321 ret
= av_frame_make_writable(ost
->frame
);
325 /* convert to destination format */
326 ret
= swr_convert(ost
->swr_ctx
,
327 ost
->frame
->data
, dst_nb_samples
,
328 (const uint8_t **)frame
->data
, frame
->nb_samples
);
330 fprintf(stderr
, "Error while converting\n");
335 frame
->pts
= av_rescale_q(ost
->samples_count
, (AVRational
){1, c
->sample_rate
}, c
->time_base
);
336 ost
->samples_count
+= dst_nb_samples
;
339 ret
= avcodec_encode_audio2(c
, &pkt
, frame
, &got_packet
);
341 fprintf(stderr
, "Error encoding audio frame: %s\n", av_err2str(ret
));
346 ret
= write_frame(oc
, &c
->time_base
, ost
->st
, &pkt
);
348 fprintf(stderr
, "Error while writing audio frame: %s\n",
354 return (frame
|| got_packet
) ? 0 : 1;
357 /**************************************************************/
360 static AVFrame
*alloc_picture(enum AVPixelFormat pix_fmt
, int width
, int height
)
365 picture
= av_frame_alloc();
369 picture
->format
= pix_fmt
;
370 picture
->width
= width
;
371 picture
->height
= height
;
373 /* allocate the buffers for the frame data */
374 ret
= av_frame_get_buffer(picture
, 32);
376 fprintf(stderr
, "Could not allocate frame data.\n");
383 static void open_video(AVFormatContext
*oc
, AVCodec
*codec
, OutputStream
*ost
, AVDictionary
*opt_arg
)
386 AVCodecContext
*c
= ost
->st
->codec
;
387 AVDictionary
*opt
= NULL
;
389 av_dict_copy(&opt
, opt_arg
, 0);
392 ret
= avcodec_open2(c
, codec
, &opt
);
395 fprintf(stderr
, "Could not open video codec: %s\n", av_err2str(ret
));
399 /* allocate and init a re-usable frame */
400 ost
->frame
= alloc_picture(c
->pix_fmt
, c
->width
, c
->height
);
402 fprintf(stderr
, "Could not allocate video frame\n");
406 /* If the output format is not YUV420P, then a temporary YUV420P
407 * picture is needed too. It is then converted to the required
409 ost
->tmp_frame
= NULL
;
410 if (c
->pix_fmt
!= AV_PIX_FMT_YUV420P
) {
411 ost
->tmp_frame
= alloc_picture(AV_PIX_FMT_YUV420P
, c
->width
, c
->height
);
412 if (!ost
->tmp_frame
) {
413 fprintf(stderr
, "Could not allocate temporary picture\n");
419 /* Prepare a dummy image. */
420 static void fill_yuv_image(AVFrame
*pict
, int frame_index
,
421 int width
, int height
)
425 /* when we pass a frame to the encoder, it may keep a reference to it
427 * make sure we do not overwrite it here
429 ret
= av_frame_make_writable(pict
);
436 for (y
= 0; y
< height
; y
++)
437 for (x
= 0; x
< width
; x
++)
438 pict
->data
[0][y
* pict
->linesize
[0] + x
] = x
+ y
+ i
* 3;
441 for (y
= 0; y
< height
/ 2; y
++) {
442 for (x
= 0; x
< width
/ 2; x
++) {
443 pict
->data
[1][y
* pict
->linesize
[1] + x
] = 128 + y
+ i
* 2;
444 pict
->data
[2][y
* pict
->linesize
[2] + x
] = 64 + x
+ i
* 5;
449 static AVFrame
*get_video_frame(OutputStream
*ost
)
451 AVCodecContext
*c
= ost
->st
->codec
;
453 /* check if we want to generate more frames */
454 if (av_compare_ts(ost
->next_pts
, ost
->st
->codec
->time_base
,
455 STREAM_DURATION
, (AVRational
){ 1, 1 }) >= 0)
458 if (c
->pix_fmt
!= AV_PIX_FMT_YUV420P
) {
459 /* as we only generate a YUV420P picture, we must convert it
460 * to the codec pixel format if needed */
462 ost
->sws_ctx
= sws_getContext(c
->width
, c
->height
,
466 SCALE_FLAGS
, NULL
, NULL
, NULL
);
469 "Could not initialize the conversion context\n");
473 fill_yuv_image(ost
->tmp_frame
, ost
->next_pts
, c
->width
, c
->height
);
474 sws_scale(ost
->sws_ctx
,
475 (const uint8_t * const *)ost
->tmp_frame
->data
, ost
->tmp_frame
->linesize
,
476 0, c
->height
, ost
->frame
->data
, ost
->frame
->linesize
);
478 fill_yuv_image(ost
->frame
, ost
->next_pts
, c
->width
, c
->height
);
481 ost
->frame
->pts
= ost
->next_pts
++;
487 * encode one video frame and send it to the muxer
488 * return 1 when encoding is finished, 0 otherwise
490 static int write_video_frame(AVFormatContext
*oc
, OutputStream
*ost
)
499 frame
= get_video_frame(ost
);
501 if (oc
->oformat
->flags
& AVFMT_RAWPICTURE
) {
502 /* a hack to avoid data copy with some raw video muxers */
504 av_init_packet(&pkt
);
509 pkt
.flags
|= AV_PKT_FLAG_KEY
;
510 pkt
.stream_index
= ost
->st
->index
;
511 pkt
.data
= (uint8_t *)frame
;
512 pkt
.size
= sizeof(AVPicture
);
514 pkt
.pts
= pkt
.dts
= frame
->pts
;
515 av_packet_rescale_ts(&pkt
, c
->time_base
, ost
->st
->time_base
);
517 ret
= av_interleaved_write_frame(oc
, &pkt
);
519 AVPacket pkt
= { 0 };
520 av_init_packet(&pkt
);
522 /* encode the image */
523 ret
= avcodec_encode_video2(c
, &pkt
, frame
, &got_packet
);
525 fprintf(stderr
, "Error encoding video frame: %s\n", av_err2str(ret
));
530 ret
= write_frame(oc
, &c
->time_base
, ost
->st
, &pkt
);
537 fprintf(stderr
, "Error while writing video frame: %s\n", av_err2str(ret
));
541 return (frame
|| got_packet
) ? 0 : 1;
544 static void close_stream(AVFormatContext
*oc
, OutputStream
*ost
)
546 avcodec_close(ost
->st
->codec
);
547 av_frame_free(&ost
->frame
);
548 av_frame_free(&ost
->tmp_frame
);
549 sws_freeContext(ost
->sws_ctx
);
550 swr_free(&ost
->swr_ctx
);
553 /**************************************************************/
554 /* media file output */
556 int main(int argc
, char **argv
)
558 OutputStream video_st
= { 0 }, audio_st
= { 0 };
559 const char *filename
;
562 AVCodec
*audio_codec
, *video_codec
;
564 int have_video
= 0, have_audio
= 0;
565 int encode_video
= 0, encode_audio
= 0;
566 AVDictionary
*opt
= NULL
;
568 /* Initialize libavcodec, and register all codecs and formats. */
572 printf("usage: %s output_file\n"
573 "API example program to output a media file with libavformat.\n"
574 "This program generates a synthetic audio and video stream, encodes and\n"
575 "muxes them into a file named output_file.\n"
576 "The output format is automatically guessed according to the file extension.\n"
577 "Raw images can also be output by using '%%d' in the filename.\n"
583 if (argc
> 3 && !strcmp(argv
[2], "-flags")) {
584 av_dict_set(&opt
, argv
[2]+1, argv
[3], 0);
587 /* allocate the output media context */
588 avformat_alloc_output_context2(&oc
, NULL
, NULL
, filename
);
590 printf("Could not deduce output format from file extension: using MPEG.\n");
591 avformat_alloc_output_context2(&oc
, NULL
, "mpeg", filename
);
598 /* Add the audio and video streams using the default format codecs
599 * and initialize the codecs. */
600 if (fmt
->video_codec
!= AV_CODEC_ID_NONE
) {
601 add_stream(&video_st
, oc
, &video_codec
, fmt
->video_codec
);
605 if (fmt
->audio_codec
!= AV_CODEC_ID_NONE
) {
606 add_stream(&audio_st
, oc
, &audio_codec
, fmt
->audio_codec
);
611 /* Now that all the parameters are set, we can open the audio and
612 * video codecs and allocate the necessary encode buffers. */
614 open_video(oc
, video_codec
, &video_st
, opt
);
617 open_audio(oc
, audio_codec
, &audio_st
, opt
);
619 av_dump_format(oc
, 0, filename
, 1);
621 /* open the output file, if needed */
622 if (!(fmt
->flags
& AVFMT_NOFILE
)) {
623 ret
= avio_open(&oc
->pb
, filename
, AVIO_FLAG_WRITE
);
625 fprintf(stderr
, "Could not open '%s': %s\n", filename
,
631 /* Write the stream header, if any. */
632 ret
= avformat_write_header(oc
, &opt
);
634 fprintf(stderr
, "Error occurred when opening output file: %s\n",
639 while (encode_video
|| encode_audio
) {
640 /* select the stream to encode */
642 (!encode_audio
|| av_compare_ts(video_st
.next_pts
, video_st
.st
->codec
->time_base
,
643 audio_st
.next_pts
, audio_st
.st
->codec
->time_base
) <= 0)) {
644 encode_video
= !write_video_frame(oc
, &video_st
);
646 encode_audio
= !write_audio_frame(oc
, &audio_st
);
650 /* Write the trailer, if any. The trailer must be written before you
651 * close the CodecContexts open when you wrote the header; otherwise
652 * av_write_trailer() may try to use memory that was freed on
653 * av_codec_close(). */
654 av_write_trailer(oc
);
656 /* Close each codec. */
658 close_stream(oc
, &video_st
);
660 close_stream(oc
, &audio_st
);
662 if (!(fmt
->flags
& AVFMT_NOFILE
))
663 /* Close the output file. */
666 /* free the stream */
667 avformat_free_context(oc
);