38
38
#include "libavformat/avformat.h"
39
39
#include "libswscale/swscale.h"
43
41
/* 5 seconds stream duration */
44
42
#define STREAM_DURATION 5.0
45
43
#define STREAM_FRAME_RATE 25 /* 25 images/s */
46
44
#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
47
#define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
45
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
49
47
static int sws_flags = SWS_BICUBIC;
54
52
static float t, tincr, tincr2;
55
53
static int16_t *samples;
56
static uint8_t *audio_outbuf;
57
static int audio_outbuf_size;
58
54
static int audio_input_frame_size;
61
57
* add an audio output stream
63
static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id)
59
static AVStream *add_audio_stream(AVFormatContext *oc, enum AVCodecID codec_id)
68
st = av_new_stream(oc, 1);
65
/* find the audio encoder */
66
codec = avcodec_find_encoder(codec_id);
68
fprintf(stderr, "codec not found\n");
72
st = avformat_new_stream(oc, codec);
70
74
fprintf(stderr, "Could not alloc stream\n");
75
c->codec_id = codec_id;
76
c->codec_type = AVMEDIA_TYPE_AUDIO;
78
80
/* put sample parameters */
79
c->sample_fmt = AV_SAMPLE_FMT_S16;
81
c->sample_fmt = AV_SAMPLE_FMT_S16;
81
83
c->sample_rate = 44100;
84
86
// some formats want stream headers to be separate
85
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
87
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
86
88
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
91
93
static void open_audio(AVFormatContext *oc, AVStream *st)
98
/* find the audio encoder */
99
codec = avcodec_find_encoder(c->codec_id);
101
fprintf(stderr, "codec not found\n");
106
if (avcodec_open(c, codec) < 0) {
100
if (avcodec_open2(c, NULL, NULL) < 0) {
107
101
fprintf(stderr, "could not open codec\n");
111
105
/* init signal generator */
113
107
tincr = 2 * M_PI * 110.0 / c->sample_rate;
114
108
/* increment frequency by 110 Hz per second */
115
109
tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
117
audio_outbuf_size = 10000;
118
audio_outbuf = av_malloc(audio_outbuf_size);
120
/* ugly hack for PCM codecs (will be removed ASAP with new PCM
121
support to compute the input frame size in samples */
122
if (c->frame_size <= 1) {
123
audio_input_frame_size = audio_outbuf_size / c->channels;
124
switch(st->codec->codec_id) {
125
case CODEC_ID_PCM_S16LE:
126
case CODEC_ID_PCM_S16BE:
127
case CODEC_ID_PCM_U16LE:
128
case CODEC_ID_PCM_U16BE:
129
audio_input_frame_size >>= 1;
111
if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
112
audio_input_frame_size = 10000;
135
114
audio_input_frame_size = c->frame_size;
137
samples = av_malloc(audio_input_frame_size * 2 * c->channels);
115
samples = av_malloc(audio_input_frame_size *
116
av_get_bytes_per_sample(c->sample_fmt) *
140
/* prepare a 16 bit dummy audio frame of 'frame_size' samples and
141
'nb_channels' channels */
120
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
121
* 'nb_channels' channels. */
142
122
static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
148
for(j=0;j<frame_size;j++) {
128
for (j = 0; j < frame_size; j++) {
149
129
v = (int)(sin(t) * 10000);
150
for(i = 0; i < nb_channels; i++)
130
for (i = 0; i < nb_channels; i++)
157
137
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
159
139
AVCodecContext *c;
140
AVPacket pkt = { 0 }; // data and size must be 0;
141
AVFrame *frame = avcodec_alloc_frame();
161
144
av_init_packet(&pkt);
165
147
get_audio_frame(samples, audio_input_frame_size, c->channels);
167
pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
169
if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
170
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
171
pkt.flags |= AV_PKT_FLAG_KEY;
172
pkt.stream_index= st->index;
173
pkt.data= audio_outbuf;
175
/* write the compressed frame in the media file */
148
frame->nb_samples = audio_input_frame_size;
149
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
151
audio_input_frame_size *
152
av_get_bytes_per_sample(c->sample_fmt) *
155
avcodec_encode_audio2(c, &pkt, frame, &got_packet);
159
pkt.stream_index = st->index;
161
/* Write the compressed frame to the media file. */
176
162
if (av_interleaved_write_frame(oc, &pkt) != 0) {
177
163
fprintf(stderr, "Error while writing audio frame\n");
166
avcodec_free_frame(&frame);
182
169
static void close_audio(AVFormatContext *oc, AVStream *st)
194
180
static uint8_t *video_outbuf;
195
181
static int frame_count, video_outbuf_size;
197
/* add a video output stream */
198
static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
183
/* Add a video output stream. */
184
static AVStream *add_video_stream(AVFormatContext *oc, enum AVCodecID codec_id)
200
186
AVCodecContext *c;
203
st = avformat_new_stream(oc, NULL);
190
/* find the video encoder */
191
codec = avcodec_find_encoder(codec_id);
193
fprintf(stderr, "codec not found\n");
197
st = avformat_new_stream(oc, codec);
205
199
fprintf(stderr, "Could not alloc stream\n");
210
c->codec_id = codec_id;
211
c->codec_type = AVMEDIA_TYPE_VIDEO;
213
/* put sample parameters */
205
/* Put sample parameters. */
214
206
c->bit_rate = 400000;
215
/* resolution must be a multiple of two */
218
/* time base: this is the fundamental unit of time (in seconds) in terms
219
of which frame timestamps are represented. for fixed-fps content,
220
timebase should be 1/framerate and timestamp increments should be
207
/* Resolution must be a multiple of two. */
210
/* timebase: This is the fundamental unit of time (in seconds) in terms
211
* of which frame timestamps are represented. For fixed-fps content,
212
* timebase should be 1/framerate and timestamp increments should be
222
214
c->time_base.den = STREAM_FRAME_RATE;
223
215
c->time_base.num = 1;
224
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
225
c->pix_fmt = STREAM_PIX_FMT;
226
if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
216
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
217
c->pix_fmt = STREAM_PIX_FMT;
218
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
227
219
/* just for testing, we also add B frames */
228
220
c->max_b_frames = 2;
230
if (c->codec_id == CODEC_ID_MPEG1VIDEO){
222
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
231
223
/* Needed to avoid using macroblocks in which some coeffs overflow.
232
This does not happen with normal video, it just happens here as
233
the motion of the chroma plane does not match the luma plane. */
224
* This does not happen with normal video, it just happens here as
225
* the motion of the chroma plane does not match the luma plane. */
236
// some formats want stream headers to be separate
237
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
228
/* Some formats want stream headers to be separate. */
229
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
238
230
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
243
static AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height)
235
static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
245
237
AVFrame *picture;
246
238
uint8_t *picture_buf;
263
255
static void open_video(AVFormatContext *oc, AVStream *st)
266
257
AVCodecContext *c;
270
/* find the video encoder */
271
codec = avcodec_find_encoder(c->codec_id);
273
fprintf(stderr, "codec not found\n");
277
261
/* open the codec */
278
if (avcodec_open(c, codec) < 0) {
262
if (avcodec_open2(c, NULL, NULL) < 0) {
279
263
fprintf(stderr, "could not open codec\n");
283
267
video_outbuf = NULL;
284
268
if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
285
/* allocate output buffer */
286
/* XXX: API change will be done */
287
/* buffers passed into lav* can be allocated any way you prefer,
288
as long as they're aligned enough for the architecture, and
289
they're freed appropriately (such as using av_free for buffers
290
allocated with av_malloc) */
269
/* Allocate output buffer. */
270
/* XXX: API change will be done. */
271
/* Buffers passed into lav* can be allocated any way you prefer,
272
* as long as they're aligned enough for the architecture, and
273
* they're freed appropriately (such as using av_free for buffers
274
* allocated with av_malloc). */
291
275
video_outbuf_size = 200000;
292
video_outbuf = av_malloc(video_outbuf_size);
276
video_outbuf = av_malloc(video_outbuf_size);
295
/* allocate the encoded raw picture */
279
/* Allocate the encoded raw picture. */
296
280
picture = alloc_picture(c->pix_fmt, c->width, c->height);
298
282
fprintf(stderr, "Could not allocate picture\n");
302
/* if the output format is not YUV420P, then a temporary YUV420P
303
picture is needed too. It is then converted to the required
286
/* If the output format is not YUV420P, then a temporary YUV420P
287
* picture is needed too. It is then converted to the required
305
289
tmp_picture = NULL;
306
if (c->pix_fmt != PIX_FMT_YUV420P) {
307
tmp_picture = alloc_picture(PIX_FMT_YUV420P, c->width, c->height);
290
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
291
tmp_picture = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
308
292
if (!tmp_picture) {
309
293
fprintf(stderr, "Could not allocate temporary picture\n");
315
/* prepare a dummy image */
316
static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
299
/* Prepare a dummy image. */
300
static void fill_yuv_image(AVFrame *pict, int frame_index,
301
int width, int height)
323
for(y=0;y<height;y++) {
324
for(x=0;x<width;x++) {
308
for (y = 0; y < height; y++)
309
for (x = 0; x < width; x++)
325
310
pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
330
for(y=0;y<height/2;y++) {
331
for(x=0;x<width/2;x++) {
313
for (y = 0; y < height / 2; y++) {
314
for (x = 0; x < width / 2; x++) {
332
315
pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
333
316
pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
346
329
if (frame_count >= STREAM_NB_FRAMES) {
347
/* no more frame to compress. The codec has a latency of a few
348
frames if using B frames, so we get the last frames by
349
passing the same picture again */
330
/* No more frames to compress. The codec has a latency of a few
331
* frames if using B-frames, so we get the last frames by
332
* passing the same picture again. */
351
if (c->pix_fmt != PIX_FMT_YUV420P) {
334
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
352
335
/* as we only generate a YUV420P picture, we must convert it
353
to the codec pixel format if needed */
336
* to the codec pixel format if needed */
354
337
if (img_convert_ctx == NULL) {
355
338
img_convert_ctx = sws_getContext(c->width, c->height,
357
340
c->width, c->height,
359
342
sws_flags, NULL, NULL, NULL);
360
343
if (img_convert_ctx == NULL) {
361
fprintf(stderr, "Cannot initialize the conversion context\n");
345
"Cannot initialize the conversion context\n");
374
357
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
375
/* raw video case. The API will change slightly in the near
358
/* Raw video case - the API will change slightly in the near
359
* future for that. */
378
361
av_init_packet(&pkt);
380
pkt.flags |= AV_PKT_FLAG_KEY;
381
pkt.stream_index= st->index;
382
pkt.data= (uint8_t *)picture;
383
pkt.size= sizeof(AVPicture);
363
pkt.flags |= AV_PKT_FLAG_KEY;
364
pkt.stream_index = st->index;
365
pkt.data = (uint8_t *)picture;
366
pkt.size = sizeof(AVPicture);
385
368
ret = av_interleaved_write_frame(oc, &pkt);
387
370
/* encode the image */
388
out_size = avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
389
/* if zero size, it means the image was buffered */
371
out_size = avcodec_encode_video(c, video_outbuf,
372
video_outbuf_size, picture);
373
/* If size is zero, it means the image was buffered. */
390
374
if (out_size > 0) {
392
376
av_init_packet(&pkt);
394
378
if (c->coded_frame->pts != AV_NOPTS_VALUE)
395
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
396
if(c->coded_frame->key_frame)
379
pkt.pts = av_rescale_q(c->coded_frame->pts,
380
c->time_base, st->time_base);
381
if (c->coded_frame->key_frame)
397
382
pkt.flags |= AV_PKT_FLAG_KEY;
398
pkt.stream_index= st->index;
399
pkt.data= video_outbuf;
383
pkt.stream_index = st->index;
384
pkt.data = video_outbuf;
402
/* write the compressed frame in the media file */
387
/* Write the compressed frame to the media file. */
403
388
ret = av_interleaved_write_frame(oc, &pkt);
471
455
oc->oformat = fmt;
472
456
snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
474
/* add the audio and video streams using the default format codecs
475
and initialize the codecs */
458
/* Add the audio and video streams using the default format codecs
459
* and initialize the codecs. */
478
if (fmt->video_codec != CODEC_ID_NONE) {
462
if (fmt->video_codec != AV_CODEC_ID_NONE) {
479
463
video_st = add_video_stream(oc, fmt->video_codec);
481
if (fmt->audio_codec != CODEC_ID_NONE) {
465
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
482
466
audio_st = add_audio_stream(oc, fmt->audio_codec);
485
/* set the output parameters (must be done even if no
487
if (av_set_parameters(oc, NULL) < 0) {
488
fprintf(stderr, "Invalid output format parameters\n");
492
av_dump_format(oc, 0, filename, 1);
494
/* now that all the parameters are set, we can open the audio and
495
video codecs and allocate the necessary encode buffers */
469
/* Now that all the parameters are set, we can open the audio and
470
* video codecs and allocate the necessary encode buffers. */
497
472
open_video(oc, video_st);
499
474
open_audio(oc, audio_st);
476
av_dump_format(oc, 0, filename, 1);
501
478
/* open the output file, if needed */
502
479
if (!(fmt->flags & AVFMT_NOFILE)) {
503
480
if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
509
/* write the stream header, if any */
486
/* Write the stream header, if any. */
487
avformat_write_header(oc, NULL);
513
/* compute current audio and video time */
490
/* Compute current audio and video time. */
515
492
audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
520
video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den;
497
video_pts = (double)video_st->pts.val * video_st->time_base.num /
498
video_st->time_base.den;
536
/* write the trailer, if any. the trailer must be written
537
* before you close the CodecContexts open when you wrote the
538
* header; otherwise write_trailer may try to use memory that
539
* was freed on av_codec_close() */
514
/* Write the trailer, if any. The trailer must be written before you
515
* close the CodecContexts open when you wrote the header; otherwise
516
* av_write_trailer() may try to use memory that was freed on
517
* av_codec_close(). */
540
518
av_write_trailer(oc);
542
/* close each codec */
520
/* Close each codec. */
544
522
close_video(oc, video_st);
546
524
close_audio(oc, audio_st);
548
/* free the streams */
549
for(i = 0; i < oc->nb_streams; i++) {
526
/* Free the streams. */
527
for (i = 0; i < oc->nb_streams; i++) {
550
528
av_freep(&oc->streams[i]->codec);
551
529
av_freep(&oc->streams[i]);
554
if (!(fmt->flags & AVFMT_NOFILE)) {
555
/* close the output file */
532
if (!(fmt->flags & AVFMT_NOFILE))
533
/* Close the output file. */
556
534
avio_close(oc->pb);
559
536
/* free the stream */