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