Move output_example.c --> libavformat/output-example.c.
[libav.git] / libavformat / output-example.c
CommitLineData
8de65d4f
FB
1/*
2 * Libavformat API example: Output a media file in any supported
3 * libavformat format. The default codecs are used.
115329f1 4 *
8de65d4f 5 * Copyright (c) 2003 Fabrice Bellard
115329f1 6 *
8de65d4f
FB
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
115329f1 13 *
8de65d4f
FB
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
115329f1 16 *
8de65d4f
FB
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
115329f1 23 * THE SOFTWARE.
8de65d4f
FB
24 */
25#include <stdlib.h>
26#include <stdio.h>
af547ce5 27#include <string.h>
8de65d4f
FB
28#include <math.h>
29
264cb2b8 30#ifndef M_PI
a40de112 31#define M_PI 3.14159265358979323846
264cb2b8
MN
32#endif
33
245976da
DB
34#include "libavformat/avformat.h"
35#include "libswscale/swscale.h"
8de65d4f 36
364a9607
DB
37#undef exit
38
8de65d4f 39/* 5 seconds stream duration */
cb0c448a
FB
40#define STREAM_DURATION 5.0
41#define STREAM_FRAME_RATE 25 /* 25 images/s */
42#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
002c01a6 43#define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
8de65d4f 44
03ae87a3
LA
45static int sws_flags = SWS_BICUBIC;
46
8de65d4f
FB
47/**************************************************************/
48/* audio output */
49
e70fcf07 50float t, tincr, tincr2;
8de65d4f
FB
51int16_t *samples;
52uint8_t *audio_outbuf;
53int audio_outbuf_size;
54int audio_input_frame_size;
55
115329f1 56/*
8de65d4f
FB
57 * add an audio output stream
58 */
ceaf1909 59static AVStream *add_audio_stream(AVFormatContext *oc, int codec_id)
8de65d4f 60{
8de65d4f
FB
61 AVCodecContext *c;
62 AVStream *st;
63
64 st = av_new_stream(oc, 1);
65 if (!st) {
66 fprintf(stderr, "Could not alloc stream\n");
67 exit(1);
68 }
69
01f4895c 70 c = st->codec;
e70fcf07 71 c->codec_id = codec_id;
8de65d4f
FB
72 c->codec_type = CODEC_TYPE_AUDIO;
73
74 /* put sample parameters */
75 c->bit_rate = 64000;
76 c->sample_rate = 44100;
77 c->channels = 2;
e70fcf07
FB
78 return st;
79}
80
ceaf1909 81static void open_audio(AVFormatContext *oc, AVStream *st)
e70fcf07
FB
82{
83 AVCodecContext *c;
84 AVCodec *codec;
85
01f4895c 86 c = st->codec;
e70fcf07
FB
87
88 /* find the audio encoder */
89 codec = avcodec_find_encoder(c->codec_id);
90 if (!codec) {
91 fprintf(stderr, "codec not found\n");
92 exit(1);
93 }
8de65d4f
FB
94
95 /* open it */
96 if (avcodec_open(c, codec) < 0) {
97 fprintf(stderr, "could not open codec\n");
98 exit(1);
99 }
100
101 /* init signal generator */
102 t = 0;
e70fcf07
FB
103 tincr = 2 * M_PI * 110.0 / c->sample_rate;
104 /* increment frequency by 110 Hz per second */
105 tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
8de65d4f
FB
106
107 audio_outbuf_size = 10000;
5d915e82 108 audio_outbuf = av_malloc(audio_outbuf_size);
8de65d4f
FB
109
110 /* ugly hack for PCM codecs (will be removed ASAP with new PCM
111 support to compute the input frame size in samples */
112 if (c->frame_size <= 1) {
113 audio_input_frame_size = audio_outbuf_size / c->channels;
01f4895c 114 switch(st->codec->codec_id) {
8de65d4f
FB
115 case CODEC_ID_PCM_S16LE:
116 case CODEC_ID_PCM_S16BE:
117 case CODEC_ID_PCM_U16LE:
118 case CODEC_ID_PCM_U16BE:
119 audio_input_frame_size >>= 1;
120 break;
121 default:
122 break;
123 }
124 } else {
125 audio_input_frame_size = c->frame_size;
126 }
5d915e82 127 samples = av_malloc(audio_input_frame_size * 2 * c->channels);
8de65d4f
FB
128}
129
cb750e33
FB
130/* prepare a 16 bit dummy audio frame of 'frame_size' samples and
131 'nb_channels' channels */
ceaf1909 132static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
cb750e33
FB
133{
134 int j, i, v;
135 int16_t *q;
136
137 q = samples;
138 for(j=0;j<frame_size;j++) {
139 v = (int)(sin(t) * 10000);
140 for(i = 0; i < nb_channels; i++)
141 *q++ = v;
142 t += tincr;
143 tincr += tincr2;
144 }
145}
146
ceaf1909 147static void write_audio_frame(AVFormatContext *oc, AVStream *st)
8de65d4f 148{
8de65d4f 149 AVCodecContext *c;
e928649b
MN
150 AVPacket pkt;
151 av_init_packet(&pkt);
115329f1 152
01f4895c 153 c = st->codec;
8de65d4f 154
cb750e33
FB
155 get_audio_frame(samples, audio_input_frame_size, c->channels);
156
e928649b
MN
157 pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
158
fb34e75d 159 if (c->coded_frame->pts != AV_NOPTS_VALUE)
817a3de9 160 pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
e928649b
MN
161 pkt.flags |= PKT_FLAG_KEY;
162 pkt.stream_index= st->index;
163 pkt.data= audio_outbuf;
8de65d4f
FB
164
165 /* write the compressed frame in the media file */
a6f925b8 166 if (av_interleaved_write_frame(oc, &pkt) != 0) {
8de65d4f
FB
167 fprintf(stderr, "Error while writing audio frame\n");
168 exit(1);
169 }
170}
171
ceaf1909 172static void close_audio(AVFormatContext *oc, AVStream *st)
e70fcf07 173{
01f4895c 174 avcodec_close(st->codec);
115329f1 175
e70fcf07
FB
176 av_free(samples);
177 av_free(audio_outbuf);
178}
179
8de65d4f
FB
180/**************************************************************/
181/* video output */
182
e70fcf07 183AVFrame *picture, *tmp_picture;
8de65d4f
FB
184uint8_t *video_outbuf;
185int frame_count, video_outbuf_size;
186
187/* add a video output stream */
ceaf1909 188static AVStream *add_video_stream(AVFormatContext *oc, int codec_id)
8de65d4f 189{
8de65d4f
FB
190 AVCodecContext *c;
191 AVStream *st;
8de65d4f
FB
192
193 st = av_new_stream(oc, 0);
194 if (!st) {
195 fprintf(stderr, "Could not alloc stream\n");
196 exit(1);
197 }
115329f1 198
01f4895c 199 c = st->codec;
e70fcf07 200 c->codec_id = codec_id;
8de65d4f
FB
201 c->codec_type = CODEC_TYPE_VIDEO;
202
203 /* put sample parameters */
204 c->bit_rate = 400000;
205 /* resolution must be a multiple of two */
115329f1 206 c->width = 352;
8de65d4f 207 c->height = 288;
5b28c8c3
MN
208 /* time base: this is the fundamental unit of time (in seconds) in terms
209 of which frame timestamps are represented. for fixed-fps content,
210 timebase should be 1/framerate and timestamp increments should be
211 identically 1. */
115329f1 212 c->time_base.den = STREAM_FRAME_RATE;
c0df9d75 213 c->time_base.num = 1;
cb0c448a 214 c->gop_size = 12; /* emit one intra frame every twelve frames at most */
002c01a6 215 c->pix_fmt = STREAM_PIX_FMT;
85e33747 216 if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
cb0c448a
FB
217 /* just for testing, we also add B frames */
218 c->max_b_frames = 2;
219 }
85e33747 220 if (c->codec_id == CODEC_ID_MPEG1VIDEO){
755bfeab
DB
221 /* Needed to avoid using macroblocks in which some coeffs overflow.
222 This does not happen with normal video, it just happens here as
223 the motion of the chroma plane does not match the luma plane. */
85e33747
MN
224 c->mb_decision=2;
225 }
0afd2a92 226 // some formats want stream headers to be separate
c12b0d86 227 if(oc->oformat->flags & AVFMT_GLOBALHEADER)
af547ce5 228 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
115329f1 229
e70fcf07
FB
230 return st;
231}
232
ceaf1909 233static AVFrame *alloc_picture(int pix_fmt, int width, int height)
e70fcf07
FB
234{
235 AVFrame *picture;
236 uint8_t *picture_buf;
237 int size;
115329f1 238
e70fcf07
FB
239 picture = avcodec_alloc_frame();
240 if (!picture)
241 return NULL;
242 size = avpicture_get_size(pix_fmt, width, height);
5d915e82 243 picture_buf = av_malloc(size);
e70fcf07
FB
244 if (!picture_buf) {
245 av_free(picture);
246 return NULL;
247 }
115329f1 248 avpicture_fill((AVPicture *)picture, picture_buf,
e70fcf07
FB
249 pix_fmt, width, height);
250 return picture;
251}
115329f1 252
ceaf1909 253static void open_video(AVFormatContext *oc, AVStream *st)
e70fcf07
FB
254{
255 AVCodec *codec;
256 AVCodecContext *c;
257
01f4895c 258 c = st->codec;
e70fcf07
FB
259
260 /* find the video encoder */
261 codec = avcodec_find_encoder(c->codec_id);
262 if (!codec) {
263 fprintf(stderr, "codec not found\n");
264 exit(1);
265 }
266
267 /* open the codec */
8de65d4f
FB
268 if (avcodec_open(c, codec) < 0) {
269 fprintf(stderr, "could not open codec\n");
270 exit(1);
271 }
272
e70fcf07
FB
273 video_outbuf = NULL;
274 if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
275 /* allocate output buffer */
276 /* XXX: API change will be done */
5d915e82
RP
277 /* buffers passed into lav* can be allocated any way you prefer,
278 as long as they're aligned enough for the architecture, and
279 they're freed appropriately (such as using av_free for buffers
280 allocated with av_malloc) */
e70fcf07 281 video_outbuf_size = 200000;
5d915e82 282 video_outbuf = av_malloc(video_outbuf_size);
e70fcf07 283 }
8de65d4f 284
e70fcf07
FB
285 /* allocate the encoded raw picture */
286 picture = alloc_picture(c->pix_fmt, c->width, c->height);
287 if (!picture) {
288 fprintf(stderr, "Could not allocate picture\n");
289 exit(1);
290 }
8de65d4f 291
e70fcf07
FB
292 /* if the output format is not YUV420P, then a temporary YUV420P
293 picture is needed too. It is then converted to the required
294 output format */
295 tmp_picture = NULL;
296 if (c->pix_fmt != PIX_FMT_YUV420P) {
297 tmp_picture = alloc_picture(PIX_FMT_YUV420P, c->width, c->height);
298 if (!tmp_picture) {
299 fprintf(stderr, "Could not allocate temporary picture\n");
300 exit(1);
301 }
302 }
303}
8de65d4f 304
e70fcf07 305/* prepare a dummy image */
ceaf1909 306static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
8de65d4f 307{
e70fcf07
FB
308 int x, y, i;
309
310 i = frame_index;
8de65d4f 311
8de65d4f 312 /* Y */
e70fcf07
FB
313 for(y=0;y<height;y++) {
314 for(x=0;x<width;x++) {
315 pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
8de65d4f
FB
316 }
317 }
115329f1 318
8de65d4f 319 /* Cb and Cr */
e70fcf07
FB
320 for(y=0;y<height/2;y++) {
321 for(x=0;x<width/2;x++) {
322 pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
323 pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
8de65d4f
FB
324 }
325 }
e70fcf07 326}
8de65d4f 327
ceaf1909 328static void write_video_frame(AVFormatContext *oc, AVStream *st)
e70fcf07
FB
329{
330 int out_size, ret;
331 AVCodecContext *c;
03ae87a3 332 static struct SwsContext *img_convert_ctx;
115329f1 333
01f4895c 334 c = st->codec;
115329f1 335
cb0c448a
FB
336 if (frame_count >= STREAM_NB_FRAMES) {
337 /* no more frame to compress. The codec has a latency of a few
338 frames if using B frames, so we get the last frames by
002c01a6 339 passing the same picture again */
e70fcf07 340 } else {
cb0c448a
FB
341 if (c->pix_fmt != PIX_FMT_YUV420P) {
342 /* as we only generate a YUV420P picture, we must convert it
343 to the codec pixel format if needed */
03ae87a3
LA
344 if (img_convert_ctx == NULL) {
345 img_convert_ctx = sws_getContext(c->width, c->height,
346 PIX_FMT_YUV420P,
347 c->width, c->height,
348 c->pix_fmt,
349 sws_flags, NULL, NULL, NULL);
350 if (img_convert_ctx == NULL) {
351 fprintf(stderr, "Cannot initialize the conversion context\n");
352 exit(1);
353 }
354 }
cb0c448a 355 fill_yuv_image(tmp_picture, frame_count, c->width, c->height);
03ae87a3
LA
356 sws_scale(img_convert_ctx, tmp_picture->data, tmp_picture->linesize,
357 0, c->height, picture->data, picture->linesize);
cb0c448a
FB
358 } else {
359 fill_yuv_image(picture, frame_count, c->width, c->height);
360 }
e70fcf07
FB
361 }
362
115329f1 363
e70fcf07
FB
364 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
365 /* raw video case. The API will change slightly in the near
366 futur for that */
e928649b
MN
367 AVPacket pkt;
368 av_init_packet(&pkt);
115329f1 369
e928649b
MN
370 pkt.flags |= PKT_FLAG_KEY;
371 pkt.stream_index= st->index;
002c01a6 372 pkt.data= (uint8_t *)picture;
e928649b 373 pkt.size= sizeof(AVPicture);
115329f1 374
a6f925b8 375 ret = av_interleaved_write_frame(oc, &pkt);
e70fcf07
FB
376 } else {
377 /* encode the image */
002c01a6 378 out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
cb0c448a 379 /* if zero size, it means the image was buffered */
b5bc8591 380 if (out_size > 0) {
e928649b
MN
381 AVPacket pkt;
382 av_init_packet(&pkt);
115329f1 383
fb34e75d 384 if (c->coded_frame->pts != AV_NOPTS_VALUE)
817a3de9 385 pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
e928649b
MN
386 if(c->coded_frame->key_frame)
387 pkt.flags |= PKT_FLAG_KEY;
388 pkt.stream_index= st->index;
389 pkt.data= video_outbuf;
390 pkt.size= out_size;
115329f1 391
cb0c448a 392 /* write the compressed frame in the media file */
a6f925b8 393 ret = av_interleaved_write_frame(oc, &pkt);
cb0c448a
FB
394 } else {
395 ret = 0;
396 }
e70fcf07
FB
397 }
398 if (ret != 0) {
8de65d4f
FB
399 fprintf(stderr, "Error while writing video frame\n");
400 exit(1);
401 }
e70fcf07
FB
402 frame_count++;
403}
404
ceaf1909 405static void close_video(AVFormatContext *oc, AVStream *st)
e70fcf07 406{
01f4895c 407 avcodec_close(st->codec);
e70fcf07
FB
408 av_free(picture->data[0]);
409 av_free(picture);
410 if (tmp_picture) {
411 av_free(tmp_picture->data[0]);
412 av_free(tmp_picture);
413 }
414 av_free(video_outbuf);
8de65d4f
FB
415}
416
417/**************************************************************/
418/* media file output */
419
420int main(int argc, char **argv)
421{
422 const char *filename;
423 AVOutputFormat *fmt;
424 AVFormatContext *oc;
e70fcf07 425 AVStream *audio_st, *video_st;
8de65d4f 426 double audio_pts, video_pts;
e70fcf07
FB
427 int i;
428
8de65d4f
FB
429 /* initialize libavcodec, and register all codecs and formats */
430 av_register_all();
115329f1 431
8de65d4f
FB
432 if (argc != 2) {
433 printf("usage: %s output_file\n"
e70fcf07
FB
434 "API example program to output a media file with libavformat.\n"
435 "The output format is automatically guessed according to the file extension.\n"
436 "Raw images can also be output by using '%%d' in the filename\n"
8de65d4f
FB
437 "\n", argv[0]);
438 exit(1);
439 }
115329f1 440
8de65d4f
FB
441 filename = argv[1];
442
443 /* auto detect the output format from the name. default is
444 mpeg. */
445 fmt = guess_format(NULL, filename, NULL);
446 if (!fmt) {
447 printf("Could not deduce output format from file extension: using MPEG.\n");
448 fmt = guess_format("mpeg", NULL, NULL);
449 }
450 if (!fmt) {
451 fprintf(stderr, "Could not find suitable output format\n");
452 exit(1);
453 }
115329f1 454
8de65d4f 455 /* allocate the output media context */
8e2fd8e1 456 oc = avformat_alloc_context();
8de65d4f
FB
457 if (!oc) {
458 fprintf(stderr, "Memory error\n");
459 exit(1);
460 }
461 oc->oformat = fmt;
e70fcf07 462 snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
8de65d4f
FB
463
464 /* add the audio and video streams using the default format codecs
465 and initialize the codecs */
466 video_st = NULL;
467 audio_st = NULL;
468 if (fmt->video_codec != CODEC_ID_NONE) {
469 video_st = add_video_stream(oc, fmt->video_codec);
470 }
471 if (fmt->audio_codec != CODEC_ID_NONE) {
472 audio_st = add_audio_stream(oc, fmt->audio_codec);
473 }
474
e70fcf07
FB
475 /* set the output parameters (must be done even if no
476 parameters). */
477 if (av_set_parameters(oc, NULL) < 0) {
478 fprintf(stderr, "Invalid output format parameters\n");
479 exit(1);
480 }
481
8de65d4f
FB
482 dump_format(oc, 0, filename, 1);
483
e70fcf07
FB
484 /* now that all the parameters are set, we can open the audio and
485 video codecs and allocate the necessary encode buffers */
486 if (video_st)
487 open_video(oc, video_st);
488 if (audio_st)
489 open_audio(oc, audio_st);
490
8de65d4f
FB
491 /* open the output file, if needed */
492 if (!(fmt->flags & AVFMT_NOFILE)) {
493 if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
494 fprintf(stderr, "Could not open '%s'\n", filename);
495 exit(1);
496 }
497 }
115329f1 498
8de65d4f
FB
499 /* write the stream header, if any */
500 av_write_header(oc);
115329f1 501
8de65d4f
FB
502 for(;;) {
503 /* compute current audio and video time */
504 if (audio_st)
e06d3d55 505 audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
8de65d4f
FB
506 else
507 audio_pts = 0.0;
115329f1 508
8de65d4f 509 if (video_st)
e06d3d55 510 video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
8de65d4f
FB
511 else
512 video_pts = 0.0;
513
115329f1 514 if ((!audio_st || audio_pts >= STREAM_DURATION) &&
8de65d4f
FB
515 (!video_st || video_pts >= STREAM_DURATION))
516 break;
115329f1 517
8de65d4f 518 /* write interleaved audio and video frames */
e70fcf07 519 if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
8de65d4f
FB
520 write_audio_frame(oc, audio_st);
521 } else {
522 write_video_frame(oc, video_st);
523 }
524 }
525
de43a239
AC
526 /* write the trailer, if any. the trailer must be written
527 * before you close the CodecContexts open when you wrote the
528 * header; otherwise write_trailer may try to use memory that
529 * was freed on av_codec_close() */
530 av_write_trailer(oc);
531
8de65d4f 532 /* close each codec */
e70fcf07
FB
533 if (video_st)
534 close_video(oc, video_st);
535 if (audio_st)
536 close_audio(oc, audio_st);
8de65d4f 537
e70fcf07
FB
538 /* free the streams */
539 for(i = 0; i < oc->nb_streams; i++) {
8720de5b 540 av_freep(&oc->streams[i]->codec);
e70fcf07
FB
541 av_freep(&oc->streams[i]);
542 }
543
8de65d4f
FB
544 if (!(fmt->flags & AVFMT_NOFILE)) {
545 /* close the output file */
899681cd 546 url_fclose(oc->pb);
8de65d4f
FB
547 }
548
549 /* free the stream */
550 av_free(oc);
551
552 return 0;
553}