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