• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/api-example.c

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

Generated on Fri Sep 16 2011 17:17:33 for FFmpeg by  doxygen 1.7.1