OSDN Git Service

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