doc/examples/decoding_encoding.c

Go to the documentation of this file.
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 }

Generated on Fri Oct 26 02:49:46 2012 for FFmpeg by doxygen 1.5.8

AltStyle によって変換されたページ (->オリジナル) /