From fe1b62fb3e8757e9db791bd4c4f647ca50834f40 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Mon, 10 Feb 2003 09:40:23 +0000 Subject: [PATCH] * still unfinished code for Options * demo code - awating more comments Originally committed as revision 1569 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/apiexample.c | 84 ++++++++++++++++++++++++++++++++++++++++- libavcodec/avcodec.c | 38 +++++++++---------- libavcodec/common.h | 18 +++++++++ libavcodec/mpegvideo.c | 25 ++++++++++++ 4 files changed, 145 insertions(+), 20 deletions(-) diff --git a/libavcodec/apiexample.c b/libavcodec/apiexample.c index 0f730d4f54..51304e4cef 100644 --- a/libavcodec/apiexample.c +++ b/libavcodec/apiexample.c @@ -9,6 +9,10 @@ #include #include +#ifdef HAVE_AV_CONFIG_H +#undef HAVE_AV_CONFIG_H +#endif + #include "avcodec.h" #define INBUF_SIZE 4096 @@ -385,6 +389,80 @@ void video_decode_example(const char *outfilename, const char *filename) printf("\n"); } +// simple example how the options could be used +int options_example(int argc, char* argv[]) +{ + AVCodec* codec = avcodec_find_encoder_by_name((argc > 1) ? argv[2] : "mpeg4"); + const AVOption* c; + AVCodecContext* avctx; + char* def = av_malloc(5000); + const char* col = ""; + int i = 0; + + if (!codec) + return -1; + c = codec->options; + avctx = avcodec_alloc_context(); + *def = 0; + + if (c) { + const AVOption *stack[FF_OPT_MAX_DEPTH]; + int depth = 0; + for (;;) { + if (!c->name) { + if (c->sub) { + stack[depth++] = c; + c = c->sub; + } else { + if (depth == 0) + break; // finished + c = stack[--depth]; + c++; + } + } else { + int t = c->type & FF_OPT_TYPE_MASK; + printf("Config %s %s\n", + t == FF_OPT_TYPE_BOOL ? "bool " : + t == FF_OPT_TYPE_DOUBLE ? "double " : + t == FF_OPT_TYPE_INT ? "integer" : + t == FF_OPT_TYPE_STRING ? "string " : + "unknown??", c->name); + switch (t) { + case FF_OPT_TYPE_BOOL: + i += sprintf(def + i, "%s%s=%s", + col, c->name, + c->defval != 0. ? "on" : "off"); + break; + case FF_OPT_TYPE_DOUBLE: + i += sprintf(def + i, "%s%s=%f", + col, c->name, c->defval); + break; + case FF_OPT_TYPE_INT: + i += sprintf(def + i, "%s%s=%d", + col, c->name, (int) c->defval); + break; + case FF_OPT_TYPE_STRING: + if (c->defstr) { + char* d = av_strdup(c->defstr); + char* f = strchr(d, ','); + if (f) + *f = 0; + i += sprintf(def + i, "%s%s=%s", + col, c->name, d); + av_free(d); + } + break; + } + col = ":"; + c++; + } + } + } + printf("Default Options: %s\n", def); + av_free(def); + return 0; +} + int main(int argc, char **argv) { @@ -396,7 +474,10 @@ 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(); - + +#ifdef OPT_TEST + options_example(argc, argv); +#else if (argc <= 1) { audio_encode_example("/tmp/test.mp2"); audio_decode_example("/tmp/test.sw", "/tmp/test.mp2"); @@ -409,6 +490,7 @@ int main(int argc, char **argv) // audio_decode_example("/tmp/test.sw", filename); video_decode_example("/tmp/test%d.pgm", filename); +#endif return 0; } diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index c82b773c65..b1fb5c88a8 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -50,9 +50,9 @@ static AVCodec* avcodec_find_by_fcc(uint32_t fcc) return NULL; } -static private_handle_t* create_handle() +static private_handle_t* create_handle(void) { - private_handle_t* t = malloc(sizeof(private_handle_t)); + private_handle_t* t = av_malloc(sizeof(private_handle_t)); if (!t) return NULL; memset(t, 0, sizeof(*t)); @@ -82,7 +82,7 @@ static void destroy_handle(private_handle_t* handle) { avcodec_close(&handle->avcontext); } - free(handle); + av_free(handle); // count referencies } @@ -96,13 +96,13 @@ int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout) case AVC_OPEN_BY_NAME: { // pin char* codec name - private_handle_t* handle = create_handle(); - (private_handle_t**)pout = handle; - if (!handle) + private_handle_t* h = create_handle(); + (private_handle_t**)pout = h; + if (!h) return -ENOMEM; - if (!handle->avcodec) + if (!h->avcodec) { - destroy_handle(handle); + destroy_handle(h); (private_handle_t**)pout = NULL; return -1;// better error } @@ -111,14 +111,14 @@ int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout) case AVC_OPEN_BY_CODEC_ID: { // pin uint32_t codec fourcc - private_handle_t* handle = create_handle(); - (private_handle_t**)pout = handle; - if (!handle) + private_handle_t* h = create_handle(); + (private_handle_t**)pout = h; + if (!h) return -ENOMEM; - if (!handle->avcodec) + if (!h->avcodec) { - destroy_handle(handle); + destroy_handle(h); (private_handle_t**)pout = NULL; return -1;// better error } @@ -127,14 +127,14 @@ int avcodec(void* handle, avc_cmd_t cmd, void* pin, void* pout) case AVC_OPEN_BY_FOURCC: { // pin uint32_t codec fourcc - private_handle_t* handle = create_handle(); - (private_handle_t**)pout = handle; - if (!handle) + private_handle_t* h = create_handle(); + (private_handle_t**)pout = h; + if (!h) return -ENOMEM; - handle->avcodec = avcodec_find_by_fcc((uint32_t) pin); - if (!handle->avcodec) + h->avcodec = avcodec_find_by_fcc((uint32_t) pin); + if (!h->avcodec) { - destroy_handle(handle); + destroy_handle(h); (private_handle_t**)pout = NULL; return -1;// better error } diff --git a/libavcodec/common.h b/libavcodec/common.h index e2bec49218..a6ad987510 100644 --- a/libavcodec/common.h +++ b/libavcodec/common.h @@ -37,6 +37,24 @@ #define M_PI 3.14159265358979323846 #endif +#include +#ifndef offsetof +# define offsetof(T,F) ((unsigned int)((char *)&((T *)0)->F)) +#endif + +#define AVOPTION_CODEC_BOOL(name, help, field) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_BOOL } +#define AVOPTION_CODEC_FLAG(name, help, field, flag, defval) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_FLAG, flag, 0, defval } +#define AVOPTION_CODEC_INT(name, help, field, minv, maxv, defval) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_INT, minv, maxv, defval } +#define AVOPTION_CODEC_STRING(name, help, field, str, val) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_STRING, .defval = val, .defstr = str } +#define AVOPTION_CODEC_RCOVERRIDE(name, help, field) \ + { name, help, offsetof(AVCodecContext, field), FF_OPT_TYPE_RCOVERRIDE, .defval = 0, .defstr = NULL } +#define AVOPTION_SUB(ptr) { .name = NULL, .sub = ptr } +#define AVOPTION_END() AVOPTION_SUB(NULL) + #endif /* HAVE_AV_CONFIG_H */ /* Suppress restrict if it was not defined in config.h. */ diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 34687d735e..956efb9f46 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -3998,6 +3998,30 @@ char ff_get_pict_type_char(int pict_type){ } } +extern const AVOption common_options[2]; +static const AVOption mpeg4_options[] = +{ + AVOPTION_CODEC_INT("bitrate", "desired video bitrate", bit_rate, 4, 240000000, 800000), + AVOPTION_CODEC_FLAG("vhq", "very high quality", flags, CODEC_FLAG_HQ, 0), + AVOPTION_CODEC_INT("ratetol", "number of bits the bitstream is allowed to diverge from the reference" + "the reference can be CBR (for CBR pass1) or VBR (for pass2)", + bit_rate_tolerance, 4, 240000000, 8000), + AVOPTION_CODEC_INT("qmin", "minimum quantizer", qmin, 1, 31, 2), + AVOPTION_CODEC_INT("qmax", "maximum quantizer", qmax, 1, 31, 31), + AVOPTION_CODEC_STRING("rc_eq", "rate control equation", + rc_eq, "tex^qComp,option1,options2", 0), + AVOPTION_CODEC_INT("rc_minrate", "rate control minimum bitrate", + rc_min_rate, 4, 24000000, 0), + AVOPTION_CODEC_INT("rc_maxrate", "rate control maximum bitrate", + rc_max_rate, 4, 24000000, 0), + AVOPTION_CODEC_FLAG("psnr", "calculate PSNR of compressed frames", + flags, CODEC_FLAG_PSNR, 0), + AVOPTION_CODEC_RCOVERRIDE("rc_override", "ratecontrol override (=startframe,endframe,qscale,quality_factor)", + rc_override), + AVOPTION_SUB(common_options), + AVOPTION_END() +}; + AVCodec mpeg1video_encoder = { "mpeg1video", CODEC_TYPE_VIDEO, @@ -4048,6 +4072,7 @@ AVCodec mpeg4_encoder = { MPV_encode_init, MPV_encode_picture, MPV_encode_end, + .options = mpeg4_options, }; AVCodec msmpeg4v1_encoder = {