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