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

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