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