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