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