]> git.sesse.net Git - ffmpeg/blob - libavcodec/api-example.c
ARM: intmath: use native-size return types for clipping functions
[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/audioconvert.h"
41 #include "libavutil/mathematics.h"
42 #include "libavutil/samplefmt.h"
43
44 #define INBUF_SIZE 4096
45 #define AUDIO_INBUF_SIZE 20480
46 #define AUDIO_REFILL_THRESH 4096
47
48 /* check that a given sample format is supported by the encoder */
49 static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
50 {
51     const enum AVSampleFormat *p = codec->sample_fmts;
52
53     while (*p != AV_SAMPLE_FMT_NONE) {
54         if (*p == sample_fmt)
55             return 1;
56         p++;
57     }
58     return 0;
59 }
60
61 /* just pick the highest supported samplerate */
62 static int select_sample_rate(AVCodec *codec)
63 {
64     const int *p;
65     int best_samplerate = 0;
66
67     if (!codec->supported_samplerates)
68         return 44100;
69
70     p = codec->supported_samplerates;
71     while (*p) {
72         best_samplerate = FFMAX(*p, best_samplerate);
73         p++;
74     }
75     return best_samplerate;
76 }
77
78 /* select layout with the highest channel count */
79 static int select_channel_layout(AVCodec *codec)
80 {
81     const uint64_t *p;
82     uint64_t best_ch_layout = 0;
83     int best_nb_channells   = 0;
84
85     if (!codec->channel_layouts)
86         return AV_CH_LAYOUT_STEREO;
87
88     p = codec->channel_layouts;
89     while (*p) {
90         int nb_channels = av_get_channel_layout_nb_channels(*p);
91
92         if (nb_channels > best_nb_channells) {
93             best_ch_layout    = *p;
94             best_nb_channells = nb_channels;
95         }
96         p++;
97     }
98     return best_ch_layout;
99 }
100
101 /*
102  * Audio encoding example
103  */
104 static void audio_encode_example(const char *filename)
105 {
106     AVCodec *codec;
107     AVCodecContext *c= NULL;
108     AVFrame *frame;
109     AVPacket pkt;
110     int i, j, k, ret, got_output;
111     int buffer_size;
112     FILE *f;
113     uint16_t *samples;
114     float t, tincr;
115
116     printf("Audio encoding\n");
117
118     /* find the MP2 encoder */
119     codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
120     if (!codec) {
121         fprintf(stderr, "codec not found\n");
122         exit(1);
123     }
124
125     c = avcodec_alloc_context3(codec);
126
127     /* put sample parameters */
128     c->bit_rate = 64000;
129
130     /* check that the encoder supports s16 pcm input */
131     c->sample_fmt = AV_SAMPLE_FMT_S16;
132     if (!check_sample_fmt(codec, c->sample_fmt)) {
133         fprintf(stderr, "encoder does not support %s",
134                 av_get_sample_fmt_name(c->sample_fmt));
135         exit(1);
136     }
137
138     /* select other audio parameters supported by the encoder */
139     c->sample_rate    = select_sample_rate(codec);
140     c->channel_layout = select_channel_layout(codec);
141     c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
142
143     /* open it */
144     if (avcodec_open2(c, codec, NULL) < 0) {
145         fprintf(stderr, "could not open codec\n");
146         exit(1);
147     }
148
149     f = fopen(filename, "wb");
150     if (!f) {
151         fprintf(stderr, "could not open %s\n", filename);
152         exit(1);
153     }
154
155     /* frame containing input raw audio */
156     frame = avcodec_alloc_frame();
157     if (!frame) {
158         fprintf(stderr, "could not allocate audio frame\n");
159         exit(1);
160     }
161
162     frame->nb_samples     = c->frame_size;
163     frame->format         = c->sample_fmt;
164     frame->channel_layout = c->channel_layout;
165
166     /* the codec gives us the frame size, in samples,
167      * we calculate the size of the samples buffer in bytes */
168     buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
169                                              c->sample_fmt, 0);
170     samples = av_malloc(buffer_size);
171     if (!samples) {
172         fprintf(stderr, "could not allocate %d bytes for samples buffer\n",
173                 buffer_size);
174         exit(1);
175     }
176     /* setup the data pointers in the AVFrame */
177     ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
178                                    (const uint8_t*)samples, buffer_size, 0);
179     if (ret < 0) {
180         fprintf(stderr, "could not setup audio frame\n");
181         exit(1);
182     }
183
184     /* encode a single tone sound */
185     t = 0;
186     tincr = 2 * M_PI * 440.0 / c->sample_rate;
187     for(i=0;i<200;i++) {
188         av_init_packet(&pkt);
189         pkt.data = NULL; // packet data will be allocated by the encoder
190         pkt.size = 0;
191
192         for (j = 0; j < c->frame_size; j++) {
193             samples[2*j] = (int)(sin(t) * 10000);
194
195             for (k = 1; k < c->channels; k++)
196                 samples[2*j + k] = samples[2*j];
197             t += tincr;
198         }
199         /* encode the samples */
200         ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
201         if (ret < 0) {
202             fprintf(stderr, "error encoding audio frame\n");
203             exit(1);
204         }
205         if (got_output) {
206             fwrite(pkt.data, 1, pkt.size, f);
207             av_free_packet(&pkt);
208         }
209     }
210     fclose(f);
211
212     av_freep(&samples);
213     av_freep(&frame);
214     avcodec_close(c);
215     av_free(c);
216 }
217
218 /*
219  * Audio decoding.
220  */
221 static void audio_decode_example(const char *outfilename, const char *filename)
222 {
223     AVCodec *codec;
224     AVCodecContext *c= NULL;
225     int len;
226     FILE *f, *outfile;
227     uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
228     AVPacket avpkt;
229     AVFrame *decoded_frame = NULL;
230
231     av_init_packet(&avpkt);
232
233     printf("Audio decoding\n");
234
235     /* find the mpeg audio decoder */
236     codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
237     if (!codec) {
238         fprintf(stderr, "codec not found\n");
239         exit(1);
240     }
241
242     c = avcodec_alloc_context3(codec);
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, "rb");
251     if (!f) {
252         fprintf(stderr, "could not open %s\n", filename);
253         exit(1);
254     }
255     outfile = fopen(outfilename, "wb");
256     if (!outfile) {
257         av_free(c);
258         exit(1);
259     }
260
261     /* decode until eof */
262     avpkt.data = inbuf;
263     avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
264
265     while (avpkt.size > 0) {
266         int got_frame = 0;
267
268         if (!decoded_frame) {
269             if (!(decoded_frame = avcodec_alloc_frame())) {
270                 fprintf(stderr, "out of memory\n");
271                 exit(1);
272             }
273         } else
274             avcodec_get_frame_defaults(decoded_frame);
275
276         len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
277         if (len < 0) {
278             fprintf(stderr, "Error while decoding\n");
279             exit(1);
280         }
281         if (got_frame) {
282             /* if a frame has been decoded, output it */
283             int data_size = av_samples_get_buffer_size(NULL, c->channels,
284                                                        decoded_frame->nb_samples,
285                                                        c->sample_fmt, 1);
286             fwrite(decoded_frame->data[0], 1, data_size, outfile);
287         }
288         avpkt.size -= len;
289         avpkt.data += len;
290         if (avpkt.size < AUDIO_REFILL_THRESH) {
291             /* Refill the input buffer, to avoid trying to decode
292              * incomplete frames. Instead of this, one could also use
293              * a parser, or use a proper container format through
294              * libavformat. */
295             memmove(inbuf, avpkt.data, avpkt.size);
296             avpkt.data = inbuf;
297             len = fread(avpkt.data + avpkt.size, 1,
298                         AUDIO_INBUF_SIZE - avpkt.size, f);
299             if (len > 0)
300                 avpkt.size += len;
301         }
302     }
303
304     fclose(outfile);
305     fclose(f);
306
307     avcodec_close(c);
308     av_free(c);
309     av_free(decoded_frame);
310 }
311
312 /*
313  * Video encoding example
314  */
315 static void video_encode_example(const char *filename)
316 {
317     AVCodec *codec;
318     AVCodecContext *c= NULL;
319     int i, out_size, size, x, y, outbuf_size;
320     FILE *f;
321     AVFrame *picture;
322     uint8_t *outbuf, *picture_buf;
323
324     printf("Video encoding\n");
325
326     /* find the mpeg1 video encoder */
327     codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);
328     if (!codec) {
329         fprintf(stderr, "codec not found\n");
330         exit(1);
331     }
332
333     c = avcodec_alloc_context3(codec);
334     picture= avcodec_alloc_frame();
335
336     /* put sample parameters */
337     c->bit_rate = 400000;
338     /* resolution must be a multiple of two */
339     c->width = 352;
340     c->height = 288;
341     /* frames per second */
342     c->time_base= (AVRational){1,25};
343     c->gop_size = 10; /* emit one intra frame every ten frames */
344     c->max_b_frames=1;
345     c->pix_fmt = PIX_FMT_YUV420P;
346
347     /* open it */
348     if (avcodec_open2(c, codec, NULL) < 0) {
349         fprintf(stderr, "could not open codec\n");
350         exit(1);
351     }
352
353     f = fopen(filename, "wb");
354     if (!f) {
355         fprintf(stderr, "could not open %s\n", filename);
356         exit(1);
357     }
358
359     /* alloc image and output buffer */
360     outbuf_size = 100000;
361     outbuf = malloc(outbuf_size);
362     size = c->width * c->height;
363     picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
364
365     picture->data[0] = picture_buf;
366     picture->data[1] = picture->data[0] + size;
367     picture->data[2] = picture->data[1] + size / 4;
368     picture->linesize[0] = c->width;
369     picture->linesize[1] = c->width / 2;
370     picture->linesize[2] = c->width / 2;
371
372     /* encode 1 second of video */
373     for(i=0;i<25;i++) {
374         fflush(stdout);
375         /* prepare a dummy image */
376         /* Y */
377         for(y=0;y<c->height;y++) {
378             for(x=0;x<c->width;x++) {
379                 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
380             }
381         }
382
383         /* Cb and Cr */
384         for(y=0;y<c->height/2;y++) {
385             for(x=0;x<c->width/2;x++) {
386                 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
387                 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
388             }
389         }
390
391         /* encode the image */
392         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
393         printf("encoding frame %3d (size=%5d)\n", i, out_size);
394         fwrite(outbuf, 1, out_size, f);
395     }
396
397     /* get the delayed frames */
398     for(; out_size; i++) {
399         fflush(stdout);
400
401         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
402         printf("write frame %3d (size=%5d)\n", i, out_size);
403         fwrite(outbuf, 1, out_size, f);
404     }
405
406     /* add sequence end code to have a real mpeg file */
407     outbuf[0] = 0x00;
408     outbuf[1] = 0x00;
409     outbuf[2] = 0x01;
410     outbuf[3] = 0xb7;
411     fwrite(outbuf, 1, 4, f);
412     fclose(f);
413     free(picture_buf);
414     free(outbuf);
415
416     avcodec_close(c);
417     av_free(c);
418     av_free(picture);
419     printf("\n");
420 }
421
422 /*
423  * Video decoding example
424  */
425
426 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
427                      char *filename)
428 {
429     FILE *f;
430     int i;
431
432     f=fopen(filename,"w");
433     fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
434     for(i=0;i<ysize;i++)
435         fwrite(buf + i * wrap,1,xsize,f);
436     fclose(f);
437 }
438
439 static void video_decode_example(const char *outfilename, const char *filename)
440 {
441     AVCodec *codec;
442     AVCodecContext *c= NULL;
443     int frame, got_picture, len;
444     FILE *f;
445     AVFrame *picture;
446     uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
447     char buf[1024];
448     AVPacket avpkt;
449
450     av_init_packet(&avpkt);
451
452     /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
453     memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
454
455     printf("Video decoding\n");
456
457     /* find the mpeg1 video decoder */
458     codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
459     if (!codec) {
460         fprintf(stderr, "codec not found\n");
461         exit(1);
462     }
463
464     c = avcodec_alloc_context3(codec);
465     picture= avcodec_alloc_frame();
466
467     if(codec->capabilities&CODEC_CAP_TRUNCATED)
468         c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
469
470     /* For some codecs, such as msmpeg4 and mpeg4, width and height
471        MUST be initialized there because this information is not
472        available in the bitstream. */
473
474     /* open it */
475     if (avcodec_open2(c, codec, NULL) < 0) {
476         fprintf(stderr, "could not open codec\n");
477         exit(1);
478     }
479
480     /* the codec gives us the frame size, in samples */
481
482     f = fopen(filename, "rb");
483     if (!f) {
484         fprintf(stderr, "could not open %s\n", filename);
485         exit(1);
486     }
487
488     frame = 0;
489     for(;;) {
490         avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
491         if (avpkt.size == 0)
492             break;
493
494         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
495            and this is the only method to use them because you cannot
496            know the compressed data size before analysing it.
497
498            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
499            based, so you must call them with all the data for one
500            frame exactly. You must also initialize 'width' and
501            'height' before initializing them. */
502
503         /* NOTE2: some codecs allow the raw parameters (frame size,
504            sample rate) to be changed at any frame. We handle this, so
505            you should also take care of it */
506
507         /* here, we use a stream based decoder (mpeg1video), so we
508            feed decoder and see if it could decode a frame */
509         avpkt.data = inbuf;
510         while (avpkt.size > 0) {
511             len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
512             if (len < 0) {
513                 fprintf(stderr, "Error while decoding frame %d\n", frame);
514                 exit(1);
515             }
516             if (got_picture) {
517                 printf("saving frame %3d\n", frame);
518                 fflush(stdout);
519
520                 /* the picture is allocated by the decoder. no need to
521                    free it */
522                 snprintf(buf, sizeof(buf), outfilename, frame);
523                 pgm_save(picture->data[0], picture->linesize[0],
524                          c->width, c->height, buf);
525                 frame++;
526             }
527             avpkt.size -= len;
528             avpkt.data += len;
529         }
530     }
531
532     /* some codecs, such as MPEG, transmit the I and P frame with a
533        latency of one frame. You must do the following to have a
534        chance to get the last frame of the video */
535     avpkt.data = NULL;
536     avpkt.size = 0;
537     len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
538     if (got_picture) {
539         printf("saving last frame %3d\n", frame);
540         fflush(stdout);
541
542         /* the picture is allocated by the decoder. no need to
543            free it */
544         snprintf(buf, sizeof(buf), outfilename, frame);
545         pgm_save(picture->data[0], picture->linesize[0],
546                  c->width, c->height, buf);
547         frame++;
548     }
549
550     fclose(f);
551
552     avcodec_close(c);
553     av_free(c);
554     av_free(picture);
555     printf("\n");
556 }
557
558 int main(int argc, char **argv)
559 {
560     const char *filename;
561
562     /* register all the codecs */
563     avcodec_register_all();
564
565     if (argc <= 1) {
566         audio_encode_example("/tmp/test.mp2");
567         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
568
569         video_encode_example("/tmp/test.mpg");
570         filename = "/tmp/test.mpg";
571     } else {
572         filename = argv[1];
573     }
574
575     //    audio_decode_example("/tmp/test.sw", filename);
576     video_decode_example("/tmp/test%d.pgm", filename);
577
578     return 0;
579 }