Use opaque iteration state instead of the previous child class. This mirrors similar changes done in lavf/lavc. Deprecate the av_opt_child_class_next() API.tags/n4.4
| @@ -15,6 +15,10 @@ libavutil: 2017-10-21 | |||
| API changes, most recent first: | |||
| 2020-06-xx - xxxxxxxxxx - lavu 56.53.100 - log.h opt.h | |||
| Add av_opt_child_class_iterate() and AVClass.child_class_iterate(). | |||
| Deprecate av_opt_child_class_next() and AVClass.child_class_next(). | |||
| 2020-06-05 - ec39c2276a - lavu 56.50.100 - buffer.h | |||
| Passing NULL as alloc argument to av_buffer_pool_init2() is now allowed. | |||
| @@ -112,6 +112,7 @@ typedef struct AVClass { | |||
| */ | |||
| void* (*child_next)(void *obj, void *prev); | |||
| #if FF_API_CHILD_CLASS_NEXT | |||
| /** | |||
| * Return an AVClass corresponding to the next potential | |||
| * AVOptions-enabled child. | |||
| @@ -120,7 +121,9 @@ typedef struct AVClass { | |||
| * child_next iterates over _already existing_ objects, while | |||
| * child_class_next iterates over _all possible_ children. | |||
| */ | |||
| attribute_deprecated | |||
| const struct AVClass* (*child_class_next)(const struct AVClass *prev); | |||
| #endif | |||
| /** | |||
| * Category used for visualization (like color) | |||
| @@ -140,6 +143,21 @@ typedef struct AVClass { | |||
| * available since version (52.12) | |||
| */ | |||
| int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); | |||
| /** | |||
| * Iterate over the AVClasses corresponding to potential AVOptions-enabled | |||
| * children. | |||
| * | |||
| * @param iter pointer to opaque iteration state. The caller must initialize | |||
| * *iter to NULL before the first call. | |||
| * @return AVClass for the next AVOptions-enabled child or NULL if there are | |||
| * no more such children. | |||
| * | |||
| * @note The difference between child_next and this is that child_next | |||
| * iterates over _already existing_ objects, while child_class_iterate | |||
| * iterates over _all possible_ children. | |||
| */ | |||
| const struct AVClass* (*child_class_iterate)(void **iter); | |||
| } AVClass; | |||
| /** | |||
| @@ -1679,8 +1679,9 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, | |||
| if (search_flags & AV_OPT_SEARCH_CHILDREN) { | |||
| if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { | |||
| const AVClass *child = NULL; | |||
| while (child = av_opt_child_class_next(c, child)) | |||
| void *iter = NULL; | |||
| const AVClass *child; | |||
| while (child = av_opt_child_class_iterate(c, &iter)) | |||
| if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) | |||
| return o; | |||
| } else { | |||
| @@ -1715,12 +1716,31 @@ void *av_opt_child_next(void *obj, void *prev) | |||
| return NULL; | |||
| } | |||
| #if FF_API_CHILD_CLASS_NEXT | |||
| FF_DISABLE_DEPRECATION_WARNINGS | |||
| const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) | |||
| { | |||
| if (parent->child_class_next) | |||
| return parent->child_class_next(prev); | |||
| return NULL; | |||
| } | |||
| FF_ENABLE_DEPRECATION_WARNINGS | |||
| #endif | |||
| const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter) | |||
| { | |||
| if (parent->child_class_iterate) | |||
| return parent->child_class_iterate(iter); | |||
| #if FF_API_CHILD_CLASS_NEXT | |||
| FF_DISABLE_DEPRECATION_WARNINGS | |||
| if (parent->child_class_next) { | |||
| *iter = parent->child_class_next(*iter); | |||
| return *iter; | |||
| } | |||
| FF_ENABLE_DEPRECATION_WARNINGS | |||
| #endif | |||
| return NULL; | |||
| } | |||
| void *av_opt_ptr(const AVClass *class, void *obj, const char *name) | |||
| { | |||
| @@ -114,7 +114,7 @@ | |||
| * libavcodec exports generic options, while its priv_data field exports | |||
| * codec-specific options). In such a case, it is possible to set up the | |||
| * parent struct to export a child's options. To do that, simply | |||
| * implement AVClass.child_next() and AVClass.child_class_next() in the | |||
| * implement AVClass.child_next() and AVClass.child_class_iterate() in the | |||
| * parent struct's AVClass. | |||
| * Assuming that the test_struct from above now also contains a | |||
| * child_struct field: | |||
| @@ -143,23 +143,25 @@ | |||
| * return t->child_struct; | |||
| * return NULL | |||
| * } | |||
| * const AVClass child_class_next(const AVClass *prev) | |||
| * const AVClass child_class_iterate(void **iter) | |||
| * { | |||
| * return prev ? NULL : &child_class; | |||
| * const AVClass *c = *iter ? NULL : &child_class; | |||
| * *iter = (void*)(uintptr_t)c; | |||
| * return c; | |||
| * } | |||
| * @endcode | |||
| * Putting child_next() and child_class_next() as defined above into | |||
| * Putting child_next() and child_class_iterate() as defined above into | |||
| * test_class will now make child_struct's options accessible through | |||
| * test_struct (again, proper setup as described above needs to be done on | |||
| * child_struct right after it is created). | |||
| * | |||
| * From the above example it might not be clear why both child_next() | |||
| * and child_class_next() are needed. The distinction is that child_next() | |||
| * iterates over actually existing objects, while child_class_next() | |||
| * and child_class_iterate() are needed. The distinction is that child_next() | |||
| * iterates over actually existing objects, while child_class_iterate() | |||
| * iterates over all possible child classes. E.g. if an AVCodecContext | |||
| * was initialized to use a codec which has private options, then its | |||
| * child_next() will return AVCodecContext.priv_data and finish | |||
| * iterating. OTOH child_class_next() on AVCodecContext.av_class will | |||
| * iterating. OTOH child_class_iterate() on AVCodecContext.av_class will | |||
| * iterate over all available codecs with private options. | |||
| * | |||
| * @subsection avoptions_implement_named_constants Named constants | |||
| @@ -194,7 +196,7 @@ | |||
| * For enumerating there are basically two cases. The first is when you want to | |||
| * get all options that may potentially exist on the struct and its children | |||
| * (e.g. when constructing documentation). In that case you should call | |||
| * av_opt_child_class_next() recursively on the parent struct's AVClass. The | |||
| * av_opt_child_class_iterate() recursively on the parent struct's AVClass. The | |||
| * second case is when you have an already initialized struct with all its | |||
| * children and you want to get all options that can be actually written or read | |||
| * from it. In that case you should call av_opt_child_next() recursively (and | |||
| @@ -646,13 +648,26 @@ const AVOption *av_opt_next(const void *obj, const AVOption *prev); | |||
| */ | |||
| void *av_opt_child_next(void *obj, void *prev); | |||
| #if FF_API_CHILD_CLASS_NEXT | |||
| /** | |||
| * Iterate over potential AVOptions-enabled children of parent. | |||
| * | |||
| * @param prev result of a previous call to this function or NULL | |||
| * @return AVClass corresponding to next potential child or NULL | |||
| * | |||
| * @deprecated use av_opt_child_class_iterate | |||
| */ | |||
| attribute_deprecated | |||
| const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev); | |||
| #endif | |||
| /** | |||
| * Iterate over potential AVOptions-enabled children of parent. | |||
| * | |||
| * @param iter a pointer where iteration state is stored. | |||
| * @return AVClass corresponding to next potential child or NULL | |||
| */ | |||
| const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter); | |||
| /** | |||
| * @defgroup opt_set_funcs Option setting functions | |||
| @@ -79,7 +79,7 @@ | |||
| */ | |||
| #define LIBAVUTIL_VERSION_MAJOR 56 | |||
| #define LIBAVUTIL_VERSION_MINOR 52 | |||
| #define LIBAVUTIL_VERSION_MINOR 53 | |||
| #define LIBAVUTIL_VERSION_MICRO 100 | |||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | |||
| @@ -129,7 +129,9 @@ | |||
| #ifndef FF_API_PSEUDOPAL | |||
| #define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) | |||
| #endif | |||
| #ifndef FF_API_CHILD_CLASS_NEXT | |||
| #define FF_API_CHILD_CLASS_NEXT (LIBAVUTIL_VERSION_MAJOR < 57) | |||
| #endif | |||
| /** | |||
| * @} | |||