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