X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fapiexample.c;h=151637bd21d7cd43d4125779ed80fd800befcec1;hb=b24daebf22762a6a68a750325c7b6a3e01d2b20e;hp=cab7d79b69a4b0fd27d5bc517d1432b09441ee84;hpb=58f26ba9162f492387c2f5b34856df74644a82f8;p=ffmpeg diff --git a/libavcodec/apiexample.c b/libavcodec/apiexample.c index cab7d79b69a..151637bd21d 100644 --- a/libavcodec/apiexample.c +++ b/libavcodec/apiexample.c @@ -1,30 +1,59 @@ -/* avcodec API use example. +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file apiexample.c + * avcodec API use example. * * Note that this library only handles codecs (mpeg, mpeg4, etc...), - * not file formats (avi, vob, etc...). See library 'libav' for the - * format handling + * not file formats (avi, vob, etc...). See library 'libavformat' for the + * format handling */ + #include #include #include #include +#define PI 3.14159265358979323846 + +#ifdef HAVE_AV_CONFIG_H +#undef HAVE_AV_CONFIG_H +#endif + #include "avcodec.h" #define INBUF_SIZE 4096 /* - * Audio encoding example + * Audio encoding example */ void audio_encode_example(const char *filename) { AVCodec *codec; - AVCodecContext codec_context, *c = &codec_context; + AVCodecContext *c= NULL; int frame_size, i, j, out_size, outbuf_size; FILE *f; short *samples; float t, tincr; - UINT8 *outbuf; + uint8_t *outbuf; printf("Audio encoding\n"); @@ -35,8 +64,7 @@ void audio_encode_example(const char *filename) exit(1); } - /* put default values */ - memset(c, 0, sizeof(*c)); + c= avcodec_alloc_context(); /* put sample parameters */ c->bit_rate = 64000; @@ -48,22 +76,22 @@ void audio_encode_example(const char *filename) fprintf(stderr, "could not open codec\n"); exit(1); } - + /* the codec gives us the frame size, in samples */ frame_size = c->frame_size; samples = malloc(frame_size * 2 * c->channels); outbuf_size = 10000; outbuf = malloc(outbuf_size); - f = fopen(filename, "w"); + f = fopen(filename, "wb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } - + /* encode a single tone sound */ t = 0; - tincr = 2 * M_PI * 440.0 / c->sample_rate; + tincr = 2 * PI * 440.0 / c->sample_rate; for(i=0;i<200;i++) { for(j=0;j 0) { - len = avcodec_decode_audio(c, (short *)outbuf, &out_size, + len = avcodec_decode_audio(c, (short *)outbuf, &out_size, inbuf_ptr, size); if (len < 0) { fprintf(stderr, "Error while decoding\n"); @@ -153,19 +181,20 @@ void audio_decode_example(const char *outfilename, const char *filename) free(outbuf); avcodec_close(c); + av_free(c); } /* - * Video encoding example + * Video encoding example */ void video_encode_example(const char *filename) { AVCodec *codec; - AVCodecContext codec_context, *c = &codec_context; + AVCodecContext *c= NULL; int i, out_size, size, x, y, outbuf_size; FILE *f; - AVPicture picture; - UINT8 *outbuf, *picture_buf; + AVFrame *picture; + uint8_t *outbuf, *picture_buf; printf("Video encoding\n"); @@ -176,67 +205,76 @@ void video_encode_example(const char *filename) exit(1); } - /* put default values */ - memset(c, 0, sizeof(*c)); + c= avcodec_alloc_context(); + picture= avcodec_alloc_frame(); /* put sample parameters */ c->bit_rate = 400000; /* resolution must be a multiple of two */ - c->width = 352; + c->width = 352; c->height = 288; /* frames per second */ - c->frame_rate = 25 * FRAME_RATE_BASE; + c->time_base= (AVRational){1,25}; c->gop_size = 10; /* emit one intra frame every ten frames */ + c->max_b_frames=1; + c->pix_fmt = PIX_FMT_YUV420P; /* open it */ if (avcodec_open(c, codec) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } - - /* the codec gives us the frame size, in samples */ - f = fopen(filename, "w"); + f = fopen(filename, "wb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } - + /* alloc image and output buffer */ outbuf_size = 100000; outbuf = malloc(outbuf_size); size = c->width * c->height; picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */ - - picture.data[0] = picture_buf; - picture.data[1] = picture.data[0] + size; - picture.data[2] = picture.data[1] + size / 4; - picture.linesize[0] = c->width; - picture.linesize[1] = c->width / 2; - picture.linesize[2] = c->width / 2; + + picture->data[0] = picture_buf; + picture->data[1] = picture->data[0] + size; + picture->data[2] = picture->data[1] + size / 4; + picture->linesize[0] = c->width; + picture->linesize[1] = c->width / 2; + picture->linesize[2] = c->width / 2; /* encode 1 second of video */ for(i=0;i<25;i++) { - printf("encoding frame %3d\r", i); fflush(stdout); /* prepare a dummy image */ /* Y */ for(y=0;yheight;y++) { for(x=0;xwidth;x++) { - picture.data[0][y * picture.linesize[0] + x] = x + y + i * 3; + picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; } } /* Cb and Cr */ for(y=0;yheight/2;y++) { for(x=0;xwidth/2;x++) { - picture.data[1][y * picture.linesize[1] + x] = 128 + y + i * 2; - picture.data[2][y * picture.linesize[2] + x] = 64 + x + i * 5; + picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; + picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; } } /* encode the image */ - out_size = avcodec_encode_video(c, outbuf, outbuf_size, &picture); + out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); + printf("encoding frame %3d (size=%5d)\n", i, out_size); + fwrite(outbuf, 1, out_size, f); + } + + /* get the delayed frames */ + for(; out_size; i++) { + fflush(stdout); + + out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); + printf("write frame %3d (size=%5d)\n", i, out_size); fwrite(outbuf, 1, out_size, f); } @@ -251,14 +289,16 @@ void video_encode_example(const char *filename) free(outbuf); avcodec_close(c); + av_free(c); + av_free(picture); printf("\n"); } /* - * Video decoding example + * Video decoding example */ -void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) +void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) { FILE *f; int i; @@ -273,13 +313,16 @@ void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename) void video_decode_example(const char *outfilename, const char *filename) { AVCodec *codec; - AVCodecContext codec_context, *c = &codec_context; + AVCodecContext *c= NULL; int frame, size, got_picture, len; FILE *f; - AVPicture picture; - UINT8 inbuf[INBUF_SIZE], *inbuf_ptr; + AVFrame *picture; + uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr; char buf[1024]; + /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ + memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); + printf("Video decoding\n"); /* find the mpeg1 video decoder */ @@ -289,8 +332,11 @@ void video_decode_example(const char *outfilename, const char *filename) exit(1); } - /* put default values */ - memset(c, 0, sizeof(*c)); + c= avcodec_alloc_context(); + picture= avcodec_alloc_frame(); + + if(codec->capabilities&CODEC_CAP_TRUNCATED) + c->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */ /* for some codecs, such as msmpeg4 and mpeg4, width and height MUST be initialized there because these info are not available @@ -301,15 +347,15 @@ void video_decode_example(const char *outfilename, const char *filename) fprintf(stderr, "could not open codec\n"); exit(1); } - + /* the codec gives us the frame size, in samples */ - f = fopen(filename, "r"); + f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } - + frame = 0; for(;;) { size = fread(inbuf, 1, INBUF_SIZE, f); @@ -318,7 +364,7 @@ void video_decode_example(const char *outfilename, const char *filename) /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio) and this is the only method to use them because you cannot - know the compressed data size before analysing it. + know the compressed data size before analysing it. BUT some other codecs (msmpeg4, mpeg4) are inherently frame based, so you must call them with all the data for one @@ -333,20 +379,20 @@ void video_decode_example(const char *outfilename, const char *filename) feed decoder and see if it could decode a frame */ inbuf_ptr = inbuf; while (size > 0) { - len = avcodec_decode_video(c, &picture, &got_picture, + len = avcodec_decode_video(c, picture, &got_picture, inbuf_ptr, size); if (len < 0) { fprintf(stderr, "Error while decoding frame %d\n", frame); exit(1); } if (got_picture) { - printf("saving frame %3d\r", frame); + printf("saving frame %3d\n", frame); fflush(stdout); /* the picture is allocated by the decoder. no need to free it */ snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture.data[0], picture.linesize[0], + pgm_save(picture->data[0], picture->linesize[0], c->width, c->height, buf); frame++; } @@ -358,27 +404,28 @@ void video_decode_example(const char *outfilename, const char *filename) /* some codecs, such as MPEG, transmit the I and P frame with a latency of one frame. You must do the following to have a chance to get the last frame of the video */ - len = avcodec_decode_video(c, &picture, &got_picture, + len = avcodec_decode_video(c, picture, &got_picture, NULL, 0); if (got_picture) { - printf("saving frame %3d\r", frame); + printf("saving last frame %3d\n", frame); fflush(stdout); - + /* the picture is allocated by the decoder. no need to free it */ snprintf(buf, sizeof(buf), outfilename, frame); - pgm_save(picture.data[0], picture.linesize[0], + pgm_save(picture->data[0], picture->linesize[0], c->width, c->height, buf); frame++; } - + fclose(f); avcodec_close(c); + av_free(c); + av_free(picture); printf("\n"); } - int main(int argc, char **argv) { const char *filename; @@ -389,7 +436,7 @@ int main(int argc, char **argv) /* register all the codecs (you can also register only the codec you wish to have smaller code */ avcodec_register_all(); - + if (argc <= 1) { audio_encode_example("/tmp/test.mp2"); audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");