Mercurial > libavcodec.hg
annotate apiexample.c @ 7351:1502ba3beb72 libavcodec
The codebook generator algorithm involves picking three
different codebook centroids ("high utility", "low
utility" and "closest to the low utility one"). This
change avoid the corner case of choosing two times the
same centroid.
author | vitor |
---|---|
date | Wed, 23 Jul 2008 03:54:31 +0000 |
parents | 0134da1737d0 |
children | 98d37cfc40a1 |
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 |
0 | 127 /* find the mpeg audio decoder */ |
128 codec = avcodec_find_decoder(CODEC_ID_MP2); | |
129 if (!codec) { | |
130 fprintf(stderr, "codec not found\n"); | |
131 exit(1); | |
132 } | |
133 | |
685 | 134 c= avcodec_alloc_context(); |
0 | 135 |
136 /* open it */ | |
137 if (avcodec_open(c, codec) < 0) { | |
138 fprintf(stderr, "could not open codec\n"); | |
139 exit(1); | |
140 } | |
2967 | 141 |
0 | 142 outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); |
143 | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
144 f = fopen(filename, "rb"); |
0 | 145 if (!f) { |
146 fprintf(stderr, "could not open %s\n", filename); | |
147 exit(1); | |
148 } | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
149 outfile = fopen(outfilename, "wb"); |
0 | 150 if (!outfile) { |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
151 av_free(c); |
0 | 152 exit(1); |
153 } | |
2967 | 154 |
0 | 155 /* decode until eof */ |
156 inbuf_ptr = inbuf; | |
157 for(;;) { | |
158 size = fread(inbuf, 1, INBUF_SIZE, f); | |
159 if (size == 0) | |
160 break; | |
161 | |
162 inbuf_ptr = inbuf; | |
163 while (size > 0) { | |
2967 | 164 len = avcodec_decode_audio(c, (short *)outbuf, &out_size, |
0 | 165 inbuf_ptr, size); |
166 if (len < 0) { | |
167 fprintf(stderr, "Error while decoding\n"); | |
168 exit(1); | |
169 } | |
170 if (out_size > 0) { | |
171 /* if a frame has been decoded, output it */ | |
172 fwrite(outbuf, 1, out_size, outfile); | |
173 } | |
174 size -= len; | |
175 inbuf_ptr += len; | |
176 } | |
177 } | |
178 | |
179 fclose(outfile); | |
180 fclose(f); | |
181 free(outbuf); | |
182 | |
183 avcodec_close(c); | |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
184 av_free(c); |
0 | 185 } |
186 | |
187 /* | |
2967 | 188 * Video encoding example |
0 | 189 */ |
190 void video_encode_example(const char *filename) | |
191 { | |
192 AVCodec *codec; | |
685 | 193 AVCodecContext *c= NULL; |
0 | 194 int i, out_size, size, x, y, outbuf_size; |
195 FILE *f; | |
925 | 196 AVFrame *picture; |
1064 | 197 uint8_t *outbuf, *picture_buf; |
0 | 198 |
199 printf("Video encoding\n"); | |
200 | |
201 /* find the mpeg1 video encoder */ | |
202 codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); | |
203 if (!codec) { | |
204 fprintf(stderr, "codec not found\n"); | |
205 exit(1); | |
206 } | |
207 | |
685 | 208 c= avcodec_alloc_context(); |
925 | 209 picture= avcodec_alloc_frame(); |
2967 | 210 |
0 | 211 /* put sample parameters */ |
212 c->bit_rate = 400000; | |
213 /* resolution must be a multiple of two */ | |
2967 | 214 c->width = 352; |
0 | 215 c->height = 288; |
216 /* frames per second */ | |
2637 | 217 c->time_base= (AVRational){1,25}; |
0 | 218 c->gop_size = 10; /* emit one intra frame every ten frames */ |
1373 | 219 c->max_b_frames=1; |
2760 | 220 c->pix_fmt = PIX_FMT_YUV420P; |
0 | 221 |
222 /* open it */ | |
223 if (avcodec_open(c, codec) < 0) { | |
224 fprintf(stderr, "could not open codec\n"); | |
225 exit(1); | |
226 } | |
2967 | 227 |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
228 f = fopen(filename, "wb"); |
0 | 229 if (!f) { |
230 fprintf(stderr, "could not open %s\n", filename); | |
231 exit(1); | |
232 } | |
2967 | 233 |
0 | 234 /* alloc image and output buffer */ |
235 outbuf_size = 100000; | |
236 outbuf = malloc(outbuf_size); | |
237 size = c->width * c->height; | |
238 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ | |
2967 | 239 |
919 | 240 picture->data[0] = picture_buf; |
241 picture->data[1] = picture->data[0] + size; | |
242 picture->data[2] = picture->data[1] + size / 4; | |
243 picture->linesize[0] = c->width; | |
244 picture->linesize[1] = c->width / 2; | |
245 picture->linesize[2] = c->width / 2; | |
0 | 246 |
247 /* encode 1 second of video */ | |
248 for(i=0;i<25;i++) { | |
249 fflush(stdout); | |
250 /* prepare a dummy image */ | |
251 /* Y */ | |
252 for(y=0;y<c->height;y++) { | |
253 for(x=0;x<c->width;x++) { | |
919 | 254 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; |
0 | 255 } |
256 } | |
257 | |
258 /* Cb and Cr */ | |
259 for(y=0;y<c->height/2;y++) { | |
260 for(x=0;x<c->width/2;x++) { | |
919 | 261 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; |
262 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; | |
0 | 263 } |
264 } | |
265 | |
266 /* encode the image */ | |
919 | 267 out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); |
1373 | 268 printf("encoding frame %3d (size=%5d)\n", i, out_size); |
269 fwrite(outbuf, 1, out_size, f); | |
270 } | |
271 | |
272 /* get the delayed frames */ | |
273 for(; out_size; i++) { | |
274 fflush(stdout); | |
2967 | 275 |
1373 | 276 out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); |
277 printf("write frame %3d (size=%5d)\n", i, out_size); | |
0 | 278 fwrite(outbuf, 1, out_size, f); |
279 } | |
280 | |
281 /* add sequence end code to have a real mpeg file */ | |
282 outbuf[0] = 0x00; | |
283 outbuf[1] = 0x00; | |
284 outbuf[2] = 0x01; | |
285 outbuf[3] = 0xb7; | |
286 fwrite(outbuf, 1, 4, f); | |
287 fclose(f); | |
288 free(picture_buf); | |
289 free(outbuf); | |
290 | |
291 avcodec_close(c); | |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
292 av_free(c); |
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
293 av_free(picture); |
0 | 294 printf("\n"); |
295 } | |
296 | |
297 /* | |
2967 | 298 * Video decoding example |
0 | 299 */ |
300 | |
2967 | 301 void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) |
0 | 302 { |
303 FILE *f; | |
304 int i; | |
305 | |
306 f=fopen(filename,"w"); | |
307 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255); | |
308 for(i=0;i<ysize;i++) | |
309 fwrite(buf + i * wrap,1,xsize,f); | |
310 fclose(f); | |
311 } | |
312 | |
313 void video_decode_example(const char *outfilename, const char *filename) | |
314 { | |
315 AVCodec *codec; | |
685 | 316 AVCodecContext *c= NULL; |
0 | 317 int frame, size, got_picture, len; |
318 FILE *f; | |
925 | 319 AVFrame *picture; |
1394 | 320 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr; |
0 | 321 char buf[1024]; |
322 | |
1394 | 323 /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ |
324 memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); | |
325 | |
0 | 326 printf("Video decoding\n"); |
327 | |
328 /* find the mpeg1 video decoder */ | |
329 codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO); | |
330 if (!codec) { | |
331 fprintf(stderr, "codec not found\n"); | |
332 exit(1); | |
333 } | |
334 | |
685 | 335 c= avcodec_alloc_context(); |
925 | 336 picture= avcodec_alloc_frame(); |
0 | 337 |
895
1a5926aeed5f
apiexample doesnt send complete frames to the codec
michaelni
parents:
685
diff
changeset
|
338 if(codec->capabilities&CODEC_CAP_TRUNCATED) |
5127 | 339 c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */ |
895
1a5926aeed5f
apiexample doesnt send complete frames to the codec
michaelni
parents:
685
diff
changeset
|
340 |
5127 | 341 /* For some codecs, such as msmpeg4 and mpeg4, width and height |
342 MUST be initialized there because this information is not | |
343 available in the bitstream. */ | |
0 | 344 |
345 /* open it */ | |
346 if (avcodec_open(c, codec) < 0) { | |
347 fprintf(stderr, "could not open codec\n"); | |
348 exit(1); | |
349 } | |
2967 | 350 |
0 | 351 /* the codec gives us the frame size, in samples */ |
352 | |
1931
902556e6d21d
writing corrupt files on MinGW patch by (Matthias Fritschi <choi at netlabs dot org>)
michael
parents:
1427
diff
changeset
|
353 f = fopen(filename, "rb"); |
0 | 354 if (!f) { |
355 fprintf(stderr, "could not open %s\n", filename); | |
356 exit(1); | |
357 } | |
2967 | 358 |
0 | 359 frame = 0; |
360 for(;;) { | |
361 size = fread(inbuf, 1, INBUF_SIZE, f); | |
362 if (size == 0) | |
363 break; | |
364 | |
365 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) | |
366 and this is the only method to use them because you cannot | |
2967 | 367 know the compressed data size before analysing it. |
0 | 368 |
71 | 369 BUT some other codecs (msmpeg4, mpeg4) are inherently frame |
370 based, so you must call them with all the data for one | |
371 frame exactly. You must also initialize 'width' and | |
0 | 372 'height' before initializing them. */ |
373 | |
374 /* NOTE2: some codecs allow the raw parameters (frame size, | |
375 sample rate) to be changed at any frame. We handle this, so | |
376 you should also take care of it */ | |
377 | |
378 /* here, we use a stream based decoder (mpeg1video), so we | |
379 feed decoder and see if it could decode a frame */ | |
380 inbuf_ptr = inbuf; | |
381 while (size > 0) { | |
2967 | 382 len = avcodec_decode_video(c, picture, &got_picture, |
0 | 383 inbuf_ptr, size); |
384 if (len < 0) { | |
385 fprintf(stderr, "Error while decoding frame %d\n", frame); | |
386 exit(1); | |
387 } | |
388 if (got_picture) { | |
1373 | 389 printf("saving frame %3d\n", frame); |
0 | 390 fflush(stdout); |
391 | |
392 /* the picture is allocated by the decoder. no need to | |
393 free it */ | |
394 snprintf(buf, sizeof(buf), outfilename, frame); | |
2967 | 395 pgm_save(picture->data[0], picture->linesize[0], |
0 | 396 c->width, c->height, buf); |
397 frame++; | |
398 } | |
399 size -= len; | |
400 inbuf_ptr += len; | |
401 } | |
402 } | |
403 | |
404 /* some codecs, such as MPEG, transmit the I and P frame with a | |
405 latency of one frame. You must do the following to have a | |
406 chance to get the last frame of the video */ | |
2967 | 407 len = avcodec_decode_video(c, picture, &got_picture, |
0 | 408 NULL, 0); |
409 if (got_picture) { | |
1373 | 410 printf("saving last frame %3d\n", frame); |
0 | 411 fflush(stdout); |
2967 | 412 |
0 | 413 /* the picture is allocated by the decoder. no need to |
414 free it */ | |
415 snprintf(buf, sizeof(buf), outfilename, frame); | |
2967 | 416 pgm_save(picture->data[0], picture->linesize[0], |
0 | 417 c->width, c->height, buf); |
418 frame++; | |
419 } | |
2967 | 420 |
0 | 421 fclose(f); |
422 | |
423 avcodec_close(c); | |
2517
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
424 av_free(c); |
3d8bbb8e7156
use av_free() instead of free() where it's meant to.
mmu_man
parents:
2423
diff
changeset
|
425 av_free(picture); |
0 | 426 printf("\n"); |
427 } | |
428 | |
429 int main(int argc, char **argv) | |
430 { | |
431 const char *filename; | |
432 | |
433 /* must be called before using avcodec lib */ | |
434 avcodec_init(); | |
435 | |
5137 | 436 /* register all the codecs */ |
0 | 437 avcodec_register_all(); |
1059 | 438 |
0 | 439 if (argc <= 1) { |
440 audio_encode_example("/tmp/test.mp2"); | |
441 audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); | |
442 | |
443 video_encode_example("/tmp/test.mpg"); | |
444 filename = "/tmp/test.mpg"; | |
445 } else { | |
446 filename = argv[1]; | |
447 } | |
448 | |
449 // audio_decode_example("/tmp/test.sw", filename); | |
450 video_decode_example("/tmp/test%d.pgm", filename); | |
451 | |
452 return 0; | |
453 } |