]> git.sesse.net Git - ffmpeg/blob - doc/examples/muxing.c
Merge commit 'a7fcd4122b19b0f934020f4e261d0c44c4c32e11'
[ffmpeg] / doc / examples / muxing.c
1 /*
2  * Copyright (c) 2003 Fabrice Bellard
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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
20  * THE SOFTWARE.
21  */
22
23 /**
24  * @file
25  * libavformat API example.
26  *
27  * Output a media file in any supported libavformat format. The default
28  * codecs are used.
29  * @example muxing.c
30  */
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <math.h>
36
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>
45
46 static int audio_is_eof, video_is_eof;
47
48 #define STREAM_DURATION   10.0
49 #define STREAM_FRAME_RATE 25 /* 25 images/s */
50 #define STREAM_PIX_FMT    AV_PIX_FMT_YUV420P /* default pix_fmt */
51
52 #define SCALE_FLAGS SWS_BICUBIC
53
54 // a wrapper around a single output AVStream
55 typedef struct OutputStream {
56     AVStream *st;
57
58     AVFrame *frame;
59     AVFrame *tmp_frame;
60
61     float t, tincr, tincr2;
62
63     struct SwsContext *sws_ctx;
64 } OutputStream;
65
66 static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
67 {
68     AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
69
70     printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
71            av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
72            av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
73            av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
74            pkt->stream_index);
75 }
76
77 static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
78 {
79     /* rescale output packet timestamp values from codec to stream timebase */
80     av_packet_rescale_ts(pkt, *time_base, st->time_base);
81     pkt->stream_index = st->index;
82
83     /* Write the compressed frame to the media file. */
84     log_packet(fmt_ctx, pkt);
85     return av_interleaved_write_frame(fmt_ctx, pkt);
86 }
87
88 /* Add an output stream. */
89 static void add_stream(OutputStream *ost, AVFormatContext *oc,
90                        AVCodec **codec,
91                        enum AVCodecID codec_id)
92 {
93     AVCodecContext *c;
94
95     /* find the encoder */
96     *codec = avcodec_find_encoder(codec_id);
97     if (!(*codec)) {
98         fprintf(stderr, "Could not find encoder for '%s'\n",
99                 avcodec_get_name(codec_id));
100         exit(1);
101     }
102
103     ost->st = avformat_new_stream(oc, *codec);
104     if (!ost->st) {
105         fprintf(stderr, "Could not allocate stream\n");
106         exit(1);
107     }
108     ost->st->id = oc->nb_streams-1;
109     c = ost->st->codec;
110
111     switch ((*codec)->type) {
112     case AVMEDIA_TYPE_AUDIO:
113         c->sample_fmt  = (*codec)->sample_fmts ?
114             (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
115         c->bit_rate    = 64000;
116         c->sample_rate = 44100;
117         c->channels    = 2;
118         c->channel_layout = AV_CH_LAYOUT_STEREO;
119         break;
120
121     case AVMEDIA_TYPE_VIDEO:
122         c->codec_id = codec_id;
123
124         c->bit_rate = 400000;
125         /* Resolution must be a multiple of two. */
126         c->width    = 352;
127         c->height   = 288;
128         /* timebase: This is the fundamental unit of time (in seconds) in terms
129          * of which frame timestamps are represented. For fixed-fps content,
130          * timebase should be 1/framerate and timestamp increments should be
131          * identical to 1. */
132         c->time_base.den = STREAM_FRAME_RATE;
133         c->time_base.num = 1;
134         c->gop_size      = 12; /* emit one intra frame every twelve frames at most */
135         c->pix_fmt       = STREAM_PIX_FMT;
136         if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
137             /* just for testing, we also add B frames */
138             c->max_b_frames = 2;
139         }
140         if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
141             /* Needed to avoid using macroblocks in which some coeffs overflow.
142              * This does not happen with normal video, it just happens here as
143              * the motion of the chroma plane does not match the luma plane. */
144             c->mb_decision = 2;
145         }
146     break;
147
148     default:
149         break;
150     }
151
152     /* Some formats want stream headers to be separate. */
153     if (oc->oformat->flags & AVFMT_GLOBALHEADER)
154         c->flags |= CODEC_FLAG_GLOBAL_HEADER;
155 }
156
157 /**************************************************************/
158 /* audio output */
159
160 int samples_count;
161
162 struct SwrContext *swr_ctx = NULL;
163
164 static void open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost)
165 {
166     AVCodecContext *c;
167     int ret;
168
169     c = ost->st->codec;
170
171     /* open it */
172     ret = avcodec_open2(c, codec, NULL);
173     if (ret < 0) {
174         fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
175         exit(1);
176     }
177
178     /* init signal generator */
179     ost->t     = 0;
180     ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
181     /* increment frequency by 110 Hz per second */
182     ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
183
184     ost->frame = av_frame_alloc();
185     if (!ost->frame)
186         exit(1);
187
188     ost->frame->sample_rate    = c->sample_rate;
189     ost->frame->format         = AV_SAMPLE_FMT_S16;
190     ost->frame->channel_layout = c->channel_layout;
191
192     if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
193         ost->frame->nb_samples = 10000;
194     else
195         ost->frame->nb_samples = c->frame_size;
196
197     ost->tmp_frame = av_frame_alloc();
198     if (!ost->frame)
199         exit(1);
200
201     ost->tmp_frame->sample_rate    = c->sample_rate;
202     ost->tmp_frame->format         = c->sample_fmt;
203     ost->tmp_frame->channel_layout = c->channel_layout;
204     ost->tmp_frame->nb_samples     = ost->frame->nb_samples;
205
206     /* create resampler context */
207     if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
208         swr_ctx = swr_alloc();
209         if (!swr_ctx) {
210             fprintf(stderr, "Could not allocate resampler context\n");
211             exit(1);
212         }
213
214         /* set options */
215         av_opt_set_int       (swr_ctx, "in_channel_count",   c->channels,       0);
216         av_opt_set_int       (swr_ctx, "in_sample_rate",     c->sample_rate,    0);
217         av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt",      AV_SAMPLE_FMT_S16, 0);
218         av_opt_set_int       (swr_ctx, "out_channel_count",  c->channels,       0);
219         av_opt_set_int       (swr_ctx, "out_sample_rate",    c->sample_rate,    0);
220         av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt",     c->sample_fmt,     0);
221
222         /* initialize the resampling context */
223         if ((ret = swr_init(swr_ctx)) < 0) {
224             fprintf(stderr, "Failed to initialize the resampling context\n");
225             exit(1);
226         }
227     }
228
229     ret = av_frame_get_buffer(ost->frame, 0);
230     if (ret < 0) {
231         fprintf(stderr, "Could not allocate an audio frame.\n");
232         exit(1);
233     }
234     ret = av_frame_get_buffer(ost->tmp_frame, 0);
235     if (ret < 0) {
236         fprintf(stderr, "Could not allocate an audio frame.\n");
237         exit(1);
238     }
239 }
240
241 /* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
242  * 'nb_channels' channels. */
243 static void get_audio_frame(OutputStream *ost, AVFrame *frame, int nb_channels)
244 {
245     int j, i, v, ret;
246     int16_t *q = (int16_t*)frame->data[0];
247
248     /* when we pass a frame to the encoder, it may keep a reference to it
249      * internally;
250      * make sure we do not overwrite it here
251      */
252     ret = av_frame_make_writable(frame);
253     if (ret < 0)
254         exit(1);
255
256     for (j = 0; j < frame->nb_samples; j++) {
257         v = (int)(sin(ost->t) * 10000);
258         for (i = 0; i < nb_channels; i++)
259             *q++ = v;
260         ost->t     += ost->tincr;
261         ost->tincr += ost->tincr2;
262     }
263 }
264
265 static void write_audio_frame(AVFormatContext *oc, OutputStream *ost, int flush)
266 {
267     AVCodecContext *c;
268     AVPacket pkt = { 0 }; // data and size must be 0;
269     int got_packet, ret;
270     int dst_nb_samples;
271     AVFrame *frame;
272
273     av_init_packet(&pkt);
274     c = ost->st->codec;
275
276     if (!flush) {
277         get_audio_frame(ost, ost->frame, c->channels);
278
279         /* convert samples from native format to destination codec format, using the resampler */
280         if (swr_ctx) {
281             /* compute destination number of samples */
282             dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, c->sample_rate) + ost->frame->nb_samples,
283                                             c->sample_rate, c->sample_rate, AV_ROUND_UP);
284             av_assert0(dst_nb_samples == ost->frame->nb_samples);
285
286             /* convert to destination format */
287             ret = swr_convert(swr_ctx,
288                               ost->tmp_frame->data, dst_nb_samples,
289                               (const uint8_t **)ost->frame->data, ost->frame->nb_samples);
290             if (ret < 0) {
291                 fprintf(stderr, "Error while converting\n");
292                 exit(1);
293             }
294             frame = ost->tmp_frame;
295         } else {
296             dst_nb_samples = ost->frame->nb_samples;
297             frame = ost->frame;
298         }
299
300         frame->pts = av_rescale_q(samples_count, (AVRational){1, c->sample_rate}, c->time_base);
301         samples_count += dst_nb_samples;
302     }
303
304     ret = avcodec_encode_audio2(c, &pkt, flush ? NULL : frame, &got_packet);
305     if (ret < 0) {
306         fprintf(stderr, "Error encoding audio frame: %s\n", av_err2str(ret));
307         exit(1);
308     }
309
310     if (!got_packet) {
311         if (flush)
312             audio_is_eof = 1;
313
314         return;
315     }
316
317     ret = write_frame(oc, &c->time_base, ost->st, &pkt);
318     if (ret < 0) {
319         fprintf(stderr, "Error while writing audio frame: %s\n",
320                 av_err2str(ret));
321         exit(1);
322     }
323 }
324
325 /**************************************************************/
326 /* video output */
327
328 static int frame_count;
329
330 static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
331 {
332     AVFrame *picture;
333     int ret;
334
335     picture = av_frame_alloc();
336     if (!picture)
337         return NULL;
338
339     picture->format = pix_fmt;
340     picture->width  = width;
341     picture->height = height;
342
343     /* allocate the buffers for the frame data */
344     ret = av_frame_get_buffer(picture, 32);
345     if (ret < 0) {
346         fprintf(stderr, "Could not allocate frame data.\n");
347         exit(1);
348     }
349
350     return picture;
351 }
352
353 static void open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost)
354 {
355     int ret;
356     AVCodecContext *c = ost->st->codec;
357
358     /* open the codec */
359     ret = avcodec_open2(c, codec, NULL);
360     if (ret < 0) {
361         fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
362         exit(1);
363     }
364
365     /* allocate and init a re-usable frame */
366     ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
367     if (!ost->frame) {
368         fprintf(stderr, "Could not allocate video frame\n");
369         exit(1);
370     }
371
372     /* If the output format is not YUV420P, then a temporary YUV420P
373      * picture is needed too. It is then converted to the required
374      * output format. */
375     ost->tmp_frame = NULL;
376     if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
377         ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
378         if (!ost->tmp_frame) {
379             fprintf(stderr, "Could not allocate temporary picture\n");
380             exit(1);
381         }
382     }
383 }
384
385 /* Prepare a dummy image. */
386 static void fill_yuv_image(AVFrame *pict, int frame_index,
387                            int width, int height)
388 {
389     int x, y, i, ret;
390
391     /* when we pass a frame to the encoder, it may keep a reference to it
392      * internally;
393      * make sure we do not overwrite it here
394      */
395     ret = av_frame_make_writable(pict);
396     if (ret < 0)
397         exit(1);
398
399     i = frame_index;
400
401     /* Y */
402     for (y = 0; y < height; y++)
403         for (x = 0; x < width; x++)
404             pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
405
406     /* Cb and Cr */
407     for (y = 0; y < height / 2; y++) {
408         for (x = 0; x < width / 2; x++) {
409             pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
410             pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
411         }
412     }
413 }
414
415 static void write_video_frame(AVFormatContext *oc, OutputStream *ost, int flush)
416 {
417     int ret;
418     AVCodecContext *c = ost->st->codec;
419
420     if (!flush) {
421         if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
422             /* as we only generate a YUV420P picture, we must convert it
423              * to the codec pixel format if needed */
424             if (!ost->sws_ctx) {
425                 ost->sws_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_YUV420P,
426                                               c->width, c->height,
427                                               c->pix_fmt,
428                                               SCALE_FLAGS, NULL, NULL, NULL);
429                 if (!ost->sws_ctx) {
430                     fprintf(stderr,
431                             "Could not initialize the conversion context\n");
432                     exit(1);
433                 }
434             }
435             fill_yuv_image(ost->tmp_frame, frame_count, c->width, c->height);
436             sws_scale(ost->sws_ctx,
437                       (const uint8_t * const *)ost->tmp_frame->data, ost->tmp_frame->linesize,
438                       0, c->height, ost->frame->data, ost->frame->linesize);
439         } else {
440             fill_yuv_image(ost->frame, frame_count, c->width, c->height);
441         }
442     }
443
444     if (oc->oformat->flags & AVFMT_RAWPICTURE && !flush) {
445         /* Raw video case - directly store the picture in the packet */
446         AVPacket pkt;
447         av_init_packet(&pkt);
448
449         pkt.flags        |= AV_PKT_FLAG_KEY;
450         pkt.stream_index  = ost->st->index;
451         pkt.data          = (uint8_t *)ost->frame;
452         pkt.size          = sizeof(AVPicture);
453
454         ret = av_interleaved_write_frame(oc, &pkt);
455     } else {
456         AVPacket pkt = { 0 };
457         int got_packet;
458         av_init_packet(&pkt);
459
460         /* encode the image */
461         ost->frame->pts = frame_count;
462         ret = avcodec_encode_video2(c, &pkt, flush ? NULL : ost->frame, &got_packet);
463         if (ret < 0) {
464             fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
465             exit(1);
466         }
467         /* If size is zero, it means the image was buffered. */
468
469         if (got_packet) {
470             ret = write_frame(oc, &c->time_base, ost->st, &pkt);
471         } else {
472             if (flush)
473                 video_is_eof = 1;
474             ret = 0;
475         }
476     }
477
478     if (ret < 0) {
479         fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
480         exit(1);
481     }
482     frame_count++;
483 }
484
485 static void close_stream(AVFormatContext *oc, OutputStream *ost)
486 {
487     avcodec_close(ost->st->codec);
488     av_frame_free(&ost->frame);
489     av_frame_free(&ost->tmp_frame);
490     sws_freeContext(ost->sws_ctx);
491 }
492
493 /**************************************************************/
494 /* media file output */
495
496 int main(int argc, char **argv)
497 {
498     OutputStream video_st = { 0 }, audio_st = { 0 };
499     const char *filename;
500     AVOutputFormat *fmt;
501     AVFormatContext *oc;
502     AVCodec *audio_codec, *video_codec;
503     double audio_time, video_time;
504     int flush, ret;
505     int have_video = 0, have_audio = 0;
506
507     /* Initialize libavcodec, and register all codecs and formats. */
508     av_register_all();
509
510     if (argc != 2) {
511         printf("usage: %s output_file\n"
512                "API example program to output a media file with libavformat.\n"
513                "This program generates a synthetic audio and video stream, encodes and\n"
514                "muxes them into a file named output_file.\n"
515                "The output format is automatically guessed according to the file extension.\n"
516                "Raw images can also be output by using '%%d' in the filename.\n"
517                "\n", argv[0]);
518         return 1;
519     }
520
521     filename = argv[1];
522
523     /* allocate the output media context */
524     avformat_alloc_output_context2(&oc, NULL, NULL, filename);
525     if (!oc) {
526         printf("Could not deduce output format from file extension: using MPEG.\n");
527         avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
528     }
529     if (!oc)
530         return 1;
531
532     fmt = oc->oformat;
533
534     /* Add the audio and video streams using the default format codecs
535      * and initialize the codecs. */
536     if (fmt->video_codec != AV_CODEC_ID_NONE) {
537         add_stream(&video_st, oc, &video_codec, fmt->video_codec);
538         have_video = 1;
539     }
540     if (fmt->audio_codec != AV_CODEC_ID_NONE) {
541         add_stream(&audio_st, oc, &audio_codec, fmt->audio_codec);
542         have_audio = 1;
543     }
544
545     /* Now that all the parameters are set, we can open the audio and
546      * video codecs and allocate the necessary encode buffers. */
547     if (have_video)
548         open_video(oc, video_codec, &video_st);
549
550     if (have_audio)
551         open_audio(oc, audio_codec, &audio_st);
552
553     av_dump_format(oc, 0, filename, 1);
554
555     /* open the output file, if needed */
556     if (!(fmt->flags & AVFMT_NOFILE)) {
557         ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
558         if (ret < 0) {
559             fprintf(stderr, "Could not open '%s': %s\n", filename,
560                     av_err2str(ret));
561             return 1;
562         }
563     }
564
565     /* Write the stream header, if any. */
566     ret = avformat_write_header(oc, NULL);
567     if (ret < 0) {
568         fprintf(stderr, "Error occurred when opening output file: %s\n",
569                 av_err2str(ret));
570         return 1;
571     }
572
573     flush = 0;
574     while ((have_video && !video_is_eof) || (have_audio && !audio_is_eof)) {
575         /* Compute current audio and video time. */
576         audio_time = (have_audio && !audio_is_eof) ? audio_st.st->pts.val * av_q2d(audio_st.st->time_base) : INFINITY;
577         video_time = (have_video && !video_is_eof) ? video_st.st->pts.val * av_q2d(video_st.st->time_base) : INFINITY;
578
579         if (!flush &&
580             (!have_audio || audio_time >= STREAM_DURATION) &&
581             (!have_video || video_time >= STREAM_DURATION)) {
582             flush = 1;
583         }
584
585         /* write interleaved audio and video frames */
586         if (have_audio && !audio_is_eof && audio_time <= video_time) {
587             write_audio_frame(oc, &audio_st, flush);
588         } else if (have_video && !video_is_eof && video_time < audio_time) {
589             write_video_frame(oc, &video_st, flush);
590         }
591     }
592
593     /* Write the trailer, if any. The trailer must be written before you
594      * close the CodecContexts open when you wrote the header; otherwise
595      * av_write_trailer() may try to use memory that was freed on
596      * av_codec_close(). */
597     av_write_trailer(oc);
598
599     /* Close each codec. */
600     if (have_video)
601         close_stream(oc, &video_st);
602     if (have_audio)
603         close_stream(oc, &audio_st);
604
605     if (!(fmt->flags & AVFMT_NOFILE))
606         /* Close the output file. */
607         avio_close(oc->pb);
608
609     /* free the stream */
610     avformat_free_context(oc);
611
612     return 0;
613 }