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