Browse Source

lavu/opt: add a more general child class iteration API

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
Anton Khirnov 5 years ago
parent
commit
1b4a98b029
5 changed files with 71 additions and 12 deletions
  1. +4
    -0
      doc/APIchanges
  2. +18
    -0
      libavutil/log.h
  3. +22
    -2
      libavutil/opt.c
  4. +23
    -8
      libavutil/opt.h
  5. +4
    -2
      libavutil/version.h

+ 4
- 0
doc/APIchanges View File

@@ -15,6 +15,10 @@ libavutil: 2017-10-21


API changes, most recent first: 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 2020-06-05 - ec39c2276a - lavu 56.50.100 - buffer.h
Passing NULL as alloc argument to av_buffer_pool_init2() is now allowed. Passing NULL as alloc argument to av_buffer_pool_init2() is now allowed.




+ 18
- 0
libavutil/log.h View File

@@ -112,6 +112,7 @@ typedef struct AVClass {
*/ */
void* (*child_next)(void *obj, void *prev); void* (*child_next)(void *obj, void *prev);


#if FF_API_CHILD_CLASS_NEXT
/** /**
* Return an AVClass corresponding to the next potential * Return an AVClass corresponding to the next potential
* AVOptions-enabled child. * AVOptions-enabled child.
@@ -120,7 +121,9 @@ typedef struct AVClass {
* child_next iterates over _already existing_ objects, while * child_next iterates over _already existing_ objects, while
* child_class_next iterates over _all possible_ children. * child_class_next iterates over _all possible_ children.
*/ */
attribute_deprecated
const struct AVClass* (*child_class_next)(const struct AVClass *prev); const struct AVClass* (*child_class_next)(const struct AVClass *prev);
#endif


/** /**
* Category used for visualization (like color) * Category used for visualization (like color)
@@ -140,6 +143,21 @@ typedef struct AVClass {
* available since version (52.12) * available since version (52.12)
*/ */
int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); 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; } AVClass;


/** /**


+ 22
- 2
libavutil/opt.c View File

@@ -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_CHILDREN) {
if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { 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)) if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))
return o; return o;
} else { } else {
@@ -1715,12 +1716,31 @@ void *av_opt_child_next(void *obj, void *prev)
return NULL; 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) const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev)
{ {
if (parent->child_class_next) if (parent->child_class_next)
return parent->child_class_next(prev); return parent->child_class_next(prev);
return NULL; 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) void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
{ {


+ 23
- 8
libavutil/opt.h View File

@@ -114,7 +114,7 @@
* libavcodec exports generic options, while its priv_data field exports * libavcodec exports generic options, while its priv_data field exports
* codec-specific options). In such a case, it is possible to set up the * 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 * 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. * parent struct's AVClass.
* Assuming that the test_struct from above now also contains a * Assuming that the test_struct from above now also contains a
* child_struct field: * child_struct field:
@@ -143,23 +143,25 @@
* return t->child_struct; * return t->child_struct;
* return NULL * 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 * @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_class will now make child_struct's options accessible through
* test_struct (again, proper setup as described above needs to be done on * test_struct (again, proper setup as described above needs to be done on
* child_struct right after it is created). * child_struct right after it is created).
* *
* From the above example it might not be clear why both child_next() * 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 * iterates over all possible child classes. E.g. if an AVCodecContext
* was initialized to use a codec which has private options, then its * was initialized to use a codec which has private options, then its
* child_next() will return AVCodecContext.priv_data and finish * 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. * iterate over all available codecs with private options.
* *
* @subsection avoptions_implement_named_constants Named constants * @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 * 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 * get all options that may potentially exist on the struct and its children
* (e.g. when constructing documentation). In that case you should call * (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 * 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 * 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 * 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); void *av_opt_child_next(void *obj, void *prev);


#if FF_API_CHILD_CLASS_NEXT
/** /**
* Iterate over potential AVOptions-enabled children of parent. * Iterate over potential AVOptions-enabled children of parent.
* *
* @param prev result of a previous call to this function or NULL * @param prev result of a previous call to this function or NULL
* @return AVClass corresponding to next potential child 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); 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 * @defgroup opt_set_funcs Option setting functions


+ 4
- 2
libavutil/version.h View File

@@ -79,7 +79,7 @@
*/ */


#define LIBAVUTIL_VERSION_MAJOR 56 #define LIBAVUTIL_VERSION_MAJOR 56
#define LIBAVUTIL_VERSION_MINOR 52
#define LIBAVUTIL_VERSION_MINOR 53
#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_MICRO 100


#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
@@ -129,7 +129,9 @@
#ifndef FF_API_PSEUDOPAL #ifndef FF_API_PSEUDOPAL
#define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) #define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57)
#endif #endif

#ifndef FF_API_CHILD_CLASS_NEXT
#define FF_API_CHILD_CLASS_NEXT (LIBAVUTIL_VERSION_MAJOR < 57)
#endif


/** /**
* @} * @}


Loading…
Cancel
Save