Statistics
| Branch: | Revision:

ffmpeg / output_example.c @ 470bce2b

History | View | Annotate | Download (16 KB)

1 8de65d4f Fabrice Bellard
/*
2
 * Libavformat API example: Output a media file in any supported
3
 * libavformat format. The default codecs are used.
4 115329f1 Diego Biurrun
 *
5 8de65d4f Fabrice Bellard
 * Copyright (c) 2003 Fabrice Bellard
6 115329f1 Diego Biurrun
 *
7 8de65d4f Fabrice Bellard
 * 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:
13 115329f1 Diego Biurrun
 *
14 8de65d4f Fabrice Bellard
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16 115329f1 Diego Biurrun
 *
17 8de65d4f Fabrice Bellard
 * 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
23 115329f1 Diego Biurrun
 * THE SOFTWARE.
24 8de65d4f Fabrice Bellard
 */
25
#include <stdlib.h>
26
#include <stdio.h>
27 af547ce5 Michael Niedermayer
#include <string.h>
28 8de65d4f Fabrice Bellard
#include <math.h>
29
30 264cb2b8 Michael Niedermayer
#ifndef M_PI
31 a40de112 Panagiotis Issaris
#define M_PI 3.14159265358979323846
32 264cb2b8 Michael Niedermayer
#endif
33
34 245976da Diego Biurrun
#include "libavformat/avformat.h"
35
#include "libswscale/swscale.h"
36 8de65d4f Fabrice Bellard
37 364a9607 Diego Biurrun
#undef exit
38
39 8de65d4f Fabrice Bellard
/* 5 seconds stream duration */
40 cb0c448a Fabrice Bellard
#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))
43 002c01a6 Andreas Öman
#define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
44 8de65d4f Fabrice Bellard
45 03ae87a3 Luca Abeni
static int sws_flags = SWS_BICUBIC;
46
47 8de65d4f Fabrice Bellard
/**************************************************************/
48
/* audio output */
49
50 e70fcf07 Fabrice Bellard
float t, tincr, tincr2;
51 8de65d4f Fabrice Bellard
int16_t *samples;
52
uint8_t *audio_outbuf;
53
int audio_outbuf_size;
54
int audio_input_frame_size;
55
56 115329f1 Diego Biurrun
/*
57 8de65d4f Fabrice Bellard
 * add an audio output stream
58
 */
59 ceaf1909 Dieter
static AVStream *add_audio_stream(AVFormatContext *oc, int codec_id)
60 8de65d4f Fabrice Bellard
{
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
70 01f4895c Michael Niedermayer
    c = st->codec;
71 e70fcf07 Fabrice Bellard
    c->codec_id = codec_id;
72 8de65d4f Fabrice Bellard
    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;
78 e70fcf07 Fabrice Bellard
    return st;
79
}
80
81 ceaf1909 Dieter
static void open_audio(AVFormatContext *oc, AVStream *st)
82 e70fcf07 Fabrice Bellard
{
83
    AVCodecContext *c;
84
    AVCodec *codec;
85
86 01f4895c Michael Niedermayer
    c = st->codec;
87 e70fcf07 Fabrice Bellard
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
    }
94 8de65d4f Fabrice Bellard
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;
103 e70fcf07 Fabrice Bellard
    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;
106 8de65d4f Fabrice Bellard
107
    audio_outbuf_size = 10000;
108 5d915e82 Ramiro Polla
    audio_outbuf = av_malloc(audio_outbuf_size);
109 8de65d4f Fabrice Bellard
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;
114 01f4895c Michael Niedermayer
        switch(st->codec->codec_id) {
115 8de65d4f Fabrice Bellard
        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
    }
127 5d915e82 Ramiro Polla
    samples = av_malloc(audio_input_frame_size * 2 * c->channels);
128 8de65d4f Fabrice Bellard
}
129
130 cb750e33 Fabrice Bellard
/* prepare a 16 bit dummy audio frame of 'frame_size' samples and
131
   'nb_channels' channels */
132 ceaf1909 Dieter
static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
133 cb750e33 Fabrice Bellard
{
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
147 ceaf1909 Dieter
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
148 8de65d4f Fabrice Bellard
{
149
    AVCodecContext *c;
150 e928649b Michael Niedermayer
    AVPacket pkt;
151
    av_init_packet(&pkt);
152 115329f1 Diego Biurrun
153 01f4895c Michael Niedermayer
    c = st->codec;
154 8de65d4f Fabrice Bellard
155 cb750e33 Fabrice Bellard
    get_audio_frame(samples, audio_input_frame_size, c->channels);
156
157 e928649b Michael Niedermayer
    pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
158
159 fb34e75d Luca Abeni
    if (c->coded_frame->pts != AV_NOPTS_VALUE)
160 817a3de9 Luca Abeni
        pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
161 e928649b Michael Niedermayer
    pkt.flags |= PKT_FLAG_KEY;
162
    pkt.stream_index= st->index;
163
    pkt.data= audio_outbuf;
164 8de65d4f Fabrice Bellard
165
    /* write the compressed frame in the media file */
166 e928649b Michael Niedermayer
    if (av_write_frame(oc, &pkt) != 0) {
167 8de65d4f Fabrice Bellard
        fprintf(stderr, "Error while writing audio frame\n");
168
        exit(1);
169
    }
170
}
171
172 ceaf1909 Dieter
static void close_audio(AVFormatContext *oc, AVStream *st)
173 e70fcf07 Fabrice Bellard
{
174 01f4895c Michael Niedermayer
    avcodec_close(st->codec);
175 115329f1 Diego Biurrun
176 e70fcf07 Fabrice Bellard
    av_free(samples);
177
    av_free(audio_outbuf);
178
}
179
180 8de65d4f Fabrice Bellard
/**************************************************************/
181
/* video output */
182
183 e70fcf07 Fabrice Bellard
AVFrame *picture, *tmp_picture;
184 8de65d4f Fabrice Bellard
uint8_t *video_outbuf;
185
int frame_count, video_outbuf_size;
186
187
/* add a video output stream */
188 ceaf1909 Dieter
static AVStream *add_video_stream(AVFormatContext *oc, int codec_id)
189 8de65d4f Fabrice Bellard
{
190
    AVCodecContext *c;
191
    AVStream *st;
192
193
    st = av_new_stream(oc, 0);
194
    if (!st) {
195
        fprintf(stderr, "Could not alloc stream\n");
196
        exit(1);
197
    }
198 115329f1 Diego Biurrun
199 01f4895c Michael Niedermayer
    c = st->codec;
200 e70fcf07 Fabrice Bellard
    c->codec_id = codec_id;
201 8de65d4f Fabrice Bellard
    c->codec_type = CODEC_TYPE_VIDEO;
202
203
    /* put sample parameters */
204
    c->bit_rate = 400000;
205
    /* resolution must be a multiple of two */
206 115329f1 Diego Biurrun
    c->width = 352;
207 8de65d4f Fabrice Bellard
    c->height = 288;
208 5b28c8c3 Michael Niedermayer
    /* 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. */
212 115329f1 Diego Biurrun
    c->time_base.den = STREAM_FRAME_RATE;
213 c0df9d75 Michael Niedermayer
    c->time_base.num = 1;
214 cb0c448a Fabrice Bellard
    c->gop_size = 12; /* emit one intra frame every twelve frames at most */
215 002c01a6 Andreas Öman
    c->pix_fmt = STREAM_PIX_FMT;
216 85e33747 Michael Niedermayer
    if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
217 cb0c448a Fabrice Bellard
        /* just for testing, we also add B frames */
218
        c->max_b_frames = 2;
219
    }
220 85e33747 Michael Niedermayer
    if (c->codec_id == CODEC_ID_MPEG1VIDEO){
221 755bfeab Diego Biurrun
        /* 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. */
224 85e33747 Michael Niedermayer
        c->mb_decision=2;
225
    }
226 0afd2a92 Diego Biurrun
    // some formats want stream headers to be separate
227 af547ce5 Michael Niedermayer
    if(!strcmp(oc->oformat->name, "mp4") || !strcmp(oc->oformat->name, "mov") || !strcmp(oc->oformat->name, "3gp"))
228
        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
229 115329f1 Diego Biurrun
230 e70fcf07 Fabrice Bellard
    return st;
231
}
232
233 ceaf1909 Dieter
static AVFrame *alloc_picture(int pix_fmt, int width, int height)
234 e70fcf07 Fabrice Bellard
{
235
    AVFrame *picture;
236
    uint8_t *picture_buf;
237
    int size;
238 115329f1 Diego Biurrun
239 e70fcf07 Fabrice Bellard
    picture = avcodec_alloc_frame();
240
    if (!picture)
241
        return NULL;
242
    size = avpicture_get_size(pix_fmt, width, height);
243 5d915e82 Ramiro Polla
    picture_buf = av_malloc(size);
244 e70fcf07 Fabrice Bellard
    if (!picture_buf) {
245
        av_free(picture);
246
        return NULL;
247
    }
248 115329f1 Diego Biurrun
    avpicture_fill((AVPicture *)picture, picture_buf,
249 e70fcf07 Fabrice Bellard
                   pix_fmt, width, height);
250
    return picture;
251
}
252 115329f1 Diego Biurrun
253 ceaf1909 Dieter
static void open_video(AVFormatContext *oc, AVStream *st)
254 e70fcf07 Fabrice Bellard
{
255
    AVCodec *codec;
256
    AVCodecContext *c;
257
258 01f4895c Michael Niedermayer
    c = st->codec;
259 e70fcf07 Fabrice Bellard
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 */
268 8de65d4f Fabrice Bellard
    if (avcodec_open(c, codec) < 0) {
269
        fprintf(stderr, "could not open codec\n");
270
        exit(1);
271
    }
272
273 e70fcf07 Fabrice Bellard
    video_outbuf = NULL;
274
    if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
275
        /* allocate output buffer */
276
        /* XXX: API change will be done */
277 5d915e82 Ramiro Polla
        /* 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) */
281 e70fcf07 Fabrice Bellard
        video_outbuf_size = 200000;
282 5d915e82 Ramiro Polla
        video_outbuf = av_malloc(video_outbuf_size);
283 e70fcf07 Fabrice Bellard
    }
284 8de65d4f Fabrice Bellard
285 e70fcf07 Fabrice Bellard
    /* 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
    }
291 8de65d4f Fabrice Bellard
292 e70fcf07 Fabrice Bellard
    /* 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
}
304 8de65d4f Fabrice Bellard
305 e70fcf07 Fabrice Bellard
/* prepare a dummy image */
306 ceaf1909 Dieter
static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
307 8de65d4f Fabrice Bellard
{
308 e70fcf07 Fabrice Bellard
    int x, y, i;
309
310
    i = frame_index;
311 8de65d4f Fabrice Bellard
312
    /* Y */
313 e70fcf07 Fabrice Bellard
    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;
316 8de65d4f Fabrice Bellard
        }
317
    }
318 115329f1 Diego Biurrun
319 8de65d4f Fabrice Bellard
    /* Cb and Cr */
320 e70fcf07 Fabrice Bellard
    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;
324 8de65d4f Fabrice Bellard
        }
325
    }
326 e70fcf07 Fabrice Bellard
}
327 8de65d4f Fabrice Bellard
328 ceaf1909 Dieter
static void write_video_frame(AVFormatContext *oc, AVStream *st)
329 e70fcf07 Fabrice Bellard
{
330
    int out_size, ret;
331
    AVCodecContext *c;
332 03ae87a3 Luca Abeni
    static struct SwsContext *img_convert_ctx;
333 115329f1 Diego Biurrun
334 01f4895c Michael Niedermayer
    c = st->codec;
335 115329f1 Diego Biurrun
336 cb0c448a Fabrice Bellard
    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
339 002c01a6 Andreas Öman
           passing the same picture again */
340 e70fcf07 Fabrice Bellard
    } else {
341 cb0c448a Fabrice Bellard
        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 */
344 03ae87a3 Luca Abeni
            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
            }
355 cb0c448a Fabrice Bellard
            fill_yuv_image(tmp_picture, frame_count, c->width, c->height);
356 03ae87a3 Luca Abeni
            sws_scale(img_convert_ctx, tmp_picture->data, tmp_picture->linesize,
357
                      0, c->height, picture->data, picture->linesize);
358 cb0c448a Fabrice Bellard
        } else {
359
            fill_yuv_image(picture, frame_count, c->width, c->height);
360
        }
361 e70fcf07 Fabrice Bellard
    }
362
363 115329f1 Diego Biurrun
364 e70fcf07 Fabrice Bellard
    if (oc->oformat->flags & AVFMT_RAWPICTURE) {
365
        /* raw video case. The API will change slightly in the near
366
           futur for that */
367 e928649b Michael Niedermayer
        AVPacket pkt;
368
        av_init_packet(&pkt);
369 115329f1 Diego Biurrun
370 e928649b Michael Niedermayer
        pkt.flags |= PKT_FLAG_KEY;
371
        pkt.stream_index= st->index;
372 002c01a6 Andreas Öman
        pkt.data= (uint8_t *)picture;
373 e928649b Michael Niedermayer
        pkt.size= sizeof(AVPicture);
374 115329f1 Diego Biurrun
375 e928649b Michael Niedermayer
        ret = av_write_frame(oc, &pkt);
376 e70fcf07 Fabrice Bellard
    } else {
377
        /* encode the image */
378 002c01a6 Andreas Öman
        out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
379 cb0c448a Fabrice Bellard
        /* if zero size, it means the image was buffered */
380 b5bc8591 Michael Niedermayer
        if (out_size > 0) {
381 e928649b Michael Niedermayer
            AVPacket pkt;
382
            av_init_packet(&pkt);
383 115329f1 Diego Biurrun
384 fb34e75d Luca Abeni
            if (c->coded_frame->pts != AV_NOPTS_VALUE)
385 817a3de9 Luca Abeni
                pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
386 e928649b Michael Niedermayer
            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;
391 115329f1 Diego Biurrun
392 cb0c448a Fabrice Bellard
            /* write the compressed frame in the media file */
393 e928649b Michael Niedermayer
            ret = av_write_frame(oc, &pkt);
394 cb0c448a Fabrice Bellard
        } else {
395
            ret = 0;
396
        }
397 e70fcf07 Fabrice Bellard
    }
398
    if (ret != 0) {
399 8de65d4f Fabrice Bellard
        fprintf(stderr, "Error while writing video frame\n");
400
        exit(1);
401
    }
402 e70fcf07 Fabrice Bellard
    frame_count++;
403
}
404
405 ceaf1909 Dieter
static void close_video(AVFormatContext *oc, AVStream *st)
406 e70fcf07 Fabrice Bellard
{
407 01f4895c Michael Niedermayer
    avcodec_close(st->codec);
408 e70fcf07 Fabrice Bellard
    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);
415 8de65d4f Fabrice Bellard
}
416
417
/**************************************************************/
418
/* media file output */
419
420
int main(int argc, char **argv)
421
{
422
    const char *filename;
423
    AVOutputFormat *fmt;
424
    AVFormatContext *oc;
425 e70fcf07 Fabrice Bellard
    AVStream *audio_st, *video_st;
426 8de65d4f Fabrice Bellard
    double audio_pts, video_pts;
427 e70fcf07 Fabrice Bellard
    int i;
428
429 8de65d4f Fabrice Bellard
    /* initialize libavcodec, and register all codecs and formats */
430
    av_register_all();
431 115329f1 Diego Biurrun
432 8de65d4f Fabrice Bellard
    if (argc != 2) {
433
        printf("usage: %s output_file\n"
434 e70fcf07 Fabrice Bellard
               "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"
437 8de65d4f Fabrice Bellard
               "\n", argv[0]);
438
        exit(1);
439
    }
440 115329f1 Diego Biurrun
441 8de65d4f Fabrice Bellard
    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
    }
454 115329f1 Diego Biurrun
455 8de65d4f Fabrice Bellard
    /* allocate the output media context */
456 bc874dae Michel Bardiaux
    oc = av_alloc_format_context();
457 8de65d4f Fabrice Bellard
    if (!oc) {
458
        fprintf(stderr, "Memory error\n");
459
        exit(1);
460
    }
461
    oc->oformat = fmt;
462 e70fcf07 Fabrice Bellard
    snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
463 8de65d4f Fabrice Bellard
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
475 e70fcf07 Fabrice Bellard
    /* 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
482 8de65d4f Fabrice Bellard
    dump_format(oc, 0, filename, 1);
483
484 e70fcf07 Fabrice Bellard
    /* 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
491 8de65d4f Fabrice Bellard
    /* 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
    }
498 115329f1 Diego Biurrun
499 8de65d4f Fabrice Bellard
    /* write the stream header, if any */
500
    av_write_header(oc);
501 115329f1 Diego Biurrun
502 8de65d4f Fabrice Bellard
    for(;;) {
503
        /* compute current audio and video time */
504
        if (audio_st)
505 e06d3d55 Michael Niedermayer
            audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
506 8de65d4f Fabrice Bellard
        else
507
            audio_pts = 0.0;
508 115329f1 Diego Biurrun
509 8de65d4f Fabrice Bellard
        if (video_st)
510 e06d3d55 Michael Niedermayer
            video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
511 8de65d4f Fabrice Bellard
        else
512
            video_pts = 0.0;
513
514 115329f1 Diego Biurrun
        if ((!audio_st || audio_pts >= STREAM_DURATION) &&
515 8de65d4f Fabrice Bellard
            (!video_st || video_pts >= STREAM_DURATION))
516
            break;
517 115329f1 Diego Biurrun
518 8de65d4f Fabrice Bellard
        /* write interleaved audio and video frames */
519 e70fcf07 Fabrice Bellard
        if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
520 8de65d4f Fabrice Bellard
            write_audio_frame(oc, audio_st);
521
        } else {
522
            write_video_frame(oc, video_st);
523
        }
524
    }
525
526
    /* close each codec */
527 e70fcf07 Fabrice Bellard
    if (video_st)
528
        close_video(oc, video_st);
529
    if (audio_st)
530
        close_audio(oc, audio_st);
531 8de65d4f Fabrice Bellard
532
    /* write the trailer, if any */
533
    av_write_trailer(oc);
534 115329f1 Diego Biurrun
535 e70fcf07 Fabrice Bellard
    /* free the streams */
536
    for(i = 0; i < oc->nb_streams; i++) {
537 8720de5b Michael Niedermayer
        av_freep(&oc->streams[i]->codec);
538 e70fcf07 Fabrice Bellard
        av_freep(&oc->streams[i]);
539
    }
540
541 8de65d4f Fabrice Bellard
    if (!(fmt->flags & AVFMT_NOFILE)) {
542
        /* close the output file */
543 899681cd Björn Axelsson
        url_fclose(oc->pb);
544 8de65d4f Fabrice Bellard
    }
545
546
    /* free the stream */
547
    av_free(oc);
548
549
    return 0;
550
}