per context frame_rate_base, this should finally fix frame_rate related av sync issues
[libav.git] / libavcodec / apiexample.c
CommitLineData
983e3246
MN
1/**
2 * @file apiexample.c
3 * avcodec API use example.
de6d9b64
FB
4 *
5 * Note that this library only handles codecs (mpeg, mpeg4, etc...),
6 * not file formats (avi, vob, etc...). See library 'libav' for the
7 * format handling
8 */
983e3246 9
de6d9b64
FB
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include <math.h>
14
fe1b62fb
ZK
15#ifdef HAVE_AV_CONFIG_H
16#undef HAVE_AV_CONFIG_H
17#endif
18
de6d9b64
FB
19#include "avcodec.h"
20
21#define INBUF_SIZE 4096
22
23/*
24 * Audio encoding example
25 */
26void audio_encode_example(const char *filename)
27{
28 AVCodec *codec;
e8b62df6 29 AVCodecContext *c= NULL;
de6d9b64
FB
30 int frame_size, i, j, out_size, outbuf_size;
31 FILE *f;
32 short *samples;
33 float t, tincr;
0c1a9eda 34 uint8_t *outbuf;
de6d9b64
FB
35
36 printf("Audio encoding\n");
37
38 /* find the MP2 encoder */
39 codec = avcodec_find_encoder(CODEC_ID_MP2);
40 if (!codec) {
41 fprintf(stderr, "codec not found\n");
42 exit(1);
43 }
44
e8b62df6
MN
45 c= avcodec_alloc_context();
46
de6d9b64
FB
47 /* put sample parameters */
48 c->bit_rate = 64000;
49 c->sample_rate = 44100;
50 c->channels = 2;
51
52 /* open it */
53 if (avcodec_open(c, codec) < 0) {
54 fprintf(stderr, "could not open codec\n");
55 exit(1);
56 }
57
58 /* the codec gives us the frame size, in samples */
59 frame_size = c->frame_size;
60 samples = malloc(frame_size * 2 * c->channels);
61 outbuf_size = 10000;
62 outbuf = malloc(outbuf_size);
63
64 f = fopen(filename, "w");
65 if (!f) {
66 fprintf(stderr, "could not open %s\n", filename);
67 exit(1);
68 }
69
70 /* encode a single tone sound */
71 t = 0;
72 tincr = 2 * M_PI * 440.0 / c->sample_rate;
73 for(i=0;i<200;i++) {
74 for(j=0;j<frame_size;j++) {
75 samples[2*j] = (int)(sin(t) * 10000);
76 samples[2*j+1] = samples[2*j];
77 t += tincr;
78 }
79 /* encode the samples */
80 out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
81 fwrite(outbuf, 1, out_size, f);
82 }
83 fclose(f);
84 free(outbuf);
85 free(samples);
86
87 avcodec_close(c);
e8b62df6 88 free(c);
de6d9b64
FB
89}
90
91/*
92 * Audio decoding.
93 */
94void audio_decode_example(const char *outfilename, const char *filename)
95{
96 AVCodec *codec;
e8b62df6 97 AVCodecContext *c= NULL;
de6d9b64
FB
98 int out_size, size, len;
99 FILE *f, *outfile;
0c1a9eda
ZK
100 uint8_t *outbuf;
101 uint8_t inbuf[INBUF_SIZE], *inbuf_ptr;
de6d9b64
FB
102
103 printf("Audio decoding\n");
104
105 /* find the mpeg audio decoder */
106 codec = avcodec_find_decoder(CODEC_ID_MP2);
107 if (!codec) {
108 fprintf(stderr, "codec not found\n");
109 exit(1);
110 }
111
e8b62df6 112 c= avcodec_alloc_context();
de6d9b64
FB
113
114 /* open it */
115 if (avcodec_open(c, codec) < 0) {
116 fprintf(stderr, "could not open codec\n");
117 exit(1);
118 }
119
120 outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
121
122 f = fopen(filename, "r");
123 if (!f) {
124 fprintf(stderr, "could not open %s\n", filename);
125 exit(1);
126 }
127 outfile = fopen(outfilename, "w");
128 if (!outfile) {
e8b62df6 129 free(c);
de6d9b64
FB
130 exit(1);
131 }
132
133 /* decode until eof */
134 inbuf_ptr = inbuf;
135 for(;;) {
136 size = fread(inbuf, 1, INBUF_SIZE, f);
137 if (size == 0)
138 break;
139
140 inbuf_ptr = inbuf;
141 while (size > 0) {
142 len = avcodec_decode_audio(c, (short *)outbuf, &out_size,
143 inbuf_ptr, size);
144 if (len < 0) {
145 fprintf(stderr, "Error while decoding\n");
146 exit(1);
147 }
148 if (out_size > 0) {
149 /* if a frame has been decoded, output it */
150 fwrite(outbuf, 1, out_size, outfile);
151 }
152 size -= len;
153 inbuf_ptr += len;
154 }
155 }
156
157 fclose(outfile);
158 fclose(f);
159 free(outbuf);
160
161 avcodec_close(c);
e8b62df6 162 free(c);
de6d9b64
FB
163}
164
165/*
166 * Video encoding example
167 */
168void video_encode_example(const char *filename)
169{
170 AVCodec *codec;
e8b62df6 171 AVCodecContext *c= NULL;
de6d9b64
FB
172 int i, out_size, size, x, y, outbuf_size;
173 FILE *f;
492cd3a9 174 AVFrame *picture;
0c1a9eda 175 uint8_t *outbuf, *picture_buf;
de6d9b64
FB
176
177 printf("Video encoding\n");
178
179 /* find the mpeg1 video encoder */
180 codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
181 if (!codec) {
182 fprintf(stderr, "codec not found\n");
183 exit(1);
184 }
185
e8b62df6 186 c= avcodec_alloc_context();
492cd3a9 187 picture= avcodec_alloc_frame();
e8b62df6 188
de6d9b64
FB
189 /* put sample parameters */
190 c->bit_rate = 400000;
191 /* resolution must be a multiple of two */
192 c->width = 352;
193 c->height = 288;
194 /* frames per second */
14bea432
MN
195 c->frame_rate = 25;
196 c->frame_rate_base= 1;
de6d9b64
FB
197 c->gop_size = 10; /* emit one intra frame every ten frames */
198
199 /* open it */
200 if (avcodec_open(c, codec) < 0) {
201 fprintf(stderr, "could not open codec\n");
202 exit(1);
203 }
204
205 /* the codec gives us the frame size, in samples */
206
207 f = fopen(filename, "w");
208 if (!f) {
209 fprintf(stderr, "could not open %s\n", filename);
210 exit(1);
211 }
212
213 /* alloc image and output buffer */
214 outbuf_size = 100000;
215 outbuf = malloc(outbuf_size);
216 size = c->width * c->height;
217 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
218
6c16199b
MN
219 picture->data[0] = picture_buf;
220 picture->data[1] = picture->data[0] + size;
221 picture->data[2] = picture->data[1] + size / 4;
222 picture->linesize[0] = c->width;
223 picture->linesize[1] = c->width / 2;
224 picture->linesize[2] = c->width / 2;
de6d9b64
FB
225
226 /* encode 1 second of video */
227 for(i=0;i<25;i++) {
228 printf("encoding frame %3d\r", i);
229 fflush(stdout);
230 /* prepare a dummy image */
231 /* Y */
232 for(y=0;y<c->height;y++) {
233 for(x=0;x<c->width;x++) {
6c16199b 234 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
de6d9b64
FB
235 }
236 }
237
238 /* Cb and Cr */
239 for(y=0;y<c->height/2;y++) {
240 for(x=0;x<c->width/2;x++) {
6c16199b
MN
241 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
242 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
de6d9b64
FB
243 }
244 }
245
246 /* encode the image */
6c16199b 247 out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
de6d9b64
FB
248 fwrite(outbuf, 1, out_size, f);
249 }
250
251 /* add sequence end code to have a real mpeg file */
252 outbuf[0] = 0x00;
253 outbuf[1] = 0x00;
254 outbuf[2] = 0x01;
255 outbuf[3] = 0xb7;
256 fwrite(outbuf, 1, 4, f);
257 fclose(f);
258 free(picture_buf);
259 free(outbuf);
260
261 avcodec_close(c);
e8b62df6 262 free(c);
6c16199b 263 free(picture);
de6d9b64
FB
264 printf("\n");
265}
266
267/*
268 * Video decoding example
269 */
270
271void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
272{
273 FILE *f;
274 int i;
275
276 f=fopen(filename,"w");
277 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
278 for(i=0;i<ysize;i++)
279 fwrite(buf + i * wrap,1,xsize,f);
280 fclose(f);
281}
282
283void video_decode_example(const char *outfilename, const char *filename)
284{
285 AVCodec *codec;
e8b62df6 286 AVCodecContext *c= NULL;
de6d9b64
FB
287 int frame, size, got_picture, len;
288 FILE *f;
492cd3a9 289 AVFrame *picture;
0c1a9eda 290 uint8_t inbuf[INBUF_SIZE], *inbuf_ptr;
de6d9b64
FB
291 char buf[1024];
292
293 printf("Video decoding\n");
294
295 /* find the mpeg1 video decoder */
296 codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
297 if (!codec) {
298 fprintf(stderr, "codec not found\n");
299 exit(1);
300 }
301
e8b62df6 302 c= avcodec_alloc_context();
492cd3a9 303 picture= avcodec_alloc_frame();
de6d9b64 304
f78ebb51
MN
305 if(codec->capabilities&CODEC_CAP_TRUNCATED)
306 c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
307
58f26ba9 308 /* for some codecs, such as msmpeg4 and mpeg4, width and height
de6d9b64
FB
309 MUST be initialized there because these info are not available
310 in the bitstream */
311
312 /* open it */
313 if (avcodec_open(c, codec) < 0) {
314 fprintf(stderr, "could not open codec\n");
315 exit(1);
316 }
317
318 /* the codec gives us the frame size, in samples */
319
320 f = fopen(filename, "r");
321 if (!f) {
322 fprintf(stderr, "could not open %s\n", filename);
323 exit(1);
324 }
325
326 frame = 0;
327 for(;;) {
328 size = fread(inbuf, 1, INBUF_SIZE, f);
329 if (size == 0)
330 break;
331
332 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
333 and this is the only method to use them because you cannot
334 know the compressed data size before analysing it.
335
58f26ba9
FB
336 BUT some other codecs (msmpeg4, mpeg4) are inherently frame
337 based, so you must call them with all the data for one
338 frame exactly. You must also initialize 'width' and
de6d9b64
FB
339 'height' before initializing them. */
340
341 /* NOTE2: some codecs allow the raw parameters (frame size,
342 sample rate) to be changed at any frame. We handle this, so
343 you should also take care of it */
344
345 /* here, we use a stream based decoder (mpeg1video), so we
346 feed decoder and see if it could decode a frame */
347 inbuf_ptr = inbuf;
348 while (size > 0) {
6c16199b 349 len = avcodec_decode_video(c, picture, &got_picture,
de6d9b64
FB
350 inbuf_ptr, size);
351 if (len < 0) {
352 fprintf(stderr, "Error while decoding frame %d\n", frame);
353 exit(1);
354 }
355 if (got_picture) {
356 printf("saving frame %3d\r", frame);
357 fflush(stdout);
358
359 /* the picture is allocated by the decoder. no need to
360 free it */
361 snprintf(buf, sizeof(buf), outfilename, frame);
6c16199b 362 pgm_save(picture->data[0], picture->linesize[0],
de6d9b64
FB
363 c->width, c->height, buf);
364 frame++;
365 }
366 size -= len;
367 inbuf_ptr += len;
368 }
369 }
370
371 /* some codecs, such as MPEG, transmit the I and P frame with a
372 latency of one frame. You must do the following to have a
373 chance to get the last frame of the video */
6c16199b 374 len = avcodec_decode_video(c, picture, &got_picture,
de6d9b64
FB
375 NULL, 0);
376 if (got_picture) {
377 printf("saving frame %3d\r", frame);
378 fflush(stdout);
379
380 /* the picture is allocated by the decoder. no need to
381 free it */
382 snprintf(buf, sizeof(buf), outfilename, frame);
6c16199b 383 pgm_save(picture->data[0], picture->linesize[0],
de6d9b64
FB
384 c->width, c->height, buf);
385 frame++;
386 }
387
388 fclose(f);
389
390 avcodec_close(c);
e8b62df6 391 free(c);
6c16199b 392 free(picture);
de6d9b64
FB
393 printf("\n");
394}
395
fe1b62fb
ZK
396// simple example how the options could be used
397int options_example(int argc, char* argv[])
398{
399 AVCodec* codec = avcodec_find_encoder_by_name((argc > 1) ? argv[2] : "mpeg4");
400 const AVOption* c;
401 AVCodecContext* avctx;
402 char* def = av_malloc(5000);
403 const char* col = "";
404 int i = 0;
405
406 if (!codec)
407 return -1;
408 c = codec->options;
409 avctx = avcodec_alloc_context();
410 *def = 0;
411
412 if (c) {
413 const AVOption *stack[FF_OPT_MAX_DEPTH];
414 int depth = 0;
415 for (;;) {
416 if (!c->name) {
bec89a84 417 if (c->help) {
fe1b62fb 418 stack[depth++] = c;
bec89a84 419 c = (const AVOption*)c->help;
fe1b62fb
ZK
420 } else {
421 if (depth == 0)
422 break; // finished
423 c = stack[--depth];
424 c++;
425 }
426 } else {
427 int t = c->type & FF_OPT_TYPE_MASK;
428 printf("Config %s %s\n",
429 t == FF_OPT_TYPE_BOOL ? "bool " :
430 t == FF_OPT_TYPE_DOUBLE ? "double " :
431 t == FF_OPT_TYPE_INT ? "integer" :
432 t == FF_OPT_TYPE_STRING ? "string " :
433 "unknown??", c->name);
434 switch (t) {
435 case FF_OPT_TYPE_BOOL:
436 i += sprintf(def + i, "%s%s=%s",
437 col, c->name,
438 c->defval != 0. ? "on" : "off");
439 break;
440 case FF_OPT_TYPE_DOUBLE:
441 i += sprintf(def + i, "%s%s=%f",
442 col, c->name, c->defval);
443 break;
444 case FF_OPT_TYPE_INT:
445 i += sprintf(def + i, "%s%s=%d",
446 col, c->name, (int) c->defval);
447 break;
448 case FF_OPT_TYPE_STRING:
449 if (c->defstr) {
450 char* d = av_strdup(c->defstr);
451 char* f = strchr(d, ',');
452 if (f)
453 *f = 0;
454 i += sprintf(def + i, "%s%s=%s",
455 col, c->name, d);
456 av_free(d);
457 }
458 break;
459 }
460 col = ":";
461 c++;
462 }
463 }
464 }
465 printf("Default Options: %s\n", def);
466 av_free(def);
467 return 0;
468}
469
de6d9b64
FB
470
471int main(int argc, char **argv)
472{
473 const char *filename;
474
475 /* must be called before using avcodec lib */
476 avcodec_init();
477
478 /* register all the codecs (you can also register only the codec
479 you wish to have smaller code */
480 avcodec_register_all();
fe1b62fb
ZK
481
482#ifdef OPT_TEST
483 options_example(argc, argv);
484#else
de6d9b64
FB
485 if (argc <= 1) {
486 audio_encode_example("/tmp/test.mp2");
487 audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
488
489 video_encode_example("/tmp/test.mpg");
490 filename = "/tmp/test.mpg";
491 } else {
492 filename = argv[1];
493 }
494
495 // audio_decode_example("/tmp/test.sw", filename);
496 video_decode_example("/tmp/test%d.pgm", filename);
fe1b62fb 497#endif
de6d9b64
FB
498
499 return 0;
500}