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