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