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