]> git.sesse.net Git - ffmpeg/blob - libavcodec/apiexample.c
av_log(NULL,... -> av_log(avctx,.. where appropriate.
[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 #include <math.h>
34
35 #ifdef HAVE_AV_CONFIG_H
36 #undef HAVE_AV_CONFIG_H
37 #endif
38
39 #include "avcodec.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     /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
126     memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
127
128     /* find the mpeg audio decoder */
129     codec = avcodec_find_decoder(CODEC_ID_MP2);
130     if (!codec) {
131         fprintf(stderr, "codec not found\n");
132         exit(1);
133     }
134
135     c= avcodec_alloc_context();
136
137     /* open it */
138     if (avcodec_open(c, codec) < 0) {
139         fprintf(stderr, "could not open codec\n");
140         exit(1);
141     }
142
143     outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
144
145     f = fopen(filename, "rb");
146     if (!f) {
147         fprintf(stderr, "could not open %s\n", filename);
148         exit(1);
149     }
150     outfile = fopen(outfilename, "wb");
151     if (!outfile) {
152         av_free(c);
153         exit(1);
154     }
155
156     /* decode until eof */
157     inbuf_ptr = inbuf;
158     for(;;) {
159         size = fread(inbuf, 1, INBUF_SIZE, f);
160         if (size == 0)
161             break;
162
163         inbuf_ptr = inbuf;
164         while (size > 0) {
165             len = avcodec_decode_audio(c, (short *)outbuf, &out_size,
166                                        inbuf_ptr, size);
167             if (len < 0) {
168                 fprintf(stderr, "Error while decoding\n");
169                 exit(1);
170             }
171             if (out_size > 0) {
172                 /* if a frame has been decoded, output it */
173                 fwrite(outbuf, 1, out_size, outfile);
174             }
175             size -= len;
176             inbuf_ptr += len;
177         }
178     }
179
180     fclose(outfile);
181     fclose(f);
182     free(outbuf);
183
184     avcodec_close(c);
185     av_free(c);
186 }
187
188 /*
189  * Video encoding example
190  */
191 void video_encode_example(const char *filename)
192 {
193     AVCodec *codec;
194     AVCodecContext *c= NULL;
195     int i, out_size, size, x, y, outbuf_size;
196     FILE *f;
197     AVFrame *picture;
198     uint8_t *outbuf, *picture_buf;
199
200     printf("Video encoding\n");
201
202     /* find the mpeg1 video encoder */
203     codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
204     if (!codec) {
205         fprintf(stderr, "codec not found\n");
206         exit(1);
207     }
208
209     c= avcodec_alloc_context();
210     picture= avcodec_alloc_frame();
211
212     /* put sample parameters */
213     c->bit_rate = 400000;
214     /* resolution must be a multiple of two */
215     c->width = 352;
216     c->height = 288;
217     /* frames per second */
218     c->time_base= (AVRational){1,25};
219     c->gop_size = 10; /* emit one intra frame every ten frames */
220     c->max_b_frames=1;
221     c->pix_fmt = PIX_FMT_YUV420P;
222
223     /* open it */
224     if (avcodec_open(c, codec) < 0) {
225         fprintf(stderr, "could not open codec\n");
226         exit(1);
227     }
228
229     /* the codec gives us the frame size, in samples */
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 }