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