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