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