mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 20:42:49 +08:00 
			
		
		
		
	Move av_set_options_string() from libavfilter to libavutil.
Originally committed as revision 25236 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
		| @@ -26,7 +26,7 @@ | ||||
|  | ||||
| #define LIBAVFILTER_VERSION_MAJOR  1 | ||||
| #define LIBAVFILTER_VERSION_MINOR 47 | ||||
| #define LIBAVFILTER_VERSION_MICRO  0 | ||||
| #define LIBAVFILTER_VERSION_MICRO  1 | ||||
|  | ||||
| #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ | ||||
|                                                LIBAVFILTER_VERSION_MINOR, \ | ||||
|   | ||||
| @@ -251,110 +251,10 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Store the value in the field in ctx that is named like key. | ||||
|  * ctx must be an AVClass context, storing is done using AVOptions. | ||||
|  * | ||||
|  * @param buf the string to parse, buf will be updated to point at the | ||||
|  * separator just after the parsed key/value pair | ||||
|  * @param key_val_sep a 0-terminated list of characters used to | ||||
|  * separate key from value | ||||
|  * @param pairs_sep a 0-terminated list of characters used to separate | ||||
|  * two pairs from each other | ||||
|  * @return 0 if the key/value pair has been successfully parsed and | ||||
|  * set, or a negative value corresponding to an AVERROR code in case | ||||
|  * of error: | ||||
|  * AVERROR(EINVAL) if the key/value pair cannot be parsed, | ||||
|  * the error code issued by av_set_string3() if the key/value pair | ||||
|  * cannot be set | ||||
|  */ | ||||
| static int parse_key_value_pair(void *ctx, const char **buf, | ||||
|                                 const char *key_val_sep, const char *pairs_sep) | ||||
| { | ||||
|     char *key = av_get_token(buf, key_val_sep); | ||||
|     char *val; | ||||
|     int ret; | ||||
|  | ||||
|     if (*key && strspn(*buf, key_val_sep)) { | ||||
|         (*buf)++; | ||||
|         val = av_get_token(buf, pairs_sep); | ||||
|     } else { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); | ||||
|         av_free(key); | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
|  | ||||
|     av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key); | ||||
|  | ||||
|     ret = av_set_string3(ctx, key, val, 1, NULL); | ||||
|     if (ret == AVERROR(ENOENT)) | ||||
|         av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); | ||||
|  | ||||
|     av_free(key); | ||||
|     av_free(val); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| int av_set_options_string(void *ctx, const char *opts, | ||||
|                           const char *key_val_sep, const char *pairs_sep) | ||||
| { | ||||
|     int ret, count = 0; | ||||
|  | ||||
|     while (*opts) { | ||||
|         if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) | ||||
|             return ret; | ||||
|         count++; | ||||
|  | ||||
|         if (*opts) | ||||
|             opts++; | ||||
|     } | ||||
|  | ||||
|     return count; | ||||
| } | ||||
|  | ||||
| #ifdef TEST | ||||
|  | ||||
| #undef printf | ||||
|  | ||||
| typedef struct TestContext | ||||
| { | ||||
|     const AVClass *class; | ||||
|     int num; | ||||
|     int toggle; | ||||
|     char *string; | ||||
|     int flags; | ||||
|     AVRational rational; | ||||
| } TestContext; | ||||
|  | ||||
| #define OFFSET(x) offsetof(TestContext, x) | ||||
|  | ||||
| #define TEST_FLAG_COOL 01 | ||||
| #define TEST_FLAG_LAME 02 | ||||
| #define TEST_FLAG_MU   04 | ||||
|  | ||||
| static const AVOption test_options[]= { | ||||
| {"num",      "set num",        OFFSET(num),      FF_OPT_TYPE_INT,      0,              0,        100                 }, | ||||
| {"toggle",   "set toggle",     OFFSET(toggle),   FF_OPT_TYPE_INT,      0,              0,        1                   }, | ||||
| {"rational", "set rational",   OFFSET(rational), FF_OPT_TYPE_RATIONAL, 0,              0,        10                  }, | ||||
| {"string",   "set string",     OFFSET(string),   FF_OPT_TYPE_STRING,   0,              CHAR_MIN, CHAR_MAX            }, | ||||
| {"flags",    "set flags",      OFFSET(flags),    FF_OPT_TYPE_FLAGS,    0,              0,        INT_MAX, 0, "flags" }, | ||||
| {"cool",     "set cool flag ", 0,                FF_OPT_TYPE_CONST,    TEST_FLAG_COOL, INT_MIN,  INT_MAX, 0, "flags" }, | ||||
| {"lame",     "set lame flag ", 0,                FF_OPT_TYPE_CONST,    TEST_FLAG_LAME, INT_MIN,  INT_MAX, 0, "flags" }, | ||||
| {"mu",       "set mu flag ",   0,                FF_OPT_TYPE_CONST,    TEST_FLAG_MU,   INT_MIN,  INT_MAX, 0, "flags" }, | ||||
| {NULL}, | ||||
| }; | ||||
|  | ||||
| static const char *test_get_name(void *ctx) | ||||
| { | ||||
|     return "test"; | ||||
| } | ||||
|  | ||||
| static const AVClass test_class = { | ||||
|     "TestContext", | ||||
|     test_get_name, | ||||
|     test_options | ||||
| }; | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|     int i; | ||||
| @@ -405,45 +305,6 @@ int main(void) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     printf("\nTesting av_set_options_string()\n"); | ||||
|     { | ||||
|         TestContext test_ctx; | ||||
|         const char *options[] = { | ||||
|             "", | ||||
|             ":", | ||||
|             "=", | ||||
|             "foo=:", | ||||
|             ":=foo", | ||||
|             "=foo", | ||||
|             "foo=", | ||||
|             "foo", | ||||
|             "foo=val", | ||||
|             "foo==val", | ||||
|             "toggle=:", | ||||
|             "string=:", | ||||
|             "toggle=1 : foo", | ||||
|             "toggle=100", | ||||
|             "toggle==1", | ||||
|             "flags=+mu-lame : num=42: toggle=0", | ||||
|             "num=42 : string=blahblah", | ||||
|             "rational=0 : rational=1/2 : rational=1/-1", | ||||
|             "rational=-1/0", | ||||
|         }; | ||||
|  | ||||
|         test_ctx.class = &test_class; | ||||
|         av_opt_set_defaults2(&test_ctx, 0, 0); | ||||
|         test_ctx.string = av_strdup("default"); | ||||
|  | ||||
|         av_log_set_level(AV_LOG_DEBUG); | ||||
|  | ||||
|         for (i=0; i < FF_ARRAY_ELEMS(options); i++) { | ||||
|             av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); | ||||
|             if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0) | ||||
|                 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); | ||||
|             printf("\n"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -46,23 +46,4 @@ | ||||
|  */ | ||||
| int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx); | ||||
|  | ||||
| /** | ||||
|  * Parse the key/value pairs list in opts. For each key/value pair | ||||
|  * found, stores the value in the field in ctx that is named like the | ||||
|  * key. ctx must be an AVClass context, storing is done using | ||||
|  * AVOptions. | ||||
|  * | ||||
|  * @param key_val_sep a 0-terminated list of characters used to | ||||
|  * separate key from value | ||||
|  * @param pairs_sep a 0-terminated list of characters used to separate | ||||
|  * two pairs from each other | ||||
|  * @return the number of successfully set key/value pairs, or a negative | ||||
|  * value corresponding to an AVERROR code in case of error: | ||||
|  * AVERROR(EINVAL) if opts cannot be parsed, | ||||
|  * the error code issued by av_set_string3() if a key/value pair | ||||
|  * cannot be set | ||||
|  */ | ||||
| int av_set_options_string(void *ctx, const char *opts, | ||||
|                           const char *key_val_sep, const char *pairs_sep); | ||||
|  | ||||
| #endif  /* AVFILTER_PARSEUTILS_H */ | ||||
|   | ||||
| @@ -40,7 +40,7 @@ | ||||
| #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) | ||||
|  | ||||
| #define LIBAVUTIL_VERSION_MAJOR 50 | ||||
| #define LIBAVUTIL_VERSION_MINOR 30 | ||||
| #define LIBAVUTIL_VERSION_MINOR 31 | ||||
| #define LIBAVUTIL_VERSION_MICRO  0 | ||||
|  | ||||
| #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | ||||
|   | ||||
							
								
								
									
										152
									
								
								libavutil/opt.c
									
									
									
									
									
								
							
							
						
						
									
										152
									
								
								libavutil/opt.c
									
									
									
									
									
								
							| @@ -26,6 +26,7 @@ | ||||
|  */ | ||||
|  | ||||
| #include "avutil.h" | ||||
| #include "avstring.h" | ||||
| #include "opt.h" | ||||
| #include "eval.h" | ||||
|  | ||||
| @@ -452,3 +453,154 @@ void av_opt_set_defaults(void *s) | ||||
|     av_opt_set_defaults2(s, 0, 0); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Store the value in the field in ctx that is named like key. | ||||
|  * ctx must be an AVClass context, storing is done using AVOptions. | ||||
|  * | ||||
|  * @param buf the string to parse, buf will be updated to point at the | ||||
|  * separator just after the parsed key/value pair | ||||
|  * @param key_val_sep a 0-terminated list of characters used to | ||||
|  * separate key from value | ||||
|  * @param pairs_sep a 0-terminated list of characters used to separate | ||||
|  * two pairs from each other | ||||
|  * @return 0 if the key/value pair has been successfully parsed and | ||||
|  * set, or a negative value corresponding to an AVERROR code in case | ||||
|  * of error: | ||||
|  * AVERROR(EINVAL) if the key/value pair cannot be parsed, | ||||
|  * the error code issued by av_set_string3() if the key/value pair | ||||
|  * cannot be set | ||||
|  */ | ||||
| static int parse_key_value_pair(void *ctx, const char **buf, | ||||
|                                 const char *key_val_sep, const char *pairs_sep) | ||||
| { | ||||
|     char *key = av_get_token(buf, key_val_sep); | ||||
|     char *val; | ||||
|     int ret; | ||||
|  | ||||
|     if (*key && strspn(*buf, key_val_sep)) { | ||||
|         (*buf)++; | ||||
|         val = av_get_token(buf, pairs_sep); | ||||
|     } else { | ||||
|         av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key); | ||||
|         av_free(key); | ||||
|         return AVERROR(EINVAL); | ||||
|     } | ||||
|  | ||||
|     av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key); | ||||
|  | ||||
|     ret = av_set_string3(ctx, key, val, 1, NULL); | ||||
|     if (ret == AVERROR(ENOENT)) | ||||
|         av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key); | ||||
|  | ||||
|     av_free(key); | ||||
|     av_free(val); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| int av_set_options_string(void *ctx, const char *opts, | ||||
|                           const char *key_val_sep, const char *pairs_sep) | ||||
| { | ||||
|     int ret, count = 0; | ||||
|  | ||||
|     while (*opts) { | ||||
|         if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) | ||||
|             return ret; | ||||
|         count++; | ||||
|  | ||||
|         if (*opts) | ||||
|             opts++; | ||||
|     } | ||||
|  | ||||
|     return count; | ||||
| } | ||||
|  | ||||
| #ifdef TEST | ||||
|  | ||||
| #undef printf | ||||
|  | ||||
| typedef struct TestContext | ||||
| { | ||||
|     const AVClass *class; | ||||
|     int num; | ||||
|     int toggle; | ||||
|     char *string; | ||||
|     int flags; | ||||
|     AVRational rational; | ||||
| } TestContext; | ||||
|  | ||||
| #define OFFSET(x) offsetof(TestContext, x) | ||||
|  | ||||
| #define TEST_FLAG_COOL 01 | ||||
| #define TEST_FLAG_LAME 02 | ||||
| #define TEST_FLAG_MU   04 | ||||
|  | ||||
| static const AVOption test_options[]= { | ||||
| {"num",      "set num",        OFFSET(num),      FF_OPT_TYPE_INT,      0,              0,        100                 }, | ||||
| {"toggle",   "set toggle",     OFFSET(toggle),   FF_OPT_TYPE_INT,      0,              0,        1                   }, | ||||
| {"rational", "set rational",   OFFSET(rational), FF_OPT_TYPE_RATIONAL, 0,              0,        10                  }, | ||||
| {"string",   "set string",     OFFSET(string),   FF_OPT_TYPE_STRING,   0,              CHAR_MIN, CHAR_MAX            }, | ||||
| {"flags",    "set flags",      OFFSET(flags),    FF_OPT_TYPE_FLAGS,    0,              0,        INT_MAX, 0, "flags" }, | ||||
| {"cool",     "set cool flag ", 0,                FF_OPT_TYPE_CONST,    TEST_FLAG_COOL, INT_MIN,  INT_MAX, 0, "flags" }, | ||||
| {"lame",     "set lame flag ", 0,                FF_OPT_TYPE_CONST,    TEST_FLAG_LAME, INT_MIN,  INT_MAX, 0, "flags" }, | ||||
| {"mu",       "set mu flag ",   0,                FF_OPT_TYPE_CONST,    TEST_FLAG_MU,   INT_MIN,  INT_MAX, 0, "flags" }, | ||||
| {NULL}, | ||||
| }; | ||||
|  | ||||
| static const char *test_get_name(void *ctx) | ||||
| { | ||||
|     return "test"; | ||||
| } | ||||
|  | ||||
| static const AVClass test_class = { | ||||
|     "TestContext", | ||||
|     test_get_name, | ||||
|     test_options | ||||
| }; | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|     int i; | ||||
|  | ||||
|     printf("\nTesting av_set_options_string()\n"); | ||||
|     { | ||||
|         TestContext test_ctx; | ||||
|         const char *options[] = { | ||||
|             "", | ||||
|             ":", | ||||
|             "=", | ||||
|             "foo=:", | ||||
|             ":=foo", | ||||
|             "=foo", | ||||
|             "foo=", | ||||
|             "foo", | ||||
|             "foo=val", | ||||
|             "foo==val", | ||||
|             "toggle=:", | ||||
|             "string=:", | ||||
|             "toggle=1 : foo", | ||||
|             "toggle=100", | ||||
|             "toggle==1", | ||||
|             "flags=+mu-lame : num=42: toggle=0", | ||||
|             "num=42 : string=blahblah", | ||||
|             "rational=0 : rational=1/2 : rational=1/-1", | ||||
|             "rational=-1/0", | ||||
|         }; | ||||
|  | ||||
|         test_ctx.class = &test_class; | ||||
|         av_opt_set_defaults2(&test_ctx, 0, 0); | ||||
|         test_ctx.string = av_strdup("default"); | ||||
|  | ||||
|         av_log_set_level(AV_LOG_DEBUG); | ||||
|  | ||||
|         for (i=0; i < FF_ARRAY_ELEMS(options); i++) { | ||||
|             av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]); | ||||
|             if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0) | ||||
|                 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); | ||||
|             printf("\n"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -204,4 +204,23 @@ int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags); | ||||
| void av_opt_set_defaults(void *s); | ||||
| void av_opt_set_defaults2(void *s, int mask, int flags); | ||||
|  | ||||
| /** | ||||
|  * Parse the key/value pairs list in opts. For each key/value pair | ||||
|  * found, stores the value in the field in ctx that is named like the | ||||
|  * key. ctx must be an AVClass context, storing is done using | ||||
|  * AVOptions. | ||||
|  * | ||||
|  * @param key_val_sep a 0-terminated list of characters used to | ||||
|  * separate key from value | ||||
|  * @param pairs_sep a 0-terminated list of characters used to separate | ||||
|  * two pairs from each other | ||||
|  * @return the number of successfully set key/value pairs, or a negative | ||||
|  * value corresponding to an AVERROR code in case of error: | ||||
|  * AVERROR(EINVAL) if opts cannot be parsed, | ||||
|  * the error code issued by av_set_string3() if a key/value pair | ||||
|  * cannot be set | ||||
|  */ | ||||
| int av_set_options_string(void *ctx, const char *opts, | ||||
|                           const char *key_val_sep, const char *pairs_sep); | ||||
|  | ||||
| #endif /* AVUTIL_OPT_H */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stefano Sabatini
					Stefano Sabatini