per context frame_rate_base, this should finally fix frame_rate related av sync issues
[ffmpeg.git] / libavcodec / apiexample.c
1 /**
2  * @file apiexample.c
3  * avcodec API use example.
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  */
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <math.h>
14
15 #ifdef HAVE_AV_CONFIG_H
16 #undef HAVE_AV_CONFIG_H
17 #endif
18
19 #include "avcodec.h"
20
21 #define INBUF_SIZE 4096
22
23 /*
24  * Audio encoding example 
25  */
26 void audio_encode_example(const char *filename)
27 {
28     AVCodec *codec;
29     AVCodecContext *c= NULL;
30     int frame_size, i, j, out_size, outbuf_size;
31     FILE *f;
32     short *samples;
33     float t, tincr;
34     uint8_t *outbuf;
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
45     c= avcodec_alloc_context();
46     
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);
88     free(c);
89 }
90
91 /*
92  * Audio decoding. 
93  */
94 void audio_decode_example(const char *outfilename, const char *filename)
95 {
96     AVCodec *codec;
97     AVCodecContext *c= NULL;
98     int out_size, size, len;
99     FILE *f, *outfile;
100     uint8_t *outbuf;
101     uint8_t inbuf[INBUF_SIZE], *inbuf_ptr;
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
112     c= avcodec_alloc_context();
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) {
129         free(c);
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);
162     free(c);
163 }
164
165 /*
166  * Video encoding example 
167  */
168 void video_encode_example(const char *filename)
169 {
170     AVCodec *codec;
171     AVCodecContext *c= NULL;
172     int i, out_size, size, x, y, outbuf_size;
173     FILE *f;
174     AVFrame *picture;
175     uint8_t *outbuf, *picture_buf;
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
186     c= avcodec_alloc_context();
187     picture= avcodec_alloc_frame();
188     
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 */
195     c->frame_rate = 25;  
196     c->frame_rate_base= 1;
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     
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;
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++) {
234                 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
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++) {
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;
243             }
244         }
245
246         /* encode the image */
247         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
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);
262     free(c);
263     free(picture);
264     printf("\n");
265 }
266
267 /*
268  * Video decoding example 
269  */
270
271 void 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
283 void video_decode_example(const char *outfilename, const char *filename)
284 {
285     AVCodec *codec;
286     AVCodecContext *c= NULL;
287     int frame, size, got_picture, len;
288     FILE *f;
289     AVFrame *picture;
290     uint8_t inbuf[INBUF_SIZE], *inbuf_ptr;
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
302     c= avcodec_alloc_context();
303     picture= avcodec_alloc_frame();
304
305     if(codec->capabilities&CODEC_CAP_TRUNCATED)
306         c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
307
308     /* for some codecs, such as msmpeg4 and mpeg4, width and height
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
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
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) {
349             len = avcodec_decode_video(c, picture, &got_picture, 
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);
362                 pgm_save(picture->data[0], picture->linesize[0], 
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 */
374     len = avcodec_decode_video(c, picture, &got_picture, 
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);
383         pgm_save(picture->data[0], picture->linesize[0], 
384                  c->width, c->height, buf);
385         frame++;
386     }
387         
388     fclose(f);
389
390     avcodec_close(c);
391     free(c);
392     free(picture);
393     printf("\n");
394 }
395
396 // simple example how the options could be used
397 int 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) {
417                 if (c->help) {
418                     stack[depth++] = c;
419                     c = (const AVOption*)c->help;
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
470
471 int 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();
481
482 #ifdef OPT_TEST
483     options_example(argc, argv);
484 #else
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);
497 #endif
498
499     return 0;
500 }