Mercurial > libavcodec.hg
annotate apiexample.c @ 4560:a798e8cc5e67 libavcodec
gcc 2.95 fix
author | michael |
---|---|
date | Thu, 22 Feb 2007 00:04:36 +0000 |
parents | 219255141aa1 |
children | de57979c3cd2 |
rev | line source |
---|---|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
1 /* |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
2 * copyright (c) 2001 Fabrice Bellard |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
3 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
4 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
5 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
6 * FFmpeg is free software; you can redistribute it and/or |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
7 * modify it under the terms of the GNU Lesser General Public |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
8 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
9 * version 2.1 of the License, or (at your option) any later version. |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
10 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
11 * FFmpeg is distributed in the hope that it will be useful, |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
14 * Lesser General Public License for more details. |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
15 * |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
16 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
17 * License along with FFmpeg; if not, write to the Free Software |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
19 */ |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
20 |
1106 | 21 /** |
22 * @file apiexample.c | |
23 * avcodec API use example. | |
0 | 24 * |
25 * Note that this library only handles codecs (mpeg, mpeg4, etc...), | |
1427 | 26 * not file formats (avi, vob, etc...). See library 'libavformat' for the |
2967 | 27 * format handling |
0 | 28 */ |
1106 | 29 |
0 | 30 #include <stdlib.h> |
31 #include <stdio.h> | |
32 #include <string.h> | |
33 #include <math.h> | |
34 | |
4545
219255141aa1
Remove a non-C dependency (being M_PI) from the libavcodec example.
takis
parents:
3947
diff
changeset
|
35 #define PI 3.14159265358979323846 |
219255141aa1
Remove a non-C dependency (being M_PI) from the libavcodec example.
takis
parents:
3947
diff
changeset
|
36 |
1059 | 37 #ifdef HAVE_AV_CONFIG_H |
38 #undef HAVE_AV_CONFIG_H | |
39 #endif | |
40 | |
0 | 41 #include "avcodec.h" |
42 | |
43 #define INBUF_SIZE 4096 | |
44 | |
45 /* | |
2967 | 46 * Audio encoding example |
0 | 47 */ |
48 void audio_encode_example(const char *filename) | |
49 { | |
50 AVCodec *codec; | |
685 | 51 AVCodecContext *c= NULL; |
0 | 52 int frame_size, i, j, out_size, outbuf_size; |
53 FILE *f; | |
54 short *samples; | |
55 float t, tincr; | |
1064 | 56 uint8_t *outbuf; |
0 | 57 |
58 printf("Audio encoding\n"); | |
59 | |
60 /* find the MP2 encoder */ | |
61 codec = avcodec_find_encoder(CODEC_ID_MP2); | |
62 if (!codec) { | |
63 fprintf(stderr, "codec not found\n"); | |
64 exit(1); | |
65 } | |
66 | |
685 | 67 c= avcodec_alloc_context(); |
2967 | 68 |
0 | 69 /* put sample parameters */ |
70 c->bit_rate = 64000; | |
71 c->sample_rate = 44100; | |
72 c->channels = 2; | |
73 | |
74 /* open it */ | |
75 if (avcodec_open(c, codec) < 0) { | |
76 fprintf(stderr, "could not open codec\n"); | |
77 exit(1); | |
78 } | |
2967 | 79 |
0 | 80 /* the codec gives us the frame size, in samples */ |
81 frame_size = c->frame_size; | |
82 samples = malloc(frame_size * 2 * c->channels); | |
83 outbuf_size = 10000; | |
84 outbuf = malloc(outbuf_size); | |
85 | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
86 f = fopen(filename, "wb"); |
0 | 87 if (!f) { |
88 fprintf(stderr, "could not open %s\n", filename); | |
89 exit(1); | |
90 } | |
2967 | 91 |
0 | 92 /* encode a single tone sound */ |
93 t = 0; | |
4545
219255141aa1
Remove a non-C dependency (being M_PI) from the libavcodec example.
takis
parents:
3947
diff
changeset
|
94 tincr = 2 * PI * 440.0 / c->sample_rate; |
0 | 95 for(i=0;i<200;i++) { |
96 for(j=0;j<frame_size;j++) { | |
97 samples[2*j] = (int)(sin(t) * 10000); | |
98 samples[2*j+1] = samples[2*j]; | |
99 t += tincr; | |
100 } | |
101 /* encode the samples */ | |
102 out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples); | |
103 fwrite(outbuf, 1, out_size, f); | |
104 } | |
105 fclose(f); | |
106 free(outbuf); | |
107 free(samples); | |
108 | |
109 avcodec_close(c); | |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
110 av_free(c); |
0 | 111 } |
112 | |
113 /* | |
2967 | 114 * Audio decoding. |
0 | 115 */ |
116 void audio_decode_example(const char *outfilename, const char *filename) | |
117 { | |
118 AVCodec *codec; | |
685 | 119 AVCodecContext *c= NULL; |
0 | 120 int out_size, size, len; |
121 FILE *f, *outfile; | |
1064 | 122 uint8_t *outbuf; |
1394 | 123 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr; |
0 | 124 |
125 printf("Audio decoding\n"); | |
2967 | 126 |
1394 | 127 /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ |
128 memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); | |
0 | 129 |
130 /* find the mpeg audio decoder */ | |
131 codec = avcodec_find_decoder(CODEC_ID_MP2); | |
132 if (!codec) { | |
133 fprintf(stderr, "codec not found\n"); | |
134 exit(1); | |
135 } | |
136 | |
685 | 137 c= avcodec_alloc_context(); |
0 | 138 |
139 /* open it */ | |
140 if (avcodec_open(c, codec) < 0) { | |
141 fprintf(stderr, "could not open codec\n"); | |
142 exit(1); | |
143 } | |
2967 | 144 |
0 | 145 outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); |
146 | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
147 f = fopen(filename, "rb"); |
0 | 148 if (!f) { |
149 fprintf(stderr, "could not open %s\n", filename); | |
150 exit(1); | |
151 } | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
152 outfile = fopen(outfilename, "wb"); |
0 | 153 if (!outfile) { |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
154 av_free(c); |
0 | 155 exit(1); |
156 } | |
2967 | 157 |
0 | 158 /* decode until eof */ |
159 inbuf_ptr = inbuf; | |
160 for(;;) { | |
161 size = fread(inbuf, 1, INBUF_SIZE, f); | |
162 if (size == 0) | |
163 break; | |
164 | |
165 inbuf_ptr = inbuf; | |
166 while (size > 0) { | |
2967 | 167 len = avcodec_decode_audio(c, (short *)outbuf, &out_size, |
0 | 168 inbuf_ptr, size); |
169 if (len < 0) { | |
170 fprintf(stderr, "Error while decoding\n"); | |
171 exit(1); | |
172 } | |
173 if (out_size > 0) { | |
174 /* if a frame has been decoded, output it */ | |
175 fwrite(outbuf, 1, out_size, outfile); | |
176 } | |
177 size -= len; | |
178 inbuf_ptr += len; | |
179 } | |
180 } | |
181 | |
182 fclose(outfile); | |
183 fclose(f); | |
184 free(outbuf); | |
185 | |
186 avcodec_close(c); | |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
187 av_free(c); |
0 | 188 } |
189 | |
190 /* | |
2967 | 191 * Video encoding example |
0 | 192 */ |
193 void video_encode_example(const char *filename) | |
194 { | |
195 AVCodec *codec; | |
685 | 196 AVCodecContext *c= NULL; |
0 | 197 int i, out_size, size, x, y, outbuf_size; |
198 FILE *f; | |
925 | 199 AVFrame *picture; |
1064 | 200 uint8_t *outbuf, *picture_buf; |
0 | 201 |
202 printf("Video encoding\n"); | |
203 | |
204 /* find the mpeg1 video encoder */ | |
205 codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); | |
206 if (!codec) { | |
207 fprintf(stderr, "codec not found\n"); | |
208 exit(1); | |
209 } | |
210 | |
685 | 211 c= avcodec_alloc_context(); |
925 | 212 picture= avcodec_alloc_frame(); |
2967 | 213 |
0 | 214 /* put sample parameters */ |
215 c->bit_rate = 400000; | |
216 /* resolution must be a multiple of two */ | |
2967 | 217 c->width = 352; |
0 | 218 c->height = 288; |
219 /* frames per second */ | |
2637 | 220 c->time_base= (AVRational){1,25}; |
0 | 221 c->gop_size = 10; /* emit one intra frame every ten frames */ |
1373 | 222 c->max_b_frames=1; |
2760 | 223 c->pix_fmt = PIX_FMT_YUV420P; |
0 | 224 |
225 /* open it */ | |
226 if (avcodec_open(c, codec) < 0) { | |
227 fprintf(stderr, "could not open codec\n"); | |
228 exit(1); | |
229 } | |
2967 | 230 |
0 | 231 /* the codec gives us the frame size, in samples */ |
232 | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
233 f = fopen(filename, "wb"); |
0 | 234 if (!f) { |
235 fprintf(stderr, "could not open %s\n", filename); | |
236 exit(1); | |
237 } | |
2967 | 238 |
0 | 239 /* alloc image and output buffer */ |
240 outbuf_size = 100000; | |
241 outbuf = malloc(outbuf_size); | |
242 size = c->width * c->height; | |
243 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ | |
2967 | 244 |
919 | 245 picture->data[0] = picture_buf; |
246 picture->data[1] = picture->data[0] + size; | |
247 picture->data[2] = picture->data[1] + size / 4; | |
248 picture->linesize[0] = c->width; | |
249 picture->linesize[1] = c->width / 2; | |
250 picture->linesize[2] = c->width / 2; | |
0 | 251 |
252 /* encode 1 second of video */ | |
253 for(i=0;i<25;i++) { | |
254 fflush(stdout); | |
255 /* prepare a dummy image */ | |
256 /* Y */ | |
257 for(y=0;y<c->height;y++) { | |
258 for(x=0;x<c->width;x++) { | |
919 | 259 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; |
0 | 260 } |
261 } | |
262 | |
263 /* Cb and Cr */ | |
264 for(y=0;y<c->height/2;y++) { | |
265 for(x=0;x<c->width/2;x++) { | |
919 | 266 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; |
267 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; | |
0 | 268 } |
269 } | |
270 | |
271 /* encode the image */ | |
919 | 272 out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); |
1373 | 273 printf("encoding frame %3d (size=%5d)\n", i, out_size); |
274 fwrite(outbuf, 1, out_size, f); | |
275 } | |
276 | |
277 /* get the delayed frames */ | |
278 for(; out_size; i++) { | |
279 fflush(stdout); | |
2967 | 280 |
1373 | 281 out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); |
282 printf("write frame %3d (size=%5d)\n", i, out_size); | |
0 | 283 fwrite(outbuf, 1, out_size, f); |
284 } | |
285 | |
286 /* add sequence end code to have a real mpeg file */ | |
287 outbuf[0] = 0x00; | |
288 outbuf[1] = 0x00; | |
289 outbuf[2] = 0x01; | |
290 outbuf[3] = 0xb7; | |
291 fwrite(outbuf, 1, 4, f); | |
292 fclose(f); | |
293 free(picture_buf); | |
294 free(outbuf); | |
295 | |
296 avcodec_close(c); | |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
297 av_free(c); |
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
298 av_free(picture); |
0 | 299 printf("\n"); |
300 } | |
301 | |
302 /* | |
2967 | 303 * Video decoding example |
0 | 304 */ |
305 | |
2967 | 306 void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) |
0 | 307 { |
308 FILE *f; | |
309 int i; | |
310 | |
311 f=fopen(filename,"w"); | |
312 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255); | |
313 for(i=0;i<ysize;i++) | |
314 fwrite(buf + i * wrap,1,xsize,f); | |
315 fclose(f); | |
316 } | |
317 | |
318 void video_decode_example(const char *outfilename, const char *filename) | |
319 { | |
320 AVCodec *codec; | |
685 | 321 AVCodecContext *c= NULL; |
0 | 322 int frame, size, got_picture, len; |
323 FILE *f; | |
925 | 324 AVFrame *picture; |
1394 | 325 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr; |
0 | 326 char buf[1024]; |
327 | |
1394 | 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 | |
0 | 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 | |
685 | 340 c= avcodec_alloc_context(); |
925 | 341 picture= avcodec_alloc_frame(); |
0 | 342 |
895
1a5926aeed5f
apiexample doesnt send complete frames to the codec
michaelni
parents:
685
diff
changeset
|
343 if(codec->capabilities&CODEC_CAP_TRUNCATED) |
1a5926aeed5f
apiexample doesnt send complete frames to the codec
michaelni
parents:
685
diff
changeset
|
344 c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */ |
1a5926aeed5f
apiexample doesnt send complete frames to the codec
michaelni
parents:
685
diff
changeset
|
345 |
71 | 346 /* for some codecs, such as msmpeg4 and mpeg4, width and height |
0 | 347 MUST be initialized there because these info are not available |
348 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 } | |
2967 | 355 |
0 | 356 /* the codec gives us the frame size, in samples */ |
357 | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
358 f = fopen(filename, "rb"); |
0 | 359 if (!f) { |
360 fprintf(stderr, "could not open %s\n", filename); | |
361 exit(1); | |
362 } | |
2967 | 363 |
0 | 364 frame = 0; |
365 for(;;) { | |
366 size = fread(inbuf, 1, INBUF_SIZE, f); | |
367 if (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 | |
2967 | 372 know the compressed data size before analysing it. |
0 | 373 |
71 | 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 | |
0 | 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 inbuf_ptr = inbuf; | |
386 while (size > 0) { | |
2967 | 387 len = avcodec_decode_video(c, picture, &got_picture, |
0 | 388 inbuf_ptr, size); |
389 if (len < 0) { | |
390 fprintf(stderr, "Error while decoding frame %d\n", frame); | |
391 exit(1); | |
392 } | |
393 if (got_picture) { | |
1373 | 394 printf("saving frame %3d\n", frame); |
0 | 395 fflush(stdout); |
396 | |
397 /* the picture is allocated by the decoder. no need to | |
398 free it */ | |
399 snprintf(buf, sizeof(buf), outfilename, frame); | |
2967 | 400 pgm_save(picture->data[0], picture->linesize[0], |
0 | 401 c->width, c->height, buf); |
402 frame++; | |
403 } | |
404 size -= len; | |
405 inbuf_ptr += len; | |
406 } | |
407 } | |
408 | |
409 /* some codecs, such as MPEG, transmit the I and P frame with a | |
410 latency of one frame. You must do the following to have a | |
411 chance to get the last frame of the video */ | |
2967 | 412 len = avcodec_decode_video(c, picture, &got_picture, |
0 | 413 NULL, 0); |
414 if (got_picture) { | |
1373 | 415 printf("saving last frame %3d\n", frame); |
0 | 416 fflush(stdout); |
2967 | 417 |
0 | 418 /* the picture is allocated by the decoder. no need to |
419 free it */ | |
420 snprintf(buf, sizeof(buf), outfilename, frame); | |
2967 | 421 pgm_save(picture->data[0], picture->linesize[0], |
0 | 422 c->width, c->height, buf); |
423 frame++; | |
424 } | |
2967 | 425 |
0 | 426 fclose(f); |
427 | |
428 avcodec_close(c); | |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
429 av_free(c); |
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
430 av_free(picture); |
0 | 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 (you can also register only the codec | |
442 you wish to have smaller code */ | |
443 avcodec_register_all(); | |
1059 | 444 |
0 | 445 if (argc <= 1) { |
446 audio_encode_example("/tmp/test.mp2"); | |
447 audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); | |
448 | |
449 video_encode_example("/tmp/test.mpg"); | |
450 filename = "/tmp/test.mpg"; | |
451 } else { | |
452 filename = argv[1]; | |
453 } | |
454 | |
455 // audio_decode_example("/tmp/test.sw", filename); | |
456 video_decode_example("/tmp/test%d.pgm", filename); | |
457 | |
458 return 0; | |
459 } |