Thibault Saunier 8162ba6338 ges: docs: fix enum value extraction for enums with gaps
Handle enums like GstBaseTextOverlayHAlign that have missing values
by dynamically calculating the actual range needed and skipping
invalid enum values instead of creating placeholder entries.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9495>
2025-08-05 14:58:30 -04:00

147 lines
5.1 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Simple script to update the children properties information for
GESTrackElement-s that add children properties all the time
"""
import os
import textwrap
from itertools import chain
import gi
gi.require_version("Gst", "1.0")
gi.require_version("GObject", "2.0")
gi.require_version("GES", "1.0")
from gi.repository import Gst, GES, GObject # noqa: E402
overrides = {
"GstFramePositioner": False,
"GstBaseTextOverlay": "GstBaseTextOverlay", # Use the actual class name for proper linking
"GstVideoDirection": "GstVideoDirection", # Use the actual interface name for proper linking
"GESVideoTestSource": "GESVideoTestSource",
"GESVideoTransition": "GESVideoTransition",
}
def get_enum_values_from_property(prop):
"""
Get enum values using proper introspection for newer pygobject versions.
"""
enum_class = prop.enum_class
# Get the enum type from the default value
try:
default_val = prop.get_default_value()
enum_type = type(default_val)
except Exception:
# Fallback: create enum values as integers
return [(i, f"Value_{i}", f"value-{i}") for i in range(enum_class.n_values)]
values = []
# In some cases there are 'gaps' like in the GstBaseTextOverlayHAlign where
# value 3 is GST_BASE_TEXT_OVERLAY_HALIGN_UNUSED - so we need to compensate
# for the gap
n_values = enum_class.n_values
for i in range(n_values):
try:
enum_type(i)
except Exception:
n_values += 1
# Get all enum values by creating them with integer values
for i in range(n_values):
try:
# For other values, create them using the enum type
enum_val = enum_type(i)
values.append((i, enum_val.value_name, enum_val.value_nick))
except Exception:
# Fallback for any failed value
if i == 0:
# Try to get first value info
try:
first_val = enum_class.values
values.append((first_val.value, first_val.value_name, first_val.value_nick))
except Exception:
continue
else:
continue
return values
if __name__ == "__main__":
Gst.init(None)
GES.init()
os.chdir(os.path.realpath(os.path.dirname(__file__)))
tl = GES.Timeline.new_audio_video()
layer = tl.append_layer()
elements = []
def add_clip(c, add=True, override_name=None):
c.props.duration = Gst.SECOND
c.props.start = layer.get_duration()
layer.add_clip(c)
if add:
elements.extend(c.children)
else:
if override_name:
elements.append((c, override_name))
else:
elements.append(c)
add_clip(GES.UriClipAsset.request_sync(Gst.filename_to_uri(
os.path.join("../../", "tests/check/assets/audio_video.ogg"))).extract())
add_clip(GES.TestClip.new())
add_clip(GES.TitleClip.new())
add_clip(GES.SourceClip.new_time_overlay(), False, "GESTimeOverlaySourceClip")
add_clip(GES.TransitionClip.new_for_nick("crossfade"), False)
for element in elements:
if isinstance(element, tuple):
element, gtype = element
else:
gtype = element.__gtype__.name
with open(gtype + '-children-props.md', 'w') as f:
for prop in GES.TimelineElement.list_children_properties(element):
prefix = '#### `%s`\n\n' % (prop.name)
prefix_len = len(prefix)
lines = [i for i in chain.from_iterable([textwrap.wrap(t, width=80) for t in prop.blurb.split('\n')])]
doc = prefix + lines[0]
if GObject.type_is_a(prop, GObject.ParamSpecEnum.__gtype__):
lines += ["", "Valid values:"]
try:
# Try the deprecated method first for backward compatibility
for value in prop.enum_class.__enum_values__.values():
lines.append(" - **%s** (%d) %s" % (value.value_name,
int(value), value.value_nick))
except AttributeError:
# Handle newer pygobject versions - use proper introspection
enum_values = get_enum_values_from_property(prop)
for value, name, nick in enum_values:
lines.append(" - **%s** (%d) %s" % (name, value, nick))
else:
lines += ["", "Value type: #" + prop.value_type.name]
typename = overrides.get(prop.owner_type.name, None)
if typename is not False:
if typename is None:
if GObject.type_is_a(prop.owner_type, Gst.Element):
typename = GObject.new(prop.owner_type).get_factory().get_name()
lines += ["", "See #%s:%s" % (typename, prop.name)]
if len(lines) > 1:
doc += '\n'
doc += '\n'.join(lines[1:])
print(doc + "\n", file=f)