Skip to content

Commit 0548ab2

Browse files
committed
lavu/log,opt: detect setting non-runtime options post-init
Add a mechanism to AVClass to allow objects to signal their state to generic code. When an object flags itself with the 'initialized' state, print an error (and fail, after the next major bump) if the caller attempts to set non-runtime options.
1 parent 3785b27 commit 0548ab2

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

doc/APIchanges

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
22

33
API changes, most recent first:
44

5+
2024-10-xx - xxxxxxxxxx - lavu 59.41.100 - log.h
6+
Add AVClass.state_flags_offset and AV_CLASS_STATE_INITIALIZED.
7+
58
2024-09-30 - xxxxxxxxxx - lavf 61.9.100 - avformat.h
69
Add {nb_}coded_side_data to AVStreamGroupTileGrid.
710

libavutil/log.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ typedef enum {
4646
AV_CLASS_CATEGORY_NB ///< not part of ABI/API
4747
}AVClassCategory;
4848

49+
enum AVClassStateFlags {
50+
/**
51+
* Object initialization has finished and it is now in the 'runtime' stage.
52+
* This affects e.g. what options can be set on the object (only
53+
* AV_OPT_FLAG_RUNTIME_PARAM options can be set on initialized objects).
54+
*/
55+
AV_CLASS_STATE_INITIALIZED = (1 << 0),
56+
};
57+
4958
#define AV_IS_INPUT_DEVICE(category) \
5059
(((category) == AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT) || \
5160
((category) == AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT) || \
@@ -155,6 +164,15 @@ typedef struct AVClass {
155164
* instance of this class.
156165
*/
157166
const struct AVClass* (*child_class_iterate)(void **iter);
167+
168+
/**
169+
* When non-zero, offset in the object to an unsigned int holding object
170+
* state flags, a combination of AVClassStateFlags values. The flags are
171+
* updated by the object to signal its state to the generic code.
172+
*
173+
* Added in version 59.41.100.
174+
*/
175+
int state_flags_offset;
158176
} AVClass;
159177

160178
/**

libavutil/opt.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,39 @@ static int opt_set_init(void *obj, const char *name, int search_flags,
185185
return AVERROR(EINVAL);
186186
}
187187

188+
if (!(o->flags & AV_OPT_FLAG_RUNTIME_PARAM)) {
189+
unsigned *state_flags = NULL;
190+
const AVClass *class;
191+
192+
// try state flags first from the target (child), then from its parent
193+
class = *(const AVClass**)tgt;
194+
if (
195+
#if LIBAVUTIL_VERSION_MAJOR < 60
196+
class->version >= AV_VERSION_INT(59, 41, 100) &&
197+
#endif
198+
class->state_flags_offset)
199+
state_flags = (unsigned*)((uint8_t*)tgt + class->state_flags_offset);
200+
201+
if (!state_flags && obj != tgt) {
202+
class = *(const AVClass**)obj;
203+
if (
204+
#if LIBAVUTIL_VERSION_MAJOR < 60
205+
class->version >= AV_VERSION_INT(59, 41, 100) &&
206+
#endif
207+
class->state_flags_offset)
208+
state_flags = (unsigned*)((uint8_t*)obj + class->state_flags_offset);
209+
}
210+
211+
if (state_flags && (*state_flags & AV_CLASS_STATE_INITIALIZED)) {
212+
av_log(obj, AV_LOG_ERROR, "Option '%s' is not a runtime option and "
213+
"so cannot be set after the object has been initialized\n",
214+
o->name);
215+
#if LIBAVUTIL_VERSION_MAJOR >= 60
216+
return AVERROR(EINVAL);
217+
#endif
218+
}
219+
}
220+
188221
if (o->flags & AV_OPT_FLAG_DEPRECATED)
189222
av_log(obj, AV_LOG_WARNING, "The \"%s\" option is deprecated: %s\n", name, o->help);
190223

libavutil/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
*/
8080

8181
#define LIBAVUTIL_VERSION_MAJOR 59
82-
#define LIBAVUTIL_VERSION_MINOR 40
82+
#define LIBAVUTIL_VERSION_MINOR 41
8383
#define LIBAVUTIL_VERSION_MICRO 100
8484

8585
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

0 commit comments

Comments
 (0)