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