00001 /* 00002 * Copyright (c) 2001 Fabrice Bellard 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00017 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00032 #include <math.h> 00033 00034 #include <libavutil/opt.h> 00035 #include <libavcodec/avcodec.h> 00036 #include <libavutil/audioconvert.h> 00037 #include <libavutil/common.h> 00038 #include <libavutil/imgutils.h> 00039 #include <libavutil/mathematics.h> 00040 #include <libavutil/samplefmt.h> 00041 00042 #define INBUF_SIZE 4096 00043 #define AUDIO_INBUF_SIZE 20480 00044 #define AUDIO_REFILL_THRESH 4096 00045 00046 /* check that a given sample format is supported by the encoder */ 00047 static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt) 00048 { 00049 const enum AVSampleFormat *p = codec->sample_fmts; 00050 00051 while (*p != AV_SAMPLE_FMT_NONE) { 00052 if (*p == sample_fmt) 00053 return 1; 00054 p++; 00055 } 00056 return 0; 00057 } 00058 00059 /* just pick the highest supported samplerate */ 00060 static int select_sample_rate(AVCodec *codec) 00061 { 00062 const int *p; 00063 int best_samplerate = 0; 00064 00065 if (!codec->supported_samplerates) 00066 return 44100; 00067 00068 p = codec->supported_samplerates; 00069 while (*p) { 00070 best_samplerate = FFMAX(*p, best_samplerate); 00071 p++; 00072 } 00073 return best_samplerate; 00074 } 00075 00076 /* select layout with the highest channel count */ 00077 static int select_channel_layout(AVCodec *codec) 00078 { 00079 const uint64_t *p; 00080 uint64_t best_ch_layout = 0; 00081 int best_nb_channells = 0; 00082 00083 if (!codec->channel_layouts) 00084 return AV_CH_LAYOUT_STEREO; 00085 00086 p = codec->channel_layouts; 00087 while (*p) { 00088 int nb_channels = av_get_channel_layout_nb_channels(*p); 00089 00090 if (nb_channels > best_nb_channells) { 00091 best_ch_layout = *p; 00092 best_nb_channells = nb_channels; 00093 } 00094 p++; 00095 } 00096 return best_ch_layout; 00097 } 00098 00099 /* 00100 * Audio encoding example 00101 */ 00102 static void audio_encode_example(const char *filename) 00103 { 00104 AVCodec *codec; 00105 AVCodecContext *c= NULL; 00106 AVFrame *frame; 00107 AVPacket pkt; 00108 int i, j, k, ret, got_output; 00109 int buffer_size; 00110 FILE *f; 00111 uint16_t *samples; 00112 float t, tincr; 00113 00114 printf("Encode audio file %s\n", filename); 00115 00116 /* find the MP2 encoder */ 00117 codec = avcodec_find_encoder(AV_CODEC_ID_MP2); 00118 if (!codec) { 00119 fprintf(stderr, "Codec not found\n"); 00120 exit(1); 00121 } 00122 00123 c = avcodec_alloc_context3(codec); 00124 00125 /* put sample parameters */ 00126 c->bit_rate = 64000; 00127 00128 /* check that the encoder supports s16 pcm input */ 00129 c->sample_fmt = AV_SAMPLE_FMT_S16; 00130 if (!check_sample_fmt(codec, c->sample_fmt)) { 00131 fprintf(stderr, "Encoder does not support sample format %s", 00132 av_get_sample_fmt_name(c->sample_fmt)); 00133 exit(1); 00134 } 00135 00136 /* select other audio parameters supported by the encoder */ 00137 c->sample_rate = select_sample_rate(codec); 00138 c->channel_layout = select_channel_layout(codec); 00139 c->channels = av_get_channel_layout_nb_channels(c->channel_layout); 00140 00141 /* open it */ 00142 if (avcodec_open2(c, codec, NULL) < 0) { 00143 fprintf(stderr, "Could not open codec\n"); 00144 exit(1); 00145 } 00146 00147 f = fopen(filename, "wb"); 00148 if (!f) { 00149 fprintf(stderr, "Could not open %s\n", filename); 00150 exit(1); 00151 } 00152 00153 /* frame containing input raw audio */ 00154 frame = avcodec_alloc_frame(); 00155 if (!frame) { 00156 fprintf(stderr, "Could not allocate audio frame\n"); 00157 exit(1); 00158 } 00159 00160 frame->nb_samples = c->frame_size; 00161 frame->format = c->sample_fmt; 00162 frame->channel_layout = c->channel_layout; 00163 00164 /* the codec gives us the frame size, in samples, 00165 * we calculate the size of the samples buffer in bytes */ 00166 buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size, 00167 c->sample_fmt, 0); 00168 samples = av_malloc(buffer_size); 00169 if (!samples) { 00170 fprintf(stderr, "Could not allocate %d bytes for samples buffer\n", 00171 buffer_size); 00172 exit(1); 00173 } 00174 /* setup the data pointers in the AVFrame */ 00175 ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, 00176 (const uint8_t*)samples, buffer_size, 0); 00177 if (ret < 0) { 00178 fprintf(stderr, "Could not setup audio frame\n"); 00179 exit(1); 00180 } 00181 00182 /* encode a single tone sound */ 00183 t = 0; 00184 tincr = 2 * M_PI * 440.0 / c->sample_rate; 00185 for(i=0;i<200;i++) { 00186 av_init_packet(&pkt); 00187 pkt.data = NULL; // packet data will be allocated by the encoder 00188 pkt.size = 0; 00189 00190 for (j = 0; j < c->frame_size; j++) { 00191 samples[2*j] = (int)(sin(t) * 10000); 00192 00193 for (k = 1; k < c->channels; k++) 00194 samples[2*j + k] = samples[2*j]; 00195 t += tincr; 00196 } 00197 /* encode the samples */ 00198 ret = avcodec_encode_audio2(c, &pkt, frame, &got_output); 00199 if (ret < 0) { 00200 fprintf(stderr, "Error encoding audio frame\n"); 00201 exit(1); 00202 } 00203 if (got_output) { 00204 fwrite(pkt.data, 1, pkt.size, f); 00205 av_free_packet(&pkt); 00206 } 00207 } 00208 00209 /* get the delayed frames */ 00210 for (got_output = 1; got_output; i++) { 00211 ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output); 00212 if (ret < 0) { 00213 fprintf(stderr, "Error encoding frame\n"); 00214 exit(1); 00215 } 00216 00217 if (got_output) { 00218 fwrite(pkt.data, 1, pkt.size, f); 00219 av_free_packet(&pkt); 00220 } 00221 } 00222 fclose(f); 00223 00224 av_freep(&samples); 00225 avcodec_free_frame(&frame); 00226 avcodec_close(c); 00227 av_free(c); 00228 } 00229 00230 /* 00231 * Audio decoding. 00232 */ 00233 static void audio_decode_example(const char *outfilename, const char *filename) 00234 { 00235 AVCodec *codec; 00236 AVCodecContext *c= NULL; 00237 int len; 00238 FILE *f, *outfile; 00239 uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 00240 AVPacket avpkt; 00241 AVFrame *decoded_frame = NULL; 00242 00243 av_init_packet(&avpkt); 00244 00245 printf("Decode audio file %s to %s\n", filename, outfilename); 00246 00247 /* find the mpeg audio decoder */ 00248 codec = avcodec_find_decoder(AV_CODEC_ID_MP2); 00249 if (!codec) { 00250 fprintf(stderr, "Codec not found\n"); 00251 exit(1); 00252 } 00253 00254 c = avcodec_alloc_context3(codec); 00255 00256 /* open it */ 00257 if (avcodec_open2(c, codec, NULL) < 0) { 00258 fprintf(stderr, "Could not open codec\n"); 00259 exit(1); 00260 } 00261 00262 f = fopen(filename, "rb"); 00263 if (!f) { 00264 fprintf(stderr, "Could not open %s\n", filename); 00265 exit(1); 00266 } 00267 outfile = fopen(outfilename, "wb"); 00268 if (!outfile) { 00269 av_free(c); 00270 exit(1); 00271 } 00272 00273 /* decode until eof */ 00274 avpkt.data = inbuf; 00275 avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f); 00276 00277 while (avpkt.size > 0) { 00278 int got_frame = 0; 00279 00280 if (!decoded_frame) { 00281 if (!(decoded_frame = avcodec_alloc_frame())) { 00282 fprintf(stderr, "Could not allocate audio frame\n"); 00283 exit(1); 00284 } 00285 } else 00286 avcodec_get_frame_defaults(decoded_frame); 00287 00288 len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); 00289 if (len < 0) { 00290 fprintf(stderr, "Error while decoding\n"); 00291 exit(1); 00292 } 00293 if (got_frame) { 00294 /* if a frame has been decoded, output it */ 00295 int data_size = av_samples_get_buffer_size(NULL, c->channels, 00296 decoded_frame->nb_samples, 00297 c->sample_fmt, 1); 00298 fwrite(decoded_frame->data[0], 1, data_size, outfile); 00299 } 00300 avpkt.size -= len; 00301 avpkt.data += len; 00302 avpkt.dts = 00303 avpkt.pts = AV_NOPTS_VALUE; 00304 if (avpkt.size < AUDIO_REFILL_THRESH) { 00305 /* Refill the input buffer, to avoid trying to decode 00306 * incomplete frames. Instead of this, one could also use 00307 * a parser, or use a proper container format through 00308 * libavformat. */ 00309 memmove(inbuf, avpkt.data, avpkt.size); 00310 avpkt.data = inbuf; 00311 len = fread(avpkt.data + avpkt.size, 1, 00312 AUDIO_INBUF_SIZE - avpkt.size, f); 00313 if (len > 0) 00314 avpkt.size += len; 00315 } 00316 } 00317 00318 fclose(outfile); 00319 fclose(f); 00320 00321 avcodec_close(c); 00322 av_free(c); 00323 avcodec_free_frame(&decoded_frame); 00324 } 00325 00326 /* 00327 * Video encoding example 00328 */ 00329 static void video_encode_example(const char *filename, int codec_id) 00330 { 00331 AVCodec *codec; 00332 AVCodecContext *c= NULL; 00333 int i, ret, x, y, got_output; 00334 FILE *f; 00335 AVFrame *frame; 00336 AVPacket pkt; 00337 uint8_t endcode[] = { 0, 0, 1, 0xb7 }; 00338 00339 printf("Encode video file %s\n", filename); 00340 00341 /* find the mpeg1 video encoder */ 00342 codec = avcodec_find_encoder(codec_id); 00343 if (!codec) { 00344 fprintf(stderr, "Codec not found\n"); 00345 exit(1); 00346 } 00347 00348 c = avcodec_alloc_context3(codec); 00349 00350 /* put sample parameters */ 00351 c->bit_rate = 400000; 00352 /* resolution must be a multiple of two */ 00353 c->width = 352; 00354 c->height = 288; 00355 /* frames per second */ 00356 c->time_base= (AVRational){1,25}; 00357 c->gop_size = 10; /* emit one intra frame every ten frames */ 00358 c->max_b_frames=1; 00359 c->pix_fmt = PIX_FMT_YUV420P; 00360 00361 if(codec_id == AV_CODEC_ID_H264) 00362 av_opt_set(c->priv_data, "preset", "slow", 0); 00363 00364 /* open it */ 00365 if (avcodec_open2(c, codec, NULL) < 0) { 00366 fprintf(stderr, "Could not open codec\n"); 00367 exit(1); 00368 } 00369 00370 f = fopen(filename, "wb"); 00371 if (!f) { 00372 fprintf(stderr, "Could not open %s\n", filename); 00373 exit(1); 00374 } 00375 00376 frame = avcodec_alloc_frame(); 00377 if (!frame) { 00378 fprintf(stderr, "Could not allocate video frame\n"); 00379 exit(1); 00380 } 00381 frame->format = c->pix_fmt; 00382 frame->width = c->width; 00383 frame->height = c->height; 00384 00385 /* the image can be allocated by any means and av_image_alloc() is 00386 * just the most convenient way if av_malloc() is to be used */ 00387 ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height, 00388 c->pix_fmt, 32); 00389 if (ret < 0) { 00390 fprintf(stderr, "Could not allocate raw picture buffer\n"); 00391 exit(1); 00392 } 00393 00394 /* encode 1 second of video */ 00395 for(i=0;i<25;i++) { 00396 av_init_packet(&pkt); 00397 pkt.data = NULL; // packet data will be allocated by the encoder 00398 pkt.size = 0; 00399 00400 fflush(stdout); 00401 /* prepare a dummy image */ 00402 /* Y */ 00403 for(y=0;y<c->height;y++) { 00404 for(x=0;x<c->width;x++) { 00405 frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3; 00406 } 00407 } 00408 00409 /* Cb and Cr */ 00410 for(y=0;y<c->height/2;y++) { 00411 for(x=0;x<c->width/2;x++) { 00412 frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2; 00413 frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5; 00414 } 00415 } 00416 00417 frame->pts = i; 00418 00419 /* encode the image */ 00420 ret = avcodec_encode_video2(c, &pkt, frame, &got_output); 00421 if (ret < 0) { 00422 fprintf(stderr, "Error encoding frame\n"); 00423 exit(1); 00424 } 00425 00426 if (got_output) { 00427 printf("Write frame %3d (size=%5d)\n", i, pkt.size); 00428 fwrite(pkt.data, 1, pkt.size, f); 00429 av_free_packet(&pkt); 00430 } 00431 } 00432 00433 /* get the delayed frames */ 00434 for (got_output = 1; got_output; i++) { 00435 fflush(stdout); 00436 00437 ret = avcodec_encode_video2(c, &pkt, NULL, &got_output); 00438 if (ret < 0) { 00439 fprintf(stderr, "Error encoding frame\n"); 00440 exit(1); 00441 } 00442 00443 if (got_output) { 00444 printf("Write frame %3d (size=%5d)\n", i, pkt.size); 00445 fwrite(pkt.data, 1, pkt.size, f); 00446 av_free_packet(&pkt); 00447 } 00448 } 00449 00450 /* add sequence end code to have a real mpeg file */ 00451 fwrite(endcode, 1, sizeof(endcode), f); 00452 fclose(f); 00453 00454 avcodec_close(c); 00455 av_free(c); 00456 av_freep(&frame->data[0]); 00457 avcodec_free_frame(&frame); 00458 printf("\n"); 00459 } 00460 00461 /* 00462 * Video decoding example 00463 */ 00464 00465 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize, 00466 char *filename) 00467 { 00468 FILE *f; 00469 int i; 00470 00471 f=fopen(filename,"w"); 00472 fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255); 00473 for(i=0;i<ysize;i++) 00474 fwrite(buf + i * wrap,1,xsize,f); 00475 fclose(f); 00476 } 00477 00478 static void video_decode_example(const char *outfilename, const char *filename) 00479 { 00480 AVCodec *codec; 00481 AVCodecContext *c= NULL; 00482 int frame, got_picture, len; 00483 FILE *f; 00484 AVFrame *picture; 00485 uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; 00486 char buf[1024]; 00487 AVPacket avpkt; 00488 00489 av_init_packet(&avpkt); 00490 00491 /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ 00492 memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); 00493 00494 printf("Decode video file %s to %s\n", filename, outfilename); 00495 00496 /* find the mpeg1 video decoder */ 00497 codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO); 00498 if (!codec) { 00499 fprintf(stderr, "Codec not found\n"); 00500 exit(1); 00501 } 00502 00503 c = avcodec_alloc_context3(codec); 00504 if(codec->capabilities&CODEC_CAP_TRUNCATED) 00505 c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */ 00506 00507 /* For some codecs, such as msmpeg4 and mpeg4, width and height 00508 MUST be initialized there because this information is not 00509 available in the bitstream. */ 00510 00511 /* open it */ 00512 if (avcodec_open2(c, codec, NULL) < 0) { 00513 fprintf(stderr, "Could not open codec\n"); 00514 exit(1); 00515 } 00516 00517 /* the codec gives us the frame size, in samples */ 00518 00519 f = fopen(filename, "rb"); 00520 if (!f) { 00521 fprintf(stderr, "Could not open %s\n", filename); 00522 exit(1); 00523 } 00524 00525 picture = avcodec_alloc_frame(); 00526 if (!picture) { 00527 fprintf(stderr, "Could not allocate video frame\n"); 00528 exit(1); 00529 } 00530 00531 frame = 0; 00532 for(;;) { 00533 avpkt.size = fread(inbuf, 1, INBUF_SIZE, f); 00534 if (avpkt.size == 0) 00535 break; 00536 00537 /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) 00538 and this is the only method to use them because you cannot 00539 know the compressed data size before analysing it. 00540 00541 BUT some other codecs (msmpeg4, mpeg4) are inherently frame 00542 based, so you must call them with all the data for one 00543 frame exactly. You must also initialize 'width' and 00544 'height' before initializing them. */ 00545 00546 /* NOTE2: some codecs allow the raw parameters (frame size, 00547 sample rate) to be changed at any frame. We handle this, so 00548 you should also take care of it */ 00549 00550 /* here, we use a stream based decoder (mpeg1video), so we 00551 feed decoder and see if it could decode a frame */ 00552 avpkt.data = inbuf; 00553 while (avpkt.size > 0) { 00554 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); 00555 if (len < 0) { 00556 fprintf(stderr, "Error while decoding frame %d\n", frame); 00557 exit(1); 00558 } 00559 if (got_picture) { 00560 printf("Saving frame %3d\n", frame); 00561 fflush(stdout); 00562 00563 /* the picture is allocated by the decoder. no need to 00564 free it */ 00565 snprintf(buf, sizeof(buf), outfilename, frame); 00566 pgm_save(picture->data[0], picture->linesize[0], 00567 c->width, c->height, buf); 00568 frame++; 00569 } 00570 avpkt.size -= len; 00571 avpkt.data += len; 00572 } 00573 } 00574 00575 /* some codecs, such as MPEG, transmit the I and P frame with a 00576 latency of one frame. You must do the following to have a 00577 chance to get the last frame of the video */ 00578 avpkt.data = NULL; 00579 avpkt.size = 0; 00580 len = avcodec_decode_video2(c, picture, &got_picture, &avpkt); 00581 if (got_picture) { 00582 printf("Saving last frame %3d\n", frame); 00583 fflush(stdout); 00584 00585 /* the picture is allocated by the decoder. no need to 00586 free it */ 00587 snprintf(buf, sizeof(buf), outfilename, frame); 00588 pgm_save(picture->data[0], picture->linesize[0], 00589 c->width, c->height, buf); 00590 frame++; 00591 } 00592 00593 fclose(f); 00594 00595 avcodec_close(c); 00596 av_free(c); 00597 avcodec_free_frame(&picture); 00598 printf("\n"); 00599 } 00600 00601 int main(int argc, char **argv) 00602 { 00603 const char *output_type; 00604 00605 /* register all the codecs */ 00606 avcodec_register_all(); 00607 00608 if (argc < 2) { 00609 printf("usage: %s output_type\n" 00610 "API example program to decode/encode a media stream with libavcodec.\n" 00611 "This program generates a synthetic stream and encodes it to a file\n" 00612 "named test.h264, test.mp2 or test.mpg depending on output_type.\n" 00613 "The encoded stream is then decoded and written to a raw data output\n." 00614 "output_type must be choosen between 'h264', 'mp2', 'mpg'\n", 00615 argv[0]); 00616 return 1; 00617 } 00618 output_type = argv[1]; 00619 00620 if (!strcmp(output_type, "h264")) { 00621 video_encode_example("test.h264", AV_CODEC_ID_H264); 00622 } else if (!strcmp(output_type, "mp2")) { 00623 audio_encode_example("test.mp2"); 00624 audio_decode_example("test.sw", "test.mp2"); 00625 } else if (!strcmp(output_type, "mpg")) { 00626 video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO); 00627 video_decode_example("test%02d.pgm", "test.mpg"); 00628 } else { 00629 fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n", 00630 output_type); 00631 return 1; 00632 } 00633 00634 return 0; 00635 }