Libav
|
00001 /* 00002 * copyright (c) 2001 Fabrice Bellard 00003 * 00004 * This file is part of FFmpeg. 00005 * 00006 * FFmpeg is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * FFmpeg is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with FFmpeg; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00030 #include <stdlib.h> 00031 #include <stdio.h> 00032 #include <string.h> 00033 00034 #ifdef HAVE_AV_CONFIG_H 00035 #undef HAVE_AV_CONFIG_H 00036 #endif 00037 00038 #include "libavcodec/avcodec.h" 00039 #include "libavutil/mathematics.h" 00040 00041 #define INBUF_SIZE 4096 00042 #define AUDIO_INBUF_SIZE 20480 00043 #define AUDIO_REFILL_THRESH 4096 00044 00045 /* 00046 * Audio encoding example 00047 */ 00048 static void audio_encode_example(const char *filename) 00049 { 00050 AVCodec *codec; 00051 AVCodecContext *c= NULL; 00052 int frame_size, i, j, out_size, outbuf_size; 00053 FILE *f; 00054 short *samples; 00055 float t, tincr; 00056 uint8_t *outbuf; 00057 00058 printf("Audio encoding\n"); 00059 00060 /* find the MP2 encoder */ 00061 codec = avcodec_find_encoder(CODEC_ID_MP2); 00062 if (!codec) { 00063 fprintf(stderr, "codec not found\n"); 00064 exit(1); 00065 } 00066 00067 c= avcodec_alloc_context(); 00068 00069 /* put sample parameters */ 00070 c->bit_rate = 64000; 00071 c->sample_rate = 44100; 00072 c->channels = 2; 00073 00074 /* open it */ 00075 if (avcodec_open(c, codec) < 0) { 00076 fprintf(stderr, "could not open codec\n"); 00077 exit(1); 00078 } 00079 00080 /* the codec gives us the frame size, in samples */ 00081 frame_size = c->frame_size; 00082 samples = malloc(frame_size * 2 * c->channels); 00083 outbuf_size = 10000; 00084 outbuf = malloc(outbuf_size); 00085 00086 f = fopen(filename, "wb"); 00087 if (!f) { 00088 fprintf(stderr, "could not open %s\n", filename); 00089 exit(1); 00090 } 00091 00092 /* encode a single tone sound */ 00093 t = 0; 00094 tincr = 2 * M_PI * 440.0 / c->sample_rate; 00095 for(i=0;i<200;i++) { 00096 for(j=0;j<frame_size;j++) { 00097 samples[2*j] = (int)(sin(t) * 10000); 00098 samples[2*j+1] = samples[2*j]; 00099 t += tincr; 00100 } 00101 /* encode the samples */ 00102 out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples); 00103 fwrite(outbuf, 1, out_size, f); 00104 } 00105 fclose(f); 00106 free(outbuf); 00107 free(samples); 00108 00109 avcodec_close(c); 00110 av_free(c); 00111 } 00112 00113 /* 00114 * Audio decoding. 00115 */ 00116 static void audio_decode_example(const char *outfilename, const char *filename) 00117 { 00118 AVCodec *codec; 00119 AVCodecContext *c= NULL; 00120 int out_size, len; 00121 FILE *f, *outfile; 00122 uint8_t *outbuf; 00123 uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 00124 AVPacket avpkt; 00125 00126 av_init_packet(&avpkt); 00127 00128 printf("Audio decoding\n"); 00129 00130 /* find the mpeg audio decoder */ 00131 codec = avcodec_find_decoder(CODEC_ID_MP2); 00132 if (!codec) { 00133 fprintf(stderr, "codec not found\n"); 00134 exit(1); 00135 } 00136 00137 c= avcodec_alloc_context(); 00138 00139 /* open it */ 00140 if (avcodec_open(c, codec) < 0) { 00141 fprintf(stderr, "could not open codec\n"); 00142 exit(1); 00143 } 00144 00145 outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); 00146 00147 f = fopen(filename, "rb"); 00148 if (!f) { 00149 fprintf(stderr, "could not open %s\n", filename); 00150 exit(1); 00151 } 00152 outfile = fopen(outfilename, "wb"); 00153 if (!outfile) { 00154 av_free(c); 00155 exit(1); 00156 } 00157 00158 /* decode until eof */ 00159 avpkt.data = inbuf; 00160 avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); 00161 00162 while (avpkt.size > 0) { 00163 out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; 00164 len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt); 00165 if (len < 0) { 00166 fprintf(stderr, "Error while decoding\n"); 00167 exit(1); 00168 } 00169 if (out_size > 0) { 00170 /* if a frame has been decoded, output it */ 00171 fwrite(outbuf, 1, out_size, outfile); 00172 } 00173 avpkt.size -= len; 00174 avpkt.data += len; 00175 if (avpkt.size < AUDIO_REFILL_THRESH) { 00176 /* Refill the input buffer, to avoid trying to decode 00177 * incomplete frames. Instead of this, one could also use 00178 * a parser, or use a proper container format through 00179 * libavformat. */ 00180 memmove(inbuf, avpkt.data, avpkt.size); 00181 avpkt.data = inbuf; 00182 len = fread(avpkt.data + avpkt.size, 1, 00183 AUDIO_INBUF_SIZE - avpkt.size, f); 00184 if (len > 0) 00185 avpkt.size += len; 00186 } 00187 } 00188 00189 fclose(outfile); 00190 fclose(f); 00191 free(outbuf); 00192 00193 avcodec_close(c); 00194 av_free(c); 00195 } 00196 00197 /* 00198 * Video encoding example 00199 */ 00200 static void video_encode_example(const char *filename) 00201 { 00202 AVCodec *codec; 00203 AVCodecContext *c= NULL; 00204 int i, out_size, size, x, y, outbuf_size; 00205 FILE *f; 00206 AVFrame *picture; 00207 uint8_t *outbuf, *picture_buf; 00208 00209 printf("Video encoding\n"); 00210 00211 /* find the mpeg1 video encoder */ 00212 codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); 00213 if (!codec) { 00214 fprintf(stderr, "codec not found\n"); 00215 exit(1); 00216 } 00217 00218 c= avcodec_alloc_context(); 00219 picture= avcodec_alloc_frame(); 00220 00221 /* put sample parameters */ 00222 c->bit_rate = 400000; 00223 /* resolution must be a multiple of two */ 00224 c->width = 352; 00225 c->height = 288; 00226 /* frames per second */ 00227 c->time_base= (AVRational){1,25}; 00228 c->gop_size = 10; /* emit one intra frame every ten frames */ 00229 c->max_b_frames=1; 00230 c->pix_fmt = PIX_FMT_YUV420P; 00231 00232 /* open it */ 00233 if (avcodec_open(c, codec) < 0) { 00234 fprintf(stderr, "could not open codec\n"); 00235 exit(1); 00236 } 00237 00238 f = fopen(filename, "wb"); 00239 if (!f) { 00240 fprintf(stderr, "could not open %s\n", filename); 00241 exit(1); 00242 } 00243 00244 /* alloc image and output buffer */ 00245 outbuf_size = 100000; 00246 outbuf = malloc(outbuf_size); 00247 size = c->width * c->height; 00248 picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ 00249 00250 picture->data[0] = picture_buf; 00251 picture->data[1] = picture->data[0] + size; 00252 picture->data[2] = picture->data[1] + size / 4; 00253 picture->linesize[0] = c->width; 00254 picture->linesize[1] = c->width / 2; 00255 picture->linesize[2] = c->width / 2; 00256 00257 /* encode 1 second of video */ 00258 for(i=0;i<25;i++) { 00259 fflush(stdout); 00260 /* prepare a dummy image */ 00261 /* Y */ 00262 for(y=0;y<c->height;y++) { 00263 for(x=0;x<c->width;x++) { 00264 picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; 00265 } 00266 } 00267 00268 /* Cb and Cr */ 00269 for(y=0;y<c->height/2;y++) { 00270 for(x=0;x<c->width/2;x++) { 00271 picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; 00272 picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; 00273 } 00274 } 00275 00276 /* encode the image */ 00277 out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); 00278 printf("encoding frame %3d (size=%5d)\n", i, out_size); 00279 fwrite(outbuf, 1, out_size, f); 00280 } 00281 00282 /* get the delayed frames */ 00283 for(; out_size; i++) { 00284 fflush(stdout); 00285 00286 out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); 00287 printf("write frame %3d (size=%5d)\n", i, out_size); 00288 fwrite(outbuf, 1, out_size, f); 00289 } 00290 00291 /* add sequence end code to have a real mpeg file */ 00292 outbuf[0] = 0x00; 00293 outbuf[1] = 0x00; 00294 outbuf[2] = 0x01; 00295 outbuf[3] = 0xb7; 00296 fwrite(outbuf, 1, 4, f); 00297 fclose(f); 00298 free(picture_buf); 00299 free(outbuf); 00300 00301 avcodec_close(c); 00302 av_free(c); 00303 av_free(picture); 00304 printf("\n"); 00305 } 00306 00307 /* 00308 * Video decoding example 00309 */ 00310 00311 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, 00312 char *filename) 00313 { 00314 FILE *f; 00315 int i; 00316 00317 f=fopen(filename,"w"); 00318 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255); 00319 for(i=0;i<ysize;i++) 00320 fwrite(buf + i * wrap,1,xsize,f); 00321 fclose(f); 00322 } 00323 00324 static void video_decode_example(const char *outfilename, const char *filename) 00325 { 00326 AVCodec *codec; 00327 AVCodecContext *c= NULL; 00328 int frame, got_picture, len; 00329 FILE *f; 00330 AVFrame *picture; 00331 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 00332 char buf[1024]; 00333 AVPacket avpkt; 00334 00335 av_init_packet(&avpkt); 00336 00337 /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ 00338 memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); 00339 00340 printf("Video decoding\n"); 00341 00342 /* find the mpeg1 video decoder */ 00343 codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO); 00344 if (!codec) { 00345 fprintf(stderr, "codec not found\n"); 00346 exit(1); 00347 } 00348 00349 c= avcodec_alloc_context(); 00350 picture= avcodec_alloc_frame(); 00351 00352 if(codec->capabilities&CODEC_CAP_TRUNCATED) 00353 c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */ 00354 00355 /* For some codecs, such as msmpeg4 and mpeg4, width and height 00356 MUST be initialized there because this information is not 00357 available in the bitstream. */ 00358 00359 /* open it */ 00360 if (avcodec_open(c, codec) < 0) { 00361 fprintf(stderr, "could not open codec\n"); 00362 exit(1); 00363 } 00364 00365 /* the codec gives us the frame size, in samples */ 00366 00367 f = fopen(filename, "rb"); 00368 if (!f) { 00369 fprintf(stderr, "could not open %s\n", filename); 00370 exit(1); 00371 } 00372 00373 frame = 0; 00374 for(;;) { 00375 avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); 00376 if (avpkt.size == 0) 00377 break; 00378 00379 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) 00380 and this is the only method to use them because you cannot 00381 know the compressed data size before analysing it. 00382 00383 BUT some other codecs (msmpeg4, mpeg4) are inherently frame 00384 based, so you must call them with all the data for one 00385 frame exactly. You must also initialize 'width' and 00386 'height' before initializing them. */ 00387 00388 /* NOTE2: some codecs allow the raw parameters (frame size, 00389 sample rate) to be changed at any frame. We handle this, so 00390 you should also take care of it */ 00391 00392 /* here, we use a stream based decoder (mpeg1video), so we 00393 feed decoder and see if it could decode a frame */ 00394 avpkt.data = inbuf; 00395 while (avpkt.size > 0) { 00396 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); 00397 if (len < 0) { 00398 fprintf(stderr, "Error while decoding frame %d\n", frame); 00399 exit(1); 00400 } 00401 if (got_picture) { 00402 printf("saving frame %3d\n", frame); 00403 fflush(stdout); 00404 00405 /* the picture is allocated by the decoder. no need to 00406 free it */ 00407 snprintf(buf, sizeof(buf), outfilename, frame); 00408 pgm_save(picture->data[0], picture->linesize[0], 00409 c->width, c->height, buf); 00410 frame++; 00411 } 00412 avpkt.size -= len; 00413 avpkt.data += len; 00414 } 00415 } 00416 00417 /* some codecs, such as MPEG, transmit the I and P frame with a 00418 latency of one frame. You must do the following to have a 00419 chance to get the last frame of the video */ 00420 avpkt.data = NULL; 00421 avpkt.size = 0; 00422 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); 00423 if (got_picture) { 00424 printf("saving last frame %3d\n", frame); 00425 fflush(stdout); 00426 00427 /* the picture is allocated by the decoder. no need to 00428 free it */ 00429 snprintf(buf, sizeof(buf), outfilename, frame); 00430 pgm_save(picture->data[0], picture->linesize[0], 00431 c->width, c->height, buf); 00432 frame++; 00433 } 00434 00435 fclose(f); 00436 00437 avcodec_close(c); 00438 av_free(c); 00439 av_free(picture); 00440 printf("\n"); 00441 } 00442 00443 int main(int argc, char **argv) 00444 { 00445 const char *filename; 00446 00447 /* must be called before using avcodec lib */ 00448 avcodec_init(); 00449 00450 /* register all the codecs */ 00451 avcodec_register_all(); 00452 00453 if (argc <= 1) { 00454 audio_encode_example("/tmp/test.mp2"); 00455 audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); 00456 00457 video_encode_example("/tmp/test.mpg"); 00458 filename = "/tmp/test.mpg"; 00459 } else { 00460 filename = argv[1]; 00461 } 00462 00463 // audio_decode_example("/tmp/test.sw", filename); 00464 video_decode_example("/tmp/test%d.pgm", filename); 00465 00466 return 0; 00467 }