Stray comment, probably copy & pasted from audio_encode_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     f = fopen(filename, "wb");
232     if (!f) {
233         fprintf(stderr, "could not open %s\n", filename);
234         exit(1);
235     }
236
237     /* alloc image and output buffer */
238     outbuf_size = 100000;
239     outbuf = malloc(outbuf_size);
240     size = c->width * c->height;
241     picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
242
243     picture->data[0] = picture_buf;
244     picture->data[1] = picture->data[0] + size;
245     picture->data[2] = picture->data[1] + size / 4;
246     picture->linesize[0] = c->width;
247     picture->linesize[1] = c->width / 2;
248     picture->linesize[2] = c->width / 2;
249
250     /* encode 1 second of video */
251     for(i=0;i<25;i++) {
252         fflush(stdout);
253         /* prepare a dummy image */
254         /* Y */
255         for(y=0;y<c->height;y++) {
256             for(x=0;x<c->width;x++) {
257                 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
258             }
259         }
260
261         /* Cb and Cr */
262         for(y=0;y<c->height/2;y++) {
263             for(x=0;x<c->width/2;x++) {
264                 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
265                 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
266             }
267         }
268
269         /* encode the image */
270         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
271         printf("encoding frame %3d (size=%5d)\n", i, out_size);
272         fwrite(outbuf, 1, out_size, f);
273     }
274
275     /* get the delayed frames */
276     for(; out_size; i++) {
277         fflush(stdout);
278
279         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
280         printf("write frame %3d (size=%5d)\n", i, out_size);
281         fwrite(outbuf, 1, out_size, f);
282     }
283
284     /* add sequence end code to have a real mpeg file */
285     outbuf[0] = 0x00;
286     outbuf[1] = 0x00;
287     outbuf[2] = 0x01;
288     outbuf[3] = 0xb7;
289     fwrite(outbuf, 1, 4, f);
290     fclose(f);
291     free(picture_buf);
292     free(outbuf);
293
294     avcodec_close(c);
295     av_free(c);
296     av_free(picture);
297     printf("\n");
298 }
299
300 /*
301  * Video decoding example
302  */
303
304 void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
305 {
306     FILE *f;
307     int i;
308
309     f=fopen(filename,"w");
310     fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
311     for(i=0;i<ysize;i++)
312         fwrite(buf + i * wrap,1,xsize,f);
313     fclose(f);
314 }
315
316 void video_decode_example(const char *outfilename, const char *filename)
317 {
318     AVCodec *codec;
319     AVCodecContext *c= NULL;
320     int frame, size, got_picture, len;
321     FILE *f;
322     AVFrame *picture;
323     uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
324     char buf[1024];
325
326     /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
327     memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
328
329     printf("Video decoding\n");
330
331     /* find the mpeg1 video decoder */
332     codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
333     if (!codec) {
334         fprintf(stderr, "codec not found\n");
335         exit(1);
336     }
337
338     c= avcodec_alloc_context();
339     picture= avcodec_alloc_frame();
340
341     if(codec->capabilities&CODEC_CAP_TRUNCATED)
342         c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
343
344     /* for some codecs, such as msmpeg4 and mpeg4, width and height
345        MUST be initialized there because these info are not available
346        in the bitstream */
347
348     /* open it */
349     if (avcodec_open(c, codec) < 0) {
350         fprintf(stderr, "could not open codec\n");
351         exit(1);
352     }
353
354     /* the codec gives us the frame size, in samples */
355
356     f = fopen(filename, "rb");
357     if (!f) {
358         fprintf(stderr, "could not open %s\n", filename);
359         exit(1);
360     }
361
362     frame = 0;
363     for(;;) {
364         size = fread(inbuf, 1, INBUF_SIZE, f);
365         if (size == 0)
366             break;
367
368         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
369            and this is the only method to use them because you cannot
370            know the compressed data size before analysing it.
371
372            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
373            based, so you must call them with all the data for one
374            frame exactly. You must also initialize 'width' and
375            'height' before initializing them. */
376
377         /* NOTE2: some codecs allow the raw parameters (frame size,
378            sample rate) to be changed at any frame. We handle this, so
379            you should also take care of it */
380
381         /* here, we use a stream based decoder (mpeg1video), so we
382            feed decoder and see if it could decode a frame */
383         inbuf_ptr = inbuf;
384         while (size > 0) {
385             len = avcodec_decode_video(c, picture, &got_picture,
386                                        inbuf_ptr, size);
387             if (len < 0) {
388                 fprintf(stderr, "Error while decoding frame %d\n", frame);
389                 exit(1);
390             }
391             if (got_picture) {
392                 printf("saving 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             size -= len;
403             inbuf_ptr += len;
404         }
405     }
406
407     /* some codecs, such as MPEG, transmit the I and P frame with a
408        latency of one frame. You must do the following to have a
409        chance to get the last frame of the video */
410     len = avcodec_decode_video(c, picture, &got_picture,
411                                NULL, 0);
412     if (got_picture) {
413         printf("saving last frame %3d\n", frame);
414         fflush(stdout);
415
416         /* the picture is allocated by the decoder. no need to
417            free it */
418         snprintf(buf, sizeof(buf), outfilename, frame);
419         pgm_save(picture->data[0], picture->linesize[0],
420                  c->width, c->height, buf);
421         frame++;
422     }
423
424     fclose(f);
425
426     avcodec_close(c);
427     av_free(c);
428     av_free(picture);
429     printf("\n");
430 }
431
432 int main(int argc, char **argv)
433 {
434     const char *filename;
435
436     /* must be called before using avcodec lib */
437     avcodec_init();
438
439     /* register all the codecs (you can also register only the codec
440        you wish to have smaller code */
441     avcodec_register_all();
442
443     if (argc <= 1) {
444         audio_encode_example("/tmp/test.mp2");
445         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
446
447         video_encode_example("/tmp/test.mpg");
448         filename = "/tmp/test.mpg";
449     } else {
450         filename = argv[1];
451     }
452
453     //    audio_decode_example("/tmp/test.sw", filename);
454     video_decode_example("/tmp/test%d.pgm", filename);
455
456     return 0;
457 }