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

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

Generated on Tue Nov 4 2014 12:59:21 for ffmpeg by  doxygen 1.7.1