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