94ec222cf3f086504b138f21738c428565f7b092
[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     c->max_b_frames=1;
199
200     /* open it */
201     if (avcodec_open(c, codec) < 0) {
202         fprintf(stderr, "could not open codec\n");
203         exit(1);
204     }
205     
206     /* the codec gives us the frame size, in samples */
207
208     f = fopen(filename, "w");
209     if (!f) {
210         fprintf(stderr, "could not open %s\n", filename);
211         exit(1);
212     }
213     
214     /* alloc image and output buffer */
215     outbuf_size = 100000;
216     outbuf = malloc(outbuf_size);
217     size = c->width * c->height;
218     picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
219     
220     picture->data[0] = picture_buf;
221     picture->data[1] = picture->data[0] + size;
222     picture->data[2] = picture->data[1] + size / 4;
223     picture->linesize[0] = c->width;
224     picture->linesize[1] = c->width / 2;
225     picture->linesize[2] = c->width / 2;
226
227     /* encode 1 second of video */
228     for(i=0;i<25;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         printf("encoding frame %3d (size=%5d)\n", i, out_size);
249         fwrite(outbuf, 1, out_size, f);
250     }
251
252     /* get the delayed frames */
253     for(; out_size; i++) {
254         fflush(stdout);
255         
256         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
257         printf("write frame %3d (size=%5d)\n", i, out_size);
258         fwrite(outbuf, 1, out_size, f);
259     }
260
261     /* add sequence end code to have a real mpeg file */
262     outbuf[0] = 0x00;
263     outbuf[1] = 0x00;
264     outbuf[2] = 0x01;
265     outbuf[3] = 0xb7;
266     fwrite(outbuf, 1, 4, f);
267     fclose(f);
268     free(picture_buf);
269     free(outbuf);
270
271     avcodec_close(c);
272     free(c);
273     free(picture);
274     printf("\n");
275 }
276
277 /*
278  * Video decoding example 
279  */
280
281 void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) 
282 {
283     FILE *f;
284     int i;
285
286     f=fopen(filename,"w");
287     fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
288     for(i=0;i<ysize;i++)
289         fwrite(buf + i * wrap,1,xsize,f);
290     fclose(f);
291 }
292
293 void video_decode_example(const char *outfilename, const char *filename)
294 {
295     AVCodec *codec;
296     AVCodecContext *c= NULL;
297     int frame, size, got_picture, len;
298     FILE *f;
299     AVFrame *picture;
300     uint8_t inbuf[INBUF_SIZE], *inbuf_ptr;
301     char buf[1024];
302
303     printf("Video decoding\n");
304
305     /* find the mpeg1 video decoder */
306     codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
307     if (!codec) {
308         fprintf(stderr, "codec not found\n");
309         exit(1);
310     }
311
312     c= avcodec_alloc_context();
313     picture= avcodec_alloc_frame();
314
315     if(codec->capabilities&CODEC_CAP_TRUNCATED)
316         c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
317
318     /* for some codecs, such as msmpeg4 and mpeg4, width and height
319        MUST be initialized there because these info are not available
320        in the bitstream */
321
322     /* open it */
323     if (avcodec_open(c, codec) < 0) {
324         fprintf(stderr, "could not open codec\n");
325         exit(1);
326     }
327     
328     /* the codec gives us the frame size, in samples */
329
330     f = fopen(filename, "r");
331     if (!f) {
332         fprintf(stderr, "could not open %s\n", filename);
333         exit(1);
334     }
335     
336     frame = 0;
337     for(;;) {
338         size = fread(inbuf, 1, INBUF_SIZE, f);
339         if (size == 0)
340             break;
341
342         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
343            and this is the only method to use them because you cannot
344            know the compressed data size before analysing it. 
345
346            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
347            based, so you must call them with all the data for one
348            frame exactly. You must also initialize 'width' and
349            'height' before initializing them. */
350
351         /* NOTE2: some codecs allow the raw parameters (frame size,
352            sample rate) to be changed at any frame. We handle this, so
353            you should also take care of it */
354
355         /* here, we use a stream based decoder (mpeg1video), so we
356            feed decoder and see if it could decode a frame */
357         inbuf_ptr = inbuf;
358         while (size > 0) {
359             len = avcodec_decode_video(c, picture, &got_picture, 
360                                        inbuf_ptr, size);
361             if (len < 0) {
362                 fprintf(stderr, "Error while decoding frame %d\n", frame);
363                 exit(1);
364             }
365             if (got_picture) {
366                 printf("saving frame %3d\n", frame);
367                 fflush(stdout);
368
369                 /* the picture is allocated by the decoder. no need to
370                    free it */
371                 snprintf(buf, sizeof(buf), outfilename, frame);
372                 pgm_save(picture->data[0], picture->linesize[0], 
373                          c->width, c->height, buf);
374                 frame++;
375             }
376             size -= len;
377             inbuf_ptr += len;
378         }
379     }
380
381     /* some codecs, such as MPEG, transmit the I and P frame with a
382        latency of one frame. You must do the following to have a
383        chance to get the last frame of the video */
384     len = avcodec_decode_video(c, picture, &got_picture, 
385                                NULL, 0);
386     if (got_picture) {
387         printf("saving last frame %3d\n", frame);
388         fflush(stdout);
389         
390         /* the picture is allocated by the decoder. no need to
391            free it */
392         snprintf(buf, sizeof(buf), outfilename, frame);
393         pgm_save(picture->data[0], picture->linesize[0], 
394                  c->width, c->height, buf);
395         frame++;
396     }
397         
398     fclose(f);
399
400     avcodec_close(c);
401     free(c);
402     free(picture);
403     printf("\n");
404 }
405
406 // simple example how the options could be used
407 int options_example(int argc, char* argv[])
408 {
409     AVCodec* codec = avcodec_find_encoder_by_name((argc > 1) ? argv[2] : "mpeg4");
410     const AVOption* c;
411     AVCodecContext* avctx;
412     char* def = av_malloc(5000);
413     const char* col = "";
414     int i = 0;
415
416     if (!codec)
417         return -1;
418     c = codec->options;
419     avctx = avcodec_alloc_context();
420     *def = 0;
421
422     if (c) {
423         const AVOption *stack[FF_OPT_MAX_DEPTH];
424         int depth = 0;
425         for (;;) {
426             if (!c->name) {
427                 if (c->help) {
428                     stack[depth++] = c;
429                     c = (const AVOption*)c->help;
430                 } else {
431                     if (depth == 0)
432                         break; // finished
433                     c = stack[--depth];
434                     c++;
435                 }
436             } else {
437                 int t = c->type & FF_OPT_TYPE_MASK;
438                 printf("Config   %s  %s\n",
439                        t == FF_OPT_TYPE_BOOL ? "bool   " :
440                        t == FF_OPT_TYPE_DOUBLE ? "double  " :
441                        t == FF_OPT_TYPE_INT ? "integer" :
442                        t == FF_OPT_TYPE_STRING ? "string " :
443                        "unknown??", c->name);
444                 switch (t) {
445                 case FF_OPT_TYPE_BOOL:
446                     i += sprintf(def + i, "%s%s=%s",
447                                  col, c->name,
448                                  c->defval != 0. ? "on" : "off");
449                     break;
450                 case FF_OPT_TYPE_DOUBLE:
451                     i += sprintf(def + i, "%s%s=%f",
452                                  col, c->name, c->defval);
453                     break;
454                 case FF_OPT_TYPE_INT:
455                     i += sprintf(def + i, "%s%s=%d",
456                                  col, c->name, (int) c->defval);
457                     break;
458                 case FF_OPT_TYPE_STRING:
459                     if (c->defstr) {
460                         char* d = av_strdup(c->defstr);
461                         char* f = strchr(d, ',');
462                         if (f)
463                             *f = 0;
464                         i += sprintf(def + i, "%s%s=%s",
465                                      col, c->name, d);
466                         av_free(d);
467                     }
468                     break;
469                 }
470                 col = ":";
471                 c++;
472             }
473         }
474     }
475     printf("Default Options: %s\n", def);
476     av_free(def);
477     return 0;
478 }
479
480
481 int main(int argc, char **argv)
482 {
483     const char *filename;
484
485     /* must be called before using avcodec lib */
486     avcodec_init();
487
488     /* register all the codecs (you can also register only the codec
489        you wish to have smaller code */
490     avcodec_register_all();
491
492 #ifdef OPT_TEST
493     options_example(argc, argv);
494 #else
495     if (argc <= 1) {
496         audio_encode_example("/tmp/test.mp2");
497         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
498
499         video_encode_example("/tmp/test.mpg");
500         filename = "/tmp/test.mpg";
501     } else {
502         filename = argv[1];
503     }
504
505     //    audio_decode_example("/tmp/test.sw", filename);
506     video_decode_example("/tmp/test%d.pgm", filename);
507 #endif
508
509     return 0;
510 }