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

Generated on Wed Nov 19 15:44:27 2008 for libextractor by  doxygen 1.5.1