]> 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_open2(c, codec, NULL) < 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_open2(c, codec, NULL) < 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         avpkt.dts =
184         avpkt.pts = AV_NOPTS_VALUE;
185         if (avpkt.size < AUDIO_REFILL_THRESH) {
186             /* Refill the input buffer, to avoid trying to decode
187              * incomplete frames. Instead of this, one could also use
188              * a parser, or use a proper container format through
189              * libavformat. */
190             memmove(inbuf, avpkt.data, avpkt.size);
191             avpkt.data = inbuf;
192             len = fread(avpkt.data + avpkt.size, 1,
193                         AUDIO_INBUF_SIZE - avpkt.size, f);
194             if (len > 0)
195                 avpkt.size += len;
196         }
197     }
198
199     fclose(outfile);
200     fclose(f);
201
202     avcodec_close(c);
203     av_free(c);
204     av_free(decoded_frame);
205 }
206
207 /*
208  * Video encoding example
209  */
210 static void video_encode_example(const char *filename, int codec_id)
211 {
212     AVCodec *codec;
213     AVCodecContext *c= NULL;
214     int i, out_size, size, x, y, outbuf_size;
215     FILE *f;
216     AVFrame *picture;
217     uint8_t *outbuf;
218
219     printf("Video encoding\n");
220
221     /* find the mpeg1 video encoder */
222     codec = avcodec_find_encoder(codec_id);
223     if (!codec) {
224         fprintf(stderr, "codec not found\n");
225         exit(1);
226     }
227
228     c = avcodec_alloc_context3(codec);
229     picture= avcodec_alloc_frame();
230
231     /* put sample parameters */
232     c->bit_rate = 400000;
233     /* resolution must be a multiple of two */
234     c->width = 352;
235     c->height = 288;
236     /* frames per second */
237     c->time_base= (AVRational){1,25};
238     c->gop_size = 10; /* emit one intra frame every ten frames */
239     c->max_b_frames=1;
240     c->pix_fmt = PIX_FMT_YUV420P;
241
242     if(codec_id == CODEC_ID_H264)
243         av_opt_set(c->priv_data, "preset", "slow", 0);
244
245     /* open it */
246     if (avcodec_open2(c, codec, NULL) < 0) {
247         fprintf(stderr, "could not open codec\n");
248         exit(1);
249     }
250
251     f = fopen(filename, "wb");
252     if (!f) {
253         fprintf(stderr, "could not open %s\n", filename);
254         exit(1);
255     }
256
257     /* alloc image and output buffer */
258     outbuf_size = 100000;
259     outbuf = malloc(outbuf_size);
260
261     /* the image can be allocated by any means and av_image_alloc() is
262      * just the most convenient way if av_malloc() is to be used */
263     av_image_alloc(picture->data, picture->linesize,
264                    c->width, c->height, c->pix_fmt, 1);
265
266     /* encode 1 second of video */
267     for(i=0;i<25;i++) {
268         fflush(stdout);
269         /* prepare a dummy image */
270         /* Y */
271         for(y=0;y<c->height;y++) {
272             for(x=0;x<c->width;x++) {
273                 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
274             }
275         }
276
277         /* Cb and Cr */
278         for(y=0;y<c->height/2;y++) {
279             for(x=0;x<c->width/2;x++) {
280                 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
281                 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
282             }
283         }
284
285         /* encode the image */
286         out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
287         printf("encoding frame %3d (size=%5d)\n", i, out_size);
288         fwrite(outbuf, 1, out_size, f);
289     }
290
291     /* get the delayed frames */
292     for(; out_size; i++) {
293         fflush(stdout);
294
295         out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
296         printf("write frame %3d (size=%5d)\n", i, out_size);
297         fwrite(outbuf, 1, out_size, f);
298     }
299
300     /* add sequence end code to have a real mpeg file */
301     outbuf[0] = 0x00;
302     outbuf[1] = 0x00;
303     outbuf[2] = 0x01;
304     outbuf[3] = 0xb7;
305     fwrite(outbuf, 1, 4, f);
306     fclose(f);
307     free(outbuf);
308
309     avcodec_close(c);
310     av_free(c);
311     av_free(picture->data[0]);
312     av_free(picture);
313     printf("\n");
314 }
315
316 /*
317  * Video decoding example
318  */
319
320 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
321                      char *filename)
322 {
323     FILE *f;
324     int i;
325
326     f=fopen(filename,"w");
327     fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
328     for(i=0;i<ysize;i++)
329         fwrite(buf + i * wrap,1,xsize,f);
330     fclose(f);
331 }
332
333 static void video_decode_example(const char *outfilename, const char *filename)
334 {
335     AVCodec *codec;
336     AVCodecContext *c= NULL;
337     int frame, got_picture, len;
338     FILE *f;
339     AVFrame *picture;
340     uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
341     char buf[1024];
342     AVPacket avpkt;
343
344     av_init_packet(&avpkt);
345
346     /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
347     memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
348
349     printf("Video decoding\n");
350
351     /* find the mpeg1 video decoder */
352     codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
353     if (!codec) {
354         fprintf(stderr, "codec not found\n");
355         exit(1);
356     }
357
358     c = avcodec_alloc_context3(codec);
359     picture= avcodec_alloc_frame();
360
361     if(codec->capabilities&CODEC_CAP_TRUNCATED)
362         c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
363
364     /* For some codecs, such as msmpeg4 and mpeg4, width and height
365        MUST be initialized there because this information is not
366        available in the bitstream. */
367
368     /* open it */
369     if (avcodec_open2(c, codec, NULL) < 0) {
370         fprintf(stderr, "could not open codec\n");
371         exit(1);
372     }
373
374     /* the codec gives us the frame size, in samples */
375
376     f = fopen(filename, "rb");
377     if (!f) {
378         fprintf(stderr, "could not open %s\n", filename);
379         exit(1);
380     }
381
382     frame = 0;
383     for(;;) {
384         avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
385         if (avpkt.size == 0)
386             break;
387
388         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
389            and this is the only method to use them because you cannot
390            know the compressed data size before analysing it.
391
392            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
393            based, so you must call them with all the data for one
394            frame exactly. You must also initialize 'width' and
395            'height' before initializing them. */
396
397         /* NOTE2: some codecs allow the raw parameters (frame size,
398            sample rate) to be changed at any frame. We handle this, so
399            you should also take care of it */
400
401         /* here, we use a stream based decoder (mpeg1video), so we
402            feed decoder and see if it could decode a frame */
403         avpkt.data = inbuf;
404         while (avpkt.size > 0) {
405             len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
406             if (len < 0) {
407                 fprintf(stderr, "Error while decoding frame %d\n", frame);
408                 exit(1);
409             }
410             if (got_picture) {
411                 printf("saving frame %3d\n", frame);
412                 fflush(stdout);
413
414                 /* the picture is allocated by the decoder. no need to
415                    free it */
416                 snprintf(buf, sizeof(buf), outfilename, frame);
417                 pgm_save(picture->data[0], picture->linesize[0],
418                          c->width, c->height, buf);
419                 frame++;
420             }
421             avpkt.size -= len;
422             avpkt.data += len;
423         }
424     }
425
426     /* some codecs, such as MPEG, transmit the I and P frame with a
427        latency of one frame. You must do the following to have a
428        chance to get the last frame of the video */
429     avpkt.data = NULL;
430     avpkt.size = 0;
431     len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
432     if (got_picture) {
433         printf("saving last frame %3d\n", frame);
434         fflush(stdout);
435
436         /* the picture is allocated by the decoder. no need to
437            free it */
438         snprintf(buf, sizeof(buf), outfilename, frame);
439         pgm_save(picture->data[0], picture->linesize[0],
440                  c->width, c->height, buf);
441         frame++;
442     }
443
444     fclose(f);
445
446     avcodec_close(c);
447     av_free(c);
448     av_free(picture);
449     printf("\n");
450 }
451
452 int main(int argc, char **argv)
453 {
454     const char *filename;
455
456     /* register all the codecs */
457     avcodec_register_all();
458
459     if (argc <= 1) {
460         audio_encode_example("/tmp/test.mp2");
461         audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
462
463         video_encode_example("/tmp/test.h264", CODEC_ID_H264);
464         video_encode_example("/tmp/test.mpg", CODEC_ID_MPEG1VIDEO);
465         filename = "/tmp/test.mpg";
466     } else {
467         filename = argv[1];
468     }
469
470     //    audio_decode_example("/tmp/test.sw", filename);
471     video_decode_example("/tmp/test%d.pgm", filename);
472
473     return 0;
474 }