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