]> git.sesse.net Git - ffmpeg/blob - libavcodec/apiexample.c
More spelling errors patch by (Kevin Baragona (kevinmb500 gawab com>)
[ffmpeg] / 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 'libavformat' 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, "wb");
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     av_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 + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
102
103     printf("Audio decoding\n");
104     
105     /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
106     memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
107
108     /* find the mpeg audio decoder */
109     codec = avcodec_find_decoder(CODEC_ID_MP2);
110     if (!codec) {
111         fprintf(stderr, "codec not found\n");
112         exit(1);
113     }
114
115     c= avcodec_alloc_context();
116
117     /* open it */
118     if (avcodec_open(c, codec) < 0) {
119         fprintf(stderr, "could not open codec\n");
120         exit(1);
121     }
122     
123     outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
124
125     f = fopen(filename, "rb");
126     if (!f) {
127         fprintf(stderr, "could not open %s\n", filename);
128         exit(1);
129     }
130     outfile = fopen(outfilename, "wb");
131     if (!outfile) {
132         av_free(c);
133         exit(1);
134     }
135         
136     /* decode until eof */
137     inbuf_ptr = inbuf;
138     for(;;) {
139         size = fread(inbuf, 1, INBUF_SIZE, f);
140         if (size == 0)
141             break;
142
143         inbuf_ptr = inbuf;
144         while (size > 0) {
145             len = avcodec_decode_audio(c, (short *)outbuf, &out_size, 
146                                        inbuf_ptr, size);
147             if (len < 0) {
148                 fprintf(stderr, "Error while decoding\n");
149                 exit(1);
150             }
151             if (out_size > 0) {
152                 /* if a frame has been decoded, output it */
153                 fwrite(outbuf, 1, out_size, outfile);
154             }
155             size -= len;
156             inbuf_ptr += len;
157         }
158     }
159
160     fclose(outfile);
161     fclose(f);
162     free(outbuf);
163
164     avcodec_close(c);
165     av_free(c);
166 }
167
168 /*
169  * Video encoding example 
170  */
171 void video_encode_example(const char *filename)
172 {
173     AVCodec *codec;
174     AVCodecContext *c= NULL;
175     int i, out_size, size, x, y, outbuf_size;
176     FILE *f;
177     AVFrame *picture;
178     uint8_t *outbuf, *picture_buf;
179
180     printf("Video encoding\n");
181
182     /* find the mpeg1 video encoder */
183     codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
184     if (!codec) {
185         fprintf(stderr, "codec not found\n");
186         exit(1);
187     }
188
189     c= avcodec_alloc_context();
190     picture= avcodec_alloc_frame();
191     
192     /* put sample parameters */
193     c->bit_rate = 400000;
194     /* resolution must be a multiple of two */
195     c->width = 352;  
196     c->height = 288;
197     /* frames per second */
198     c->time_base= (AVRational){1,25};
199     c->gop_size = 10; /* emit one intra frame every ten frames */
200     c->max_b_frames=1;
201
202     /* open it */
203     if (avcodec_open(c, codec) < 0) {
204         fprintf(stderr, "could not open codec\n");
205         exit(1);
206     }
207     
208     /* the codec gives us the frame size, in samples */
209
210     f = fopen(filename, "wb");
211     if (!f) {
212         fprintf(stderr, "could not open %s\n", filename);
213         exit(1);
214     }
215     
216     /* alloc image and output buffer */
217     outbuf_size = 100000;
218     outbuf = malloc(outbuf_size);
219     size = c->width * c->height;
220     picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
221     
222     picture->data[0] = picture_buf;
223     picture->data[1] = picture->data[0] + size;
224     picture->data[2] = picture->data[1] + size / 4;
225     picture->linesize[0] = c->width;
226     picture->linesize[1] = c->width / 2;
227     picture->linesize[2] = c->width / 2;
228
229     /* encode 1 second of video */
230     for(i=0;i<25;i++) {
231         fflush(stdout);
232         /* prepare a dummy image */
233         /* Y */
234         for(y=0;y<c->height;y++) {
235             for(x=0;x<c->width;x++) {
236                 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
237             }
238         }
239
240         /* Cb and Cr */
241         for(y=0;y<c->height/2;y++) {
242             for(x=0;x<c->width/2;x++) {
243                 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
244                 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
245             }
246         }
247
248         /* encode the image */
249         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
250         printf("encoding frame %3d (size=%5d)\n", i, out_size);
251         fwrite(outbuf, 1, out_size, f);
252     }
253
254     /* get the delayed frames */
255     for(; out_size; i++) {
256         fflush(stdout);
257         
258         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
259         printf("write frame %3d (size=%5d)\n", i, out_size);
260         fwrite(outbuf, 1, out_size, f);
261     }
262
263     /* add sequence end code to have a real mpeg file */
264     outbuf[0] = 0x00;
265     outbuf[1] = 0x00;
266     outbuf[2] = 0x01;
267     outbuf[3] = 0xb7;
268     fwrite(outbuf, 1, 4, f);
269     fclose(f);
270     free(picture_buf);
271     free(outbuf);
272
273     avcodec_close(c);
274     av_free(c);
275     av_free(picture);
276     printf("\n");
277 }
278
279 /*
280  * Video decoding example 
281  */
282
283 void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) 
284 {
285     FILE *f;
286     int i;
287
288     f=fopen(filename,"w");
289     fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
290     for(i=0;i<ysize;i++)
291         fwrite(buf + i * wrap,1,xsize,f);
292     fclose(f);
293 }
294
295 void video_decode_example(const char *outfilename, const char *filename)
296 {
297     AVCodec *codec;
298     AVCodecContext *c= NULL;
299     int frame, size, got_picture, len;
300     FILE *f;
301     AVFrame *picture;
302     uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
303     char buf[1024];
304
305     /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
306     memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
307
308     printf("Video decoding\n");
309
310     /* find the mpeg1 video decoder */
311     codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
312     if (!codec) {
313         fprintf(stderr, "codec not found\n");
314         exit(1);
315     }
316
317     c= avcodec_alloc_context();
318     picture= avcodec_alloc_frame();
319
320     if(codec->capabilities&CODEC_CAP_TRUNCATED)
321         c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
322
323     /* for some codecs, such as msmpeg4 and mpeg4, width and height
324        MUST be initialized there because these info are not available
325        in the bitstream */
326
327     /* open it */
328     if (avcodec_open(c, codec) < 0) {
329         fprintf(stderr, "could not open codec\n");
330         exit(1);
331     }
332     
333     /* the codec gives us the frame size, in samples */
334
335     f = fopen(filename, "rb");
336     if (!f) {
337         fprintf(stderr, "could not open %s\n", filename);
338         exit(1);
339     }
340     
341     frame = 0;
342     for(;;) {
343         size = fread(inbuf, 1, INBUF_SIZE, f);
344         if (size == 0)
345             break;
346
347         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
348            and this is the only method to use them because you cannot
349            know the compressed data size before analysing it. 
350
351            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
352            based, so you must call them with all the data for one
353            frame exactly. You must also initialize 'width' and
354            'height' before initializing them. */
355
356         /* NOTE2: some codecs allow the raw parameters (frame size,
357            sample rate) to be changed at any frame. We handle this, so
358            you should also take care of it */
359
360         /* here, we use a stream based decoder (mpeg1video), so we
361            feed decoder and see if it could decode a frame */
362         inbuf_ptr = inbuf;
363         while (size > 0) {
364             len = avcodec_decode_video(c, picture, &got_picture, 
365                                        inbuf_ptr, size);
366             if (len < 0) {
367                 fprintf(stderr, "Error while decoding frame %d\n", frame);
368                 exit(1);
369             }
370             if (got_picture) {
371                 printf("saving frame %3d\n", frame);
372                 fflush(stdout);
373
374                 /* the picture is allocated by the decoder. no need to
375                    free it */
376                 snprintf(buf, sizeof(buf), outfilename, frame);
377                 pgm_save(picture->data[0], picture->linesize[0], 
378                          c->width, c->height, buf);
379                 frame++;
380             }
381             size -= len;
382             inbuf_ptr += len;
383         }
384     }
385
386     /* some codecs, such as MPEG, transmit the I and P frame with a
387        latency of one frame. You must do the following to have a
388        chance to get the last frame of the video */
389     len = avcodec_decode_video(c, picture, &got_picture, 
390                                NULL, 0);
391     if (got_picture) {
392         printf("saving last frame %3d\n", frame);
393         fflush(stdout);
394         
395         /* the picture is allocated by the decoder. no need to
396            free it */
397         snprintf(buf, sizeof(buf), outfilename, frame);
398         pgm_save(picture->data[0], picture->linesize[0], 
399                  c->width, c->height, buf);
400         frame++;
401     }
402         
403     fclose(f);
404
405     avcodec_close(c);
406     av_free(c);
407     av_free(picture);
408     printf("\n");
409 }
410
411 int main(int argc, char **argv)
412 {
413     const char *filename;
414
415     /* must be called before using avcodec lib */
416     avcodec_init();
417
418     /* register all the codecs (you can also register only the codec
419        you wish to have smaller code */
420     avcodec_register_all();
421
422     if (argc <= 1) {
423         audio_encode_example("/tmp/test.mp2");
424         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
425
426         video_encode_example("/tmp/test.mpg");
427         filename = "/tmp/test.mpg";
428     } else {
429         filename = argv[1];
430     }
431
432     //    audio_decode_example("/tmp/test.sw", filename);
433     video_decode_example("/tmp/test%d.pgm", filename);
434
435     return 0;
436 }