]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/api-example.c
7f682cde30a208406faeab5dd4a8edae743818dd
[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 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             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 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 void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
301 {
302     FILE *f;
303     int i;
304
305     f=fopen(filename,"w");
306     fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
307     for(i=0;i<ysize;i++)
308         fwrite(buf + i * wrap,1,xsize,f);
309     fclose(f);
310 }
311
312 void video_decode_example(const char *outfilename, const char *filename)
313 {
314     AVCodec *codec;
315     AVCodecContext *c= NULL;
316     int frame, size, got_picture, len;
317     FILE *f;
318     AVFrame *picture;
319     uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
320     char buf[1024];
321
322     /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
323     memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
324
325     printf("Video decoding\n");
326
327     /* find the mpeg1 video decoder */
328     codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
329     if (!codec) {
330         fprintf(stderr, "codec not found\n");
331         exit(1);
332     }
333
334     c= avcodec_alloc_context();
335     picture= avcodec_alloc_frame();
336
337     if(codec->capabilities&CODEC_CAP_TRUNCATED)
338         c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
339
340     /* For some codecs, such as msmpeg4 and mpeg4, width and height
341        MUST be initialized there because this information is not
342        available in the bitstream. */
343
344     /* open it */
345     if (avcodec_open(c, codec) < 0) {
346         fprintf(stderr, "could not open codec\n");
347         exit(1);
348     }
349
350     /* the codec gives us the frame size, in samples */
351
352     f = fopen(filename, "rb");
353     if (!f) {
354         fprintf(stderr, "could not open %s\n", filename);
355         exit(1);
356     }
357
358     frame = 0;
359     for(;;) {
360         size = fread(inbuf, 1, INBUF_SIZE, f);
361         if (size == 0)
362             break;
363
364         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
365            and this is the only method to use them because you cannot
366            know the compressed data size before analysing it.
367
368            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
369            based, so you must call them with all the data for one
370            frame exactly. You must also initialize 'width' and
371            'height' before initializing them. */
372
373         /* NOTE2: some codecs allow the raw parameters (frame size,
374            sample rate) to be changed at any frame. We handle this, so
375            you should also take care of it */
376
377         /* here, we use a stream based decoder (mpeg1video), so we
378            feed decoder and see if it could decode a frame */
379         inbuf_ptr = inbuf;
380         while (size > 0) {
381             len = avcodec_decode_video(c, picture, &got_picture,
382                                        inbuf_ptr, size);
383             if (len < 0) {
384                 fprintf(stderr, "Error while decoding frame %d\n", frame);
385                 exit(1);
386             }
387             if (got_picture) {
388                 printf("saving frame %3d\n", frame);
389                 fflush(stdout);
390
391                 /* the picture is allocated by the decoder. no need to
392                    free it */
393                 snprintf(buf, sizeof(buf), outfilename, frame);
394                 pgm_save(picture->data[0], picture->linesize[0],
395                          c->width, c->height, buf);
396                 frame++;
397             }
398             size -= len;
399             inbuf_ptr += len;
400         }
401     }
402
403     /* some codecs, such as MPEG, transmit the I and P frame with a
404        latency of one frame. You must do the following to have a
405        chance to get the last frame of the video */
406     len = avcodec_decode_video(c, picture, &got_picture,
407                                NULL, 0);
408     if (got_picture) {
409         printf("saving last frame %3d\n", frame);
410         fflush(stdout);
411
412         /* the picture is allocated by the decoder. no need to
413            free it */
414         snprintf(buf, sizeof(buf), outfilename, frame);
415         pgm_save(picture->data[0], picture->linesize[0],
416                  c->width, c->height, buf);
417         frame++;
418     }
419
420     fclose(f);
421
422     avcodec_close(c);
423     av_free(c);
424     av_free(picture);
425     printf("\n");
426 }
427
428 int main(int argc, char **argv)
429 {
430     const char *filename;
431
432     /* must be called before using avcodec lib */
433     avcodec_init();
434
435     /* register all the codecs */
436     avcodec_register_all();
437
438     if (argc <= 1) {
439         audio_encode_example("/tmp/test.mp2");
440         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
441
442         video_encode_example("/tmp/test.mpg");
443         filename = "/tmp/test.mpg";
444     } else {
445         filename = argv[1];
446     }
447
448     //    audio_decode_example("/tmp/test.sw", filename);
449     video_decode_example("/tmp/test%d.pgm", filename);
450
451     return 0;
452 }