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