~ubuntu-branches/ubuntu/utopic/libav/utopic-proposed

« back to all changes in this revision

Viewing changes to doc/examples/output.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler, Reinhard Tartler, Rico Tzschichholz
  • Date: 2014-08-30 11:02:45 UTC
  • mfrom: (1.3.47 sid)
  • Revision ID: package-import@ubuntu.com-20140830110245-io3dg7q85wfr7125
Tags: 6:11~beta1-2
[ Reinhard Tartler ]
* Make libavcodec-dev depend on libavresample-dev

[ Rico Tzschichholz ]
* Some fixes and leftovers from soname bumps

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include <string.h>
35
35
#include <math.h>
36
36
 
 
37
#include "libavutil/channel_layout.h"
37
38
#include "libavutil/mathematics.h"
 
39
#include "libavutil/opt.h"
38
40
#include "libavformat/avformat.h"
 
41
#include "libavresample/avresample.h"
39
42
#include "libswscale/swscale.h"
40
43
 
41
44
/* 5 seconds stream duration */
44
47
#define STREAM_NB_FRAMES  ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
45
48
#define STREAM_PIX_FMT    AV_PIX_FMT_YUV420P /* default pix_fmt */
46
49
 
47
 
static int sws_flags = SWS_BICUBIC;
 
50
#define SCALE_FLAGS SWS_BICUBIC
 
51
 
 
52
// a wrapper around a single output AVStream
 
53
typedef struct OutputStream {
 
54
    AVStream *st;
 
55
 
 
56
    /* pts of the next frame that will be generated */
 
57
    int64_t next_pts;
 
58
 
 
59
    AVFrame *frame;
 
60
    AVFrame *tmp_frame;
 
61
 
 
62
    float t, tincr, tincr2;
 
63
 
 
64
    struct SwsContext *sws_ctx;
 
65
    AVAudioResampleContext *avr;
 
66
} OutputStream;
48
67
 
49
68
/**************************************************************/
50
69
/* audio output */
51
70
 
52
 
static float t, tincr, tincr2;
53
 
static int16_t *samples;
54
 
static int audio_input_frame_size;
55
 
 
56
71
/*
57
72
 * add an audio output stream
58
73
 */
59
 
static AVStream *add_audio_stream(AVFormatContext *oc, enum AVCodecID codec_id)
 
74
static void add_audio_stream(OutputStream *ost, AVFormatContext *oc,
 
75
                             enum AVCodecID codec_id)
60
76
{
61
77
    AVCodecContext *c;
62
 
    AVStream *st;
63
78
    AVCodec *codec;
 
79
    int ret;
64
80
 
65
81
    /* find the audio encoder */
66
82
    codec = avcodec_find_encoder(codec_id);
69
85
        exit(1);
70
86
    }
71
87
 
72
 
    st = avformat_new_stream(oc, codec);
73
 
    if (!st) {
 
88
    ost->st = avformat_new_stream(oc, codec);
 
89
    if (!ost->st) {
74
90
        fprintf(stderr, "Could not alloc stream\n");
75
91
        exit(1);
76
92
    }
77
93
 
78
 
    c = st->codec;
 
94
    c = ost->st->codec;
79
95
 
80
96
    /* put sample parameters */
81
 
    c->sample_fmt  = AV_SAMPLE_FMT_S16;
82
 
    c->bit_rate    = 64000;
83
 
    c->sample_rate = 44100;
84
 
    c->channels    = 2;
 
97
    c->sample_fmt     = codec->sample_fmts           ? codec->sample_fmts[0]           : AV_SAMPLE_FMT_S16;
 
98
    c->sample_rate    = codec->supported_samplerates ? codec->supported_samplerates[0] : 44100;
 
99
    c->channel_layout = codec->channel_layouts       ? codec->channel_layouts[0]       : AV_CH_LAYOUT_STEREO;
 
100
    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
 
101
    c->bit_rate       = 64000;
 
102
 
 
103
    ost->st->time_base = (AVRational){ 1, c->sample_rate };
85
104
 
86
105
    // some formats want stream headers to be separate
87
106
    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
88
107
        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
89
108
 
90
 
    return st;
91
 
}
92
 
 
93
 
static void open_audio(AVFormatContext *oc, AVStream *st)
 
109
    /* initialize sample format conversion;
 
110
     * to simplify the code, we always pass the data through lavr, even
 
111
     * if the encoder supports the generated format directly -- the price is
 
112
     * some extra data copying;
 
113
     */
 
114
    ost->avr = avresample_alloc_context();
 
115
    if (!ost->avr) {
 
116
        fprintf(stderr, "Error allocating the resampling context\n");
 
117
        exit(1);
 
118
    }
 
119
 
 
120
    av_opt_set_int(ost->avr, "in_sample_fmt",      AV_SAMPLE_FMT_S16,   0);
 
121
    av_opt_set_int(ost->avr, "in_sample_rate",     44100,               0);
 
122
    av_opt_set_int(ost->avr, "in_channel_layout",  AV_CH_LAYOUT_STEREO, 0);
 
123
    av_opt_set_int(ost->avr, "out_sample_fmt",     c->sample_fmt,       0);
 
124
    av_opt_set_int(ost->avr, "out_sample_rate",    c->sample_rate,      0);
 
125
    av_opt_set_int(ost->avr, "out_channel_layout", c->channel_layout,   0);
 
126
 
 
127
    ret = avresample_open(ost->avr);
 
128
    if (ret < 0) {
 
129
        fprintf(stderr, "Error opening the resampling context\n");
 
130
        exit(1);
 
131
    }
 
132
}
 
133
 
 
134
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
 
135
                                  uint64_t channel_layout,
 
136
                                  int sample_rate, int nb_samples)
 
137
{
 
138
    AVFrame *frame = av_frame_alloc();
 
139
    int ret;
 
140
 
 
141
    if (!frame) {
 
142
        fprintf(stderr, "Error allocating an audio frame\n");
 
143
        exit(1);
 
144
    }
 
145
 
 
146
    frame->format = sample_fmt;
 
147
    frame->channel_layout = channel_layout;
 
148
    frame->sample_rate = sample_rate;
 
149
    frame->nb_samples = nb_samples;
 
150
 
 
151
    if (nb_samples) {
 
152
        ret = av_frame_get_buffer(frame, 0);
 
153
        if (ret < 0) {
 
154
            fprintf(stderr, "Error allocating an audio buffer\n");
 
155
            exit(1);
 
156
        }
 
157
    }
 
158
 
 
159
    return frame;
 
160
}
 
161
 
 
162
static void open_audio(AVFormatContext *oc, OutputStream *ost)
94
163
{
95
164
    AVCodecContext *c;
 
165
    int nb_samples;
96
166
 
97
 
    c = st->codec;
 
167
    c = ost->st->codec;
98
168
 
99
169
    /* open it */
100
170
    if (avcodec_open2(c, NULL, NULL) < 0) {
103
173
    }
104
174
 
105
175
    /* init signal generator */
106
 
    t     = 0;
107
 
    tincr = 2 * M_PI * 110.0 / c->sample_rate;
 
176
    ost->t     = 0;
 
177
    ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
108
178
    /* increment frequency by 110 Hz per second */
109
 
    tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
 
179
    ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
110
180
 
111
181
    if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
112
 
        audio_input_frame_size = 10000;
 
182
        nb_samples = 10000;
113
183
    else
114
 
        audio_input_frame_size = c->frame_size;
115
 
    samples = av_malloc(audio_input_frame_size *
116
 
                        av_get_bytes_per_sample(c->sample_fmt) *
117
 
                        c->channels);
 
184
        nb_samples = c->frame_size;
 
185
 
 
186
    ost->frame     = alloc_audio_frame(c->sample_fmt, c->channel_layout,
 
187
                                       c->sample_rate, nb_samples);
 
188
    ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, AV_CH_LAYOUT_STEREO,
 
189
                                       44100, nb_samples);
118
190
}
119
191
 
120
192
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
121
193
 * 'nb_channels' channels. */
122
 
static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
 
194
static AVFrame *get_audio_frame(OutputStream *ost)
123
195
{
 
196
    AVFrame *frame = ost->tmp_frame;
124
197
    int j, i, v;
125
 
    int16_t *q;
126
 
 
127
 
    q = samples;
128
 
    for (j = 0; j < frame_size; j++) {
129
 
        v = (int)(sin(t) * 10000);
130
 
        for (i = 0; i < nb_channels; i++)
 
198
    int16_t *q = (int16_t*)frame->data[0];
 
199
 
 
200
    /* check if we want to generate more frames */
 
201
    if (av_compare_ts(ost->next_pts, ost->st->codec->time_base,
 
202
                      STREAM_DURATION, (AVRational){ 1, 1 }) >= 0)
 
203
        return NULL;
 
204
 
 
205
 
 
206
    for (j = 0; j < frame->nb_samples; j++) {
 
207
        v = (int)(sin(ost->t) * 10000);
 
208
        for (i = 0; i < ost->st->codec->channels; i++)
131
209
            *q++ = v;
132
 
        t     += tincr;
133
 
        tincr += tincr2;
 
210
        ost->t     += ost->tincr;
 
211
        ost->tincr += ost->tincr2;
134
212
    }
 
213
 
 
214
    return frame;
135
215
}
136
216
 
137
 
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
 
217
/* if a frame is provided, send it to the encoder, otherwise flush the encoder;
 
218
 * return 1 when encoding is finished, 0 otherwise
 
219
 */
 
220
static int encode_audio_frame(AVFormatContext *oc, OutputStream *ost,
 
221
                              AVFrame *frame)
138
222
{
139
 
    AVCodecContext *c;
140
223
    AVPacket pkt = { 0 }; // data and size must be 0;
141
 
    AVFrame *frame = av_frame_alloc();
142
224
    int got_packet;
143
225
 
144
226
    av_init_packet(&pkt);
145
 
    c = st->codec;
146
 
 
147
 
    get_audio_frame(samples, audio_input_frame_size, c->channels);
148
 
    frame->nb_samples = audio_input_frame_size;
149
 
    avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
150
 
                             (uint8_t *)samples,
151
 
                             audio_input_frame_size *
152
 
                             av_get_bytes_per_sample(c->sample_fmt) *
153
 
                             c->channels, 1);
154
 
 
155
 
    avcodec_encode_audio2(c, &pkt, frame, &got_packet);
156
 
    if (!got_packet)
157
 
        return;
158
 
 
159
 
    pkt.stream_index = st->index;
160
 
 
161
 
    /* Write the compressed frame to the media file. */
162
 
    if (av_interleaved_write_frame(oc, &pkt) != 0) {
163
 
        fprintf(stderr, "Error while writing audio frame\n");
164
 
        exit(1);
 
227
    avcodec_encode_audio2(ost->st->codec, &pkt, frame, &got_packet);
 
228
 
 
229
    if (got_packet) {
 
230
        pkt.stream_index = ost->st->index;
 
231
 
 
232
        av_packet_rescale_ts(&pkt, ost->st->codec->time_base, ost->st->time_base);
 
233
 
 
234
        /* Write the compressed frame to the media file. */
 
235
        if (av_interleaved_write_frame(oc, &pkt) != 0) {
 
236
            fprintf(stderr, "Error while writing audio frame\n");
 
237
            exit(1);
 
238
        }
165
239
    }
166
 
    av_frame_free(&frame);
 
240
 
 
241
    return (frame || got_packet) ? 0 : 1;
167
242
}
168
243
 
169
 
static void close_audio(AVFormatContext *oc, AVStream *st)
 
244
/*
 
245
 * encode one audio frame and send it to the muxer
 
246
 * return 1 when encoding is finished, 0 otherwise
 
247
 */
 
248
static int process_audio_stream(AVFormatContext *oc, OutputStream *ost)
170
249
{
171
 
    avcodec_close(st->codec);
172
 
 
173
 
    av_free(samples);
 
250
    AVFrame *frame;
 
251
    int got_output = 0;
 
252
    int ret;
 
253
 
 
254
    frame = get_audio_frame(ost);
 
255
    got_output |= !!frame;
 
256
 
 
257
    /* feed the data to lavr */
 
258
    if (frame) {
 
259
        ret = avresample_convert(ost->avr, NULL, 0, 0,
 
260
                                 frame->extended_data, frame->linesize[0],
 
261
                                 frame->nb_samples);
 
262
        if (ret < 0) {
 
263
            fprintf(stderr, "Error feeding audio data to the resampler\n");
 
264
            exit(1);
 
265
        }
 
266
    }
 
267
 
 
268
    while ((frame && avresample_available(ost->avr) >= ost->frame->nb_samples) ||
 
269
           (!frame && avresample_get_out_samples(ost->avr, 0))) {
 
270
        /* when we pass a frame to the encoder, it may keep a reference to it
 
271
         * internally;
 
272
         * make sure we do not overwrite it here
 
273
         */
 
274
        ret = av_frame_make_writable(ost->frame);
 
275
        if (ret < 0)
 
276
            exit(1);
 
277
 
 
278
        /* the difference between the two avresample calls here is that the
 
279
         * first one just reads the already converted data that is buffered in
 
280
         * the lavr output buffer, while the second one also flushes the
 
281
         * resampler */
 
282
        if (frame) {
 
283
            ret = avresample_read(ost->avr, ost->frame->extended_data,
 
284
                                  ost->frame->nb_samples);
 
285
        } else {
 
286
            ret = avresample_convert(ost->avr, ost->frame->extended_data,
 
287
                                     ost->frame->linesize[0], ost->frame->nb_samples,
 
288
                                     NULL, 0, 0);
 
289
        }
 
290
 
 
291
        if (ret < 0) {
 
292
            fprintf(stderr, "Error while resampling\n");
 
293
            exit(1);
 
294
        } else if (frame && ret != ost->frame->nb_samples) {
 
295
            fprintf(stderr, "Too few samples returned from lavr\n");
 
296
            exit(1);
 
297
        }
 
298
 
 
299
        ost->frame->nb_samples = ret;
 
300
 
 
301
        ost->frame->pts        = ost->next_pts;
 
302
        ost->next_pts         += ost->frame->nb_samples;
 
303
 
 
304
        got_output |= encode_audio_frame(oc, ost, ret ? ost->frame : NULL);
 
305
    }
 
306
 
 
307
    return !got_output;
174
308
}
175
309
 
176
310
/**************************************************************/
177
311
/* video output */
178
312
 
179
 
static AVFrame *picture, *tmp_picture;
180
 
static int frame_count;
181
 
 
182
313
/* Add a video output stream. */
183
 
static AVStream *add_video_stream(AVFormatContext *oc, enum AVCodecID codec_id)
 
314
static void add_video_stream(OutputStream *ost, AVFormatContext *oc,
 
315
                             enum AVCodecID codec_id)
184
316
{
185
317
    AVCodecContext *c;
186
 
    AVStream *st;
187
318
    AVCodec *codec;
188
319
 
189
320
    /* find the video encoder */
193
324
        exit(1);
194
325
    }
195
326
 
196
 
    st = avformat_new_stream(oc, codec);
197
 
    if (!st) {
 
327
    ost->st = avformat_new_stream(oc, codec);
 
328
    if (!ost->st) {
198
329
        fprintf(stderr, "Could not alloc stream\n");
199
330
        exit(1);
200
331
    }
201
332
 
202
 
    c = st->codec;
 
333
    c = ost->st->codec;
203
334
 
204
335
    /* Put sample parameters. */
205
336
    c->bit_rate = 400000;
210
341
     * of which frame timestamps are represented. For fixed-fps content,
211
342
     * timebase should be 1/framerate and timestamp increments should be
212
343
     * identical to 1. */
213
 
    c->time_base.den = STREAM_FRAME_RATE;
214
 
    c->time_base.num = 1;
 
344
    ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
 
345
    c->time_base       = ost->st->time_base;
 
346
 
215
347
    c->gop_size      = 12; /* emit one intra frame every twelve frames at most */
216
348
    c->pix_fmt       = STREAM_PIX_FMT;
217
349
    if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
227
359
    /* Some formats want stream headers to be separate. */
228
360
    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
229
361
        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
230
 
 
231
 
    return st;
232
362
}
233
363
 
234
364
static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
235
365
{
236
366
    AVFrame *picture;
237
 
    uint8_t *picture_buf;
238
 
    int size;
 
367
    int ret;
239
368
 
240
369
    picture = av_frame_alloc();
241
370
    if (!picture)
242
371
        return NULL;
243
 
    size        = avpicture_get_size(pix_fmt, width, height);
244
 
    picture_buf = av_malloc(size);
245
 
    if (!picture_buf) {
246
 
        av_free(picture);
247
 
        return NULL;
 
372
 
 
373
    picture->format = pix_fmt;
 
374
    picture->width  = width;
 
375
    picture->height = height;
 
376
 
 
377
    /* allocate the buffers for the frame data */
 
378
    ret = av_frame_get_buffer(picture, 32);
 
379
    if (ret < 0) {
 
380
        fprintf(stderr, "Could not allocate frame data.\n");
 
381
        exit(1);
248
382
    }
249
 
    avpicture_fill((AVPicture *)picture, picture_buf,
250
 
                   pix_fmt, width, height);
 
383
 
251
384
    return picture;
252
385
}
253
386
 
254
 
static void open_video(AVFormatContext *oc, AVStream *st)
 
387
static void open_video(AVFormatContext *oc, OutputStream *ost)
255
388
{
256
389
    AVCodecContext *c;
257
390
 
258
 
    c = st->codec;
 
391
    c = ost->st->codec;
259
392
 
260
393
    /* open the codec */
261
394
    if (avcodec_open2(c, NULL, NULL) < 0) {
264
397
    }
265
398
 
266
399
    /* Allocate the encoded raw picture. */
267
 
    picture = alloc_picture(c->pix_fmt, c->width, c->height);
268
 
    if (!picture) {
 
400
    ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
 
401
    if (!ost->frame) {
269
402
        fprintf(stderr, "Could not allocate picture\n");
270
403
        exit(1);
271
404
    }
273
406
    /* If the output format is not YUV420P, then a temporary YUV420P
274
407
     * picture is needed too. It is then converted to the required
275
408
     * output format. */
276
 
    tmp_picture = NULL;
 
409
    ost->tmp_frame = NULL;
277
410
    if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
278
 
        tmp_picture = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
279
 
        if (!tmp_picture) {
 
411
        ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
 
412
        if (!ost->tmp_frame) {
280
413
            fprintf(stderr, "Could not allocate temporary picture\n");
281
414
            exit(1);
282
415
        }
287
420
static void fill_yuv_image(AVFrame *pict, int frame_index,
288
421
                           int width, int height)
289
422
{
290
 
    int x, y, i;
 
423
    int x, y, i, ret;
 
424
 
 
425
    /* when we pass a frame to the encoder, it may keep a reference to it
 
426
     * internally;
 
427
     * make sure we do not overwrite it here
 
428
     */
 
429
    ret = av_frame_make_writable(pict);
 
430
    if (ret < 0)
 
431
        exit(1);
291
432
 
292
433
    i = frame_index;
293
434
 
305
446
    }
306
447
}
307
448
 
308
 
static void write_video_frame(AVFormatContext *oc, AVStream *st)
 
449
static AVFrame *get_video_frame(OutputStream *ost)
 
450
{
 
451
    AVCodecContext *c = ost->st->codec;
 
452
 
 
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)
 
456
        return NULL;
 
457
 
 
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 */
 
461
        if (!ost->sws_ctx) {
 
462
            ost->sws_ctx = sws_getContext(c->width, c->height,
 
463
                                          AV_PIX_FMT_YUV420P,
 
464
                                          c->width, c->height,
 
465
                                          c->pix_fmt,
 
466
                                          SCALE_FLAGS, NULL, NULL, NULL);
 
467
            if (!ost->sws_ctx) {
 
468
                fprintf(stderr,
 
469
                        "Cannot initialize the conversion context\n");
 
470
                exit(1);
 
471
            }
 
472
        }
 
473
        fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
 
474
        sws_scale(ost->sws_ctx, ost->tmp_frame->data, ost->tmp_frame->linesize,
 
475
                  0, c->height, ost->frame->data, ost->frame->linesize);
 
476
    } else {
 
477
        fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
 
478
    }
 
479
 
 
480
    ost->frame->pts = ost->next_pts++;
 
481
 
 
482
    return ost->frame;
 
483
}
 
484
 
 
485
/*
 
486
 * encode one video frame and send it to the muxer
 
487
 * return 1 when encoding is finished, 0 otherwise
 
488
 */
 
489
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
309
490
{
310
491
    int ret;
311
492
    AVCodecContext *c;
312
 
    static struct SwsContext *img_convert_ctx;
313
 
 
314
 
    c = st->codec;
315
 
 
316
 
    if (frame_count >= STREAM_NB_FRAMES) {
317
 
        /* No more frames to compress. The codec has a latency of a few
318
 
         * frames if using B-frames, so we get the last frames by
319
 
         * passing the same picture again. */
320
 
    } else {
321
 
        if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
322
 
            /* as we only generate a YUV420P picture, we must convert it
323
 
             * to the codec pixel format if needed */
324
 
            if (img_convert_ctx == NULL) {
325
 
                img_convert_ctx = sws_getContext(c->width, c->height,
326
 
                                                 AV_PIX_FMT_YUV420P,
327
 
                                                 c->width, c->height,
328
 
                                                 c->pix_fmt,
329
 
                                                 sws_flags, NULL, NULL, NULL);
330
 
                if (img_convert_ctx == NULL) {
331
 
                    fprintf(stderr,
332
 
                            "Cannot initialize the conversion context\n");
333
 
                    exit(1);
334
 
                }
335
 
            }
336
 
            fill_yuv_image(tmp_picture, frame_count, c->width, c->height);
337
 
            sws_scale(img_convert_ctx, tmp_picture->data, tmp_picture->linesize,
338
 
                      0, c->height, picture->data, picture->linesize);
339
 
        } else {
340
 
            fill_yuv_image(picture, frame_count, c->width, c->height);
341
 
        }
342
 
    }
 
493
    AVFrame *frame;
 
494
    int got_packet = 0;
 
495
 
 
496
    c = ost->st->codec;
 
497
 
 
498
    frame = get_video_frame(ost);
343
499
 
344
500
    if (oc->oformat->flags & AVFMT_RAWPICTURE) {
345
 
        /* Raw video case - the API will change slightly in the near
346
 
         * future for that. */
 
501
        /* a hack to avoid data copy with some raw video muxers */
347
502
        AVPacket pkt;
348
503
        av_init_packet(&pkt);
349
504
 
 
505
        if (!frame)
 
506
            return 1;
 
507
 
350
508
        pkt.flags        |= AV_PKT_FLAG_KEY;
351
 
        pkt.stream_index  = st->index;
352
 
        pkt.data          = (uint8_t *)picture;
 
509
        pkt.stream_index  = ost->st->index;
 
510
        pkt.data          = (uint8_t *)frame;
353
511
        pkt.size          = sizeof(AVPicture);
354
512
 
 
513
        pkt.pts = pkt.dts = frame->pts;
 
514
        av_packet_rescale_ts(&pkt, c->time_base, ost->st->time_base);
 
515
 
355
516
        ret = av_interleaved_write_frame(oc, &pkt);
356
517
    } else {
357
518
        AVPacket pkt = { 0 };
358
 
        int got_packet;
359
519
        av_init_packet(&pkt);
360
520
 
361
521
        /* encode the image */
362
 
        ret = avcodec_encode_video2(c, &pkt, picture, &got_packet);
363
 
        /* If size is zero, it means the image was buffered. */
364
 
        if (!ret && got_packet && pkt.size) {
365
 
            if (pkt.pts != AV_NOPTS_VALUE) {
366
 
                pkt.pts = av_rescale_q(pkt.pts,
367
 
                                       c->time_base, st->time_base);
368
 
            }
369
 
            if (pkt.dts != AV_NOPTS_VALUE) {
370
 
                pkt.dts = av_rescale_q(pkt.dts,
371
 
                                       c->time_base, st->time_base);
372
 
            }
373
 
            pkt.stream_index = st->index;
 
522
        ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
 
523
        if (ret < 0) {
 
524
            fprintf(stderr, "Error encoding a video frame\n");
 
525
            exit(1);
 
526
        }
 
527
 
 
528
        if (got_packet) {
 
529
            av_packet_rescale_ts(&pkt, c->time_base, ost->st->time_base);
 
530
            pkt.stream_index = ost->st->index;
374
531
 
375
532
            /* Write the compressed frame to the media file. */
376
533
            ret = av_interleaved_write_frame(oc, &pkt);
377
 
        } else {
378
 
            ret = 0;
379
534
        }
380
535
    }
381
536
    if (ret != 0) {
382
537
        fprintf(stderr, "Error while writing video frame\n");
383
538
        exit(1);
384
539
    }
385
 
    frame_count++;
 
540
 
 
541
    return (frame || got_packet) ? 0 : 1;
386
542
}
387
543
 
388
 
static void close_video(AVFormatContext *oc, AVStream *st)
 
544
static void close_stream(AVFormatContext *oc, OutputStream *ost)
389
545
{
390
 
    avcodec_close(st->codec);
391
 
    av_free(picture->data[0]);
392
 
    av_free(picture);
393
 
    if (tmp_picture) {
394
 
        av_free(tmp_picture->data[0]);
395
 
        av_free(tmp_picture);
396
 
    }
 
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
    avresample_free(&ost->avr);
397
551
}
398
552
 
399
553
/**************************************************************/
401
555
 
402
556
int main(int argc, char **argv)
403
557
{
 
558
    OutputStream video_st = { 0 }, audio_st = { 0 };
404
559
    const char *filename;
405
560
    AVOutputFormat *fmt;
406
561
    AVFormatContext *oc;
407
 
    AVStream *audio_st, *video_st;
408
 
    double audio_pts, video_pts;
409
 
    int i;
 
562
    int have_video = 0, have_audio = 0;
 
563
    int encode_video = 0, encode_audio = 0;
410
564
 
411
565
    /* Initialize libavcodec, and register all codecs and formats. */
412
566
    av_register_all();
444
598
 
445
599
    /* Add the audio and video streams using the default format codecs
446
600
     * and initialize the codecs. */
447
 
    video_st = NULL;
448
 
    audio_st = NULL;
449
601
    if (fmt->video_codec != AV_CODEC_ID_NONE) {
450
 
        video_st = add_video_stream(oc, fmt->video_codec);
 
602
        add_video_stream(&video_st, oc, fmt->video_codec);
 
603
        have_video = 1;
 
604
        encode_video = 1;
451
605
    }
452
606
    if (fmt->audio_codec != AV_CODEC_ID_NONE) {
453
 
        audio_st = add_audio_stream(oc, fmt->audio_codec);
 
607
        add_audio_stream(&audio_st, oc, fmt->audio_codec);
 
608
        have_audio = 1;
 
609
        encode_audio = 1;
454
610
    }
455
611
 
456
612
    /* Now that all the parameters are set, we can open the audio and
457
613
     * video codecs and allocate the necessary encode buffers. */
458
 
    if (video_st)
459
 
        open_video(oc, video_st);
460
 
    if (audio_st)
461
 
        open_audio(oc, audio_st);
 
614
    if (have_video)
 
615
        open_video(oc, &video_st);
 
616
    if (have_audio)
 
617
        open_audio(oc, &audio_st);
462
618
 
463
619
    av_dump_format(oc, 0, filename, 1);
464
620
 
473
629
    /* Write the stream header, if any. */
474
630
    avformat_write_header(oc, NULL);
475
631
 
476
 
    for (;;) {
477
 
        /* Compute current audio and video time. */
478
 
        if (audio_st)
479
 
            audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
480
 
        else
481
 
            audio_pts = 0.0;
482
 
 
483
 
        if (video_st)
484
 
            video_pts = (double)video_st->pts.val * video_st->time_base.num /
485
 
                        video_st->time_base.den;
486
 
        else
487
 
            video_pts = 0.0;
488
 
 
489
 
        if ((!audio_st || audio_pts >= STREAM_DURATION) &&
490
 
            (!video_st || video_pts >= STREAM_DURATION))
491
 
            break;
492
 
 
493
 
        /* write interleaved audio and video frames */
494
 
        if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
495
 
            write_audio_frame(oc, audio_st);
 
632
    while (encode_video || encode_audio) {
 
633
        /* select the stream to encode */
 
634
        if (encode_video &&
 
635
            (!encode_audio || av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
 
636
                                            audio_st.next_pts, audio_st.st->codec->time_base) <= 0)) {
 
637
            encode_video = !write_video_frame(oc, &video_st);
496
638
        } else {
497
 
            write_video_frame(oc, video_st);
 
639
            encode_audio = !process_audio_stream(oc, &audio_st);
498
640
        }
499
641
    }
500
642
 
505
647
    av_write_trailer(oc);
506
648
 
507
649
    /* Close each codec. */
508
 
    if (video_st)
509
 
        close_video(oc, video_st);
510
 
    if (audio_st)
511
 
        close_audio(oc, audio_st);
512
 
 
513
 
    /* Free the streams. */
514
 
    for (i = 0; i < oc->nb_streams; i++) {
515
 
        av_freep(&oc->streams[i]->codec);
516
 
        av_freep(&oc->streams[i]);
517
 
    }
 
650
    if (have_video)
 
651
        close_stream(oc, &video_st);
 
652
    if (have_audio)
 
653
        close_stream(oc, &audio_st);
518
654
 
519
655
    if (!(fmt->flags & AVFMT_NOFILE))
520
656
        /* Close the output file. */
521
657
        avio_close(oc->pb);
522
658
 
523
659
    /* free the stream */
524
 
    av_free(oc);
 
660
    avformat_free_context(oc);
525
661
 
526
662
    return 0;
527
663
}