pub const ext = @import("ext.zig");
const gst = @This();

const std = @import("std");
const compat = @import("compat");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
/// Alias for `gst.MapInfo` to be used with `g_auto`:
/// ```c
/// void my_func(GstBuffer *buf)
/// {
///   g_auto(GstBufferMapInfo) map = GST_MAP_INFO_INIT;
///   if (!gst_buffer_map(buf, &map, GST_MAP_READWRITE))
///     return;
///   ...
///   // No need to call `gst.Buffer.unmap`
/// }
/// ```
///
/// `gst.MapInfo` cannot be used with `g_auto` because it is ambiguous whether it
/// needs to be unmapped using `gst.Buffer.unmap` or `gst.Memory.unmap`.
///
/// See also `gst.MemoryMapInfo`.
pub const BufferMapInfo = gst.MapInfo;

/// A datatype to hold the handle to an outstanding sync or async clock callback.
pub const ClockID = *anyopaque;

/// A datatype to hold a time, measured in nanoseconds.
pub const ClockTime = u64;

/// A datatype to hold a time difference, measured in nanoseconds.
pub const ClockTimeDiff = i64;

/// A type defining the type of an element factory.
pub const ElementFactoryListType = u64;

/// Alias for `gst.MapInfo` to be used with `g_auto`:
/// ```c
/// void my_func(GstMemory *mem)
/// {
///   g_auto(GstMemoryMapInfo) map = GST_MAP_INFO_INIT;
///   if (!gst_memory_map(mem, &map, GST_MAP_READWRITE))
///     return;
///   ...
///   // No need to call `gst.Memory.unmap`
/// }
/// ```
///
/// `gst.MapInfo` cannot be used with `g_auto` because it is ambiguous whether it
/// needs to be unmapped using `gst.Buffer.unmap` or `gst.Memory.unmap`.
///
/// See also `gst.BufferMapInfo`.
pub const MemoryMapInfo = gst.MapInfo;

/// Memory is usually created by allocators with a `gst.Allocator.alloc`
/// method call. When `NULL` is used as the allocator, the default allocator will
/// be used.
///
/// New allocators can be registered with `gst.Allocator.register`.
/// Allocators are identified by name and can be retrieved with
/// `gst.Allocator.find`. `gst.Allocator.setDefault` can be used to change the
/// default allocator.
///
/// New memory can be created with `gst.Memory.newWrapped` that wraps the memory
/// allocated elsewhere.
pub const Allocator = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.AllocatorClass;
    f_object: gst.Object,
    f_mem_type: ?[*:0]const u8,
    /// the implementation of the GstMemoryMapFunction
    f_mem_map: ?gst.MemoryMapFunction,
    /// the implementation of the GstMemoryUnmapFunction
    f_mem_unmap: ?gst.MemoryUnmapFunction,
    /// the implementation of the GstMemoryCopyFunction
    f_mem_copy: ?gst.MemoryCopyFunction,
    /// the implementation of the GstMemoryShareFunction
    f_mem_share: ?gst.MemoryShareFunction,
    /// the implementation of the GstMemoryIsSpanFunction
    f_mem_is_span: ?gst.MemoryIsSpanFunction,
    /// the implementation of the GstMemoryMapFullFunction.
    ///      Will be used instead of `mem_map` if present. (Since: 1.6)
    f_mem_map_full: ?gst.MemoryMapFullFunction,
    /// the implementation of the GstMemoryUnmapFullFunction.
    ///      Will be used instead of `mem_unmap` if present. (Since: 1.6)
    f_mem_unmap_full: ?gst.MemoryUnmapFullFunction,
    f__gst_reserved: [2]*anyopaque,
    f_priv: ?*gst.AllocatorPrivate,

    pub const virtual_methods = struct {
        /// Use `allocator` to allocate a new memory block with memory that is at least
        /// `size` big.
        ///
        /// The optional `params` can specify the prefix and padding for the memory. If
        /// `NULL` is passed, no flags, no extra prefix/padding and a default alignment is
        /// used.
        ///
        /// The prefix/padding will be filled with 0 if flags contains
        /// `GST_MEMORY_FLAG_ZERO_PREFIXED` and `GST_MEMORY_FLAG_ZERO_PADDED` respectively.
        ///
        /// When `allocator` is `NULL`, the default allocator will be used.
        ///
        /// The alignment in `params` is given as a bitmask so that `align` + 1 equals
        /// the amount of bytes to align to. For example, to align to 8 bytes,
        /// use an alignment of 7.
        pub const alloc = struct {
            pub fn call(p_class: anytype, p_allocator: ?*@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_size: usize, p_params: ?*gst.AllocationParams) ?*gst.Memory {
                return gobject.ext.as(Allocator.Class, p_class).f_alloc.?(gobject.ext.as(Allocator, p_allocator), p_size, p_params);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_allocator: ?*@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_size: usize, p_params: ?*gst.AllocationParams) callconv(.c) ?*gst.Memory) void {
                gobject.ext.as(Allocator.Class, p_class).f_alloc = @ptrCast(p_implementation);
            }
        };

        /// Free `memory` that was previously allocated with `gst.Allocator.alloc`.
        pub const free = struct {
            pub fn call(p_class: anytype, p_allocator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_memory: *gst.Memory) void {
                return gobject.ext.as(Allocator.Class, p_class).f_free.?(gobject.ext.as(Allocator, p_allocator), p_memory);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_allocator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_memory: *gst.Memory) callconv(.c) void) void {
                gobject.ext.as(Allocator.Class, p_class).f_free = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// Find a previously registered allocator with `name`. When `name` is `NULL`, the
    /// default allocator will be returned.
    extern fn gst_allocator_find(p_name: ?[*:0]const u8) ?*gst.Allocator;
    pub const find = gst_allocator_find;

    /// Registers the memory `allocator` with `name`.
    extern fn gst_allocator_register(p_name: [*:0]const u8, p_allocator: *gst.Allocator) void;
    pub const register = gst_allocator_register;

    /// Use `allocator` to allocate a new memory block with memory that is at least
    /// `size` big.
    ///
    /// The optional `params` can specify the prefix and padding for the memory. If
    /// `NULL` is passed, no flags, no extra prefix/padding and a default alignment is
    /// used.
    ///
    /// The prefix/padding will be filled with 0 if flags contains
    /// `GST_MEMORY_FLAG_ZERO_PREFIXED` and `GST_MEMORY_FLAG_ZERO_PADDED` respectively.
    ///
    /// When `allocator` is `NULL`, the default allocator will be used.
    ///
    /// The alignment in `params` is given as a bitmask so that `align` + 1 equals
    /// the amount of bytes to align to. For example, to align to 8 bytes,
    /// use an alignment of 7.
    extern fn gst_allocator_alloc(p_allocator: ?*Allocator, p_size: usize, p_params: ?*gst.AllocationParams) ?*gst.Memory;
    pub const alloc = gst_allocator_alloc;

    /// Free `memory` that was previously allocated with `gst.Allocator.alloc`.
    extern fn gst_allocator_free(p_allocator: *Allocator, p_memory: *gst.Memory) void;
    pub const free = gst_allocator_free;

    /// Set the default allocator.
    extern fn gst_allocator_set_default(p_allocator: *Allocator) void;
    pub const setDefault = gst_allocator_set_default;

    extern fn gst_allocator_get_type() usize;
    pub const getGObjectType = gst_allocator_get_type;

    extern fn g_object_ref(p_self: *gst.Allocator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Allocator) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Allocator, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.Bin` is an element that can contain other `gst.Element`, allowing them to be
/// managed as a group.
/// Pads from the child elements can be ghosted to the bin, see `gst.GhostPad`.
/// This makes the bin look like any other elements and enables creation of
/// higher-level abstraction elements.
///
/// A new `gst.Bin` is created with `gst.Bin.new`. Use a `gst.Pipeline` instead if you
/// want to create a toplevel bin because a normal bin doesn't have a bus or
/// handle clock distribution of its own.
///
/// After the bin has been created you will typically add elements to it with
/// `gst.Bin.add`. You can remove elements with `gst.Bin.remove`.
///
/// An element can be retrieved from a bin with `gst.Bin.getByName`, using the
/// elements name. `gst.Bin.getByNameRecurseUp` is mainly used for internal
/// purposes and will query the parent bins when the element is not found in the
/// current bin.
///
/// An iterator of elements in a bin can be retrieved with
/// `gst.Bin.iterateElements`. Various other iterators exist to retrieve the
/// elements in a bin.
///
/// `gst.Object.unref` is used to drop your reference to the bin.
///
/// The `gst.Bin.signals.element`-added signal is fired whenever a new element is added to
/// the bin. Likewise the `gst.Bin.signals.element`-removed signal is fired whenever an
/// element is removed from the bin.
///
/// A `gst.Bin` internally intercepts every `gst.Message` posted by its children and
/// implements the following default behaviour for each of them:
///
/// * `GST_MESSAGE_EOS`: This message is only posted by sinks in the PLAYING
/// state. If all sinks posted the EOS message, this bin will post and EOS
/// message upwards.
///
/// * `GST_MESSAGE_SEGMENT_START`: Just collected and never forwarded upwards.
///   The messages are used to decide when all elements have completed playback
///   of their segment.
///
/// * `GST_MESSAGE_SEGMENT_DONE`: Is posted by `gst.Bin` when all elements that posted
///   a SEGMENT_START have posted a SEGMENT_DONE.
///
/// * `GST_MESSAGE_DURATION_CHANGED`: Is posted by an element that detected a change
///   in the stream duration. The duration change is posted to the
///   application so that it can refetch the new duration with a duration
///   query.
///
///   Note that these messages can be posted before the bin is prerolled, in which
///   case the duration query might fail.
///
///   Note also that there might be a discrepancy (due to internal buffering/queueing)
///   between the stream being currently displayed and the returned duration query.
///
///   Applications might want to also query for duration (and changes) by
///   listening to the `GST_MESSAGE_STREAM_START` message, signaling the active start
///   of a (new) stream.
///
/// * `GST_MESSAGE_CLOCK_LOST`: This message is posted by an element when it
///   can no longer provide a clock.
///
///   The default bin behaviour is to check if the lost clock was the one provided
///   by the bin. If so and the bin is currently in the PLAYING state, the message
///   is forwarded to the bin parent.
///
///   This message is also generated when a clock provider is removed from
///   the bin. If this message is received by the application, it should
///   PAUSE the pipeline and set it back to PLAYING to force a new clock
///   distribution.
///
/// * `GST_MESSAGE_CLOCK_PROVIDE`: This message is generated when an element
///   can provide a clock. This mostly happens when a new clock
///   provider is added to the bin.
///
///   The default behaviour of the bin is to mark the currently selected clock as
///   dirty, which will perform a clock recalculation the next time the bin is
///   asked to provide a clock.
///
///   This message is never sent to the application but is forwarded to
///   the parent of the bin.
///
/// * OTHERS: posted upwards.
///
/// A `gst.Bin` implements the following default behaviour for answering to a
/// `gst.Query`:
///
/// * `GST_QUERY_DURATION`: The bin will forward the query to all sink
///   elements contained within and will return the maximum value.
///   If no sinks are available in the bin, the query fails.
///
/// * `GST_QUERY_POSITION`: The query is sent to all sink elements in the bin and the
///   MAXIMUM of all values is returned. If no sinks are available in the bin,
///   the query fails.
///
/// * OTHERS: the query is forwarded to all sink elements, the result
///   of the first sink that answers the query successfully is returned. If no
///   sink is in the bin, the query fails.
///
/// A `gst.Bin` will by default forward any event sent to it to all sink
/// ( `GST_EVENT_TYPE_UPSTREAM` ) or source ( `GST_EVENT_TYPE_DOWNSTREAM` ) elements
/// depending on the event type.
///
/// If all the elements return `TRUE`, the bin will also return `TRUE`, else `FALSE`
/// is returned. If no elements of the required type are in the bin, the event
/// handler will return `TRUE`.
pub const Bin = extern struct {
    pub const Parent = gst.Element;
    pub const Implements = [_]type{gst.ChildProxy};
    pub const Class = gst.BinClass;
    f_element: gst.Element,
    /// the number of children in this bin
    f_numchildren: c_int,
    /// the list of children in this bin
    f_children: ?*glib.List,
    /// updated whenever `children` changes
    f_children_cookie: u32,
    /// internal bus for handling child messages
    f_child_bus: ?*gst.Bus,
    /// queued and cached messages
    f_messages: ?*glib.List,
    /// the bin is currently calculating its state
    f_polling: c_int,
    /// the bin needs to recalculate its state (deprecated)
    f_state_dirty: c_int,
    /// the bin needs to select a new clock
    f_clock_dirty: c_int,
    /// the last clock selected
    f_provided_clock: ?*gst.Clock,
    /// the element that provided `provided_clock`
    f_clock_provider: ?*gst.Element,
    f_priv: ?*gst.BinPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Method to add an element to the bin.
        pub const add_element = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_element: *gst.Element) c_int {
                return gobject.ext.as(Bin.Class, p_class).f_add_element.?(gobject.ext.as(Bin, p_bin), p_element);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_element: *gst.Element) callconv(.c) c_int) void {
                gobject.ext.as(Bin.Class, p_class).f_add_element = @ptrCast(p_implementation);
            }
        };

        /// Method called when an element was added somewhere in the bin hierarchy.
        pub const deep_element_added = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_sub_bin: *gst.Bin, p_child: *gst.Element) void {
                return gobject.ext.as(Bin.Class, p_class).f_deep_element_added.?(gobject.ext.as(Bin, p_bin), p_sub_bin, p_child);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_sub_bin: *gst.Bin, p_child: *gst.Element) callconv(.c) void) void {
                gobject.ext.as(Bin.Class, p_class).f_deep_element_added = @ptrCast(p_implementation);
            }
        };

        /// Method called when an element was removed somewhere in the bin hierarchy.
        pub const deep_element_removed = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_sub_bin: *gst.Bin, p_child: *gst.Element) void {
                return gobject.ext.as(Bin.Class, p_class).f_deep_element_removed.?(gobject.ext.as(Bin, p_bin), p_sub_bin, p_child);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_sub_bin: *gst.Bin, p_child: *gst.Element) callconv(.c) void) void {
                gobject.ext.as(Bin.Class, p_class).f_deep_element_removed = @ptrCast(p_implementation);
            }
        };

        pub const do_latency = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(Bin.Class, p_class).f_do_latency.?(gobject.ext.as(Bin, p_bin));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(Bin.Class, p_class).f_do_latency = @ptrCast(p_implementation);
            }
        };

        /// Method called when an element was added to the bin.
        pub const element_added = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gst.Element) void {
                return gobject.ext.as(Bin.Class, p_class).f_element_added.?(gobject.ext.as(Bin, p_bin), p_child);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gst.Element) callconv(.c) void) void {
                gobject.ext.as(Bin.Class, p_class).f_element_added = @ptrCast(p_implementation);
            }
        };

        /// Method called when an element was removed from the bin.
        pub const element_removed = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gst.Element) void {
                return gobject.ext.as(Bin.Class, p_class).f_element_removed.?(gobject.ext.as(Bin, p_bin), p_child);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gst.Element) callconv(.c) void) void {
                gobject.ext.as(Bin.Class, p_class).f_element_removed = @ptrCast(p_implementation);
            }
        };

        /// Method to handle a message from the children.
        pub const handle_message = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) void {
                return gobject.ext.as(Bin.Class, p_class).f_handle_message.?(gobject.ext.as(Bin, p_bin), p_message);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) callconv(.c) void) void {
                gobject.ext.as(Bin.Class, p_class).f_handle_message = @ptrCast(p_implementation);
            }
        };

        /// Method to remove an element from the bin.
        pub const remove_element = struct {
            pub fn call(p_class: anytype, p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_element: *gst.Element) c_int {
                return gobject.ext.as(Bin.Class, p_class).f_remove_element.?(gobject.ext.as(Bin, p_bin), p_element);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bin: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_element: *gst.Element) callconv(.c) c_int) void {
                gobject.ext.as(Bin.Class, p_class).f_remove_element = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// If set to `TRUE`, the bin will handle asynchronous state changes.
        /// This should be used only if the bin subclass is modifying the state
        /// of its children on its own.
        pub const async_handling = struct {
            pub const name = "async-handling";

            pub const Type = c_int;
        };

        /// Forward all children messages, even those that would normally be filtered by
        /// the bin. This can be interesting when one wants to be notified of the EOS
        /// state of individual elements, for example.
        ///
        /// The messages are converted to an ELEMENT message with the bin as the
        /// source. The structure of the message is named `GstBinForwarded` and contains
        /// a field named `message` that contains the original forwarded `gst.Message`.
        pub const message_forward = struct {
            pub const name = "message-forward";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {
        /// Will be emitted after the element was added to `sub_bin`.
        pub const deep_element_added = struct {
            pub const name = "deep-element-added";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_sub_bin: *gst.Bin, p_element: *gst.Element, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Bin, p_instance))),
                    gobject.signalLookup("deep-element-added", Bin.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted after the element was removed from `sub_bin`.
        pub const deep_element_removed = struct {
            pub const name = "deep-element-removed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_sub_bin: *gst.Bin, p_element: *gst.Element, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Bin, p_instance))),
                    gobject.signalLookup("deep-element-removed", Bin.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted when the bin needs to perform latency calculations. This
        /// signal is only emitted for toplevel bins or when `gst.Bin.properties.async`-handling is
        /// enabled.
        ///
        /// Only one signal handler is invoked. If no signals are connected, the
        /// default handler is invoked, which will query and distribute the lowest
        /// possible latency to all sinks.
        ///
        /// Connect to this signal if the default latency calculations are not
        /// sufficient, like when you need different latencies for different sinks in
        /// the same pipeline.
        pub const do_latency = struct {
            pub const name = "do-latency";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), P_Data) callconv(.c) c_int, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Bin, p_instance))),
                    gobject.signalLookup("do-latency", Bin.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted after the element was added to the bin.
        pub const element_added = struct {
            pub const name = "element-added";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_element: *gst.Element, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Bin, p_instance))),
                    gobject.signalLookup("element-added", Bin.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted after the element was removed from the bin.
        pub const element_removed = struct {
            pub const name = "element-removed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_element: *gst.Element, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Bin, p_instance))),
                    gobject.signalLookup("element-removed", Bin.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Creates a new bin with the given name.
    extern fn gst_bin_new(p_name: ?[*:0]const u8) *gst.Bin;
    pub const new = gst_bin_new;

    /// Adds the given element to the bin.  Sets the element's parent, and thus
    /// takes ownership of the element. An element can only be added to one bin.
    ///
    /// If the element's pads are linked to other pads, the pads will be unlinked
    /// before the element is added to the bin.
    ///
    /// > When you add an element to an already-running pipeline, you will have to
    /// > take care to set the state of the newly-added element to the desired
    /// > state (usually PLAYING or PAUSED, same you set the pipeline to originally)
    /// > with `gst.Element.setState`, or use `gst.Element.syncStateWithParent`.
    /// > The bin or pipeline will not take care of this for you.
    extern fn gst_bin_add(p_bin: *Bin, p_element: *gst.Element) c_int;
    pub const add = gst_bin_add;

    /// Adds a `NULL`-terminated list of elements to a bin.  This function is
    /// equivalent to calling `gst.Bin.add` for each member of the list. The return
    /// value of each `gst.Bin.add` is ignored.
    extern fn gst_bin_add_many(p_bin: *Bin, p_element_1: *gst.Element, ...) void;
    pub const addMany = gst_bin_add_many;

    /// Recursively looks for elements with an unlinked pad of the given
    /// direction within the specified bin and returns an unlinked pad
    /// if one is found, or `NULL` otherwise. If a pad is found, the caller
    /// owns a reference to it and should use `gst.Object.unref` on the
    /// pad when it is not needed any longer.
    extern fn gst_bin_find_unlinked_pad(p_bin: *Bin, p_direction: gst.PadDirection) ?*gst.Pad;
    pub const findUnlinkedPad = gst_bin_find_unlinked_pad;

    /// Looks for an element inside the bin that implements the given
    /// interface. If such an element is found, it returns the element.
    /// You can cast this element to the given interface afterwards.  If you want
    /// all elements that implement the interface, use
    /// `gst.Bin.iterateAllByInterface`. This function recurses into child bins.
    extern fn gst_bin_get_by_interface(p_bin: *Bin, p_iface: usize) ?*gst.Element;
    pub const getByInterface = gst_bin_get_by_interface;

    /// Gets the element with the given name from a bin. This
    /// function recurses into child bins.
    extern fn gst_bin_get_by_name(p_bin: *Bin, p_name: [*:0]const u8) ?*gst.Element;
    pub const getByName = gst_bin_get_by_name;

    /// Gets the element with the given name from this bin. If the
    /// element is not found, a recursion is performed on the parent bin.
    extern fn gst_bin_get_by_name_recurse_up(p_bin: *Bin, p_name: [*:0]const u8) ?*gst.Element;
    pub const getByNameRecurseUp = gst_bin_get_by_name_recurse_up;

    extern fn gst_bin_get_suppressed_flags(p_bin: *Bin) gst.ElementFlags;
    pub const getSuppressedFlags = gst_bin_get_suppressed_flags;

    /// Looks for all elements inside the bin with the given element factory name.
    /// The function recurses inside child bins. The iterator will yield a series of
    /// `gst.Element`.
    extern fn gst_bin_iterate_all_by_element_factory_name(p_bin: *Bin, p_factory_name: [*:0]const u8) ?*gst.Iterator;
    pub const iterateAllByElementFactoryName = gst_bin_iterate_all_by_element_factory_name;

    /// Looks for all elements inside the bin that implements the given
    /// interface. You can safely cast all returned elements to the given interface.
    /// The function recurses inside child bins. The iterator will yield a series
    /// of `gst.Element`.
    extern fn gst_bin_iterate_all_by_interface(p_bin: *Bin, p_iface: usize) ?*gst.Iterator;
    pub const iterateAllByInterface = gst_bin_iterate_all_by_interface;

    /// Gets an iterator for the elements in this bin.
    extern fn gst_bin_iterate_elements(p_bin: *Bin) ?*gst.Iterator;
    pub const iterateElements = gst_bin_iterate_elements;

    /// Gets an iterator for the elements in this bin.
    /// This iterator recurses into GstBin children.
    extern fn gst_bin_iterate_recurse(p_bin: *Bin) ?*gst.Iterator;
    pub const iterateRecurse = gst_bin_iterate_recurse;

    /// Gets an iterator for all elements in the bin that have the
    /// `GST_ELEMENT_FLAG_SINK` flag set.
    extern fn gst_bin_iterate_sinks(p_bin: *Bin) ?*gst.Iterator;
    pub const iterateSinks = gst_bin_iterate_sinks;

    /// Gets an iterator for the elements in this bin in topologically
    /// sorted order. This means that the elements are returned from
    /// the most downstream elements (sinks) to the sources.
    ///
    /// This function is used internally to perform the state changes
    /// of the bin elements and for clock selection.
    extern fn gst_bin_iterate_sorted(p_bin: *Bin) ?*gst.Iterator;
    pub const iterateSorted = gst_bin_iterate_sorted;

    /// Gets an iterator for all elements in the bin that have the
    /// `GST_ELEMENT_FLAG_SOURCE` flag set.
    extern fn gst_bin_iterate_sources(p_bin: *Bin) ?*gst.Iterator;
    pub const iterateSources = gst_bin_iterate_sources;

    /// Queries `bin` for the current latency and reconfigures this latency on all the
    /// elements using a LATENCY event.
    ///
    /// This method is typically called on the pipeline when a `GST_MESSAGE_LATENCY`
    /// is posted on the bus.
    ///
    /// This function simply emits the `gst.Bin.signals.do`-latency signal so any custom latency
    /// calculations will be performed.
    extern fn gst_bin_recalculate_latency(p_bin: *Bin) c_int;
    pub const recalculateLatency = gst_bin_recalculate_latency;

    /// Removes the element from the bin, unparenting it as well.
    /// Unparenting the element means that the element will be dereferenced,
    /// so if the bin holds the only reference to the element, the element
    /// will be freed in the process of removing it from the bin.  If you
    /// want the element to still exist after removing, you need to call
    /// `gst.Object.ref` before removing it from the bin.
    ///
    /// If the element's pads are linked to other pads, the pads will be unlinked
    /// before the element is removed from the bin.
    extern fn gst_bin_remove(p_bin: *Bin, p_element: *gst.Element) c_int;
    pub const remove = gst_bin_remove;

    /// Removes a list of elements from a bin. This function is equivalent
    /// to calling `gst.Bin.remove` with each member of the list.
    extern fn gst_bin_remove_many(p_bin: *Bin, p_element_1: *gst.Element, ...) void;
    pub const removeMany = gst_bin_remove_many;

    /// Suppresses the given flags on the bin. `gst.ElementFlags` of a
    /// child element are propagated when it is added to the bin.
    /// When suppressed flags are set, those specified flags will
    /// not be propagated to the bin.
    extern fn gst_bin_set_suppressed_flags(p_bin: *Bin, p_flags: gst.ElementFlags) void;
    pub const setSuppressedFlags = gst_bin_set_suppressed_flags;

    /// Synchronizes the state of every child of `bin` with the state
    /// of `bin`. See also `gst.Element.syncStateWithParent`.
    extern fn gst_bin_sync_children_states(p_bin: *Bin) c_int;
    pub const syncChildrenStates = gst_bin_sync_children_states;

    extern fn gst_bin_get_type() usize;
    pub const getGObjectType = gst_bin_get_type;

    extern fn g_object_ref(p_self: *gst.Bin) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Bin) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Bin, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a 64-bit bitmask
pub const Bitmask = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = Bitmask;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_bitmask_get_type() usize;
    pub const getGObjectType = gst_bitmask_get_type;

    pub fn as(p_instance: *Bitmask, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.BufferPool` is an object that can be used to pre-allocate and recycle
/// buffers of the same size and with the same properties.
///
/// A `gst.BufferPool` is created with `gst.BufferPool.new`.
///
/// Once a pool is created, it needs to be configured. A call to
/// `gst.BufferPool.getConfig` returns the current configuration structure from
/// the pool. With `gst.BufferPool.configSetParams` and
/// `gst.BufferPool.configSetAllocator` the bufferpool parameters and
/// allocator can be configured. Other properties can be configured in the pool
/// depending on the pool implementation.
///
/// A bufferpool can have extra options that can be enabled with
/// `gst.BufferPool.configAddOption`. The available options can be retrieved
/// with `gst.BufferPool.getOptions`. Some options allow for additional
/// configuration properties to be set.
///
/// After the configuration structure has been configured,
/// `gst.BufferPool.setConfig` updates the configuration in the pool. This can
/// fail when the configuration structure is not accepted.
///
/// After the pool has been configured, it can be activated with
/// `gst.BufferPool.setActive`. This will preallocate the configured resources
/// in the pool.
///
/// When the pool is active, `gst.BufferPool.acquireBuffer` can be used to
/// retrieve a buffer from the pool.
///
/// Buffers allocated from a bufferpool will automatically be returned to the
/// pool with `gst.BufferPool.releaseBuffer` when their refcount drops to 0.
///
/// The bufferpool can be deactivated again with `gst.BufferPool.setActive`.
/// All further `gst.BufferPool.acquireBuffer` calls will return an error. When
/// all buffers are returned to the pool they will be freed.
pub const BufferPool = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.BufferPoolClass;
    /// the parent structure
    f_object: gst.Object,
    /// whether the pool is currently gathering back outstanding buffers
    f_flushing: c_int,
    f_priv: ?*gst.BufferPoolPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Acquires a buffer from `pool`. `buffer` should point to a memory location that
        /// can hold a pointer to the new buffer. When the pool is empty, this function
        /// will by default block until a buffer is released into the pool again or when
        /// the pool is set to flushing or deactivated.
        ///
        /// `params` can contain optional parameters to influence the allocation.
        pub const acquire_buffer = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: ?**gst.Buffer, p_params: ?*gst.BufferPoolAcquireParams) gst.FlowReturn {
                return gobject.ext.as(BufferPool.Class, p_class).f_acquire_buffer.?(gobject.ext.as(BufferPool, p_pool), p_buffer, p_params);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: ?**gst.Buffer, p_params: ?*gst.BufferPoolAcquireParams) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(BufferPool.Class, p_class).f_acquire_buffer = @ptrCast(p_implementation);
            }
        };

        /// Allocate a buffer. the default implementation allocates
        /// buffers from the configured memory allocator and with the configured
        /// parameters. All metadata that is present on the allocated buffer will
        /// be marked as `GST_META_FLAG_POOLED` and `GST_META_FLAG_LOCKED` and will
        /// not be removed from the buffer in `gst.BufferPoolClass.signals.reset_buffer`.
        /// The buffer should have the `GST_BUFFER_FLAG_TAG_MEMORY` cleared.
        pub const alloc_buffer = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: ?**gst.Buffer, p_params: ?*gst.BufferPoolAcquireParams) gst.FlowReturn {
                return gobject.ext.as(BufferPool.Class, p_class).f_alloc_buffer.?(gobject.ext.as(BufferPool, p_pool), p_buffer, p_params);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: ?**gst.Buffer, p_params: ?*gst.BufferPoolAcquireParams) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(BufferPool.Class, p_class).f_alloc_buffer = @ptrCast(p_implementation);
            }
        };

        /// Enter the flushing state.
        pub const flush_start = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(BufferPool.Class, p_class).f_flush_start.?(gobject.ext.as(BufferPool, p_pool));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(BufferPool.Class, p_class).f_flush_start = @ptrCast(p_implementation);
            }
        };

        /// Leave the flushing state.
        pub const flush_stop = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(BufferPool.Class, p_class).f_flush_stop.?(gobject.ext.as(BufferPool, p_pool));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(BufferPool.Class, p_class).f_flush_stop = @ptrCast(p_implementation);
            }
        };

        /// Free a buffer. The default implementation unrefs the buffer.
        pub const free_buffer = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: *gst.Buffer) void {
                return gobject.ext.as(BufferPool.Class, p_class).f_free_buffer.?(gobject.ext.as(BufferPool, p_pool), p_buffer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: *gst.Buffer) callconv(.c) void) void {
                gobject.ext.as(BufferPool.Class, p_class).f_free_buffer = @ptrCast(p_implementation);
            }
        };

        /// Gets a `NULL` terminated array of string with supported bufferpool options for
        /// `pool`. An option would typically be enabled with
        /// `gst.BufferPool.configAddOption`.
        pub const get_options = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) [*][*:0]const u8 {
                return gobject.ext.as(BufferPool.Class, p_class).f_get_options.?(gobject.ext.as(BufferPool, p_pool));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) [*][*:0]const u8) void {
                gobject.ext.as(BufferPool.Class, p_class).f_get_options = @ptrCast(p_implementation);
            }
        };

        /// Releases `buffer` to `pool`. `buffer` should have previously been allocated from
        /// `pool` with `gst.BufferPool.acquireBuffer`.
        ///
        /// This function is usually called automatically when the last ref on `buffer`
        /// disappears.
        pub const release_buffer = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: *gst.Buffer) void {
                return gobject.ext.as(BufferPool.Class, p_class).f_release_buffer.?(gobject.ext.as(BufferPool, p_pool), p_buffer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: *gst.Buffer) callconv(.c) void) void {
                gobject.ext.as(BufferPool.Class, p_class).f_release_buffer = @ptrCast(p_implementation);
            }
        };

        /// Reset the buffer to its state when it was freshly allocated.
        /// The default implementation will clear the flags, timestamps and
        /// will remove the metadata without the `GST_META_FLAG_POOLED` flag (even
        /// the metadata with `GST_META_FLAG_LOCKED`). If the
        /// `GST_BUFFER_FLAG_TAG_MEMORY` was set, this function can also try to
        /// restore the memory and clear the `GST_BUFFER_FLAG_TAG_MEMORY` again.
        pub const reset_buffer = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: *gst.Buffer) void {
                return gobject.ext.as(BufferPool.Class, p_class).f_reset_buffer.?(gobject.ext.as(BufferPool, p_pool), p_buffer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: *gst.Buffer) callconv(.c) void) void {
                gobject.ext.as(BufferPool.Class, p_class).f_reset_buffer = @ptrCast(p_implementation);
            }
        };

        /// Sets the configuration of the pool. If the pool is already configured, and
        /// the configuration hasn't changed, this function will return `TRUE`. If the
        /// pool is active, this method will return `FALSE` and active configuration
        /// will remain. Buffers allocated from this pool must be returned or else this
        /// function will do nothing and return `FALSE`.
        ///
        /// `config` is a `gst.Structure` that contains the configuration parameters for
        /// the pool. A default and mandatory set of parameters can be configured with
        /// `gst.BufferPool.configSetParams`, `gst.BufferPool.configSetAllocator`
        /// and `gst.BufferPool.configAddOption`.
        ///
        /// If the parameters in `config` can not be set exactly, this function returns
        /// `FALSE` and will try to update as much state as possible. The new state can
        /// then be retrieved and refined with `gst.BufferPool.getConfig`.
        ///
        /// This function takes ownership of `config`.
        pub const set_config = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_config: *gst.Structure) c_int {
                return gobject.ext.as(BufferPool.Class, p_class).f_set_config.?(gobject.ext.as(BufferPool, p_pool), p_config);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_config: *gst.Structure) callconv(.c) c_int) void {
                gobject.ext.as(BufferPool.Class, p_class).f_set_config = @ptrCast(p_implementation);
            }
        };

        /// Start the bufferpool. The default implementation will preallocate
        /// min-buffers buffers and put them in the queue.
        ///
        /// Subclasses do not need to chain up to the parent's default implementation
        /// if they don't want min-buffers based preallocation.
        pub const start = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(BufferPool.Class, p_class).f_start.?(gobject.ext.as(BufferPool, p_pool));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(BufferPool.Class, p_class).f_start = @ptrCast(p_implementation);
            }
        };

        /// Stop the bufferpool. the default implementation will free the
        /// preallocated buffers. This function is called when all the buffers are
        /// returned to the pool.
        pub const stop = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(BufferPool.Class, p_class).f_stop.?(gobject.ext.as(BufferPool, p_pool));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(BufferPool.Class, p_class).f_stop = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// Enables the option in `config`. This will instruct the `bufferpool` to enable
    /// the specified option on the buffers that it allocates.
    ///
    /// The options supported by `pool` can be retrieved with `gst.BufferPool.getOptions`.
    extern fn gst_buffer_pool_config_add_option(p_config: *gst.Structure, p_option: [*:0]const u8) void;
    pub const configAddOption = gst_buffer_pool_config_add_option;

    /// Gets the `allocator` and `params` from `config`.
    extern fn gst_buffer_pool_config_get_allocator(p_config: *gst.Structure, p_allocator: ?**gst.Allocator, p_params: ?*gst.AllocationParams) c_int;
    pub const configGetAllocator = gst_buffer_pool_config_get_allocator;

    /// Parses an available `config` and gets the option at `index` of the options API
    /// array.
    extern fn gst_buffer_pool_config_get_option(p_config: *gst.Structure, p_index: c_uint) ?[*:0]const u8;
    pub const configGetOption = gst_buffer_pool_config_get_option;

    /// Gets the configuration values from `config`.
    extern fn gst_buffer_pool_config_get_params(p_config: *gst.Structure, p_caps: ?**gst.Caps, p_size: ?*c_uint, p_min_buffers: ?*c_uint, p_max_buffers: ?*c_uint) c_int;
    pub const configGetParams = gst_buffer_pool_config_get_params;

    /// Checks if `config` contains `option`.
    extern fn gst_buffer_pool_config_has_option(p_config: *gst.Structure, p_option: [*:0]const u8) c_int;
    pub const configHasOption = gst_buffer_pool_config_has_option;

    /// Retrieves the number of values currently stored in the options array of the
    /// `config` structure.
    extern fn gst_buffer_pool_config_n_options(p_config: *gst.Structure) c_uint;
    pub const configNOptions = gst_buffer_pool_config_n_options;

    /// Sets the `allocator` and `params` on `config`.
    ///
    /// One of `allocator` and `params` can be `NULL`, but not both. When `allocator`
    /// is `NULL`, the default allocator of the pool will use the values in `param`
    /// to perform its allocation. When `param` is `NULL`, the pool will use the
    /// provided `allocator` with its default `gst.AllocationParams`.
    ///
    /// A call to `gst.BufferPool.setConfig` can update the allocator and params
    /// with the values that it is able to do. Some pools are, for example, not able
    /// to operate with different allocators or cannot allocate with the values
    /// specified in `params`. Use `gst.BufferPool.getConfig` to get the currently
    /// used values.
    extern fn gst_buffer_pool_config_set_allocator(p_config: *gst.Structure, p_allocator: ?*gst.Allocator, p_params: ?*const gst.AllocationParams) void;
    pub const configSetAllocator = gst_buffer_pool_config_set_allocator;

    /// Configures `config` with the given parameters.
    extern fn gst_buffer_pool_config_set_params(p_config: *gst.Structure, p_caps: ?*gst.Caps, p_size: c_uint, p_min_buffers: c_uint, p_max_buffers: c_uint) void;
    pub const configSetParams = gst_buffer_pool_config_set_params;

    /// Validates that changes made to `config` are still valid in the context of the
    /// expected parameters. This function is a helper that can be used to validate
    /// changes made by a pool to a config when `gst.BufferPool.setConfig`
    /// returns `FALSE`. This expects that `caps` haven't changed and that
    /// `min_buffers` aren't lower then what we initially expected.
    /// This does not check if options or allocator parameters are still valid,
    /// won't check if size have changed, since changing the size is valid to adapt
    /// padding.
    extern fn gst_buffer_pool_config_validate_params(p_config: *gst.Structure, p_caps: ?*gst.Caps, p_size: c_uint, p_min_buffers: c_uint, p_max_buffers: c_uint) c_int;
    pub const configValidateParams = gst_buffer_pool_config_validate_params;

    /// Creates a new `gst.BufferPool` instance.
    extern fn gst_buffer_pool_new() *gst.BufferPool;
    pub const new = gst_buffer_pool_new;

    /// Acquires a buffer from `pool`. `buffer` should point to a memory location that
    /// can hold a pointer to the new buffer. When the pool is empty, this function
    /// will by default block until a buffer is released into the pool again or when
    /// the pool is set to flushing or deactivated.
    ///
    /// `params` can contain optional parameters to influence the allocation.
    extern fn gst_buffer_pool_acquire_buffer(p_pool: *BufferPool, p_buffer: ?**gst.Buffer, p_params: ?*gst.BufferPoolAcquireParams) gst.FlowReturn;
    pub const acquireBuffer = gst_buffer_pool_acquire_buffer;

    /// Gets a copy of the current configuration of the pool. This configuration
    /// can be modified and used for the `gst.BufferPool.setConfig` call.
    extern fn gst_buffer_pool_get_config(p_pool: *BufferPool) *gst.Structure;
    pub const getConfig = gst_buffer_pool_get_config;

    /// Gets a `NULL` terminated array of string with supported bufferpool options for
    /// `pool`. An option would typically be enabled with
    /// `gst.BufferPool.configAddOption`.
    extern fn gst_buffer_pool_get_options(p_pool: *BufferPool) [*][*:0]const u8;
    pub const getOptions = gst_buffer_pool_get_options;

    /// Checks if the bufferpool supports `option`.
    extern fn gst_buffer_pool_has_option(p_pool: *BufferPool, p_option: [*:0]const u8) c_int;
    pub const hasOption = gst_buffer_pool_has_option;

    /// Checks if `pool` is active. A pool can be activated with the
    /// `gst.BufferPool.setActive` call.
    extern fn gst_buffer_pool_is_active(p_pool: *BufferPool) c_int;
    pub const isActive = gst_buffer_pool_is_active;

    /// Releases `buffer` to `pool`. `buffer` should have previously been allocated from
    /// `pool` with `gst.BufferPool.acquireBuffer`.
    ///
    /// This function is usually called automatically when the last ref on `buffer`
    /// disappears.
    extern fn gst_buffer_pool_release_buffer(p_pool: *BufferPool, p_buffer: *gst.Buffer) void;
    pub const releaseBuffer = gst_buffer_pool_release_buffer;

    /// Controls the active state of `pool`. When the pool is inactive, new calls to
    /// `gst.BufferPool.acquireBuffer` will return with `GST_FLOW_FLUSHING`.
    ///
    /// Activating the bufferpool will preallocate all resources in the pool based on
    /// the configuration of the pool.
    ///
    /// Deactivating will free the resources again when there are no outstanding
    /// buffers. When there are outstanding buffers, they will be freed as soon as
    /// they are all returned to the pool.
    extern fn gst_buffer_pool_set_active(p_pool: *BufferPool, p_active: c_int) c_int;
    pub const setActive = gst_buffer_pool_set_active;

    /// Sets the configuration of the pool. If the pool is already configured, and
    /// the configuration hasn't changed, this function will return `TRUE`. If the
    /// pool is active, this method will return `FALSE` and active configuration
    /// will remain. Buffers allocated from this pool must be returned or else this
    /// function will do nothing and return `FALSE`.
    ///
    /// `config` is a `gst.Structure` that contains the configuration parameters for
    /// the pool. A default and mandatory set of parameters can be configured with
    /// `gst.BufferPool.configSetParams`, `gst.BufferPool.configSetAllocator`
    /// and `gst.BufferPool.configAddOption`.
    ///
    /// If the parameters in `config` can not be set exactly, this function returns
    /// `FALSE` and will try to update as much state as possible. The new state can
    /// then be retrieved and refined with `gst.BufferPool.getConfig`.
    ///
    /// This function takes ownership of `config`.
    extern fn gst_buffer_pool_set_config(p_pool: *BufferPool, p_config: *gst.Structure) c_int;
    pub const setConfig = gst_buffer_pool_set_config;

    /// Enables or disables the flushing state of a `pool` without freeing or
    /// allocating buffers.
    extern fn gst_buffer_pool_set_flushing(p_pool: *BufferPool, p_flushing: c_int) void;
    pub const setFlushing = gst_buffer_pool_set_flushing;

    extern fn gst_buffer_pool_get_type() usize;
    pub const getGObjectType = gst_buffer_pool_get_type;

    extern fn g_object_ref(p_self: *gst.BufferPool) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.BufferPool) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *BufferPool, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.Bus` is an object responsible for delivering `gst.Message` packets in
/// a first-in first-out way from the streaming threads (see `gst.Task`) to the
/// application.
///
/// Since the application typically only wants to deal with delivery of these
/// messages from one thread, the GstBus will marshall the messages between
/// different threads. This is important since the actual streaming of media
/// is done in another thread than the application.
///
/// The GstBus provides support for `glib.Source` based notifications. This makes it
/// possible to handle the delivery in the glib `glib.MainLoop`.
///
/// The `glib.Source` callback function `gst.Bus.asyncSignalFunc` can be used to
/// convert all bus messages into signal emissions.
///
/// A message is posted on the bus with the `gst.Bus.post` method. With the
/// `gst.Bus.peek` and `gst.Bus.pop` methods one can look at or retrieve a
/// previously posted message.
///
/// The bus can be polled with the `gst.Bus.poll` method. This methods blocks
/// up to the specified timeout value until one of the specified messages types
/// is posted on the bus. The application can then `gst.Bus.pop` the messages
/// from the bus to handle them.
/// Alternatively the application can register an asynchronous bus function
/// using `gst.Bus.addWatchFull` or `gst.Bus.addWatch`. This function will
/// install a `glib.Source` in the default glib main loop and will deliver messages
/// a short while after they have been posted. Note that the main loop should
/// be running for the asynchronous callbacks.
///
/// It is also possible to get messages from the bus without any thread
/// marshalling with the `gst.Bus.setSyncHandler` method. This makes it
/// possible to react to a message in the same thread that posted the
/// message on the bus. This should only be used if the application is able
/// to deal with messages from different threads.
///
/// Every `gst.Pipeline` has one bus.
///
/// Note that a `gst.Pipeline` will set its bus into flushing state when changing
/// from READY to NULL state.
pub const Bus = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.BusClass;
    /// the parent structure
    f_object: gst.Object,
    f_priv: ?*gst.BusPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// A message has been posted on the bus.
        pub const message = struct {
            pub fn call(p_class: anytype, p_bus: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) void {
                return gobject.ext.as(Bus.Class, p_class).f_message.?(gobject.ext.as(Bus, p_bus), p_message);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bus: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) callconv(.c) void) void {
                gobject.ext.as(Bus.Class, p_class).f_message = @ptrCast(p_implementation);
            }
        };

        /// A message has been posted on the bus.
        pub const sync_message = struct {
            pub fn call(p_class: anytype, p_bus: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) void {
                return gobject.ext.as(Bus.Class, p_class).f_sync_message.?(gobject.ext.as(Bus, p_bus), p_message);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_bus: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) callconv(.c) void) void {
                gobject.ext.as(Bus.Class, p_class).f_sync_message = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// Enables async message delivery support for bus watches,
        /// `gst.Bus.pop` and similar API. Without this only the
        /// synchronous message handlers are called.
        ///
        /// This property is used to create the child element buses
        /// in `gst.Bin`.
        pub const enable_async = struct {
            pub const name = "enable-async";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {
        /// A message has been posted on the bus. This signal is emitted from a
        /// `glib.Source` added to the mainloop. this signal will only be emitted when
        /// there is a `glib.MainLoop` running.
        pub const message = struct {
            pub const name = "message";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_message: *gst.Message, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Bus, p_instance))),
                    gobject.signalLookup("message", Bus.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// A message has been posted on the bus. This signal is emitted from the
        /// thread that posted the message so one has to be careful with locking.
        ///
        /// This signal will not be emitted by default, you have to call
        /// `gst.Bus.enableSyncMessageEmission` before.
        pub const sync_message = struct {
            pub const name = "sync-message";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_message: *gst.Message, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Bus, p_instance))),
                    gobject.signalLookup("sync-message", Bus.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Creates a new `gst.Bus` instance.
    extern fn gst_bus_new() *gst.Bus;
    pub const new = gst_bus_new;

    /// Adds a bus signal watch to the default main context with the default priority
    /// ( `G_PRIORITY_DEFAULT` ). It is also possible to use a non-default
    /// main context set up using `glib.MainContext.pushThreadDefault` (before
    /// one had to create a bus watch source and attach it to the desired main
    /// context 'manually').
    ///
    /// After calling this statement, the bus will emit the "message" signal for each
    /// message posted on the bus.
    ///
    /// This function may be called multiple times. To clean up, the caller is
    /// responsible for calling `gst.Bus.removeSignalWatch` as many times as this
    /// function is called.
    extern fn gst_bus_add_signal_watch(p_bus: *Bus) void;
    pub const addSignalWatch = gst_bus_add_signal_watch;

    /// Adds a bus signal watch to the default main context with the given `priority`
    /// (e.g. `G_PRIORITY_DEFAULT`). It is also possible to use a non-default main
    /// context set up using `glib.MainContext.pushThreadDefault`
    /// (before one had to create a bus watch source and attach it to the desired
    /// main context 'manually').
    ///
    /// After calling this statement, the bus will emit the "message" signal for each
    /// message posted on the bus when the `glib.MainLoop` is running.
    ///
    /// This function may be called multiple times. To clean up, the caller is
    /// responsible for calling `gst.Bus.removeSignalWatch` as many times as this
    /// function is called.
    ///
    /// There can only be a single bus watch per bus, you must remove any signal
    /// watch before you can set another type of watch.
    extern fn gst_bus_add_signal_watch_full(p_bus: *Bus, p_priority: c_int) void;
    pub const addSignalWatchFull = gst_bus_add_signal_watch_full;

    /// Adds a bus watch to the default main context with the default priority
    /// ( `G_PRIORITY_DEFAULT` ). It is also possible to use a non-default main
    /// context set up using `glib.MainContext.pushThreadDefault` (before
    /// one had to create a bus watch source and attach it to the desired main
    /// context 'manually').
    ///
    /// This function is used to receive asynchronous messages in the main loop.
    /// There can only be a single bus watch per bus, you must remove it before you
    /// can set a new one.
    ///
    /// The bus watch will only work if a `glib.MainLoop` is being run.
    ///
    /// The watch can be removed using `gst.Bus.removeWatch` or by returning `FALSE`
    /// from `func`. If the watch was added to the default main context it is also
    /// possible to remove the watch using `glib.sourceRemove`.
    ///
    /// The bus watch will take its own reference to the `bus`, so it is safe to unref
    /// `bus` using `gst.Object.unref` after setting the bus watch.
    extern fn gst_bus_add_watch(p_bus: *Bus, p_func: gst.BusFunc, p_user_data: ?*anyopaque) c_uint;
    pub const addWatch = gst_bus_add_watch;

    /// Adds a bus watch to the default main context with the given `priority` (e.g.
    /// `G_PRIORITY_DEFAULT`). It is also possible to use a non-default  main
    /// context set up using `glib.MainContext.pushThreadDefault` (before
    /// one had to create a bus watch source and attach it to the desired main
    /// context 'manually').
    ///
    /// This function is used to receive asynchronous messages in the main loop.
    /// There can only be a single bus watch per bus, you must remove it before you
    /// can set a new one.
    ///
    /// The bus watch will only work if a `glib.MainLoop` is being run.
    ///
    /// When `func` is called, the message belongs to the caller; if you want to
    /// keep a copy of it, call `gst.Message.ref` before leaving `func`.
    ///
    /// The watch can be removed using `gst.Bus.removeWatch` or by returning `FALSE`
    /// from `func`. If the watch was added to the default main context it is also
    /// possible to remove the watch using `glib.sourceRemove`.
    ///
    /// The bus watch will take its own reference to the `bus`, so it is safe to unref
    /// `bus` using `gst.Object.unref` after setting the bus watch.
    extern fn gst_bus_add_watch_full(p_bus: *Bus, p_priority: c_int, p_func: gst.BusFunc, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) c_uint;
    pub const addWatchFull = gst_bus_add_watch_full;

    /// A helper `gst.BusFunc` that can be used to convert all asynchronous messages
    /// into signals.
    extern fn gst_bus_async_signal_func(p_bus: *Bus, p_message: *gst.Message, p_data: ?*anyopaque) c_int;
    pub const asyncSignalFunc = gst_bus_async_signal_func;

    /// Create watch for this bus. The `glib.Source` will be dispatched whenever
    /// a message is on the bus. After the GSource is dispatched, the
    /// message is popped off the bus and unreffed.
    ///
    /// As with other watches, there can only be one watch on the bus, including
    /// any signal watch added with `gst.Bus.addSignalWatch`.
    extern fn gst_bus_create_watch(p_bus: *Bus) ?*glib.Source;
    pub const createWatch = gst_bus_create_watch;

    /// Instructs GStreamer to stop emitting the "sync-message" signal for this bus.
    /// See `gst.Bus.enableSyncMessageEmission` for more information.
    ///
    /// In the event that multiple pieces of code have called
    /// `gst.Bus.enableSyncMessageEmission`, the sync-message emissions will only
    /// be stopped after all calls to `gst.Bus.enableSyncMessageEmission` were
    /// "cancelled" by calling this function. In this way the semantics are exactly
    /// the same as `gst.Object.ref` that which calls enable should also call
    /// disable.
    extern fn gst_bus_disable_sync_message_emission(p_bus: *Bus) void;
    pub const disableSyncMessageEmission = gst_bus_disable_sync_message_emission;

    /// Instructs GStreamer to emit the "sync-message" signal after running the bus's
    /// sync handler. This function is here so that code can ensure that they can
    /// synchronously receive messages without having to affect what the bin's sync
    /// handler is.
    ///
    /// This function may be called multiple times. To clean up, the caller is
    /// responsible for calling `gst.Bus.disableSyncMessageEmission` as many times
    /// as this function is called.
    ///
    /// While this function looks similar to `gst.Bus.addSignalWatch`, it is not
    /// exactly the same -- this function enables *synchronous* emission of
    /// signals when messages arrive; `gst.Bus.addSignalWatch` adds an idle callback
    /// to pop messages off the bus *asynchronously*. The sync-message signal
    /// comes from the thread of whatever object posted the message; the "message"
    /// signal is marshalled to the main thread via the `glib.MainLoop`.
    extern fn gst_bus_enable_sync_message_emission(p_bus: *Bus) void;
    pub const enableSyncMessageEmission = gst_bus_enable_sync_message_emission;

    /// Gets the file descriptor from the bus which can be used to get notified about
    /// messages being available with functions like `glib.poll`, and allows integration
    /// into other event loops based on file descriptors.
    /// Whenever a message is available, the POLLIN / `G_IO_IN` event is set.
    ///
    /// Warning: NEVER read or write anything to the returned fd but only use it
    /// for getting notifications via `glib.poll` or similar and then use the normal
    /// GstBus API, e.g. `gst.Bus.pop`.
    extern fn gst_bus_get_pollfd(p_bus: *Bus, p_fd: *glib.PollFD) void;
    pub const getPollfd = gst_bus_get_pollfd;

    /// Checks if there are pending messages on the bus that
    /// should be handled.
    extern fn gst_bus_have_pending(p_bus: *Bus) c_int;
    pub const havePending = gst_bus_have_pending;

    /// Peeks the message on the top of the bus' queue. The message will remain
    /// on the bus' message queue.
    extern fn gst_bus_peek(p_bus: *Bus) ?*gst.Message;
    pub const peek = gst_bus_peek;

    /// Polls the bus for messages. Will block while waiting for messages to come.
    /// You can specify a maximum time to poll with the `timeout` parameter. If
    /// `timeout` is negative, this function will block indefinitely.
    ///
    /// All messages not in `events` will be popped off the bus and will be ignored.
    /// It is not possible to use message enums beyond `GST_MESSAGE_EXTENDED` in the
    /// `events` mask
    ///
    /// Because poll is implemented using the "message" signal enabled by
    /// `gst.Bus.addSignalWatch`, calling `gst.Bus.poll` will cause the "message"
    /// signal to be emitted for every message that poll sees. Thus a "message"
    /// signal handler will see the same messages that this function sees -- neither
    /// will steal messages from the other.
    ///
    /// This function will run a `glib.MainLoop` from the default main context when
    /// polling.
    ///
    /// You should never use this function, since it is pure evil. This is
    /// especially true for GUI applications based on Gtk+ or Qt, but also for any
    /// other non-trivial application that uses the GLib main loop. As this function
    /// runs a GLib main loop, any callback attached to the default GLib main
    /// context may be invoked. This could be timeouts, GUI events, I/O events etc.;
    /// even if `gst.Bus.poll` is called with a 0 timeout. Any of these callbacks
    /// may do things you do not expect, e.g. destroy the main application window or
    /// some other resource; change other application state; display a dialog and
    /// run another main loop until the user clicks it away. In short, using this
    /// function may add a lot of complexity to your code through unexpected
    /// re-entrancy and unexpected changes to your application's state.
    ///
    /// For 0 timeouts use `gst.Bus.popFiltered` instead of this function; for
    /// other short timeouts use `gst.Bus.timedPopFiltered`; everything else is
    /// better handled by setting up an asynchronous bus watch and doing things
    /// from there.
    extern fn gst_bus_poll(p_bus: *Bus, p_events: gst.MessageType, p_timeout: gst.ClockTime) ?*gst.Message;
    pub const poll = gst_bus_poll;

    /// Gets a message from the bus.
    extern fn gst_bus_pop(p_bus: *Bus) ?*gst.Message;
    pub const pop = gst_bus_pop;

    /// Gets a message matching `type` from the bus.  Will discard all messages on
    /// the bus that do not match `type` and that have been posted before the first
    /// message that does match `type`.  If there is no message matching `type` on
    /// the bus, all messages will be discarded. It is not possible to use message
    /// enums beyond `GST_MESSAGE_EXTENDED` in the `events` mask.
    extern fn gst_bus_pop_filtered(p_bus: *Bus, p_types: gst.MessageType) ?*gst.Message;
    pub const popFiltered = gst_bus_pop_filtered;

    /// Posts a message on the given bus. Ownership of the message
    /// is taken by the bus.
    extern fn gst_bus_post(p_bus: *Bus, p_message: *gst.Message) c_int;
    pub const post = gst_bus_post;

    /// Removes a signal watch previously added with `gst.Bus.addSignalWatch`.
    extern fn gst_bus_remove_signal_watch(p_bus: *Bus) void;
    pub const removeSignalWatch = gst_bus_remove_signal_watch;

    /// Removes an installed bus watch from `bus`.
    extern fn gst_bus_remove_watch(p_bus: *Bus) c_int;
    pub const removeWatch = gst_bus_remove_watch;

    /// If `flushing`, flushes out and unrefs any messages queued in the bus. Releases
    /// references to the message origin objects. Will flush future messages until
    /// `gst.Bus.setFlushing` sets `flushing` to `FALSE`.
    extern fn gst_bus_set_flushing(p_bus: *Bus, p_flushing: c_int) void;
    pub const setFlushing = gst_bus_set_flushing;

    /// Sets the synchronous handler on the bus. The function will be called
    /// every time a new message is posted on the bus. Note that the function
    /// will be called in the same thread context as the posting object. This
    /// function is usually only called by the creator of the bus. Applications
    /// should handle messages asynchronously using the gst_bus watch and poll
    /// functions.
    ///
    /// Before 1.16.3 it was not possible to replace an existing handler and
    /// clearing an existing handler with `NULL` was not thread-safe.
    extern fn gst_bus_set_sync_handler(p_bus: *Bus, p_func: ?gst.BusSyncHandler, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setSyncHandler = gst_bus_set_sync_handler;

    /// A helper `gst.BusSyncHandler` that can be used to convert all synchronous
    /// messages into signals.
    extern fn gst_bus_sync_signal_handler(p_bus: *Bus, p_message: *gst.Message, p_data: ?*anyopaque) gst.BusSyncReply;
    pub const syncSignalHandler = gst_bus_sync_signal_handler;

    /// Gets a message from the bus, waiting up to the specified timeout.
    ///
    /// If `timeout` is 0, this function behaves like `gst.Bus.pop`. If `timeout` is
    /// `GST_CLOCK_TIME_NONE`, this function will block forever until a message was
    /// posted on the bus.
    extern fn gst_bus_timed_pop(p_bus: *Bus, p_timeout: gst.ClockTime) ?*gst.Message;
    pub const timedPop = gst_bus_timed_pop;

    /// Gets a message from the bus whose type matches the message type mask `types`,
    /// waiting up to the specified timeout (and discarding any messages that do not
    /// match the mask provided).
    ///
    /// If `timeout` is 0, this function behaves like `gst.Bus.popFiltered`. If
    /// `timeout` is `GST_CLOCK_TIME_NONE`, this function will block forever until a
    /// matching message was posted on the bus.
    extern fn gst_bus_timed_pop_filtered(p_bus: *Bus, p_timeout: gst.ClockTime, p_types: gst.MessageType) ?*gst.Message;
    pub const timedPopFiltered = gst_bus_timed_pop_filtered;

    extern fn gst_bus_get_type() usize;
    pub const getGObjectType = gst_bus_get_type;

    extern fn g_object_ref(p_self: *gst.Bus) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Bus) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Bus, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GStreamer uses a global clock to synchronize the plugins in a pipeline.
/// Different clock implementations are possible by implementing this abstract
/// base class or, more conveniently, by subclassing `gst.SystemClock`.
///
/// The `gst.Clock` returns a monotonically increasing time with the method
/// `gst.Clock.getTime`. Its accuracy and base time depend on the specific
/// clock implementation but time is always expressed in nanoseconds. Since the
/// baseline of the clock is undefined, the clock time returned is not
/// meaningful in itself, what matters are the deltas between two clock times.
/// The time returned by a clock is called the absolute time.
///
/// The pipeline uses the clock to calculate the running time. Usually all
/// renderers synchronize to the global clock using the buffer timestamps, the
/// `GST_EVENT_SEGMENT` events and the element's base time, see `gst.Pipeline`.
///
/// A clock implementation can support periodic and single shot clock
/// notifications both synchronous and asynchronous.
///
/// One first needs to create a `gst.ClockID` for the periodic or single shot
/// notification using `gst.Clock.newSingleShotId` or
/// `gst.Clock.newPeriodicId`.
///
/// To perform a blocking wait for the specific time of the `gst.ClockID` use
/// `gst.Clock.idWait`. To receive a callback when the specific time is reached
/// in the clock use `gst.Clock.idWaitAsync`. Both these calls can be
/// interrupted with the `gst.Clock.idUnschedule` call. If the blocking wait is
/// unscheduled a return value of `GST_CLOCK_UNSCHEDULED` is returned.
///
/// Periodic callbacks scheduled async will be repeatedly called automatically
/// until they are unscheduled. To schedule a sync periodic callback,
/// `gst.Clock.idWait` should be called repeatedly.
///
/// The async callbacks can happen from any thread, either provided by the core
/// or from a streaming thread. The application should be prepared for this.
///
/// A `gst.ClockID` that has been unscheduled cannot be used again for any wait
/// operation, a new `gst.ClockID` should be created and the old unscheduled one
/// should be destroyed with `gst.Clock.idUnref`.
///
/// It is possible to perform a blocking wait on the same `gst.ClockID` from
/// multiple threads. However, registering the same `gst.ClockID` for multiple
/// async notifications is not possible, the callback will only be called for
/// the thread registering the entry last.
///
/// None of the wait operations unref the `gst.ClockID`, the owner is responsible
/// for unreffing the ids itself. This holds for both periodic and single shot
/// notifications. The reason being that the owner of the `gst.ClockID` has to
/// keep a handle to the `gst.ClockID` to unblock the wait on FLUSHING events or
/// state changes and if the entry would be unreffed automatically, the handle
/// might become invalid without any notification.
///
/// These clock operations do not operate on the running time, so the callbacks
/// will also occur when not in PLAYING state as if the clock just keeps on
/// running. Some clocks however do not progress when the element that provided
/// the clock is not PLAYING.
///
/// When a clock has the `GST_CLOCK_FLAG_CAN_SET_MASTER` flag set, it can be
/// slaved to another `gst.Clock` with `gst.Clock.setMaster`. The clock will
/// then automatically be synchronized to this master clock by repeatedly
/// sampling the master clock and the slave clock and recalibrating the slave
/// clock with `gst.Clock.setCalibration`. This feature is mostly useful for
/// plugins that have an internal clock but must operate with another clock
/// selected by the `gst.Pipeline`.  They can track the offset and rate difference
/// of their internal clock relative to the master clock by using the
/// `gst.Clock.getCalibration` function.
///
/// The master/slave synchronisation can be tuned with the `gst.Clock.properties.timeout`,
/// `gst.Clock.properties.window`-size and `gst.Clock.properties.window`-threshold properties.
/// The `gst.Clock.properties.timeout` property defines the interval to sample the master
/// clock and run the calibration functions. `gst.Clock.properties.window`-size defines the
/// number of samples to use when calibrating and `gst.Clock.properties.window`-threshold
/// defines the minimum number of samples before the calibration is performed.
pub const Clock = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.ClockClass;
    /// the parent structure
    f_object: gst.Object,
    f_priv: ?*gst.ClockPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Change the resolution of the clock. Not all values might
        /// be acceptable.
        pub const change_resolution = struct {
            pub fn call(p_class: anytype, p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_old_resolution: gst.ClockTime, p_new_resolution: gst.ClockTime) gst.ClockTime {
                return gobject.ext.as(Clock.Class, p_class).f_change_resolution.?(gobject.ext.as(Clock, p_clock), p_old_resolution, p_new_resolution);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_old_resolution: gst.ClockTime, p_new_resolution: gst.ClockTime) callconv(.c) gst.ClockTime) void {
                gobject.ext.as(Clock.Class, p_class).f_change_resolution = @ptrCast(p_implementation);
            }
        };

        /// Gets the current internal time of the given clock. The time is returned
        /// unadjusted for the offset and the rate.
        pub const get_internal_time = struct {
            pub fn call(p_class: anytype, p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gst.ClockTime {
                return gobject.ext.as(Clock.Class, p_class).f_get_internal_time.?(gobject.ext.as(Clock, p_clock));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) gst.ClockTime) void {
                gobject.ext.as(Clock.Class, p_class).f_get_internal_time = @ptrCast(p_implementation);
            }
        };

        /// Gets the accuracy of the clock. The accuracy of the clock is the granularity
        /// of the values returned by `gst.Clock.getTime`.
        pub const get_resolution = struct {
            pub fn call(p_class: anytype, p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gst.ClockTime {
                return gobject.ext.as(Clock.Class, p_class).f_get_resolution.?(gobject.ext.as(Clock, p_clock));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) gst.ClockTime) void {
                gobject.ext.as(Clock.Class, p_class).f_get_resolution = @ptrCast(p_implementation);
            }
        };

        /// Unblock a blocking or async wait operation.
        pub const unschedule = struct {
            pub fn call(p_class: anytype, p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_entry: *gst.ClockEntry) void {
                return gobject.ext.as(Clock.Class, p_class).f_unschedule.?(gobject.ext.as(Clock, p_clock), p_entry);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_entry: *gst.ClockEntry) callconv(.c) void) void {
                gobject.ext.as(Clock.Class, p_class).f_unschedule = @ptrCast(p_implementation);
            }
        };

        /// Perform a blocking wait on the given `gst.ClockEntry` and return
        /// the jitter.
        pub const wait = struct {
            pub fn call(p_class: anytype, p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_entry: *gst.ClockEntry, p_jitter: ?*gst.ClockTimeDiff) gst.ClockReturn {
                return gobject.ext.as(Clock.Class, p_class).f_wait.?(gobject.ext.as(Clock, p_clock), p_entry, p_jitter);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_entry: *gst.ClockEntry, p_jitter: ?*gst.ClockTimeDiff) callconv(.c) gst.ClockReturn) void {
                gobject.ext.as(Clock.Class, p_class).f_wait = @ptrCast(p_implementation);
            }
        };

        /// Perform an asynchronous wait on the given `gst.ClockEntry`.
        pub const wait_async = struct {
            pub fn call(p_class: anytype, p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_entry: *gst.ClockEntry) gst.ClockReturn {
                return gobject.ext.as(Clock.Class, p_class).f_wait_async.?(gobject.ext.as(Clock, p_clock), p_entry);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_clock: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_entry: *gst.ClockEntry) callconv(.c) gst.ClockReturn) void {
                gobject.ext.as(Clock.Class, p_class).f_wait_async = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const timeout = struct {
            pub const name = "timeout";

            pub const Type = u64;
        };

        pub const window_size = struct {
            pub const name = "window-size";

            pub const Type = c_int;
        };

        pub const window_threshold = struct {
            pub const name = "window-threshold";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {
        /// Signaled on clocks with `GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC` set once
        /// the clock is synchronized, or when it completely lost synchronization.
        /// This signal will not be emitted on clocks without the flag.
        ///
        /// This signal will be emitted from an arbitrary thread, most likely not
        /// the application's main thread.
        pub const synced = struct {
            pub const name = "synced";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_synced: c_int, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Clock, p_instance))),
                    gobject.signalLookup("synced", Clock.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Compares the two `gst.ClockID` instances. This function can be used
    /// as a GCompareFunc when sorting ids.
    extern fn gst_clock_id_compare_func(p_id1: ?*const anyopaque, p_id2: ?*const anyopaque) c_int;
    pub const idCompareFunc = gst_clock_id_compare_func;

    /// This function returns the underlying clock.
    extern fn gst_clock_id_get_clock(p_id: gst.ClockID) ?*gst.Clock;
    pub const idGetClock = gst_clock_id_get_clock;

    /// Gets the time of the clock ID
    extern fn gst_clock_id_get_time(p_id: gst.ClockID) gst.ClockTime;
    pub const idGetTime = gst_clock_id_get_time;

    /// Increases the refcount of given `id`.
    extern fn gst_clock_id_ref(p_id: gst.ClockID) gst.ClockID;
    pub const idRef = gst_clock_id_ref;

    /// Unrefs given `id`. When the refcount reaches 0 the
    /// `gst.ClockID` will be freed.
    extern fn gst_clock_id_unref(p_id: gst.ClockID) void;
    pub const idUnref = gst_clock_id_unref;

    /// Cancels an outstanding request with `id`. This can either
    /// be an outstanding async notification or a pending sync notification.
    /// After this call, `id` cannot be used anymore to receive sync or
    /// async notifications, you need to create a new `gst.ClockID`.
    extern fn gst_clock_id_unschedule(p_id: gst.ClockID) void;
    pub const idUnschedule = gst_clock_id_unschedule;

    /// This function returns whether `id` uses `clock` as the underlying clock.
    /// `clock` can be NULL, in which case the return value indicates whether
    /// the underlying clock has been freed.  If this is the case, the `id` is
    /// no longer usable and should be freed.
    extern fn gst_clock_id_uses_clock(p_id: gst.ClockID, p_clock: *gst.Clock) c_int;
    pub const idUsesClock = gst_clock_id_uses_clock;

    /// Performs a blocking wait on `id`.
    /// `id` should have been created with `gst.Clock.newSingleShotId`
    /// or `gst.Clock.newPeriodicId` and should not have been unscheduled
    /// with a call to `gst.Clock.idUnschedule`.
    ///
    /// If the `jitter` argument is not `NULL` and this function returns `GST_CLOCK_OK`
    /// or `GST_CLOCK_EARLY`, it will contain the difference
    /// against the clock and the time of `id` when this method was
    /// called.
    /// Positive values indicate how late `id` was relative to the clock
    /// (in which case this function will return `GST_CLOCK_EARLY`).
    /// Negative values indicate how much time was spent waiting on the clock
    /// before this function returned.
    extern fn gst_clock_id_wait(p_id: gst.ClockID, p_jitter: ?*gst.ClockTimeDiff) gst.ClockReturn;
    pub const idWait = gst_clock_id_wait;

    /// Registers a callback on the given `gst.ClockID` `id` with the given
    /// function and user_data. When passing a `gst.ClockID` with an invalid
    /// time to this function, the callback will be called immediately
    /// with  a time set to `GST_CLOCK_TIME_NONE`. The callback will
    /// be called when the time of `id` has been reached.
    ///
    /// The callback `func` can be invoked from any thread, either provided by the
    /// core or from a streaming thread. The application should be prepared for this.
    extern fn gst_clock_id_wait_async(p_id: gst.ClockID, p_func: gst.ClockCallback, p_user_data: ?*anyopaque, p_destroy_data: ?glib.DestroyNotify) gst.ClockReturn;
    pub const idWaitAsync = gst_clock_id_wait_async;

    /// The time `observation_external` of the external or master clock and the time
    /// `observation_internal` of the internal or slave clock are added to the list of
    /// observations. If enough observations are available, a linear regression
    /// algorithm is run on the observations and `clock` is recalibrated.
    ///
    /// If this functions returns `TRUE`, `r_squared` will contain the
    /// correlation coefficient of the interpolation. A value of 1.0
    /// means a perfect regression was performed. This value can
    /// be used to control the sampling frequency of the master and slave
    /// clocks.
    extern fn gst_clock_add_observation(p_clock: *Clock, p_observation_internal: gst.ClockTime, p_observation_external: gst.ClockTime, p_r_squared: *f64) c_int;
    pub const addObservation = gst_clock_add_observation;

    /// Add a clock observation to the internal slaving algorithm the same as
    /// `gst.Clock.addObservation`, and return the result of the external or master
    /// clock estimation, without updating the internal calibration.
    ///
    /// The caller can then take the results and call `gst.Clock.setCalibration`
    /// with the values, or some modified version of them.
    extern fn gst_clock_add_observation_unapplied(p_clock: *Clock, p_observation_internal: gst.ClockTime, p_observation_external: gst.ClockTime, p_r_squared: *f64, p_internal: ?*gst.ClockTime, p_external: ?*gst.ClockTime, p_rate_num: ?*gst.ClockTime, p_rate_denom: ?*gst.ClockTime) c_int;
    pub const addObservationUnapplied = gst_clock_add_observation_unapplied;

    /// Converts the given `internal` clock time to the external time, adjusting for the
    /// rate and reference time set with `gst.Clock.setCalibration` and making sure
    /// that the returned time is increasing. This function should be called with the
    /// clock's OBJECT_LOCK held and is mainly used by clock subclasses.
    ///
    /// This function is the reverse of `gst.Clock.unadjustUnlocked`.
    extern fn gst_clock_adjust_unlocked(p_clock: *Clock, p_internal: gst.ClockTime) gst.ClockTime;
    pub const adjustUnlocked = gst_clock_adjust_unlocked;

    /// Converts the given `internal_target` clock time to the external time,
    /// using the passed calibration parameters. This function performs the
    /// same calculation as `gst.Clock.adjustUnlocked` when called using the
    /// current calibration parameters, but doesn't ensure a monotonically
    /// increasing result as `gst.Clock.adjustUnlocked` does.
    ///
    /// Note: The `clock` parameter is unused and can be NULL
    extern fn gst_clock_adjust_with_calibration(p_clock: ?*Clock, p_internal_target: gst.ClockTime, p_cinternal: gst.ClockTime, p_cexternal: gst.ClockTime, p_cnum: gst.ClockTime, p_cdenom: gst.ClockTime) gst.ClockTime;
    pub const adjustWithCalibration = gst_clock_adjust_with_calibration;

    /// Gets the internal rate and reference time of `clock`. See
    /// `gst.Clock.setCalibration` for more information.
    ///
    /// `internal`, `external`, `rate_num`, and `rate_denom` can be left `NULL` if the
    /// caller is not interested in the values.
    extern fn gst_clock_get_calibration(p_clock: *Clock, p_internal: ?*gst.ClockTime, p_external: ?*gst.ClockTime, p_rate_num: ?*gst.ClockTime, p_rate_denom: ?*gst.ClockTime) void;
    pub const getCalibration = gst_clock_get_calibration;

    /// Gets the current internal time of the given clock. The time is returned
    /// unadjusted for the offset and the rate.
    extern fn gst_clock_get_internal_time(p_clock: *Clock) gst.ClockTime;
    pub const getInternalTime = gst_clock_get_internal_time;

    /// Gets the master clock that `clock` is slaved to or `NULL` when the clock is
    /// not slaved to any master clock.
    extern fn gst_clock_get_master(p_clock: *Clock) ?*gst.Clock;
    pub const getMaster = gst_clock_get_master;

    /// Gets the accuracy of the clock. The accuracy of the clock is the granularity
    /// of the values returned by `gst.Clock.getTime`.
    extern fn gst_clock_get_resolution(p_clock: *Clock) gst.ClockTime;
    pub const getResolution = gst_clock_get_resolution;

    /// Gets the current time of the given clock. The time is always
    /// monotonically increasing and adjusted according to the current
    /// offset and rate.
    extern fn gst_clock_get_time(p_clock: *Clock) gst.ClockTime;
    pub const getTime = gst_clock_get_time;

    /// Gets the amount of time that master and slave clocks are sampled.
    extern fn gst_clock_get_timeout(p_clock: *Clock) gst.ClockTime;
    pub const getTimeout = gst_clock_get_timeout;

    /// Checks if the clock is currently synced, by looking at whether
    /// `GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC` is set.
    extern fn gst_clock_is_synced(p_clock: *Clock) c_int;
    pub const isSynced = gst_clock_is_synced;

    /// Gets an ID from `clock` to trigger a periodic notification.
    /// The periodic notifications will start at time `start_time` and
    /// will then be fired with the given `interval`.
    extern fn gst_clock_new_periodic_id(p_clock: *Clock, p_start_time: gst.ClockTime, p_interval: gst.ClockTime) gst.ClockID;
    pub const newPeriodicId = gst_clock_new_periodic_id;

    /// Gets a `gst.ClockID` from `clock` to trigger a single shot
    /// notification at the requested time.
    extern fn gst_clock_new_single_shot_id(p_clock: *Clock, p_time: gst.ClockTime) gst.ClockID;
    pub const newSingleShotId = gst_clock_new_single_shot_id;

    /// Reinitializes the provided periodic `id` to the provided start time and
    /// interval. Does not modify the reference count.
    extern fn gst_clock_periodic_id_reinit(p_clock: *Clock, p_id: gst.ClockID, p_start_time: gst.ClockTime, p_interval: gst.ClockTime) c_int;
    pub const periodicIdReinit = gst_clock_periodic_id_reinit;

    /// Adjusts the rate and time of `clock`. A rate of 1/1 is the normal speed of
    /// the clock. Values bigger than 1/1 make the clock go faster.
    ///
    /// `internal` and `external` are calibration parameters that arrange that
    /// `gst.Clock.getTime` should have been `external` at internal time `internal`.
    /// This internal time should not be in the future; that is, it should be less
    /// than the value of `gst.Clock.getInternalTime` when this function is called.
    ///
    /// Subsequent calls to `gst.Clock.getTime` will return clock times computed as
    /// follows:
    ///
    /// ``` C
    ///   time = (internal_time - internal) * rate_num / rate_denom + external
    /// ```
    ///
    /// This formula is implemented in `gst.Clock.adjustUnlocked`. Of course, it
    /// tries to do the integer arithmetic as precisely as possible.
    ///
    /// Note that `gst.Clock.getTime` always returns increasing values so when you
    /// move the clock backwards, `gst.Clock.getTime` will report the previous value
    /// until the clock catches up.
    extern fn gst_clock_set_calibration(p_clock: *Clock, p_internal: gst.ClockTime, p_external: gst.ClockTime, p_rate_num: gst.ClockTime, p_rate_denom: gst.ClockTime) void;
    pub const setCalibration = gst_clock_set_calibration;

    /// Sets `master` as the master clock for `clock`. `clock` will be automatically
    /// calibrated so that `gst.Clock.getTime` reports the same time as the
    /// master clock.
    ///
    /// A clock provider that slaves its clock to a master can get the current
    /// calibration values with `gst.Clock.getCalibration`.
    ///
    /// `master` can be `NULL` in which case `clock` will not be slaved anymore. It will
    /// however keep reporting its time adjusted with the last configured rate
    /// and time offsets.
    extern fn gst_clock_set_master(p_clock: *Clock, p_master: ?*gst.Clock) c_int;
    pub const setMaster = gst_clock_set_master;

    /// Sets the accuracy of the clock. Some clocks have the possibility to operate
    /// with different accuracy at the expense of more resource usage. There is
    /// normally no need to change the default resolution of a clock. The resolution
    /// of a clock can only be changed if the clock has the
    /// `GST_CLOCK_FLAG_CAN_SET_RESOLUTION` flag set.
    extern fn gst_clock_set_resolution(p_clock: *Clock, p_resolution: gst.ClockTime) gst.ClockTime;
    pub const setResolution = gst_clock_set_resolution;

    /// Sets `clock` to synced and emits the `gst.Clock.signals.synced` signal, and wakes up any
    /// thread waiting in `gst.Clock.waitForSync`.
    ///
    /// This function must only be called if `GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC`
    /// is set on the clock, and is intended to be called by subclasses only.
    extern fn gst_clock_set_synced(p_clock: *Clock, p_synced: c_int) void;
    pub const setSynced = gst_clock_set_synced;

    /// Sets the amount of time, in nanoseconds, to sample master and slave
    /// clocks
    extern fn gst_clock_set_timeout(p_clock: *Clock, p_timeout: gst.ClockTime) void;
    pub const setTimeout = gst_clock_set_timeout;

    /// Reinitializes the provided single shot `id` to the provided time. Does not
    /// modify the reference count.
    extern fn gst_clock_single_shot_id_reinit(p_clock: *Clock, p_id: gst.ClockID, p_time: gst.ClockTime) c_int;
    pub const singleShotIdReinit = gst_clock_single_shot_id_reinit;

    /// Converts the given `external` clock time to the internal time of `clock`,
    /// using the rate and reference time set with `gst.Clock.setCalibration`.
    /// This function should be called with the clock's OBJECT_LOCK held and
    /// is mainly used by clock subclasses.
    ///
    /// This function is the reverse of `gst.Clock.adjustUnlocked`.
    extern fn gst_clock_unadjust_unlocked(p_clock: *Clock, p_external: gst.ClockTime) gst.ClockTime;
    pub const unadjustUnlocked = gst_clock_unadjust_unlocked;

    /// Converts the given `external_target` clock time to the internal time,
    /// using the passed calibration parameters. This function performs the
    /// same calculation as `gst.Clock.unadjustUnlocked` when called using the
    /// current calibration parameters.
    ///
    /// Note: The `clock` parameter is unused and can be NULL
    extern fn gst_clock_unadjust_with_calibration(p_clock: ?*Clock, p_external_target: gst.ClockTime, p_cinternal: gst.ClockTime, p_cexternal: gst.ClockTime, p_cnum: gst.ClockTime, p_cdenom: gst.ClockTime) gst.ClockTime;
    pub const unadjustWithCalibration = gst_clock_unadjust_with_calibration;

    /// Waits until `clock` is synced for reporting the current time. If `timeout`
    /// is `GST_CLOCK_TIME_NONE` it will wait forever, otherwise it will time out
    /// after `timeout` nanoseconds.
    ///
    /// For asynchronous waiting, the `gst.Clock.signals.synced` signal can be used.
    ///
    /// This returns immediately with `TRUE` if `GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC`
    /// is not set on the clock, or if the clock is already synced.
    extern fn gst_clock_wait_for_sync(p_clock: *Clock, p_timeout: gst.ClockTime) c_int;
    pub const waitForSync = gst_clock_wait_for_sync;

    extern fn gst_clock_get_type() usize;
    pub const getGObjectType = gst_clock_get_type;

    extern fn g_object_ref(p_self: *gst.Clock) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Clock) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Clock, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A base class for value mapping objects that attaches control sources to `gobject.Object`
/// properties. Such an object is taking one or more `gst.ControlSource` instances,
/// combines them and maps the resulting value to the type and value range of the
/// bound property.
pub const ControlBinding = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.ControlBindingClass;
    /// the parent structure
    f_parent: gst.Object,
    /// name of the property of this binding
    f_name: ?[*:0]u8,
    /// `gobject.ParamSpec` for this property
    f_pspec: ?*gobject.ParamSpec,
    f_object: ?*gst.Object,
    f_disabled: c_int,
    anon0: extern union {
        anon0: extern struct {
            f_priv: ?*gst.ControlBindingPrivate,
        },
        f__gst_reserved: [4]*anyopaque,
    },

    pub const virtual_methods = struct {
        /// Gets a number of `GValues` for the given controlled property starting at the
        /// requested time. The array `values` need to hold enough space for `n_values` of
        /// `gobject.Value`.
        ///
        /// This function is useful if one wants to e.g. draw a graph of the control
        /// curve or apply a control curve sample by sample.
        pub const get_g_value_array = struct {
            pub fn call(p_class: anytype, p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]gobject.Value) c_int {
                return gobject.ext.as(ControlBinding.Class, p_class).f_get_g_value_array.?(gobject.ext.as(ControlBinding, p_binding), p_timestamp, p_interval, p_n_values, p_values);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]gobject.Value) callconv(.c) c_int) void {
                gobject.ext.as(ControlBinding.Class, p_class).f_get_g_value_array = @ptrCast(p_implementation);
            }
        };

        /// Gets the value for the given controlled property at the requested time.
        pub const get_value = struct {
            pub fn call(p_class: anytype, p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime) ?*gobject.Value {
                return gobject.ext.as(ControlBinding.Class, p_class).f_get_value.?(gobject.ext.as(ControlBinding, p_binding), p_timestamp);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime) callconv(.c) ?*gobject.Value) void {
                gobject.ext.as(ControlBinding.Class, p_class).f_get_value = @ptrCast(p_implementation);
            }
        };

        /// Gets a number of values for the given controlled property starting at the
        /// requested time. The array `values` needs to hold enough space for `n_values` of
        /// the same type as the objects property's type.
        ///
        /// This function is useful if one wants to e.g. draw a graph of the control
        /// curve or apply a control curve sample by sample.
        ///
        /// The values are unboxed and ready to be used. The similar function
        /// `gst.ControlBinding.getGValueArray` returns the array as `GValues` and is
        /// more suitable for bindings.
        pub const get_value_array = struct {
            pub fn call(p_class: anytype, p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]*anyopaque) c_int {
                return gobject.ext.as(ControlBinding.Class, p_class).f_get_value_array.?(gobject.ext.as(ControlBinding, p_binding), p_timestamp, p_interval, p_n_values, p_values);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]*anyopaque) callconv(.c) c_int) void {
                gobject.ext.as(ControlBinding.Class, p_class).f_get_value_array = @ptrCast(p_implementation);
            }
        };

        /// Sets the property of the `object`, according to the `GstControlSources` that
        /// handles it and for the given timestamp.
        ///
        /// If this function fails, it is most likely the application developers fault.
        /// Most probably the control sources are not setup correctly.
        pub const sync_values = struct {
            pub fn call(p_class: anytype, p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_object: *gst.Object, p_timestamp: gst.ClockTime, p_last_sync: gst.ClockTime) c_int {
                return gobject.ext.as(ControlBinding.Class, p_class).f_sync_values.?(gobject.ext.as(ControlBinding, p_binding), p_object, p_timestamp, p_last_sync);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_binding: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_object: *gst.Object, p_timestamp: gst.ClockTime, p_last_sync: gst.ClockTime) callconv(.c) c_int) void {
                gobject.ext.as(ControlBinding.Class, p_class).f_sync_values = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const name = struct {
            pub const name = "name";

            pub const Type = ?[*:0]u8;
        };

        pub const object = struct {
            pub const name = "object";

            pub const Type = ?*gst.Object;
        };
    };

    pub const signals = struct {};

    /// Gets a number of `GValues` for the given controlled property starting at the
    /// requested time. The array `values` need to hold enough space for `n_values` of
    /// `gobject.Value`.
    ///
    /// This function is useful if one wants to e.g. draw a graph of the control
    /// curve or apply a control curve sample by sample.
    extern fn gst_control_binding_get_g_value_array(p_binding: *ControlBinding, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]gobject.Value) c_int;
    pub const getGValueArray = gst_control_binding_get_g_value_array;

    /// Gets the value for the given controlled property at the requested time.
    extern fn gst_control_binding_get_value(p_binding: *ControlBinding, p_timestamp: gst.ClockTime) ?*gobject.Value;
    pub const getValue = gst_control_binding_get_value;

    /// Gets a number of values for the given controlled property starting at the
    /// requested time. The array `values` needs to hold enough space for `n_values` of
    /// the same type as the objects property's type.
    ///
    /// This function is useful if one wants to e.g. draw a graph of the control
    /// curve or apply a control curve sample by sample.
    ///
    /// The values are unboxed and ready to be used. The similar function
    /// `gst.ControlBinding.getGValueArray` returns the array as `GValues` and is
    /// more suitable for bindings.
    extern fn gst_control_binding_get_value_array(p_binding: *ControlBinding, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]*anyopaque) c_int;
    pub const getValueArray = gst_control_binding_get_value_array;

    /// Checks if the control binding is disabled.
    extern fn gst_control_binding_is_disabled(p_binding: *ControlBinding) c_int;
    pub const isDisabled = gst_control_binding_is_disabled;

    /// This function is used to disable a control binding for some time, i.e.
    /// `gst.Object.syncValues` will do nothing.
    extern fn gst_control_binding_set_disabled(p_binding: *ControlBinding, p_disabled: c_int) void;
    pub const setDisabled = gst_control_binding_set_disabled;

    /// Sets the property of the `object`, according to the `GstControlSources` that
    /// handles it and for the given timestamp.
    ///
    /// If this function fails, it is most likely the application developers fault.
    /// Most probably the control sources are not setup correctly.
    extern fn gst_control_binding_sync_values(p_binding: *ControlBinding, p_object: *gst.Object, p_timestamp: gst.ClockTime, p_last_sync: gst.ClockTime) c_int;
    pub const syncValues = gst_control_binding_sync_values;

    extern fn gst_control_binding_get_type() usize;
    pub const getGObjectType = gst_control_binding_get_type;

    extern fn g_object_ref(p_self: *gst.ControlBinding) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.ControlBinding) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *ControlBinding, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.ControlSource` is a base class for control value sources that could
/// be used to get timestamp-value pairs. A control source essentially is a
/// function over time.
///
/// A `gst.ControlSource` is used by first getting an instance of a specific
/// control-source, creating a binding for the control-source to the target property
/// of the element and then adding the binding to the element. The binding will
/// convert the data types and value range to fit to the bound property.
///
/// For implementing a new `gst.ControlSource` one has to implement
/// `gst.ControlSourceGetValue` and `gst.ControlSourceGetValueArray` functions.
/// These are then used by `gst.ControlSource.controlSourceGetValue` and
/// `gst.ControlSource.controlSourceGetValueArray` to get values for specific timestamps.
pub const ControlSource = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.ControlSourceClass;
    /// the parent structure
    f_parent: gst.Object,
    /// Function for returning a value for a given timestamp
    f_get_value: ?gst.ControlSourceGetValue,
    /// Function for returning a values array for a given timestamp
    f_get_value_array: ?gst.ControlSourceGetValueArray,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Gets the value for this `gst.ControlSource` at a given timestamp.
    extern fn gst_control_source_get_value(p_self: *ControlSource, p_timestamp: gst.ClockTime, p_value: *f64) c_int;
    pub const controlSourceGetValue = gst_control_source_get_value;

    /// Gets an array of values for for this `gst.ControlSource`. Values that are
    /// undefined contain NANs.
    extern fn gst_control_source_get_value_array(p_self: *ControlSource, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]f64) c_int;
    pub const controlSourceGetValueArray = gst_control_source_get_value_array;

    extern fn gst_control_source_get_type() usize;
    pub const getGObjectType = gst_control_source_get_type;

    extern fn g_object_ref(p_self: *gst.ControlSource) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.ControlSource) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *ControlSource, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.Device` are objects representing a device, they contain
/// relevant metadata about the device, such as its class and the `gst.Caps`
/// representing the media types it can produce or handle.
///
/// `gst.Device` are created by `gst.DeviceProvider` objects which can be
/// aggregated by `gst.DeviceMonitor` objects.
pub const Device = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.DeviceClass;
    /// The parent `gst.Object` structure.
    f_parent: gst.Object,
    f_priv: ?*gst.DevicePrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Creates the element with all of the required parameters set to use
        /// this device.
        pub const create_element = struct {
            pub fn call(p_class: anytype, p_device: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: ?[*:0]const u8) ?*gst.Element {
                return gobject.ext.as(Device.Class, p_class).f_create_element.?(gobject.ext.as(Device, p_device), p_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_device: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: ?[*:0]const u8) callconv(.c) ?*gst.Element) void {
                gobject.ext.as(Device.Class, p_class).f_create_element = @ptrCast(p_implementation);
            }
        };

        /// Tries to reconfigure an existing element to use the device. If this
        /// function fails, then one must destroy the element and create a new one
        /// using `gst.Device.createElement`.
        ///
        /// Note: This should only be implemented for elements can change their
        /// device in the PLAYING state.
        pub const reconfigure_element = struct {
            pub fn call(p_class: anytype, p_device: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_element: *gst.Element) c_int {
                return gobject.ext.as(Device.Class, p_class).f_reconfigure_element.?(gobject.ext.as(Device, p_device), p_element);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_device: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_element: *gst.Element) callconv(.c) c_int) void {
                gobject.ext.as(Device.Class, p_class).f_reconfigure_element = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const caps = struct {
            pub const name = "caps";

            pub const Type = ?*gst.Caps;
        };

        pub const device_class = struct {
            pub const name = "device-class";

            pub const Type = ?[*:0]u8;
        };

        pub const display_name = struct {
            pub const name = "display-name";

            pub const Type = ?[*:0]u8;
        };

        pub const properties = struct {
            pub const name = "properties";

            pub const Type = ?*gst.Structure;
        };
    };

    pub const signals = struct {
        pub const removed = struct {
            pub const name = "removed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Device, p_instance))),
                    gobject.signalLookup("removed", Device.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Creates the element with all of the required parameters set to use
    /// this device.
    extern fn gst_device_create_element(p_device: *Device, p_name: ?[*:0]const u8) ?*gst.Element;
    pub const createElement = gst_device_create_element;

    /// Getter for the `gst.Caps` that this device supports.
    extern fn gst_device_get_caps(p_device: *Device) ?*gst.Caps;
    pub const getCaps = gst_device_get_caps;

    /// Gets the "class" of a device. This is a "/" separated list of
    /// classes that represent this device. They are a subset of the
    /// classes of the `gst.DeviceProvider` that produced this device.
    extern fn gst_device_get_device_class(p_device: *Device) [*:0]u8;
    pub const getDeviceClass = gst_device_get_device_class;

    /// Gets the user-friendly name of the device.
    extern fn gst_device_get_display_name(p_device: *Device) [*:0]u8;
    pub const getDisplayName = gst_device_get_display_name;

    /// Gets the extra properties of a device.
    extern fn gst_device_get_properties(p_device: *Device) ?*gst.Structure;
    pub const getProperties = gst_device_get_properties;

    /// Check if `device` matches all of the given classes
    extern fn gst_device_has_classes(p_device: *Device, p_classes: [*:0]const u8) c_int;
    pub const hasClasses = gst_device_has_classes;

    /// Check if `factory` matches all of the given classes
    extern fn gst_device_has_classesv(p_device: *Device, p_classes: [*][*:0]u8) c_int;
    pub const hasClassesv = gst_device_has_classesv;

    /// Tries to reconfigure an existing element to use the device. If this
    /// function fails, then one must destroy the element and create a new one
    /// using `gst.Device.createElement`.
    ///
    /// Note: This should only be implemented for elements can change their
    /// device in the PLAYING state.
    extern fn gst_device_reconfigure_element(p_device: *Device, p_element: *gst.Element) c_int;
    pub const reconfigureElement = gst_device_reconfigure_element;

    extern fn gst_device_get_type() usize;
    pub const getGObjectType = gst_device_get_type;

    extern fn g_object_ref(p_self: *gst.Device) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Device) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Device, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Applications should create a `gst.DeviceMonitor` when they want
/// to probe, list and monitor devices of a specific type. The
/// `gst.DeviceMonitor` will create the appropriate
/// `gst.DeviceProvider` objects and manage them. It will then post
/// messages on its `gst.Bus` for devices that have been added and
/// removed.
///
/// The device monitor will monitor all devices matching the filters that
/// the application has set.
///
/// The basic use pattern of a device monitor is as follows:
/// ```
///   static gboolean
///   my_bus_func (GstBus * bus, GstMessage * message, gpointer user_data)
///   {
///      GstDevice *device;
///      gchar *name;
///
///      switch (GST_MESSAGE_TYPE (message)) {
///        case GST_MESSAGE_DEVICE_ADDED:
///          gst_message_parse_device_added (message, &device);
///          name = gst_device_get_display_name (device);
///          g_print("Device added: `s`\n", name);
///          g_free (name);
///          gst_object_unref (device);
///          break;
///        case GST_MESSAGE_DEVICE_REMOVED:
///          gst_message_parse_device_removed (message, &device);
///          name = gst_device_get_display_name (device);
///          g_print("Device removed: `s`\n", name);
///          g_free (name);
///          gst_object_unref (device);
///          break;
///        default:
///          break;
///      }
///
///      return G_SOURCE_CONTINUE;
///   }
///
///   GstDeviceMonitor *
///   setup_raw_video_source_device_monitor (void) {
///      GstDeviceMonitor *monitor;
///      GstBus *bus;
///      GstCaps *caps;
///
///      monitor = gst_device_monitor_new ();
///
///      bus = gst_device_monitor_get_bus (monitor);
///      gst_bus_add_watch (bus, my_bus_func, NULL);
///      gst_object_unref (bus);
///
///      caps = gst_caps_new_empty_simple ("video/x-raw");
///      gst_device_monitor_add_filter (monitor, "Video/Source", caps);
///      gst_caps_unref (caps);
///
///      gst_device_monitor_start (monitor);
///
///      return monitor;
///   }
/// ```
pub const DeviceMonitor = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.DeviceMonitorClass;
    /// the parent `gst.Object` structure
    f_parent: gst.Object,
    f_priv: ?*gst.DeviceMonitorPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const show_all = struct {
            pub const name = "show-all";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    /// Create a new `gst.DeviceMonitor`
    extern fn gst_device_monitor_new() *gst.DeviceMonitor;
    pub const new = gst_device_monitor_new;

    /// Adds a filter for which `gst.Device` will be monitored, any device that matches
    /// all these classes and the `gst.Caps` will be returned.
    ///
    /// If this function is called multiple times to add more filters, each will be
    /// matched independently. That is, adding more filters will not further restrict
    /// what devices are matched.
    ///
    /// The `gst.Caps` supported by the device as returned by `gst.Device.getCaps` are
    /// not intersected with caps filters added using this function.
    ///
    /// Filters must be added before the `gst.DeviceMonitor` is started.
    extern fn gst_device_monitor_add_filter(p_monitor: *DeviceMonitor, p_classes: ?[*:0]const u8, p_caps: ?*gst.Caps) c_uint;
    pub const addFilter = gst_device_monitor_add_filter;

    /// Gets the `gst.Bus` of this `gst.DeviceMonitor`
    extern fn gst_device_monitor_get_bus(p_monitor: *DeviceMonitor) *gst.Bus;
    pub const getBus = gst_device_monitor_get_bus;

    /// Gets a list of devices from all of the relevant monitors. This may actually
    /// probe the hardware if the monitor is not currently started.
    extern fn gst_device_monitor_get_devices(p_monitor: *DeviceMonitor) ?*glib.List;
    pub const getDevices = gst_device_monitor_get_devices;

    /// Get a list of the currently selected device provider factories.
    ///
    /// This
    extern fn gst_device_monitor_get_providers(p_monitor: *DeviceMonitor) [*][*:0]u8;
    pub const getProviders = gst_device_monitor_get_providers;

    /// Get if `monitor` is currently showing all devices, even those from hidden
    /// providers.
    extern fn gst_device_monitor_get_show_all_devices(p_monitor: *DeviceMonitor) c_int;
    pub const getShowAllDevices = gst_device_monitor_get_show_all_devices;

    /// Removes a filter from the `gst.DeviceMonitor` using the id that was returned
    /// by `gst.DeviceMonitor.addFilter`.
    extern fn gst_device_monitor_remove_filter(p_monitor: *DeviceMonitor, p_filter_id: c_uint) c_int;
    pub const removeFilter = gst_device_monitor_remove_filter;

    /// Set if all devices should be visible, even those devices from hidden
    /// providers. Setting `show_all` to true might show some devices multiple times.
    extern fn gst_device_monitor_set_show_all_devices(p_monitor: *DeviceMonitor, p_show_all: c_int) void;
    pub const setShowAllDevices = gst_device_monitor_set_show_all_devices;

    /// Starts monitoring the devices, one this has succeeded, the
    /// `GST_MESSAGE_DEVICE_ADDED` and `GST_MESSAGE_DEVICE_REMOVED` messages
    /// will be emitted on the bus when the list of devices changes.
    extern fn gst_device_monitor_start(p_monitor: *DeviceMonitor) c_int;
    pub const start = gst_device_monitor_start;

    /// Stops monitoring the devices.
    extern fn gst_device_monitor_stop(p_monitor: *DeviceMonitor) void;
    pub const stop = gst_device_monitor_stop;

    extern fn gst_device_monitor_get_type() usize;
    pub const getGObjectType = gst_device_monitor_get_type;

    extern fn g_object_ref(p_self: *gst.DeviceMonitor) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.DeviceMonitor) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *DeviceMonitor, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.DeviceProvider` subclass is provided by a plugin that handles devices
/// if there is a way to programmatically list connected devices. It can also
/// optionally provide updates to the list of connected devices.
///
/// Each `gst.DeviceProvider` subclass is a singleton, a plugin should
/// normally provide a single subclass for all devices.
///
/// Applications would normally use a `gst.DeviceMonitor` to monitor devices
/// from all relevant providers.
pub const DeviceProvider = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.DeviceProviderClass;
    /// The parent `gst.Object`
    f_parent: gst.Object,
    /// a `glib.List` of the `gst.Device` objects
    f_devices: ?*glib.List,
    f_priv: ?*gst.DeviceProviderPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Returns a list of devices that are currently available.
        ///  This should never block. The devices should not have a parent and should
        ///  be floating.
        pub const probe = struct {
            pub fn call(p_class: anytype, p_provider: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) *glib.List {
                return gobject.ext.as(DeviceProvider.Class, p_class).f_probe.?(gobject.ext.as(DeviceProvider, p_provider));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_provider: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) *glib.List) void {
                gobject.ext.as(DeviceProvider.Class, p_class).f_probe = @ptrCast(p_implementation);
            }
        };

        /// Starts providering the devices. This will cause `GST_MESSAGE_DEVICE_ADDED`
        /// and `GST_MESSAGE_DEVICE_REMOVED` messages to be posted on the provider's bus
        /// when devices are added or removed from the system.
        ///
        /// Since the `gst.DeviceProvider` is a singleton,
        /// `gst.DeviceProvider.start` may already have been called by another
        /// user of the object, `gst.DeviceProvider.stop` needs to be called the same
        /// number of times.
        ///
        /// After this function has been called, `gst.DeviceProvider.getDevices` will
        /// return the same objects that have been received from the
        /// `GST_MESSAGE_DEVICE_ADDED` messages and will no longer probe.
        pub const start = struct {
            pub fn call(p_class: anytype, p_provider: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(DeviceProvider.Class, p_class).f_start.?(gobject.ext.as(DeviceProvider, p_provider));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_provider: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_int) void {
                gobject.ext.as(DeviceProvider.Class, p_class).f_start = @ptrCast(p_implementation);
            }
        };

        /// Decreases the use-count by one. If the use count reaches zero, this
        /// `gst.DeviceProvider` will stop providering the devices. This needs to be
        /// called the same number of times that `gst.DeviceProvider.start` was called.
        pub const stop = struct {
            pub fn call(p_class: anytype, p_provider: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(DeviceProvider.Class, p_class).f_stop.?(gobject.ext.as(DeviceProvider, p_provider));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_provider: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(DeviceProvider.Class, p_class).f_stop = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {
        pub const provider_hidden = struct {
            pub const name = "provider-hidden";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_object: [*:0]u8, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(DeviceProvider, p_instance))),
                    gobject.signalLookup("provider-hidden", DeviceProvider.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        pub const provider_unhidden = struct {
            pub const name = "provider-unhidden";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_object: [*:0]u8, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(DeviceProvider, p_instance))),
                    gobject.signalLookup("provider-unhidden", DeviceProvider.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Create a new device providerfactory capable of instantiating objects of the
    /// `type` and add the factory to `plugin`.
    extern fn gst_device_provider_register(p_plugin: ?*gst.Plugin, p_name: [*:0]const u8, p_rank: c_uint, p_type: usize) c_int;
    pub const register = gst_device_provider_register;

    extern fn gst_device_provider_can_monitor(p_provider: *DeviceProvider) c_int;
    pub const canMonitor = gst_device_provider_can_monitor;

    /// Posts a message on the provider's `gst.Bus` to inform applications that
    /// a new device has been added.
    ///
    /// This is for use by subclasses.
    ///
    /// `device`'s reference count will be incremented, and any floating reference
    /// will be removed (see `gst.Object.refSink`).
    extern fn gst_device_provider_device_add(p_provider: *DeviceProvider, p_device: *gst.Device) void;
    pub const deviceAdd = gst_device_provider_device_add;

    /// This function is used when `changed_device` was modified into its new form
    /// `device`. This will post a `DEVICE_CHANGED` message on the bus to let
    /// the application know that the device was modified. `gst.Device` is immutable
    /// for MT. safety purposes so this is an "atomic" way of letting the application
    /// know when a device was modified.
    extern fn gst_device_provider_device_changed(p_provider: *DeviceProvider, p_device: *gst.Device, p_changed_device: *gst.Device) void;
    pub const deviceChanged = gst_device_provider_device_changed;

    /// Posts a message on the provider's `gst.Bus` to inform applications that
    /// a device has been removed.
    ///
    /// This is for use by subclasses.
    extern fn gst_device_provider_device_remove(p_provider: *DeviceProvider, p_device: *gst.Device) void;
    pub const deviceRemove = gst_device_provider_device_remove;

    /// Gets the `gst.Bus` of this `gst.DeviceProvider`
    extern fn gst_device_provider_get_bus(p_provider: *DeviceProvider) *gst.Bus;
    pub const getBus = gst_device_provider_get_bus;

    /// Gets a list of devices that this provider understands. This may actually
    /// probe the hardware if the provider is not currently started.
    ///
    /// If the provider has been started, this will returned the same `gst.Device`
    /// objedcts that have been returned by the `GST_MESSAGE_DEVICE_ADDED` messages.
    extern fn gst_device_provider_get_devices(p_provider: *DeviceProvider) *glib.List;
    pub const getDevices = gst_device_provider_get_devices;

    /// Retrieves the factory that was used to create this device provider.
    extern fn gst_device_provider_get_factory(p_provider: *DeviceProvider) ?*gst.DeviceProviderFactory;
    pub const getFactory = gst_device_provider_get_factory;

    /// Get the provider factory names of the `gst.DeviceProvider` instances that
    /// are hidden by `provider`.
    extern fn gst_device_provider_get_hidden_providers(p_provider: *DeviceProvider) [*][*:0]u8;
    pub const getHiddenProviders = gst_device_provider_get_hidden_providers;

    /// Get metadata with `key` in `provider`.
    extern fn gst_device_provider_get_metadata(p_provider: *DeviceProvider, p_key: [*:0]const u8) [*:0]const u8;
    pub const getMetadata = gst_device_provider_get_metadata;

    /// Make `provider` hide the devices from the factory with `name`.
    ///
    /// This function is used when `provider` will also provide the devices reported
    /// by provider factory `name`. A monitor should stop monitoring the
    /// device provider with `name` to avoid duplicate devices.
    extern fn gst_device_provider_hide_provider(p_provider: *DeviceProvider, p_name: [*:0]const u8) void;
    pub const hideProvider = gst_device_provider_hide_provider;

    /// This function can be used to know if the `provider` was successfully started.
    extern fn gst_device_provider_is_started(p_provider: *DeviceProvider) c_int;
    pub const isStarted = gst_device_provider_is_started;

    /// Starts providering the devices. This will cause `GST_MESSAGE_DEVICE_ADDED`
    /// and `GST_MESSAGE_DEVICE_REMOVED` messages to be posted on the provider's bus
    /// when devices are added or removed from the system.
    ///
    /// Since the `gst.DeviceProvider` is a singleton,
    /// `gst.DeviceProvider.start` may already have been called by another
    /// user of the object, `gst.DeviceProvider.stop` needs to be called the same
    /// number of times.
    ///
    /// After this function has been called, `gst.DeviceProvider.getDevices` will
    /// return the same objects that have been received from the
    /// `GST_MESSAGE_DEVICE_ADDED` messages and will no longer probe.
    extern fn gst_device_provider_start(p_provider: *DeviceProvider) c_int;
    pub const start = gst_device_provider_start;

    /// Decreases the use-count by one. If the use count reaches zero, this
    /// `gst.DeviceProvider` will stop providering the devices. This needs to be
    /// called the same number of times that `gst.DeviceProvider.start` was called.
    extern fn gst_device_provider_stop(p_provider: *DeviceProvider) void;
    pub const stop = gst_device_provider_stop;

    /// Make `provider` unhide the devices from factory `name`.
    ///
    /// This function is used when `provider` will no longer provide the devices
    /// reported by provider factory `name`. A monitor should start
    /// monitoring the devices from provider factory `name` in order to see
    /// all devices again.
    extern fn gst_device_provider_unhide_provider(p_provider: *DeviceProvider, p_name: [*:0]const u8) void;
    pub const unhideProvider = gst_device_provider_unhide_provider;

    extern fn gst_device_provider_get_type() usize;
    pub const getGObjectType = gst_device_provider_get_type;

    extern fn g_object_ref(p_self: *gst.DeviceProvider) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.DeviceProvider) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *DeviceProvider, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.DeviceProviderFactory` is used to create instances of device providers. A
/// GstDeviceProviderfactory can be added to a `gst.Plugin` as it is also a
/// `gst.PluginFeature`.
///
/// Use the `gst.DeviceProviderFactory.find` and
/// `gst.DeviceProviderFactory.get` functions to create device
/// provider instances or use `gst.DeviceProviderFactory.getByName` as a
/// convenient shortcut.
pub const DeviceProviderFactory = opaque {
    pub const Parent = gst.PluginFeature;
    pub const Implements = [_]type{};
    pub const Class = gst.DeviceProviderFactoryClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Search for an device provider factory of the given name. Refs the returned
    /// device provider factory; caller is responsible for unreffing.
    extern fn gst_device_provider_factory_find(p_name: [*:0]const u8) ?*gst.DeviceProviderFactory;
    pub const find = gst_device_provider_factory_find;

    /// Returns the device provider of the type defined by the given device
    /// provider factory.
    extern fn gst_device_provider_factory_get_by_name(p_factoryname: [*:0]const u8) ?*gst.DeviceProvider;
    pub const getByName = gst_device_provider_factory_get_by_name;

    /// Get a list of factories with a rank greater or equal to `minrank`.
    /// The list of factories is returned by decreasing rank.
    extern fn gst_device_provider_factory_list_get_device_providers(p_minrank: gst.Rank) *glib.List;
    pub const listGetDeviceProviders = gst_device_provider_factory_list_get_device_providers;

    /// Returns the device provider of the type defined by the given device
    /// providerfactory.
    extern fn gst_device_provider_factory_get(p_factory: *DeviceProviderFactory) ?*gst.DeviceProvider;
    pub const get = gst_device_provider_factory_get;

    /// Get the `gobject.Type` for device providers managed by this factory. The type can
    /// only be retrieved if the device provider factory is loaded, which can be
    /// assured with `gst.PluginFeature.load`.
    extern fn gst_device_provider_factory_get_device_provider_type(p_factory: *DeviceProviderFactory) usize;
    pub const getDeviceProviderType = gst_device_provider_factory_get_device_provider_type;

    /// Get the metadata on `factory` with `key`.
    extern fn gst_device_provider_factory_get_metadata(p_factory: *DeviceProviderFactory, p_key: [*:0]const u8) ?[*:0]const u8;
    pub const getMetadata = gst_device_provider_factory_get_metadata;

    /// Get the available keys for the metadata on `factory`.
    extern fn gst_device_provider_factory_get_metadata_keys(p_factory: *DeviceProviderFactory) ?[*][*:0]u8;
    pub const getMetadataKeys = gst_device_provider_factory_get_metadata_keys;

    /// Check if `factory` matches all of the given `classes`
    extern fn gst_device_provider_factory_has_classes(p_factory: *DeviceProviderFactory, p_classes: ?[*:0]const u8) c_int;
    pub const hasClasses = gst_device_provider_factory_has_classes;

    /// Check if `factory` matches all of the given classes
    extern fn gst_device_provider_factory_has_classesv(p_factory: *DeviceProviderFactory, p_classes: ?[*][*:0]u8) c_int;
    pub const hasClassesv = gst_device_provider_factory_has_classesv;

    extern fn gst_device_provider_factory_get_type() usize;
    pub const getGObjectType = gst_device_provider_factory_get_type;

    extern fn g_object_ref(p_self: *gst.DeviceProviderFactory) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.DeviceProviderFactory) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *DeviceProviderFactory, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a `gdouble` range
pub const DoubleRange = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = DoubleRange;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_double_range_get_type() usize;
    pub const getGObjectType = gst_double_range_get_type;

    pub fn as(p_instance: *DoubleRange, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.DynamicTypeFactory` is used to represent a type that can be
/// automatically loaded the first time it is used. For example,
/// a non-standard type for use in caps fields.
///
/// In general, applications and plugins don't need to use the factory
/// beyond registering the type in a plugin init function. Once that is
/// done, the type is stored in the registry, and ready as soon as the
/// registry is loaded.
///
/// ## Registering a type for dynamic loading
///
/// ```
///
/// static gboolean
/// plugin_init (GstPlugin * plugin)
/// {
///   return gst_dynamic_type_register (plugin, GST_TYPE_CUSTOM_CAPS_FIELD);
/// }
/// ```
pub const DynamicTypeFactory = opaque {
    pub const Parent = gst.PluginFeature;
    pub const Implements = [_]type{};
    pub const Class = gst.DynamicTypeFactoryClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_dynamic_type_factory_load(p_factoryname: [*:0]const u8) usize;
    pub const load = gst_dynamic_type_factory_load;

    extern fn gst_dynamic_type_factory_get_type() usize;
    pub const getGObjectType = gst_dynamic_type_factory_get_type;

    extern fn g_object_ref(p_self: *gst.DynamicTypeFactory) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.DynamicTypeFactory) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *DynamicTypeFactory, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstElement is the abstract base class needed to construct an element that
/// can be used in a GStreamer pipeline. Please refer to the plugin writers
/// guide for more information on creating `gst.Element` subclasses.
///
/// The name of a `gst.Element` can be get with `gst_element_get_name` and set with
/// `gst_element_set_name`.  For speed, `GST_ELEMENT_NAME` can be used in the
/// core when using the appropriate locking. Do not use this in plug-ins or
/// applications in order to retain ABI compatibility.
///
/// Elements can have pads (of the type `gst.Pad`).  These pads link to pads on
/// other elements.  `gst.Buffer` flow between these linked pads.
/// A `gst.Element` has a `glib.List` of `gst.Pad` structures for all their input (or sink)
/// and output (or source) pads.
/// Core and plug-in writers can add and remove pads with `gst.Element.addPad`
/// and `gst.Element.removePad`.
///
/// An existing pad of an element can be retrieved by name with
/// `gst.Element.getStaticPad`. A new dynamic pad can be created using
/// `gst.Element.requestPad` with a `gst.PadTemplate`.
/// An iterator of all pads can be retrieved with `gst.Element.iteratePads`.
///
/// Elements can be linked through their pads.
/// If the link is straightforward, use the `gst.Element.link`
/// convenience function to link two elements, or `gst.Element.linkMany`
/// for more elements in a row.
/// Use `gst.Element.linkFiltered` to link two elements constrained by
/// a specified set of `gst.Caps`.
/// For finer control, use `gst.Element.linkPads` and
/// `gst.Element.linkPadsFiltered` to specify the pads to link on
/// each element by name.
///
/// Each element has a state (see `gst.State`).  You can get and set the state
/// of an element with `gst.Element.getState` and `gst.Element.setState`.
/// Setting a state triggers a `gst.StateChange`. To get a string representation
/// of a `gst.State`, use `gst.Element.stateGetName`.
///
/// You can get and set a `gst.Clock` on an element using `gst.Element.getClock`
/// and `gst.Element.setClock`.
/// Some elements can provide a clock for the pipeline if
/// the `GST_ELEMENT_FLAG_PROVIDE_CLOCK` flag is set. With the
/// `gst.Element.provideClock` method one can retrieve the clock provided by
/// such an element.
/// Not all elements require a clock to operate correctly. If the
/// `GST_ELEMENT_FLAG_REQUIRE_CLOCK``GST_ELEMENT_FLAG_REQUIRE_CLOCK` flag is set, a clock should be set on the
/// element with `gst.Element.setClock`.
///
/// Note that clock selection and distribution is normally handled by the
/// toplevel `gst.Pipeline` so the clock functions are only to be used in very
/// specific situations.
pub const Element = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.ElementClass;
    f_object: gst.Object,
    /// Used to serialize execution of `gst.Element.setState`
    f_state_lock: glib.RecMutex,
    /// Used to signal completion of a state change
    f_state_cond: glib.Cond,
    /// Used to detect concurrent execution of
    /// `gst.Element.setState` and `gst.Element.getState`
    f_state_cookie: u32,
    /// the target state of an element as set by the application
    f_target_state: gst.State,
    /// the current state of an element
    f_current_state: gst.State,
    /// the next state of an element, can be `GST_STATE_VOID_PENDING` if
    /// the element is in the correct state.
    f_next_state: gst.State,
    /// the final state the element should go to, can be
    /// `GST_STATE_VOID_PENDING` if the element is in the correct state
    f_pending_state: gst.State,
    /// the last return value of an element state change
    f_last_return: gst.StateChangeReturn,
    /// the bus of the element. This bus is provided to the element by the
    /// parent element or the application. A `gst.Pipeline` has a bus of its own.
    f_bus: ?*gst.Bus,
    /// the clock of the element. This clock is usually provided to the
    /// element by the toplevel `gst.Pipeline`.
    f_clock: ?*gst.Clock,
    /// the time of the clock right before the element is set to
    /// PLAYING. Subtracting `base_time` from the current clock time in the PLAYING
    /// state will yield the running_time against the clock.
    f_base_time: gst.ClockTimeDiff,
    /// the running_time of the last PAUSED state
    f_start_time: gst.ClockTime,
    /// number of pads of the element, includes both source and sink pads.
    f_numpads: u16,
    /// list of pads
    f_pads: ?*glib.List,
    /// number of source pads of the element.
    f_numsrcpads: u16,
    /// list of source pads
    f_srcpads: ?*glib.List,
    /// number of sink pads of the element.
    f_numsinkpads: u16,
    /// list of sink pads
    f_sinkpads: ?*glib.List,
    /// updated whenever the a pad is added or removed
    f_pads_cookie: u32,
    /// list of contexts
    f_contexts: ?*glib.List,
    f__gst_reserved: [3]*anyopaque,

    pub const virtual_methods = struct {
        /// Perform `transition` on `element`.
        ///
        /// This function must be called with STATE_LOCK held and is mainly used
        /// internally.
        pub const change_state = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_transition: gst.StateChange) gst.StateChangeReturn {
                return gobject.ext.as(Element.Class, p_class).f_change_state.?(gobject.ext.as(Element, p_element), p_transition);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_transition: gst.StateChange) callconv(.c) gst.StateChangeReturn) void {
                gobject.ext.as(Element.Class, p_class).f_change_state = @ptrCast(p_implementation);
            }
        };

        /// Gets the state of the element.
        ///
        /// For elements that performed an ASYNC state change, as reported by
        /// `gst.Element.setState`, this function will block up to the
        /// specified timeout value for the state change to complete.
        /// If the element completes the state change or goes into
        /// an error, this function returns immediately with a return value of
        /// `GST_STATE_CHANGE_SUCCESS` or `GST_STATE_CHANGE_FAILURE` respectively.
        ///
        /// For elements that did not return `GST_STATE_CHANGE_ASYNC`, this function
        /// returns the current and pending state immediately.
        ///
        /// This function returns `GST_STATE_CHANGE_NO_PREROLL` if the element
        /// successfully changed its state but is not able to provide data yet.
        /// This mostly happens for live sources that only produce data in
        /// `GST_STATE_PLAYING`. While the state change return is equivalent to
        /// `GST_STATE_CHANGE_SUCCESS`, it is returned to the application to signal that
        /// some sink elements might not be able to complete their state change because
        /// an element is not producing data to complete the preroll. When setting the
        /// element to playing, the preroll will complete and playback will start.
        pub const get_state = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: ?*gst.State, p_pending: ?*gst.State, p_timeout: gst.ClockTime) gst.StateChangeReturn {
                return gobject.ext.as(Element.Class, p_class).f_get_state.?(gobject.ext.as(Element, p_element), p_state, p_pending, p_timeout);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: ?*gst.State, p_pending: ?*gst.State, p_timeout: gst.ClockTime) callconv(.c) gst.StateChangeReturn) void {
                gobject.ext.as(Element.Class, p_class).f_get_state = @ptrCast(p_implementation);
            }
        };

        /// Use this function to signal that the element does not expect any more pads
        /// to show up in the current pipeline. This function should be called whenever
        /// pads have been added by the element itself. Elements with `GST_PAD_SOMETIMES`
        /// pad templates use this in combination with autopluggers to figure out that
        /// the element is done initializing its pads.
        ///
        /// This function emits the `gst.Element.signals.no`-more-pads signal.
        ///
        /// MT safe.
        pub const no_more_pads = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(Element.Class, p_class).f_no_more_pads.?(gobject.ext.as(Element, p_element));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(Element.Class, p_class).f_no_more_pads = @ptrCast(p_implementation);
            }
        };

        pub const pad_added = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) void {
                return gobject.ext.as(Element.Class, p_class).f_pad_added.?(gobject.ext.as(Element, p_element), p_pad);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) callconv(.c) void) void {
                gobject.ext.as(Element.Class, p_class).f_pad_added = @ptrCast(p_implementation);
            }
        };

        pub const pad_removed = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) void {
                return gobject.ext.as(Element.Class, p_class).f_pad_removed.?(gobject.ext.as(Element, p_element), p_pad);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) callconv(.c) void) void {
                gobject.ext.as(Element.Class, p_class).f_pad_removed = @ptrCast(p_implementation);
            }
        };

        /// Post a message on the element's `gst.Bus`. This function takes ownership of the
        /// message; if you want to access the message after this call, you should add an
        /// additional reference before calling.
        pub const post_message = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) c_int {
                return gobject.ext.as(Element.Class, p_class).f_post_message.?(gobject.ext.as(Element, p_element), p_message);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_message: *gst.Message) callconv(.c) c_int) void {
                gobject.ext.as(Element.Class, p_class).f_post_message = @ptrCast(p_implementation);
            }
        };

        /// Get the clock provided by the given element.
        /// > An element is only required to provide a clock in the PAUSED
        /// > state. Some elements can provide a clock in other states.
        pub const provide_clock = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) ?*gst.Clock {
                return gobject.ext.as(Element.Class, p_class).f_provide_clock.?(gobject.ext.as(Element, p_element));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) ?*gst.Clock) void {
                gobject.ext.as(Element.Class, p_class).f_provide_clock = @ptrCast(p_implementation);
            }
        };

        /// Performs a query on the given element.
        ///
        /// For elements that don't implement a query handler, this function
        /// forwards the query to a random srcpad or to the peer of a
        /// random linked sinkpad of this element.
        ///
        /// Please note that some queries might need a running pipeline to work.
        pub const query = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(Element.Class, p_class).f_query.?(gobject.ext.as(Element, p_element), p_query);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) callconv(.c) c_int) void {
                gobject.ext.as(Element.Class, p_class).f_query = @ptrCast(p_implementation);
            }
        };

        /// called when a request pad is to be released
        pub const release_pad = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) void {
                return gobject.ext.as(Element.Class, p_class).f_release_pad.?(gobject.ext.as(Element, p_element), p_pad);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) callconv(.c) void) void {
                gobject.ext.as(Element.Class, p_class).f_release_pad = @ptrCast(p_implementation);
            }
        };

        /// Retrieves a request pad from the element according to the provided template.
        /// Pad templates can be looked up using
        /// `gst.ElementFactory.getStaticPadTemplates`.
        ///
        /// The pad should be released with `gst.Element.releaseRequestPad`.
        pub const request_new_pad = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_templ: *gst.PadTemplate, p_name: ?[*:0]const u8, p_caps: ?*const gst.Caps) ?*gst.Pad {
                return gobject.ext.as(Element.Class, p_class).f_request_new_pad.?(gobject.ext.as(Element, p_element), p_templ, p_name, p_caps);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_templ: *gst.PadTemplate, p_name: ?[*:0]const u8, p_caps: ?*const gst.Caps) callconv(.c) ?*gst.Pad) void {
                gobject.ext.as(Element.Class, p_class).f_request_new_pad = @ptrCast(p_implementation);
            }
        };

        /// Sends an event to an element. If the element doesn't implement an
        /// event handler, the event will be pushed on a random linked sink pad for
        /// downstream events or a random linked source pad for upstream events.
        ///
        /// This function takes ownership of the provided event so you should
        /// `gst.Event.ref` it if you want to reuse the event after this call.
        ///
        /// MT safe.
        pub const send_event = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(Element.Class, p_class).f_send_event.?(gobject.ext.as(Element, p_element), p_event);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) callconv(.c) c_int) void {
                gobject.ext.as(Element.Class, p_class).f_send_event = @ptrCast(p_implementation);
            }
        };

        /// Sets the bus of the element. Increases the refcount on the bus.
        /// For internal use only, unless you're testing elements.
        ///
        /// MT safe.
        pub const set_bus = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_bus: ?*gst.Bus) void {
                return gobject.ext.as(Element.Class, p_class).f_set_bus.?(gobject.ext.as(Element, p_element), p_bus);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_bus: ?*gst.Bus) callconv(.c) void) void {
                gobject.ext.as(Element.Class, p_class).f_set_bus = @ptrCast(p_implementation);
            }
        };

        /// Sets the clock for the element. This function increases the
        /// refcount on the clock. Any previously set clock on the object
        /// is unreffed.
        pub const set_clock = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_clock: ?*gst.Clock) c_int {
                return gobject.ext.as(Element.Class, p_class).f_set_clock.?(gobject.ext.as(Element, p_element), p_clock);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_clock: ?*gst.Clock) callconv(.c) c_int) void {
                gobject.ext.as(Element.Class, p_class).f_set_clock = @ptrCast(p_implementation);
            }
        };

        /// Sets the context of the element. Increases the refcount of the context.
        ///
        /// MT safe.
        pub const set_context = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_context: *gst.Context) void {
                return gobject.ext.as(Element.Class, p_class).f_set_context.?(gobject.ext.as(Element, p_element), p_context);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_context: *gst.Context) callconv(.c) void) void {
                gobject.ext.as(Element.Class, p_class).f_set_context = @ptrCast(p_implementation);
            }
        };

        /// Sets the state of the element. This function will try to set the
        /// requested state by going through all the intermediary states and calling
        /// the class's state change function for each.
        ///
        /// This function can return `GST_STATE_CHANGE_ASYNC`, in which case the
        /// element will perform the remainder of the state change asynchronously in
        /// another thread.
        /// An application can use `gst.Element.getState` to wait for the completion
        /// of the state change or it can wait for a `GST_MESSAGE_ASYNC_DONE` or
        /// `GST_MESSAGE_STATE_CHANGED` on the bus.
        ///
        /// State changes to `GST_STATE_READY` or `GST_STATE_NULL` never return
        /// `GST_STATE_CHANGE_ASYNC`.
        pub const set_state = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: gst.State) gst.StateChangeReturn {
                return gobject.ext.as(Element.Class, p_class).f_set_state.?(gobject.ext.as(Element, p_element), p_state);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: gst.State) callconv(.c) gst.StateChangeReturn) void {
                gobject.ext.as(Element.Class, p_class).f_set_state = @ptrCast(p_implementation);
            }
        };

        /// called immediately after a new state was set.
        pub const state_changed = struct {
            pub fn call(p_class: anytype, p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_oldstate: gst.State, p_newstate: gst.State, p_pending: gst.State) void {
                return gobject.ext.as(Element.Class, p_class).f_state_changed.?(gobject.ext.as(Element, p_element), p_oldstate, p_newstate, p_pending);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_element: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_oldstate: gst.State, p_newstate: gst.State, p_pending: gst.State) callconv(.c) void) void {
                gobject.ext.as(Element.Class, p_class).f_state_changed = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {
        /// This signals that the element will not generate more dynamic pads.
        /// Note that this signal will usually be emitted from the context of
        /// the streaming thread.
        pub const no_more_pads = struct {
            pub const name = "no-more-pads";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Element, p_instance))),
                    gobject.signalLookup("no-more-pads", Element.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// a new `gst.Pad` has been added to the element. Note that this signal will
        /// usually be emitted from the context of the streaming thread. Also keep in
        /// mind that if you add new elements to the pipeline in the signal handler
        /// you will need to set them to the desired target state with
        /// `gst.Element.setState` or `gst.Element.syncStateWithParent`.
        pub const pad_added = struct {
            pub const name = "pad-added";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_new_pad: *gst.Pad, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Element, p_instance))),
                    gobject.signalLookup("pad-added", Element.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// a `gst.Pad` has been removed from the element
        pub const pad_removed = struct {
            pub const name = "pad-removed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_old_pad: *gst.Pad, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Element, p_instance))),
                    gobject.signalLookup("pad-removed", Element.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Creates an element for handling the given URI.
    extern fn gst_element_make_from_uri(p_type: gst.URIType, p_uri: [*:0]const u8, p_elementname: ?[*:0]const u8, p_error: ?*?*glib.Error) ?*gst.Element;
    pub const makeFromUri = gst_element_make_from_uri;

    /// Create a new elementfactory capable of instantiating objects of the
    /// `type` and add the factory to `plugin`.
    extern fn gst_element_register(p_plugin: ?*gst.Plugin, p_name: [*:0]const u8, p_rank: c_uint, p_type: usize) c_int;
    pub const register = gst_element_register;

    /// Gets a string representing the given state change result.
    extern fn gst_element_state_change_return_get_name(p_state_ret: gst.StateChangeReturn) [*:0]const u8;
    pub const stateChangeReturnGetName = gst_element_state_change_return_get_name;

    /// Gets a string representing the given state.
    extern fn gst_element_state_get_name(p_state: gst.State) [*:0]const u8;
    pub const stateGetName = gst_element_state_get_name;

    /// Marks `type` as "documentation should be skipped".
    /// Can be useful for dynamically registered element to be excluded from
    /// plugin documentation system.
    ///
    /// Example:
    /// ```c
    /// GType my_type;
    /// GTypeInfo my_type_info;
    ///
    /// // Fill "my_type_info"
    /// ...
    ///
    /// my_type = g_type_register_static (GST_TYPE_MY_ELEMENT, "my-type-name",
    ///    &my_type_info, 0);
    /// gst_element_type_set_skip_documentation (my_type);
    /// gst_element_register (plugin, "my-plugin-feature-name", rank, my_type);
    /// ```
    extern fn gst_element_type_set_skip_documentation(p_type: usize) void;
    pub const typeSetSkipDocumentation = gst_element_type_set_skip_documentation;

    /// Abort the state change of the element. This function is used
    /// by elements that do asynchronous state changes and find out
    /// something is wrong.
    ///
    /// This function should be called with the STATE_LOCK held.
    ///
    /// MT safe.
    extern fn gst_element_abort_state(p_element: *Element) void;
    pub const abortState = gst_element_abort_state;

    /// Adds a pad (link point) to `element`. `pad`'s parent will be set to `element`;
    /// see `gst.Object.setParent` for refcounting information.
    ///
    /// Pads are automatically activated when added in the PAUSED or PLAYING
    /// state.
    ///
    /// The pad and the element should be unlocked when calling this function.
    ///
    /// This function will emit the `gst.Element.signals.pad`-added signal on the element.
    extern fn gst_element_add_pad(p_element: *Element, p_pad: *gst.Pad) c_int;
    pub const addPad = gst_element_add_pad;

    extern fn gst_element_add_property_deep_notify_watch(p_element: *Element, p_property_name: ?[*:0]const u8, p_include_value: c_int) c_ulong;
    pub const addPropertyDeepNotifyWatch = gst_element_add_property_deep_notify_watch;

    extern fn gst_element_add_property_notify_watch(p_element: *Element, p_property_name: ?[*:0]const u8, p_include_value: c_int) c_ulong;
    pub const addPropertyNotifyWatch = gst_element_add_property_notify_watch;

    /// Calls `func` from another thread and passes `user_data` to it. This is to be
    /// used for cases when a state change has to be performed from a streaming
    /// thread, directly via `gst.Element.setState` or indirectly e.g. via SEEK
    /// events.
    ///
    /// Calling those functions directly from the streaming thread will cause
    /// deadlocks in many situations, as they might involve waiting for the
    /// streaming thread to shut down from this very streaming thread.
    ///
    /// MT safe.
    extern fn gst_element_call_async(p_element: *Element, p_func: gst.ElementCallAsyncFunc, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const callAsync = gst_element_call_async;

    /// Perform `transition` on `element`.
    ///
    /// This function must be called with STATE_LOCK held and is mainly used
    /// internally.
    extern fn gst_element_change_state(p_element: *Element, p_transition: gst.StateChange) gst.StateChangeReturn;
    pub const changeState = gst_element_change_state;

    /// Commit the state change of the element and proceed to the next
    /// pending state if any. This function is used
    /// by elements that do asynchronous state changes.
    /// The core will normally call this method automatically when an
    /// element returned `GST_STATE_CHANGE_SUCCESS` from the state change function.
    ///
    /// If after calling this method the element still has not reached
    /// the pending state, the next state change is performed.
    ///
    /// This method is used internally and should normally not be called by plugins
    /// or applications.
    ///
    /// This function must be called with STATE_LOCK held.
    extern fn gst_element_continue_state(p_element: *Element, p_ret: gst.StateChangeReturn) gst.StateChangeReturn;
    pub const continueState = gst_element_continue_state;

    /// Creates a pad for each pad template that is always available.
    /// This function is only useful during object initialization of
    /// subclasses of `gst.Element`.
    extern fn gst_element_create_all_pads(p_element: *Element) void;
    pub const createAllPads = gst_element_create_all_pads;

    /// Creates a stream-id for `element` by combining the upstream information with
    /// the `stream_id`.
    ///
    /// This function generates an unique stream-id by getting the upstream
    /// stream-start event stream ID and appending `stream_id` to it. If the element
    /// has no sinkpad it will generate an upstream stream-id by doing an URI query
    /// on the element and in the worst case just uses a random number. Source
    /// elements that don't implement the URI handler interface should ideally
    /// generate a unique, deterministic stream-id manually instead.
    ///
    /// Since stream IDs are sorted alphabetically, any numbers in the stream ID
    /// should be printed with a fixed number of characters, preceded by 0's, such as
    /// by using the format \%03u instead of \%u.
    extern fn gst_element_decorate_stream_id(p_element: *Element, p_stream_id: [*:0]const u8) [*:0]u8;
    pub const decorateStreamId = gst_element_decorate_stream_id;

    /// Creates a stream-id for `element` by combining the upstream information with
    /// the `format`.
    ///
    /// This function generates an unique stream-id by getting the upstream
    /// stream-start event stream ID and appending the stream-id to it. If the element
    /// has no sinkpad it will generate an upstream stream-id by doing an URI query
    /// on the element and in the worst case just uses a random number. Source
    /// elements that don't implement the URI handler interface should ideally
    /// generate a unique, deterministic stream-id manually instead.
    ///
    /// Since stream IDs are sorted alphabetically, any numbers in the stream ID
    /// should be printed with a fixed number of characters, preceded by 0's, such as
    /// by using the format \%03u instead of \%u.
    extern fn gst_element_decorate_stream_id_printf(p_element: *Element, p_format: [*:0]const u8, ...) [*:0]u8;
    pub const decorateStreamIdPrintf = gst_element_decorate_stream_id_printf;

    /// Creates a stream-id for `element` by combining the upstream information with
    /// the `format`.
    ///
    /// This function generates an unique stream-id by getting the upstream
    /// stream-start event stream ID and appending `format` to it. If the element
    /// has no sinkpad it will generate an upstream stream-id by doing an URI query
    /// on the element and in the worst case just uses a random number. Source
    /// elements that don't implement the URI handler interface should ideally
    /// generate a unique, deterministic stream-id manually instead.
    ///
    /// Since stream IDs are sorted alphabetically, any numbers in the stream ID
    /// should be printed with a fixed number of characters, preceded by 0's, such as
    /// by using the format \%03u instead of \%u.
    extern fn gst_element_decorate_stream_id_printf_valist(p_element: *Element, p_format: [*:0]const u8, p_var_args: std.builtin.VaList) [*:0]u8;
    pub const decorateStreamIdPrintfValist = gst_element_decorate_stream_id_printf_valist;

    /// Call `func` with `user_data` for each of `element`'s pads. `func` will be called
    /// exactly once for each pad that exists at the time of this call, unless
    /// one of the calls to `func` returns `FALSE` in which case we will stop
    /// iterating pads and return early. If new pads are added or pads are removed
    /// while pads are being iterated, this will not be taken into account until
    /// next time this function is used.
    extern fn gst_element_foreach_pad(p_element: *Element, p_func: gst.ElementForeachPadFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreachPad = gst_element_foreach_pad;

    /// Call `func` with `user_data` for each of `element`'s sink pads. `func` will be
    /// called exactly once for each sink pad that exists at the time of this call,
    /// unless one of the calls to `func` returns `FALSE` in which case we will stop
    /// iterating pads and return early. If new sink pads are added or sink pads
    /// are removed while the sink pads are being iterated, this will not be taken
    /// into account until next time this function is used.
    extern fn gst_element_foreach_sink_pad(p_element: *Element, p_func: gst.ElementForeachPadFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreachSinkPad = gst_element_foreach_sink_pad;

    /// Call `func` with `user_data` for each of `element`'s source pads. `func` will be
    /// called exactly once for each source pad that exists at the time of this call,
    /// unless one of the calls to `func` returns `FALSE` in which case we will stop
    /// iterating pads and return early. If new source pads are added or source pads
    /// are removed while the source pads are being iterated, this will not be taken
    /// into account until next time this function is used.
    extern fn gst_element_foreach_src_pad(p_element: *Element, p_func: gst.ElementForeachPadFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreachSrcPad = gst_element_foreach_src_pad;

    /// Returns the base time of the element. The base time is the
    /// absolute time of the clock when this element was last put to
    /// PLAYING. Subtracting the base time from the clock time gives
    /// the running time of the element.
    extern fn gst_element_get_base_time(p_element: *Element) gst.ClockTime;
    pub const getBaseTime = gst_element_get_base_time;

    /// Returns the bus of the element. Note that only a `gst.Pipeline` will provide a
    /// bus for the application.
    extern fn gst_element_get_bus(p_element: *Element) ?*gst.Bus;
    pub const getBus = gst_element_get_bus;

    /// Gets the currently configured clock of the element. This is the clock as was
    /// last set with `gst.Element.setClock`.
    ///
    /// Elements in a pipeline will only have their clock set when the
    /// pipeline is in the PLAYING state.
    extern fn gst_element_get_clock(p_element: *Element) ?*gst.Clock;
    pub const getClock = gst_element_get_clock;

    /// Looks for an unlinked pad to which the given pad can link. It is not
    /// guaranteed that linking the pads will work, though it should work in most
    /// cases.
    ///
    /// This function will first attempt to find a compatible unlinked ALWAYS pad,
    /// and if none can be found, it will request a compatible REQUEST pad by looking
    /// at the templates of `element`.
    extern fn gst_element_get_compatible_pad(p_element: *Element, p_pad: *gst.Pad, p_caps: ?*gst.Caps) ?*gst.Pad;
    pub const getCompatiblePad = gst_element_get_compatible_pad;

    /// Retrieves a pad template from `element` that is compatible with `compattempl`.
    /// Pads from compatible templates can be linked together.
    extern fn gst_element_get_compatible_pad_template(p_element: *Element, p_compattempl: *gst.PadTemplate) ?*gst.PadTemplate;
    pub const getCompatiblePadTemplate = gst_element_get_compatible_pad_template;

    /// Gets the context with `context_type` set on the element or NULL.
    ///
    /// MT safe.
    extern fn gst_element_get_context(p_element: *Element, p_context_type: [*:0]const u8) ?*gst.Context;
    pub const getContext = gst_element_get_context;

    /// Gets the context with `context_type` set on the element or NULL.
    extern fn gst_element_get_context_unlocked(p_element: *Element, p_context_type: [*:0]const u8) ?*gst.Context;
    pub const getContextUnlocked = gst_element_get_context_unlocked;

    /// Gets the contexts set on the element.
    ///
    /// MT safe.
    extern fn gst_element_get_contexts(p_element: *Element) *glib.List;
    pub const getContexts = gst_element_get_contexts;

    /// Returns the current clock time of the element, as in, the time of the
    /// element's clock, or GST_CLOCK_TIME_NONE if there is no clock.
    extern fn gst_element_get_current_clock_time(p_element: *Element) gst.ClockTime;
    pub const getCurrentClockTime = gst_element_get_current_clock_time;

    /// Returns the running time of the element. The running time is the
    /// element's clock time minus its base time. Will return GST_CLOCK_TIME_NONE
    /// if the element has no clock, or if its base time has not been set.
    extern fn gst_element_get_current_running_time(p_element: *Element) gst.ClockTime;
    pub const getCurrentRunningTime = gst_element_get_current_running_time;

    /// Retrieves the factory that was used to create this element.
    extern fn gst_element_get_factory(p_element: *Element) ?*gst.ElementFactory;
    pub const getFactory = gst_element_get_factory;

    /// Get metadata with `key` in `klass`.
    extern fn gst_element_get_metadata(p_element: *Element, p_key: [*:0]const u8) [*:0]const u8;
    pub const getMetadata = gst_element_get_metadata;

    /// Retrieves a padtemplate from `element` with the given name.
    extern fn gst_element_get_pad_template(p_element: *Element, p_name: [*:0]const u8) ?*gst.PadTemplate;
    pub const getPadTemplate = gst_element_get_pad_template;

    /// Retrieves a list of the pad templates associated with `element`. The
    /// list must not be modified by the calling code.
    extern fn gst_element_get_pad_template_list(p_element: *Element) *glib.List;
    pub const getPadTemplateList = gst_element_get_pad_template_list;

    /// The name of this function is confusing to people learning GStreamer.
    /// `gst.Element.requestPadSimple` aims at making it more explicit it is
    /// a simplified `gst.Element.requestPad`.
    extern fn gst_element_get_request_pad(p_element: *Element, p_name: [*:0]const u8) ?*gst.Pad;
    pub const getRequestPad = gst_element_get_request_pad;

    /// Returns the start time of the element. The start time is the
    /// running time of the clock when this element was last put to PAUSED.
    ///
    /// Usually the start_time is managed by a toplevel element such as
    /// `gst.Pipeline`.
    ///
    /// MT safe.
    extern fn gst_element_get_start_time(p_element: *Element) gst.ClockTime;
    pub const getStartTime = gst_element_get_start_time;

    /// Gets the state of the element.
    ///
    /// For elements that performed an ASYNC state change, as reported by
    /// `gst.Element.setState`, this function will block up to the
    /// specified timeout value for the state change to complete.
    /// If the element completes the state change or goes into
    /// an error, this function returns immediately with a return value of
    /// `GST_STATE_CHANGE_SUCCESS` or `GST_STATE_CHANGE_FAILURE` respectively.
    ///
    /// For elements that did not return `GST_STATE_CHANGE_ASYNC`, this function
    /// returns the current and pending state immediately.
    ///
    /// This function returns `GST_STATE_CHANGE_NO_PREROLL` if the element
    /// successfully changed its state but is not able to provide data yet.
    /// This mostly happens for live sources that only produce data in
    /// `GST_STATE_PLAYING`. While the state change return is equivalent to
    /// `GST_STATE_CHANGE_SUCCESS`, it is returned to the application to signal that
    /// some sink elements might not be able to complete their state change because
    /// an element is not producing data to complete the preroll. When setting the
    /// element to playing, the preroll will complete and playback will start.
    extern fn gst_element_get_state(p_element: *Element, p_state: ?*gst.State, p_pending: ?*gst.State, p_timeout: gst.ClockTime) gst.StateChangeReturn;
    pub const getState = gst_element_get_state;

    /// Retrieves a pad from `element` by name. This version only retrieves
    /// already-existing (i.e. 'static') pads.
    extern fn gst_element_get_static_pad(p_element: *Element, p_name: [*:0]const u8) ?*gst.Pad;
    pub const getStaticPad = gst_element_get_static_pad;

    /// Checks if the state of an element is locked.
    /// If the state of an element is locked, state changes of the parent don't
    /// affect the element.
    /// This way you can leave currently unused elements inside bins. Just lock their
    /// state before changing the state from `GST_STATE_NULL`.
    ///
    /// MT safe.
    extern fn gst_element_is_locked_state(p_element: *Element) c_int;
    pub const isLockedState = gst_element_is_locked_state;

    /// Retrieves an iterator of `element`'s pads. The iterator should
    /// be freed after usage. Also more specialized iterators exists such as
    /// `gst.Element.iterateSrcPads` or `gst.Element.iterateSinkPads`.
    ///
    /// The order of pads returned by the iterator will be the order in which
    /// the pads were added to the element.
    extern fn gst_element_iterate_pads(p_element: *Element) *gst.Iterator;
    pub const iteratePads = gst_element_iterate_pads;

    /// Retrieves an iterator of `element`'s sink pads.
    ///
    /// The order of pads returned by the iterator will be the order in which
    /// the pads were added to the element.
    extern fn gst_element_iterate_sink_pads(p_element: *Element) *gst.Iterator;
    pub const iterateSinkPads = gst_element_iterate_sink_pads;

    /// Retrieves an iterator of `element`'s source pads.
    ///
    /// The order of pads returned by the iterator will be the order in which
    /// the pads were added to the element.
    extern fn gst_element_iterate_src_pads(p_element: *Element) *gst.Iterator;
    pub const iterateSrcPads = gst_element_iterate_src_pads;

    /// Links `src` to `dest`. The link must be from source to
    /// destination; the other direction will not be tried. The function looks for
    /// existing pads that aren't linked yet. It will request new pads if necessary.
    /// Such pads need to be released manually when unlinking.
    /// If multiple links are possible, only one is established.
    ///
    /// Make sure you have added your elements to a bin or pipeline with
    /// `gst.Bin.add` before trying to link them.
    extern fn gst_element_link(p_src: *Element, p_dest: *gst.Element) c_int;
    pub const link = gst_element_link;

    /// Links `src` to `dest` using the given caps as filtercaps.
    /// The link must be from source to
    /// destination; the other direction will not be tried. The function looks for
    /// existing pads that aren't linked yet. It will request new pads if necessary.
    /// If multiple links are possible, only one is established.
    ///
    /// Make sure you have added your elements to a bin or pipeline with
    /// `gst.Bin.add` before trying to link them.
    extern fn gst_element_link_filtered(p_src: *Element, p_dest: *gst.Element, p_filter: ?*gst.Caps) c_int;
    pub const linkFiltered = gst_element_link_filtered;

    /// Chain together a series of elements. Uses `gst.Element.link`.
    /// Make sure you have added your elements to a bin or pipeline with
    /// `gst.Bin.add` before trying to link them.
    extern fn gst_element_link_many(p_element_1: *Element, p_element_2: *gst.Element, ...) c_int;
    pub const linkMany = gst_element_link_many;

    /// Links the two named pads of the source and destination elements.
    /// Side effect is that if one of the pads has no parent, it becomes a
    /// child of the parent of the other element.  If they have different
    /// parents, the link fails.
    extern fn gst_element_link_pads(p_src: *Element, p_srcpadname: ?[*:0]const u8, p_dest: *gst.Element, p_destpadname: ?[*:0]const u8) c_int;
    pub const linkPads = gst_element_link_pads;

    /// Links the two named pads of the source and destination elements. Side effect
    /// is that if one of the pads has no parent, it becomes a child of the parent of
    /// the other element. If they have different parents, the link fails. If `caps`
    /// is not `NULL`, makes sure that the caps of the link is a subset of `caps`.
    extern fn gst_element_link_pads_filtered(p_src: *Element, p_srcpadname: ?[*:0]const u8, p_dest: *gst.Element, p_destpadname: ?[*:0]const u8, p_filter: ?*gst.Caps) c_int;
    pub const linkPadsFiltered = gst_element_link_pads_filtered;

    /// Links the two named pads of the source and destination elements.
    /// Side effect is that if one of the pads has no parent, it becomes a
    /// child of the parent of the other element.  If they have different
    /// parents, the link fails.
    ///
    /// Calling `gst.Element.linkPadsFull` with `flags` == `GST_PAD_LINK_CHECK_DEFAULT`
    /// is the same as calling `gst.Element.linkPads` and the recommended way of
    /// linking pads with safety checks applied.
    ///
    /// This is a convenience function for `gst.Pad.linkFull`.
    extern fn gst_element_link_pads_full(p_src: *Element, p_srcpadname: ?[*:0]const u8, p_dest: *gst.Element, p_destpadname: ?[*:0]const u8, p_flags: gst.PadLinkCheck) c_int;
    pub const linkPadsFull = gst_element_link_pads_full;

    /// Brings the element to the lost state. The current state of the
    /// element is copied to the pending state so that any call to
    /// `gst.Element.getState` will return `GST_STATE_CHANGE_ASYNC`.
    ///
    /// An ASYNC_START message is posted. If the element was PLAYING, it will
    /// go to PAUSED. The element will be restored to its PLAYING state by
    /// the parent pipeline when it prerolls again.
    ///
    /// This is mostly used for elements that lost their preroll buffer
    /// in the `GST_STATE_PAUSED` or `GST_STATE_PLAYING` state after a flush,
    /// they will go to their pending state again when a new preroll buffer is
    /// queued. This function can only be called when the element is currently
    /// not in error or an async state change.
    ///
    /// This function is used internally and should normally not be called from
    /// plugins or applications.
    extern fn gst_element_lost_state(p_element: *Element) void;
    pub const lostState = gst_element_lost_state;

    /// Post an error, warning or info message on the bus from inside an element.
    ///
    /// `type` must be of `GST_MESSAGE_ERROR`, `GST_MESSAGE_WARNING` or
    /// `GST_MESSAGE_INFO`.
    ///
    /// MT safe.
    extern fn gst_element_message_full(p_element: *Element, p_type: gst.MessageType, p_domain: glib.Quark, p_code: c_int, p_text: ?[*:0]u8, p_debug: ?[*:0]u8, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int) void;
    pub const messageFull = gst_element_message_full;

    /// Post an error, warning or info message on the bus from inside an element.
    ///
    /// `type` must be of `GST_MESSAGE_ERROR`, `GST_MESSAGE_WARNING` or
    /// `GST_MESSAGE_INFO`.
    extern fn gst_element_message_full_with_details(p_element: *Element, p_type: gst.MessageType, p_domain: glib.Quark, p_code: c_int, p_text: ?[*:0]u8, p_debug: ?[*:0]u8, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_structure: *gst.Structure) void;
    pub const messageFullWithDetails = gst_element_message_full_with_details;

    /// Use this function to signal that the element does not expect any more pads
    /// to show up in the current pipeline. This function should be called whenever
    /// pads have been added by the element itself. Elements with `GST_PAD_SOMETIMES`
    /// pad templates use this in combination with autopluggers to figure out that
    /// the element is done initializing its pads.
    ///
    /// This function emits the `gst.Element.signals.no`-more-pads signal.
    ///
    /// MT safe.
    extern fn gst_element_no_more_pads(p_element: *Element) void;
    pub const noMorePads = gst_element_no_more_pads;

    /// Post a message on the element's `gst.Bus`. This function takes ownership of the
    /// message; if you want to access the message after this call, you should add an
    /// additional reference before calling.
    extern fn gst_element_post_message(p_element: *Element, p_message: *gst.Message) c_int;
    pub const postMessage = gst_element_post_message;

    /// Get the clock provided by the given element.
    /// > An element is only required to provide a clock in the PAUSED
    /// > state. Some elements can provide a clock in other states.
    extern fn gst_element_provide_clock(p_element: *Element) ?*gst.Clock;
    pub const provideClock = gst_element_provide_clock;

    /// Performs a query on the given element.
    ///
    /// For elements that don't implement a query handler, this function
    /// forwards the query to a random srcpad or to the peer of a
    /// random linked sinkpad of this element.
    ///
    /// Please note that some queries might need a running pipeline to work.
    extern fn gst_element_query(p_element: *Element, p_query: *gst.Query) c_int;
    pub const query = gst_element_query;

    /// Queries an element to convert `src_val` in `src_format` to `dest_format`.
    extern fn gst_element_query_convert(p_element: *Element, p_src_format: gst.Format, p_src_val: i64, p_dest_format: gst.Format, p_dest_val: *i64) c_int;
    pub const queryConvert = gst_element_query_convert;

    /// Queries an element (usually top-level pipeline or playbin element) for the
    /// total stream duration in nanoseconds. This query will only work once the
    /// pipeline is prerolled (i.e. reached PAUSED or PLAYING state). The application
    /// will receive an ASYNC_DONE message on the pipeline bus when that is the case.
    ///
    /// If the duration changes for some reason, you will get a DURATION_CHANGED
    /// message on the pipeline bus, in which case you should re-query the duration
    /// using this function.
    extern fn gst_element_query_duration(p_element: *Element, p_format: gst.Format, p_duration: ?*i64) c_int;
    pub const queryDuration = gst_element_query_duration;

    /// Queries an element (usually top-level pipeline or playbin element) for the
    /// stream position in nanoseconds. This will be a value between 0 and the
    /// stream duration (if the stream duration is known). This query will usually
    /// only work once the pipeline is prerolled (i.e. reached PAUSED or PLAYING
    /// state). The application will receive an ASYNC_DONE message on the pipeline
    /// bus when that is the case.
    ///
    /// If one repeatedly calls this function one can also create a query and reuse
    /// it in `gst.Element.query`.
    extern fn gst_element_query_position(p_element: *Element, p_format: gst.Format, p_cur: ?*i64) c_int;
    pub const queryPosition = gst_element_query_position;

    /// Makes the element free the previously requested pad as obtained
    /// with `gst.Element.requestPad`.
    ///
    /// This does not unref the pad. If the pad was created by using
    /// `gst.Element.requestPad`, `gst.Element.releaseRequestPad` needs to be
    /// followed by `gst.Object.unref` to free the `pad`.
    ///
    /// MT safe.
    extern fn gst_element_release_request_pad(p_element: *Element, p_pad: *gst.Pad) void;
    pub const releaseRequestPad = gst_element_release_request_pad;

    /// Removes `pad` from `element`. `pad` will be destroyed if it has not been
    /// referenced elsewhere using `gst.Object.unparent`.
    ///
    /// This function is used by plugin developers and should not be used
    /// by applications. Pads that were dynamically requested from elements
    /// with `gst.Element.requestPad` should be released with the
    /// `gst.Element.releaseRequestPad` function instead.
    ///
    /// Pads are not automatically deactivated so elements should perform the needed
    /// steps to deactivate the pad in case this pad is removed in the PAUSED or
    /// PLAYING state. See `gst.Pad.setActive` for more information about
    /// deactivating pads.
    ///
    /// The pad and the element should be unlocked when calling this function.
    ///
    /// This function will emit the `gst.Element.signals.pad`-removed signal on the element.
    extern fn gst_element_remove_pad(p_element: *Element, p_pad: *gst.Pad) c_int;
    pub const removePad = gst_element_remove_pad;

    extern fn gst_element_remove_property_notify_watch(p_element: *Element, p_watch_id: c_ulong) void;
    pub const removePropertyNotifyWatch = gst_element_remove_property_notify_watch;

    /// Retrieves a request pad from the element according to the provided template.
    /// Pad templates can be looked up using
    /// `gst.ElementFactory.getStaticPadTemplates`.
    ///
    /// The pad should be released with `gst.Element.releaseRequestPad`.
    extern fn gst_element_request_pad(p_element: *Element, p_templ: *gst.PadTemplate, p_name: ?[*:0]const u8, p_caps: ?*const gst.Caps) ?*gst.Pad;
    pub const requestPad = gst_element_request_pad;

    /// Retrieves a pad from the element by name (e.g. "src_\%d"). This version only
    /// retrieves request pads. The pad should be released with
    /// `gst.Element.releaseRequestPad`.
    ///
    /// This method is slower than manually getting the pad template and calling
    /// `gst.Element.requestPad` if the pads should have a specific name (e.g.
    /// `name` is "src_1" instead of "src_\%u").
    ///
    /// Note that this function was introduced in GStreamer 1.20 in order to provide
    /// a better name to `gst.Element.getRequestPad`. Prior to 1.20, users
    /// should use `gst.Element.getRequestPad` which provides the same
    /// functionality.
    extern fn gst_element_request_pad_simple(p_element: *Element, p_name: [*:0]const u8) ?*gst.Pad;
    pub const requestPadSimple = gst_element_request_pad_simple;

    /// Sends a seek event to an element. See `gst.Event.newSeek` for the details of
    /// the parameters. The seek event is sent to the element using
    /// `gst.Element.sendEvent`.
    ///
    /// MT safe.
    extern fn gst_element_seek(p_element: *Element, p_rate: f64, p_format: gst.Format, p_flags: gst.SeekFlags, p_start_type: gst.SeekType, p_start: i64, p_stop_type: gst.SeekType, p_stop: i64) c_int;
    pub const seek = gst_element_seek;

    /// Simple API to perform a seek on the given element, meaning it just seeks
    /// to the given position relative to the start of the stream. For more complex
    /// operations like segment seeks (e.g. for looping) or changing the playback
    /// rate or seeking relative to the last configured playback segment you should
    /// use `gst.Element.seek`.
    ///
    /// In a completely prerolled PAUSED or PLAYING pipeline, seeking is always
    /// guaranteed to return `TRUE` on a seekable media type or `FALSE` when the media
    /// type is certainly not seekable (such as a live stream).
    ///
    /// Some elements allow for seeking in the READY state, in this
    /// case they will store the seek event and execute it when they are put to
    /// PAUSED. If the element supports seek in READY, it will always return `TRUE` when
    /// it receives the event in the READY state.
    extern fn gst_element_seek_simple(p_element: *Element, p_format: gst.Format, p_seek_flags: gst.SeekFlags, p_seek_pos: i64) c_int;
    pub const seekSimple = gst_element_seek_simple;

    /// Sends an event to an element. If the element doesn't implement an
    /// event handler, the event will be pushed on a random linked sink pad for
    /// downstream events or a random linked source pad for upstream events.
    ///
    /// This function takes ownership of the provided event so you should
    /// `gst.Event.ref` it if you want to reuse the event after this call.
    ///
    /// MT safe.
    extern fn gst_element_send_event(p_element: *Element, p_event: *gst.Event) c_int;
    pub const sendEvent = gst_element_send_event;

    /// Set the base time of an element. See `gst.Element.getBaseTime`.
    ///
    /// MT safe.
    extern fn gst_element_set_base_time(p_element: *Element, p_time: gst.ClockTime) void;
    pub const setBaseTime = gst_element_set_base_time;

    /// Sets the bus of the element. Increases the refcount on the bus.
    /// For internal use only, unless you're testing elements.
    ///
    /// MT safe.
    extern fn gst_element_set_bus(p_element: *Element, p_bus: ?*gst.Bus) void;
    pub const setBus = gst_element_set_bus;

    /// Sets the clock for the element. This function increases the
    /// refcount on the clock. Any previously set clock on the object
    /// is unreffed.
    extern fn gst_element_set_clock(p_element: *Element, p_clock: ?*gst.Clock) c_int;
    pub const setClock = gst_element_set_clock;

    /// Sets the context of the element. Increases the refcount of the context.
    ///
    /// MT safe.
    extern fn gst_element_set_context(p_element: *Element, p_context: *gst.Context) void;
    pub const setContext = gst_element_set_context;

    /// Locks the state of an element, so state changes of the parent don't affect
    /// this element anymore.
    ///
    /// Note that this is racy if the state lock of the parent bin is not taken.
    /// The parent bin might've just checked the flag in another thread and as the
    /// next step proceed to change the child element's state.
    ///
    /// MT safe.
    extern fn gst_element_set_locked_state(p_element: *Element, p_locked_state: c_int) c_int;
    pub const setLockedState = gst_element_set_locked_state;

    /// Set the start time of an element. The start time of the element is the
    /// running time of the element when it last went to the PAUSED state. In READY
    /// or after a flushing seek, it is set to 0.
    ///
    /// Toplevel elements like `gst.Pipeline` will manage the start_time and
    /// base_time on its children. Setting the start_time to `GST_CLOCK_TIME_NONE`
    /// on such a toplevel element will disable the distribution of the base_time to
    /// the children and can be useful if the application manages the base_time
    /// itself, for example if you want to synchronize capture from multiple
    /// pipelines, and you can also ensure that the pipelines have the same clock.
    ///
    /// MT safe.
    extern fn gst_element_set_start_time(p_element: *Element, p_time: gst.ClockTime) void;
    pub const setStartTime = gst_element_set_start_time;

    /// Sets the state of the element. This function will try to set the
    /// requested state by going through all the intermediary states and calling
    /// the class's state change function for each.
    ///
    /// This function can return `GST_STATE_CHANGE_ASYNC`, in which case the
    /// element will perform the remainder of the state change asynchronously in
    /// another thread.
    /// An application can use `gst.Element.getState` to wait for the completion
    /// of the state change or it can wait for a `GST_MESSAGE_ASYNC_DONE` or
    /// `GST_MESSAGE_STATE_CHANGED` on the bus.
    ///
    /// State changes to `GST_STATE_READY` or `GST_STATE_NULL` never return
    /// `GST_STATE_CHANGE_ASYNC`.
    extern fn gst_element_set_state(p_element: *Element, p_state: gst.State) gst.StateChangeReturn;
    pub const setState = gst_element_set_state;

    /// Tries to change the state of the element to the same as its parent.
    /// If this function returns `FALSE`, the state of element is undefined.
    extern fn gst_element_sync_state_with_parent(p_element: *Element) c_int;
    pub const syncStateWithParent = gst_element_sync_state_with_parent;

    /// Unlinks all source pads of the source element with all sink pads
    /// of the sink element to which they are linked.
    ///
    /// If the link has been made using `gst.Element.link`, it could have created an
    /// requestpad, which has to be released using `gst.Element.releaseRequestPad`.
    extern fn gst_element_unlink(p_src: *Element, p_dest: *gst.Element) void;
    pub const unlink = gst_element_unlink;

    /// Unlinks a series of elements. Uses `gst.Element.unlink`.
    extern fn gst_element_unlink_many(p_element_1: *Element, p_element_2: *gst.Element, ...) void;
    pub const unlinkMany = gst_element_unlink_many;

    /// Unlinks the two named pads of the source and destination elements.
    ///
    /// This is a convenience function for `gst.Pad.unlink`.
    extern fn gst_element_unlink_pads(p_src: *Element, p_srcpadname: [*:0]const u8, p_dest: *gst.Element, p_destpadname: [*:0]const u8) void;
    pub const unlinkPads = gst_element_unlink_pads;

    extern fn gst_element_get_type() usize;
    pub const getGObjectType = gst_element_get_type;

    extern fn g_object_ref(p_self: *gst.Element) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Element) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Element, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.ElementFactory` is used to create instances of elements. A
/// GstElementFactory can be added to a `gst.Plugin` as it is also a
/// `gst.PluginFeature`.
///
/// Use the `gst.ElementFactory.find` and `gst.ElementFactory.create`
/// functions to create element instances or use `gst.ElementFactory.make` as a
/// convenient shortcut.
///
/// The following code example shows you how to create a GstFileSrc element.
///
/// ## Using an element factory
/// ```
///   `include` <gst/gst.h>
///
///   GstElement *src;
///   GstElementFactory *srcfactory;
///
///   gst_init (&argc, &argv);
///
///   srcfactory = gst_element_factory_find ("filesrc");
///   g_return_if_fail (srcfactory != NULL);
///   src = gst_element_factory_create (srcfactory, "src");
///   g_return_if_fail (src != NULL);
///   ...
/// ```
pub const ElementFactory = opaque {
    pub const Parent = gst.PluginFeature;
    pub const Implements = [_]type{};
    pub const Class = gst.ElementFactoryClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Search for an element factory of the given name. Refs the returned
    /// element factory; caller is responsible for unreffing.
    extern fn gst_element_factory_find(p_name: [*:0]const u8) ?*gst.ElementFactory;
    pub const find = gst_element_factory_find;

    /// Filter out all the elementfactories in `list` that can handle `caps` in
    /// the given direction.
    ///
    /// If `subsetonly` is `TRUE`, then only the elements whose pads templates
    /// are a complete superset of `caps` will be returned. Else any element
    /// whose pad templates caps can intersect with `caps` will be returned.
    extern fn gst_element_factory_list_filter(p_list: *glib.List, p_caps: *const gst.Caps, p_direction: gst.PadDirection, p_subsetonly: c_int) *glib.List;
    pub const listFilter = gst_element_factory_list_filter;

    /// Get a list of factories that match the given `type`. Only elements
    /// with a rank greater or equal to `minrank` will be returned.
    /// The list of factories is returned by decreasing rank.
    extern fn gst_element_factory_list_get_elements(p_type: gst.ElementFactoryListType, p_minrank: gst.Rank) *glib.List;
    pub const listGetElements = gst_element_factory_list_get_elements;

    /// Create a new element of the type defined by the given element factory.
    /// If name is `NULL`, then the element will receive a guaranteed unique name,
    /// consisting of the element factory name and a number.
    /// If name is given, it will be given the name supplied.
    extern fn gst_element_factory_make(p_factoryname: [*:0]const u8, p_name: ?[*:0]const u8) ?*gst.Element;
    pub const make = gst_element_factory_make;

    /// Create a new element of the type defined by the given element factory.
    /// The supplied list of properties, will be passed at object construction.
    extern fn gst_element_factory_make_full(p_factoryname: [*:0]const u8, p_first: ?[*:0]const u8, ...) ?*gst.Element;
    pub const makeFull = gst_element_factory_make_full;

    /// Create a new element of the type defined by the given element factory.
    /// The supplied list of properties, will be passed at object construction.
    extern fn gst_element_factory_make_valist(p_factoryname: [*:0]const u8, p_first: ?[*:0]const u8, p_properties: std.builtin.VaList) ?*gst.Element;
    pub const makeValist = gst_element_factory_make_valist;

    /// Create a new element of the type defined by the given elementfactory.
    /// The supplied list of properties, will be passed at object construction.
    extern fn gst_element_factory_make_with_properties(p_factoryname: [*:0]const u8, p_n: c_uint, p_names: ?[*][*:0]const u8, p_values: ?[*]const gobject.Value) ?*gst.Element;
    pub const makeWithProperties = gst_element_factory_make_with_properties;

    /// Checks if the factory can sink all possible capabilities.
    extern fn gst_element_factory_can_sink_all_caps(p_factory: *ElementFactory, p_caps: *const gst.Caps) c_int;
    pub const canSinkAllCaps = gst_element_factory_can_sink_all_caps;

    /// Checks if the factory can sink any possible capability.
    extern fn gst_element_factory_can_sink_any_caps(p_factory: *ElementFactory, p_caps: *const gst.Caps) c_int;
    pub const canSinkAnyCaps = gst_element_factory_can_sink_any_caps;

    /// Checks if the factory can src all possible capabilities.
    extern fn gst_element_factory_can_src_all_caps(p_factory: *ElementFactory, p_caps: *const gst.Caps) c_int;
    pub const canSrcAllCaps = gst_element_factory_can_src_all_caps;

    /// Checks if the factory can src any possible capability.
    extern fn gst_element_factory_can_src_any_caps(p_factory: *ElementFactory, p_caps: *const gst.Caps) c_int;
    pub const canSrcAnyCaps = gst_element_factory_can_src_any_caps;

    /// Create a new element of the type defined by the given elementfactory.
    /// It will be given the name supplied, since all elements require a name as
    /// their first argument.
    extern fn gst_element_factory_create(p_factory: *ElementFactory, p_name: ?[*:0]const u8) ?*gst.Element;
    pub const create = gst_element_factory_create;

    /// Create a new element of the type defined by the given elementfactory.
    /// The supplied list of properties, will be passed at object construction.
    extern fn gst_element_factory_create_full(p_factory: *ElementFactory, p_first: ?[*:0]const u8, ...) ?*gst.Element;
    pub const createFull = gst_element_factory_create_full;

    /// Create a new element of the type defined by the given elementfactory.
    /// The supplied list of properties, will be passed at object construction.
    extern fn gst_element_factory_create_valist(p_factory: *ElementFactory, p_first: ?[*:0]const u8, p_properties: std.builtin.VaList) ?*gst.Element;
    pub const createValist = gst_element_factory_create_valist;

    /// Create a new element of the type defined by the given elementfactory.
    /// The supplied list of properties, will be passed at object construction.
    extern fn gst_element_factory_create_with_properties(p_factory: *ElementFactory, p_n: c_uint, p_names: ?[*][*:0]const u8, p_values: ?[*]const gobject.Value) ?*gst.Element;
    pub const createWithProperties = gst_element_factory_create_with_properties;

    /// Get the `gobject.Type` for elements managed by this factory. The type can
    /// only be retrieved if the element factory is loaded, which can be
    /// assured with `gst.PluginFeature.load`.
    extern fn gst_element_factory_get_element_type(p_factory: *ElementFactory) usize;
    pub const getElementType = gst_element_factory_get_element_type;

    /// Get the metadata on `factory` with `key`.
    extern fn gst_element_factory_get_metadata(p_factory: *ElementFactory, p_key: [*:0]const u8) ?[*:0]const u8;
    pub const getMetadata = gst_element_factory_get_metadata;

    /// Get the available keys for the metadata on `factory`.
    extern fn gst_element_factory_get_metadata_keys(p_factory: *ElementFactory) ?[*][*:0]u8;
    pub const getMetadataKeys = gst_element_factory_get_metadata_keys;

    /// Gets the number of pad_templates in this factory.
    extern fn gst_element_factory_get_num_pad_templates(p_factory: *ElementFactory) c_uint;
    pub const getNumPadTemplates = gst_element_factory_get_num_pad_templates;

    /// Queries whether registered element managed by `factory` needs to
    /// be excluded from documentation system or not.
    extern fn gst_element_factory_get_skip_documentation(p_factory: *ElementFactory) c_int;
    pub const getSkipDocumentation = gst_element_factory_get_skip_documentation;

    /// Gets the `glib.List` of `gst.StaticPadTemplate` for this factory.
    extern fn gst_element_factory_get_static_pad_templates(p_factory: *ElementFactory) *const glib.List;
    pub const getStaticPadTemplates = gst_element_factory_get_static_pad_templates;

    /// Gets a `NULL`-terminated array of protocols this element supports or `NULL` if
    /// no protocols are supported. You may not change the contents of the returned
    /// array, as it is still owned by the element factory. Use `glib.strdupv` to
    /// make a copy of the protocol string array if you need to.
    extern fn gst_element_factory_get_uri_protocols(p_factory: *ElementFactory) [*]const [*:0]const u8;
    pub const getUriProtocols = gst_element_factory_get_uri_protocols;

    /// Gets the type of URIs the element supports or `GST_URI_UNKNOWN` if none.
    extern fn gst_element_factory_get_uri_type(p_factory: *ElementFactory) gst.URIType;
    pub const getUriType = gst_element_factory_get_uri_type;

    /// Check if `factory` implements the interface with name `interfacename`.
    extern fn gst_element_factory_has_interface(p_factory: *ElementFactory, p_interfacename: [*:0]const u8) c_int;
    pub const hasInterface = gst_element_factory_has_interface;

    /// Check if `factory` is of the given types.
    extern fn gst_element_factory_list_is_type(p_factory: *ElementFactory, p_type: gst.ElementFactoryListType) c_int;
    pub const listIsType = gst_element_factory_list_is_type;

    extern fn gst_element_factory_get_type() usize;
    pub const getGObjectType = gst_element_factory_get_type;

    extern fn g_object_ref(p_self: *gst.ElementFactory) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.ElementFactory) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *ElementFactory, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a 32-bit flag bitfield, with 32-bit
/// mask indicating which of the bits in the field are explicitly set.
pub const FlagSet = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = FlagSet;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Create a new sub-class of `GST_TYPE_FLAG_SET`
    /// which will pretty-print the human-readable flags
    /// when serializing, for easier debugging.
    extern fn gst_flagset_register(p_flags_type: usize) usize;
    pub const register = gst_flagset_register;

    extern fn gst_flagset_get_type() usize;
    pub const getGObjectType = gst_flagset_get_type;

    pub fn as(p_instance: *FlagSet, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a fraction of an integer numerator
/// over an integer denominator
pub const Fraction = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = Fraction;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_fraction_get_type() usize;
    pub const getGObjectType = gst_fraction_get_type;

    pub fn as(p_instance: *Fraction, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a `GstFractionRange` range
pub const FractionRange = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = FractionRange;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_fraction_range_get_type() usize;
    pub const getGObjectType = gst_fraction_range_get_type;

    pub fn as(p_instance: *FractionRange, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GhostPads are useful when organizing pipelines with `gst.Bin` like elements.
/// The idea here is to create hierarchical element graphs. The bin element
/// contains a sub-graph. Now one would like to treat the bin-element like any
/// other `gst.Element`. This is where GhostPads come into play. A GhostPad acts as
/// a proxy for another pad. Thus the bin can have sink and source ghost-pads
/// that are associated with sink and source pads of the child elements.
///
/// If the target pad is known at creation time, `gst.GhostPad.new` is the
/// function to use to get a ghost-pad. Otherwise one can use `gst.GhostPad.newNoTarget`
/// to create the ghost-pad and use `gst.GhostPad.setTarget` to establish the
/// association later on.
///
/// Note that GhostPads add overhead to the data processing of a pipeline.
pub const GhostPad = extern struct {
    pub const Parent = gst.ProxyPad;
    pub const Implements = [_]type{};
    pub const Class = gst.GhostPadClass;
    f_pad: gst.ProxyPad,
    f_priv: ?*gst.GhostPadPrivate,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Invoke the default activate mode function of a ghost pad.
    extern fn gst_ghost_pad_activate_mode_default(p_pad: *gst.Pad, p_parent: ?*gst.Object, p_mode: gst.PadMode, p_active: c_int) c_int;
    pub const activateModeDefault = gst_ghost_pad_activate_mode_default;

    /// Invoke the default activate mode function of a proxy pad that is
    /// owned by a ghost pad.
    extern fn gst_ghost_pad_internal_activate_mode_default(p_pad: *gst.Pad, p_parent: ?*gst.Object, p_mode: gst.PadMode, p_active: c_int) c_int;
    pub const internalActivateModeDefault = gst_ghost_pad_internal_activate_mode_default;

    /// Create a new ghostpad with `target` as the target. The direction will be taken
    /// from the target pad. `target` must be unlinked.
    ///
    /// Will ref the target.
    extern fn gst_ghost_pad_new(p_name: ?[*:0]const u8, p_target: *gst.Pad) ?*gst.GhostPad;
    pub const new = gst_ghost_pad_new;

    /// Create a new ghostpad with `target` as the target. The direction will be taken
    /// from the target pad. The template used on the ghostpad will be `template`.
    ///
    /// Will ref the target.
    extern fn gst_ghost_pad_new_from_template(p_name: ?[*:0]const u8, p_target: *gst.Pad, p_templ: *gst.PadTemplate) ?*gst.GhostPad;
    pub const newFromTemplate = gst_ghost_pad_new_from_template;

    /// Create a new ghostpad without a target with the given direction.
    /// A target can be set on the ghostpad later with the
    /// `gst.GhostPad.setTarget` function.
    ///
    /// The created ghostpad will not have a padtemplate.
    extern fn gst_ghost_pad_new_no_target(p_name: ?[*:0]const u8, p_dir: gst.PadDirection) ?*gst.GhostPad;
    pub const newNoTarget = gst_ghost_pad_new_no_target;

    /// Create a new ghostpad based on `templ`, without setting a target. The
    /// direction will be taken from the `templ`.
    extern fn gst_ghost_pad_new_no_target_from_template(p_name: ?[*:0]const u8, p_templ: *gst.PadTemplate) ?*gst.GhostPad;
    pub const newNoTargetFromTemplate = gst_ghost_pad_new_no_target_from_template;

    /// Finish initialization of a newly allocated ghost pad.
    ///
    /// This function is most useful in language bindings and when subclassing
    /// `gst.GhostPad`; plugin and application developers normally will not call this
    /// function. Call this function directly after a call to g_object_new
    /// (GST_TYPE_GHOST_PAD, "direction", `dir`, ..., NULL).
    extern fn gst_ghost_pad_construct(p_gpad: *GhostPad) c_int;
    pub const construct = gst_ghost_pad_construct;

    /// Get the target pad of `gpad`. Unref target pad after usage.
    extern fn gst_ghost_pad_get_target(p_gpad: *GhostPad) ?*gst.Pad;
    pub const getTarget = gst_ghost_pad_get_target;

    /// Set the new target of the ghostpad `gpad`. Any existing target
    /// is unlinked and links to the new target are established. if `newtarget` is
    /// `NULL` the target will be cleared.
    extern fn gst_ghost_pad_set_target(p_gpad: *GhostPad, p_newtarget: ?*gst.Pad) c_int;
    pub const setTarget = gst_ghost_pad_set_target;

    extern fn gst_ghost_pad_get_type() usize;
    pub const getGObjectType = gst_ghost_pad_get_type;

    extern fn g_object_ref(p_self: *gst.GhostPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.GhostPad) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *GhostPad, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a `gint64` range
pub const Int64Range = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = Int64Range;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_int64_range_get_type() usize;
    pub const getGObjectType = gst_int64_range_get_type;

    pub fn as(p_instance: *Int64Range, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a `gint` range
pub const IntRange = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = IntRange;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_int_range_get_type() usize;
    pub const getGObjectType = gst_int_range_get_type;

    pub fn as(p_instance: *IntRange, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.Object` provides a root for the object hierarchy tree filed in by the
/// GStreamer library.  It is currently a thin wrapper on top of
/// `gobject.InitiallyUnowned`. It is an abstract class that is not very usable on its own.
///
/// `gst.Object` gives us basic refcounting, parenting functionality and locking.
/// Most of the functions are just extended for special GStreamer needs and can be
/// found under the same name in the base class of `gst.Object` which is `gobject.Object`
/// (e.g. `gobject.Object.ref` becomes `gst.Object.ref`).
///
/// Since `gst.Object` derives from `gobject.InitiallyUnowned`, it also inherits the
/// floating reference. Be aware that functions such as `gst.Bin.add` and
/// `gst.Element.addPad` take ownership of the floating reference.
///
/// In contrast to `gobject.Object` instances, `gst.Object` adds a name property. The functions
/// `gst.Object.setName` and `gst.Object.getName` are used to set/get the name
/// of the object.
///
/// ## controlled properties
///
/// Controlled properties offers a lightweight way to adjust gobject properties
/// over stream-time. It works by using time-stamped value pairs that are queued
/// for element-properties. At run-time the elements continuously pull value
/// changes for the current stream-time.
///
/// What needs to be changed in a `gst.Element`?
/// Very little - it is just two steps to make a plugin controllable!
///
///   * mark gobject-properties paramspecs that make sense to be controlled,
///     by GST_PARAM_CONTROLLABLE.
///
///   * when processing data (get, chain, loop function) at the beginning call
///     gst_object_sync_values(element,timestamp).
///     This will make the controller update all GObject properties that are
///     under its control with the current values based on the timestamp.
///
/// What needs to be done in applications? Again it's not a lot to change.
///
///   * create a `gst.ControlSource`.
///     csource = gst_interpolation_control_source_new ();
///     g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
///
///   * Attach the `gst.ControlSource` on the controller to a property.
///     gst_object_add_control_binding (object, gst_direct_control_binding_new (object, "prop1", csource));
///
///   * Set the control values
///     gst_timed_value_control_source_set ((GstTimedValueControlSource *)csource,0 * GST_SECOND, value1);
///     gst_timed_value_control_source_set ((GstTimedValueControlSource *)csource,1 * GST_SECOND, value2);
///
///   * start your pipeline
pub const Object = extern struct {
    pub const Parent = gobject.InitiallyUnowned;
    pub const Implements = [_]type{};
    pub const Class = gst.ObjectClass;
    f_object: gobject.InitiallyUnowned,
    /// object LOCK
    f_lock: glib.Mutex,
    /// The name of the object
    f_name: ?[*:0]u8,
    /// this object's parent, weak ref
    f_parent: ?*gst.Object,
    /// flags for this object
    f_flags: u32,
    f_control_bindings: ?*glib.List,
    f_control_rate: u64,
    f_last_sync: u64,
    f__gst_reserved: ?*anyopaque,

    pub const virtual_methods = struct {
        /// default signal handler
        pub const deep_notify = struct {
            pub fn call(p_class: anytype, p_object: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_orig: *gst.Object, p_pspec: *gobject.ParamSpec) void {
                return gobject.ext.as(Object.Class, p_class).f_deep_notify.?(gobject.ext.as(Object, p_object), p_orig, p_pspec);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_object: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_orig: *gst.Object, p_pspec: *gobject.ParamSpec) callconv(.c) void) void {
                gobject.ext.as(Object.Class, p_class).f_deep_notify = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const name = struct {
            pub const name = "name";

            pub const Type = ?[*:0]u8;
        };

        /// The parent of the object. Please note, that when changing the 'parent'
        /// property, we don't emit `gobject.Object.signals.notify` and `gst.Object.signals.deep`-notify
        /// signals due to locking issues. In some cases one can use
        /// `gst.Bin.signals.element`-added or `gst.Bin.signals.element`-removed signals on the parent to
        /// achieve a similar effect.
        pub const parent = struct {
            pub const name = "parent";

            pub const Type = ?*gst.Object;
        };
    };

    pub const signals = struct {
        /// The deep notify signal is used to be notified of property changes. It is
        /// typically attached to the toplevel bin to receive notifications from all
        /// the elements contained in that bin.
        pub const deep_notify = struct {
            pub const name = "deep-notify";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_prop_object: *gst.Object, p_prop: *gobject.ParamSpec, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Object, p_instance))),
                    gobject.signalLookup("deep-notify", Object.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Checks to see if there is any object named `name` in `list`. This function
    /// does not do any locking of any kind. You might want to protect the
    /// provided list with the lock of the owner of the list. This function
    /// will lock each `gst.Object` in the list to compare the name, so be
    /// careful when passing a list with a locked object.
    extern fn gst_object_check_uniqueness(p_list: *glib.List, p_name: [*:0]const u8) c_int;
    pub const checkUniqueness = gst_object_check_uniqueness;

    /// A default deep_notify signal callback for an object. The user data
    /// should contain a pointer to an array of strings that should be excluded
    /// from the notify. The default handler will print the new value of the property
    /// using g_print.
    ///
    /// MT safe. This function grabs and releases `object`'s LOCK for getting its
    ///          path string.
    extern fn gst_object_default_deep_notify(p_object: *gobject.Object, p_orig: *gst.Object, p_pspec: *gobject.ParamSpec, p_excluded_props: ?[*][*:0]u8) void;
    pub const defaultDeepNotify = gst_object_default_deep_notify;

    /// Increase the reference count of `object`, and possibly remove the floating
    /// reference, if `object` has a floating reference.
    ///
    /// In other words, if the object is floating, then this call "assumes ownership"
    /// of the floating reference, converting it to a normal reference by clearing
    /// the floating flag while leaving the reference count unchanged. If the object
    /// is not floating, then this call adds a new normal reference increasing the
    /// reference count by one.
    ///
    /// For more background on "floating references" please see the `gobject.Object`
    /// documentation.
    extern fn gst_object_ref_sink(p_object: ?*anyopaque) ?*anyopaque;
    pub const refSink = gst_object_ref_sink;

    /// Atomically modifies a pointer to point to a new object.
    /// The reference count of `oldobj` is decreased and the reference count of
    /// `newobj` is increased.
    ///
    /// Either `newobj` and the value pointed to by `oldobj` may be `NULL`.
    extern fn gst_object_replace(p_oldobj: ?**gst.Object, p_newobj: ?*gst.Object) c_int;
    pub const replace = gst_object_replace;

    /// Attach the `gst.ControlBinding` to the object. If there already was a
    /// `gst.ControlBinding` for this property it will be replaced.
    ///
    /// The object's reference count will be incremented, and any floating
    /// reference will be removed (see `gst.Object.refSink`)
    extern fn gst_object_add_control_binding(p_object: *Object, p_binding: *gst.ControlBinding) c_int;
    pub const addControlBinding = gst_object_add_control_binding;

    /// A default error function that uses `glib.printerr` to display the error message
    /// and the optional debug string..
    ///
    /// The default handler will simply print the error string using g_print.
    extern fn gst_object_default_error(p_source: *Object, p_error: *const glib.Error, p_debug: ?[*:0]const u8) void;
    pub const defaultError = gst_object_default_error;

    /// Gets the corresponding `gst.ControlBinding` for the property. This should be
    /// unreferenced again after use.
    extern fn gst_object_get_control_binding(p_object: *Object, p_property_name: [*:0]const u8) ?*gst.ControlBinding;
    pub const getControlBinding = gst_object_get_control_binding;

    /// Obtain the control-rate for this `object`. Audio processing `gst.Element`
    /// objects will use this rate to sub-divide their processing loop and call
    /// `gst.Object.syncValues` in between. The length of the processing segment
    /// should be up to `control`-rate nanoseconds.
    ///
    /// If the `object` is not under property control, this will return
    /// `GST_CLOCK_TIME_NONE`. This allows the element to avoid the sub-dividing.
    ///
    /// The control-rate is not expected to change if the element is in
    /// `GST_STATE_PAUSED` or `GST_STATE_PLAYING`.
    extern fn gst_object_get_control_rate(p_object: *Object) gst.ClockTime;
    pub const getControlRate = gst_object_get_control_rate;

    /// Gets a number of `GValues` for the given controlled property starting at the
    /// requested time. The array `values` need to hold enough space for `n_values` of
    /// `gobject.Value`.
    ///
    /// This function is useful if one wants to e.g. draw a graph of the control
    /// curve or apply a control curve sample by sample.
    extern fn gst_object_get_g_value_array(p_object: *Object, p_property_name: [*:0]const u8, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]gobject.Value) c_int;
    pub const getGValueArray = gst_object_get_g_value_array;

    /// Returns a copy of the name of `object`.
    /// Caller should `glib.free` the return value after usage.
    /// For a nameless object, this returns `NULL`, which you can safely `glib.free`
    /// as well.
    ///
    /// Free-function: g_free
    extern fn gst_object_get_name(p_object: *Object) ?[*:0]u8;
    pub const getName = gst_object_get_name;

    /// Returns the parent of `object`. This function increases the refcount
    /// of the parent object so you should `gst.Object.unref` it after usage.
    extern fn gst_object_get_parent(p_object: *Object) ?*gst.Object;
    pub const getParent = gst_object_get_parent;

    /// Generates a string describing the path of `object` in
    /// the object hierarchy. Only useful (or used) for debugging.
    ///
    /// Free-function: g_free
    extern fn gst_object_get_path_string(p_object: *Object) [*:0]u8;
    pub const getPathString = gst_object_get_path_string;

    /// Gets the value for the given controlled property at the requested time.
    extern fn gst_object_get_value(p_object: *Object, p_property_name: [*:0]const u8, p_timestamp: gst.ClockTime) ?*gobject.Value;
    pub const getValue = gst_object_get_value;

    /// Gets a number of values for the given controlled property starting at the
    /// requested time. The array `values` need to hold enough space for `n_values` of
    /// the same type as the objects property's type.
    ///
    /// This function is useful if one wants to e.g. draw a graph of the control
    /// curve or apply a control curve sample by sample.
    ///
    /// The values are unboxed and ready to be used. The similar function
    /// `gst.Object.getGValueArray` returns the array as `GValues` and is
    /// better suites for bindings.
    extern fn gst_object_get_value_array(p_object: *Object, p_property_name: [*:0]const u8, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]*anyopaque) c_int;
    pub const getValueArray = gst_object_get_value_array;

    /// Check if the `object` has active controlled properties.
    extern fn gst_object_has_active_control_bindings(p_object: *Object) c_int;
    pub const hasActiveControlBindings = gst_object_has_active_control_bindings;

    /// Check if `object` has an ancestor `ancestor` somewhere up in
    /// the hierarchy. One can e.g. check if a `gst.Element` is inside a `gst.Pipeline`.
    extern fn gst_object_has_ancestor(p_object: *Object, p_ancestor: *gst.Object) c_int;
    pub const hasAncestor = gst_object_has_ancestor;

    /// Check if `object` has an ancestor `ancestor` somewhere up in
    /// the hierarchy. One can e.g. check if a `gst.Element` is inside a `gst.Pipeline`.
    extern fn gst_object_has_as_ancestor(p_object: *Object, p_ancestor: *gst.Object) c_int;
    pub const hasAsAncestor = gst_object_has_as_ancestor;

    /// Check if `parent` is the parent of `object`.
    /// E.g. a `gst.Element` can check if it owns a given `gst.Pad`.
    extern fn gst_object_has_as_parent(p_object: *Object, p_parent: *gst.Object) c_int;
    pub const hasAsParent = gst_object_has_as_parent;

    /// Increments the reference count on `object`. This function
    /// does not take the lock on `object` because it relies on
    /// atomic refcounting.
    ///
    /// This object returns the input parameter to ease writing
    /// constructs like :
    ///  result = gst_object_ref (object->parent);
    extern fn gst_object_ref(p_object: *Object) *gst.Object;
    pub const ref = gst_object_ref;

    /// Removes the corresponding `gst.ControlBinding`. If it was the
    /// last ref of the binding, it will be disposed.
    extern fn gst_object_remove_control_binding(p_object: *Object, p_binding: *gst.ControlBinding) c_int;
    pub const removeControlBinding = gst_object_remove_control_binding;

    /// This function is used to disable the control bindings on a property for
    /// some time, i.e. `gst.Object.syncValues` will do nothing for the
    /// property.
    extern fn gst_object_set_control_binding_disabled(p_object: *Object, p_property_name: [*:0]const u8, p_disabled: c_int) void;
    pub const setControlBindingDisabled = gst_object_set_control_binding_disabled;

    /// This function is used to disable all controlled properties of the `object` for
    /// some time, i.e. `gst.Object.syncValues` will do nothing.
    extern fn gst_object_set_control_bindings_disabled(p_object: *Object, p_disabled: c_int) void;
    pub const setControlBindingsDisabled = gst_object_set_control_bindings_disabled;

    /// Change the control-rate for this `object`. Audio processing `gst.Element`
    /// objects will use this rate to sub-divide their processing loop and call
    /// `gst.Object.syncValues` in between. The length of the processing segment
    /// should be up to `control`-rate nanoseconds.
    ///
    /// The control-rate should not change if the element is in `GST_STATE_PAUSED` or
    /// `GST_STATE_PLAYING`.
    extern fn gst_object_set_control_rate(p_object: *Object, p_control_rate: gst.ClockTime) void;
    pub const setControlRate = gst_object_set_control_rate;

    /// Sets the name of `object`, or gives `object` a guaranteed unique
    /// name (if `name` is `NULL`).
    /// This function makes a copy of the provided name, so the caller
    /// retains ownership of the name it sent.
    extern fn gst_object_set_name(p_object: *Object, p_name: ?[*:0]const u8) c_int;
    pub const setName = gst_object_set_name;

    /// Sets the parent of `object` to `parent`. The object's reference count will
    /// be incremented, and any floating reference will be removed (see `gst.Object.refSink`).
    extern fn gst_object_set_parent(p_object: *Object, p_parent: *gst.Object) c_int;
    pub const setParent = gst_object_set_parent;

    /// Returns a suggestion for timestamps where buffers should be split
    /// to get best controller results.
    extern fn gst_object_suggest_next_sync(p_object: *Object) gst.ClockTime;
    pub const suggestNextSync = gst_object_suggest_next_sync;

    /// Sets the properties of the object, according to the `GstControlSources` that
    /// (maybe) handle them and for the given timestamp.
    ///
    /// If this function fails, it is most likely the application developers fault.
    /// Most probably the control sources are not setup correctly.
    extern fn gst_object_sync_values(p_object: *Object, p_timestamp: gst.ClockTime) c_int;
    pub const syncValues = gst_object_sync_values;

    /// Clear the parent of `object`, removing the associated reference.
    /// This function decreases the refcount of `object`.
    ///
    /// MT safe. Grabs and releases `object`'s lock.
    extern fn gst_object_unparent(p_object: *Object) void;
    pub const unparent = gst_object_unparent;

    /// Decrements the reference count on `object`.  If reference count hits
    /// zero, destroy `object`. This function does not take the lock
    /// on `object` as it relies on atomic refcounting.
    ///
    /// The unref method should never be called with the LOCK held since
    /// this might deadlock the dispose function.
    extern fn gst_object_unref(p_object: *Object) void;
    pub const unref = gst_object_unref;

    extern fn gst_object_get_type() usize;
    pub const getGObjectType = gst_object_get_type;

    pub fn as(p_instance: *Object, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.Element` is linked to other elements via "pads", which are extremely
/// light-weight generic link points.
///
/// Pads have a `gst.PadDirection`, source pads produce data, sink pads consume
/// data.
///
/// Pads are typically created from a `gst.PadTemplate` with
/// `gst.Pad.newFromTemplate` and are then added to a `gst.Element`. This usually
/// happens when the element is created but it can also happen dynamically based
/// on the data that the element is processing or based on the pads that the
/// application requests.
///
/// Pads without pad templates can be created with `gst.Pad.new`,
/// which takes a direction and a name as an argument.  If the name is `NULL`,
/// then a guaranteed unique name will be assigned to it.
///
/// A `gst.Element` creating a pad will typically use the various
/// gst_pad_set_*_function\() calls to register callbacks for events, queries or
/// dataflow on the pads.
///
/// `gst_pad_get_parent` will retrieve the `gst.Element` that owns the pad.
///
/// After two pads are retrieved from an element by `gst.Element.getStaticPad`,
/// the pads can be linked with `gst.Pad.link`. (For quick links,
/// you can also use `gst.Element.link`, which will make the obvious
/// link for you if it's straightforward.). Pads can be unlinked again with
/// `gst.Pad.unlink`. `gst.Pad.getPeer` can be used to check what the pad is
/// linked to.
///
/// Before dataflow is possible on the pads, they need to be activated with
/// `gst.Pad.setActive`.
///
/// `gst.Pad.query` and `gst.Pad.peerQuery` can be used to query various
/// properties of the pad and the stream.
///
/// To send a `gst.Event` on a pad, use `gst.Pad.sendEvent` and
/// `gst.Pad.pushEvent`. Some events will be sticky on the pad, meaning that
/// after they pass on the pad they can be queried later with
/// `gst.Pad.getStickyEvent` and `gst.Pad.stickyEventsForeach`.
/// `gst.Pad.getCurrentCaps` and `gst.Pad.hasCurrentCaps` are convenience
/// functions to query the current sticky CAPS event on a pad.
///
/// GstElements will use `gst.Pad.push` and `gst.Pad.pullRange` to push out
/// or pull in a buffer.
///
/// The dataflow, events and queries that happen on a pad can be monitored with
/// probes that can be installed with `gst.Pad.addProbe`. `gst.Pad.isBlocked`
/// can be used to check if a block probe is installed on the pad.
/// `gst.Pad.isBlocking` checks if the blocking probe is currently blocking the
/// pad. `gst.Pad.removeProbe` is used to remove a previously installed probe
/// and unblock blocking probes if any.
///
/// Pad have an offset that can be retrieved with `gst.Pad.getOffset`. This
/// offset will be applied to the running_time of all data passing over the pad.
/// `gst.Pad.setOffset` can be used to change the offset.
///
/// Convenience functions exist to start, pause and stop the task on a pad with
/// `gst.Pad.startTask`, `gst.Pad.pauseTask` and `gst.Pad.stopTask`
/// respectively.
pub const Pad = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.PadClass;
    f_object: gst.Object,
    /// private data owned by the parent element
    f_element_private: ?*anyopaque,
    /// padtemplate for this pad
    f_padtemplate: ?*gst.PadTemplate,
    /// the direction of the pad, cannot change after creating
    ///             the pad.
    f_direction: gst.PadDirection,
    f_stream_rec_lock: glib.RecMutex,
    f_task: ?*gst.Task,
    f_block_cond: glib.Cond,
    f_probes: glib.HookList,
    f_mode: gst.PadMode,
    f_activatefunc: ?gst.PadActivateFunction,
    f_activatedata: ?*anyopaque,
    f_activatenotify: ?glib.DestroyNotify,
    f_activatemodefunc: ?gst.PadActivateModeFunction,
    f_activatemodedata: ?*anyopaque,
    f_activatemodenotify: ?glib.DestroyNotify,
    f_peer: ?*gst.Pad,
    f_linkfunc: ?gst.PadLinkFunction,
    f_linkdata: ?*anyopaque,
    f_linknotify: ?glib.DestroyNotify,
    f_unlinkfunc: ?gst.PadUnlinkFunction,
    f_unlinkdata: ?*anyopaque,
    f_unlinknotify: ?glib.DestroyNotify,
    f_chainfunc: ?gst.PadChainFunction,
    f_chaindata: ?*anyopaque,
    f_chainnotify: ?glib.DestroyNotify,
    f_chainlistfunc: ?gst.PadChainListFunction,
    f_chainlistdata: ?*anyopaque,
    f_chainlistnotify: ?glib.DestroyNotify,
    f_getrangefunc: ?gst.PadGetRangeFunction,
    f_getrangedata: ?*anyopaque,
    f_getrangenotify: ?glib.DestroyNotify,
    f_eventfunc: ?gst.PadEventFunction,
    f_eventdata: ?*anyopaque,
    f_eventnotify: ?glib.DestroyNotify,
    f_offset: i64,
    f_queryfunc: ?gst.PadQueryFunction,
    f_querydata: ?*anyopaque,
    f_querynotify: ?glib.DestroyNotify,
    f_iterintlinkfunc: ?gst.PadIterIntLinkFunction,
    f_iterintlinkdata: ?*anyopaque,
    f_iterintlinknotify: ?glib.DestroyNotify,
    f_num_probes: c_int,
    f_num_blocked: c_int,
    f_priv: ?*gst.PadPrivate,
    anon0: extern union {
        f__gst_reserved: [4]*anyopaque,
        anon0: extern struct {
            f_last_flowret: gst.FlowReturn,
            f_eventfullfunc: ?gst.PadEventFullFunction,
        },
    },

    pub const virtual_methods = struct {
        pub const linked = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_peer: *gst.Pad) void {
                return gobject.ext.as(Pad.Class, p_class).f_linked.?(gobject.ext.as(Pad, p_pad), p_peer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_peer: *gst.Pad) callconv(.c) void) void {
                gobject.ext.as(Pad.Class, p_class).f_linked = @ptrCast(p_implementation);
            }
        };

        pub const unlinked = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_peer: *gst.Pad) void {
                return gobject.ext.as(Pad.Class, p_class).f_unlinked.?(gobject.ext.as(Pad, p_pad), p_peer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_peer: *gst.Pad) callconv(.c) void) void {
                gobject.ext.as(Pad.Class, p_class).f_unlinked = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const caps = struct {
            pub const name = "caps";

            pub const Type = ?*gst.Caps;
        };

        pub const direction = struct {
            pub const name = "direction";

            pub const Type = gst.PadDirection;
        };

        /// The offset that will be applied to the running time of the pad.
        pub const offset = struct {
            pub const name = "offset";

            pub const Type = i64;
        };

        pub const template = struct {
            pub const name = "template";

            pub const Type = ?*gst.PadTemplate;
        };
    };

    pub const signals = struct {
        /// Signals that a pad has been linked to the peer pad.
        pub const linked = struct {
            pub const name = "linked";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_peer: *gst.Pad, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Pad, p_instance))),
                    gobject.signalLookup("linked", Pad.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Signals that a pad has been unlinked from the peer pad.
        pub const unlinked = struct {
            pub const name = "unlinked";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_peer: *gst.Pad, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Pad, p_instance))),
                    gobject.signalLookup("unlinked", Pad.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Gets a string representing the given pad-link return.
    extern fn gst_pad_link_get_name(p_ret: gst.PadLinkReturn) [*:0]const u8;
    pub const linkGetName = gst_pad_link_get_name;

    /// Creates a new pad with the given name in the given direction.
    /// If name is `NULL`, a guaranteed unique name (across all pads)
    /// will be assigned.
    /// This function makes a copy of the name so you can safely free the name.
    extern fn gst_pad_new(p_name: ?[*:0]const u8, p_direction: gst.PadDirection) *gst.Pad;
    pub const new = gst_pad_new;

    /// Creates a new pad with the given name from the given static template.
    /// If name is `NULL`, a guaranteed unique name (across all pads)
    /// will be assigned.
    /// This function makes a copy of the name so you can safely free the name.
    extern fn gst_pad_new_from_static_template(p_templ: *gst.StaticPadTemplate, p_name: [*:0]const u8) *gst.Pad;
    pub const newFromStaticTemplate = gst_pad_new_from_static_template;

    /// Creates a new pad with the given name from the given template.
    /// If name is `NULL`, a guaranteed unique name (across all pads)
    /// will be assigned.
    /// This function makes a copy of the name so you can safely free the name.
    extern fn gst_pad_new_from_template(p_templ: *gst.PadTemplate, p_name: ?[*:0]const u8) *gst.Pad;
    pub const newFromTemplate = gst_pad_new_from_template;

    /// Activates or deactivates the given pad in `mode` via dispatching to the
    /// pad's activatemodefunc. For use from within pad activation functions only.
    ///
    /// If you don't know what this is, you probably don't want to call it.
    extern fn gst_pad_activate_mode(p_pad: *Pad, p_mode: gst.PadMode, p_active: c_int) c_int;
    pub const activateMode = gst_pad_activate_mode;

    /// Be notified of different states of pads. The provided callback is called for
    /// every state that matches `mask`.
    ///
    /// Probes are called in groups: First GST_PAD_PROBE_TYPE_BLOCK probes are
    /// called, then others, then finally GST_PAD_PROBE_TYPE_IDLE. The only
    /// exception here are GST_PAD_PROBE_TYPE_IDLE probes that are called
    /// immediately if the pad is already idle while calling `gst.Pad.addProbe`.
    /// In each of the groups, probes are called in the order in which they were
    /// added.
    extern fn gst_pad_add_probe(p_pad: *Pad, p_mask: gst.PadProbeType, p_callback: gst.PadProbeCallback, p_user_data: ?*anyopaque, p_destroy_data: ?glib.DestroyNotify) c_ulong;
    pub const addProbe = gst_pad_add_probe;

    /// Checks if the source pad and the sink pad are compatible so they can be
    /// linked.
    extern fn gst_pad_can_link(p_srcpad: *Pad, p_sinkpad: *gst.Pad) c_int;
    pub const canLink = gst_pad_can_link;

    /// Chain a buffer to `pad`.
    ///
    /// The function returns `GST_FLOW_FLUSHING` if the pad was flushing.
    ///
    /// If the buffer type is not acceptable for `pad` (as negotiated with a
    /// preceding GST_EVENT_CAPS event), this function returns
    /// `GST_FLOW_NOT_NEGOTIATED`.
    ///
    /// The function proceeds calling the chain function installed on `pad` (see
    /// `gst_pad_set_chain_function`) and the return value of that function is
    /// returned to the caller. `GST_FLOW_NOT_SUPPORTED` is returned if `pad` has no
    /// chain function.
    ///
    /// In all cases, success or failure, the caller loses its reference to `buffer`
    /// after calling this function.
    extern fn gst_pad_chain(p_pad: *Pad, p_buffer: *gst.Buffer) gst.FlowReturn;
    pub const chain = gst_pad_chain;

    /// Chain a bufferlist to `pad`.
    ///
    /// The function returns `GST_FLOW_FLUSHING` if the pad was flushing.
    ///
    /// If `pad` was not negotiated properly with a CAPS event, this function
    /// returns `GST_FLOW_NOT_NEGOTIATED`.
    ///
    /// The function proceeds calling the chainlist function installed on `pad` (see
    /// `gst_pad_set_chain_list_function`) and the return value of that function is
    /// returned to the caller. `GST_FLOW_NOT_SUPPORTED` is returned if `pad` has no
    /// chainlist function.
    ///
    /// In all cases, success or failure, the caller loses its reference to `list`
    /// after calling this function.
    ///
    /// MT safe.
    extern fn gst_pad_chain_list(p_pad: *Pad, p_list: *gst.BufferList) gst.FlowReturn;
    pub const chainList = gst_pad_chain_list;

    /// Check and clear the `GST_PAD_FLAG_NEED_RECONFIGURE` flag on `pad` and return `TRUE`
    /// if the flag was set.
    extern fn gst_pad_check_reconfigure(p_pad: *Pad) c_int;
    pub const checkReconfigure = gst_pad_check_reconfigure;

    /// Creates a stream-id for the source `gst.Pad` `pad` by combining the
    /// upstream information with the optional `stream_id` of the stream
    /// of `pad`. `pad` must have a parent `gst.Element` and which must have zero
    /// or one sinkpad. `stream_id` can only be `NULL` if the parent element
    /// of `pad` has only a single source pad.
    ///
    /// This function generates an unique stream-id by getting the upstream
    /// stream-start event stream ID and appending `stream_id` to it. If the
    /// element has no sinkpad it will generate an upstream stream-id by
    /// doing an URI query on the element and in the worst case just uses
    /// a random number. Source elements that don't implement the URI
    /// handler interface should ideally generate a unique, deterministic
    /// stream-id manually instead.
    ///
    /// Since stream IDs are sorted alphabetically, any numbers in the
    /// stream ID should be printed with a fixed number of characters,
    /// preceded by 0's, such as by using the format \%03u instead of \%u.
    extern fn gst_pad_create_stream_id(p_pad: *Pad, p_parent: *gst.Element, p_stream_id: ?[*:0]const u8) [*:0]u8;
    pub const createStreamId = gst_pad_create_stream_id;

    /// Creates a stream-id for the source `gst.Pad` `pad` by combining the
    /// upstream information with the optional `stream_id` of the stream
    /// of `pad`. `pad` must have a parent `gst.Element` and which must have zero
    /// or one sinkpad. `stream_id` can only be `NULL` if the parent element
    /// of `pad` has only a single source pad.
    ///
    /// This function generates an unique stream-id by getting the upstream
    /// stream-start event stream ID and appending `stream_id` to it. If the
    /// element has no sinkpad it will generate an upstream stream-id by
    /// doing an URI query on the element and in the worst case just uses
    /// a random number. Source elements that don't implement the URI
    /// handler interface should ideally generate a unique, deterministic
    /// stream-id manually instead.
    extern fn gst_pad_create_stream_id_printf(p_pad: *Pad, p_parent: *gst.Element, p_stream_id: ?[*:0]const u8, ...) [*:0]u8;
    pub const createStreamIdPrintf = gst_pad_create_stream_id_printf;

    /// Creates a stream-id for the source `gst.Pad` `pad` by combining the
    /// upstream information with the optional `stream_id` of the stream
    /// of `pad`. `pad` must have a parent `gst.Element` and which must have zero
    /// or one sinkpad. `stream_id` can only be `NULL` if the parent element
    /// of `pad` has only a single source pad.
    ///
    /// This function generates an unique stream-id by getting the upstream
    /// stream-start event stream ID and appending `stream_id` to it. If the
    /// element has no sinkpad it will generate an upstream stream-id by
    /// doing an URI query on the element and in the worst case just uses
    /// a random number. Source elements that don't implement the URI
    /// handler interface should ideally generate a unique, deterministic
    /// stream-id manually instead.
    extern fn gst_pad_create_stream_id_printf_valist(p_pad: *Pad, p_parent: *gst.Element, p_stream_id: ?[*:0]const u8, p_var_args: std.builtin.VaList) [*:0]u8;
    pub const createStreamIdPrintfValist = gst_pad_create_stream_id_printf_valist;

    /// Invokes the default event handler for the given pad.
    ///
    /// The EOS event will pause the task associated with `pad` before it is forwarded
    /// to all internally linked pads,
    ///
    /// The event is sent to all pads internally linked to `pad`. This function
    /// takes ownership of `event`.
    extern fn gst_pad_event_default(p_pad: *Pad, p_parent: ?*gst.Object, p_event: *gst.Event) c_int;
    pub const eventDefault = gst_pad_event_default;

    /// Calls `forward` for all internally linked pads of `pad`. This function deals with
    /// dynamically changing internal pads and will make sure that the `forward`
    /// function is only called once for each pad.
    ///
    /// When `forward` returns `TRUE`, no further pads will be processed.
    extern fn gst_pad_forward(p_pad: *Pad, p_forward: gst.PadForwardFunction, p_user_data: ?*anyopaque) c_int;
    pub const forward = gst_pad_forward;

    /// Gets the capabilities of the allowed media types that can flow through
    /// `pad` and its peer.
    ///
    /// The allowed capabilities is calculated as the intersection of the results of
    /// calling `gst.Pad.queryCaps` on `pad` and its peer. The caller owns a reference
    /// on the resulting caps.
    extern fn gst_pad_get_allowed_caps(p_pad: *Pad) ?*gst.Caps;
    pub const getAllowedCaps = gst_pad_get_allowed_caps;

    /// Gets the capabilities currently configured on `pad` with the last
    /// `GST_EVENT_CAPS` event.
    extern fn gst_pad_get_current_caps(p_pad: *Pad) ?*gst.Caps;
    pub const getCurrentCaps = gst_pad_get_current_caps;

    /// Gets the direction of the pad. The direction of the pad is
    /// decided at construction time so this function does not take
    /// the LOCK.
    extern fn gst_pad_get_direction(p_pad: *Pad) gst.PadDirection;
    pub const getDirection = gst_pad_get_direction;

    /// Gets the private data of a pad.
    /// No locking is performed in this function.
    extern fn gst_pad_get_element_private(p_pad: *Pad) ?*anyopaque;
    pub const getElementPrivate = gst_pad_get_element_private;

    /// Gets the `gst.FlowReturn` return from the last data passed by this pad.
    extern fn gst_pad_get_last_flow_return(p_pad: *Pad) gst.FlowReturn;
    pub const getLastFlowReturn = gst_pad_get_last_flow_return;

    /// Get the offset applied to the running time of `pad`. `pad` has to be a source
    /// pad.
    extern fn gst_pad_get_offset(p_pad: *Pad) i64;
    pub const getOffset = gst_pad_get_offset;

    /// Gets the template for `pad`.
    extern fn gst_pad_get_pad_template(p_pad: *Pad) ?*gst.PadTemplate;
    pub const getPadTemplate = gst_pad_get_pad_template;

    /// Gets the capabilities for `pad`'s template.
    extern fn gst_pad_get_pad_template_caps(p_pad: *Pad) *gst.Caps;
    pub const getPadTemplateCaps = gst_pad_get_pad_template_caps;

    /// Gets the parent of `pad`, cast to a `gst.Element`. If a `pad` has no parent or
    /// its parent is not an element, return `NULL`.
    extern fn gst_pad_get_parent_element(p_pad: *Pad) ?*gst.Element;
    pub const getParentElement = gst_pad_get_parent_element;

    /// Gets the peer of `pad`. This function refs the peer pad so
    /// you need to unref it after use.
    extern fn gst_pad_get_peer(p_pad: *Pad) ?*gst.Pad;
    pub const getPeer = gst_pad_get_peer;

    /// When `pad` is flushing this function returns `GST_FLOW_FLUSHING`
    /// immediately and `buffer` is `NULL`.
    ///
    /// Calls the getrange function of `pad`, see `gst.PadGetRangeFunction` for a
    /// description of a getrange function. If `pad` has no getrange function
    /// installed (see `gst_pad_set_getrange_function`) this function returns
    /// `GST_FLOW_NOT_SUPPORTED`.
    ///
    /// If `buffer` points to a variable holding `NULL`, a valid new `gst.Buffer` will be
    /// placed in `buffer` when this function returns `GST_FLOW_OK`. The new buffer
    /// must be freed with `gst.Buffer.unref` after usage.
    ///
    /// When `buffer` points to a variable that points to a valid `gst.Buffer`, the
    /// buffer will be filled with the result data when this function returns
    /// `GST_FLOW_OK`. If the provided buffer is larger than `size`, only
    /// `size` bytes will be filled in the result buffer and its size will be updated
    /// accordingly.
    ///
    /// Note that less than `size` bytes can be returned in `buffer` when, for example,
    /// an EOS condition is near or when `buffer` is not large enough to hold `size`
    /// bytes. The caller should check the result buffer size to get the result size.
    ///
    /// When this function returns any other result value than `GST_FLOW_OK`, `buffer`
    /// will be unchanged.
    ///
    /// This is a lowlevel function. Usually `gst.Pad.pullRange` is used.
    extern fn gst_pad_get_range(p_pad: *Pad, p_offset: u64, p_size: c_uint, p_buffer: **gst.Buffer) gst.FlowReturn;
    pub const getRange = gst_pad_get_range;

    /// If there is a single internal link of the given pad, this function will
    /// return it. Otherwise, it will return NULL.
    extern fn gst_pad_get_single_internal_link(p_pad: *Pad) ?*gst.Pad;
    pub const getSingleInternalLink = gst_pad_get_single_internal_link;

    /// Returns a new reference of the sticky event of type `event_type`
    /// from the event.
    extern fn gst_pad_get_sticky_event(p_pad: *Pad, p_event_type: gst.EventType, p_idx: c_uint) ?*gst.Event;
    pub const getStickyEvent = gst_pad_get_sticky_event;

    /// Returns the current `gst.Stream` for the `pad`, or `NULL` if none has been
    /// set yet, i.e. the pad has not received a stream-start event yet.
    ///
    /// This is a convenience wrapper around `gst.Pad.getStickyEvent` and
    /// `gst.Event.parseStream`.
    extern fn gst_pad_get_stream(p_pad: *Pad) ?*gst.Stream;
    pub const getStream = gst_pad_get_stream;

    /// Returns the current stream-id for the `pad`, or `NULL` if none has been
    /// set yet, i.e. the pad has not received a stream-start event yet.
    ///
    /// This is a convenience wrapper around `gst.Pad.getStickyEvent` and
    /// `gst.Event.parseStreamStart`.
    ///
    /// The returned stream-id string should be treated as an opaque string, its
    /// contents should not be interpreted.
    extern fn gst_pad_get_stream_id(p_pad: *Pad) ?[*:0]u8;
    pub const getStreamId = gst_pad_get_stream_id;

    /// Get `pad` task state. If no task is currently
    /// set, `GST_TASK_STOPPED` is returned.
    extern fn gst_pad_get_task_state(p_pad: *Pad) gst.TaskState;
    pub const getTaskState = gst_pad_get_task_state;

    /// Check if `pad` has caps set on it with a `GST_EVENT_CAPS` event.
    extern fn gst_pad_has_current_caps(p_pad: *Pad) c_int;
    pub const hasCurrentCaps = gst_pad_has_current_caps;

    /// Query if a pad is active
    extern fn gst_pad_is_active(p_pad: *Pad) c_int;
    pub const isActive = gst_pad_is_active;

    /// Checks if the pad is blocked or not. This function returns the
    /// last requested state of the pad. It is not certain that the pad
    /// is actually blocking at this point (see `gst.Pad.isBlocking`).
    extern fn gst_pad_is_blocked(p_pad: *Pad) c_int;
    pub const isBlocked = gst_pad_is_blocked;

    /// Checks if the pad is blocking or not. This is a guaranteed state
    /// of whether the pad is actually blocking on a `gst.Buffer` or a `gst.Event`.
    extern fn gst_pad_is_blocking(p_pad: *Pad) c_int;
    pub const isBlocking = gst_pad_is_blocking;

    /// Checks if a `pad` is linked to another pad or not.
    extern fn gst_pad_is_linked(p_pad: *Pad) c_int;
    pub const isLinked = gst_pad_is_linked;

    /// Gets an iterator for the pads to which the given pad is linked to inside
    /// of the parent element.
    ///
    /// Each `gst.Pad` element yielded by the iterator will have its refcount increased,
    /// so unref after use.
    ///
    /// Free-function: gst_iterator_free
    extern fn gst_pad_iterate_internal_links(p_pad: *Pad) ?*gst.Iterator;
    pub const iterateInternalLinks = gst_pad_iterate_internal_links;

    /// Iterate the list of pads to which the given pad is linked to inside of
    /// the parent element.
    /// This is the default handler, and thus returns an iterator of all of the
    /// pads inside the parent element with opposite direction.
    ///
    /// The caller must free this iterator after use with `gst.Iterator.free`.
    extern fn gst_pad_iterate_internal_links_default(p_pad: *Pad, p_parent: ?*gst.Object) ?*gst.Iterator;
    pub const iterateInternalLinksDefault = gst_pad_iterate_internal_links_default;

    /// Links the source pad and the sink pad.
    extern fn gst_pad_link(p_srcpad: *Pad, p_sinkpad: *gst.Pad) gst.PadLinkReturn;
    pub const link = gst_pad_link;

    /// Links the source pad and the sink pad.
    ///
    /// This variant of `gst.Pad.link` provides a more granular control on the
    /// checks being done when linking. While providing some considerable speedups
    /// the caller of this method must be aware that wrong usage of those flags
    /// can cause severe issues. Refer to the documentation of `gst.PadLinkCheck`
    /// for more information.
    ///
    /// MT Safe.
    extern fn gst_pad_link_full(p_srcpad: *Pad, p_sinkpad: *gst.Pad, p_flags: gst.PadLinkCheck) gst.PadLinkReturn;
    pub const linkFull = gst_pad_link_full;

    /// Links `src` to `sink`, creating any `gst.GhostPad`'s in between as necessary.
    ///
    /// This is a convenience function to save having to create and add intermediate
    /// `gst.GhostPad`'s as required for linking across `gst.Bin` boundaries.
    ///
    /// If `src` or `sink` pads don't have parent elements or do not share a common
    /// ancestor, the link will fail.
    extern fn gst_pad_link_maybe_ghosting(p_src: *Pad, p_sink: *gst.Pad) c_int;
    pub const linkMaybeGhosting = gst_pad_link_maybe_ghosting;

    /// Links `src` to `sink`, creating any `gst.GhostPad`'s in between as necessary.
    ///
    /// This is a convenience function to save having to create and add intermediate
    /// `gst.GhostPad`'s as required for linking across `gst.Bin` boundaries.
    ///
    /// If `src` or `sink` pads don't have parent elements or do not share a common
    /// ancestor, the link will fail.
    ///
    /// Calling `gst.Pad.linkMaybeGhostingFull` with
    /// `flags` == `GST_PAD_LINK_CHECK_DEFAULT` is the recommended way of linking
    /// pads with safety checks applied.
    extern fn gst_pad_link_maybe_ghosting_full(p_src: *Pad, p_sink: *gst.Pad, p_flags: gst.PadLinkCheck) c_int;
    pub const linkMaybeGhostingFull = gst_pad_link_maybe_ghosting_full;

    /// Mark a pad for needing reconfiguration. The next call to
    /// `gst.Pad.checkReconfigure` will return `TRUE` after this call.
    extern fn gst_pad_mark_reconfigure(p_pad: *Pad) void;
    pub const markReconfigure = gst_pad_mark_reconfigure;

    /// Check the `GST_PAD_FLAG_NEED_RECONFIGURE` flag on `pad` and return `TRUE`
    /// if the flag was set.
    extern fn gst_pad_needs_reconfigure(p_pad: *Pad) c_int;
    pub const needsReconfigure = gst_pad_needs_reconfigure;

    /// Pause the task of `pad`. This function will also wait until the
    /// function executed by the task is finished if this function is not
    /// called from the task function.
    extern fn gst_pad_pause_task(p_pad: *Pad) c_int;
    pub const pauseTask = gst_pad_pause_task;

    /// Performs `gst.Pad.query` on the peer of `pad`.
    ///
    /// The caller is responsible for both the allocation and deallocation of
    /// the query structure.
    extern fn gst_pad_peer_query(p_pad: *Pad, p_query: *gst.Query) c_int;
    pub const peerQuery = gst_pad_peer_query;

    /// Check if the peer of `pad` accepts `caps`. If `pad` has no peer, this function
    /// returns `TRUE`.
    extern fn gst_pad_peer_query_accept_caps(p_pad: *Pad, p_caps: *gst.Caps) c_int;
    pub const peerQueryAcceptCaps = gst_pad_peer_query_accept_caps;

    /// Gets the capabilities of the peer connected to this pad. Similar to
    /// `gst.Pad.queryCaps`.
    ///
    /// When called on srcpads `filter` contains the caps that
    /// upstream could produce in the order preferred by upstream. When
    /// called on sinkpads `filter` contains the caps accepted by
    /// downstream in the preferred order. `filter` might be `NULL` but
    /// if it is not `NULL` the returned caps will be a subset of `filter`.
    extern fn gst_pad_peer_query_caps(p_pad: *Pad, p_filter: ?*gst.Caps) *gst.Caps;
    pub const peerQueryCaps = gst_pad_peer_query_caps;

    /// Queries the peer pad of a given sink pad to convert `src_val` in `src_format`
    /// to `dest_format`.
    extern fn gst_pad_peer_query_convert(p_pad: *Pad, p_src_format: gst.Format, p_src_val: i64, p_dest_format: gst.Format, p_dest_val: *i64) c_int;
    pub const peerQueryConvert = gst_pad_peer_query_convert;

    /// Queries the peer pad of a given sink pad for the total stream duration.
    extern fn gst_pad_peer_query_duration(p_pad: *Pad, p_format: gst.Format, p_duration: ?*i64) c_int;
    pub const peerQueryDuration = gst_pad_peer_query_duration;

    /// Queries the peer of a given sink pad for the stream position.
    extern fn gst_pad_peer_query_position(p_pad: *Pad, p_format: gst.Format, p_cur: ?*i64) c_int;
    pub const peerQueryPosition = gst_pad_peer_query_position;

    /// Checks if all internally linked pads of `pad` accepts the caps in `query` and
    /// returns the intersection of the results.
    ///
    /// This function is useful as a default accept caps query function for an element
    /// that can handle any stream format, but requires caps that are acceptable for
    /// all opposite pads.
    extern fn gst_pad_proxy_query_accept_caps(p_pad: *Pad, p_query: *gst.Query) c_int;
    pub const proxyQueryAcceptCaps = gst_pad_proxy_query_accept_caps;

    /// Calls `gst.Pad.queryCaps` for all internally linked pads of `pad` and returns
    /// the intersection of the results.
    ///
    /// This function is useful as a default caps query function for an element
    /// that can handle any stream format, but requires all its pads to have
    /// the same caps.  Two such elements are tee and adder.
    extern fn gst_pad_proxy_query_caps(p_pad: *Pad, p_query: *gst.Query) c_int;
    pub const proxyQueryCaps = gst_pad_proxy_query_caps;

    /// Pulls a `buffer` from the peer pad or fills up a provided buffer.
    ///
    /// This function will first trigger the pad block signal if it was
    /// installed.
    ///
    /// When `pad` is not linked `GST_FLOW_NOT_LINKED` is returned else this
    /// function returns the result of `gst.Pad.getRange` on the peer pad.
    /// See `gst.Pad.getRange` for a list of return values and for the
    /// semantics of the arguments of this function.
    ///
    /// If `buffer` points to a variable holding `NULL`, a valid new `gst.Buffer` will be
    /// placed in `buffer` when this function returns `GST_FLOW_OK`. The new buffer
    /// must be freed with `gst.Buffer.unref` after usage. When this function
    /// returns any other result value, `buffer` will still point to `NULL`.
    ///
    /// When `buffer` points to a variable that points to a valid `gst.Buffer`, the
    /// buffer will be filled with the result data when this function returns
    /// `GST_FLOW_OK`. When this function returns any other result value,
    /// `buffer` will be unchanged. If the provided buffer is larger than `size`, only
    /// `size` bytes will be filled in the result buffer and its size will be updated
    /// accordingly.
    ///
    /// Note that less than `size` bytes can be returned in `buffer` when, for example,
    /// an EOS condition is near or when `buffer` is not large enough to hold `size`
    /// bytes. The caller should check the result buffer size to get the result size.
    extern fn gst_pad_pull_range(p_pad: *Pad, p_offset: u64, p_size: c_uint, p_buffer: **gst.Buffer) gst.FlowReturn;
    pub const pullRange = gst_pad_pull_range;

    /// Pushes a buffer to the peer of `pad`.
    ///
    /// This function will call installed block probes before triggering any
    /// installed data probes.
    ///
    /// The function proceeds calling `gst.Pad.chain` on the peer pad and returns
    /// the value from that function. If `pad` has no peer, `GST_FLOW_NOT_LINKED` will
    /// be returned.
    ///
    /// In all cases, success or failure, the caller loses its reference to `buffer`
    /// after calling this function.
    extern fn gst_pad_push(p_pad: *Pad, p_buffer: *gst.Buffer) gst.FlowReturn;
    pub const push = gst_pad_push;

    /// Sends the event to the peer of the given pad. This function is
    /// mainly used by elements to send events to their peer
    /// elements.
    ///
    /// This function takes ownership of the provided event so you should
    /// `gst.Event.ref` it if you want to reuse the event after this call.
    extern fn gst_pad_push_event(p_pad: *Pad, p_event: *gst.Event) c_int;
    pub const pushEvent = gst_pad_push_event;

    /// Pushes a buffer list to the peer of `pad`.
    ///
    /// This function will call installed block probes before triggering any
    /// installed data probes.
    ///
    /// The function proceeds calling the chain function on the peer pad and returns
    /// the value from that function. If `pad` has no peer, `GST_FLOW_NOT_LINKED` will
    /// be returned. If the peer pad does not have any installed chainlist function
    /// every group buffer of the list will be merged into a normal `gst.Buffer` and
    /// chained via `gst.Pad.chain`.
    ///
    /// In all cases, success or failure, the caller loses its reference to `list`
    /// after calling this function.
    extern fn gst_pad_push_list(p_pad: *Pad, p_list: *gst.BufferList) gst.FlowReturn;
    pub const pushList = gst_pad_push_list;

    /// Dispatches a query to a pad. The query should have been allocated by the
    /// caller via one of the type-specific allocation functions. The element that
    /// the pad belongs to is responsible for filling the query with an appropriate
    /// response, which should then be parsed with a type-specific query parsing
    /// function.
    ///
    /// Again, the caller is responsible for both the allocation and deallocation of
    /// the query structure.
    ///
    /// Please also note that some queries might need a running pipeline to work.
    extern fn gst_pad_query(p_pad: *Pad, p_query: *gst.Query) c_int;
    pub const query = gst_pad_query;

    /// Check if the given pad accepts the caps.
    extern fn gst_pad_query_accept_caps(p_pad: *Pad, p_caps: *gst.Caps) c_int;
    pub const queryAcceptCaps = gst_pad_query_accept_caps;

    /// Gets the capabilities this pad can produce or consume.
    /// Note that this method doesn't necessarily return the caps set by sending a
    /// `gst.Event.newCaps` - use `gst.Pad.getCurrentCaps` for that instead.
    /// gst_pad_query_caps returns all possible caps a pad can operate with, using
    /// the pad's CAPS query function, If the query fails, this function will return
    /// `filter`, if not `NULL`, otherwise ANY.
    ///
    /// When called on sinkpads `filter` contains the caps that
    /// upstream could produce in the order preferred by upstream. When
    /// called on srcpads `filter` contains the caps accepted by
    /// downstream in the preferred order. `filter` might be `NULL` but
    /// if it is not `NULL` the returned caps will be a subset of `filter`.
    ///
    /// Note that this function does not return writable `gst.Caps`, use
    /// `gst_caps_make_writable` before modifying the caps.
    extern fn gst_pad_query_caps(p_pad: *Pad, p_filter: ?*gst.Caps) *gst.Caps;
    pub const queryCaps = gst_pad_query_caps;

    /// Queries a pad to convert `src_val` in `src_format` to `dest_format`.
    extern fn gst_pad_query_convert(p_pad: *Pad, p_src_format: gst.Format, p_src_val: i64, p_dest_format: gst.Format, p_dest_val: *i64) c_int;
    pub const queryConvert = gst_pad_query_convert;

    /// Invokes the default query handler for the given pad.
    /// The query is sent to all pads internally linked to `pad`. Note that
    /// if there are many possible sink pads that are internally linked to
    /// `pad`, only one will be sent the query.
    /// Multi-sinkpad elements should implement custom query handlers.
    extern fn gst_pad_query_default(p_pad: *Pad, p_parent: ?*gst.Object, p_query: *gst.Query) c_int;
    pub const queryDefault = gst_pad_query_default;

    /// Queries a pad for the total stream duration.
    extern fn gst_pad_query_duration(p_pad: *Pad, p_format: gst.Format, p_duration: ?*i64) c_int;
    pub const queryDuration = gst_pad_query_duration;

    /// Queries a pad for the stream position.
    extern fn gst_pad_query_position(p_pad: *Pad, p_format: gst.Format, p_cur: ?*i64) c_int;
    pub const queryPosition = gst_pad_query_position;

    /// Remove the probe with `id` from `pad`.
    ///
    /// MT safe.
    extern fn gst_pad_remove_probe(p_pad: *Pad, p_id: c_ulong) void;
    pub const removeProbe = gst_pad_remove_probe;

    /// Sends the event to the pad. This function can be used
    /// by applications to send events in the pipeline.
    ///
    /// If `pad` is a source pad, `event` should be an upstream event. If `pad` is a
    /// sink pad, `event` should be a downstream event. For example, you would not
    /// send a `GST_EVENT_EOS` on a src pad; EOS events only propagate downstream.
    /// Furthermore, some downstream events have to be serialized with data flow,
    /// like EOS, while some can travel out-of-band, like `GST_EVENT_FLUSH_START`. If
    /// the event needs to be serialized with data flow, this function will take the
    /// pad's stream lock while calling its event function.
    ///
    /// To find out whether an event type is upstream, downstream, or downstream and
    /// serialized, see `gst.EventTypeFlags`, `gst.eventTypeGetFlags`,
    /// `GST_EVENT_IS_UPSTREAM`, `GST_EVENT_IS_DOWNSTREAM`, and
    /// `GST_EVENT_IS_SERIALIZED`. Note that in practice that an application or
    /// plugin doesn't need to bother itself with this information; the core handles
    /// all necessary locks and checks.
    ///
    /// This function takes ownership of the provided event so you should
    /// `gst.Event.ref` it if you want to reuse the event after this call.
    extern fn gst_pad_send_event(p_pad: *Pad, p_event: *gst.Event) c_int;
    pub const sendEvent = gst_pad_send_event;

    /// Sets the given activate function for `pad`. The activate function will
    /// dispatch to `gst.Pad.activateMode` to perform the actual activation.
    /// Only makes sense to set on sink pads.
    ///
    /// Call this function if your sink pad can start a pull-based task.
    extern fn gst_pad_set_activate_function_full(p_pad: *Pad, p_activate: gst.PadActivateFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setActivateFunctionFull = gst_pad_set_activate_function_full;

    /// Sets the given activate_mode function for the pad. An activate_mode function
    /// prepares the element for data passing.
    extern fn gst_pad_set_activatemode_function_full(p_pad: *Pad, p_activatemode: gst.PadActivateModeFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setActivatemodeFunctionFull = gst_pad_set_activatemode_function_full;

    /// Activates or deactivates the given pad.
    /// Normally called from within core state change functions.
    ///
    /// If `active`, makes sure the pad is active. If it is already active, either in
    /// push or pull mode, just return. Otherwise dispatches to the pad's activate
    /// function to perform the actual activation.
    ///
    /// If not `active`, calls `gst.Pad.activateMode` with the pad's current mode
    /// and a `FALSE` argument.
    extern fn gst_pad_set_active(p_pad: *Pad, p_active: c_int) c_int;
    pub const setActive = gst_pad_set_active;

    /// Sets the given chain function for the pad. The chain function is called to
    /// process a `gst.Buffer` input buffer. see `gst.PadChainFunction` for more details.
    extern fn gst_pad_set_chain_function_full(p_pad: *Pad, p_chain: gst.PadChainFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setChainFunctionFull = gst_pad_set_chain_function_full;

    /// Sets the given chain list function for the pad. The chainlist function is
    /// called to process a `gst.BufferList` input buffer list. See
    /// `gst.PadChainListFunction` for more details.
    extern fn gst_pad_set_chain_list_function_full(p_pad: *Pad, p_chainlist: gst.PadChainListFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setChainListFunctionFull = gst_pad_set_chain_list_function_full;

    /// Set the given private data gpointer on the pad.
    /// This function can only be used by the element that owns the pad.
    /// No locking is performed in this function.
    extern fn gst_pad_set_element_private(p_pad: *Pad, p_priv: ?*anyopaque) void;
    pub const setElementPrivate = gst_pad_set_element_private;

    /// Sets the given event handler for the pad.
    extern fn gst_pad_set_event_full_function_full(p_pad: *Pad, p_event: gst.PadEventFullFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setEventFullFunctionFull = gst_pad_set_event_full_function_full;

    /// Sets the given event handler for the pad.
    extern fn gst_pad_set_event_function_full(p_pad: *Pad, p_event: gst.PadEventFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setEventFunctionFull = gst_pad_set_event_function_full;

    /// Sets the given getrange function for the pad. The getrange function is
    /// called to produce a new `gst.Buffer` to start the processing pipeline. see
    /// `gst.PadGetRangeFunction` for a description of the getrange function.
    extern fn gst_pad_set_getrange_function_full(p_pad: *Pad, p_get: gst.PadGetRangeFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setGetrangeFunctionFull = gst_pad_set_getrange_function_full;

    /// Sets the given internal link iterator function for the pad.
    extern fn gst_pad_set_iterate_internal_links_function_full(p_pad: *Pad, p_iterintlink: gst.PadIterIntLinkFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setIterateInternalLinksFunctionFull = gst_pad_set_iterate_internal_links_function_full;

    /// Sets the given link function for the pad. It will be called when
    /// the pad is linked with another pad.
    ///
    /// The return value `GST_PAD_LINK_OK` should be used when the connection can be
    /// made.
    ///
    /// The return value `GST_PAD_LINK_REFUSED` should be used when the connection
    /// cannot be made for some reason.
    ///
    /// If `link` is installed on a source pad, it should call the `gst.PadLinkFunction`
    /// of the peer sink pad, if present.
    extern fn gst_pad_set_link_function_full(p_pad: *Pad, p_link: gst.PadLinkFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setLinkFunctionFull = gst_pad_set_link_function_full;

    /// Set the offset that will be applied to the running time of `pad`. Upon next
    /// buffer, every sticky events (notably segment) will be pushed again with
    /// their running time adjusted. For that reason this is only reliable on
    /// source pads.
    extern fn gst_pad_set_offset(p_pad: *Pad, p_offset: i64) void;
    pub const setOffset = gst_pad_set_offset;

    /// Set the given query function for the pad.
    extern fn gst_pad_set_query_function_full(p_pad: *Pad, p_query: gst.PadQueryFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setQueryFunctionFull = gst_pad_set_query_function_full;

    /// Sets the given unlink function for the pad. It will be called
    /// when the pad is unlinked.
    ///
    /// Note that the pad's lock is already held when the unlink
    /// function is called, so most pad functions cannot be called
    /// from within the callback.
    extern fn gst_pad_set_unlink_function_full(p_pad: *Pad, p_unlink: gst.PadUnlinkFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setUnlinkFunctionFull = gst_pad_set_unlink_function_full;

    /// Starts a task that repeatedly calls `func` with `user_data`. This function
    /// is mostly used in pad activation functions to start the dataflow.
    /// The `GST_PAD_STREAM_LOCK` of `pad` will automatically be acquired
    /// before `func` is called.
    extern fn gst_pad_start_task(p_pad: *Pad, p_func: gst.TaskFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) c_int;
    pub const startTask = gst_pad_start_task;

    /// Iterates all sticky events on `pad` and calls `foreach_func` for every
    /// event. If `foreach_func` returns `FALSE` the iteration is immediately stopped.
    extern fn gst_pad_sticky_events_foreach(p_pad: *Pad, p_foreach_func: gst.PadStickyEventsForeachFunction, p_user_data: ?*anyopaque) void;
    pub const stickyEventsForeach = gst_pad_sticky_events_foreach;

    /// Stop the task of `pad`. This function will also make sure that the
    /// function executed by the task will effectively stop if not called
    /// from the GstTaskFunction.
    ///
    /// This function will deadlock if called from the GstTaskFunction of
    /// the task. Use `gst.Task.pause` instead.
    ///
    /// Regardless of whether the pad has a task, the stream lock is acquired and
    /// released so as to ensure that streaming through this pad has finished.
    extern fn gst_pad_stop_task(p_pad: *Pad) c_int;
    pub const stopTask = gst_pad_stop_task;

    /// Store the sticky `event` on `pad`
    extern fn gst_pad_store_sticky_event(p_pad: *Pad, p_event: *gst.Event) gst.FlowReturn;
    pub const storeStickyEvent = gst_pad_store_sticky_event;

    /// Unlinks the source pad from the sink pad. Will emit the `gst.Pad.signals.unlinked`
    /// signal on both pads.
    extern fn gst_pad_unlink(p_srcpad: *Pad, p_sinkpad: *gst.Pad) c_int;
    pub const unlink = gst_pad_unlink;

    /// A helper function you can use that sets the FIXED_CAPS flag
    /// This way the default CAPS query will always return the negotiated caps
    /// or in case the pad is not negotiated, the padtemplate caps.
    ///
    /// The negotiated caps are the caps of the last CAPS event that passed on the
    /// pad. Use this function on a pad that, once it negotiated to a CAPS, cannot
    /// be renegotiated to something else.
    extern fn gst_pad_use_fixed_caps(p_pad: *Pad) void;
    pub const useFixedCaps = gst_pad_use_fixed_caps;

    extern fn gst_pad_get_type() usize;
    pub const getGObjectType = gst_pad_get_type;

    extern fn g_object_ref(p_self: *gst.Pad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Pad) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Pad, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Padtemplates describe the possible media types a pad or an elementfactory can
/// handle. This allows for both inspection of handled types before loading the
/// element plugin as well as identifying pads on elements that are not yet
/// created (request or sometimes pads).
///
/// Pad and PadTemplates have `gst.Caps` attached to it to describe the media type
/// they are capable of dealing with. `gst.PadTemplate.getCaps` or
/// `GST_PAD_TEMPLATE_CAPS` are used to get the caps of a padtemplate. It's not
/// possible to modify the caps of a padtemplate after creation.
///
/// PadTemplates have a `gst.PadPresence` property which identifies the lifetime
/// of the pad and that can be retrieved with `GST_PAD_TEMPLATE_PRESENCE`. Also
/// the direction of the pad can be retrieved from the `gst.PadTemplate` with
/// `GST_PAD_TEMPLATE_DIRECTION`.
///
/// The GST_PAD_TEMPLATE_NAME_TEMPLATE () is important for GST_PAD_REQUEST pads
/// because it has to be used as the name in the `gst.Element.requestPadSimple`
/// call to instantiate a pad from this template.
///
/// Padtemplates can be created with `gst.PadTemplate.new` or with
/// gst_static_pad_template_get (), which creates a `gst.PadTemplate` from a
/// `gst.StaticPadTemplate` that can be filled with the
/// convenient `GST_STATIC_PAD_TEMPLATE` macro.
///
/// A padtemplate can be used to create a pad (see `gst.Pad.newFromTemplate`
/// or gst_pad_new_from_static_template ()) or to add to an element class
/// (see gst_element_class_add_static_pad_template ()).
///
/// The following code example shows the code to create a pad from a padtemplate.
/// ```
///   GstStaticPadTemplate my_template =
///   GST_STATIC_PAD_TEMPLATE (
///     "sink",          // the name of the pad
///     GST_PAD_SINK,    // the direction of the pad
///     GST_PAD_ALWAYS,  // when this pad will be present
///     GST_STATIC_CAPS (        // the capabilities of the padtemplate
///       "audio/x-raw, "
///         "channels = (int) [ 1, 6 ]"
///     )
///   );
///   void
///   my_method (void)
///   {
///     GstPad *pad;
///     pad = gst_pad_new_from_static_template (&my_template, "sink");
///     ...
///   }
/// ```
///
/// The following example shows you how to add the padtemplate to an
/// element class, this is usually done in the class_init of the class:
/// ```
///   static void
///   my_element_class_init (GstMyElementClass *klass)
///   {
///     GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
///
///     gst_element_class_add_static_pad_template (gstelement_class, &my_template);
///   }
/// ```
pub const PadTemplate = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.PadTemplateClass;
    f_object: gst.Object,
    f_name_template: ?[*:0]u8,
    f_direction: gst.PadDirection,
    f_presence: gst.PadPresence,
    f_caps: ?*gst.Caps,
    anon0: extern union {
        f__gst_reserved: [4]*anyopaque,
        anon0: extern struct {
            f_gtype: usize,
            f_documentation_caps: ?*gst.Caps,
        },
    },

    pub const virtual_methods = struct {
        /// Emit the pad-created signal for this template when created by this pad.
        pub const pad_created = struct {
            pub fn call(p_class: anytype, p_templ: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) void {
                return gobject.ext.as(PadTemplate.Class, p_class).f_pad_created.?(gobject.ext.as(PadTemplate, p_templ), p_pad);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_templ: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad) callconv(.c) void) void {
                gobject.ext.as(PadTemplate.Class, p_class).f_pad_created = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// The capabilities of the pad described by the pad template.
        pub const caps = struct {
            pub const name = "caps";

            pub const Type = ?*gst.Caps;
        };

        /// The direction of the pad described by the pad template.
        pub const direction = struct {
            pub const name = "direction";

            pub const Type = gst.PadDirection;
        };

        /// The type of the pad described by the pad template.
        pub const gtype = struct {
            pub const name = "gtype";

            pub const Type = usize;
        };

        /// The name template of the pad template.
        pub const name_template = struct {
            pub const name = "name-template";

            pub const Type = ?[*:0]u8;
        };

        /// When the pad described by the pad template will become available.
        pub const presence = struct {
            pub const name = "presence";

            pub const Type = gst.PadPresence;
        };
    };

    pub const signals = struct {
        /// This signal is fired when an element creates a pad from this template.
        pub const pad_created = struct {
            pub const name = "pad-created";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_pad: *gst.Pad, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(PadTemplate, p_instance))),
                    gobject.signalLookup("pad-created", PadTemplate.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Creates a new pad template with a name according to the given template
    /// and with the given arguments.
    extern fn gst_pad_template_new(p_name_template: [*:0]const u8, p_direction: gst.PadDirection, p_presence: gst.PadPresence, p_caps: *gst.Caps) ?*gst.PadTemplate;
    pub const new = gst_pad_template_new;

    /// Converts a `gst.StaticPadTemplate` into a `gst.PadTemplate` with a type.
    extern fn gst_pad_template_new_from_static_pad_template_with_gtype(p_pad_template: *gst.StaticPadTemplate, p_pad_type: usize) ?*gst.PadTemplate;
    pub const newFromStaticPadTemplateWithGtype = gst_pad_template_new_from_static_pad_template_with_gtype;

    /// Creates a new pad template with a name according to the given template
    /// and with the given arguments.
    extern fn gst_pad_template_new_with_gtype(p_name_template: [*:0]const u8, p_direction: gst.PadDirection, p_presence: gst.PadPresence, p_caps: *gst.Caps, p_pad_type: usize) ?*gst.PadTemplate;
    pub const newWithGtype = gst_pad_template_new_with_gtype;

    /// Gets the capabilities of the pad template.
    extern fn gst_pad_template_get_caps(p_templ: *PadTemplate) *gst.Caps;
    pub const getCaps = gst_pad_template_get_caps;

    /// See `gst.PadTemplate.setDocumentationCaps`.
    extern fn gst_pad_template_get_documentation_caps(p_templ: *PadTemplate) *gst.Caps;
    pub const getDocumentationCaps = gst_pad_template_get_documentation_caps;

    /// Emit the pad-created signal for this template when created by this pad.
    extern fn gst_pad_template_pad_created(p_templ: *PadTemplate, p_pad: *gst.Pad) void;
    pub const padCreated = gst_pad_template_pad_created;

    /// Certain elements will dynamically construct the caps of their
    /// pad templates. In order not to let environment-specific information
    /// into the documentation, element authors should use this method to
    /// expose "stable" caps to the reader.
    extern fn gst_pad_template_set_documentation_caps(p_templ: *PadTemplate, p_caps: *gst.Caps) void;
    pub const setDocumentationCaps = gst_pad_template_set_documentation_caps;

    extern fn gst_pad_template_get_type() usize;
    pub const getGObjectType = gst_pad_template_get_type;

    extern fn g_object_ref(p_self: *gst.PadTemplate) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.PadTemplate) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *PadTemplate, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a `gobject.ParamSpec` for arrays of
/// values
pub const ParamArray = opaque {
    pub const Parent = gobject.ParamSpec;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = ParamArray;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_param_spec_array_get_type() usize;
    pub const getGObjectType = gst_param_spec_array_get_type;

    pub fn as(p_instance: *ParamArray, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes a `gobject.ParamSpec` for fractional
/// properties
pub const ParamFraction = opaque {
    pub const Parent = gobject.ParamSpec;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = ParamFraction;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_param_spec_fraction_get_type() usize;
    pub const getGObjectType = gst_param_spec_fraction_get_type;

    pub fn as(p_instance: *ParamFraction, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.Pipeline` is a special `gst.Bin` used as the toplevel container for
/// the filter graph. The `gst.Pipeline` will manage the selection and
/// distribution of a global `gst.Clock` as well as provide a `gst.Bus` to the
/// application.
///
/// `gst.Pipeline.new` is used to create a pipeline. when you are done with
/// the pipeline, use `gst.Object.unref` to free its resources including all
/// added `gst.Element` objects (if not otherwise referenced).
///
/// Elements are added and removed from the pipeline using the `gst.Bin`
/// methods like `gst.Bin.add` and `gst.Bin.remove` (see `gst.Bin`).
///
/// Before changing the state of the `gst.Pipeline` (see `gst.Element`) a `gst.Bus`
/// should be retrieved with `gst.Pipeline.getBus`. This `gst.Bus` should then
/// be used to receive `gst.Message` from the elements in the pipeline. Listening
/// to the `gst.Bus` is necessary for retrieving error messages from the
/// `gst.Pipeline` and otherwise the `gst.Pipeline` might stop without any
/// indication, why. Furthermore, the `gst.Pipeline` posts messages even if
/// nobody listens on the `gst.Bus`, which will pile up and use up memory.
///
/// By default, a `gst.Pipeline` will automatically flush the pending `gst.Bus`
/// messages when going to the NULL state to ensure that no circular
/// references exist when no messages are read from the `gst.Bus`. This
/// behaviour can be changed with `gst.Pipeline.setAutoFlushBus`.
///
/// When the `gst.Pipeline` performs the PAUSED to PLAYING state change it will
/// select a clock for the elements. The clock selection algorithm will by
/// default select a clock provided by an element that is most upstream
/// (closest to the source). For live pipelines (ones that return
/// `GST_STATE_CHANGE_NO_PREROLL` from the `gst.Element.setState` call) this
/// will select the clock provided by the live source. For normal pipelines
/// this will select a clock provided by the sinks (most likely the audio
/// sink). If no element provides a clock, a default `gst.SystemClock` is used.
///
/// The clock selection can be controlled with the `gst.Pipeline.useClock`
/// method, which will enforce a given clock on the pipeline. With
/// `gst.Pipeline.autoClock` the default clock selection algorithm can be
/// restored.
///
/// A `gst.Pipeline` maintains a running time for the elements. The running
/// time is defined as the difference between the current clock time and
/// the base time. When the pipeline goes to READY or a flushing seek is
/// performed on it, the running time is reset to 0. When the pipeline is
/// set from PLAYING to PAUSED, the current clock time is sampled and used to
/// configure the base time for the elements when the pipeline is set
/// to PLAYING again. The effect is that the running time (as the difference
/// between the clock time and the base time) will count how much time was spent
/// in the PLAYING state. This default behaviour can be changed with the
/// `gst.Element.setStartTime` method.
pub const Pipeline = extern struct {
    pub const Parent = gst.Bin;
    pub const Implements = [_]type{gst.ChildProxy};
    pub const Class = gst.PipelineClass;
    f_bin: gst.Bin,
    /// The fixed clock of the pipeline, used when
    ///               GST_PIPELINE_FLAG_FIXED_CLOCK is set.
    f_fixed_clock: ?*gst.Clock,
    /// The stream time of the pipeline. A better name for this
    ///         property would be the running_time, the total time spent in the
    ///         PLAYING state without being flushed. (deprecated, use the start_time
    ///         on GstElement).
    f_stream_time: gst.ClockTime,
    /// Extra delay added to base_time to compensate for computing delays
    ///         when setting elements to PLAYING.
    f_delay: gst.ClockTime,
    f_priv: ?*gst.PipelinePrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// Whether or not to automatically flush all messages on the
        /// pipeline's bus when going from READY to NULL state. Please see
        /// `gst.Pipeline.setAutoFlushBus` for more information on this option.
        pub const auto_flush_bus = struct {
            pub const name = "auto-flush-bus";

            pub const Type = c_int;
        };

        /// The expected delay needed for elements to spin up to the
        /// PLAYING state expressed in nanoseconds.
        /// see `gst.Pipeline.setDelay` for more information on this option.
        pub const delay = struct {
            pub const name = "delay";

            pub const Type = u64;
        };

        /// Latency to configure on the pipeline. See `gst.Pipeline.setLatency`.
        pub const latency = struct {
            pub const name = "latency";

            pub const Type = u64;
        };
    };

    pub const signals = struct {};

    /// Create a new pipeline with the given name.
    extern fn gst_pipeline_new(p_name: ?[*:0]const u8) *gst.Pipeline;
    pub const new = gst_pipeline_new;

    /// Let `pipeline` select a clock automatically. This is the default
    /// behaviour.
    ///
    /// Use this function if you previous forced a fixed clock with
    /// `gst.Pipeline.useClock` and want to restore the default
    /// pipeline clock selection algorithm.
    ///
    /// MT safe.
    extern fn gst_pipeline_auto_clock(p_pipeline: *Pipeline) void;
    pub const autoClock = gst_pipeline_auto_clock;

    /// Check if `pipeline` will automatically flush messages when going to
    /// the NULL state.
    extern fn gst_pipeline_get_auto_flush_bus(p_pipeline: *Pipeline) c_int;
    pub const getAutoFlushBus = gst_pipeline_get_auto_flush_bus;

    /// Gets the `gst.Bus` of `pipeline`. The bus allows applications to receive
    /// `gst.Message` packets.
    extern fn gst_pipeline_get_bus(p_pipeline: *Pipeline) *gst.Bus;
    pub const getBus = gst_pipeline_get_bus;

    /// Gets the current clock used by `pipeline`. Users of object
    /// oriented languages should use `gst.Pipeline.getPipelineClock`
    /// to avoid confusion with `gst.Element.getClock` which has a different behavior.
    ///
    /// Unlike `gst.Element.getClock`, this function will always return a
    /// clock, even if the pipeline is not in the PLAYING state.
    extern fn gst_pipeline_get_clock(p_pipeline: *Pipeline) *gst.Clock;
    pub const getClock = gst_pipeline_get_clock;

    /// Return the configured latency on `pipeline`.
    extern fn gst_pipeline_get_configured_latency(p_pipeline: *Pipeline) gst.ClockTime;
    pub const getConfiguredLatency = gst_pipeline_get_configured_latency;

    /// Get the configured delay (see `gst.Pipeline.setDelay`).
    extern fn gst_pipeline_get_delay(p_pipeline: *Pipeline) gst.ClockTime;
    pub const getDelay = gst_pipeline_get_delay;

    /// Gets the latency that should be configured on the pipeline. See
    /// `gst.Pipeline.setLatency`.
    extern fn gst_pipeline_get_latency(p_pipeline: *Pipeline) gst.ClockTime;
    pub const getLatency = gst_pipeline_get_latency;

    /// Gets the current clock used by `pipeline`.
    ///
    /// Unlike `gst.Element.getClock`, this function will always return a
    /// clock, even if the pipeline is not in the PLAYING state.
    extern fn gst_pipeline_get_pipeline_clock(p_pipeline: *Pipeline) *gst.Clock;
    pub const getPipelineClock = gst_pipeline_get_pipeline_clock;

    /// Check if `pipeline` is live.
    extern fn gst_pipeline_is_live(p_pipeline: *Pipeline) c_int;
    pub const isLive = gst_pipeline_is_live;

    /// Usually, when a pipeline goes from READY to NULL state, it automatically
    /// flushes all pending messages on the bus, which is done for refcounting
    /// purposes, to break circular references.
    ///
    /// This means that applications that update state using (async) bus messages
    /// (e.g. do certain things when a pipeline goes from PAUSED to READY) might
    /// not get to see messages when the pipeline is shut down, because they might
    /// be flushed before they can be dispatched in the main thread. This behaviour
    /// can be disabled using this function.
    ///
    /// It is important that all messages on the bus are handled when the
    /// automatic flushing is disabled else memory leaks will be introduced.
    ///
    /// MT safe.
    extern fn gst_pipeline_set_auto_flush_bus(p_pipeline: *Pipeline, p_auto_flush: c_int) void;
    pub const setAutoFlushBus = gst_pipeline_set_auto_flush_bus;

    /// Set the clock for `pipeline`. The clock will be distributed
    /// to all the elements managed by the pipeline.
    extern fn gst_pipeline_set_clock(p_pipeline: *Pipeline, p_clock: ?*gst.Clock) c_int;
    pub const setClock = gst_pipeline_set_clock;

    /// Set the expected delay needed for all elements to perform the
    /// PAUSED to PLAYING state change. `delay` will be added to the
    /// base time of the elements so that they wait an additional `delay`
    /// amount of time before starting to process buffers and cannot be
    /// `GST_CLOCK_TIME_NONE`.
    ///
    /// This option is used for tuning purposes and should normally not be
    /// used.
    ///
    /// MT safe.
    extern fn gst_pipeline_set_delay(p_pipeline: *Pipeline, p_delay: gst.ClockTime) void;
    pub const setDelay = gst_pipeline_set_delay;

    /// Sets the latency that should be configured on the pipeline. Setting
    /// GST_CLOCK_TIME_NONE will restore the default behaviour of using the minimum
    /// latency from the LATENCY query. Setting this is usually not required and
    /// the pipeline will figure out an appropriate latency automatically.
    ///
    /// Setting a too low latency, especially lower than the minimum latency from
    /// the LATENCY query, will most likely cause the pipeline to fail.
    extern fn gst_pipeline_set_latency(p_pipeline: *Pipeline, p_latency: gst.ClockTime) void;
    pub const setLatency = gst_pipeline_set_latency;

    /// Force `pipeline` to use the given `clock`. The pipeline will
    /// always use the given clock even if new clock providers are added
    /// to this pipeline.
    ///
    /// If `clock` is `NULL` all clocking will be disabled which will make
    /// the pipeline run as fast as possible.
    ///
    /// MT safe.
    extern fn gst_pipeline_use_clock(p_pipeline: *Pipeline, p_clock: ?*gst.Clock) void;
    pub const useClock = gst_pipeline_use_clock;

    extern fn gst_pipeline_get_type() usize;
    pub const getGObjectType = gst_pipeline_get_type;

    extern fn g_object_ref(p_self: *gst.Pipeline) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Pipeline) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Pipeline, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GStreamer is extensible, so `gst.Element` instances can be loaded at runtime.
/// A plugin system can provide one or more of the basic GStreamer
/// `gst.PluginFeature` subclasses.
///
/// A plugin should export a symbol `gst_plugin_desc` that is a
/// struct of type `gst.PluginDesc`.
/// the plugin loader will check the version of the core library the plugin was
/// linked against and will create a new `gst.Plugin`. It will then call the
/// `gst.PluginInitFunc` function that was provided in the
/// `gst_plugin_desc`.
///
/// Once you have a handle to a `gst.Plugin` (e.g. from the `gst.Registry`), you
/// can add any object that subclasses `gst.PluginFeature`.
///
/// Usually plugins are always automatically loaded so you don't need to call
/// `gst.Plugin.load` explicitly to bring it into memory. There are options to
/// statically link plugins to an app or even use GStreamer without a plugin
/// repository in which case `gst.Plugin.load` can be needed to bring the plugin
/// into memory.
pub const Plugin = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.PluginClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Unrefs each member of `list`, then frees the list.
    extern fn gst_plugin_list_free(p_list: *glib.List) void;
    pub const listFree = gst_plugin_list_free;

    /// Load the named plugin. Refs the plugin.
    extern fn gst_plugin_load_by_name(p_name: [*:0]const u8) ?*gst.Plugin;
    pub const loadByName = gst_plugin_load_by_name;

    /// Loads the given plugin and refs it.  Caller needs to unref after use.
    extern fn gst_plugin_load_file(p_filename: [*:0]const u8, p_error: ?*?*glib.Error) ?*gst.Plugin;
    pub const loadFile = gst_plugin_load_file;

    /// Registers a static plugin, ie. a plugin which is private to an application
    /// or library and contained within the application or library (as opposed to
    /// being shipped as a separate module file).
    ///
    /// You must make sure that GStreamer has been initialised (with `gst.init` or
    /// via `gst.initGetOptionGroup`) before calling this function.
    extern fn gst_plugin_register_static(p_major_version: c_int, p_minor_version: c_int, p_name: [*:0]const u8, p_description: [*:0]const u8, p_init_func: gst.PluginInitFunc, p_version: [*:0]const u8, p_license: [*:0]const u8, p_source: [*:0]const u8, p_package: [*:0]const u8, p_origin: [*:0]const u8) c_int;
    pub const registerStatic = gst_plugin_register_static;

    /// Registers a static plugin, ie. a plugin which is private to an application
    /// or library and contained within the application or library (as opposed to
    /// being shipped as a separate module file) with a `gst.PluginInitFullFunc`
    /// which allows user data to be passed to the callback function (useful
    /// for bindings).
    ///
    /// You must make sure that GStreamer has been initialised (with `gst.init` or
    /// via `gst.initGetOptionGroup`) before calling this function.
    extern fn gst_plugin_register_static_full(p_major_version: c_int, p_minor_version: c_int, p_name: [*:0]const u8, p_description: [*:0]const u8, p_init_full_func: gst.PluginInitFullFunc, p_version: [*:0]const u8, p_license: [*:0]const u8, p_source: [*:0]const u8, p_package: [*:0]const u8, p_origin: [*:0]const u8, p_user_data: ?*anyopaque) c_int;
    pub const registerStaticFull = gst_plugin_register_static_full;

    /// Make GStreamer aware of external dependencies which affect the feature
    /// set of this plugin (ie. the elements or typefinders associated with it).
    ///
    /// GStreamer will re-inspect plugins with external dependencies whenever any
    /// of the external dependencies change. This is useful for plugins which wrap
    /// other plugin systems, e.g. a plugin which wraps a plugin-based visualisation
    /// library and makes visualisations available as GStreamer elements, or a
    /// codec loader which exposes elements and/or caps dependent on what external
    /// codec libraries are currently installed.
    extern fn gst_plugin_add_dependency(p_plugin: *Plugin, p_env_vars: ?[*][*:0]const u8, p_paths: ?[*][*:0]const u8, p_names: ?[*][*:0]const u8, p_flags: gst.PluginDependencyFlags) void;
    pub const addDependency = gst_plugin_add_dependency;

    /// Make GStreamer aware of external dependencies which affect the feature
    /// set of this plugin (ie. the elements or typefinders associated with it).
    ///
    /// GStreamer will re-inspect plugins with external dependencies whenever any
    /// of the external dependencies change. This is useful for plugins which wrap
    /// other plugin systems, e.g. a plugin which wraps a plugin-based visualisation
    /// library and makes visualisations available as GStreamer elements, or a
    /// codec loader which exposes elements and/or caps dependent on what external
    /// codec libraries are currently installed.
    ///
    /// Convenience wrapper function for `gst.Plugin.addDependency` which
    /// takes simple strings as arguments instead of string arrays, with multiple
    /// arguments separated by predefined delimiters (see above).
    extern fn gst_plugin_add_dependency_simple(p_plugin: *Plugin, p_env_vars: ?[*:0]const u8, p_paths: ?[*:0]const u8, p_names: ?[*:0]const u8, p_flags: gst.PluginDependencyFlags) void;
    pub const addDependencySimple = gst_plugin_add_dependency_simple;

    extern fn gst_plugin_add_status_error(p_plugin: *Plugin, p_message: [*:0]const u8) void;
    pub const addStatusError = gst_plugin_add_status_error;

    extern fn gst_plugin_add_status_info(p_plugin: *Plugin, p_message: [*:0]const u8) void;
    pub const addStatusInfo = gst_plugin_add_status_info;

    extern fn gst_plugin_add_status_warning(p_plugin: *Plugin, p_message: [*:0]const u8) void;
    pub const addStatusWarning = gst_plugin_add_status_warning;

    /// Gets the plugin specific data cache. If it is `NULL` there is no cached data
    /// stored. This is the case when the registry is getting rebuilt.
    extern fn gst_plugin_get_cache_data(p_plugin: *Plugin) ?*const gst.Structure;
    pub const getCacheData = gst_plugin_get_cache_data;

    /// Get the long descriptive name of the plugin
    extern fn gst_plugin_get_description(p_plugin: *Plugin) [*:0]const u8;
    pub const getDescription = gst_plugin_get_description;

    /// get the filename of the plugin
    extern fn gst_plugin_get_filename(p_plugin: *Plugin) ?[*:0]const u8;
    pub const getFilename = gst_plugin_get_filename;

    /// get the license of the plugin
    extern fn gst_plugin_get_license(p_plugin: *Plugin) [*:0]const u8;
    pub const getLicense = gst_plugin_get_license;

    /// Get the short name of the plugin
    extern fn gst_plugin_get_name(p_plugin: *Plugin) [*:0]const u8;
    pub const getName = gst_plugin_get_name;

    /// get the URL where the plugin comes from
    extern fn gst_plugin_get_origin(p_plugin: *Plugin) [*:0]const u8;
    pub const getOrigin = gst_plugin_get_origin;

    /// get the package the plugin belongs to.
    extern fn gst_plugin_get_package(p_plugin: *Plugin) [*:0]const u8;
    pub const getPackage = gst_plugin_get_package;

    /// Get the release date (and possibly time) in form of a string, if available.
    ///
    /// For normal GStreamer plugin releases this will usually just be a date in
    /// the form of "YYYY-MM-DD", while pre-releases and builds from git may contain
    /// a time component after the date as well, in which case the string will be
    /// formatted like "YYYY-MM-DDTHH:MMZ" (e.g. "2012-04-30T09:30Z").
    ///
    /// There may be plugins that do not have a valid release date set on them.
    extern fn gst_plugin_get_release_date_string(p_plugin: *Plugin) ?[*:0]const u8;
    pub const getReleaseDateString = gst_plugin_get_release_date_string;

    /// get the source module the plugin belongs to.
    extern fn gst_plugin_get_source(p_plugin: *Plugin) [*:0]const u8;
    pub const getSource = gst_plugin_get_source;

    extern fn gst_plugin_get_status_errors(p_plugin: *Plugin) ?[*][*:0]u8;
    pub const getStatusErrors = gst_plugin_get_status_errors;

    extern fn gst_plugin_get_status_infos(p_plugin: *Plugin) ?[*][*:0]u8;
    pub const getStatusInfos = gst_plugin_get_status_infos;

    extern fn gst_plugin_get_status_warnings(p_plugin: *Plugin) ?[*][*:0]u8;
    pub const getStatusWarnings = gst_plugin_get_status_warnings;

    /// get the version of the plugin
    extern fn gst_plugin_get_version(p_plugin: *Plugin) [*:0]const u8;
    pub const getVersion = gst_plugin_get_version;

    /// queries if the plugin is loaded into memory
    extern fn gst_plugin_is_loaded(p_plugin: *Plugin) c_int;
    pub const isLoaded = gst_plugin_is_loaded;

    /// Loads `plugin`. Note that the *return value* is the loaded plugin; `plugin` is
    /// untouched. The normal use pattern of this function goes like this:
    ///
    /// ```
    /// GstPlugin *loaded_plugin;
    /// loaded_plugin = gst_plugin_load (plugin);
    /// // presumably, we're no longer interested in the potentially-unloaded plugin
    /// gst_object_unref (plugin);
    /// plugin = loaded_plugin;
    /// ```
    extern fn gst_plugin_load(p_plugin: *Plugin) ?*gst.Plugin;
    pub const load = gst_plugin_load;

    /// Adds plugin specific data to cache. Passes the ownership of the structure to
    /// the `plugin`.
    ///
    /// The cache is flushed every time the registry is rebuilt.
    extern fn gst_plugin_set_cache_data(p_plugin: *Plugin, p_cache_data: *gst.Structure) void;
    pub const setCacheData = gst_plugin_set_cache_data;

    extern fn gst_plugin_get_type() usize;
    pub const getGObjectType = gst_plugin_get_type;

    extern fn g_object_ref(p_self: *gst.Plugin) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Plugin) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Plugin, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// This is a base class for anything that can be added to a `gst.Plugin`.
pub const PluginFeature = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.PluginFeatureClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Copies the list of features. Caller should call `gst_plugin_feature_list_free`
    /// when done with the list.
    extern fn gst_plugin_feature_list_copy(p_list: *glib.List) *glib.List;
    pub const listCopy = gst_plugin_feature_list_copy;

    /// Debug the plugin feature names in `list`.
    extern fn gst_plugin_feature_list_debug(p_list: *glib.List) void;
    pub const listDebug = gst_plugin_feature_list_debug;

    /// Unrefs each member of `list`, then frees the list.
    extern fn gst_plugin_feature_list_free(p_list: *glib.List) void;
    pub const listFree = gst_plugin_feature_list_free;

    /// Compares the two given `gst.PluginFeature` instances. This function can be
    /// used as a `glib.CompareFunc` when sorting by rank and then by name.
    extern fn gst_plugin_feature_rank_compare_func(p_p1: ?*const anyopaque, p_p2: ?*const anyopaque) c_int;
    pub const rankCompareFunc = gst_plugin_feature_rank_compare_func;

    /// Checks whether the given plugin feature is at least the required version.
    ///
    /// Note: Since version 1.24 this function no longer returns `TRUE` if the
    /// version is a git development version (e.g. 1.23.0.1) and the check is
    /// for the "next" micro version, that is it will no longer return `TRUE` for
    /// e.g. 1.23.0.1 if the check is for 1.23.1. It is still possible to parse
    /// the nano version from the string and do this check that way if needed.
    extern fn gst_plugin_feature_check_version(p_feature: *PluginFeature, p_min_major: c_uint, p_min_minor: c_uint, p_min_micro: c_uint) c_int;
    pub const checkVersion = gst_plugin_feature_check_version;

    /// Get the plugin that provides this feature.
    extern fn gst_plugin_feature_get_plugin(p_feature: *PluginFeature) ?*gst.Plugin;
    pub const getPlugin = gst_plugin_feature_get_plugin;

    /// Get the name of the plugin that provides this feature.
    extern fn gst_plugin_feature_get_plugin_name(p_feature: *PluginFeature) ?[*:0]const u8;
    pub const getPluginName = gst_plugin_feature_get_plugin_name;

    /// Gets the rank of a plugin feature.
    extern fn gst_plugin_feature_get_rank(p_feature: *PluginFeature) c_uint;
    pub const getRank = gst_plugin_feature_get_rank;

    /// Loads the plugin containing `feature` if it's not already loaded. `feature` is
    /// unaffected; use the return value instead.
    ///
    /// Normally this function is used like this:
    /// ```
    /// GstPluginFeature *loaded_feature;
    ///
    /// loaded_feature = gst_plugin_feature_load (feature);
    /// // presumably, we're no longer interested in the potentially-unloaded feature
    /// gst_object_unref (feature);
    /// feature = loaded_feature;
    /// ```
    extern fn gst_plugin_feature_load(p_feature: *PluginFeature) ?*gst.PluginFeature;
    pub const load = gst_plugin_feature_load;

    /// Specifies a rank for a plugin feature, so that autoplugging uses
    /// the most appropriate feature.
    extern fn gst_plugin_feature_set_rank(p_feature: *PluginFeature, p_rank: c_uint) void;
    pub const setRank = gst_plugin_feature_set_rank;

    extern fn gst_plugin_feature_get_type() usize;
    pub const getGObjectType = gst_plugin_feature_get_type;

    extern fn g_object_ref(p_self: *gst.PluginFeature) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.PluginFeature) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *PluginFeature, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ProxyPad = extern struct {
    pub const Parent = gst.Pad;
    pub const Implements = [_]type{};
    pub const Class = gst.ProxyPadClass;
    f_pad: gst.Pad,
    f_priv: ?*gst.ProxyPadPrivate,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Invoke the default chain function of the proxy pad.
    extern fn gst_proxy_pad_chain_default(p_pad: *gst.Pad, p_parent: ?*gst.Object, p_buffer: *gst.Buffer) gst.FlowReturn;
    pub const chainDefault = gst_proxy_pad_chain_default;

    /// Invoke the default chain list function of the proxy pad.
    extern fn gst_proxy_pad_chain_list_default(p_pad: *gst.Pad, p_parent: ?*gst.Object, p_list: *gst.BufferList) gst.FlowReturn;
    pub const chainListDefault = gst_proxy_pad_chain_list_default;

    /// Invoke the default getrange function of the proxy pad.
    extern fn gst_proxy_pad_getrange_default(p_pad: *gst.Pad, p_parent: *gst.Object, p_offset: u64, p_size: c_uint, p_buffer: **gst.Buffer) gst.FlowReturn;
    pub const getrangeDefault = gst_proxy_pad_getrange_default;

    /// Invoke the default iterate internal links function of the proxy pad.
    extern fn gst_proxy_pad_iterate_internal_links_default(p_pad: *gst.Pad, p_parent: ?*gst.Object) ?*gst.Iterator;
    pub const iterateInternalLinksDefault = gst_proxy_pad_iterate_internal_links_default;

    /// Get the internal pad of `pad`. Unref target pad after usage.
    ///
    /// The internal pad of a `gst.GhostPad` is the internally used
    /// pad of opposite direction, which is used to link to the target.
    extern fn gst_proxy_pad_get_internal(p_pad: *ProxyPad) ?*gst.ProxyPad;
    pub const getInternal = gst_proxy_pad_get_internal;

    extern fn gst_proxy_pad_get_type() usize;
    pub const getGObjectType = gst_proxy_pad_get_type;

    extern fn g_object_ref(p_self: *gst.ProxyPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.ProxyPad) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *ProxyPad, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// One registry holds the metadata of a set of plugins.
///
/// <emphasis role="bold">Design:</emphasis>
///
/// The `gst.Registry` object is a list of plugins and some functions for dealing
/// with them. Each `gst.Plugin` is matched 1-1 with a file on disk, and may or may
/// not be loaded at a given time.
///
/// The primary source, at all times, of plugin information is each plugin file
/// itself. Thus, if an application wants information about a particular plugin,
/// or wants to search for a feature that satisfies given criteria, the primary
/// means of doing so is to load every plugin and look at the resulting
/// information that is gathered in the default registry. Clearly, this is a time
/// consuming process, so we cache information in the registry file. The format
/// and location of the cache file is internal to gstreamer.
///
/// On startup, plugins are searched for in the plugin search path. The following
/// locations are checked in this order:
///
/// * location from --gst-plugin-path commandline option.
/// * the GST_PLUGIN_PATH environment variable.
/// * the GST_PLUGIN_SYSTEM_PATH environment variable.
/// * default locations (if GST_PLUGIN_SYSTEM_PATH is not set).
///   Those default locations are:
///   `$XDG_DATA_HOME/gstreamer-$GST_API_VERSION/plugins/`
///   and `$prefix/libs/gstreamer-$GST_API_VERSION/`.
///   [$XDG_DATA_HOME](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html) defaults to
///   `$HOME/.local/share`.
///
/// The registry cache file is loaded from
/// `$XDG_CACHE_HOME/gstreamer-$GST_API_VERSION/registry-$ARCH.bin`
/// (where $XDG_CACHE_HOME defaults to `$HOME/.cache`) or the file listed in the `GST_REGISTRY`
/// env var. One reason to change the registry location is for testing.
///
/// For each plugin that is found in the plugin search path, there could be 3
/// possibilities for cached information:
///
///   * the cache may not contain information about a given file.
///   * the cache may have stale information.
///   * the cache may have current information.
///
/// In the first two cases, the plugin is loaded and the cache updated. In
/// addition to these cases, the cache may have entries for plugins that are not
/// relevant to the current process. These are marked as not available to the
/// current process. If the cache is updated for whatever reason, it is marked
/// dirty.
///
/// A dirty cache is written out at the end of initialization. Each entry is
/// checked to make sure the information is minimally valid. If not, the entry is
/// simply dropped.
///
/// ## Implementation notes:
///
/// The "cache" and "registry" are different concepts and can represent
/// different sets of plugins. For various reasons, at init time, the cache is
/// stored in the default registry, and plugins not relevant to the current
/// process are marked with the `GST_PLUGIN_FLAG_CACHED` bit. These plugins are
/// removed at the end of initialization.
pub const Registry = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.RegistryClass;
    f_object: gst.Object,
    f_priv: ?*gst.RegistryPrivate,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {
        /// Signals that a feature has been added to the registry (possibly
        /// replacing a previously-added one by the same name)
        pub const feature_added = struct {
            pub const name = "feature-added";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_feature: *gst.PluginFeature, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Registry, p_instance))),
                    gobject.signalLookup("feature-added", Registry.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Signals that a plugin has been added to the registry (possibly
        /// replacing a previously-added one by the same name)
        pub const plugin_added = struct {
            pub const name = "plugin-added";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_plugin: *gst.Plugin, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(Registry, p_instance))),
                    gobject.signalLookup("plugin-added", Registry.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// By default GStreamer will perform scanning and rebuilding of the
    /// registry file using a helper child process.
    ///
    /// Applications might want to disable this behaviour with the
    /// `gst.Registry.forkSetEnabled` function, in which case new plugins
    /// are scanned (and loaded) into the application process.
    extern fn gst_registry_fork_is_enabled() c_int;
    pub const forkIsEnabled = gst_registry_fork_is_enabled;

    /// Applications might want to disable/enable spawning of a child helper process
    /// when rebuilding the registry. See `gst.Registry.forkIsEnabled` for more
    /// information.
    extern fn gst_registry_fork_set_enabled(p_enabled: c_int) void;
    pub const forkSetEnabled = gst_registry_fork_set_enabled;

    /// Retrieves the singleton plugin registry. The caller does not own a
    /// reference on the registry, as it is alive as long as GStreamer is
    /// initialized.
    extern fn gst_registry_get() *gst.Registry;
    pub const get = gst_registry_get;

    /// Add the feature to the registry. The feature-added signal will be emitted.
    ///
    /// `feature`'s reference count will be incremented, and any floating
    /// reference will be removed (see `gst.Object.refSink`)
    extern fn gst_registry_add_feature(p_registry: *Registry, p_feature: *gst.PluginFeature) c_int;
    pub const addFeature = gst_registry_add_feature;

    /// Add the plugin to the registry. The plugin-added signal will be emitted.
    ///
    /// `plugin`'s reference count will be incremented, and any floating
    /// reference will be removed (see `gst.Object.refSink`)
    extern fn gst_registry_add_plugin(p_registry: *Registry, p_plugin: *gst.Plugin) c_int;
    pub const addPlugin = gst_registry_add_plugin;

    /// Checks whether a plugin feature by the given name exists in
    /// `registry` and whether its version is at least the
    /// version required.
    extern fn gst_registry_check_feature_version(p_registry: *Registry, p_feature_name: [*:0]const u8, p_min_major: c_uint, p_min_minor: c_uint, p_min_micro: c_uint) c_int;
    pub const checkFeatureVersion = gst_registry_check_feature_version;

    /// Runs a filter against all features of the plugins in the registry
    /// and returns a GList with the results.
    /// If the first flag is set, only the first match is
    /// returned (as a list with a single object).
    extern fn gst_registry_feature_filter(p_registry: *Registry, p_filter: gst.PluginFeatureFilter, p_first: c_int, p_user_data: ?*anyopaque) *glib.List;
    pub const featureFilter = gst_registry_feature_filter;

    /// Find the pluginfeature with the given name and type in the registry.
    extern fn gst_registry_find_feature(p_registry: *Registry, p_name: [*:0]const u8, p_type: usize) ?*gst.PluginFeature;
    pub const findFeature = gst_registry_find_feature;

    /// Find the plugin with the given name in the registry.
    /// The plugin will be reffed; caller is responsible for unreffing.
    extern fn gst_registry_find_plugin(p_registry: *Registry, p_name: [*:0]const u8) ?*gst.Plugin;
    pub const findPlugin = gst_registry_find_plugin;

    /// Retrieves a `glib.List` of `gst.PluginFeature` of `type`.
    extern fn gst_registry_get_feature_list(p_registry: *Registry, p_type: usize) *glib.List;
    pub const getFeatureList = gst_registry_get_feature_list;

    /// Retrieves a `glib.List` of features of the plugin with name `name`.
    extern fn gst_registry_get_feature_list_by_plugin(p_registry: *Registry, p_name: [*:0]const u8) *glib.List;
    pub const getFeatureListByPlugin = gst_registry_get_feature_list_by_plugin;

    /// Returns the registry's feature list cookie. This changes
    /// every time a feature is added or removed from the registry.
    extern fn gst_registry_get_feature_list_cookie(p_registry: *Registry) u32;
    pub const getFeatureListCookie = gst_registry_get_feature_list_cookie;

    /// Get a copy of all plugins registered in the given registry. The refcount
    /// of each element in the list in incremented.
    extern fn gst_registry_get_plugin_list(p_registry: *Registry) *glib.List;
    pub const getPluginList = gst_registry_get_plugin_list;

    /// Look up a plugin in the given registry with the given filename.
    /// If found, plugin is reffed.
    extern fn gst_registry_lookup(p_registry: *Registry, p_filename: [*:0]const u8) ?*gst.Plugin;
    pub const lookup = gst_registry_lookup;

    /// Find a `gst.PluginFeature` with `name` in `registry`.
    extern fn gst_registry_lookup_feature(p_registry: *Registry, p_name: [*:0]const u8) ?*gst.PluginFeature;
    pub const lookupFeature = gst_registry_lookup_feature;

    /// Runs a filter against all plugins in the registry and returns a `glib.List` with
    /// the results. If the first flag is set, only the first match is
    /// returned (as a list with a single object).
    /// Every plugin is reffed; use `gst.Plugin.listFree` after use, which
    /// will unref again.
    extern fn gst_registry_plugin_filter(p_registry: *Registry, p_filter: gst.PluginFilter, p_first: c_int, p_user_data: ?*anyopaque) *glib.List;
    pub const pluginFilter = gst_registry_plugin_filter;

    /// Remove the feature from the registry.
    ///
    /// MT safe.
    extern fn gst_registry_remove_feature(p_registry: *Registry, p_feature: *gst.PluginFeature) void;
    pub const removeFeature = gst_registry_remove_feature;

    /// Remove the plugin from the registry.
    ///
    /// MT safe.
    extern fn gst_registry_remove_plugin(p_registry: *Registry, p_plugin: *gst.Plugin) void;
    pub const removePlugin = gst_registry_remove_plugin;

    /// Scan the given path for plugins to add to the registry. The syntax of the
    /// path is specific to the registry.
    extern fn gst_registry_scan_path(p_registry: *Registry, p_path: [*:0]const u8) c_int;
    pub const scanPath = gst_registry_scan_path;

    extern fn gst_registry_get_type() usize;
    pub const getGObjectType = gst_registry_get_type;

    extern fn g_object_ref(p_self: *gst.Registry) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Registry) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Registry, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.SharedTaskPool` object.
pub const SharedTaskPool = extern struct {
    pub const Parent = gst.TaskPool;
    pub const Implements = [_]type{};
    pub const Class = gst.SharedTaskPoolClass;
    f_parent: gst.TaskPool,
    f_priv: ?*gst.SharedTaskPoolPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Create a new shared task pool. The shared task pool will queue tasks on
    /// a maximum number of threads, 1 by default.
    ///
    /// Do not use a `gst.SharedTaskPool` to manage potentially inter-dependent tasks such
    /// as pad tasks, as having one task waiting on another to return before returning
    /// would cause obvious deadlocks if they happen to share the same thread.
    extern fn gst_shared_task_pool_new() *gst.SharedTaskPool;
    pub const new = gst_shared_task_pool_new;

    extern fn gst_shared_task_pool_get_max_threads(p_pool: *SharedTaskPool) c_uint;
    pub const getMaxThreads = gst_shared_task_pool_get_max_threads;

    /// Update the maximal number of threads the `pool` may spawn. When
    /// the maximal number of threads is reduced, existing threads are not
    /// immediately shut down, see `glib.ThreadPool.setMaxThreads`.
    ///
    /// Setting `max_threads` to 0 effectively freezes the pool.
    extern fn gst_shared_task_pool_set_max_threads(p_pool: *SharedTaskPool, p_max_threads: c_uint) void;
    pub const setMaxThreads = gst_shared_task_pool_set_max_threads;

    extern fn gst_shared_task_pool_get_type() usize;
    pub const getGObjectType = gst_shared_task_pool_get_type;

    extern fn g_object_ref(p_self: *gst.SharedTaskPool) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.SharedTaskPool) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *SharedTaskPool, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A high-level object representing a single stream. It might be backed, or
/// not, by an actual flow of data in a pipeline (`gst.Pad`).
///
/// A `gst.Stream` does not care about data changes (such as decoding, encoding,
/// parsing,...) as long as the underlying data flow corresponds to the same
/// high-level flow (ex: a certain audio track).
///
/// A `gst.Stream` contains all the information pertinent to a stream, such as
/// stream-id, tags, caps, type, ...
///
/// Elements can subclass a `gst.Stream` for internal usage (to contain information
/// pertinent to streams of data).
pub const Stream = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.StreamClass;
    f_object: gst.Object,
    /// The Stream Identifier for this `gst.Stream`
    f_stream_id: ?[*:0]const u8,
    f_priv: ?*gst.StreamPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The `gst.Caps` of the `gst.Stream`.
        pub const caps = struct {
            pub const name = "caps";

            pub const Type = ?*gst.Caps;
        };

        pub const stream_flags = struct {
            pub const name = "stream-flags";

            pub const Type = gst.StreamFlags;
        };

        /// The unique identifier of the `gst.Stream`. Can only be set at construction
        /// time.
        pub const stream_id = struct {
            pub const name = "stream-id";

            pub const Type = ?[*:0]u8;
        };

        /// The `gst.StreamType` of the `gst.Stream`. Can only be set at construction time.
        pub const stream_type = struct {
            pub const name = "stream-type";

            pub const Type = gst.StreamType;
        };

        /// The `gst.TagList` of the `gst.Stream`.
        pub const tags = struct {
            pub const name = "tags";

            pub const Type = ?*gst.TagList;
        };
    };

    pub const signals = struct {};

    /// Create a new `gst.Stream` for the given `stream_id`, `caps`, `type`
    /// and `flags`
    extern fn gst_stream_new(p_stream_id: ?[*:0]const u8, p_caps: ?*gst.Caps, p_type: gst.StreamType, p_flags: gst.StreamFlags) *gst.Stream;
    pub const new = gst_stream_new;

    /// Retrieve the caps for `stream`, if any
    extern fn gst_stream_get_caps(p_stream: *Stream) ?*gst.Caps;
    pub const getCaps = gst_stream_get_caps;

    /// Retrieve the current stream flags for `stream`
    extern fn gst_stream_get_stream_flags(p_stream: *Stream) gst.StreamFlags;
    pub const getStreamFlags = gst_stream_get_stream_flags;

    /// Returns the stream ID of `stream`.
    extern fn gst_stream_get_stream_id(p_stream: *Stream) ?[*:0]const u8;
    pub const getStreamId = gst_stream_get_stream_id;

    /// Retrieve the stream type for `stream`
    extern fn gst_stream_get_stream_type(p_stream: *Stream) gst.StreamType;
    pub const getStreamType = gst_stream_get_stream_type;

    /// Retrieve the tags for `stream`, if any
    extern fn gst_stream_get_tags(p_stream: *Stream) ?*gst.TagList;
    pub const getTags = gst_stream_get_tags;

    /// Set the caps for the `gst.Stream`
    extern fn gst_stream_set_caps(p_stream: *Stream, p_caps: ?*gst.Caps) void;
    pub const setCaps = gst_stream_set_caps;

    /// Set the `flags` for the `stream`.
    extern fn gst_stream_set_stream_flags(p_stream: *Stream, p_flags: gst.StreamFlags) void;
    pub const setStreamFlags = gst_stream_set_stream_flags;

    /// Set the stream type of `stream`
    extern fn gst_stream_set_stream_type(p_stream: *Stream, p_stream_type: gst.StreamType) void;
    pub const setStreamType = gst_stream_set_stream_type;

    /// Set the tags for the `gst.Stream`
    extern fn gst_stream_set_tags(p_stream: *Stream, p_tags: ?*gst.TagList) void;
    pub const setTags = gst_stream_set_tags;

    extern fn gst_stream_get_type() usize;
    pub const getGObjectType = gst_stream_get_type;

    extern fn g_object_ref(p_self: *gst.Stream) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Stream) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Stream, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A collection of `gst.Stream` that are available.
///
/// A `gst.StreamCollection` will be provided by elements that can make those
/// streams available. Applications can use the collection to show the user
/// what streams are available by using `gst.StreamCollection.getStream``gst.StreamCollection.getStream`
///
/// Once posted, a `gst.StreamCollection` is immutable. Updates are made by sending
/// a new `gst.StreamCollection` message, which may or may not share some of
/// the `gst.Stream` objects from the collection it replaces. The receiver can check
/// the sender of a stream collection message to know which collection is
/// obsoleted.
///
/// Several elements in a pipeline can provide `gst.StreamCollection`.
///
/// Applications can activate streams from a collection by using the
/// `GST_EVENT_SELECT_STREAMS` event on a pipeline, bin or element.
pub const StreamCollection = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.StreamCollectionClass;
    f_object: gst.Object,
    f_upstream_id: ?[*:0]u8,
    f_priv: ?*gst.StreamCollectionPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// default signal handler for the stream-notify signal
        pub const stream_notify = struct {
            pub fn call(p_class: anytype, p_collection: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_stream: *gst.Stream, p_pspec: *gobject.ParamSpec) void {
                return gobject.ext.as(StreamCollection.Class, p_class).f_stream_notify.?(gobject.ext.as(StreamCollection, p_collection), p_stream, p_pspec);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_collection: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_stream: *gst.Stream, p_pspec: *gobject.ParamSpec) callconv(.c) void) void {
                gobject.ext.as(StreamCollection.Class, p_class).f_stream_notify = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// stream-id
        pub const upstream_id = struct {
            pub const name = "upstream-id";

            pub const Type = ?[*:0]u8;
        };
    };

    pub const signals = struct {
        /// The stream notify signal is used to be notified of property changes to
        /// streams within the collection.
        pub const stream_notify = struct {
            pub const name = "stream-notify";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_prop_stream: *gst.Stream, p_prop: *gobject.ParamSpec, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(StreamCollection, p_instance))),
                    gobject.signalLookup("stream-notify", StreamCollection.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Create a new `gst.StreamCollection`.
    extern fn gst_stream_collection_new(p_upstream_id: ?[*:0]const u8) *gst.StreamCollection;
    pub const new = gst_stream_collection_new;

    /// Add the given `stream` to the `collection`.
    extern fn gst_stream_collection_add_stream(p_collection: *StreamCollection, p_stream: *gst.Stream) c_int;
    pub const addStream = gst_stream_collection_add_stream;

    /// Get the number of streams this collection contains
    extern fn gst_stream_collection_get_size(p_collection: *StreamCollection) c_uint;
    pub const getSize = gst_stream_collection_get_size;

    /// Retrieve the `gst.Stream` with index `index` from the collection.
    ///
    /// The caller should not modify the returned `gst.Stream`
    extern fn gst_stream_collection_get_stream(p_collection: *StreamCollection, p_index: c_uint) ?*gst.Stream;
    pub const getStream = gst_stream_collection_get_stream;

    /// Returns the upstream id of the `collection`.
    extern fn gst_stream_collection_get_upstream_id(p_collection: *StreamCollection) ?[*:0]const u8;
    pub const getUpstreamId = gst_stream_collection_get_upstream_id;

    extern fn gst_stream_collection_get_type() usize;
    pub const getGObjectType = gst_stream_collection_get_type;

    extern fn g_object_ref(p_self: *gst.StreamCollection) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.StreamCollection) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *StreamCollection, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The GStreamer core provides a GstSystemClock based on the system time.
/// Asynchronous callbacks are scheduled from an internal thread.
///
/// Clock implementors are encouraged to subclass this systemclock as it
/// implements the async notification.
///
/// Subclasses can however override all of the important methods for sync and
/// async notifications to implement their own callback methods or blocking
/// wait operations.
pub const SystemClock = extern struct {
    pub const Parent = gst.Clock;
    pub const Implements = [_]type{};
    pub const Class = gst.SystemClockClass;
    f_clock: gst.Clock,
    f_priv: ?*gst.SystemClockPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const clock_type = struct {
            pub const name = "clock-type";

            pub const Type = gst.ClockType;
        };
    };

    pub const signals = struct {};

    /// Get a handle to the default system clock. The refcount of the
    /// clock will be increased so you need to unref the clock after
    /// usage.
    extern fn gst_system_clock_obtain() *gst.Clock;
    pub const obtain = gst_system_clock_obtain;

    /// Sets the default system clock that can be obtained with
    /// `gst.SystemClock.obtain`.
    ///
    /// This is mostly used for testing and debugging purposes when you
    /// want to have control over the time reported by the default system
    /// clock.
    ///
    /// MT safe.
    extern fn gst_system_clock_set_default(p_new_clock: ?*gst.Clock) void;
    pub const setDefault = gst_system_clock_set_default;

    extern fn gst_system_clock_get_type() usize;
    pub const getGObjectType = gst_system_clock_get_type;

    extern fn g_object_ref(p_self: *gst.SystemClock) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.SystemClock) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *SystemClock, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.Task` is used by `gst.Element` and `gst.Pad` to provide the data passing
/// threads in a `gst.Pipeline`.
///
/// A `gst.Pad` will typically start a `gst.Task` to push or pull data to/from the
/// peer pads. Most source elements start a `gst.Task` to push data. In some cases
/// a demuxer element can start a `gst.Task` to pull data from a peer element. This
/// is typically done when the demuxer can perform random access on the upstream
/// peer element for improved performance.
///
/// Although convenience functions exist on `gst.Pad` to start/pause/stop tasks, it
/// might sometimes be needed to create a `gst.Task` manually if it is not related to
/// a `gst.Pad`.
///
/// Before the `gst.Task` can be run, it needs a `glib.RecMutex` that can be set with
/// `gst.Task.setLock`.
///
/// The task can be started, paused and stopped with `gst.Task.start`, `gst.Task.pause`
/// and `gst.Task.stop` respectively or with the `gst.Task.setState` function.
///
/// A `gst.Task` will repeatedly call the `gst.TaskFunction` with the user data
/// that was provided when creating the task with `gst.Task.new`. While calling
/// the function it will acquire the provided lock. The provided lock is released
/// when the task pauses or stops.
///
/// Stopping a task with `gst.Task.stop` will not immediately make sure the task is
/// not running anymore. Use `gst.Task.join` to make sure the task is completely
/// stopped and the thread is stopped.
///
/// After creating a `gst.Task`, use `gst.Object.unref` to free its resources. This can
/// only be done when the task is not running anymore.
///
/// Task functions can send a `gst.Message` to send out-of-band data to the
/// application. The application can receive messages from the `gst.Bus` in its
/// mainloop.
///
/// For debugging purposes, the task will configure its object name as the thread
/// name on Linux. Please note that the object name should be configured before the
/// task is started; changing the object name after the task has been started, has
/// no effect on the thread name.
pub const Task = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.TaskClass;
    f_object: gst.Object,
    /// the state of the task
    f_state: gst.TaskState,
    /// used to pause/resume the task
    f_cond: glib.Cond,
    /// The lock taken when iterating the task function
    f_lock: ?*glib.RecMutex,
    /// the function executed by this task
    f_func: ?gst.TaskFunction,
    /// user_data passed to the task function
    f_user_data: ?*anyopaque,
    /// GDestroyNotify for `user_data`
    f_notify: ?glib.DestroyNotify,
    /// a flag indicating that the task is running
    f_running: c_int,
    f_thread: ?*glib.Thread,
    f_priv: ?*gst.TaskPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Wait for all tasks to be stopped. This is mainly used internally
    /// to ensure proper cleanup of internal data structures in test suites.
    ///
    /// MT safe.
    extern fn gst_task_cleanup_all() void;
    pub const cleanupAll = gst_task_cleanup_all;

    /// Create a new Task that will repeatedly call the provided `func`
    /// with `user_data` as a parameter. Typically the task will run in
    /// a new thread.
    ///
    /// The function cannot be changed after the task has been created. You
    /// must create a new `gst.Task` to change the function.
    ///
    /// This function will not yet create and start a thread. Use `gst.Task.start` or
    /// `gst.Task.pause` to create and start the GThread.
    ///
    /// Before the task can be used, a `glib.RecMutex` must be configured using the
    /// `gst.Task.setLock` function. This lock will always be acquired while
    /// `func` is called.
    extern fn gst_task_new(p_func: gst.TaskFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) *gst.Task;
    pub const new = gst_task_new;

    /// Get the `gst.TaskPool` that this task will use for its streaming
    /// threads.
    ///
    /// MT safe.
    extern fn gst_task_get_pool(p_task: *Task) *gst.TaskPool;
    pub const getPool = gst_task_get_pool;

    /// Get the current state of the task.
    extern fn gst_task_get_state(p_task: *Task) gst.TaskState;
    pub const getState = gst_task_get_state;

    /// Joins `task`. After this call, it is safe to unref the task
    /// and clean up the lock set with `gst.Task.setLock`.
    ///
    /// The task will automatically be stopped with this call.
    ///
    /// This function cannot be called from within a task function as this
    /// would cause a deadlock. The function will detect this and print a
    /// g_warning.
    extern fn gst_task_join(p_task: *Task) c_int;
    pub const join = gst_task_join;

    /// Pauses `task`. This method can also be called on a task in the
    /// stopped state, in which case a thread will be started and will remain
    /// in the paused state. This function does not wait for the task to complete
    /// the paused state.
    extern fn gst_task_pause(p_task: *Task) c_int;
    pub const pause = gst_task_pause;

    /// Resume `task` in case it was paused. If the task was stopped, it will
    /// remain in that state and this function will return `FALSE`.
    extern fn gst_task_resume(p_task: *Task) c_int;
    pub const @"resume" = gst_task_resume;

    /// Call `enter_func` when the task function of `task` is entered. `user_data` will
    /// be passed to `enter_func` and `notify` will be called when `user_data` is no
    /// longer referenced.
    extern fn gst_task_set_enter_callback(p_task: *Task, p_enter_func: gst.TaskThreadFunc, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setEnterCallback = gst_task_set_enter_callback;

    /// Call `leave_func` when the task function of `task` is left. `user_data` will
    /// be passed to `leave_func` and `notify` will be called when `user_data` is no
    /// longer referenced.
    extern fn gst_task_set_leave_callback(p_task: *Task, p_leave_func: gst.TaskThreadFunc, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
    pub const setLeaveCallback = gst_task_set_leave_callback;

    /// Set the mutex used by the task. The mutex will be acquired before
    /// calling the `gst.TaskFunction`.
    ///
    /// This function has to be called before calling `gst.Task.pause` or
    /// `gst.Task.start`.
    ///
    /// MT safe.
    extern fn gst_task_set_lock(p_task: *Task, p_mutex: *glib.RecMutex) void;
    pub const setLock = gst_task_set_lock;

    /// Set `pool` as the new GstTaskPool for `task`. Any new streaming threads that
    /// will be created by `task` will now use `pool`.
    ///
    /// MT safe.
    extern fn gst_task_set_pool(p_task: *Task, p_pool: *gst.TaskPool) void;
    pub const setPool = gst_task_set_pool;

    /// Sets the state of `task` to `state`.
    ///
    /// The `task` must have a lock associated with it using
    /// `gst.Task.setLock` when going to GST_TASK_STARTED or GST_TASK_PAUSED or
    /// this function will return `FALSE`.
    ///
    /// MT safe.
    extern fn gst_task_set_state(p_task: *Task, p_state: gst.TaskState) c_int;
    pub const setState = gst_task_set_state;

    /// Starts `task`. The `task` must have a lock associated with it using
    /// `gst.Task.setLock` or this function will return `FALSE`.
    extern fn gst_task_start(p_task: *Task) c_int;
    pub const start = gst_task_start;

    /// Stops `task`. This method merely schedules the task to stop and
    /// will not wait for the task to have completely stopped. Use
    /// `gst.Task.join` to stop and wait for completion.
    extern fn gst_task_stop(p_task: *Task) c_int;
    pub const stop = gst_task_stop;

    extern fn gst_task_get_type() usize;
    pub const getGObjectType = gst_task_get_type;

    extern fn g_object_ref(p_self: *gst.Task) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Task) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Task, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// This object provides an abstraction for creating threads. The default
/// implementation uses a regular GThreadPool to start tasks.
///
/// Subclasses can be made to create custom threads.
pub const TaskPool = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.TaskPoolClass;
    f_object: gst.Object,
    f_pool: ?*glib.ThreadPool,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Wait for all tasks to be stopped. This is mainly used internally
        /// to ensure proper cleanup of internal data structures in test suites.
        ///
        /// MT safe.
        pub const cleanup = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(TaskPool.Class, p_class).f_cleanup.?(gobject.ext.as(TaskPool, p_pool));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(TaskPool.Class, p_class).f_cleanup = @ptrCast(p_implementation);
            }
        };

        /// Dispose of the handle returned by `gst.TaskPool.push`. This does
        /// not need to be called with the default implementation as the default
        /// `gst.TaskPoolClass.signals.push` implementation always returns `NULL`. This does not need to be
        /// called either when calling `gst.TaskPool.join`, but should be called
        /// when joining is not necessary, but `gst.TaskPool.push` returned a
        /// non-`NULL` value.
        ///
        /// This method should only be called with the same `pool` instance that provided
        /// `id`.
        pub const dispose_handle = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_id: ?*anyopaque) void {
                return gobject.ext.as(TaskPool.Class, p_class).f_dispose_handle.?(gobject.ext.as(TaskPool, p_pool), p_id);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_id: ?*anyopaque) callconv(.c) void) void {
                gobject.ext.as(TaskPool.Class, p_class).f_dispose_handle = @ptrCast(p_implementation);
            }
        };

        /// Join a task and/or return it to the pool. `id` is the id obtained from
        /// `gst.TaskPool.push`. The default implementation does nothing, as the
        /// default `gst.TaskPoolClass.signals.push` implementation always returns `NULL`.
        ///
        /// This method should only be called with the same `pool` instance that provided
        /// `id`.
        pub const join = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_id: ?*anyopaque) void {
                return gobject.ext.as(TaskPool.Class, p_class).f_join.?(gobject.ext.as(TaskPool, p_pool), p_id);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_id: ?*anyopaque) callconv(.c) void) void {
                gobject.ext.as(TaskPool.Class, p_class).f_join = @ptrCast(p_implementation);
            }
        };

        /// Prepare the taskpool for accepting `gst.TaskPool.push` operations.
        ///
        /// MT safe.
        pub const prepare = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_error: ?*?*glib.Error) void {
                return gobject.ext.as(TaskPool.Class, p_class).f_prepare.?(gobject.ext.as(TaskPool, p_pool), p_error);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_error: ?*?*glib.Error) callconv(.c) void) void {
                gobject.ext.as(TaskPool.Class, p_class).f_prepare = @ptrCast(p_implementation);
            }
        };

        /// Start the execution of a new thread from `pool`.
        pub const push = struct {
            pub fn call(p_class: anytype, p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_func: gst.TaskPoolFunction, p_user_data: ?*anyopaque, p_error: ?*?*glib.Error) ?*anyopaque {
                return gobject.ext.as(TaskPool.Class, p_class).f_push.?(gobject.ext.as(TaskPool, p_pool), p_func, p_user_data, p_error);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pool: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_func: gst.TaskPoolFunction, p_user_data: ?*anyopaque, p_error: ?*?*glib.Error) callconv(.c) ?*anyopaque) void {
                gobject.ext.as(TaskPool.Class, p_class).f_push = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// Create a new default task pool. The default task pool will use a regular
    /// GThreadPool for threads.
    extern fn gst_task_pool_new() *gst.TaskPool;
    pub const new = gst_task_pool_new;

    /// Wait for all tasks to be stopped. This is mainly used internally
    /// to ensure proper cleanup of internal data structures in test suites.
    ///
    /// MT safe.
    extern fn gst_task_pool_cleanup(p_pool: *TaskPool) void;
    pub const cleanup = gst_task_pool_cleanup;

    /// Dispose of the handle returned by `gst.TaskPool.push`. This does
    /// not need to be called with the default implementation as the default
    /// `gst.TaskPoolClass.signals.push` implementation always returns `NULL`. This does not need to be
    /// called either when calling `gst.TaskPool.join`, but should be called
    /// when joining is not necessary, but `gst.TaskPool.push` returned a
    /// non-`NULL` value.
    ///
    /// This method should only be called with the same `pool` instance that provided
    /// `id`.
    extern fn gst_task_pool_dispose_handle(p_pool: *TaskPool, p_id: ?*anyopaque) void;
    pub const disposeHandle = gst_task_pool_dispose_handle;

    /// Join a task and/or return it to the pool. `id` is the id obtained from
    /// `gst.TaskPool.push`. The default implementation does nothing, as the
    /// default `gst.TaskPoolClass.signals.push` implementation always returns `NULL`.
    ///
    /// This method should only be called with the same `pool` instance that provided
    /// `id`.
    extern fn gst_task_pool_join(p_pool: *TaskPool, p_id: ?*anyopaque) void;
    pub const join = gst_task_pool_join;

    /// Prepare the taskpool for accepting `gst.TaskPool.push` operations.
    ///
    /// MT safe.
    extern fn gst_task_pool_prepare(p_pool: *TaskPool, p_error: ?*?*glib.Error) void;
    pub const prepare = gst_task_pool_prepare;

    /// Start the execution of a new thread from `pool`.
    extern fn gst_task_pool_push(p_pool: *TaskPool, p_func: gst.TaskPoolFunction, p_user_data: ?*anyopaque, p_error: ?*?*glib.Error) ?*anyopaque;
    pub const push = gst_task_pool_push;

    extern fn gst_task_pool_get_type() usize;
    pub const getGObjectType = gst_task_pool_get_type;

    extern fn g_object_ref(p_self: *gst.TaskPool) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.TaskPool) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *TaskPool, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Tracing modules will subclass `gst.Tracer` and register through
/// `gst.Tracer.register`. Modules can attach to various hook-types - see
/// `gst.tracingRegisterHook`. When invoked they receive hook specific
/// contextual data, which they must not modify.
pub const Tracer = extern struct {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.TracerClass;
    f_parent: gst.Object,
    f_priv: ?*gst.TracerPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const params = struct {
            pub const name = "params";

            pub const Type = ?[*:0]u8;
        };
    };

    pub const signals = struct {};

    /// Create a new tracer-factory  capable of instantiating objects of the
    /// `type` and add the factory to `plugin`.
    extern fn gst_tracer_register(p_plugin: ?*gst.Plugin, p_name: [*:0]const u8, p_type: usize) c_int;
    pub const register = gst_tracer_register;

    extern fn gst_tracer_get_type() usize;
    pub const getGObjectType = gst_tracer_get_type;

    extern fn g_object_ref(p_self: *gst.Tracer) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Tracer) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Tracer, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Use `gst.TracerFactory.getList` to get a list of tracer factories known to
/// GStreamer.
pub const TracerFactory = opaque {
    pub const Parent = gst.PluginFeature;
    pub const Implements = [_]type{};
    pub const Class = gst.TracerFactoryClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Gets the list of all registered tracer factories. You must free the
    /// list using `gst.PluginFeature.listFree`.
    ///
    /// The returned factories are sorted by factory name.
    ///
    /// Free-function: gst_plugin_feature_list_free
    extern fn gst_tracer_factory_get_list() *glib.List;
    pub const getList = gst_tracer_factory_get_list;

    /// Get the `gobject.Type` for elements managed by this factory. The type can
    /// only be retrieved if the element factory is loaded, which can be
    /// assured with `gst.PluginFeature.load`.
    extern fn gst_tracer_factory_get_tracer_type(p_factory: *TracerFactory) usize;
    pub const getTracerType = gst_tracer_factory_get_tracer_type;

    extern fn gst_tracer_factory_get_type() usize;
    pub const getGObjectType = gst_tracer_factory_get_type;

    extern fn g_object_ref(p_self: *gst.TracerFactory) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.TracerFactory) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *TracerFactory, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Tracing modules will create instances of this class to announce the data they
/// will log and create a log formatter.
pub const TracerRecord = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gst.TracerRecordClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Create a new tracer record. The record instance can be used to efficiently
    /// log entries using `gst.TracerRecord.log`.
    /// `NULL` terminator required after the last argument.
    ///
    /// The `name` without the ".class" suffix will be used for the log records.
    /// There must be fields for each value that gets logged where the field name is
    /// the value name. The field must be a `gst.Structure` describing the value. The
    /// sub structure must contain a field called 'type' of `G_TYPE_GTYPE` that
    /// contains the GType of the value. The resulting `gst.TracerRecord` will take
    /// ownership of the field structures.
    ///
    /// The way to deal with optional values is to log an additional boolean before
    /// the optional field, that if `TRUE` signals that the optional field is valid
    /// and `FALSE` signals that the optional field should be ignored. One must still
    /// log a placeholder value for the optional field though. Please also note, that
    /// pointer type values must not be NULL - the underlying serialisation can not
    /// handle that right now.
    ///
    /// > Please note that this is still under discussion and subject to change.
    extern fn gst_tracer_record_new(p_name: [*:0]const u8, p_firstfield: [*:0]const u8, ...) *gst.TracerRecord;
    pub const new = gst_tracer_record_new;

    /// Serialzes the trace event into the log.
    ///
    /// Right now this is using the gstreamer debug log with the level TRACE (7) and
    /// the category "GST_TRACER".
    ///
    /// > Please note that this is still under discussion and subject to change.
    extern fn gst_tracer_record_log(p_self: *TracerRecord, ...) void;
    pub const log = gst_tracer_record_log;

    extern fn gst_tracer_record_get_type() usize;
    pub const getGObjectType = gst_tracer_record_get_type;

    extern fn g_object_ref(p_self: *gst.TracerRecord) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.TracerRecord) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *TracerRecord, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// These functions allow querying information about registered typefind
/// functions. How to create and register these functions is described in
/// the section <link linkend="gstreamer-Writing-typefind-functions">
/// "Writing typefind functions"</link>.
///
/// The following example shows how to write a very simple typefinder that
/// identifies the given data. You can get quite a bit more complicated than
/// that though.
/// ```
///   typedef struct {
///     guint8 *data;
///     guint size;
///     guint probability;
///     GstCaps *data;
///   } MyTypeFind;
///   static void
///   my_peek (gpointer data, gint64 offset, guint size)
///   {
///     MyTypeFind *find = (MyTypeFind *) data;
///     if (offset >= 0 && offset + size <= find->size) {
///       return find->data + offset;
///     }
///     return NULL;
///   }
///   static void
///   my_suggest (gpointer data, guint probability, GstCaps *caps)
///   {
///     MyTypeFind *find = (MyTypeFind *) data;
///     if (probability > find->probability) {
///       find->probability = probability;
///       gst_caps_replace (&find->caps, caps);
///     }
///   }
///   static GstCaps *
///   find_type (guint8 *data, guint size)
///   {
///     GList *walk, *type_list;
///     MyTypeFind find = {data, size, 0, NULL};
///     GstTypeFind gst_find = {my_peek, my_suggest, &find, };
///     walk = type_list = gst_type_find_factory_get_list ();
///     while (walk) {
///       GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
///       walk = g_list_next (walk)
///       gst_type_find_factory_call_function (factory, &gst_find);
///     }
///     g_list_free (type_list);
///     return find.caps;
///   };
/// ```
pub const TypeFindFactory = opaque {
    pub const Parent = gst.PluginFeature;
    pub const Implements = [_]type{};
    pub const Class = gst.TypeFindFactoryClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Gets the list of all registered typefind factories. You must free the
    /// list using `gst.PluginFeature.listFree`.
    ///
    /// The returned factories are sorted by highest rank first, and then by
    /// factory name.
    ///
    /// Free-function: gst_plugin_feature_list_free
    extern fn gst_type_find_factory_get_list() *glib.List;
    pub const getList = gst_type_find_factory_get_list;

    /// Calls the `gst.TypeFindFunction` associated with this factory.
    extern fn gst_type_find_factory_call_function(p_factory: *TypeFindFactory, p_find: *gst.TypeFind) void;
    pub const callFunction = gst_type_find_factory_call_function;

    /// Gets the `gst.Caps` associated with a typefind factory.
    extern fn gst_type_find_factory_get_caps(p_factory: *TypeFindFactory) ?*gst.Caps;
    pub const getCaps = gst_type_find_factory_get_caps;

    /// Gets the extensions associated with a `gst.TypeFindFactory`. The returned
    /// array should not be changed. If you need to change stuff in it, you should
    /// copy it using `glib.strdupv`.  This function may return `NULL` to indicate
    /// a 0-length list.
    extern fn gst_type_find_factory_get_extensions(p_factory: *TypeFindFactory) ?[*]const [*:0]const u8;
    pub const getExtensions = gst_type_find_factory_get_extensions;

    /// Check whether the factory has a typefind function. Typefind factories
    /// without typefind functions are a last-effort fallback mechanism to
    /// e.g. assume a certain media type based on the file extension.
    extern fn gst_type_find_factory_has_function(p_factory: *TypeFindFactory) c_int;
    pub const hasFunction = gst_type_find_factory_has_function;

    extern fn gst_type_find_factory_get_type() usize;
    pub const getGObjectType = gst_type_find_factory_get_type;

    extern fn g_object_ref(p_self: *gst.TypeFindFactory) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.TypeFindFactory) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *TypeFindFactory, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes an ordered list of `gobject.Value`
pub const ValueArray = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = ValueArray;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Appends `append_value` to the GstValueArray in `value`.
    extern fn gst_value_array_append_and_take_value(p_value: *gobject.Value, p_append_value: *gobject.Value) void;
    pub const appendAndTakeValue = gst_value_array_append_and_take_value;

    /// Appends `append_value` to the GstValueArray in `value`.
    extern fn gst_value_array_append_value(p_value: *gobject.Value, p_append_value: *const gobject.Value) void;
    pub const appendValue = gst_value_array_append_value;

    /// Gets the number of values contained in `value`.
    extern fn gst_value_array_get_size(p_value: *const gobject.Value) c_uint;
    pub const getSize = gst_value_array_get_size;

    /// Gets the value that is a member of the array contained in `value` and
    /// has the index `index`.
    extern fn gst_value_array_get_value(p_value: *const gobject.Value, p_index: c_uint) *const gobject.Value;
    pub const getValue = gst_value_array_get_value;

    /// Initializes and pre-allocates a `gobject.Value` of type `GST_TYPE_ARRAY`.
    extern fn gst_value_array_init(p_value: *gobject.Value, p_prealloc: c_uint) *gobject.Value;
    pub const init = gst_value_array_init;

    /// Prepends `prepend_value` to the GstValueArray in `value`.
    extern fn gst_value_array_prepend_value(p_value: *gobject.Value, p_prepend_value: *const gobject.Value) void;
    pub const prependValue = gst_value_array_prepend_value;

    extern fn gst_value_array_get_type() usize;
    pub const getGObjectType = gst_value_array_get_type;

    pub fn as(p_instance: *ValueArray, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A fundamental type that describes an unordered list of `gobject.Value`
pub const ValueList = opaque {
    pub const Parent = gobject.TypeInstance;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = ValueList;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Appends `append_value` to the GstValueList in `value`.
    extern fn gst_value_list_append_and_take_value(p_value: *gobject.Value, p_append_value: *gobject.Value) void;
    pub const appendAndTakeValue = gst_value_list_append_and_take_value;

    /// Appends `append_value` to the GstValueList in `value`.
    extern fn gst_value_list_append_value(p_value: *gobject.Value, p_append_value: *const gobject.Value) void;
    pub const appendValue = gst_value_list_append_value;

    /// Concatenates copies of `value1` and `value2` into a list.  Values that are not
    /// of type `GST_TYPE_LIST` are treated as if they were lists of length 1.
    /// `dest` will be initialized to the type `GST_TYPE_LIST`.
    extern fn gst_value_list_concat(p_dest: *gobject.Value, p_value1: *const gobject.Value, p_value2: *const gobject.Value) void;
    pub const concat = gst_value_list_concat;

    /// Gets the number of values contained in `value`.
    extern fn gst_value_list_get_size(p_value: *const gobject.Value) c_uint;
    pub const getSize = gst_value_list_get_size;

    /// Gets the value that is a member of the list contained in `value` and
    /// has the index `index`.
    extern fn gst_value_list_get_value(p_value: *const gobject.Value, p_index: c_uint) *const gobject.Value;
    pub const getValue = gst_value_list_get_value;

    /// Initializes and pre-allocates a `gobject.Value` of type `GST_TYPE_LIST`.
    extern fn gst_value_list_init(p_value: *gobject.Value, p_prealloc: c_uint) *gobject.Value;
    pub const init = gst_value_list_init;

    /// Merges copies of `value1` and `value2`.  Values that are not
    /// of type `GST_TYPE_LIST` are treated as if they were lists of length 1.
    ///
    /// The result will be put into `dest` and will either be a list that will not
    /// contain any duplicates, or a non-list type (if `value1` and `value2`
    /// were equal).
    extern fn gst_value_list_merge(p_dest: *gobject.Value, p_value1: *const gobject.Value, p_value2: *const gobject.Value) void;
    pub const merge = gst_value_list_merge;

    /// Prepends `prepend_value` to the GstValueList in `value`.
    extern fn gst_value_list_prepend_value(p_value: *gobject.Value, p_prepend_value: *const gobject.Value) void;
    pub const prependValue = gst_value_list_prepend_value;

    extern fn gst_value_list_get_type() usize;
    pub const getGObjectType = gst_value_list_get_type;

    pub fn as(p_instance: *ValueList, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// This interface abstracts handling of property sets for elements with
/// children. Imagine elements such as mixers or polyphonic generators. They all
/// have multiple `gst.Pad` or some kind of voice objects. Another use case are
/// container elements like `gst.Bin`.
/// The element implementing the interface acts as a parent for those child
/// objects.
///
/// By implementing this interface the child properties can be accessed from the
/// parent element by using `gst.ChildProxy.get` and `gst.ChildProxy.set`.
///
/// Property names are written as `child-name::property-name`. The whole naming
/// scheme is recursive. Thus `child1::child2::property` is valid too, if
/// `child1` and `child2` implement the `gst.ChildProxy` interface.
pub const ChildProxy = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gst.ChildProxyInterface;
    pub const virtual_methods = struct {
        /// Emits the `gst.ChildProxy.signals.child`-added signal.
        pub const child_added = struct {
            pub fn call(p_class: anytype, p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gobject.Object, p_name: [*:0]const u8) void {
                return gobject.ext.as(ChildProxy.Iface, p_class).f_child_added.?(gobject.ext.as(ChildProxy, p_parent), p_child, p_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gobject.Object, p_name: [*:0]const u8) callconv(.c) void) void {
                gobject.ext.as(ChildProxy.Iface, p_class).f_child_added = @ptrCast(p_implementation);
            }
        };

        /// Emits the `gst.ChildProxy.signals.child`-removed signal.
        pub const child_removed = struct {
            pub fn call(p_class: anytype, p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gobject.Object, p_name: [*:0]const u8) void {
                return gobject.ext.as(ChildProxy.Iface, p_class).f_child_removed.?(gobject.ext.as(ChildProxy, p_parent), p_child, p_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_child: *gobject.Object, p_name: [*:0]const u8) callconv(.c) void) void {
                gobject.ext.as(ChildProxy.Iface, p_class).f_child_removed = @ptrCast(p_implementation);
            }
        };

        /// Fetches a child by its number.
        pub const get_child_by_index = struct {
            pub fn call(p_class: anytype, p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_index: c_uint) ?*gobject.Object {
                return gobject.ext.as(ChildProxy.Iface, p_class).f_get_child_by_index.?(gobject.ext.as(ChildProxy, p_parent), p_index);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_index: c_uint) callconv(.c) ?*gobject.Object) void {
                gobject.ext.as(ChildProxy.Iface, p_class).f_get_child_by_index = @ptrCast(p_implementation);
            }
        };

        /// Looks up a child element by the given name.
        ///
        /// This virtual method has a default implementation that uses `gst.Object`
        /// together with `gst.Object.getName`. If the interface is to be used with
        /// `GObjects`, this methods needs to be overridden.
        pub const get_child_by_name = struct {
            pub fn call(p_class: anytype, p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) ?*gobject.Object {
                return gobject.ext.as(ChildProxy.Iface, p_class).f_get_child_by_name.?(gobject.ext.as(ChildProxy, p_parent), p_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) callconv(.c) ?*gobject.Object) void {
                gobject.ext.as(ChildProxy.Iface, p_class).f_get_child_by_name = @ptrCast(p_implementation);
            }
        };

        /// Gets the number of child objects this parent contains.
        pub const get_children_count = struct {
            pub fn call(p_class: anytype, p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_uint {
                return gobject.ext.as(ChildProxy.Iface, p_class).f_get_children_count.?(gobject.ext.as(ChildProxy, p_parent));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_parent: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) c_uint) void {
                gobject.ext.as(ChildProxy.Iface, p_class).f_get_children_count = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {
        /// Will be emitted after the `object` was added to the `child_proxy`.
        pub const child_added = struct {
            pub const name = "child-added";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_object: *gobject.Object, p_name: [*:0]u8, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(ChildProxy, p_instance))),
                    gobject.signalLookup("child-added", ChildProxy.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        /// Will be emitted after the `object` was removed from the `child_proxy`.
        pub const child_removed = struct {
            pub const name = "child-removed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_object: *gobject.Object, p_name: [*:0]u8, P_Data) callconv(.c) void, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(ChildProxy, p_instance))),
                    gobject.signalLookup("child-removed", ChildProxy.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Emits the `gst.ChildProxy.signals.child`-added signal.
    extern fn gst_child_proxy_child_added(p_parent: *ChildProxy, p_child: *gobject.Object, p_name: [*:0]const u8) void;
    pub const childAdded = gst_child_proxy_child_added;

    /// Emits the `gst.ChildProxy.signals.child`-removed signal.
    extern fn gst_child_proxy_child_removed(p_parent: *ChildProxy, p_child: *gobject.Object, p_name: [*:0]const u8) void;
    pub const childRemoved = gst_child_proxy_child_removed;

    /// Gets properties of the parent object and its children.
    extern fn gst_child_proxy_get(p_object: *ChildProxy, p_first_property_name: [*:0]const u8, ...) void;
    pub const get = gst_child_proxy_get;

    /// Fetches a child by its number.
    extern fn gst_child_proxy_get_child_by_index(p_parent: *ChildProxy, p_index: c_uint) ?*gobject.Object;
    pub const getChildByIndex = gst_child_proxy_get_child_by_index;

    /// Looks up a child element by the given name.
    ///
    /// This virtual method has a default implementation that uses `gst.Object`
    /// together with `gst.Object.getName`. If the interface is to be used with
    /// `GObjects`, this methods needs to be overridden.
    extern fn gst_child_proxy_get_child_by_name(p_parent: *ChildProxy, p_name: [*:0]const u8) ?*gobject.Object;
    pub const getChildByName = gst_child_proxy_get_child_by_name;

    /// Looks up a child element by the given full-path name.
    ///
    /// Similar to `gst.ChildProxy.getChildByName`, this method
    /// searches and returns a child given a name. The difference is that
    /// this method allows a hierarchical path in the form of
    /// child1::child2::child3. In the later example this method would
    /// return a reference to child3, if found. The name should be made of
    /// element names only and should not contain any property names.
    extern fn gst_child_proxy_get_child_by_name_recurse(p_child_proxy: *ChildProxy, p_name: [*:0]const u8) ?*gobject.Object;
    pub const getChildByNameRecurse = gst_child_proxy_get_child_by_name_recurse;

    /// Gets the number of child objects this parent contains.
    extern fn gst_child_proxy_get_children_count(p_parent: *ChildProxy) c_uint;
    pub const getChildrenCount = gst_child_proxy_get_children_count;

    /// Gets a single property using the GstChildProxy mechanism.
    /// You are responsible for freeing it by calling `gobject.Value.unset`
    extern fn gst_child_proxy_get_property(p_object: *ChildProxy, p_name: [*:0]const u8, p_value: *gobject.Value) void;
    pub const getProperty = gst_child_proxy_get_property;

    /// Gets properties of the parent object and its children.
    extern fn gst_child_proxy_get_valist(p_object: *ChildProxy, p_first_property_name: [*:0]const u8, p_var_args: std.builtin.VaList) void;
    pub const getValist = gst_child_proxy_get_valist;

    /// Looks up which object and `gobject.ParamSpec` would be effected by the given `name`.
    extern fn gst_child_proxy_lookup(p_object: *ChildProxy, p_name: [*:0]const u8, p_target: ?**gobject.Object, p_pspec: ?**gobject.ParamSpec) c_int;
    pub const lookup = gst_child_proxy_lookup;

    /// Sets properties of the parent object and its children.
    extern fn gst_child_proxy_set(p_object: *ChildProxy, p_first_property_name: [*:0]const u8, ...) void;
    pub const set = gst_child_proxy_set;

    /// Sets a single property using the GstChildProxy mechanism.
    extern fn gst_child_proxy_set_property(p_object: *ChildProxy, p_name: [*:0]const u8, p_value: *const gobject.Value) void;
    pub const setProperty = gst_child_proxy_set_property;

    /// Sets properties of the parent object and its children.
    extern fn gst_child_proxy_set_valist(p_object: *ChildProxy, p_first_property_name: [*:0]const u8, p_var_args: std.builtin.VaList) void;
    pub const setValist = gst_child_proxy_set_valist;

    extern fn gst_child_proxy_get_type() usize;
    pub const getGObjectType = gst_child_proxy_get_type;

    extern fn g_object_ref(p_self: *gst.ChildProxy) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.ChildProxy) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *ChildProxy, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// This interface offers methods to query and manipulate parameter preset sets.
/// A preset is a bunch of property settings, together with meta data and a name.
/// The name of a preset serves as key for subsequent method calls to manipulate
/// single presets.
/// All instances of one type will share the list of presets. The list is created
/// on demand, if presets are not used, the list is not created.
///
/// The interface comes with a default implementation that serves most plugins.
/// Wrapper plugins will override most methods to implement support for the
/// native preset format of those wrapped plugins.
/// One method that is useful to be overridden is `gst.Preset.getPropertyNames`.
/// With that one can control which properties are saved and in which order.
/// When implementing support for read-only presets, one should set the vmethods
/// for `gst.Preset.savePreset` and `gst.Preset.deletePreset` to `NULL`.
/// Applications can use `gst.Preset.isEditable` to check for that.
///
/// The default implementation supports presets located in a system directory,
/// application specific directory and in the users home directory. When getting
/// a list of presets individual presets are read and overlaid in 1) system,
/// 2) application and 3) user order. Whenever an earlier entry is newer, the
/// later entries will be updated. Since 1.8 you can also provide extra paths
/// where to find presets through the GST_PRESET_PATH environment variable.
/// Presets found in those paths will be considered as "app presets".
pub const Preset = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gst.PresetInterface;
    pub const virtual_methods = struct {
        /// Delete the given preset.
        pub const delete_preset = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) c_int {
                return gobject.ext.as(Preset.Iface, p_class).f_delete_preset.?(gobject.ext.as(Preset, p_preset), p_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) callconv(.c) c_int) void {
                gobject.ext.as(Preset.Iface, p_class).f_delete_preset = @ptrCast(p_implementation);
            }
        };

        /// Gets the `value` for an existing meta data `tag`. Meta data `tag` names can be
        /// something like e.g. "comment". Returned values need to be released when done.
        pub const get_meta = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: *[*:0]u8) c_int {
                return gobject.ext.as(Preset.Iface, p_class).f_get_meta.?(gobject.ext.as(Preset, p_preset), p_name, p_tag, p_value);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: *[*:0]u8) callconv(.c) c_int) void {
                gobject.ext.as(Preset.Iface, p_class).f_get_meta = @ptrCast(p_implementation);
            }
        };

        /// Get a copy of preset names as a `NULL` terminated string array.
        pub const get_preset_names = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) [*][*:0]u8 {
                return gobject.ext.as(Preset.Iface, p_class).f_get_preset_names.?(gobject.ext.as(Preset, p_preset));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) [*][*:0]u8) void {
                gobject.ext.as(Preset.Iface, p_class).f_get_preset_names = @ptrCast(p_implementation);
            }
        };

        /// Get a the names of the GObject properties that can be used for presets.
        pub const get_property_names = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) [*][*:0]u8 {
                return gobject.ext.as(Preset.Iface, p_class).f_get_property_names.?(gobject.ext.as(Preset, p_preset));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) [*][*:0]u8) void {
                gobject.ext.as(Preset.Iface, p_class).f_get_property_names = @ptrCast(p_implementation);
            }
        };

        /// Load the given preset.
        pub const load_preset = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) c_int {
                return gobject.ext.as(Preset.Iface, p_class).f_load_preset.?(gobject.ext.as(Preset, p_preset), p_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) callconv(.c) c_int) void {
                gobject.ext.as(Preset.Iface, p_class).f_load_preset = @ptrCast(p_implementation);
            }
        };

        /// Renames a preset. If there is already a preset by the `new_name` it will be
        /// overwritten.
        pub const rename_preset = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_old_name: [*:0]const u8, p_new_name: [*:0]const u8) c_int {
                return gobject.ext.as(Preset.Iface, p_class).f_rename_preset.?(gobject.ext.as(Preset, p_preset), p_old_name, p_new_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_old_name: [*:0]const u8, p_new_name: [*:0]const u8) callconv(.c) c_int) void {
                gobject.ext.as(Preset.Iface, p_class).f_rename_preset = @ptrCast(p_implementation);
            }
        };

        /// Save the current object settings as a preset under the given name. If there
        /// is already a preset by this `name` it will be overwritten.
        pub const save_preset = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) c_int {
                return gobject.ext.as(Preset.Iface, p_class).f_save_preset.?(gobject.ext.as(Preset, p_preset), p_name);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8) callconv(.c) c_int) void {
                gobject.ext.as(Preset.Iface, p_class).f_save_preset = @ptrCast(p_implementation);
            }
        };

        /// Sets a new `value` for an existing meta data item or adds a new item. Meta
        /// data `tag` names can be something like e.g. "comment". Supplying `NULL` for the
        /// `value` will unset an existing value.
        pub const set_meta = struct {
            pub fn call(p_class: anytype, p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: ?[*:0]const u8) c_int {
                return gobject.ext.as(Preset.Iface, p_class).f_set_meta.?(gobject.ext.as(Preset, p_preset), p_name, p_tag, p_value);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_preset: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: ?[*:0]const u8) callconv(.c) c_int) void {
                gobject.ext.as(Preset.Iface, p_class).f_set_meta = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// Gets the directory for application specific presets if set by the
    /// application.
    extern fn gst_preset_get_app_dir() ?[*:0]const u8;
    pub const getAppDir = gst_preset_get_app_dir;

    /// Sets an extra directory as an absolute path that should be considered when
    /// looking for presets. Any presets in the application dir will shadow the
    /// system presets.
    extern fn gst_preset_set_app_dir(p_app_dir: [*:0]const u8) c_int;
    pub const setAppDir = gst_preset_set_app_dir;

    /// Delete the given preset.
    extern fn gst_preset_delete_preset(p_preset: *Preset, p_name: [*:0]const u8) c_int;
    pub const deletePreset = gst_preset_delete_preset;

    /// Gets the `value` for an existing meta data `tag`. Meta data `tag` names can be
    /// something like e.g. "comment". Returned values need to be released when done.
    extern fn gst_preset_get_meta(p_preset: *Preset, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: *[*:0]u8) c_int;
    pub const getMeta = gst_preset_get_meta;

    /// Get a copy of preset names as a `NULL` terminated string array.
    extern fn gst_preset_get_preset_names(p_preset: *Preset) [*][*:0]u8;
    pub const getPresetNames = gst_preset_get_preset_names;

    /// Get a the names of the GObject properties that can be used for presets.
    extern fn gst_preset_get_property_names(p_preset: *Preset) [*][*:0]u8;
    pub const getPropertyNames = gst_preset_get_property_names;

    /// Check if one can add new presets, change existing ones and remove presets.
    extern fn gst_preset_is_editable(p_preset: *Preset) c_int;
    pub const isEditable = gst_preset_is_editable;

    /// Load the given preset.
    extern fn gst_preset_load_preset(p_preset: *Preset, p_name: [*:0]const u8) c_int;
    pub const loadPreset = gst_preset_load_preset;

    /// Renames a preset. If there is already a preset by the `new_name` it will be
    /// overwritten.
    extern fn gst_preset_rename_preset(p_preset: *Preset, p_old_name: [*:0]const u8, p_new_name: [*:0]const u8) c_int;
    pub const renamePreset = gst_preset_rename_preset;

    /// Save the current object settings as a preset under the given name. If there
    /// is already a preset by this `name` it will be overwritten.
    extern fn gst_preset_save_preset(p_preset: *Preset, p_name: [*:0]const u8) c_int;
    pub const savePreset = gst_preset_save_preset;

    /// Sets a new `value` for an existing meta data item or adds a new item. Meta
    /// data `tag` names can be something like e.g. "comment". Supplying `NULL` for the
    /// `value` will unset an existing value.
    extern fn gst_preset_set_meta(p_preset: *Preset, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: ?[*:0]const u8) c_int;
    pub const setMeta = gst_preset_set_meta;

    extern fn gst_preset_get_type() usize;
    pub const getGObjectType = gst_preset_get_type;

    extern fn g_object_ref(p_self: *gst.Preset) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.Preset) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *Preset, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Element interface that allows setting of media metadata.
///
/// Elements that support changing a stream's metadata will implement this
/// interface. Examples of such elements are 'vorbisenc', 'theoraenc' and
/// 'id3v2mux'.
///
/// If you just want to retrieve metadata in your application then all you
/// need to do is watch for tag messages on your pipeline's bus. This
/// interface is only for setting metadata, not for extracting it. To set tags
/// from the application, find tagsetter elements and set tags using e.g.
/// `gst.TagSetter.mergeTags` or `gst.TagSetter.addTags`. Also consider
/// setting the `gst.TagMergeMode` that is used for tag events that arrive at the
/// tagsetter element (default mode is to keep existing tags).
/// The application should do that before the element goes to `GST_STATE_PAUSED`.
///
/// Elements implementing the `gst.TagSetter` interface often have to merge
/// any tags received from upstream and the tags set by the application via
/// the interface. This can be done like this:
///
/// ```
/// GstTagMergeMode merge_mode;
/// const GstTagList *application_tags;
/// const GstTagList *event_tags;
/// GstTagSetter *tagsetter;
/// GstTagList *result;
///
/// tagsetter = GST_TAG_SETTER (element);
///
/// merge_mode = gst_tag_setter_get_tag_merge_mode (tagsetter);
/// application_tags = gst_tag_setter_get_tag_list (tagsetter);
/// event_tags = (const GstTagList *) element->event_tags;
///
/// GST_LOG_OBJECT (tagsetter, "merging tags, merge mode = `d`", merge_mode);
/// GST_LOG_OBJECT (tagsetter, "event tags: %" GST_PTR_FORMAT, event_tags);
/// GST_LOG_OBJECT (tagsetter, "set   tags: %" GST_PTR_FORMAT, application_tags);
///
/// result = gst_tag_list_merge (application_tags, event_tags, merge_mode);
///
/// GST_LOG_OBJECT (tagsetter, "final tags: %" GST_PTR_FORMAT, result);
/// ```
pub const TagSetter = opaque {
    pub const Prerequisites = [_]type{gst.Element};
    pub const Iface = gst.TagSetterInterface;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Adds the given tag / value pairs on the setter using the given merge mode.
    /// The list must be terminated with `NULL`.
    extern fn gst_tag_setter_add_tag_valist(p_setter: *TagSetter, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, p_var_args: std.builtin.VaList) void;
    pub const addTagValist = gst_tag_setter_add_tag_valist;

    /// Adds the given tag / GValue pairs on the setter using the given merge mode.
    /// The list must be terminated with `NULL`.
    extern fn gst_tag_setter_add_tag_valist_values(p_setter: *TagSetter, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, p_var_args: std.builtin.VaList) void;
    pub const addTagValistValues = gst_tag_setter_add_tag_valist_values;

    /// Adds the given tag / GValue pair on the setter using the given merge mode.
    extern fn gst_tag_setter_add_tag_value(p_setter: *TagSetter, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, p_value: *const gobject.Value) void;
    pub const addTagValue = gst_tag_setter_add_tag_value;

    /// Adds the given tag / GValue pairs on the setter using the given merge mode.
    /// The list must be terminated with `NULL`.
    extern fn gst_tag_setter_add_tag_values(p_setter: *TagSetter, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, ...) void;
    pub const addTagValues = gst_tag_setter_add_tag_values;

    /// Adds the given tag / value pairs on the setter using the given merge mode.
    /// The list must be terminated with `NULL`.
    extern fn gst_tag_setter_add_tags(p_setter: *TagSetter, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, ...) void;
    pub const addTags = gst_tag_setter_add_tags;

    /// Returns the current list of tags the setter uses.  The list should not be
    /// modified or freed.
    ///
    /// This function is not thread-safe.
    extern fn gst_tag_setter_get_tag_list(p_setter: *TagSetter) ?*const gst.TagList;
    pub const getTagList = gst_tag_setter_get_tag_list;

    /// Queries the mode by which tags inside the setter are overwritten by tags
    /// from events
    extern fn gst_tag_setter_get_tag_merge_mode(p_setter: *TagSetter) gst.TagMergeMode;
    pub const getTagMergeMode = gst_tag_setter_get_tag_merge_mode;

    /// Merges the given list into the setter's list using the given mode.
    extern fn gst_tag_setter_merge_tags(p_setter: *TagSetter, p_list: *const gst.TagList, p_mode: gst.TagMergeMode) void;
    pub const mergeTags = gst_tag_setter_merge_tags;

    /// Reset the internal taglist. Elements should call this from within the
    /// state-change handler.
    extern fn gst_tag_setter_reset_tags(p_setter: *TagSetter) void;
    pub const resetTags = gst_tag_setter_reset_tags;

    /// Sets the given merge mode that is used for adding tags from events to tags
    /// specified by this interface. The default is `GST_TAG_MERGE_KEEP`, which keeps
    /// the tags set with this interface and discards tags from events.
    extern fn gst_tag_setter_set_tag_merge_mode(p_setter: *TagSetter, p_mode: gst.TagMergeMode) void;
    pub const setTagMergeMode = gst_tag_setter_set_tag_merge_mode;

    extern fn gst_tag_setter_get_type() usize;
    pub const getGObjectType = gst_tag_setter_get_type;

    extern fn g_object_ref(p_self: *gst.TagSetter) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.TagSetter) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *TagSetter, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Element interface that allows setting of the TOC.
///
/// Elements that support some kind of chapters or editions (or tracks like in
/// the FLAC cue sheet) will implement this interface.
///
/// If you just want to retrieve the TOC in your application then all you
/// need to do is watch for TOC messages on your pipeline's bus (or you can
/// perform TOC query). This interface is only for setting TOC data, not for
/// extracting it. To set TOC from the application, find proper tocsetter element
/// and set TOC using `gst.TocSetter.setToc`.
///
/// Elements implementing the `gst.TocSetter` interface can extend existing TOC
/// by getting extend UID for that (you can use `gst.Toc.findEntry` to retrieve it)
/// with any TOC entries received from downstream.
pub const TocSetter = opaque {
    pub const Prerequisites = [_]type{gst.Element};
    pub const Iface = gst.TocSetterInterface;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Return current TOC the setter uses. The TOC should not be
    /// modified without making it writable first.
    extern fn gst_toc_setter_get_toc(p_setter: *TocSetter) ?*gst.Toc;
    pub const getToc = gst_toc_setter_get_toc;

    /// Reset the internal TOC. Elements should call this from within the
    /// state-change handler.
    extern fn gst_toc_setter_reset(p_setter: *TocSetter) void;
    pub const reset = gst_toc_setter_reset;

    /// Set the given TOC on the setter. Previously set TOC will be
    /// unreffed before setting a new one.
    extern fn gst_toc_setter_set_toc(p_setter: *TocSetter, p_toc: ?*gst.Toc) void;
    pub const setToc = gst_toc_setter_set_toc;

    extern fn gst_toc_setter_get_type() usize;
    pub const getGObjectType = gst_toc_setter_get_type;

    extern fn g_object_ref(p_self: *gst.TocSetter) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.TocSetter) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *TocSetter, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.URIHandler` is an interface that is implemented by Source and Sink
/// `gst.Element` to unify handling of URI.
///
/// An application can use the following functions to quickly get an element
/// that handles the given URI for reading or writing
/// (`gst.Element.makeFromUri`).
///
/// Source and Sink plugins should implement this interface when possible.
pub const URIHandler = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gst.URIHandlerInterface;
    pub const virtual_methods = struct {
        /// Gets the currently handled URI.
        pub const get_uri = struct {
            pub fn call(p_class: anytype, p_handler: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) ?[*:0]u8 {
                return gobject.ext.as(URIHandler.Iface, p_class).f_get_uri.?(gobject.ext.as(URIHandler, p_handler));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_handler: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) ?[*:0]u8) void {
                gobject.ext.as(URIHandler.Iface, p_class).f_get_uri = @ptrCast(p_implementation);
            }
        };

        /// Tries to set the URI of the given handler.
        pub const set_uri = struct {
            pub fn call(p_class: anytype, p_handler: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_uri: [*:0]const u8, p_error: ?*?*glib.Error) c_int {
                return gobject.ext.as(URIHandler.Iface, p_class).f_set_uri.?(gobject.ext.as(URIHandler, p_handler), p_uri, p_error);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_handler: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_uri: [*:0]const u8, p_error: ?*?*glib.Error) callconv(.c) c_int) void {
                gobject.ext.as(URIHandler.Iface, p_class).f_set_uri = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// Gets the list of protocols supported by `handler`. This list may not be
    /// modified.
    extern fn gst_uri_handler_get_protocols(p_handler: *URIHandler) ?[*]const [*:0]const u8;
    pub const getProtocols = gst_uri_handler_get_protocols;

    /// Gets the currently handled URI.
    extern fn gst_uri_handler_get_uri(p_handler: *URIHandler) ?[*:0]u8;
    pub const getUri = gst_uri_handler_get_uri;

    /// Gets the type of the given URI handler
    extern fn gst_uri_handler_get_uri_type(p_handler: *URIHandler) gst.URIType;
    pub const getUriType = gst_uri_handler_get_uri_type;

    /// Tries to set the URI of the given handler.
    extern fn gst_uri_handler_set_uri(p_handler: *URIHandler, p_uri: [*:0]const u8, p_error: ?*?*glib.Error) c_int;
    pub const setUri = gst_uri_handler_set_uri;

    extern fn gst_uri_handler_get_type() usize;
    pub const getGObjectType = gst_uri_handler_get_type;

    extern fn g_object_ref(p_self: *gst.URIHandler) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gst.URIHandler) void;
    pub const unref = g_object_unref;

    pub fn as(p_instance: *URIHandler, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Parameters to control the allocation of memory
pub const AllocationParams = extern struct {
    /// flags to control allocation
    f_flags: gst.MemoryFlags,
    /// the desired alignment of the memory
    f_align: usize,
    /// the desired prefix
    f_prefix: usize,
    /// the desired padding
    f_padding: usize,
    f__gst_reserved: [4]*anyopaque,

    /// Create a new `gst.AllocationParams` on the heap.  This function is for
    /// use in GStreamer language bindings.  In your own code, you can just
    /// declare a `gst.AllocationParams` on the stack or in a struct, and
    /// call `gst.AllocationParams.init` to initialize it.
    ///
    /// You do not need to call `gst.AllocationParams.init` on the instance
    /// returned by this function.
    extern fn gst_allocation_params_new() *gst.AllocationParams;
    pub const new = gst_allocation_params_new;

    /// Create a copy of `params`.
    extern fn gst_allocation_params_copy(p_params: ?*const AllocationParams) ?*gst.AllocationParams;
    pub const copy = gst_allocation_params_copy;

    /// Free `params`
    extern fn gst_allocation_params_free(p_params: *AllocationParams) void;
    pub const free = gst_allocation_params_free;

    /// Initialize `params` to its default values
    extern fn gst_allocation_params_init(p_params: *AllocationParams) void;
    pub const init = gst_allocation_params_init;

    extern fn gst_allocation_params_get_type() usize;
    pub const getGObjectType = gst_allocation_params_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.Allocator` is used to create new memory.
pub const AllocatorClass = extern struct {
    pub const Instance = gst.Allocator;

    /// Object parent class
    f_object_class: gst.ObjectClass,
    /// implementation that acquires memory
    f_alloc: ?*const fn (p_allocator: ?*gst.Allocator, p_size: usize, p_params: ?*gst.AllocationParams) callconv(.c) ?*gst.Memory,
    /// implementation that releases memory
    f_free: ?*const fn (p_allocator: *gst.Allocator, p_memory: *gst.Memory) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *AllocatorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const AllocatorPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.AtomicQueue` object implements a queue that can be used from multiple
/// threads without performing any blocking operations.
pub const AtomicQueue = opaque {
    /// Create a new atomic queue instance. `initial_size` will be rounded up to the
    /// nearest power of 2 and used as the initial size of the queue.
    extern fn gst_atomic_queue_new(p_initial_size: c_uint) *gst.AtomicQueue;
    pub const new = gst_atomic_queue_new;

    /// Get the amount of items in the queue.
    extern fn gst_atomic_queue_length(p_queue: *AtomicQueue) c_uint;
    pub const length = gst_atomic_queue_length;

    /// Peek the head element of the queue without removing it from the queue.
    extern fn gst_atomic_queue_peek(p_queue: *AtomicQueue) ?*anyopaque;
    pub const peek = gst_atomic_queue_peek;

    /// Get the head element of the queue.
    extern fn gst_atomic_queue_pop(p_queue: *AtomicQueue) ?*anyopaque;
    pub const pop = gst_atomic_queue_pop;

    /// Append `data` to the tail of the queue.
    extern fn gst_atomic_queue_push(p_queue: *AtomicQueue, p_data: ?*anyopaque) void;
    pub const push = gst_atomic_queue_push;

    /// Increase the refcount of `queue`.
    extern fn gst_atomic_queue_ref(p_queue: *AtomicQueue) void;
    pub const ref = gst_atomic_queue_ref;

    /// Unref `queue` and free the memory when the refcount reaches 0.
    extern fn gst_atomic_queue_unref(p_queue: *AtomicQueue) void;
    pub const unref = gst_atomic_queue_unref;

    extern fn gst_atomic_queue_get_type() usize;
    pub const getGObjectType = gst_atomic_queue_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Subclasses can override `gst.BinClass.signals.add_element` and `gst.BinClass.signals.remove_element`
/// to update the list of children in the bin.
///
/// The `gst.BinClass.signals.handle_message` method can be overridden to implement custom
/// message handling.
///
/// `gst.BinClass.signals.deep_element_added` will be called when a new element has been
/// added to any bin inside this bin, so it will also be called if a new child
/// was added to a sub-bin of this bin. `gst.Bin` implementations that override
/// this message should chain up to the parent class implementation so the
/// `gst.Bin.signals.deep`-element-added signal is emitted on all parents.
pub const BinClass = extern struct {
    pub const Instance = gst.Bin;

    /// bin parent class
    f_parent_class: gst.ElementClass,
    f_pool: ?*glib.ThreadPool,
    f_element_added: ?*const fn (p_bin: *gst.Bin, p_child: *gst.Element) callconv(.c) void,
    f_element_removed: ?*const fn (p_bin: *gst.Bin, p_child: *gst.Element) callconv(.c) void,
    f_add_element: ?*const fn (p_bin: *gst.Bin, p_element: *gst.Element) callconv(.c) c_int,
    f_remove_element: ?*const fn (p_bin: *gst.Bin, p_element: *gst.Element) callconv(.c) c_int,
    f_handle_message: ?*const fn (p_bin: *gst.Bin, p_message: *gst.Message) callconv(.c) void,
    f_do_latency: ?*const fn (p_bin: *gst.Bin) callconv(.c) c_int,
    f_deep_element_added: ?*const fn (p_bin: *gst.Bin, p_sub_bin: *gst.Bin, p_child: *gst.Element) callconv(.c) void,
    f_deep_element_removed: ?*const fn (p_bin: *gst.Bin, p_sub_bin: *gst.Bin, p_child: *gst.Element) callconv(.c) void,
    f__gst_reserved: [2]*anyopaque,

    pub fn as(p_instance: *BinClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const BinPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Buffers are the basic unit of data transfer in GStreamer. They contain the
/// timing and offset along with other arbitrary metadata that is associated
/// with the `gst.Memory` blocks that the buffer contains.
///
/// Buffers are usually created with `gst.Buffer.new`. After a buffer has been
/// created one will typically allocate memory for it and add it to the buffer.
/// The following example creates a buffer that can hold a given video frame
/// with a given width, height and bits per plane.
///
/// ``` C
///   GstBuffer *buffer;
///   GstMemory *memory;
///   gint size, width, height, bpp;
///   ...
///   size = width * height * bpp;
///   buffer = gst_buffer_new ();
///   memory = gst_allocator_alloc (NULL, size, NULL);
///   gst_buffer_insert_memory (buffer, -1, memory);
///   ...
/// ```
///
/// Alternatively, use `gst.Buffer.newAllocate` to create a buffer with
/// preallocated data of a given size.
///
/// Buffers can contain a list of `gst.Memory` objects. You can retrieve how many
/// memory objects with `gst.Buffer.nMemory` and you can get a pointer
/// to memory with `gst.Buffer.peekMemory`
///
/// A buffer will usually have timestamps, and a duration, but neither of these
/// are guaranteed (they may be set to `GST_CLOCK_TIME_NONE`). Whenever a
/// meaningful value can be given for these, they should be set. The timestamps
/// and duration are measured in nanoseconds (they are `gst.ClockTime` values).
///
/// The buffer DTS refers to the timestamp when the buffer should be decoded and
/// is usually monotonically increasing. The buffer PTS refers to the timestamp when
/// the buffer content should be presented to the user and is not always
/// monotonically increasing.
///
/// A buffer can also have one or both of a start and an end offset. These are
/// media-type specific. For video buffers, the start offset will generally be
/// the frame number. For audio buffers, it will be the number of samples
/// produced so far. For compressed data, it could be the byte offset in a
/// source or destination file. Likewise, the end offset will be the offset of
/// the end of the buffer. These can only be meaningfully interpreted if you
/// know the media type of the buffer (the preceding CAPS event). Either or both
/// can be set to `GST_BUFFER_OFFSET_NONE`.
///
/// `gst.Buffer.ref` is used to increase the refcount of a buffer. This must be
/// done when you want to keep a handle to the buffer after pushing it to the
/// next element. The buffer refcount determines the writability of the buffer, a
/// buffer is only writable when the refcount is exactly 1, i.e. when the caller
/// has the only reference to the buffer.
///
/// To efficiently create a smaller buffer out of an existing one, you can
/// use `gst.Buffer.copyRegion`. This method tries to share the memory objects
/// between the two buffers.
///
/// If a plug-in wants to modify the buffer data or metadata in-place, it should
/// first obtain a buffer that is safe to modify by using
/// `gst_buffer_make_writable`. This function is optimized so that a copy will
/// only be made when it is necessary.
///
/// Several flags of the buffer can be set and unset with the
/// `GST_BUFFER_FLAG_SET` and `GST_BUFFER_FLAG_UNSET` macros. Use
/// `GST_BUFFER_FLAG_IS_SET` to test if a certain `gst.BufferFlags` flag is set.
///
/// Buffers can be efficiently merged into a larger buffer with
/// `gst.Buffer.append`. Copying of memory will only be done when absolutely
/// needed.
///
/// Arbitrary extra metadata can be set on a buffer with `gst.Buffer.addMeta`.
/// Metadata can be retrieved with `gst.Buffer.getMeta`. See also `gst.Meta`.
///
/// An element should either unref the buffer or push it out on a src pad
/// using `gst.Pad.push` (see `gst.Pad`).
///
/// Buffers are usually freed by unreffing them with `gst.Buffer.unref`. When
/// the refcount drops to 0, any memory and metadata pointed to by the buffer is
/// unreffed as well. Buffers allocated from a `gst.BufferPool` will be returned to
/// the pool when the refcount drops to 0.
///
/// The `gst.ParentBufferMeta` is a meta which can be attached to a `gst.Buffer`
/// to hold a reference to another buffer that is only released when the child
/// `gst.Buffer` is released.
///
/// Typically, `gst.ParentBufferMeta` is used when the child buffer is directly
/// using the `gst.Memory` of the parent buffer, and wants to prevent the parent
/// buffer from being returned to a buffer pool until the `gst.Memory` is available
/// for re-use. (Since: 1.6)
pub const Buffer = extern struct {
    /// the parent structure
    f_mini_object: gst.MiniObject,
    /// pointer to the pool owner of the buffer
    f_pool: ?*gst.BufferPool,
    /// presentation timestamp of the buffer, can be `GST_CLOCK_TIME_NONE` when the
    ///     pts is not known or relevant. The pts contains the timestamp when the
    ///     media should be presented to the user.
    f_pts: gst.ClockTime,
    /// decoding timestamp of the buffer, can be `GST_CLOCK_TIME_NONE` when the
    ///     dts is not known or relevant. The dts contains the timestamp when the
    ///     media should be processed.
    f_dts: gst.ClockTime,
    /// duration in time of the buffer data, can be `GST_CLOCK_TIME_NONE`
    ///     when the duration is not known or relevant.
    f_duration: gst.ClockTime,
    /// a media specific offset for the buffer data.
    ///     For video frames, this is the frame number of this buffer.
    ///     For audio samples, this is the offset of the first sample in this buffer.
    ///     For file data or compressed data this is the byte offset of the first
    ///       byte in this buffer.
    f_offset: u64,
    /// the last offset contained in this buffer. It has the same
    ///     format as `offset`.
    f_offset_end: u64,

    /// Gets the maximum amount of memory blocks that a buffer can hold. This is a
    /// compile time constant that can be queried with the function.
    ///
    /// When more memory blocks are added, existing memory blocks will be merged
    /// together to make room for the new block.
    extern fn gst_buffer_get_max_memory() c_uint;
    pub const getMaxMemory = gst_buffer_get_max_memory;

    /// Modifies a pointer to a `gst.Buffer` to point to a different `gst.Buffer`. The
    /// modification is done atomically (so this is useful for ensuring thread safety
    /// in some cases), and the reference counts are updated appropriately (the old
    /// buffer is unreffed, the new is reffed).
    ///
    /// Either `nbuf` or the `gst.Buffer` pointed to by `obuf` may be `NULL`.
    extern fn gst_buffer_replace(p_obuf: ?**gst.Buffer, p_nbuf: ?*gst.Buffer) c_int;
    pub const replace = gst_buffer_replace;

    /// Creates a newly allocated buffer without any data.
    extern fn gst_buffer_new() *gst.Buffer;
    pub const new = gst_buffer_new;

    /// Tries to create a newly allocated buffer with data of the given size and
    /// extra parameters from `allocator`. If the requested amount of memory can't be
    /// allocated, `NULL` will be returned. The allocated buffer memory is not cleared.
    ///
    /// When `allocator` is `NULL`, the default memory allocator will be used.
    ///
    /// Note that when `size` == 0, the buffer will not have memory associated with it.
    extern fn gst_buffer_new_allocate(p_allocator: ?*gst.Allocator, p_size: usize, p_params: ?*gst.AllocationParams) ?*gst.Buffer;
    pub const newAllocate = gst_buffer_new_allocate;

    /// Creates a new buffer of size `size` and fills it with a copy of `data`.
    extern fn gst_buffer_new_memdup(p_data: [*]const u8, p_size: usize) *gst.Buffer;
    pub const newMemdup = gst_buffer_new_memdup;

    /// Creates a new buffer that wraps the given `data`. The memory will be freed
    /// with `glib.free` and will be marked writable.
    extern fn gst_buffer_new_wrapped(p_data: [*]u8, p_size: usize) *gst.Buffer;
    pub const newWrapped = gst_buffer_new_wrapped;

    /// Creates a new `gst.Buffer` that wraps the given `bytes`. The data inside
    /// `bytes` cannot be `NULL` and the resulting buffer will be marked as read only.
    extern fn gst_buffer_new_wrapped_bytes(p_bytes: *glib.Bytes) *gst.Buffer;
    pub const newWrappedBytes = gst_buffer_new_wrapped_bytes;

    /// Allocates a new buffer that wraps the given memory. `data` must point to
    /// `maxsize` of memory, the wrapped buffer will have the region from `offset` and
    /// `size` visible.
    ///
    /// When the buffer is destroyed, `notify` will be called with `user_data`.
    ///
    /// The prefix/padding must be filled with 0 if `flags` contains
    /// `GST_MEMORY_FLAG_ZERO_PREFIXED` and `GST_MEMORY_FLAG_ZERO_PADDED` respectively.
    extern fn gst_buffer_new_wrapped_full(p_flags: gst.MemoryFlags, p_data: [*]u8, p_maxsize: usize, p_offset: usize, p_size: usize, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) *gst.Buffer;
    pub const newWrappedFull = gst_buffer_new_wrapped_full;

    /// Creates and adds a `gst.CustomMeta` for the desired `name`. `name` must have
    /// been successfully registered with `gst.metaRegisterCustom`.
    extern fn gst_buffer_add_custom_meta(p_buffer: *Buffer, p_name: [*:0]const u8) ?*gst.CustomMeta;
    pub const addCustomMeta = gst_buffer_add_custom_meta;

    /// Adds metadata for `info` to `buffer` using the parameters in `params`.
    extern fn gst_buffer_add_meta(p_buffer: *Buffer, p_info: *const gst.MetaInfo, p_params: ?*anyopaque) ?*gst.Meta;
    pub const addMeta = gst_buffer_add_meta;

    /// Adds a `gst.ParentBufferMeta` to `buffer` that holds a reference on
    /// `ref` until the buffer is freed.
    extern fn gst_buffer_add_parent_buffer_meta(p_buffer: *Buffer, p_ref: *gst.Buffer) ?*gst.ParentBufferMeta;
    pub const addParentBufferMeta = gst_buffer_add_parent_buffer_meta;

    /// Attaches protection metadata to a `gst.Buffer`.
    extern fn gst_buffer_add_protection_meta(p_buffer: *Buffer, p_info: *gst.Structure) *gst.ProtectionMeta;
    pub const addProtectionMeta = gst_buffer_add_protection_meta;

    /// Adds a `gst.ReferenceTimestampMeta` to `buffer` that holds a `timestamp` and
    /// optionally `duration` based on a specific timestamp `reference`. See the
    /// documentation of `gst.ReferenceTimestampMeta` for details.
    extern fn gst_buffer_add_reference_timestamp_meta(p_buffer: *Buffer, p_reference: *gst.Caps, p_timestamp: gst.ClockTime, p_duration: gst.ClockTime) ?*gst.ReferenceTimestampMeta;
    pub const addReferenceTimestampMeta = gst_buffer_add_reference_timestamp_meta;

    /// Appends all the memory from `buf2` to `buf1`. The result buffer will contain a
    /// concatenation of the memory of `buf1` and `buf2`.
    extern fn gst_buffer_append(p_buf1: *Buffer, p_buf2: *gst.Buffer) *gst.Buffer;
    pub const append = gst_buffer_append;

    /// Appends the memory block `mem` to `buffer`. This function takes
    /// ownership of `mem` and thus doesn't increase its refcount.
    ///
    /// This function is identical to `gst.Buffer.insertMemory` with an index of -1.
    /// See `gst.Buffer.insertMemory` for more details.
    extern fn gst_buffer_append_memory(p_buffer: *Buffer, p_mem: *gst.Memory) void;
    pub const appendMemory = gst_buffer_append_memory;

    /// Appends `size` bytes at `offset` from `buf2` to `buf1`. The result buffer will
    /// contain a concatenation of the memory of `buf1` and the requested region of
    /// `buf2`.
    extern fn gst_buffer_append_region(p_buf1: *Buffer, p_buf2: *gst.Buffer, p_offset: isize, p_size: isize) *gst.Buffer;
    pub const appendRegion = gst_buffer_append_region;

    /// Creates a copy of the given buffer. This will only copy the buffer's
    /// data to a newly allocated memory if needed (if the type of memory
    /// requires it), otherwise the underlying data is just referenced.
    /// Check `gst.Buffer.copyDeep` if you want to force the data
    /// to be copied to newly allocated memory.
    extern fn gst_buffer_copy(p_buf: *const Buffer) ?*gst.Buffer;
    pub const copy = gst_buffer_copy;

    /// Creates a copy of the given buffer. This will make a newly allocated
    /// copy of the data the source buffer contains.
    extern fn gst_buffer_copy_deep(p_buf: *const Buffer) ?*gst.Buffer;
    pub const copyDeep = gst_buffer_copy_deep;

    /// Copies the information from `src` into `dest`.
    ///
    /// If `dest` already contains memory and `flags` contains GST_BUFFER_COPY_MEMORY,
    /// the memory from `src` will be appended to `dest`.
    ///
    /// `flags` indicate which fields will be copied.
    extern fn gst_buffer_copy_into(p_dest: *Buffer, p_src: *gst.Buffer, p_flags: gst.BufferCopyFlags, p_offset: usize, p_size: usize) c_int;
    pub const copyInto = gst_buffer_copy_into;

    /// Creates a sub-buffer from `parent` at `offset` and `size`.
    /// This sub-buffer uses the actual memory space of the parent buffer.
    /// This function will copy the offset and timestamp fields when the
    /// offset is 0. If not, they will be set to `GST_CLOCK_TIME_NONE` and
    /// `GST_BUFFER_OFFSET_NONE`.
    /// If `offset` equals 0 and `size` equals the total size of `buffer`, the
    /// duration and offset end fields are also copied. If not they will be set
    /// to `GST_CLOCK_TIME_NONE` and `GST_BUFFER_OFFSET_NONE`.
    extern fn gst_buffer_copy_region(p_parent: *Buffer, p_flags: gst.BufferCopyFlags, p_offset: usize, p_size: usize) ?*gst.Buffer;
    pub const copyRegion = gst_buffer_copy_region;

    /// Copies `size` bytes starting from `offset` in `buffer` to `dest`.
    extern fn gst_buffer_extract(p_buffer: *Buffer, p_offset: usize, p_dest: [*]u8, p_size: usize) usize;
    pub const extract = gst_buffer_extract;

    /// Extracts a copy of at most `size` bytes the data at `offset` into
    /// newly-allocated memory. `dest` must be freed using `glib.free` when done.
    extern fn gst_buffer_extract_dup(p_buffer: *Buffer, p_offset: usize, p_size: usize, p_dest: *[*]u8, p_dest_size: *usize) void;
    pub const extractDup = gst_buffer_extract_dup;

    /// Copies `size` bytes from `src` to `buffer` at `offset`.
    extern fn gst_buffer_fill(p_buffer: *Buffer, p_offset: usize, p_src: [*]const u8, p_size: usize) usize;
    pub const fill = gst_buffer_fill;

    /// Finds the memory blocks that span `size` bytes starting from `offset`
    /// in `buffer`.
    ///
    /// When this function returns `TRUE`, `idx` will contain the index of the first
    /// memory block where the byte for `offset` can be found and `length` contains the
    /// number of memory blocks containing the `size` remaining bytes. `skip` contains
    /// the number of bytes to skip in the memory block at `idx` to get to the byte
    /// for `offset`.
    ///
    /// `size` can be -1 to get all the memory blocks after `idx`.
    extern fn gst_buffer_find_memory(p_buffer: *Buffer, p_offset: usize, p_size: usize, p_idx: *c_uint, p_length: *c_uint, p_skip: *usize) c_int;
    pub const findMemory = gst_buffer_find_memory;

    /// Calls `func` with `user_data` for each meta in `buffer`.
    ///
    /// `func` can modify the passed meta pointer or its contents. The return value
    /// of `func` defines if this function returns or if the remaining metadata items
    /// in the buffer should be skipped.
    extern fn gst_buffer_foreach_meta(p_buffer: *Buffer, p_func: gst.BufferForeachMetaFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreachMeta = gst_buffer_foreach_meta;

    /// Gets all the memory blocks in `buffer`. The memory blocks will be merged
    /// into one large `gst.Memory`.
    extern fn gst_buffer_get_all_memory(p_buffer: *Buffer) ?*gst.Memory;
    pub const getAllMemory = gst_buffer_get_all_memory;

    /// Finds the first `gst.CustomMeta` on `buffer` for the desired `name`.
    extern fn gst_buffer_get_custom_meta(p_buffer: *Buffer, p_name: [*:0]const u8) ?*gst.CustomMeta;
    pub const getCustomMeta = gst_buffer_get_custom_meta;

    /// Gets the `gst.BufferFlags` flags set on this buffer.
    extern fn gst_buffer_get_flags(p_buffer: *Buffer) gst.BufferFlags;
    pub const getFlags = gst_buffer_get_flags;

    /// Gets the memory block at index `idx` in `buffer`.
    extern fn gst_buffer_get_memory(p_buffer: *Buffer, p_idx: c_uint) ?*gst.Memory;
    pub const getMemory = gst_buffer_get_memory;

    /// Gets `length` memory blocks in `buffer` starting at `idx`. The memory blocks will
    /// be merged into one large `gst.Memory`.
    ///
    /// If `length` is -1, all memory starting from `idx` is merged.
    extern fn gst_buffer_get_memory_range(p_buffer: *Buffer, p_idx: c_uint, p_length: c_int) ?*gst.Memory;
    pub const getMemoryRange = gst_buffer_get_memory_range;

    /// Gets the metadata for `api` on buffer. When there is no such metadata, `NULL` is
    /// returned. If multiple metadata with the given `api` are attached to this
    /// buffer only the first one is returned.  To handle multiple metadata with a
    /// given API use `gst.Buffer.iterateMeta` or `gst.Buffer.foreachMeta` instead
    /// and check the `meta->info.api` member for the API type.
    extern fn gst_buffer_get_meta(p_buffer: *Buffer, p_api: usize) ?*gst.Meta;
    pub const getMeta = gst_buffer_get_meta;

    extern fn gst_buffer_get_n_meta(p_buffer: *Buffer, p_api_type: usize) c_uint;
    pub const getNMeta = gst_buffer_get_n_meta;

    /// Finds the first `gst.ReferenceTimestampMeta` on `buffer` that conforms to
    /// `reference`. Conformance is tested by checking if the meta's reference is a
    /// subset of `reference`.
    ///
    /// Buffers can contain multiple `gst.ReferenceTimestampMeta` metadata items.
    extern fn gst_buffer_get_reference_timestamp_meta(p_buffer: *Buffer, p_reference: ?*gst.Caps) ?*gst.ReferenceTimestampMeta;
    pub const getReferenceTimestampMeta = gst_buffer_get_reference_timestamp_meta;

    /// Gets the total size of the memory blocks in `buffer`.
    extern fn gst_buffer_get_size(p_buffer: *Buffer) usize;
    pub const getSize = gst_buffer_get_size;

    /// Gets the total size of the memory blocks in `buffer`.
    ///
    /// When not `NULL`, `offset` will contain the offset of the data in the
    /// first memory block in `buffer` and `maxsize` will contain the sum of
    /// the size and `offset` and the amount of extra padding on the last
    /// memory block.  `offset` and `maxsize` can be used to resize the
    /// buffer memory blocks with `gst.Buffer.resize`.
    extern fn gst_buffer_get_sizes(p_buffer: *Buffer, p_offset: ?*usize, p_maxsize: ?*usize) usize;
    pub const getSizes = gst_buffer_get_sizes;

    /// Gets the total size of `length` memory blocks stating from `idx` in `buffer`.
    ///
    /// When not `NULL`, `offset` will contain the offset of the data in the
    /// memory block in `buffer` at `idx` and `maxsize` will contain the sum of the size
    /// and `offset` and the amount of extra padding on the memory block at `idx` +
    /// `length` -1.
    /// `offset` and `maxsize` can be used to resize the buffer memory blocks with
    /// `gst.Buffer.resizeRange`.
    extern fn gst_buffer_get_sizes_range(p_buffer: *Buffer, p_idx: c_uint, p_length: c_int, p_offset: ?*usize, p_maxsize: ?*usize) usize;
    pub const getSizesRange = gst_buffer_get_sizes_range;

    /// Gives the status of a specific flag on a buffer.
    extern fn gst_buffer_has_flags(p_buffer: *Buffer, p_flags: gst.BufferFlags) c_int;
    pub const hasFlags = gst_buffer_has_flags;

    /// Inserts the memory block `mem` into `buffer` at `idx`. This function takes ownership
    /// of `mem` and thus doesn't increase its refcount.
    ///
    /// Only `gst.bufferGetMaxMemory` can be added to a buffer. If more memory is
    /// added, existing memory blocks will automatically be merged to make room for
    /// the new memory.
    extern fn gst_buffer_insert_memory(p_buffer: *Buffer, p_idx: c_int, p_mem: *gst.Memory) void;
    pub const insertMemory = gst_buffer_insert_memory;

    /// Checks if all memory blocks in `buffer` are writable.
    ///
    /// Note that this function does not check if `buffer` is writable, use
    /// `gst_buffer_is_writable` to check that if needed.
    extern fn gst_buffer_is_all_memory_writable(p_buffer: *Buffer) c_int;
    pub const isAllMemoryWritable = gst_buffer_is_all_memory_writable;

    /// Checks if `length` memory blocks in `buffer` starting from `idx` are writable.
    ///
    /// `length` can be -1 to check all the memory blocks after `idx`.
    ///
    /// Note that this function does not check if `buffer` is writable, use
    /// `gst_buffer_is_writable` to check that if needed.
    extern fn gst_buffer_is_memory_range_writable(p_buffer: *Buffer, p_idx: c_uint, p_length: c_int) c_int;
    pub const isMemoryRangeWritable = gst_buffer_is_memory_range_writable;

    /// Retrieves the next `gst.Meta` after `current`. If `state` points
    /// to `NULL`, the first metadata is returned.
    ///
    /// `state` will be updated with an opaque state pointer
    extern fn gst_buffer_iterate_meta(p_buffer: *Buffer, p_state: ?*anyopaque) ?*gst.Meta;
    pub const iterateMeta = gst_buffer_iterate_meta;

    /// Retrieves the next `gst.Meta` of type `meta_api_type` after the current one
    /// according to `state`. If `state` points to `NULL`, the first metadata of
    /// type `meta_api_type` is returned.
    ///
    /// `state` will be updated with an opaque state pointer
    extern fn gst_buffer_iterate_meta_filtered(p_buffer: *Buffer, p_state: ?*anyopaque, p_meta_api_type: usize) ?*gst.Meta;
    pub const iterateMetaFiltered = gst_buffer_iterate_meta_filtered;

    /// Fills `info` with the `gst.MapInfo` of all merged memory blocks in `buffer`.
    ///
    /// `flags` describe the desired access of the memory. When `flags` is
    /// `GST_MAP_WRITE`, `buffer` should be writable (as returned from
    /// `gst_buffer_is_writable`).
    ///
    /// When `buffer` is writable but the memory isn't, a writable copy will
    /// automatically be created and returned. The readonly copy of the
    /// buffer memory will then also be replaced with this writable copy.
    ///
    /// The memory in `info` should be unmapped with `gst.Buffer.unmap` after
    /// usage.
    extern fn gst_buffer_map(p_buffer: *Buffer, p_info: *gst.MapInfo, p_flags: gst.MapFlags) c_int;
    pub const map = gst_buffer_map;

    /// Fills `info` with the `gst.MapInfo` of `length` merged memory blocks
    /// starting at `idx` in `buffer`. When `length` is -1, all memory blocks starting
    /// from `idx` are merged and mapped.
    ///
    /// `flags` describe the desired access of the memory. When `flags` is
    /// `GST_MAP_WRITE`, `buffer` should be writable (as returned from
    /// `gst_buffer_is_writable`).
    ///
    /// When `buffer` is writable but the memory isn't, a writable copy will
    /// automatically be created and returned. The readonly copy of the buffer memory
    /// will then also be replaced with this writable copy.
    ///
    /// The memory in `info` should be unmapped with `gst.Buffer.unmap` after usage.
    extern fn gst_buffer_map_range(p_buffer: *Buffer, p_idx: c_uint, p_length: c_int, p_info: *gst.MapInfo, p_flags: gst.MapFlags) c_int;
    pub const mapRange = gst_buffer_map_range;

    /// Compares `size` bytes starting from `offset` in `buffer` with the memory in `mem`.
    extern fn gst_buffer_memcmp(p_buffer: *Buffer, p_offset: usize, p_mem: [*]const u8, p_size: usize) c_int;
    pub const memcmp = gst_buffer_memcmp;

    /// Fills `buf` with `size` bytes with `val` starting from `offset`.
    extern fn gst_buffer_memset(p_buffer: *Buffer, p_offset: usize, p_val: u8, p_size: usize) usize;
    pub const memset = gst_buffer_memset;

    /// Gets the amount of memory blocks that this buffer has. This amount is never
    /// larger than what `gst.bufferGetMaxMemory` returns.
    extern fn gst_buffer_n_memory(p_buffer: *Buffer) c_uint;
    pub const nMemory = gst_buffer_n_memory;

    /// Gets the memory block at `idx` in `buffer`. The memory block stays valid until
    /// the memory block in `buffer` is removed, replaced or merged, typically with
    /// any call that modifies the memory in `buffer`.
    extern fn gst_buffer_peek_memory(p_buffer: *Buffer, p_idx: c_uint) ?*gst.Memory;
    pub const peekMemory = gst_buffer_peek_memory;

    /// Prepends the memory block `mem` to `buffer`. This function takes
    /// ownership of `mem` and thus doesn't increase its refcount.
    ///
    /// This function is identical to `gst.Buffer.insertMemory` with an index of 0.
    /// See `gst.Buffer.insertMemory` for more details.
    extern fn gst_buffer_prepend_memory(p_buffer: *Buffer, p_mem: *gst.Memory) void;
    pub const prependMemory = gst_buffer_prepend_memory;

    /// Increases the refcount of the given buffer by one.
    ///
    /// Note that the refcount affects the writability
    /// of `buf` and its metadata, see `gst_buffer_is_writable`.
    /// It is important to note that keeping additional references to
    /// GstBuffer instances can potentially increase the number
    /// of `memcpy` operations in a pipeline.
    extern fn gst_buffer_ref(p_buf: *Buffer) *gst.Buffer;
    pub const ref = gst_buffer_ref;

    /// Removes all the memory blocks in `buffer`.
    extern fn gst_buffer_remove_all_memory(p_buffer: *Buffer) void;
    pub const removeAllMemory = gst_buffer_remove_all_memory;

    /// Removes the memory block in `b` at index `i`.
    extern fn gst_buffer_remove_memory(p_buffer: *Buffer, p_idx: c_uint) void;
    pub const removeMemory = gst_buffer_remove_memory;

    /// Removes `length` memory blocks in `buffer` starting from `idx`.
    ///
    /// `length` can be -1, in which case all memory starting from `idx` is removed.
    extern fn gst_buffer_remove_memory_range(p_buffer: *Buffer, p_idx: c_uint, p_length: c_int) void;
    pub const removeMemoryRange = gst_buffer_remove_memory_range;

    /// Removes the metadata for `meta` on `buffer`.
    extern fn gst_buffer_remove_meta(p_buffer: *Buffer, p_meta: *gst.Meta) c_int;
    pub const removeMeta = gst_buffer_remove_meta;

    /// Replaces all memory in `buffer` with `mem`.
    extern fn gst_buffer_replace_all_memory(p_buffer: *Buffer, p_mem: *gst.Memory) void;
    pub const replaceAllMemory = gst_buffer_replace_all_memory;

    /// Replaces the memory block at index `idx` in `buffer` with `mem`.
    extern fn gst_buffer_replace_memory(p_buffer: *Buffer, p_idx: c_uint, p_mem: *gst.Memory) void;
    pub const replaceMemory = gst_buffer_replace_memory;

    /// Replaces `length` memory blocks in `buffer` starting at `idx` with `mem`.
    ///
    /// If `length` is -1, all memory starting from `idx` will be removed and
    /// replaced with `mem`.
    ///
    /// `buffer` should be writable.
    extern fn gst_buffer_replace_memory_range(p_buffer: *Buffer, p_idx: c_uint, p_length: c_int, p_mem: *gst.Memory) void;
    pub const replaceMemoryRange = gst_buffer_replace_memory_range;

    /// Sets the offset and total size of the memory blocks in `buffer`.
    extern fn gst_buffer_resize(p_buffer: *Buffer, p_offset: isize, p_size: isize) void;
    pub const resize = gst_buffer_resize;

    /// Sets the total size of the `length` memory blocks starting at `idx` in
    /// `buffer`
    extern fn gst_buffer_resize_range(p_buffer: *Buffer, p_idx: c_uint, p_length: c_int, p_offset: isize, p_size: isize) c_int;
    pub const resizeRange = gst_buffer_resize_range;

    /// Sets one or more buffer flags on a buffer.
    extern fn gst_buffer_set_flags(p_buffer: *Buffer, p_flags: gst.BufferFlags) c_int;
    pub const setFlags = gst_buffer_set_flags;

    /// Sets the total size of the memory blocks in `buffer`.
    extern fn gst_buffer_set_size(p_buffer: *Buffer, p_size: isize) void;
    pub const setSize = gst_buffer_set_size;

    /// Releases the memory previously mapped with `gst.Buffer.map`.
    extern fn gst_buffer_unmap(p_buffer: *Buffer, p_info: *gst.MapInfo) void;
    pub const unmap = gst_buffer_unmap;

    /// Decreases the refcount of the buffer. If the refcount reaches 0, the buffer
    /// with the associated metadata and memory will be freed.
    extern fn gst_buffer_unref(p_buf: *Buffer) void;
    pub const unref = gst_buffer_unref;

    /// Clears one or more buffer flags.
    extern fn gst_buffer_unset_flags(p_buffer: *Buffer, p_flags: gst.BufferFlags) c_int;
    pub const unsetFlags = gst_buffer_unset_flags;

    extern fn gst_buffer_get_type() usize;
    pub const getGObjectType = gst_buffer_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Buffer lists are an object containing a list of buffers.
///
/// Buffer lists are created with `gst.BufferList.new` and filled with data
/// using `gst.BufferList.insert`.
///
/// Buffer lists can be pushed on a srcpad with `gst.Pad.pushList`. This is
/// interesting when multiple buffers need to be pushed in one go because it
/// can reduce the amount of overhead for pushing each buffer individually.
pub const BufferList = opaque {
    /// Modifies a pointer to a `gst.BufferList` to point to a different
    /// `gst.BufferList`. The modification is done atomically (so this is useful for
    /// ensuring thread safety in some cases), and the reference counts are updated
    /// appropriately (the old buffer list is unreffed, the new is reffed).
    ///
    /// Either `new_list` or the `gst.BufferList` pointed to by `old_list` may be `NULL`.
    extern fn gst_buffer_list_replace(p_old_list: ?**gst.BufferList, p_new_list: ?*gst.BufferList) c_int;
    pub const replace = gst_buffer_list_replace;

    /// Modifies a pointer to a `gst.BufferList` to point to a different
    /// `gst.BufferList`. This function is similar to `gst.bufferListReplace` except
    /// that it takes ownership of `new_list`.
    extern fn gst_buffer_list_take(p_old_list: **gst.BufferList, p_new_list: ?*gst.BufferList) c_int;
    pub const take = gst_buffer_list_take;

    /// Creates a new, empty `gst.BufferList`.
    extern fn gst_buffer_list_new() *gst.BufferList;
    pub const new = gst_buffer_list_new;

    /// Creates a new, empty `gst.BufferList`. The list will have `size` space
    /// preallocated so that memory reallocations can be avoided.
    extern fn gst_buffer_list_new_sized(p_size: c_uint) *gst.BufferList;
    pub const newSized = gst_buffer_list_new_sized;

    /// Calculates the size of the data contained in `list` by adding the
    /// size of all buffers.
    extern fn gst_buffer_list_calculate_size(p_list: *BufferList) usize;
    pub const calculateSize = gst_buffer_list_calculate_size;

    /// Creates a shallow copy of the given buffer list. This will make a newly
    /// allocated copy of the source list with copies of buffer pointers. The
    /// refcount of buffers pointed to will be increased by one.
    extern fn gst_buffer_list_copy(p_list: *const BufferList) *gst.BufferList;
    pub const copy = gst_buffer_list_copy;

    /// Creates a copy of the given buffer list. This will make a newly allocated
    /// copy of the buffers that the source buffer list contains.
    extern fn gst_buffer_list_copy_deep(p_list: *const BufferList) *gst.BufferList;
    pub const copyDeep = gst_buffer_list_copy_deep;

    /// Calls `func` with `data` for each buffer in `list`.
    ///
    /// `func` can modify the passed buffer pointer or its contents. The return value
    /// of `func` defines if this function returns or if the remaining buffers in
    /// the list should be skipped.
    extern fn gst_buffer_list_foreach(p_list: *BufferList, p_func: gst.BufferListFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreach = gst_buffer_list_foreach;

    /// Gets the buffer at `idx`.
    ///
    /// You must make sure that `idx` does not exceed the number of
    /// buffers available.
    extern fn gst_buffer_list_get(p_list: *BufferList, p_idx: c_uint) *gst.Buffer;
    pub const get = gst_buffer_list_get;

    /// Gets the buffer at `idx`, ensuring it is a writable buffer.
    ///
    /// You must make sure that `idx` does not exceed the number of
    /// buffers available.
    extern fn gst_buffer_list_get_writable(p_list: *BufferList, p_idx: c_uint) *gst.Buffer;
    pub const getWritable = gst_buffer_list_get_writable;

    /// Inserts `buffer` at `idx` in `list`. Other buffers are moved to make room for
    /// this new buffer.
    ///
    /// A -1 value for `idx` will append the buffer at the end.
    extern fn gst_buffer_list_insert(p_list: *BufferList, p_idx: c_int, p_buffer: *gst.Buffer) void;
    pub const insert = gst_buffer_list_insert;

    /// Returns the number of buffers in `list`.
    extern fn gst_buffer_list_length(p_list: *BufferList) c_uint;
    pub const length = gst_buffer_list_length;

    /// Increases the refcount of the given buffer list by one.
    ///
    /// Note that the refcount affects the writability of `list` and its data, see
    /// `gst_buffer_list_make_writable`. It is important to note that keeping
    /// additional references to GstBufferList instances can potentially increase
    /// the number of memcpy operations in a pipeline.
    extern fn gst_buffer_list_ref(p_list: *BufferList) *gst.BufferList;
    pub const ref = gst_buffer_list_ref;

    /// Removes `length` buffers starting from `idx` in `list`. The following buffers
    /// are moved to close the gap.
    extern fn gst_buffer_list_remove(p_list: *BufferList, p_idx: c_uint, p_length: c_uint) void;
    pub const remove = gst_buffer_list_remove;

    /// Decreases the refcount of the buffer list. If the refcount reaches 0, the
    /// buffer list will be freed.
    extern fn gst_buffer_list_unref(p_list: *BufferList) void;
    pub const unref = gst_buffer_list_unref;

    extern fn gst_buffer_list_get_type() usize;
    pub const getGObjectType = gst_buffer_list_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Parameters passed to the `gst.BufferPool.acquireBuffer` function to control the
/// allocation of the buffer.
///
/// The default implementation ignores the `start` and `stop` members but other
/// implementations can use this extra information to decide what buffer to
/// return.
pub const BufferPoolAcquireParams = extern struct {
    /// the format of `start` and `stop`
    f_format: gst.Format,
    /// the start position
    f_start: i64,
    /// the stop position
    f_stop: i64,
    /// additional flags
    f_flags: gst.BufferPoolAcquireFlags,
    f__gst_reserved: [4]*anyopaque,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.BufferPool` class.
pub const BufferPoolClass = extern struct {
    pub const Instance = gst.BufferPool;

    /// Object parent class
    f_object_class: gst.ObjectClass,
    f_get_options: ?*const fn (p_pool: *gst.BufferPool) callconv(.c) [*][*:0]const u8,
    f_set_config: ?*const fn (p_pool: *gst.BufferPool, p_config: *gst.Structure) callconv(.c) c_int,
    f_start: ?*const fn (p_pool: *gst.BufferPool) callconv(.c) c_int,
    f_stop: ?*const fn (p_pool: *gst.BufferPool) callconv(.c) c_int,
    f_acquire_buffer: ?*const fn (p_pool: *gst.BufferPool, p_buffer: ?**gst.Buffer, p_params: ?*gst.BufferPoolAcquireParams) callconv(.c) gst.FlowReturn,
    f_alloc_buffer: ?*const fn (p_pool: *gst.BufferPool, p_buffer: ?**gst.Buffer, p_params: ?*gst.BufferPoolAcquireParams) callconv(.c) gst.FlowReturn,
    f_reset_buffer: ?*const fn (p_pool: *gst.BufferPool, p_buffer: *gst.Buffer) callconv(.c) void,
    f_release_buffer: ?*const fn (p_pool: *gst.BufferPool, p_buffer: *gst.Buffer) callconv(.c) void,
    f_free_buffer: ?*const fn (p_pool: *gst.BufferPool, p_buffer: *gst.Buffer) callconv(.c) void,
    f_flush_start: ?*const fn (p_pool: *gst.BufferPool) callconv(.c) void,
    f_flush_stop: ?*const fn (p_pool: *gst.BufferPool) callconv(.c) void,
    f__gst_reserved: [2]*anyopaque,

    pub fn as(p_instance: *BufferPoolClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const BufferPoolPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GStreamer bus class.
pub const BusClass = extern struct {
    pub const Instance = gst.Bus;

    /// the parent class structure
    f_parent_class: gst.ObjectClass,
    f_message: ?*const fn (p_bus: *gst.Bus, p_message: *gst.Message) callconv(.c) void,
    f_sync_message: ?*const fn (p_bus: *gst.Bus, p_message: *gst.Message) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *BusClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const BusPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Interface for an array of bytes. It is expected to be subclassed to implement
/// `resize` virtual method using language native array implementation, such as
/// GLib's `glib.ByteArray`, C++'s `std::vector<uint8_t>` or Rust's `Vec<u8>`.
///
/// `resize` implementation could allocate more than requested to avoid repeated
/// reallocations. It can return `FALSE`, or be set to `NULL`, in the case the
/// array cannot grow.
pub const ByteArrayInterface = extern struct {
    /// A pointer to an array of bytes.
    f_data: ?*u8,
    /// Number of bytes in `data`.
    f_len: usize,
    /// Reallocate `data`.
    f_resize: ?*const fn (p_self: *gst.ByteArrayInterface, p_length: usize) callconv(.c) c_int,
    f__gst_reserved: [4]*anyopaque,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Caps (capabilities) are lightweight refcounted objects describing media types.
/// They are composed of an array of `gst.Structure`.
///
/// Caps are exposed on `gst.PadTemplate` to describe all possible types a
/// given pad can handle. They are also stored in the `gst.Registry` along with
/// a description of the `gst.Element`.
///
/// Caps are exposed on the element pads using the `gst.Pad.queryCaps` pad
/// function. This function describes the possible types that the pad can
/// handle or produce at runtime.
///
/// A `gst.Caps` can be constructed with the following code fragment:
///
/// ``` C
///   GstCaps *caps = gst_caps_new_simple ("video/x-raw",
///      "format", G_TYPE_STRING, "I420",
///      "framerate", GST_TYPE_FRACTION, 25, 1,
///      "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
///      "width", G_TYPE_INT, 320,
///      "height", G_TYPE_INT, 240,
///      NULL);
/// ```
///
/// A `gst.Caps` is fixed when it has no fields with ranges or lists. Use
/// `gst.Caps.isFixed` to test for fixed caps. Fixed caps can be used in a
/// caps event to notify downstream elements of the current media type.
///
/// Various methods exist to work with the media types such as subtracting
/// or intersecting.
///
/// Be aware that until 1.20 the `gst.Caps` / `gst.Structure` serialization into string
/// had limited support for nested `gst.Caps` / `gst.Structure` fields. It could only
/// support one level of nesting. Using more levels would lead to unexpected
/// behavior when using serialization features, such as `gst.Caps.toString` or
/// `gst.valueSerialize` and their counterparts.
pub const Caps = extern struct {
    /// the parent type
    f_mini_object: gst.MiniObject,

    /// Converts `caps` from a string representation.
    ///
    /// The implementation of serialization up to 1.20 would lead to unexpected results
    /// when there were nested `gst.Caps` / `gst.Structure` deeper than one level.
    extern fn gst_caps_from_string(p_string: [*:0]const u8) ?*gst.Caps;
    pub const fromString = gst_caps_from_string;

    /// Modifies a pointer to a `gst.Caps` to point to a different `gst.Caps`. The
    /// modification is done atomically (so this is useful for ensuring thread safety
    /// in some cases), and the reference counts are updated appropriately (the old
    /// caps is unreffed, the new is reffed).
    ///
    /// Either `new_caps` or the `gst.Caps` pointed to by `old_caps` may be `NULL`.
    extern fn gst_caps_replace(p_old_caps: ?**gst.Caps, p_new_caps: ?*gst.Caps) c_int;
    pub const replace = gst_caps_replace;

    /// Modifies a pointer to a `gst.Caps` to point to a different `gst.Caps`. This
    /// function is similar to `gst.capsReplace` except that it takes ownership
    /// of `new_caps`.
    extern fn gst_caps_take(p_old_caps: **gst.Caps, p_new_caps: ?*gst.Caps) c_int;
    pub const take = gst_caps_take;

    /// Creates a new `gst.Caps` that indicates that it is compatible with
    /// any media format.
    extern fn gst_caps_new_any() *gst.Caps;
    pub const newAny = gst_caps_new_any;

    /// Creates a new `gst.Caps` that is empty.  That is, the returned
    /// `gst.Caps` contains no media formats.
    /// The `gst.Caps` is guaranteed to be writable.
    extern fn gst_caps_new_empty() *gst.Caps;
    pub const newEmpty = gst_caps_new_empty;

    /// Creates a new `gst.Caps` that contains one `gst.Structure` with name
    /// `media_type`.
    extern fn gst_caps_new_empty_simple(p_media_type: [*:0]const u8) *gst.Caps;
    pub const newEmptySimple = gst_caps_new_empty_simple;

    /// Creates a new `gst.Caps` and adds all the structures listed as
    /// arguments.  The list must be `NULL`-terminated.  The structures
    /// are not copied; the returned `gst.Caps` owns the structures.
    extern fn gst_caps_new_full(p_struct1: *gst.Structure, ...) *gst.Caps;
    pub const newFull = gst_caps_new_full;

    /// Creates a new `gst.Caps` and adds all the structures listed as
    /// arguments.  The list must be `NULL`-terminated.  The structures
    /// are not copied; the returned `gst.Caps` owns the structures.
    extern fn gst_caps_new_full_valist(p_structure: *gst.Structure, p_var_args: std.builtin.VaList) *gst.Caps;
    pub const newFullValist = gst_caps_new_full_valist;

    /// Creates a new `gst.Caps` that contains one `gst.Structure` with name
    /// `media_type`.
    extern fn gst_caps_new_id_str_empty_simple(p_media_type: *const gst.IdStr) *gst.Caps;
    pub const newIdStrEmptySimple = gst_caps_new_id_str_empty_simple;

    /// Creates a new `gst.Caps` that contains one `gst.Structure`.  The
    /// structure is defined by the arguments, which have the same format
    /// as `gst.Structure.new`.
    extern fn gst_caps_new_id_str_simple(p_media_type: *const gst.IdStr, p_fieldname: *const gst.IdStr, ...) *gst.Caps;
    pub const newIdStrSimple = gst_caps_new_id_str_simple;

    /// Creates a new `gst.Caps` that contains one `gst.Structure`.  The
    /// structure is defined by the arguments, which have the same format
    /// as `gst.Structure.new`.
    extern fn gst_caps_new_simple(p_media_type: [*:0]const u8, p_fieldname: [*:0]const u8, ...) *gst.Caps;
    pub const newSimple = gst_caps_new_simple;

    /// Creates a new `gst.Caps` that contains one `gst.Structure` with name
    /// `media_type`.
    ///
    /// `media_type` needs to be valid for the remaining lifetime of the process, e.g.
    /// has to be a static string.
    extern fn gst_caps_new_static_str_empty_simple(p_media_type: [*:0]const u8) *gst.Caps;
    pub const newStaticStrEmptySimple = gst_caps_new_static_str_empty_simple;

    /// Creates a new `gst.Caps` that contains one `gst.Structure`.  The
    /// structure is defined by the arguments, which have the same format
    /// as `gst.Structure.new`.
    ///
    /// `media_type`, `fieldname` and all other fieldnames need to be valid for the
    /// remaining lifetime of the process, e.g. have to be static strings.
    extern fn gst_caps_new_static_str_simple(p_media_type: [*:0]const u8, p_fieldname: [*:0]const u8, ...) *gst.Caps;
    pub const newStaticStrSimple = gst_caps_new_static_str_simple;

    /// Appends the structures contained in `caps2` to `caps1`. The structures in
    /// `caps2` are not copied -- they are transferred to `caps1`, and then `caps2` is
    /// freed. If either caps is ANY, the resulting caps will be ANY.
    extern fn gst_caps_append(p_caps1: *Caps, p_caps2: *gst.Caps) void;
    pub const append = gst_caps_append;

    /// Appends `structure` to `caps`.  The structure is not copied; `caps`
    /// becomes the owner of `structure`.
    extern fn gst_caps_append_structure(p_caps: *Caps, p_structure: *gst.Structure) void;
    pub const appendStructure = gst_caps_append_structure;

    /// Appends `structure` with `features` to `caps`.  The structure is not copied; `caps`
    /// becomes the owner of `structure`.
    extern fn gst_caps_append_structure_full(p_caps: *Caps, p_structure: *gst.Structure, p_features: ?*gst.CapsFeatures) void;
    pub const appendStructureFull = gst_caps_append_structure_full;

    /// Tries intersecting `caps1` and `caps2` and reports whether the result would not
    /// be empty
    extern fn gst_caps_can_intersect(p_caps1: *const Caps, p_caps2: *const gst.Caps) c_int;
    pub const canIntersect = gst_caps_can_intersect;

    /// Creates a new `gst.Caps` as a copy of the old `caps`. The new caps will have a
    /// refcount of 1, owned by the caller. The structures are copied as well.
    ///
    /// Note that this function is the semantic equivalent of a `gst.Caps.ref`
    /// followed by a `gst_caps_make_writable`. If you only want to hold on to a
    /// reference to the data, you should use `gst.Caps.ref`.
    extern fn gst_caps_copy(p_caps: *const Caps) *gst.Caps;
    pub const copy = gst_caps_copy;

    /// Creates a new `gst.Caps` and appends a copy of the nth structure
    /// contained in `caps`.
    extern fn gst_caps_copy_nth(p_caps: *const Caps, p_nth: c_uint) *gst.Caps;
    pub const copyNth = gst_caps_copy_nth;

    /// Calls the provided function once for each structure and caps feature in the
    /// `gst.Caps`. In contrast to `gst.Caps.foreach`, the function may modify the
    /// structure and features. In contrast to `gst.Caps.mapInPlace`, the structure
    /// and features are removed from the caps if `FALSE` is returned from the
    /// function. The caps must be mutable.
    extern fn gst_caps_filter_and_map_in_place(p_caps: *Caps, p_func: gst.CapsFilterMapFunc, p_user_data: ?*anyopaque) void;
    pub const filterAndMapInPlace = gst_caps_filter_and_map_in_place;

    /// Modifies the given `caps` into a representation with only fixed
    /// values. First the caps will be truncated and then the first structure will be
    /// fixated with `gst.Structure.fixate`.
    ///
    /// This function takes ownership of `caps` and will call `gst_caps_make_writable`
    /// on it so you must not use `caps` afterwards unless you keep an additional
    /// reference to it with `gst.Caps.ref`.
    ///
    /// Note that it is not guaranteed that the returned caps have exactly one
    /// structure. If `caps` are empty caps then the returned caps will be
    /// the empty too and contain no structure at all.
    ///
    /// Calling this function with ANY caps is not allowed.
    extern fn gst_caps_fixate(p_caps: *Caps) *gst.Caps;
    pub const fixate = gst_caps_fixate;

    /// Calls the provided function once for each structure and caps feature in the
    /// `gst.Caps`. The function must not modify the fields.
    /// Also see `gst.Caps.mapInPlace` and `gst.Caps.filterAndMapInPlace`.
    extern fn gst_caps_foreach(p_caps: *const Caps, p_func: gst.CapsForeachFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreach = gst_caps_foreach;

    /// Finds the features in `caps` at `index`, and returns it.
    ///
    /// WARNING: This function takes a `const GstCaps *`, but returns a
    /// non-const `GstCapsFeatures *`.  This is for programming convenience --
    /// the caller should be aware that features inside a constant
    /// `gst.Caps` should not be modified. However, if you know the caps
    /// are writable, either because you have just copied them or made
    /// them writable with `gst_caps_make_writable`, you may modify the
    /// features returned in the usual way, e.g. with functions like
    /// `gst.CapsFeatures.add`.
    extern fn gst_caps_get_features(p_caps: *const Caps, p_index: c_uint) ?*gst.CapsFeatures;
    pub const getFeatures = gst_caps_get_features;

    /// Gets the number of structures contained in `caps`.
    extern fn gst_caps_get_size(p_caps: *const Caps) c_uint;
    pub const getSize = gst_caps_get_size;

    /// Finds the structure in `caps` at `index`, and returns it.
    ///
    /// WARNING: This function takes a `const GstCaps *`, but returns a
    /// non-const `GstStructure *`.  This is for programming convenience --
    /// the caller should be aware that structures inside a constant
    /// `gst.Caps` should not be modified. However, if you know the caps
    /// are writable, either because you have just copied them or made
    /// them writable with `gst_caps_make_writable`, you may modify the
    /// structure returned in the usual way, e.g. with functions like
    /// `gst.Structure.set`.
    extern fn gst_caps_get_structure(p_caps: *const Caps, p_index: c_uint) *gst.Structure;
    pub const getStructure = gst_caps_get_structure;

    /// Sets fields in a `gst.Caps`.  The arguments must be passed in the same
    /// manner as `gst.Structure.idStrSet`, and be `NULL`-terminated.
    extern fn gst_caps_id_str_set_simple(p_caps: *Caps, p_field: *const gst.IdStr, ...) void;
    pub const idStrSetSimple = gst_caps_id_str_set_simple;

    /// Sets fields in a `gst.Caps`.  The arguments must be passed in the same
    /// manner as `gst.Structure.idStrSet`, and be `NULL`-terminated.
    extern fn gst_caps_id_str_set_simple_valist(p_caps: *Caps, p_field: *const gst.IdStr, p_varargs: std.builtin.VaList) void;
    pub const idStrSetSimpleValist = gst_caps_id_str_set_simple_valist;

    /// Sets the given `field` on all structures of `caps` to the given `value`.
    /// This is a convenience function for calling `gst.Structure.setValue` on
    /// all structures of `caps`.
    extern fn gst_caps_id_str_set_value(p_caps: *Caps, p_field: *const gst.IdStr, p_value: *const gobject.Value) void;
    pub const idStrSetValue = gst_caps_id_str_set_value;

    /// Creates a new `gst.Caps` that contains all the formats that are common
    /// to both `caps1` and `caps2`. Defaults to `GST_CAPS_INTERSECT_ZIG_ZAG` mode.
    extern fn gst_caps_intersect(p_caps1: *Caps, p_caps2: *gst.Caps) *gst.Caps;
    pub const intersect = gst_caps_intersect;

    /// Creates a new `gst.Caps` that contains all the formats that are common
    /// to both `caps1` and `caps2`, the order is defined by the `gst.CapsIntersectMode`
    /// used.
    extern fn gst_caps_intersect_full(p_caps1: *Caps, p_caps2: *gst.Caps, p_mode: gst.CapsIntersectMode) *gst.Caps;
    pub const intersectFull = gst_caps_intersect_full;

    /// A given `gst.Caps` structure is always compatible with another if
    /// every media format that is in the first is also contained in the
    /// second.  That is, `caps1` is a subset of `caps2`.
    extern fn gst_caps_is_always_compatible(p_caps1: *const Caps, p_caps2: *const gst.Caps) c_int;
    pub const isAlwaysCompatible = gst_caps_is_always_compatible;

    /// Determines if `caps` represents any media format.
    extern fn gst_caps_is_any(p_caps: *const Caps) c_int;
    pub const isAny = gst_caps_is_any;

    /// Determines if `caps` represents no media formats.
    extern fn gst_caps_is_empty(p_caps: *const Caps) c_int;
    pub const isEmpty = gst_caps_is_empty;

    /// Checks if the given caps represent the same set of caps.
    extern fn gst_caps_is_equal(p_caps1: *const Caps, p_caps2: *const gst.Caps) c_int;
    pub const isEqual = gst_caps_is_equal;

    /// Tests if two `gst.Caps` are equal.  This function only works on fixed
    /// `gst.Caps`.
    extern fn gst_caps_is_equal_fixed(p_caps1: *const Caps, p_caps2: *const gst.Caps) c_int;
    pub const isEqualFixed = gst_caps_is_equal_fixed;

    /// Fixed `gst.Caps` describe exactly one format, that is, they have exactly
    /// one structure, and each field in the structure describes a fixed type.
    /// Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
    extern fn gst_caps_is_fixed(p_caps: *const Caps) c_int;
    pub const isFixed = gst_caps_is_fixed;

    /// Checks if the given caps are exactly the same set of caps.
    extern fn gst_caps_is_strictly_equal(p_caps1: *const Caps, p_caps2: *const gst.Caps) c_int;
    pub const isStrictlyEqual = gst_caps_is_strictly_equal;

    /// Checks if all caps represented by `subset` are also represented by `superset`.
    extern fn gst_caps_is_subset(p_subset: *const Caps, p_superset: *const gst.Caps) c_int;
    pub const isSubset = gst_caps_is_subset;

    /// Checks if `structure` is a subset of `caps`. See `gst.Caps.isSubset`
    /// for more information.
    extern fn gst_caps_is_subset_structure(p_caps: *const Caps, p_structure: *const gst.Structure) c_int;
    pub const isSubsetStructure = gst_caps_is_subset_structure;

    /// Checks if `structure` is a subset of `caps`. See `gst.Caps.isSubset`
    /// for more information.
    extern fn gst_caps_is_subset_structure_full(p_caps: *const Caps, p_structure: *const gst.Structure, p_features: ?*const gst.CapsFeatures) c_int;
    pub const isSubsetStructureFull = gst_caps_is_subset_structure_full;

    /// Calls the provided function once for each structure and caps feature in the
    /// `gst.Caps`. In contrast to `gst.Caps.foreach`, the function may modify but not
    /// delete the structures and features. The caps must be mutable.
    extern fn gst_caps_map_in_place(p_caps: *Caps, p_func: gst.CapsMapFunc, p_user_data: ?*anyopaque) c_int;
    pub const mapInPlace = gst_caps_map_in_place;

    /// Appends the structures contained in `caps2` to `caps1` if they are not yet
    /// expressed by `caps1`. The structures in `caps2` are not copied -- they are
    /// transferred to a writable copy of `caps1`, and then `caps2` is freed.
    /// If either caps is ANY, the resulting caps will be ANY.
    extern fn gst_caps_merge(p_caps1: *Caps, p_caps2: *gst.Caps) *gst.Caps;
    pub const merge = gst_caps_merge;

    /// Appends `structure` to `caps` if it is not already expressed by `caps`.
    extern fn gst_caps_merge_structure(p_caps: *Caps, p_structure: *gst.Structure) *gst.Caps;
    pub const mergeStructure = gst_caps_merge_structure;

    /// Appends `structure` with `features` to `caps` if its not already expressed by `caps`.
    extern fn gst_caps_merge_structure_full(p_caps: *Caps, p_structure: *gst.Structure, p_features: ?*gst.CapsFeatures) *gst.Caps;
    pub const mergeStructureFull = gst_caps_merge_structure_full;

    /// Returns a `gst.Caps` that represents the same set of formats as
    /// `caps`, but contains no lists.  Each list is expanded into separate
    /// `gst.Structure`.
    ///
    /// This function takes ownership of `caps` and will call `gst_caps_make_writable`
    /// on it so you must not use `caps` afterwards unless you keep an additional
    /// reference to it with `gst.Caps.ref`.
    extern fn gst_caps_normalize(p_caps: *Caps) *gst.Caps;
    pub const normalize = gst_caps_normalize;

    /// Adds a reference to a `gst.Caps` object.
    ///
    /// From this point on, until the caller calls `gst.Caps.unref` or
    /// `gst_caps_make_writable`, it is guaranteed that the caps object will not
    /// change. This means its structures won't change, etc. To use a `gst.Caps`
    /// object, you must always have a refcount on it -- either the one made
    /// implicitly by e.g. `gst.Caps.newSimple`, or via taking one explicitly with
    /// this function.
    extern fn gst_caps_ref(p_caps: *Caps) *gst.Caps;
    pub const ref = gst_caps_ref;

    /// Removes the structure with the given index from the list of structures
    /// contained in `caps`.
    extern fn gst_caps_remove_structure(p_caps: *Caps, p_idx: c_uint) void;
    pub const removeStructure = gst_caps_remove_structure;

    /// Converts `caps` to a string representation.  This string representation can be
    /// converted back to a `gst.Caps` by `gst.capsFromString`.
    ///
    /// This prints the caps in human readable form.
    ///
    /// This version of the caps serialization function introduces support for nested
    /// structures and caps but the resulting strings won't be parsable with
    /// GStreamer prior to 1.20 unless `GST_SERIALIZE_FLAG_BACKWARD_COMPAT` is passed
    /// as `flag`.
    extern fn gst_caps_serialize(p_caps: *const Caps, p_flags: gst.SerializeFlags) [*:0]u8;
    pub const serialize = gst_caps_serialize;

    /// Sets the `features` for the structure at `index`.
    extern fn gst_caps_set_features(p_caps: *Caps, p_index: c_uint, p_features: ?*gst.CapsFeatures) void;
    pub const setFeatures = gst_caps_set_features;

    /// Sets the `features` for all the structures of `caps`.
    extern fn gst_caps_set_features_simple(p_caps: *Caps, p_features: ?*gst.CapsFeatures) void;
    pub const setFeaturesSimple = gst_caps_set_features_simple;

    /// Sets fields in a `gst.Caps`.  The arguments must be passed in the same
    /// manner as `gst.Structure.set`, and be `NULL`-terminated.
    extern fn gst_caps_set_simple(p_caps: *Caps, p_field: [*:0]const u8, ...) void;
    pub const setSimple = gst_caps_set_simple;

    /// Sets fields in a `gst.Caps`.  The arguments must be passed in the same
    /// manner as `gst.Structure.set`, and be `NULL`-terminated.
    ///
    /// `field` and all other field names need to be valid for the remaining lifetime
    /// of the process, e.g. have to be static strings.
    extern fn gst_caps_set_simple_static_str(p_caps: *Caps, p_field: [*:0]const u8, ...) void;
    pub const setSimpleStaticStr = gst_caps_set_simple_static_str;

    /// Sets fields in a `gst.Caps`.  The arguments must be passed in the same
    /// manner as `gst.Structure.set`, and be `NULL`-terminated.
    ///
    /// `field` and all other field names need to be valid for the remaining lifetime
    /// of the process, e.g. have to be static strings.
    extern fn gst_caps_set_simple_static_str_valist(p_caps: *Caps, p_field: [*:0]const u8, p_varargs: std.builtin.VaList) void;
    pub const setSimpleStaticStrValist = gst_caps_set_simple_static_str_valist;

    /// Sets fields in a `gst.Caps`.  The arguments must be passed in the same
    /// manner as `gst.Structure.set`, and be `NULL`-terminated.
    extern fn gst_caps_set_simple_valist(p_caps: *Caps, p_field: [*:0]const u8, p_varargs: std.builtin.VaList) void;
    pub const setSimpleValist = gst_caps_set_simple_valist;

    /// Sets the given `field` on all structures of `caps` to the given `value`.
    /// This is a convenience function for calling `gst.Structure.setValue` on
    /// all structures of `caps`.
    extern fn gst_caps_set_value(p_caps: *Caps, p_field: [*:0]const u8, p_value: *const gobject.Value) void;
    pub const setValue = gst_caps_set_value;

    /// Sets the given `field` on all structures of `caps` to the given `value`.
    /// This is a convenience function for calling `gst.Structure.setValue` on
    /// all structures of `caps`.
    ///
    /// `field` needs to be valid for the remaining lifetime of the process, e.g.
    /// has to be a static string.
    extern fn gst_caps_set_value_static_str(p_caps: *Caps, p_field: [*:0]const u8, p_value: *const gobject.Value) void;
    pub const setValueStaticStr = gst_caps_set_value_static_str;

    /// Converts the given `caps` into a representation that represents the
    /// same set of formats, but in a simpler form.  Component structures that are
    /// identical are merged.  Component structures that have values that can be
    /// merged are also merged.
    ///
    /// This function takes ownership of `caps` and will call `gst_caps_make_writable`
    /// on it if necessary, so you must not use `caps` afterwards unless you keep an
    /// additional reference to it with `gst.Caps.ref`.
    ///
    /// This method does not preserve the original order of `caps`.
    extern fn gst_caps_simplify(p_caps: *Caps) *gst.Caps;
    pub const simplify = gst_caps_simplify;

    /// Retrieves the structure with the given index from the list of structures
    /// contained in `caps`. The caller becomes the owner of the returned structure.
    extern fn gst_caps_steal_structure(p_caps: *Caps, p_index: c_uint) ?*gst.Structure;
    pub const stealStructure = gst_caps_steal_structure;

    /// Subtracts the `subtrahend` from the `minuend`.
    /// > This function does not work reliably if optional properties for caps
    /// > are included on one caps and omitted on the other.
    extern fn gst_caps_subtract(p_minuend: *Caps, p_subtrahend: *gst.Caps) *gst.Caps;
    pub const subtract = gst_caps_subtract;

    /// Converts `caps` to a string representation.  This string representation
    /// can be converted back to a `gst.Caps` by `gst.capsFromString`.
    ///
    /// For debugging purposes its easier to do something like this:
    ///
    /// ``` C
    /// GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
    /// ```
    ///
    /// This prints the caps in human readable form.
    ///
    /// The implementation of serialization up to 1.20 would lead to unexpected results
    /// when there were nested `gst.Caps` / `gst.Structure` deeper than one level.
    extern fn gst_caps_to_string(p_caps: *const Caps) [*:0]u8;
    pub const toString = gst_caps_to_string;

    /// Discards all but the first structure from `caps`. Useful when
    /// fixating.
    ///
    /// This function takes ownership of `caps` and will call `gst_caps_make_writable`
    /// on it if necessary, so you must not use `caps` afterwards unless you keep an
    /// additional reference to it with `gst.Caps.ref`.
    ///
    /// Note that it is not guaranteed that the returned caps have exactly one
    /// structure. If `caps` is any or empty caps then the returned caps will be
    /// the same and contain no structure at all.
    extern fn gst_caps_truncate(p_caps: *Caps) *gst.Caps;
    pub const truncate = gst_caps_truncate;

    /// Unrefs a `gst.Caps` and frees all its structures and the
    /// structures' values when the refcount reaches 0.
    extern fn gst_caps_unref(p_caps: *Caps) void;
    pub const unref = gst_caps_unref;

    extern fn gst_caps_get_type() usize;
    pub const getGObjectType = gst_caps_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.CapsFeatures` can optionally be set on a `gst.Caps` to add requirements
/// for additional features for a specific `gst.Structure`. Caps structures with
/// the same name but with a non-equal set of caps features are not compatible.
/// If a pad supports multiple sets of features it has to add multiple equal
/// structures with different feature sets to the caps.
///
/// Empty `gst.CapsFeatures` are equivalent with the `gst.CapsFeatures` that only
/// contain `GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY`. ANY `gst.CapsFeatures` as
/// created by `gst.CapsFeatures.newAny` are equal to any other `gst.CapsFeatures`
/// and can be used to specify that any `gst.CapsFeatures` would be supported, e.g.
/// for elements that don't touch buffer memory. `gst.Caps` with ANY `gst.CapsFeatures`
/// are considered non-fixed and during negotiation some `gst.CapsFeatures` have
/// to be selected.
///
/// Examples for caps features would be the requirement of a specific `gst.Memory`
/// types or the requirement of having a specific `gst.Meta` on the buffer. Features
/// are given as a string of the format `memory:GstMemoryTypeName` or
/// `meta:GstMetaAPIName`.
pub const CapsFeatures = opaque {
    /// Creates a `gst.CapsFeatures` from a string representation.
    extern fn gst_caps_features_from_string(p_features: [*:0]const u8) ?*gst.CapsFeatures;
    pub const fromString = gst_caps_features_from_string;

    /// Creates a new `gst.CapsFeatures` with the given features.
    /// The last argument must be `NULL`.
    extern fn gst_caps_features_new(p_feature1: [*:0]const u8, ...) *gst.CapsFeatures;
    pub const new = gst_caps_features_new;

    /// Creates a new, ANY `gst.CapsFeatures`. This will be equal
    /// to any other `gst.CapsFeatures` but caps with these are
    /// unfixed.
    extern fn gst_caps_features_new_any() *gst.CapsFeatures;
    pub const newAny = gst_caps_features_new_any;

    /// Creates a new, empty `gst.CapsFeatures`.
    extern fn gst_caps_features_new_empty() *gst.CapsFeatures;
    pub const newEmpty = gst_caps_features_new_empty;

    /// Creates a new `gst.CapsFeatures` with the given features.
    /// The last argument must be 0.
    extern fn gst_caps_features_new_id(p_feature1: glib.Quark, ...) *gst.CapsFeatures;
    pub const newId = gst_caps_features_new_id;

    /// Creates a new `gst.CapsFeatures` with the given features.
    /// The last argument must be 0.
    extern fn gst_caps_features_new_id_str(p_feature1: *const gst.IdStr, ...) *gst.CapsFeatures;
    pub const newIdStr = gst_caps_features_new_id_str;

    /// Creates a new `gst.CapsFeatures` with the given features.
    extern fn gst_caps_features_new_id_str_valist(p_feature1: *const gst.IdStr, p_varargs: std.builtin.VaList) *gst.CapsFeatures;
    pub const newIdStrValist = gst_caps_features_new_id_str_valist;

    /// Creates a new `gst.CapsFeatures` with the given features.
    extern fn gst_caps_features_new_id_valist(p_feature1: glib.Quark, p_varargs: std.builtin.VaList) *gst.CapsFeatures;
    pub const newIdValist = gst_caps_features_new_id_valist;

    /// Creates a new `gst.CapsFeatures` with a single feature.
    extern fn gst_caps_features_new_single(p_feature: [*:0]const u8) *gst.CapsFeatures;
    pub const newSingle = gst_caps_features_new_single;

    /// Creates a new `gst.CapsFeatures` with a single feature.
    ///
    /// `feature` needs to be valid for the remaining lifetime of the process, e.g. has
    /// to be a static string.
    extern fn gst_caps_features_new_single_static_str(p_feature: [*:0]const u8) *gst.CapsFeatures;
    pub const newSingleStaticStr = gst_caps_features_new_single_static_str;

    /// Creates a new `gst.CapsFeatures` with the given features.
    /// The last argument must be `NULL`.
    ///
    /// `feature1` and all other features need to be valid for the remaining lifetime
    /// of the process, e.g. have to be a static string.
    extern fn gst_caps_features_new_static_str(p_feature1: [*:0]const u8, ...) *gst.CapsFeatures;
    pub const newStaticStr = gst_caps_features_new_static_str;

    /// Creates a new `gst.CapsFeatures` with the given features.
    ///
    /// `feature1` and all other features need to be valid for the remaining lifetime
    /// of the process, e.g. have to be a static string.
    extern fn gst_caps_features_new_static_str_valist(p_feature1: [*:0]const u8, p_varargs: std.builtin.VaList) *gst.CapsFeatures;
    pub const newStaticStrValist = gst_caps_features_new_static_str_valist;

    /// Creates a new `gst.CapsFeatures` with the given features.
    extern fn gst_caps_features_new_valist(p_feature1: [*:0]const u8, p_varargs: std.builtin.VaList) *gst.CapsFeatures;
    pub const newValist = gst_caps_features_new_valist;

    /// Adds `feature` to `features`.
    extern fn gst_caps_features_add(p_features: *CapsFeatures, p_feature: [*:0]const u8) void;
    pub const add = gst_caps_features_add;

    /// Adds `feature` to `features`.
    extern fn gst_caps_features_add_id(p_features: *CapsFeatures, p_feature: glib.Quark) void;
    pub const addId = gst_caps_features_add_id;

    /// Adds `feature` to `features`.
    extern fn gst_caps_features_add_id_str(p_features: *CapsFeatures, p_feature: *const gst.IdStr) void;
    pub const addIdStr = gst_caps_features_add_id_str;

    /// Adds `feature` to `features`.
    ///
    /// `feature` needs to be valid for the remaining lifetime of the process, e.g. has
    /// to be a static string.
    extern fn gst_caps_features_add_static_str(p_features: *CapsFeatures, p_feature: [*:0]const u8) void;
    pub const addStaticStr = gst_caps_features_add_static_str;

    /// Checks if `features` contains `feature`.
    extern fn gst_caps_features_contains(p_features: *const CapsFeatures, p_feature: [*:0]const u8) c_int;
    pub const contains = gst_caps_features_contains;

    /// Checks if `features` contains `feature`.
    extern fn gst_caps_features_contains_id(p_features: *const CapsFeatures, p_feature: glib.Quark) c_int;
    pub const containsId = gst_caps_features_contains_id;

    /// Checks if `features` contains `feature`.
    extern fn gst_caps_features_contains_id_str(p_features: *const CapsFeatures, p_feature: *const gst.IdStr) c_int;
    pub const containsIdStr = gst_caps_features_contains_id_str;

    /// Duplicates a `gst.CapsFeatures` and all its values.
    extern fn gst_caps_features_copy(p_features: *const CapsFeatures) *gst.CapsFeatures;
    pub const copy = gst_caps_features_copy;

    /// Frees a `gst.CapsFeatures` and all its values. The caps features must not
    /// have a parent when this function is called.
    extern fn gst_caps_features_free(p_features: *CapsFeatures) void;
    pub const free = gst_caps_features_free;

    /// Returns the `i`-th feature of `features`.
    extern fn gst_caps_features_get_nth(p_features: *const CapsFeatures, p_i: c_uint) ?[*:0]const u8;
    pub const getNth = gst_caps_features_get_nth;

    /// Returns the `i`-th feature of `features`.
    extern fn gst_caps_features_get_nth_id(p_features: *const CapsFeatures, p_i: c_uint) glib.Quark;
    pub const getNthId = gst_caps_features_get_nth_id;

    /// Returns the `i`-th feature of `features`.
    extern fn gst_caps_features_get_nth_id_str(p_features: *const CapsFeatures, p_i: c_uint) *const gst.IdStr;
    pub const getNthIdStr = gst_caps_features_get_nth_id_str;

    /// Returns the number of features in `features`.
    extern fn gst_caps_features_get_size(p_features: *const CapsFeatures) c_uint;
    pub const getSize = gst_caps_features_get_size;

    /// Checks if `features` is `GST_CAPS_FEATURES_ANY`.
    extern fn gst_caps_features_is_any(p_features: *const CapsFeatures) c_int;
    pub const isAny = gst_caps_features_is_any;

    /// Checks if `features1` and `features2` are equal.
    extern fn gst_caps_features_is_equal(p_features1: *const CapsFeatures, p_features2: *const gst.CapsFeatures) c_int;
    pub const isEqual = gst_caps_features_is_equal;

    /// Removes `feature` from `features`.
    extern fn gst_caps_features_remove(p_features: *CapsFeatures, p_feature: [*:0]const u8) void;
    pub const remove = gst_caps_features_remove;

    /// Removes `feature` from `features`.
    extern fn gst_caps_features_remove_id(p_features: *CapsFeatures, p_feature: glib.Quark) void;
    pub const removeId = gst_caps_features_remove_id;

    /// Removes `feature` from `features`.
    extern fn gst_caps_features_remove_id_str(p_features: *CapsFeatures, p_feature: *const gst.IdStr) void;
    pub const removeIdStr = gst_caps_features_remove_id_str;

    /// Sets the parent_refcount field of `gst.CapsFeatures`. This field is used to
    /// determine whether a caps features is mutable or not. This function should only be
    /// called by code implementing parent objects of `gst.CapsFeatures`, as described in
    /// [the MT refcounting design document](additional/design/MT-refcounting.md).
    extern fn gst_caps_features_set_parent_refcount(p_features: *CapsFeatures, p_refcount: *c_int) c_int;
    pub const setParentRefcount = gst_caps_features_set_parent_refcount;

    /// Converts `features` to a human-readable string representation.
    ///
    /// For debugging purposes its easier to do something like this:
    ///
    /// ``` C
    /// GST_LOG ("features is %" GST_PTR_FORMAT, features);
    /// ```
    ///
    /// This prints the features in human readable form.
    extern fn gst_caps_features_to_string(p_features: *const CapsFeatures) [*:0]u8;
    pub const toString = gst_caps_features_to_string;

    extern fn gst_caps_features_get_type() usize;
    pub const getGObjectType = gst_caps_features_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.ChildProxy` interface.
pub const ChildProxyInterface = extern struct {
    pub const Instance = gst.ChildProxy;

    /// parent interface type.
    f_parent: gobject.TypeInterface,
    /// Fetch a child object by name
    f_get_child_by_name: ?*const fn (p_parent: *gst.ChildProxy, p_name: [*:0]const u8) callconv(.c) ?*gobject.Object,
    /// Fetch a child object by index
    f_get_child_by_index: ?*const fn (p_parent: *gst.ChildProxy, p_index: c_uint) callconv(.c) ?*gobject.Object,
    /// Get the number of children in `parent`
    f_get_children_count: ?*const fn (p_parent: *gst.ChildProxy) callconv(.c) c_uint,
    /// Called when `child` is added to `parent`
    f_child_added: ?*const fn (p_parent: *gst.ChildProxy, p_child: *gobject.Object, p_name: [*:0]const u8) callconv(.c) void,
    /// Called when `child` is removed from `parent`
    f_child_removed: ?*const fn (p_parent: *gst.ChildProxy, p_child: *gobject.Object, p_name: [*:0]const u8) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *ChildProxyInterface, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GStreamer clock class. Override the vmethods to implement the clock
/// functionality.
pub const ClockClass = extern struct {
    pub const Instance = gst.Clock;

    /// the parent class structure
    f_parent_class: gst.ObjectClass,
    f_change_resolution: ?*const fn (p_clock: *gst.Clock, p_old_resolution: gst.ClockTime, p_new_resolution: gst.ClockTime) callconv(.c) gst.ClockTime,
    f_get_resolution: ?*const fn (p_clock: *gst.Clock) callconv(.c) gst.ClockTime,
    f_get_internal_time: ?*const fn (p_clock: *gst.Clock) callconv(.c) gst.ClockTime,
    f_wait: ?*const fn (p_clock: *gst.Clock, p_entry: *gst.ClockEntry, p_jitter: ?*gst.ClockTimeDiff) callconv(.c) gst.ClockReturn,
    f_wait_async: ?*const fn (p_clock: *gst.Clock, p_entry: *gst.ClockEntry) callconv(.c) gst.ClockReturn,
    f_unschedule: ?*const fn (p_clock: *gst.Clock, p_entry: *gst.ClockEntry) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *ClockClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// All pending timeouts or periodic notifies are converted into
/// an entry.
/// Note that GstClockEntry should be treated as an opaque structure. It must
/// not be extended or allocated using a custom allocator.
pub const ClockEntry = extern struct {
    /// reference counter (read-only)
    f_refcount: c_int,
    f_clock: ?*gst.Clock,
    f_type: gst.ClockEntryType,
    f_time: gst.ClockTime,
    f_interval: gst.ClockTime,
    f_status: gst.ClockReturn,
    f_func: ?gst.ClockCallback,
    f_user_data: ?*anyopaque,
    f_destroy_data: ?glib.DestroyNotify,
    f_unscheduled: c_int,
    f_woken_up: c_int,
    f__gst_reserved: [4]*anyopaque,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ClockPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.Context` is a container object used to store contexts like a device
/// context, a display server connection and similar concepts that should
/// be shared between multiple elements.
///
/// Applications can set a context on a complete pipeline by using
/// `gst.Element.setContext`, which will then be propagated to all
/// child elements. Elements can handle these in `gst.ElementClass.signals.set_context`
/// and merge them with the context information they already have.
///
/// When an element needs a context it will do the following actions in this
/// order until one step succeeds:
///
/// 1. Check if the element already has a context
/// 2. Query downstream with `GST_QUERY_CONTEXT` for the context
/// 3. Query upstream with `GST_QUERY_CONTEXT` for the context
/// 4. Post a `GST_MESSAGE_NEED_CONTEXT` message on the bus with the required
///    context types and afterwards check if a usable context was set now
/// 5. Create a context by itself and post a `GST_MESSAGE_HAVE_CONTEXT` message
///    on the bus.
///
/// Bins will catch `GST_MESSAGE_NEED_CONTEXT` messages and will set any previously
/// known context on the element that asks for it if possible. Otherwise the
/// application should provide one if it can.
///
/// `gst.Context` can be persistent.
/// A persistent `gst.Context` is kept in elements when they reach
/// `GST_STATE_NULL`, non-persistent ones will be removed.
/// Also, a non-persistent context won't override a previous persistent
/// context set to an element.
pub const Context = opaque {
    /// Modifies a pointer to a `gst.Context` to point to a different `gst.Context`. The
    /// modification is done atomically (so this is useful for ensuring thread safety
    /// in some cases), and the reference counts are updated appropriately (the old
    /// context is unreffed, the new one is reffed).
    ///
    /// Either `new_context` or the `gst.Context` pointed to by `old_context` may be `NULL`.
    extern fn gst_context_replace(p_old_context: **gst.Context, p_new_context: ?*gst.Context) c_int;
    pub const replace = gst_context_replace;

    /// Creates a new context.
    extern fn gst_context_new(p_context_type: [*:0]const u8, p_persistent: c_int) *gst.Context;
    pub const new = gst_context_new;

    /// Creates a copy of the context. Returns a copy of the context.
    extern fn gst_context_copy(p_context: *const Context) *gst.Context;
    pub const copy = gst_context_copy;

    /// Gets the type of `context`.
    extern fn gst_context_get_context_type(p_context: *const Context) [*:0]const u8;
    pub const getContextType = gst_context_get_context_type;

    /// Accesses the structure of the context.
    extern fn gst_context_get_structure(p_context: *const Context) *const gst.Structure;
    pub const getStructure = gst_context_get_structure;

    /// Checks if `context` has `context_type`.
    extern fn gst_context_has_context_type(p_context: *const Context, p_context_type: [*:0]const u8) c_int;
    pub const hasContextType = gst_context_has_context_type;

    /// Checks if `context` is persistent.
    extern fn gst_context_is_persistent(p_context: *const Context) c_int;
    pub const isPersistent = gst_context_is_persistent;

    /// Convenience macro to increase the reference count of the context.
    extern fn gst_context_ref(p_context: *Context) *gst.Context;
    pub const ref = gst_context_ref;

    /// Convenience macro to decrease the reference count of the context, possibly
    /// freeing it.
    extern fn gst_context_unref(p_context: *Context) void;
    pub const unref = gst_context_unref;

    /// Gets a writable version of the structure.
    extern fn gst_context_writable_structure(p_context: *Context) *gst.Structure;
    pub const writableStructure = gst_context_writable_structure;

    extern fn gst_context_get_type() usize;
    pub const getGObjectType = gst_context_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The class structure of `gst.ControlBinding`.
pub const ControlBindingClass = extern struct {
    pub const Instance = gst.ControlBinding;

    /// Parent class
    f_parent_class: gst.ObjectClass,
    f_sync_values: ?*const fn (p_binding: *gst.ControlBinding, p_object: *gst.Object, p_timestamp: gst.ClockTime, p_last_sync: gst.ClockTime) callconv(.c) c_int,
    f_get_value: ?*const fn (p_binding: *gst.ControlBinding, p_timestamp: gst.ClockTime) callconv(.c) ?*gobject.Value,
    f_get_value_array: ?*const fn (p_binding: *gst.ControlBinding, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]*anyopaque) callconv(.c) c_int,
    f_get_g_value_array: ?*const fn (p_binding: *gst.ControlBinding, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: [*]gobject.Value) callconv(.c) c_int,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *ControlBindingClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ControlBindingPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The class structure of `gst.ControlSource`.
pub const ControlSourceClass = extern struct {
    pub const Instance = gst.ControlSource;

    /// Parent class
    f_parent_class: gst.ObjectClass,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *ControlSourceClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Extra custom metadata. The `structure` field is the same as returned by
/// `gst.CustomMeta.getStructure`.
///
/// Since 1.24 it can be serialized using `gst.Meta.serialize` and
/// `gst.metaDeserialize`, but only if the `gst.Structure` does not contain any
/// fields that cannot be serialized, see `GST_SERIALIZE_FLAG_STRICT`.
pub const CustomMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// `gst.Structure` containing custom metadata.
    f_structure: ?*gst.Structure,

    /// Retrieve the `gst.Structure` backing a custom meta, the structure's mutability
    /// is conditioned to the writability of the `gst.Buffer` `meta` is attached to.
    extern fn gst_custom_meta_get_structure(p_meta: *CustomMeta) *gst.Structure;
    pub const getStructure = gst_custom_meta_get_structure;

    /// Checks whether the name of the custom meta is `name`
    extern fn gst_custom_meta_has_name(p_meta: *CustomMeta, p_name: [*:0]const u8) c_int;
    pub const hasName = gst_custom_meta_has_name;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Struct to store date, time and timezone information altogether.
/// `gst.DateTime` is refcounted and immutable.
///
/// Date information is handled using the [proleptic Gregorian calendar].
///
/// Provides basic creation functions and accessor functions to its fields.
///
/// [proleptic Gregorian calendar]: https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar
pub const DateTime = opaque {
    /// Creates a new `gst.DateTime` using the date and times in the gregorian calendar
    /// in the supplied timezone.
    ///
    /// `year` should be from 1 to 9999, `month` should be from 1 to 12, `day` from
    /// 1 to 31, `hour` from 0 to 23, `minutes` and `seconds` from 0 to 59.
    ///
    /// Note that `tzoffset` is a float and was chosen so for being able to handle
    /// some fractional timezones, while it still keeps the readability of
    /// representing it in hours for most timezones.
    ///
    /// If value is -1 then all over value will be ignored. For example
    /// if `month` == -1, then `gst.DateTime` will be created only for `year`. If
    /// `day` == -1, then `gst.DateTime` will be created for `year` and `month` and
    /// so on.
    extern fn gst_date_time_new(p_tzoffset: f32, p_year: c_int, p_month: c_int, p_day: c_int, p_hour: c_int, p_minute: c_int, p_seconds: f64) ?*gst.DateTime;
    pub const new = gst_date_time_new;

    /// Creates a new `gst.DateTime` from a `glib.DateTime` object.
    extern fn gst_date_time_new_from_g_date_time(p_dt: ?*glib.DateTime) ?*gst.DateTime;
    pub const newFromGDateTime = gst_date_time_new_from_g_date_time;

    /// Tries to parse common variants of ISO-8601 datetime strings into a
    /// `gst.DateTime`. Possible input formats are (for example):
    /// `2012-06-30T22:46:43Z`, `2012`, `2012-06`, `2012-06-30`, `2012-06-30T22:46:43-0430`,
    /// `2012-06-30T22:46Z`, `2012-06-30T22:46-0430`, `2012-06-30 22:46`,
    /// `2012-06-30 22:46:43`, `2012-06-00`, `2012-00-00`, `2012-00-30`, `22:46:43Z`, `22:46Z`,
    /// `22:46:43-0430`, `22:46-0430`, `22:46:30`, `22:46`
    /// If no date is provided, it is assumed to be "today" in the timezone
    /// provided (if any), otherwise UTC.
    extern fn gst_date_time_new_from_iso8601_string(p_string: [*:0]const u8) ?*gst.DateTime;
    pub const newFromIso8601String = gst_date_time_new_from_iso8601_string;

    /// Creates a new `gst.DateTime` using the time since Jan 1, 1970 specified by
    /// `secs`. The `gst.DateTime` is in the local timezone.
    extern fn gst_date_time_new_from_unix_epoch_local_time(p_secs: i64) ?*gst.DateTime;
    pub const newFromUnixEpochLocalTime = gst_date_time_new_from_unix_epoch_local_time;

    /// Creates a new `gst.DateTime` using the time since Jan 1, 1970 specified by
    /// `usecs`. The `gst.DateTime` is in the local timezone.
    extern fn gst_date_time_new_from_unix_epoch_local_time_usecs(p_usecs: i64) ?*gst.DateTime;
    pub const newFromUnixEpochLocalTimeUsecs = gst_date_time_new_from_unix_epoch_local_time_usecs;

    /// Creates a new `gst.DateTime` using the time since Jan 1, 1970 specified by
    /// `secs`. The `gst.DateTime` is in the UTC timezone.
    extern fn gst_date_time_new_from_unix_epoch_utc(p_secs: i64) ?*gst.DateTime;
    pub const newFromUnixEpochUtc = gst_date_time_new_from_unix_epoch_utc;

    /// Creates a new `gst.DateTime` using the time since Jan 1, 1970 specified by
    /// `usecs`. The `gst.DateTime` is in UTC.
    extern fn gst_date_time_new_from_unix_epoch_utc_usecs(p_usecs: i64) ?*gst.DateTime;
    pub const newFromUnixEpochUtcUsecs = gst_date_time_new_from_unix_epoch_utc_usecs;

    /// Creates a new `gst.DateTime` using the date and times in the gregorian calendar
    /// in the local timezone.
    ///
    /// `year` should be from 1 to 9999, `month` should be from 1 to 12, `day` from
    /// 1 to 31, `hour` from 0 to 23, `minutes` and `seconds` from 0 to 59.
    ///
    /// If `month` is -1, then the `gst.DateTime` created will only contain `year`,
    /// and all other fields will be considered not set.
    ///
    /// If `day` is -1, then the `gst.DateTime` created will only contain `year` and
    /// `month` and all other fields will be considered not set.
    ///
    /// If `hour` is -1, then the `gst.DateTime` created will only contain `year` and
    /// `month` and `day`, and the time fields will be considered not set. In this
    /// case `minute` and `seconds` should also be -1.
    extern fn gst_date_time_new_local_time(p_year: c_int, p_month: c_int, p_day: c_int, p_hour: c_int, p_minute: c_int, p_seconds: f64) ?*gst.DateTime;
    pub const newLocalTime = gst_date_time_new_local_time;

    /// Creates a new `gst.DateTime` representing the current date and time.
    extern fn gst_date_time_new_now_local_time() ?*gst.DateTime;
    pub const newNowLocalTime = gst_date_time_new_now_local_time;

    /// Creates a new `gst.DateTime` that represents the current instant at Universal
    /// coordinated time.
    extern fn gst_date_time_new_now_utc() ?*gst.DateTime;
    pub const newNowUtc = gst_date_time_new_now_utc;

    /// Creates a new `gst.DateTime` using the date and times in the gregorian calendar
    /// in the local timezone.
    ///
    /// `year` should be from 1 to 9999.
    extern fn gst_date_time_new_y(p_year: c_int) ?*gst.DateTime;
    pub const newY = gst_date_time_new_y;

    /// Creates a new `gst.DateTime` using the date and times in the gregorian calendar
    /// in the local timezone.
    ///
    /// `year` should be from 1 to 9999, `month` should be from 1 to 12.
    ///
    /// If value is -1 then all over value will be ignored. For example
    /// if `month` == -1, then `gst.DateTime` will created only for `year`.
    extern fn gst_date_time_new_ym(p_year: c_int, p_month: c_int) ?*gst.DateTime;
    pub const newYm = gst_date_time_new_ym;

    /// Creates a new `gst.DateTime` using the date and times in the gregorian calendar
    /// in the local timezone.
    ///
    /// `year` should be from 1 to 9999, `month` should be from 1 to 12, `day` from
    /// 1 to 31.
    ///
    /// If value is -1 then all over value will be ignored. For example
    /// if `month` == -1, then `gst.DateTime` will created only for `year`. If
    /// `day` == -1, then `gst.DateTime` will created for `year` and `month` and
    /// so on.
    extern fn gst_date_time_new_ymd(p_year: c_int, p_month: c_int, p_day: c_int) ?*gst.DateTime;
    pub const newYmd = gst_date_time_new_ymd;

    /// Returns the day of the month of this `gst.DateTime`.
    extern fn gst_date_time_get_day(p_datetime: *const DateTime) c_int;
    pub const getDay = gst_date_time_get_day;

    /// Retrieves the hour of the day represented by `datetime` in the gregorian
    /// calendar. The return is in the range of 0 to 23.
    extern fn gst_date_time_get_hour(p_datetime: *const DateTime) c_int;
    pub const getHour = gst_date_time_get_hour;

    /// Retrieves the fractional part of the seconds in microseconds represented by
    /// `datetime` in the gregorian calendar.
    extern fn gst_date_time_get_microsecond(p_datetime: *const DateTime) c_int;
    pub const getMicrosecond = gst_date_time_get_microsecond;

    /// Retrieves the minute of the hour represented by `datetime` in the gregorian
    /// calendar.
    extern fn gst_date_time_get_minute(p_datetime: *const DateTime) c_int;
    pub const getMinute = gst_date_time_get_minute;

    /// Returns the month of this `gst.DateTime`. January is 1, February is 2, etc..
    extern fn gst_date_time_get_month(p_datetime: *const DateTime) c_int;
    pub const getMonth = gst_date_time_get_month;

    /// Retrieves the second of the minute represented by `datetime` in the gregorian
    /// calendar.
    extern fn gst_date_time_get_second(p_datetime: *const DateTime) c_int;
    pub const getSecond = gst_date_time_get_second;

    /// Retrieves the offset from UTC in hours that the timezone specified
    /// by `datetime` represents. Timezones ahead (to the east) of UTC have positive
    /// values, timezones before (to the west) of UTC have negative values.
    /// If `datetime` represents UTC time, then the offset is zero.
    extern fn gst_date_time_get_time_zone_offset(p_datetime: *const DateTime) f32;
    pub const getTimeZoneOffset = gst_date_time_get_time_zone_offset;

    /// Returns the year of this `gst.DateTime`.
    /// Call `gst.DateTime.hasYear` before, to avoid warnings.
    extern fn gst_date_time_get_year(p_datetime: *const DateTime) c_int;
    pub const getYear = gst_date_time_get_year;

    extern fn gst_date_time_has_day(p_datetime: *const DateTime) c_int;
    pub const hasDay = gst_date_time_has_day;

    extern fn gst_date_time_has_month(p_datetime: *const DateTime) c_int;
    pub const hasMonth = gst_date_time_has_month;

    extern fn gst_date_time_has_second(p_datetime: *const DateTime) c_int;
    pub const hasSecond = gst_date_time_has_second;

    extern fn gst_date_time_has_time(p_datetime: *const DateTime) c_int;
    pub const hasTime = gst_date_time_has_time;

    extern fn gst_date_time_has_year(p_datetime: *const DateTime) c_int;
    pub const hasYear = gst_date_time_has_year;

    /// Atomically increments the reference count of `datetime` by one.
    extern fn gst_date_time_ref(p_datetime: *DateTime) *gst.DateTime;
    pub const ref = gst_date_time_ref;

    /// Creates a new `glib.DateTime` from a fully defined `gst.DateTime` object.
    extern fn gst_date_time_to_g_date_time(p_datetime: *DateTime) ?*glib.DateTime;
    pub const toGDateTime = gst_date_time_to_g_date_time;

    /// Create a minimal string compatible with ISO-8601. Possible output formats
    /// are (for example): `2012`, `2012-06`, `2012-06-23`, `2012-06-23T23:30Z`,
    /// `2012-06-23T23:30+0100`, `2012-06-23T23:30:59Z`, `2012-06-23T23:30:59+0100`
    extern fn gst_date_time_to_iso8601_string(p_datetime: *DateTime) ?[*:0]u8;
    pub const toIso8601String = gst_date_time_to_iso8601_string;

    /// Atomically decrements the reference count of `datetime` by one.  When the
    /// reference count reaches zero, the structure is freed.
    extern fn gst_date_time_unref(p_datetime: *DateTime) void;
    pub const unref = gst_date_time_unref;

    extern fn gst_date_time_get_type() usize;
    pub const getGObjectType = gst_date_time_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// This is the struct that describes the categories. Once initialized with
/// `GST_DEBUG_CATEGORY_INIT`, its values can't be changed anymore.
pub const DebugCategory = extern struct {
    f_threshold: c_int,
    f_color: c_uint,
    f_name: ?[*:0]const u8,
    f_description: ?[*:0]const u8,

    /// Removes and frees the category and all associated resources.
    extern fn gst_debug_category_free(p_category: *DebugCategory) void;
    pub const free = gst_debug_category_free;

    /// Returns the color of a debug category used when printing output in this
    /// category.
    extern fn gst_debug_category_get_color(p_category: *DebugCategory) c_uint;
    pub const getColor = gst_debug_category_get_color;

    /// Returns the description of a debug category.
    extern fn gst_debug_category_get_description(p_category: *DebugCategory) [*:0]const u8;
    pub const getDescription = gst_debug_category_get_description;

    /// Returns the name of a debug category.
    extern fn gst_debug_category_get_name(p_category: *DebugCategory) [*:0]const u8;
    pub const getName = gst_debug_category_get_name;

    /// Returns the threshold of a `gst.DebugCategory`.
    extern fn gst_debug_category_get_threshold(p_category: *DebugCategory) gst.DebugLevel;
    pub const getThreshold = gst_debug_category_get_threshold;

    /// Resets the threshold of the category to the default level. Debug information
    /// will only be output if the threshold is lower or equal to the level of the
    /// debugging message.
    /// Use this function to set the threshold back to where it was after using
    /// `gst.DebugCategory.setThreshold`.
    extern fn gst_debug_category_reset_threshold(p_category: *DebugCategory) void;
    pub const resetThreshold = gst_debug_category_reset_threshold;

    /// Sets the threshold of the category to the given level. Debug information will
    /// only be output if the threshold is lower or equal to the level of the
    /// debugging message.
    /// > Do not use this function in production code, because other functions may
    /// > change the threshold of categories as side effect. It is however a nice
    /// > function to use when debugging (even from gdb).
    extern fn gst_debug_category_set_threshold(p_category: *DebugCategory, p_level: gst.DebugLevel) void;
    pub const setThreshold = gst_debug_category_set_threshold;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const DebugMessage = opaque {
    /// Gets the string representation of a `gst.DebugMessage`. This function is used
    /// in debug handlers to extract the message.
    extern fn gst_debug_message_get(p_message: *DebugMessage) ?[*:0]const u8;
    pub const get = gst_debug_message_get;

    /// Get the id of the object that emitted this message. This function is used in
    /// debug handlers. Can be empty.
    extern fn gst_debug_message_get_id(p_message: *DebugMessage) ?[*:0]const u8;
    pub const getId = gst_debug_message_get_id;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The class structure for a `gst.Device` object.
pub const DeviceClass = extern struct {
    pub const Instance = gst.Device;

    /// The parent `gst.ObjectClass` structure.
    f_parent_class: gst.ObjectClass,
    /// Creates the fully configured element to access this device.
    ///  Subclasses need to override this and return a new element.
    f_create_element: ?*const fn (p_device: *gst.Device, p_name: ?[*:0]const u8) callconv(.c) ?*gst.Element,
    /// This only needs to be implemented by subclasses if the
    ///  element can be reconfigured to use a different device. See the documentation
    ///  for `gst.Device.reconfigureElement`.
    f_reconfigure_element: ?*const fn (p_device: *gst.Device, p_element: *gst.Element) callconv(.c) c_int,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *DeviceClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque device monitor class structure.
pub const DeviceMonitorClass = extern struct {
    pub const Instance = gst.DeviceMonitor;

    /// the parent `gst.ObjectClass` structure
    f_parent_class: gst.ObjectClass,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *DeviceMonitorClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const DeviceMonitorPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const DevicePrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The structure of the base `gst.DeviceProviderClass`
pub const DeviceProviderClass = extern struct {
    pub const Instance = gst.DeviceProvider;

    /// the parent `gst.ObjectClass` structure
    f_parent_class: gst.ObjectClass,
    /// a pointer to the `gst.DeviceProviderFactory` that creates this
    ///  provider
    f_factory: ?*gst.DeviceProviderFactory,
    /// Returns a list of devices that are currently available.
    ///  This should never block. The devices should not have a parent and should
    ///  be floating.
    f_probe: ?*const fn (p_provider: *gst.DeviceProvider) callconv(.c) *glib.List,
    /// Starts monitoring for new devices. Only subclasses that can know
    ///  that devices have been added or remove need to implement this method.
    f_start: ?*const fn (p_provider: *gst.DeviceProvider) callconv(.c) c_int,
    /// Stops monitoring for new devices. Only subclasses that implement
    ///  the `start` method need to implement this method.
    f_stop: ?*const fn (p_provider: *gst.DeviceProvider) callconv(.c) void,
    f_metadata: ?*anyopaque,
    f__gst_reserved: [4]*anyopaque,

    /// Set `key` with `value` as metadata in `klass`.
    extern fn gst_device_provider_class_add_metadata(p_klass: *DeviceProviderClass, p_key: [*:0]const u8, p_value: [*:0]const u8) void;
    pub const addMetadata = gst_device_provider_class_add_metadata;

    /// Set `key` with `value` as metadata in `klass`.
    ///
    /// Same as `gst.DeviceProviderClass.addMetadata`, but `value` must be a static string
    /// or an inlined string, as it will not be copied. (GStreamer plugins will
    /// be made resident once loaded, so this function can be used even from
    /// dynamically loaded plugins.)
    extern fn gst_device_provider_class_add_static_metadata(p_klass: *DeviceProviderClass, p_key: [*:0]const u8, p_value: [*:0]const u8) void;
    pub const addStaticMetadata = gst_device_provider_class_add_static_metadata;

    /// Get metadata with `key` in `klass`.
    extern fn gst_device_provider_class_get_metadata(p_klass: *DeviceProviderClass, p_key: [*:0]const u8) ?[*:0]const u8;
    pub const getMetadata = gst_device_provider_class_get_metadata;

    /// Sets the detailed information for a `gst.DeviceProviderClass`.
    ///
    /// > This function is for use in _class_init functions only.
    extern fn gst_device_provider_class_set_metadata(p_klass: *DeviceProviderClass, p_longname: [*:0]const u8, p_classification: [*:0]const u8, p_description: [*:0]const u8, p_author: [*:0]const u8) void;
    pub const setMetadata = gst_device_provider_class_set_metadata;

    /// Sets the detailed information for a `gst.DeviceProviderClass`.
    ///
    /// > This function is for use in _class_init functions only.
    ///
    /// Same as `gst.DeviceProviderClass.setMetadata`, but `longname`, `classification`,
    /// `description`, and `author` must be static strings or inlined strings, as
    /// they will not be copied. (GStreamer plugins will be made resident once
    /// loaded, so this function can be used even from dynamically loaded plugins.)
    extern fn gst_device_provider_class_set_static_metadata(p_klass: *DeviceProviderClass, p_longname: [*:0]const u8, p_classification: [*:0]const u8, p_description: [*:0]const u8, p_author: [*:0]const u8) void;
    pub const setStaticMetadata = gst_device_provider_class_set_static_metadata;

    pub fn as(p_instance: *DeviceProviderClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The opaque `gst.DeviceProviderFactoryClass` data structure.
pub const DeviceProviderFactoryClass = opaque {
    pub const Instance = gst.DeviceProviderFactory;

    pub fn as(p_instance: *DeviceProviderFactoryClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const DeviceProviderPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const DynamicTypeFactoryClass = opaque {
    pub const Instance = gst.DynamicTypeFactory;

    pub fn as(p_instance: *DynamicTypeFactoryClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GStreamer element class. Override the vmethods to implement the element
/// functionality.
pub const ElementClass = extern struct {
    pub const Instance = gst.Element;

    /// the parent class structure
    f_parent_class: gst.ObjectClass,
    /// metadata for elements of this class
    f_metadata: ?*anyopaque,
    /// the `gst.ElementFactory` that creates these elements
    f_elementfactory: ?*gst.ElementFactory,
    /// a `glib.List` of `gst.PadTemplate`
    f_padtemplates: ?*glib.List,
    /// the number of padtemplates
    f_numpadtemplates: c_int,
    /// changed whenever the padtemplates change
    f_pad_templ_cookie: u32,
    f_pad_added: ?*const fn (p_element: *gst.Element, p_pad: *gst.Pad) callconv(.c) void,
    f_pad_removed: ?*const fn (p_element: *gst.Element, p_pad: *gst.Pad) callconv(.c) void,
    f_no_more_pads: ?*const fn (p_element: *gst.Element) callconv(.c) void,
    /// called when a new pad is requested
    f_request_new_pad: ?*const fn (p_element: *gst.Element, p_templ: *gst.PadTemplate, p_name: ?[*:0]const u8, p_caps: ?*const gst.Caps) callconv(.c) ?*gst.Pad,
    /// called when a request pad is to be released
    f_release_pad: ?*const fn (p_element: *gst.Element, p_pad: *gst.Pad) callconv(.c) void,
    /// get the state of the element
    f_get_state: ?*const fn (p_element: *gst.Element, p_state: ?*gst.State, p_pending: ?*gst.State, p_timeout: gst.ClockTime) callconv(.c) gst.StateChangeReturn,
    /// set a new state on the element
    f_set_state: ?*const fn (p_element: *gst.Element, p_state: gst.State) callconv(.c) gst.StateChangeReturn,
    /// called by `set_state` to perform an incremental state change
    f_change_state: ?*const fn (p_element: *gst.Element, p_transition: gst.StateChange) callconv(.c) gst.StateChangeReturn,
    /// called immediately after a new state was set.
    f_state_changed: ?*const fn (p_element: *gst.Element, p_oldstate: gst.State, p_newstate: gst.State, p_pending: gst.State) callconv(.c) void,
    /// set a `gst.Bus` on the element
    f_set_bus: ?*const fn (p_element: *gst.Element, p_bus: ?*gst.Bus) callconv(.c) void,
    /// gets the `gst.Clock` provided by the element
    f_provide_clock: ?*const fn (p_element: *gst.Element) callconv(.c) ?*gst.Clock,
    /// set the `gst.Clock` on the element
    f_set_clock: ?*const fn (p_element: *gst.Element, p_clock: ?*gst.Clock) callconv(.c) c_int,
    /// send a `gst.Event` to the element
    f_send_event: ?*const fn (p_element: *gst.Element, p_event: *gst.Event) callconv(.c) c_int,
    /// perform a `gst.Query` on the element
    f_query: ?*const fn (p_element: *gst.Element, p_query: *gst.Query) callconv(.c) c_int,
    /// called when a message is posted on the element. Chain up to
    ///                the parent class' handler to have it posted on the bus.
    f_post_message: ?*const fn (p_element: *gst.Element, p_message: *gst.Message) callconv(.c) c_int,
    /// set a `gst.Context` on the element
    f_set_context: ?*const fn (p_element: *gst.Element, p_context: *gst.Context) callconv(.c) void,
    f__gst_reserved: [18]*anyopaque,

    /// Set `key` with `value` as metadata in `klass`.
    extern fn gst_element_class_add_metadata(p_klass: *ElementClass, p_key: [*:0]const u8, p_value: [*:0]const u8) void;
    pub const addMetadata = gst_element_class_add_metadata;

    /// Adds a padtemplate to an element class. This is mainly used in the _class_init
    /// functions of classes. If a pad template with the same name as an already
    /// existing one is added the old one is replaced by the new one.
    ///
    /// `templ`'s reference count will be incremented, and any floating
    /// reference will be removed (see `gst.Object.refSink`)
    extern fn gst_element_class_add_pad_template(p_klass: *ElementClass, p_templ: *gst.PadTemplate) void;
    pub const addPadTemplate = gst_element_class_add_pad_template;

    /// Set `key` with `value` as metadata in `klass`.
    ///
    /// Same as `gst.ElementClass.addMetadata`, but `value` must be a static string
    /// or an inlined string, as it will not be copied. (GStreamer plugins will
    /// be made resident once loaded, so this function can be used even from
    /// dynamically loaded plugins.)
    extern fn gst_element_class_add_static_metadata(p_klass: *ElementClass, p_key: [*:0]const u8, p_value: [*:0]const u8) void;
    pub const addStaticMetadata = gst_element_class_add_static_metadata;

    /// Adds a pad template to an element class based on the static pad template
    /// `templ`. This is mainly used in the _class_init functions of element
    /// implementations. If a pad template with the same name already exists,
    /// the old one is replaced by the new one.
    extern fn gst_element_class_add_static_pad_template(p_klass: *ElementClass, p_static_templ: *gst.StaticPadTemplate) void;
    pub const addStaticPadTemplate = gst_element_class_add_static_pad_template;

    /// Adds a pad template to an element class based on the static pad template
    /// `templ`. This is mainly used in the _class_init functions of element
    /// implementations. If a pad template with the same name already exists,
    /// the old one is replaced by the new one.
    extern fn gst_element_class_add_static_pad_template_with_gtype(p_klass: *ElementClass, p_static_templ: *gst.StaticPadTemplate, p_pad_type: usize) void;
    pub const addStaticPadTemplateWithGtype = gst_element_class_add_static_pad_template_with_gtype;

    /// Get metadata with `key` in `klass`.
    extern fn gst_element_class_get_metadata(p_klass: *ElementClass, p_key: [*:0]const u8) [*:0]const u8;
    pub const getMetadata = gst_element_class_get_metadata;

    /// Retrieves a padtemplate from `element_class` with the given name.
    /// > If you use this function in the GInstanceInitFunc of an object class
    /// > that has subclasses, make sure to pass the g_class parameter of the
    /// > GInstanceInitFunc here.
    extern fn gst_element_class_get_pad_template(p_element_class: *ElementClass, p_name: [*:0]const u8) ?*gst.PadTemplate;
    pub const getPadTemplate = gst_element_class_get_pad_template;

    /// Retrieves a list of the pad templates associated with `element_class`. The
    /// list must not be modified by the calling code.
    /// > If you use this function in the GInstanceInitFunc of an object class
    /// > that has subclasses, make sure to pass the g_class parameter of the
    /// > GInstanceInitFunc here.
    extern fn gst_element_class_get_pad_template_list(p_element_class: *ElementClass) *glib.List;
    pub const getPadTemplateList = gst_element_class_get_pad_template_list;

    /// Sets the detailed information for a `gst.ElementClass`.
    /// > This function is for use in _class_init functions only.
    extern fn gst_element_class_set_metadata(p_klass: *ElementClass, p_longname: [*:0]const u8, p_classification: [*:0]const u8, p_description: [*:0]const u8, p_author: [*:0]const u8) void;
    pub const setMetadata = gst_element_class_set_metadata;

    /// Sets the detailed information for a `gst.ElementClass`.
    ///
    /// > This function is for use in _class_init functions only.
    ///
    /// Same as `gst.ElementClass.setMetadata`, but `longname`, `classification`,
    /// `description`, and `author` must be static strings or inlined strings, as
    /// they will not be copied. (GStreamer plugins will be made resident once
    /// loaded, so this function can be used even from dynamically loaded plugins.)
    extern fn gst_element_class_set_static_metadata(p_klass: *ElementClass, p_longname: [*:0]const u8, p_classification: [*:0]const u8, p_description: [*:0]const u8, p_author: [*:0]const u8) void;
    pub const setStaticMetadata = gst_element_class_set_static_metadata;

    pub fn as(p_instance: *ElementClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ElementFactoryClass = opaque {
    pub const Instance = gst.ElementFactory;

    pub fn as(p_instance: *ElementFactoryClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The event class provides factory methods to construct events for sending
/// and functions to query (parse) received events.
///
/// Events are usually created with gst_event_new_*() which takes event-type
/// specific parameters as arguments.
/// To send an event application will usually use `gst.Element.sendEvent` and
/// elements will use `gst.Pad.sendEvent` or `gst.Pad.pushEvent`.
/// The event should be unreffed with `gst.Event.unref` if it has not been sent.
///
/// Events that have been received can be parsed with their respective
/// gst_event_parse_*() functions. It is valid to pass `NULL` for unwanted details.
///
/// Events are passed between elements in parallel to the data stream. Some events
/// are serialized with buffers, others are not. Some events only travel downstream,
/// others only upstream. Some events can travel both upstream and downstream.
///
/// The events are used to signal special conditions in the datastream such as
/// EOS (end of stream) or the start of a new stream-segment.
/// Events are also used to flush the pipeline of any pending data.
///
/// Most of the event API is used inside plugins. Applications usually only
/// construct and use seek events.
/// To do that `gst.Event.newSeek` is used to create a seek event. It takes
/// the needed parameters to specify seeking time and mode.
/// ```
///   GstEvent *event;
///   gboolean result;
///   ...
///   // construct a seek event to play the media from second 2 to 5, flush
///   // the pipeline to decrease latency.
///   event = gst_event_new_seek (1.0,
///      GST_FORMAT_TIME,
///      GST_SEEK_FLAG_FLUSH,
///      GST_SEEK_TYPE_SET, 2 * GST_SECOND,
///      GST_SEEK_TYPE_SET, 5 * GST_SECOND);
///   ...
///   result = gst_element_send_event (pipeline, event);
///   if (!result)
///     g_warning ("seek failed");
///   ...
/// ```
pub const Event = extern struct {
    /// the parent structure
    f_mini_object: gst.MiniObject,
    /// the `gst.EventType` of the event
    f_type: gst.EventType,
    /// the timestamp of the event
    f_timestamp: u64,
    /// the sequence number of the event
    f_seqnum: u32,

    /// Modifies a pointer to a `gst.Event` to point to a different `gst.Event`. The
    /// modification is done atomically (so this is useful for ensuring thread safety
    /// in some cases), and the reference counts are updated appropriately (the old
    /// event is unreffed, the new one is reffed).
    ///
    /// Either `new_event` or the `gst.Event` pointed to by `old_event` may be `NULL`.
    extern fn gst_event_replace(p_old_event: ?**gst.Event, p_new_event: ?*gst.Event) c_int;
    pub const replace = gst_event_replace;

    /// Atomically replace the `gst.Event` pointed to by `old_event` with `NULL` and
    /// return the original event.
    extern fn gst_event_steal(p_old_event: ?**gst.Event) *gst.Event;
    pub const steal = gst_event_steal;

    /// Modifies a pointer to a `gst.Event` to point to a different `gst.Event`. This
    /// function is similar to `gst.eventReplace` except that it takes ownership of
    /// `new_event`.
    ///
    /// Either `new_event` or the `gst.Event` pointed to by `old_event` may be `NULL`.
    extern fn gst_event_take(p_old_event: ?**gst.Event, p_new_event: ?*gst.Event) c_int;
    pub const take = gst_event_take;

    /// Create a new buffersize event. The event is sent downstream and notifies
    /// elements that they should provide a buffer of the specified dimensions.
    ///
    /// When the `async` flag is set, a thread boundary is preferred.
    extern fn gst_event_new_buffer_size(p_format: gst.Format, p_minsize: i64, p_maxsize: i64, p_async: c_int) *gst.Event;
    pub const newBufferSize = gst_event_new_buffer_size;

    /// Create a new CAPS event for `caps`. The caps event can only travel downstream
    /// synchronized with the buffer flow and contains the format of the buffers
    /// that will follow after the event.
    extern fn gst_event_new_caps(p_caps: *gst.Caps) *gst.Event;
    pub const newCaps = gst_event_new_caps;

    /// Create a new custom-typed event. This can be used for anything not
    /// handled by other event-specific functions to pass an event to another
    /// element.
    ///
    /// Make sure to allocate an event type with the `GST_EVENT_MAKE_TYPE` macro,
    /// assigning a free number and filling in the correct direction and
    /// serialization flags.
    ///
    /// New custom events can also be created by subclassing the event type if
    /// needed.
    extern fn gst_event_new_custom(p_type: gst.EventType, p_structure: *gst.Structure) *gst.Event;
    pub const newCustom = gst_event_new_custom;

    /// Create a new EOS event. The eos event can only travel downstream
    /// synchronized with the buffer flow. Elements that receive the EOS
    /// event on a pad can return `GST_FLOW_EOS` as a `gst.FlowReturn`
    /// when data after the EOS event arrives.
    ///
    /// The EOS event will travel down to the sink elements in the pipeline
    /// which will then post the `GST_MESSAGE_EOS` on the bus after they have
    /// finished playing any buffered data.
    ///
    /// When all sinks have posted an EOS message, an EOS message is
    /// forwarded to the application.
    ///
    /// The EOS event itself will not cause any state transitions of the pipeline.
    extern fn gst_event_new_eos() *gst.Event;
    pub const newEos = gst_event_new_eos;

    /// Allocate a new flush start event. The flush start event can be sent
    /// upstream and downstream and travels out-of-bounds with the dataflow.
    ///
    /// It marks pads as being flushing and will make them return
    /// `GST_FLOW_FLUSHING` when used for data flow with `gst.Pad.push`,
    /// `gst.Pad.chain`, `gst.Pad.getRange` and `gst.Pad.pullRange`.
    /// Any event (except a `GST_EVENT_FLUSH_STOP`) received
    /// on a flushing pad will return `FALSE` immediately.
    ///
    /// Elements should unlock any blocking functions and exit their streaming
    /// functions as fast as possible when this event is received.
    ///
    /// This event is typically generated after a seek to flush out all queued data
    /// in the pipeline so that the new media is played as soon as possible.
    extern fn gst_event_new_flush_start() *gst.Event;
    pub const newFlushStart = gst_event_new_flush_start;

    /// Allocate a new flush stop event. The flush stop event can be sent
    /// upstream and downstream and travels serialized with the dataflow.
    /// It is typically sent after sending a FLUSH_START event to make the
    /// pads accept data again.
    ///
    /// Elements can process this event synchronized with the dataflow since
    /// the preceding FLUSH_START event stopped the dataflow.
    ///
    /// This event is typically generated to complete a seek and to resume
    /// dataflow.
    extern fn gst_event_new_flush_stop(p_reset_time: c_int) *gst.Event;
    pub const newFlushStop = gst_event_new_flush_stop;

    /// Create a new GAP event. A gap event can be thought of as conceptually
    /// equivalent to a buffer to signal that there is no data for a certain
    /// amount of time. This is useful to signal a gap to downstream elements
    /// which may wait for data, such as muxers or mixers or overlays, especially
    /// for sparse streams such as subtitle streams.
    extern fn gst_event_new_gap(p_timestamp: gst.ClockTime, p_duration: gst.ClockTime) *gst.Event;
    pub const newGap = gst_event_new_gap;

    /// Create a new instant-rate-change event. This event is sent by seek
    /// handlers (e.g. demuxers) when receiving a seek with the
    /// `GST_SEEK_FLAG_INSTANT_RATE_CHANGE` and signals to downstream elements that
    /// the playback rate in the existing segment should be immediately multiplied
    /// by the `rate_multiplier` factor.
    ///
    /// The flags provided replace any flags in the existing segment, for the
    /// flags within the `GST_SEGMENT_INSTANT_FLAGS` set. Other GstSegmentFlags
    /// are ignored and not transferred in the event.
    extern fn gst_event_new_instant_rate_change(p_rate_multiplier: f64, p_new_flags: gst.SegmentFlags) *gst.Event;
    pub const newInstantRateChange = gst_event_new_instant_rate_change;

    /// Create a new instant-rate-sync-time event. This event is sent by the
    /// pipeline to notify elements handling the instant-rate-change event about
    /// the running-time when the new rate should be applied. The running time
    /// may be in the past when elements handle this event, which can lead to
    /// switching artifacts. The magnitude of those depends on the exact timing
    /// of event delivery to each element and the magnitude of the change in
    /// playback rate being applied.
    ///
    /// The `running_time` and `upstream_running_time` are the same if this
    /// is the first instant-rate adjustment, but will differ for later ones
    /// to compensate for the accumulated offset due to playing at a rate
    /// different to the one indicated in the playback segments.
    extern fn gst_event_new_instant_rate_sync_time(p_rate_multiplier: f64, p_running_time: gst.ClockTime, p_upstream_running_time: gst.ClockTime) *gst.Event;
    pub const newInstantRateSyncTime = gst_event_new_instant_rate_sync_time;

    /// Create a new latency event. The event is sent upstream from the sinks and
    /// notifies elements that they should add an additional `latency` to the
    /// running time before synchronising against the clock.
    ///
    /// The latency is mostly used in live sinks and is always expressed in
    /// the time format.
    extern fn gst_event_new_latency(p_latency: gst.ClockTime) *gst.Event;
    pub const newLatency = gst_event_new_latency;

    /// Create a new navigation event from the given description.
    extern fn gst_event_new_navigation(p_structure: *gst.Structure) *gst.Event;
    pub const newNavigation = gst_event_new_navigation;

    /// Creates a new event containing information specific to a particular
    /// protection system (uniquely identified by `system_id`), by which that
    /// protection system can acquire key(s) to decrypt a protected stream.
    ///
    /// In order for a decryption element to decrypt media
    /// protected using a specific system, it first needs all the
    /// protection system specific information necessary to acquire the decryption
    /// key(s) for that stream. The functions defined here enable this information
    /// to be passed in events from elements that extract it
    /// (e.g., ISOBMFF demuxers, MPEG DASH demuxers) to protection decrypter
    /// elements that use it.
    ///
    /// Events containing protection system specific information are created using
    /// `gst.Event.newProtection`, and they can be parsed by downstream elements
    /// using `gst.Event.parseProtection`.
    ///
    /// In Common Encryption, protection system specific information may be located
    /// within ISOBMFF files, both in movie (moov) boxes and movie fragment (moof)
    /// boxes; it may also be contained in ContentProtection elements within MPEG
    /// DASH MPDs. The events created by `gst.Event.newProtection` contain data
    /// identifying from which of these locations the encapsulated protection system
    /// specific information originated. This origin information is required as
    /// some protection systems use different encodings depending upon where the
    /// information originates.
    ///
    /// The events returned by `gst.Event.newProtection` are implemented
    /// in such a way as to ensure that the most recently-pushed protection info
    /// event of a particular `origin` and `system_id` will
    /// be stuck to the output pad of the sending element.
    extern fn gst_event_new_protection(p_system_id: [*:0]const u8, p_data: *gst.Buffer, p_origin: [*:0]const u8) *gst.Event;
    pub const newProtection = gst_event_new_protection;

    /// Allocate a new qos event with the given values.
    /// The QOS event is generated in an element that wants an upstream
    /// element to either reduce or increase its rate because of
    /// high/low CPU load or other resource usage such as network performance or
    /// throttling. Typically sinks generate these events for each buffer
    /// they receive.
    ///
    /// `type` indicates the reason for the QoS event. `GST_QOS_TYPE_OVERFLOW` is
    /// used when a buffer arrived in time or when the sink cannot keep up with
    /// the upstream datarate. `GST_QOS_TYPE_UNDERFLOW` is when the sink is not
    /// receiving buffers fast enough and thus has to drop late buffers.
    /// `GST_QOS_TYPE_THROTTLE` is used when the datarate is artificially limited
    /// by the application, for example to reduce power consumption.
    ///
    /// `proportion` indicates the real-time performance of the streaming in the
    /// element that generated the QoS event (usually the sink). The value is
    /// generally computed based on more long term statistics about the streams
    /// timestamps compared to the clock.
    /// A value < 1.0 indicates that the upstream element is producing data faster
    /// than real-time. A value > 1.0 indicates that the upstream element is not
    /// producing data fast enough. 1.0 is the ideal `proportion` value. The
    /// proportion value can safely be used to lower or increase the quality of
    /// the element.
    ///
    /// `diff` is the difference against the clock in running time of the last
    /// buffer that caused the element to generate the QOS event. A negative value
    /// means that the buffer with `timestamp` arrived in time. A positive value
    /// indicates how late the buffer with `timestamp` was. When throttling is
    /// enabled, `diff` will be set to the requested throttling interval.
    ///
    /// `timestamp` is the timestamp of the last buffer that cause the element
    /// to generate the QOS event. It is expressed in running time and thus an ever
    /// increasing value.
    ///
    /// The upstream element can use the `diff` and `timestamp` values to decide
    /// whether to process more buffers. For positive `diff`, all buffers with
    /// timestamp <= `timestamp` + `diff` will certainly arrive late in the sink
    /// as well. A (negative) `diff` value so that `timestamp` + `diff` would yield a
    /// result smaller than 0 is not allowed.
    ///
    /// The application can use general event probes to intercept the QoS
    /// event and implement custom application specific QoS handling.
    extern fn gst_event_new_qos(p_type: gst.QOSType, p_proportion: f64, p_diff: gst.ClockTimeDiff, p_timestamp: gst.ClockTime) *gst.Event;
    pub const newQos = gst_event_new_qos;

    /// Create a new reconfigure event. The purpose of the reconfigure event is
    /// to travel upstream and make elements renegotiate their caps or reconfigure
    /// their buffer pools. This is useful when changing properties on elements
    /// or changing the topology of the pipeline.
    extern fn gst_event_new_reconfigure() *gst.Event;
    pub const newReconfigure = gst_event_new_reconfigure;

    /// Allocate a new seek event with the given parameters.
    ///
    /// The seek event configures playback of the pipeline between `start` to `stop`
    /// at the speed given in `rate`, also called a playback segment.
    /// The `start` and `stop` values are expressed in `format`.
    ///
    /// A `rate` of 1.0 means normal playback rate, 2.0 means double speed.
    /// Negatives values means backwards playback. A value of 0.0 for the
    /// rate is not allowed and should be accomplished instead by PAUSING the
    /// pipeline.
    ///
    /// A pipeline has a default playback segment configured with a start
    /// position of 0, a stop position of -1 and a rate of 1.0. The currently
    /// configured playback segment can be queried with `GST_QUERY_SEGMENT`.
    ///
    /// `start_type` and `stop_type` specify how to adjust the currently configured
    /// start and stop fields in playback segment. Adjustments can be made relative
    /// or absolute to the last configured values. A type of `GST_SEEK_TYPE_NONE`
    /// means that the position should not be updated.
    ///
    /// When the rate is positive and `start` has been updated, playback will start
    /// from the newly configured start position.
    ///
    /// For negative rates, playback will start from the newly configured stop
    /// position (if any). If the stop position is updated, it must be different from
    /// -1 (`GST_CLOCK_TIME_NONE`) for negative rates.
    ///
    /// It is not possible to seek relative to the current playback position, to do
    /// this, PAUSE the pipeline, query the current playback position with
    /// `GST_QUERY_POSITION` and update the playback segment current position with a
    /// `GST_SEEK_TYPE_SET` to the desired position.
    extern fn gst_event_new_seek(p_rate: f64, p_format: gst.Format, p_flags: gst.SeekFlags, p_start_type: gst.SeekType, p_start: i64, p_stop_type: gst.SeekType, p_stop: i64) *gst.Event;
    pub const newSeek = gst_event_new_seek;

    /// Create a new SEGMENT event for `segment`. The segment event can only travel
    /// downstream synchronized with the buffer flow and contains timing information
    /// and playback properties for the buffers that will follow.
    ///
    /// The segment event marks the range of buffers to be processed. All
    /// data not within the segment range is not to be processed. This can be
    /// used intelligently by plugins to apply more efficient methods of skipping
    /// unneeded data. The valid range is expressed with the `start` and `stop`
    /// values.
    ///
    /// The time value of the segment is used in conjunction with the start
    /// value to convert the buffer timestamps into the stream time. This is
    /// usually done in sinks to report the current stream_time.
    /// `time` represents the stream_time of a buffer carrying a timestamp of
    /// `start`. `time` cannot be -1.
    ///
    /// `start` cannot be -1, `stop` can be -1. If there
    /// is a valid `stop` given, it must be greater or equal the `start`, including
    /// when the indicated playback `rate` is < 0.
    ///
    /// The `applied_rate` value provides information about any rate adjustment that
    /// has already been made to the timestamps and content on the buffers of the
    /// stream. (`rate` * `applied_rate`) should always equal the rate that has been
    /// requested for playback. For example, if an element has an input segment
    /// with intended playback `rate` of 2.0 and applied_rate of 1.0, it can adjust
    /// incoming timestamps and buffer content by half and output a segment event
    /// with `rate` of 1.0 and `applied_rate` of 2.0
    ///
    /// After a segment event, the buffer stream time is calculated with:
    ///
    ///   time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
    extern fn gst_event_new_segment(p_segment: *const gst.Segment) *gst.Event;
    pub const newSegment = gst_event_new_segment;

    /// Create a new segment-done event. This event is sent by elements that
    /// finish playback of a segment as a result of a segment seek.
    extern fn gst_event_new_segment_done(p_format: gst.Format, p_position: i64) *gst.Event;
    pub const newSegmentDone = gst_event_new_segment_done;

    /// Allocate a new select-streams event.
    ///
    /// The select-streams event requests the specified `streams` to be activated.
    ///
    /// The list of `streams` corresponds to the "Stream ID" of each stream to be
    /// activated. Those ID can be obtained via the `gst.Stream` objects present
    /// in `GST_EVENT_STREAM_START`, `GST_EVENT_STREAM_COLLECTION` or
    /// `GST_MESSAGE_STREAM_COLLECTION`.
    ///
    /// Note: The list of `streams` can not be empty.
    extern fn gst_event_new_select_streams(p_streams: *glib.List) *gst.Event;
    pub const newSelectStreams = gst_event_new_select_streams;

    /// Create a new sink-message event. The purpose of the sink-message event is
    /// to instruct a sink to post the message contained in the event synchronized
    /// with the stream.
    ///
    /// `name` is used to store multiple sticky events on one pad.
    extern fn gst_event_new_sink_message(p_name: [*:0]const u8, p_msg: *gst.Message) *gst.Event;
    pub const newSinkMessage = gst_event_new_sink_message;

    /// Create a new step event. The purpose of the step event is to instruct a sink
    /// to skip `amount` (expressed in `format`) of media. It can be used to implement
    /// stepping through the video frame by frame or for doing fast trick modes.
    ///
    /// A rate of <= 0.0 is not allowed. Pause the pipeline, for the effect of rate
    /// = 0.0 or first reverse the direction of playback using a seek event to get
    /// the same effect as rate < 0.0.
    ///
    /// The `flush` flag will clear any pending data in the pipeline before starting
    /// the step operation.
    ///
    /// The `intermediate` flag instructs the pipeline that this step operation is
    /// part of a larger step operation.
    extern fn gst_event_new_step(p_format: gst.Format, p_amount: u64, p_rate: f64, p_flush: c_int, p_intermediate: c_int) *gst.Event;
    pub const newStep = gst_event_new_step;

    /// Create a new STREAM_COLLECTION event. The stream collection event can only
    /// travel downstream synchronized with the buffer flow.
    ///
    /// Source elements, demuxers and other elements that manage collections
    /// of streams and post `gst.StreamCollection` messages on the bus also send
    /// this event downstream on each pad involved in the collection, so that
    /// activation of a new collection can be tracked through the downstream
    /// data flow.
    extern fn gst_event_new_stream_collection(p_collection: *gst.StreamCollection) *gst.Event;
    pub const newStreamCollection = gst_event_new_stream_collection;

    /// Create a new Stream Group Done event. The stream-group-done event can
    /// only travel downstream synchronized with the buffer flow. Elements
    /// that receive the event on a pad should handle it mostly like EOS,
    /// and emit any data or pending buffers that would depend on more data
    /// arriving and unblock, since there won't be any more data.
    ///
    /// This event is followed by EOS at some point in the future, and is
    /// generally used when switching pads - to unblock downstream so that
    /// new pads can be exposed before sending EOS on the existing pads.
    extern fn gst_event_new_stream_group_done(p_group_id: c_uint) *gst.Event;
    pub const newStreamGroupDone = gst_event_new_stream_group_done;

    /// Create a new STREAM_START event. The stream start event can only
    /// travel downstream synchronized with the buffer flow. It is expected
    /// to be the first event that is sent for a new stream.
    ///
    /// Source elements, demuxers and other elements that create new streams
    /// are supposed to send this event as the first event of a new stream. It
    /// should not be sent after a flushing seek or in similar situations
    /// and is used to mark the beginning of a new logical stream. Elements
    /// combining multiple streams must ensure that this event is only forwarded
    /// downstream once and not for every single input stream.
    ///
    /// The `stream_id` should be a unique string that consists of the upstream
    /// stream-id, / as separator and a unique stream-id for this specific
    /// stream. A new stream-id should only be created for a stream if the upstream
    /// stream is split into (potentially) multiple new streams, e.g. in a demuxer,
    /// but not for every single element in the pipeline.
    /// `gst.Pad.createStreamId` or `gst.Pad.createStreamIdPrintf` can be
    /// used to create a stream-id.  There are no particular semantics for the
    /// stream-id, though it should be deterministic (to support stream matching)
    /// and it might be used to order streams (besides any information conveyed by
    /// stream flags).
    extern fn gst_event_new_stream_start(p_stream_id: [*:0]const u8) *gst.Event;
    pub const newStreamStart = gst_event_new_stream_start;

    /// Generates a metadata tag event from the given `taglist`.
    ///
    /// The scope of the taglist specifies if the taglist applies to the
    /// complete medium or only to this specific stream. As the tag event
    /// is a sticky event, elements should merge tags received from
    /// upstream with a given scope with their own tags with the same
    /// scope and create a new tag event from it.
    extern fn gst_event_new_tag(p_taglist: *gst.TagList) *gst.Event;
    pub const newTag = gst_event_new_tag;

    /// Generate a TOC event from the given `toc`. The purpose of the TOC event is to
    /// inform elements that some kind of the TOC was found.
    extern fn gst_event_new_toc(p_toc: *gst.Toc, p_updated: c_int) *gst.Event;
    pub const newToc = gst_event_new_toc;

    /// Generate a TOC select event with the given `uid`. The purpose of the
    /// TOC select event is to start playback based on the TOC's entry with the
    /// given `uid`.
    extern fn gst_event_new_toc_select(p_uid: [*:0]const u8) *gst.Event;
    pub const newTocSelect = gst_event_new_toc_select;

    /// Copy the event using the event specific copy function.
    extern fn gst_event_copy(p_event: *const Event) *gst.Event;
    pub const copy = gst_event_copy;

    /// Parses a segment `event` and copies the `gst.Segment` into the location
    /// given by `segment`.
    extern fn gst_event_copy_segment(p_event: *Event, p_segment: *gst.Segment) void;
    pub const copySegment = gst_event_copy_segment;

    /// Retrieve the accumulated running time offset of the event.
    ///
    /// Events passing through `GstPads` that have a running time
    /// offset set via `gst.Pad.setOffset` will get their offset
    /// adjusted according to the pad's offset.
    ///
    /// If the event contains any information that related to the
    /// running time, this information will need to be updated
    /// before usage with this offset.
    extern fn gst_event_get_running_time_offset(p_event: *Event) i64;
    pub const getRunningTimeOffset = gst_event_get_running_time_offset;

    /// Retrieve the sequence number of a event.
    ///
    /// Events have ever-incrementing sequence numbers, which may also be set
    /// explicitly via `gst.Event.setSeqnum`. Sequence numbers are typically used to
    /// indicate that a event corresponds to some other set of events or messages,
    /// for example an EOS event corresponding to a SEEK event. It is considered good
    /// practice to make this correspondence when possible, though it is not
    /// required.
    ///
    /// Note that events and messages share the same sequence number incrementor;
    /// two events or messages will never have the same sequence number unless
    /// that correspondence was made explicitly.
    extern fn gst_event_get_seqnum(p_event: *Event) u32;
    pub const getSeqnum = gst_event_get_seqnum;

    /// Access the structure of the event.
    extern fn gst_event_get_structure(p_event: *Event) ?*const gst.Structure;
    pub const getStructure = gst_event_get_structure;

    /// Checks if `event` has the given `name`. This function is usually used to
    /// check the name of a custom event.
    extern fn gst_event_has_name(p_event: *Event, p_name: [*:0]const u8) c_int;
    pub const hasName = gst_event_has_name;

    /// Checks if `event` has the given `name`. This function is usually used to
    /// check the name of a custom event.
    extern fn gst_event_has_name_id(p_event: *Event, p_name: glib.Quark) c_int;
    pub const hasNameId = gst_event_has_name_id;

    /// Get the format, minsize, maxsize and async-flag in the buffersize event.
    extern fn gst_event_parse_buffer_size(p_event: *Event, p_format: ?*gst.Format, p_minsize: ?*i64, p_maxsize: ?*i64, p_async: ?*c_int) void;
    pub const parseBufferSize = gst_event_parse_buffer_size;

    /// Get the caps from `event`. The caps remains valid as long as `event` remains
    /// valid.
    extern fn gst_event_parse_caps(p_event: *Event, p_caps: ?**gst.Caps) void;
    pub const parseCaps = gst_event_parse_caps;

    /// Parse the FLUSH_STOP event and retrieve the `reset_time` member.
    extern fn gst_event_parse_flush_stop(p_event: *Event, p_reset_time: ?*c_int) void;
    pub const parseFlushStop = gst_event_parse_flush_stop;

    /// Extract timestamp and duration from a new GAP event.
    extern fn gst_event_parse_gap(p_event: *Event, p_timestamp: ?*gst.ClockTime, p_duration: ?*gst.ClockTime) void;
    pub const parseGap = gst_event_parse_gap;

    /// Retrieve the gap flags that may have been set on a gap event with
    /// `gst.Event.setGapFlags`.
    extern fn gst_event_parse_gap_flags(p_event: *Event, p_flags: ?*gst.GapFlags) void;
    pub const parseGapFlags = gst_event_parse_gap_flags;

    extern fn gst_event_parse_group_id(p_event: *Event, p_group_id: ?*c_uint) c_int;
    pub const parseGroupId = gst_event_parse_group_id;

    /// Extract rate and flags from an instant-rate-change event.
    extern fn gst_event_parse_instant_rate_change(p_event: *Event, p_rate_multiplier: ?*f64, p_new_flags: ?*gst.SegmentFlags) void;
    pub const parseInstantRateChange = gst_event_parse_instant_rate_change;

    /// Extract the rate multiplier and running times from an instant-rate-sync-time event.
    extern fn gst_event_parse_instant_rate_sync_time(p_event: *Event, p_rate_multiplier: ?*f64, p_running_time: ?*gst.ClockTime, p_upstream_running_time: ?*gst.ClockTime) void;
    pub const parseInstantRateSyncTime = gst_event_parse_instant_rate_sync_time;

    /// Get the latency in the latency event.
    extern fn gst_event_parse_latency(p_event: *Event, p_latency: ?*gst.ClockTime) void;
    pub const parseLatency = gst_event_parse_latency;

    /// Parses an event containing protection system specific information and stores
    /// the results in `system_id`, `data` and `origin`. The data stored in `system_id`,
    /// `origin` and `data` are valid until `event` is released.
    extern fn gst_event_parse_protection(p_event: *Event, p_system_id: ?*[*:0]const u8, p_data: ?**gst.Buffer, p_origin: ?*[*:0]const u8) void;
    pub const parseProtection = gst_event_parse_protection;

    /// Get the type, proportion, diff and timestamp in the qos event. See
    /// `gst.Event.newQos` for more information about the different QoS values.
    ///
    /// `timestamp` will be adjusted for any pad offsets of pads it was passing through.
    extern fn gst_event_parse_qos(p_event: *Event, p_type: ?*gst.QOSType, p_proportion: ?*f64, p_diff: ?*gst.ClockTimeDiff, p_timestamp: ?*gst.ClockTime) void;
    pub const parseQos = gst_event_parse_qos;

    /// Parses a seek `event` and stores the results in the given result locations.
    extern fn gst_event_parse_seek(p_event: *Event, p_rate: ?*f64, p_format: ?*gst.Format, p_flags: ?*gst.SeekFlags, p_start_type: ?*gst.SeekType, p_start: ?*i64, p_stop_type: ?*gst.SeekType, p_stop: ?*i64) void;
    pub const parseSeek = gst_event_parse_seek;

    /// Retrieve the trickmode interval that may have been set on a
    /// seek event with `gst.Event.setSeekTrickmodeInterval`.
    extern fn gst_event_parse_seek_trickmode_interval(p_event: *Event, p_interval: ?*gst.ClockTime) void;
    pub const parseSeekTrickmodeInterval = gst_event_parse_seek_trickmode_interval;

    /// Parses a segment `event` and stores the result in the given `segment` location.
    /// `segment` remains valid only until the `event` is freed. Don't modify the segment
    /// and make a copy if you want to modify it or store it for later use.
    extern fn gst_event_parse_segment(p_event: *Event, p_segment: ?**const gst.Segment) void;
    pub const parseSegment = gst_event_parse_segment;

    /// Extracts the position and format from the segment done message.
    extern fn gst_event_parse_segment_done(p_event: *Event, p_format: ?*gst.Format, p_position: ?*i64) void;
    pub const parseSegmentDone = gst_event_parse_segment_done;

    /// Parse the SELECT_STREAMS event and retrieve the contained streams.
    extern fn gst_event_parse_select_streams(p_event: *Event, p_streams: ?**glib.List) void;
    pub const parseSelectStreams = gst_event_parse_select_streams;

    /// Parse the sink-message event. Unref `msg` after usage.
    extern fn gst_event_parse_sink_message(p_event: *Event, p_msg: ?**gst.Message) void;
    pub const parseSinkMessage = gst_event_parse_sink_message;

    /// Parse the step event.
    extern fn gst_event_parse_step(p_event: *Event, p_format: ?*gst.Format, p_amount: ?*u64, p_rate: ?*f64, p_flush: ?*c_int, p_intermediate: ?*c_int) void;
    pub const parseStep = gst_event_parse_step;

    /// Parse a stream-start `event` and extract the `gst.Stream` from it.
    extern fn gst_event_parse_stream(p_event: *Event, p_stream: ?**gst.Stream) void;
    pub const parseStream = gst_event_parse_stream;

    /// Retrieve new `gst.StreamCollection` from STREAM_COLLECTION event `event`.
    extern fn gst_event_parse_stream_collection(p_event: *Event, p_collection: ?**gst.StreamCollection) void;
    pub const parseStreamCollection = gst_event_parse_stream_collection;

    extern fn gst_event_parse_stream_flags(p_event: *Event, p_flags: ?*gst.StreamFlags) void;
    pub const parseStreamFlags = gst_event_parse_stream_flags;

    /// Parse a stream-group-done `event` and store the result in the given
    /// `group_id` location.
    extern fn gst_event_parse_stream_group_done(p_event: *Event, p_group_id: ?*c_uint) void;
    pub const parseStreamGroupDone = gst_event_parse_stream_group_done;

    /// Parse a stream-id `event` and store the result in the given `stream_id`
    /// location. The string stored in `stream_id` must not be modified and will
    /// remain valid only until `event` gets freed. Make a copy if you want to
    /// modify it or store it for later use.
    extern fn gst_event_parse_stream_start(p_event: *Event, p_stream_id: ?*[*:0]const u8) void;
    pub const parseStreamStart = gst_event_parse_stream_start;

    /// Parses a tag `event` and stores the results in the given `taglist` location.
    /// No reference to the taglist will be returned, it remains valid only until
    /// the `event` is freed. Don't modify or free the taglist, make a copy if you
    /// want to modify it or store it for later use.
    extern fn gst_event_parse_tag(p_event: *Event, p_taglist: ?**gst.TagList) void;
    pub const parseTag = gst_event_parse_tag;

    /// Parse a TOC `event` and store the results in the given `toc` and `updated` locations.
    extern fn gst_event_parse_toc(p_event: *Event, p_toc: ?**gst.Toc, p_updated: ?*c_int) void;
    pub const parseToc = gst_event_parse_toc;

    /// Parse a TOC select `event` and store the results in the given `uid` location.
    extern fn gst_event_parse_toc_select(p_event: *Event, p_uid: ?*[*:0]u8) void;
    pub const parseTocSelect = gst_event_parse_toc_select;

    /// Increase the refcount of this event.
    extern fn gst_event_ref(p_event: *Event) *gst.Event;
    pub const ref = gst_event_ref;

    /// Sets `flags` on `event` to give additional information about the reason for
    /// the `GST_EVENT_GAP`.
    extern fn gst_event_set_gap_flags(p_event: *Event, p_flags: gst.GapFlags) void;
    pub const setGapFlags = gst_event_set_gap_flags;

    /// All streams that have the same group id are supposed to be played
    /// together, i.e. all streams inside a container file should have the
    /// same group id but different stream ids. The group id should change
    /// each time the stream is started, resulting in different group ids
    /// each time a file is played for example.
    ///
    /// Use `gst.utilGroupIdNext` to get a new group id.
    extern fn gst_event_set_group_id(p_event: *Event, p_group_id: c_uint) void;
    pub const setGroupId = gst_event_set_group_id;

    /// Set the running time offset of a event. See
    /// `gst.Event.getRunningTimeOffset` for more information.
    ///
    /// MT safe.
    extern fn gst_event_set_running_time_offset(p_event: *Event, p_offset: i64) void;
    pub const setRunningTimeOffset = gst_event_set_running_time_offset;

    /// Sets a trickmode interval on a (writable) seek event. Elements
    /// that support TRICKMODE_KEY_UNITS seeks SHOULD use this as the minimal
    /// interval between each frame they may output.
    extern fn gst_event_set_seek_trickmode_interval(p_event: *Event, p_interval: gst.ClockTime) void;
    pub const setSeekTrickmodeInterval = gst_event_set_seek_trickmode_interval;

    /// Set the sequence number of a event.
    ///
    /// This function might be called by the creator of a event to indicate that the
    /// event relates to other events or messages. See `gst.Event.getSeqnum` for
    /// more information.
    ///
    /// MT safe.
    extern fn gst_event_set_seqnum(p_event: *Event, p_seqnum: u32) void;
    pub const setSeqnum = gst_event_set_seqnum;

    /// Set the `stream` on the stream-start `event`
    extern fn gst_event_set_stream(p_event: *Event, p_stream: *gst.Stream) void;
    pub const setStream = gst_event_set_stream;

    extern fn gst_event_set_stream_flags(p_event: *Event, p_flags: gst.StreamFlags) void;
    pub const setStreamFlags = gst_event_set_stream_flags;

    /// Decrease the refcount of an event, freeing it if the refcount reaches 0.
    extern fn gst_event_unref(p_event: *Event) void;
    pub const unref = gst_event_unref;

    /// Get a writable version of the structure.
    extern fn gst_event_writable_structure(p_event: *Event) *gst.Structure;
    pub const writableStructure = gst_event_writable_structure;

    extern fn gst_event_get_type() usize;
    pub const getGObjectType = gst_event_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A format definition
pub const FormatDefinition = extern struct {
    /// The unique id of this format
    f_value: gst.Format,
    /// A short nick of the format
    f_nick: ?[*:0]const u8,
    /// A longer description of the format
    f_description: ?[*:0]const u8,
    /// A quark for the nick
    f_quark: glib.Quark,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GhostPadClass = extern struct {
    pub const Instance = gst.GhostPad;

    f_parent_class: gst.ProxyPadClass,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *GhostPadClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const GhostPadPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.IdStr` is string type optimized for short strings and used for structure
/// names, structure field names and in other places.
///
/// Strings up to 16 bytes (including NUL terminator) are stored inline, other
/// strings are stored on the heap.
///
/// ```cpp
/// GstIdStr s = GST_ID_STR_INIT;
///
/// gst_id_str_set (&s, "Hello, World!");
/// g_print ("`s`\n", gst_id_str_as_str (&s));
///
/// gst_id_str_clear (&s);
/// ```
pub const IdStr = extern struct {
    f_pointer: ?*anyopaque,
    f_padding: [8]u8,

    /// Returns a newly heap allocated empty string.
    extern fn gst_id_str_new() *gst.IdStr;
    pub const new = gst_id_str_new;

    extern fn gst_id_str_as_str(p_s: *const IdStr) [*:0]const u8;
    pub const asStr = gst_id_str_as_str;

    /// Clears `s` and sets it to the empty string.
    extern fn gst_id_str_clear(p_s: *IdStr) void;
    pub const clear = gst_id_str_clear;

    /// Copies `s` into newly allocated heap memory.
    extern fn gst_id_str_copy(p_s: *const IdStr) *gst.IdStr;
    pub const copy = gst_id_str_copy;

    /// Copies `s` into `d`.
    extern fn gst_id_str_copy_into(p_d: *IdStr, p_s: *const gst.IdStr) void;
    pub const copyInto = gst_id_str_copy_into;

    /// Frees `s`. This should only be called for heap-allocated `gst.IdStr`.
    extern fn gst_id_str_free(p_s: *IdStr) void;
    pub const free = gst_id_str_free;

    /// Returns the length of `s`, exluding the NUL-terminator. This is equivalent to
    /// calling ``strcmp`` but potentially faster.
    extern fn gst_id_str_get_len(p_s: *const IdStr) usize;
    pub const getLen = gst_id_str_get_len;

    /// Initializes a (usually stack-allocated) id string `s`. The newly-initialized
    /// id string will contain an empty string by default as value.
    extern fn gst_id_str_init(p_s: *IdStr) void;
    pub const init = gst_id_str_init;

    /// Compares `s1` and `s2` for equality.
    extern fn gst_id_str_is_equal(p_s1: *const IdStr, p_s2: *const gst.IdStr) c_int;
    pub const isEqual = gst_id_str_is_equal;

    /// Compares `s1` and `s2` for equality.
    extern fn gst_id_str_is_equal_to_str(p_s1: *const IdStr, p_s2: [*:0]const u8) c_int;
    pub const isEqualToStr = gst_id_str_is_equal_to_str;

    /// Compares `s1` and `s2` with length `len` for equality. `s2` does not have to be
    /// NUL-terminated and `len` should not include the NUL-terminator.
    ///
    /// This is generally faster than `gst.IdStr.isEqualToStr` if the length is
    /// already known.
    extern fn gst_id_str_is_equal_to_str_with_len(p_s1: *const IdStr, p_s2: [*:0]const u8, p_len: usize) c_int;
    pub const isEqualToStrWithLen = gst_id_str_is_equal_to_str_with_len;

    /// Moves `s` into `d` and resets `s`.
    extern fn gst_id_str_move(p_d: *IdStr, p_s: *gst.IdStr) void;
    pub const move = gst_id_str_move;

    /// Sets `s` to the string `value`.
    extern fn gst_id_str_set(p_s: *IdStr, p_value: [*:0]const u8) void;
    pub const set = gst_id_str_set;

    /// Sets `s` to the string `value`. `value` needs to be valid for the remaining
    /// lifetime of the process, e.g. has to be a static string.
    extern fn gst_id_str_set_static_str(p_s: *IdStr, p_value: [*:0]const u8) void;
    pub const setStaticStr = gst_id_str_set_static_str;

    /// Sets `s` to the string `value` of length `len`. `value` needs to be valid for the
    /// remaining lifetime of the process, e.g. has to be a static string.
    ///
    /// `value` must be NUL-terminated and `len` should not include the
    /// NUL-terminator.
    extern fn gst_id_str_set_static_str_with_len(p_s: *IdStr, p_value: [*:0]const u8, p_len: usize) void;
    pub const setStaticStrWithLen = gst_id_str_set_static_str_with_len;

    /// Sets `s` to the string `value` of length `len`. `value` does not have to be
    /// NUL-terminated and `len` should not include the NUL-terminator.
    extern fn gst_id_str_set_with_len(p_s: *IdStr, p_value: [*:0]const u8, p_len: usize) void;
    pub const setWithLen = gst_id_str_set_with_len;

    extern fn gst_id_str_get_type() usize;
    pub const getGObjectType = gst_id_str_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A GstIterator is used to retrieve multiple objects from another object in
/// a threadsafe way.
///
/// Various GStreamer objects provide access to their internal structures using
/// an iterator.
///
/// Note that if calling a GstIterator function results in your code receiving
/// a refcounted object (with, say, `gobject.Value.getObject`), the refcount for that
/// object will not be increased. Your code is responsible for taking a reference
/// if it wants to continue using it later.
///
/// The basic use pattern of an iterator is as follows:
/// ```
///   GstIterator *it = _get_iterator(object);
///   GValue item = G_VALUE_INIT;
///   done = FALSE;
///   while (!done) {
///     switch (gst_iterator_next (it, &item)) {
///       case GST_ITERATOR_OK:
///         ...get/use/change item here...
///         g_value_reset (&item);
///         break;
///       case GST_ITERATOR_RESYNC:
///         ...rollback changes to items...
///         gst_iterator_resync (it);
///         break;
///       case GST_ITERATOR_ERROR:
///         ...wrong parameters were given...
///         done = TRUE;
///         break;
///       case GST_ITERATOR_DONE:
///         done = TRUE;
///         break;
///     }
///   }
///   g_value_unset (&item);
///   gst_iterator_free (it);
/// ```
pub const Iterator = extern struct {
    /// The function to copy the iterator
    f_copy: ?gst.IteratorCopyFunction,
    /// The function to get the next item in the iterator
    f_next: ?gst.IteratorNextFunction,
    /// The function to be called for each item retrieved
    f_item: ?gst.IteratorItemFunction,
    /// The function to call when a resync is needed.
    f_resync: ?gst.IteratorResyncFunction,
    /// The function to call when the iterator is freed
    f_free: ?gst.IteratorFreeFunction,
    /// The iterator that is currently pushed with `gst.Iterator.push`
    f_pushed: ?*gst.Iterator,
    /// The type of the object that this iterator will return
    f_type: usize,
    /// The lock protecting the data structure and the cookie.
    f_lock: ?*glib.Mutex,
    /// The cookie; the value of the master_cookie when this iterator was
    ///          created.
    f_cookie: u32,
    /// A pointer to the master cookie.
    f_master_cookie: ?*u32,
    /// the size of the iterator
    f_size: c_uint,
    f__gst_reserved: [4]*anyopaque,

    /// Create a new iterator. This function is mainly used for objects
    /// implementing the next/resync/free function to iterate a data structure.
    ///
    /// For each item retrieved, the `item` function is called with the lock
    /// held. The `free` function is called when the iterator is freed.
    extern fn gst_iterator_new(p_size: c_uint, p_type: usize, p_lock: *glib.Mutex, p_master_cookie: *u32, p_copy: gst.IteratorCopyFunction, p_next: gst.IteratorNextFunction, p_item: gst.IteratorItemFunction, p_resync: gst.IteratorResyncFunction, p_free: gst.IteratorFreeFunction) *gst.Iterator;
    pub const new = gst_iterator_new;

    /// Create a new iterator designed for iterating `list`.
    ///
    /// The list you iterate is usually part of a data structure `owner` and is
    /// protected with `lock`.
    ///
    /// The iterator will use `lock` to retrieve the next item of the list and it
    /// will then call the `item` function before releasing `lock` again.
    ///
    /// When a concurrent update to the list is performed, usually by `owner` while
    /// holding `lock`, `master_cookie` will be updated. The iterator implementation
    /// will notice the update of the cookie and will return `GST_ITERATOR_RESYNC` to
    /// the user of the iterator in the next call to `gst.Iterator.next`.
    extern fn gst_iterator_new_list(p_type: usize, p_lock: *glib.Mutex, p_master_cookie: *u32, p_list: **glib.List, p_owner: *gobject.Object, p_item: gst.IteratorItemFunction) *gst.Iterator;
    pub const newList = gst_iterator_new_list;

    /// This `gst.Iterator` is a convenient iterator for the common
    /// case where a `gst.Iterator` needs to be returned but only
    /// a single object has to be considered. This happens often
    /// for the `gst.PadIterIntLinkFunction`.
    extern fn gst_iterator_new_single(p_type: usize, p_object: *const gobject.Value) *gst.Iterator;
    pub const newSingle = gst_iterator_new_single;

    /// Copy the iterator and its state.
    extern fn gst_iterator_copy(p_it: *const Iterator) *gst.Iterator;
    pub const copy = gst_iterator_copy;

    /// Create a new iterator from an existing iterator. The new iterator
    /// will only return those elements that match the given compare function `func`.
    /// The first parameter that is passed to `func` is the `gobject.Value` of the current
    /// iterator element and the second parameter is `user_data`. `func` should
    /// return 0 for elements that should be included in the filtered iterator.
    ///
    /// When this iterator is freed, `it` will also be freed.
    extern fn gst_iterator_filter(p_it: *Iterator, p_func: glib.CompareFunc, p_user_data: *const gobject.Value) *gst.Iterator;
    pub const filter = gst_iterator_filter;

    /// Find the first element in `it` that matches the compare function `func`.
    /// `func` should return 0 when the element is found. The first parameter
    /// to `func` will be the current element of the iterator and the
    /// second parameter will be `user_data`.
    /// The result will be stored in `elem` if a result is found.
    ///
    /// The iterator will not be freed.
    ///
    /// This function will return `FALSE` if an error happened to the iterator
    /// or if the element wasn't found.
    extern fn gst_iterator_find_custom(p_it: *Iterator, p_func: glib.CompareFunc, p_elem: *gobject.Value, p_user_data: ?*anyopaque) c_int;
    pub const findCustom = gst_iterator_find_custom;

    /// Folds `func` over the elements of `iter`. That is to say, `func` will be called
    /// as `func` (object, `ret`, `user_data`) for each object in `it`. The normal use
    /// of this procedure is to accumulate the results of operating on the objects in
    /// `ret`.
    ///
    /// This procedure can be used (and is used internally) to implement the
    /// `gst.Iterator.foreach` and `gst.Iterator.findCustom` operations.
    ///
    /// The fold will proceed as long as `func` returns `TRUE`. When the iterator has no
    /// more arguments, `GST_ITERATOR_DONE` will be returned. If `func` returns `FALSE`,
    /// the fold will stop, and `GST_ITERATOR_OK` will be returned. Errors or resyncs
    /// will cause fold to return `GST_ITERATOR_ERROR` or `GST_ITERATOR_RESYNC` as
    /// appropriate.
    ///
    /// The iterator will not be freed.
    extern fn gst_iterator_fold(p_it: *Iterator, p_func: gst.IteratorFoldFunction, p_ret: *gobject.Value, p_user_data: ?*anyopaque) gst.IteratorResult;
    pub const fold = gst_iterator_fold;

    /// Iterate over all element of `it` and call the given function `func` for
    /// each element.
    extern fn gst_iterator_foreach(p_it: *Iterator, p_func: gst.IteratorForeachFunction, p_user_data: ?*anyopaque) gst.IteratorResult;
    pub const foreach = gst_iterator_foreach;

    /// Free the iterator.
    ///
    /// MT safe.
    extern fn gst_iterator_free(p_it: *Iterator) void;
    pub const free = gst_iterator_free;

    /// Get the next item from the iterator in `elem`.
    ///
    /// Only when this function returns `GST_ITERATOR_OK`, `elem` will contain a valid
    /// value. `elem` must have been initialized to the type of the iterator or
    /// initialized to zeroes with `gobject.Value.unset`. The caller is responsible for
    /// unsetting or resetting `elem` with `gobject.Value.unset` or `gobject.Value.reset`
    /// after usage.
    ///
    /// When this function returns `GST_ITERATOR_DONE`, no more elements can be
    /// retrieved from `it`.
    ///
    /// A return value of `GST_ITERATOR_RESYNC` indicates that the element list was
    /// concurrently updated. The user of `it` should call `gst.Iterator.resync` to
    /// get the newly updated list.
    ///
    /// A return value of `GST_ITERATOR_ERROR` indicates an unrecoverable fatal error.
    extern fn gst_iterator_next(p_it: *Iterator, p_elem: *gobject.Value) gst.IteratorResult;
    pub const next = gst_iterator_next;

    /// Pushes `other` iterator onto `it`. All calls performed on `it` are
    /// forwarded to `other`. If `other` returns `GST_ITERATOR_DONE`, it is
    /// popped again and calls are handled by `it` again.
    ///
    /// This function is mainly used by objects implementing the iterator
    /// next function to recurse into substructures.
    ///
    /// When `gst.Iterator.resync` is called on `it`, `other` will automatically be
    /// popped.
    ///
    /// MT safe.
    extern fn gst_iterator_push(p_it: *Iterator, p_other: *gst.Iterator) void;
    pub const push = gst_iterator_push;

    /// Resync the iterator. this function is mostly called
    /// after `gst.Iterator.next` returned `GST_ITERATOR_RESYNC`.
    ///
    /// When an iterator was pushed on `it`, it will automatically be popped again
    /// with this function.
    ///
    /// MT safe.
    extern fn gst_iterator_resync(p_it: *Iterator) void;
    pub const resync = gst_iterator_resync;

    extern fn gst_iterator_get_type() usize;
    pub const getGObjectType = gst_iterator_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A structure containing the result of a map operation such as
/// `gst.Memory.map`. It contains the data and size.
///
/// `gst.MapInfo` cannot be used with `g_auto` because it is ambiguous whether it
/// needs to be unmapped using `gst.Buffer.unmap` or `gst.Memory.unmap`. Instead,
/// `gst.BufferMapInfo` and `gst.MemoryMapInfo` can be used in that case.
pub const MapInfo = extern struct {
    /// a pointer to the mapped memory
    f_memory: ?*gst.Memory,
    /// flags used when mapping the memory
    f_flags: gst.MapFlags,
    /// a pointer to the mapped data
    f_data: ?[*]u8,
    /// the valid size in `data`
    f_size: usize,
    /// the maximum bytes in `data`
    f_maxsize: usize,
    /// extra private user_data that the implementation of the memory
    ///             can use to store extra info.
    f_user_data: [4]*anyopaque,
    f__gst_reserved: [4]*anyopaque,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstMemory is a lightweight refcounted object that wraps a region of memory.
/// They are typically used to manage the data of a `gst.Buffer`.
///
/// A GstMemory object has an allocated region of memory of maxsize. The maximum
/// size does not change during the lifetime of the memory object. The memory
/// also has an offset and size property that specifies the valid range of memory
/// in the allocated region.
///
/// Memory is usually created by allocators with a `gst.Allocator.alloc`
/// method call. When `NULL` is used as the allocator, the default allocator will
/// be used.
///
/// New allocators can be registered with `gst.Allocator.register`.
/// Allocators are identified by name and can be retrieved with
/// `gst.Allocator.find`. `gst.Allocator.setDefault` can be used to change the
/// default allocator.
///
/// New memory can be created with `gst.Memory.newWrapped` that wraps the memory
/// allocated elsewhere.
///
/// Refcounting of the memory block is performed with `gst.Memory.ref` and
/// `gst.Memory.unref`.
///
/// The size of the memory can be retrieved and changed with
/// `gst.Memory.getSizes` and `gst.Memory.resize` respectively.
///
/// Getting access to the data of the memory is performed with `gst.Memory.map`.
/// The call will return a pointer to offset bytes into the region of memory.
/// After the memory access is completed, `gst.Memory.unmap` should be called.
///
/// Memory can be copied with `gst.Memory.copy`, which will return a writable
/// copy. `gst.Memory.share` will create a new memory block that shares the
/// memory with an existing memory block at a custom offset and with a custom
/// size.
///
/// Memory can be efficiently merged when `gst.Memory.isSpan` returns `TRUE`.
pub const Memory = extern struct {
    /// parent structure
    f_mini_object: gst.MiniObject,
    /// pointer to the `gst.Allocator`
    f_allocator: ?*gst.Allocator,
    /// parent memory block
    f_parent: ?*gst.Memory,
    /// the maximum size allocated
    f_maxsize: usize,
    /// the alignment of the memory
    f_align: usize,
    /// the offset where valid data starts
    f_offset: usize,
    /// the size of valid data
    f_size: usize,

    /// Allocate a new memory block that wraps the given `data`.
    ///
    /// The prefix/padding must be filled with 0 if `flags` contains
    /// `GST_MEMORY_FLAG_ZERO_PREFIXED` and `GST_MEMORY_FLAG_ZERO_PADDED` respectively.
    extern fn gst_memory_new_wrapped(p_flags: gst.MemoryFlags, p_data: [*]u8, p_maxsize: usize, p_offset: usize, p_size: usize, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) ?*gst.Memory;
    pub const newWrapped = gst_memory_new_wrapped;

    /// Return a copy of `size` bytes from `mem` starting from `offset`. This copy is
    /// guaranteed to be writable. `size` can be set to -1 to return a copy
    /// from `offset` to the end of the memory region.
    extern fn gst_memory_copy(p_mem: *Memory, p_offset: isize, p_size: isize) ?*gst.Memory;
    pub const copy = gst_memory_copy;

    /// Get the current `size`, `offset` and `maxsize` of `mem`.
    extern fn gst_memory_get_sizes(p_mem: *Memory, p_offset: ?*usize, p_maxsize: ?*usize) usize;
    pub const getSizes = gst_memory_get_sizes;

    /// Initializes a newly allocated `mem` with the given parameters. This function
    /// will call `gst.MiniObject.init` with the default memory parameters.
    extern fn gst_memory_init(p_mem: *Memory, p_flags: gst.MemoryFlags, p_allocator: *gst.Allocator, p_parent: *gst.Memory, p_maxsize: usize, p_align: usize, p_offset: usize, p_size: usize) void;
    pub const init = gst_memory_init;

    /// Check if `mem1` and mem2 share the memory with a common parent memory object
    /// and that the memory is contiguous.
    ///
    /// If this is the case, the memory of `mem1` and `mem2` can be merged
    /// efficiently by performing `gst.Memory.share` on the parent object from
    /// the returned `offset`.
    extern fn gst_memory_is_span(p_mem1: *Memory, p_mem2: *gst.Memory, p_offset: *usize) c_int;
    pub const isSpan = gst_memory_is_span;

    /// Check if `mem` if allocated with an allocator for `mem_type`.
    extern fn gst_memory_is_type(p_mem: *Memory, p_mem_type: [*:0]const u8) c_int;
    pub const isType = gst_memory_is_type;

    /// Create a `gst.Memory` object that is mapped with `flags`. If `mem` is mappable
    /// with `flags`, this function returns the mapped `mem` directly. Otherwise a
    /// mapped copy of `mem` is returned.
    ///
    /// This function takes ownership of old `mem` and returns a reference to a new
    /// `gst.Memory`.
    extern fn gst_memory_make_mapped(p_mem: *Memory, p_info: *gst.MapInfo, p_flags: gst.MapFlags) ?*gst.Memory;
    pub const makeMapped = gst_memory_make_mapped;

    /// Fill `info` with the pointer and sizes of the memory in `mem` that can be
    /// accessed according to `flags`.
    ///
    /// This function can return `FALSE` for various reasons:
    /// - the memory backed by `mem` is not accessible with the given `flags`.
    /// - the memory was already mapped with a different mapping.
    ///
    /// `info` and its contents remain valid for as long as `mem` is valid and
    /// until `gst.Memory.unmap` is called.
    ///
    /// For each `gst.Memory.map` call, a corresponding `gst.Memory.unmap` call
    /// should be done.
    extern fn gst_memory_map(p_mem: *Memory, p_info: *gst.MapInfo, p_flags: gst.MapFlags) c_int;
    pub const map = gst_memory_map;

    /// Increase the refcount of this memory.
    extern fn gst_memory_ref(p_memory: *Memory) *gst.Memory;
    pub const ref = gst_memory_ref;

    /// Resize the memory region. `mem` should be writable and offset + size should be
    /// less than the maxsize of `mem`.
    ///
    /// `GST_MEMORY_FLAG_ZERO_PREFIXED` and `GST_MEMORY_FLAG_ZERO_PADDED` will be
    /// cleared when offset or padding is increased respectively.
    extern fn gst_memory_resize(p_mem: *Memory, p_offset: isize, p_size: usize) void;
    pub const resize = gst_memory_resize;

    /// Return a shared copy of `size` bytes from `mem` starting from `offset`. No
    /// memory copy is performed and the memory region is simply shared. The result
    /// is guaranteed to be non-writable. `size` can be set to -1 to return a shared
    /// copy from `offset` to the end of the memory region.
    extern fn gst_memory_share(p_mem: *Memory, p_offset: isize, p_size: isize) *gst.Memory;
    pub const share = gst_memory_share;

    /// Release the memory obtained with `gst.Memory.map`
    extern fn gst_memory_unmap(p_mem: *Memory, p_info: *gst.MapInfo) void;
    pub const unmap = gst_memory_unmap;

    /// Decrease the refcount of a memory, freeing it if the refcount reaches 0.
    extern fn gst_memory_unref(p_memory: *Memory) void;
    pub const unref = gst_memory_unref;

    extern fn gst_memory_get_type() usize;
    pub const getGObjectType = gst_memory_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Messages are implemented as a subclass of `gst.MiniObject` with a generic
/// `gst.Structure` as the content. This allows for writing custom messages without
/// requiring an API change while allowing a wide range of different types
/// of messages.
///
/// Messages are posted by objects in the pipeline and are passed to the
/// application using the `gst.Bus`.
///
/// The basic use pattern of posting a message on a `gst.Bus` is as follows:
/// ```
///   gst_bus_post (bus, `gst.Message.newEos`);
/// ```
///
/// A `gst.Element` usually posts messages on the bus provided by the parent
/// container using `gst.Element.postMessage`.
pub const Message = extern struct {
    /// the parent structure
    f_mini_object: gst.MiniObject,
    /// the `gst.MessageType` of the message
    f_type: gst.MessageType,
    /// the timestamp of the message
    f_timestamp: u64,
    /// the src of the message
    f_src: ?*gst.Object,
    /// the sequence number of the message
    f_seqnum: u32,
    f_lock: glib.Mutex,
    f_cond: glib.Cond,

    /// Modifies a pointer to a `gst.Message` to point to a different `gst.Message`. The
    /// modification is done atomically (so this is useful for ensuring thread safety
    /// in some cases), and the reference counts are updated appropriately (the old
    /// message is unreffed, the new one is reffed).
    ///
    /// Either `new_message` or the `gst.Message` pointed to by `old_message` may be `NULL`.
    extern fn gst_message_replace(p_old_message: ?**gst.Message, p_new_message: ?*gst.Message) c_int;
    pub const replace = gst_message_replace;

    /// Modifies a pointer to a `gst.Message` to point to a different `gst.Message`. This
    /// function is similar to `gst.messageReplace` except that it takes ownership
    /// of `new_message`.
    extern fn gst_message_take(p_old_message: **gst.Message, p_new_message: ?*gst.Message) c_int;
    pub const take = gst_message_take;

    /// Create a new application-typed message. GStreamer will never create these
    /// messages; they are a gift from us to you. Enjoy.
    extern fn gst_message_new_application(p_src: ?*gst.Object, p_structure: *gst.Structure) *gst.Message;
    pub const newApplication = gst_message_new_application;

    /// The message is posted when elements completed an ASYNC state change.
    /// `running_time` contains the time of the desired running_time when this
    /// elements goes to PLAYING. A value of `GST_CLOCK_TIME_NONE` for `running_time`
    /// means that the element has no clock interaction and thus doesn't care about
    /// the running_time of the pipeline.
    extern fn gst_message_new_async_done(p_src: ?*gst.Object, p_running_time: gst.ClockTime) *gst.Message;
    pub const newAsyncDone = gst_message_new_async_done;

    /// This message is posted by elements when they start an ASYNC state change.
    extern fn gst_message_new_async_start(p_src: ?*gst.Object) *gst.Message;
    pub const newAsyncStart = gst_message_new_async_start;

    /// Create a new buffering message. This message can be posted by an element that
    /// needs to buffer data before it can continue processing. `percent` should be a
    /// value between 0 and 100. A value of 100 means that the buffering completed.
    ///
    /// When `percent` is < 100 the application should PAUSE a PLAYING pipeline. When
    /// `percent` is 100, the application can set the pipeline (back) to PLAYING.
    /// The application must be prepared to receive BUFFERING messages in the
    /// PREROLLING state and may only set the pipeline to PLAYING after receiving a
    /// message with `percent` set to 100, which can happen after the pipeline
    /// completed prerolling.
    ///
    /// MT safe.
    extern fn gst_message_new_buffering(p_src: ?*gst.Object, p_percent: c_int) *gst.Message;
    pub const newBuffering = gst_message_new_buffering;

    /// Create a clock lost message. This message is posted whenever the
    /// clock is not valid anymore.
    ///
    /// If this message is posted by the pipeline, the pipeline will
    /// select a new clock again when it goes to PLAYING. It might therefore
    /// be needed to set the pipeline to PAUSED and PLAYING again.
    extern fn gst_message_new_clock_lost(p_src: ?*gst.Object, p_clock: *gst.Clock) *gst.Message;
    pub const newClockLost = gst_message_new_clock_lost;

    /// Create a clock provide message. This message is posted whenever an
    /// element is ready to provide a clock or lost its ability to provide
    /// a clock (maybe because it paused or became EOS).
    ///
    /// This message is mainly used internally to manage the clock
    /// selection.
    extern fn gst_message_new_clock_provide(p_src: ?*gst.Object, p_clock: *gst.Clock, p_ready: c_int) *gst.Message;
    pub const newClockProvide = gst_message_new_clock_provide;

    /// Create a new custom-typed message. This can be used for anything not
    /// handled by other message-specific functions to pass a message to the
    /// app. The structure field can be `NULL`.
    extern fn gst_message_new_custom(p_type: gst.MessageType, p_src: ?*gst.Object, p_structure: ?*gst.Structure) *gst.Message;
    pub const newCustom = gst_message_new_custom;

    /// Creates a new device-added message. The device-added message is produced by
    /// `gst.DeviceProvider` or a `gst.DeviceMonitor`. They announce the appearance
    /// of monitored devices.
    extern fn gst_message_new_device_added(p_src: ?*gst.Object, p_device: *gst.Device) *gst.Message;
    pub const newDeviceAdded = gst_message_new_device_added;

    /// Creates a new device-changed message. The device-changed message is produced
    /// by `gst.DeviceProvider` or a `gst.DeviceMonitor`. They announce that a device
    /// properties has changed and `device` represent the new modified version of `changed_device`.
    extern fn gst_message_new_device_changed(p_src: ?*gst.Object, p_device: *gst.Device, p_changed_device: *gst.Device) *gst.Message;
    pub const newDeviceChanged = gst_message_new_device_changed;

    /// Creates a new device-removed message. The device-removed message is produced
    /// by `gst.DeviceProvider` or a `gst.DeviceMonitor`. They announce the
    /// disappearance of monitored devices.
    extern fn gst_message_new_device_removed(p_src: ?*gst.Object, p_device: *gst.Device) *gst.Message;
    pub const newDeviceRemoved = gst_message_new_device_removed;

    /// Create a new duration changed message. This message is posted by elements
    /// that know the duration of a stream when the duration changes. This message
    /// is received by bins and is used to calculate the total duration of a
    /// pipeline.
    extern fn gst_message_new_duration_changed(p_src: ?*gst.Object) *gst.Message;
    pub const newDurationChanged = gst_message_new_duration_changed;

    /// Create a new element-specific message. This is meant as a generic way of
    /// allowing one-way communication from an element to an application, for example
    /// "the firewire cable was unplugged". The format of the message should be
    /// documented in the element's documentation. The structure field can be `NULL`.
    extern fn gst_message_new_element(p_src: ?*gst.Object, p_structure: *gst.Structure) *gst.Message;
    pub const newElement = gst_message_new_element;

    /// Create a new eos message. This message is generated and posted in
    /// the sink elements of a GstBin. The bin will only forward the EOS
    /// message to the application if all sinks have posted an EOS message.
    extern fn gst_message_new_eos(p_src: ?*gst.Object) *gst.Message;
    pub const newEos = gst_message_new_eos;

    /// Create a new error message. The message will copy `error` and
    /// `debug`. This message is posted by element when a fatal event
    /// occurred. The pipeline will probably (partially) stop. The application
    /// receiving this message should stop the pipeline.
    extern fn gst_message_new_error(p_src: ?*gst.Object, p_error: *glib.Error, p_debug: [*:0]const u8) *gst.Message;
    pub const newError = gst_message_new_error;

    /// Create a new error message. The message will copy `error` and
    /// `debug`. This message is posted by element when a fatal event
    /// occurred. The pipeline will probably (partially) stop. The application
    /// receiving this message should stop the pipeline.
    extern fn gst_message_new_error_with_details(p_src: ?*gst.Object, p_error: *glib.Error, p_debug: [*:0]const u8, p_details: ?*gst.Structure) *gst.Message;
    pub const newErrorWithDetails = gst_message_new_error_with_details;

    /// This message is posted when an element has a new local `gst.Context`.
    extern fn gst_message_new_have_context(p_src: ?*gst.Object, p_context: *gst.Context) *gst.Message;
    pub const newHaveContext = gst_message_new_have_context;

    /// Create a new info message. The message will make copies of `error` and
    /// `debug`.
    extern fn gst_message_new_info(p_src: ?*gst.Object, p_error: *glib.Error, p_debug: [*:0]const u8) *gst.Message;
    pub const newInfo = gst_message_new_info;

    /// Create a new info message. The message will make copies of `error` and
    /// `debug`.
    extern fn gst_message_new_info_with_details(p_src: ?*gst.Object, p_error: *glib.Error, p_debug: [*:0]const u8, p_details: ?*gst.Structure) *gst.Message;
    pub const newInfoWithDetails = gst_message_new_info_with_details;

    /// Creates a new instant-rate-request message. Elements handling the
    /// instant-rate-change event must post this message. The message is
    /// handled at the pipeline, and allows the pipeline to select the
    /// running time when the rate change should happen and to send an
    /// `GST_EVENT_INSTANT_RATE_SYNC_TIME` event to notify the elements
    /// in the pipeline.
    extern fn gst_message_new_instant_rate_request(p_src: ?*gst.Object, p_rate_multiplier: f64) *gst.Message;
    pub const newInstantRateRequest = gst_message_new_instant_rate_request;

    /// This message can be posted by elements when their latency requirements have
    /// changed.
    extern fn gst_message_new_latency(p_src: ?*gst.Object) *gst.Message;
    pub const newLatency = gst_message_new_latency;

    /// This message is posted when an element needs a specific `gst.Context`.
    extern fn gst_message_new_need_context(p_src: ?*gst.Object, p_context_type: [*:0]const u8) *gst.Message;
    pub const newNeedContext = gst_message_new_need_context;

    /// Create a new clock message. This message is posted whenever the
    /// pipeline selects a new clock for the pipeline.
    extern fn gst_message_new_new_clock(p_src: ?*gst.Object, p_clock: *gst.Clock) *gst.Message;
    pub const newNewClock = gst_message_new_new_clock;

    /// Progress messages are posted by elements when they use an asynchronous task
    /// to perform actions triggered by a state change.
    ///
    /// `code` contains a well defined string describing the action.
    /// `text` should contain a user visible string detailing the current action.
    extern fn gst_message_new_progress(p_src: ?*gst.Object, p_type: gst.ProgressType, p_code: [*:0]const u8, p_text: [*:0]const u8) *gst.Message;
    pub const newProgress = gst_message_new_progress;

    extern fn gst_message_new_property_notify(p_src: *gst.Object, p_property_name: [*:0]const u8, p_val: ?*gobject.Value) *gst.Message;
    pub const newPropertyNotify = gst_message_new_property_notify;

    /// A QOS message is posted on the bus whenever an element decides to drop a
    /// buffer because of QoS reasons or whenever it changes its processing strategy
    /// because of QoS reasons (quality adjustments such as processing at lower
    /// accuracy).
    ///
    /// This message can be posted by an element that performs synchronisation against the
    /// clock (live) or it could be dropped by an element that performs QoS because of QOS
    /// events received from a downstream element (!live).
    ///
    /// `running_time`, `stream_time`, `timestamp`, `duration` should be set to the
    /// respective running-time, stream-time, timestamp and duration of the (dropped)
    /// buffer that generated the QoS event. Values can be left to
    /// GST_CLOCK_TIME_NONE when unknown.
    extern fn gst_message_new_qos(p_src: ?*gst.Object, p_live: c_int, p_running_time: u64, p_stream_time: u64, p_timestamp: u64, p_duration: u64) *gst.Message;
    pub const newQos = gst_message_new_qos;

    /// Creates a new redirect message and adds a new entry to it. Redirect messages
    /// are posted when an element detects that the actual data has to be retrieved
    /// from a different location. This is useful if such a redirection cannot be
    /// handled inside a source element, for example when HTTP 302/303 redirects
    /// return a non-HTTP URL.
    ///
    /// The redirect message can hold multiple entries. The first one is added
    /// when the redirect message is created, with the given location, tag_list,
    /// entry_struct arguments. Use `gst.Message.addRedirectEntry` to add more
    /// entries.
    ///
    /// Each entry has a location, a tag list, and a structure. All of these are
    /// optional. The tag list and structure are useful for additional metadata,
    /// such as bitrate statistics for the given location.
    ///
    /// By default, message recipients should treat entries in the order they are
    /// stored. The recipient should therefore try entry \#0 first, and if this
    /// entry is not acceptable or working, try entry \#1 etc. Senders must make
    /// sure that they add entries in this order. However, recipients are free to
    /// ignore the order and pick an entry that is "best" for them. One example
    /// would be a recipient that scans the entries for the one with the highest
    /// bitrate tag.
    ///
    /// The specified location string is copied. However, ownership over the tag
    /// list and structure are transferred to the message.
    extern fn gst_message_new_redirect(p_src: ?*gst.Object, p_location: [*:0]const u8, p_tag_list: ?*gst.TagList, p_entry_struct: ?*const gst.Structure) *gst.Message;
    pub const newRedirect = gst_message_new_redirect;

    /// This message can be posted by elements when they want to have their state
    /// changed. A typical use case would be an audio server that wants to pause the
    /// pipeline because a higher priority stream is being played.
    extern fn gst_message_new_request_state(p_src: ?*gst.Object, p_state: gst.State) *gst.Message;
    pub const newRequestState = gst_message_new_request_state;

    /// This message is posted when the pipeline running-time should be reset to
    /// `running_time`, like after a flushing seek.
    extern fn gst_message_new_reset_time(p_src: ?*gst.Object, p_running_time: gst.ClockTime) *gst.Message;
    pub const newResetTime = gst_message_new_reset_time;

    /// Create a new segment done message. This message is posted by elements that
    /// finish playback of a segment as a result of a segment seek. This message
    /// is received by the application after all elements that posted a segment_start
    /// have posted the segment_done.
    extern fn gst_message_new_segment_done(p_src: ?*gst.Object, p_format: gst.Format, p_position: i64) *gst.Message;
    pub const newSegmentDone = gst_message_new_segment_done;

    /// Create a new segment message. This message is posted by elements that
    /// start playback of a segment as a result of a segment seek. This message
    /// is not received by the application but is used for maintenance reasons in
    /// container elements.
    extern fn gst_message_new_segment_start(p_src: ?*gst.Object, p_format: gst.Format, p_position: i64) *gst.Message;
    pub const newSegmentStart = gst_message_new_segment_start;

    /// Create a state change message. This message is posted whenever an element
    /// changed its state.
    extern fn gst_message_new_state_changed(p_src: ?*gst.Object, p_oldstate: gst.State, p_newstate: gst.State, p_pending: gst.State) *gst.Message;
    pub const newStateChanged = gst_message_new_state_changed;

    /// Create a state dirty message. This message is posted whenever an element
    /// changed its state asynchronously and is used internally to update the
    /// states of container objects.
    extern fn gst_message_new_state_dirty(p_src: ?*gst.Object) *gst.Message;
    pub const newStateDirty = gst_message_new_state_dirty;

    /// This message is posted by elements when they complete a part, when `intermediate` set
    /// to `TRUE`, or a complete step operation.
    ///
    /// `duration` will contain the amount of time (in GST_FORMAT_TIME) of the stepped
    /// `amount` of media in format `format`.
    extern fn gst_message_new_step_done(p_src: ?*gst.Object, p_format: gst.Format, p_amount: u64, p_rate: f64, p_flush: c_int, p_intermediate: c_int, p_duration: u64, p_eos: c_int) *gst.Message;
    pub const newStepDone = gst_message_new_step_done;

    /// This message is posted by elements when they accept or activate a new step
    /// event for `amount` in `format`.
    ///
    /// `active` is set to `FALSE` when the element accepted the new step event and has
    /// queued it for execution in the streaming threads.
    ///
    /// `active` is set to `TRUE` when the element has activated the step operation and
    /// is now ready to start executing the step in the streaming thread. After this
    /// message is emitted, the application can queue a new step operation in the
    /// element.
    extern fn gst_message_new_step_start(p_src: ?*gst.Object, p_active: c_int, p_format: gst.Format, p_amount: u64, p_rate: f64, p_flush: c_int, p_intermediate: c_int) *gst.Message;
    pub const newStepStart = gst_message_new_step_start;

    /// Creates a new stream-collection message. The message is used to announce new
    /// `gst.StreamCollection`
    extern fn gst_message_new_stream_collection(p_src: ?*gst.Object, p_collection: *gst.StreamCollection) *gst.Message;
    pub const newStreamCollection = gst_message_new_stream_collection;

    /// Create a new stream_start message. This message is generated and posted in
    /// the sink elements of a GstBin. The bin will only forward the STREAM_START
    /// message to the application if all sinks have posted an STREAM_START message.
    extern fn gst_message_new_stream_start(p_src: ?*gst.Object) *gst.Message;
    pub const newStreamStart = gst_message_new_stream_start;

    /// Create a new stream status message. This message is posted when a streaming
    /// thread is created/destroyed or when the state changed.
    extern fn gst_message_new_stream_status(p_src: ?*gst.Object, p_type: gst.StreamStatusType, p_owner: *gst.Element) *gst.Message;
    pub const newStreamStatus = gst_message_new_stream_status;

    /// Creates a new steams-selected message. The message is used to announce
    /// that an array of streams has been selected. This is generally in response
    /// to a `GST_EVENT_SELECT_STREAMS` event, or when an element (such as decodebin3)
    /// makes an initial selection of streams.
    ///
    /// The message also contains the `gst.StreamCollection` to which the various streams
    /// belong to.
    ///
    /// Users of `gst.Message.newStreamsSelected` can add the selected streams with
    /// `gst.Message.streamsSelectedAdd`.
    extern fn gst_message_new_streams_selected(p_src: ?*gst.Object, p_collection: *gst.StreamCollection) *gst.Message;
    pub const newStreamsSelected = gst_message_new_streams_selected;

    /// Create a new structure change message. This message is posted when the
    /// structure of a pipeline is in the process of being changed, for example
    /// when pads are linked or unlinked.
    ///
    /// `src` should be the sinkpad that unlinked or linked.
    extern fn gst_message_new_structure_change(p_src: ?*gst.Object, p_type: gst.StructureChangeType, p_owner: *gst.Element, p_busy: c_int) *gst.Message;
    pub const newStructureChange = gst_message_new_structure_change;

    /// Create a new tag message. The message will take ownership of the tag list.
    /// The message is posted by elements that discovered a new taglist.
    extern fn gst_message_new_tag(p_src: ?*gst.Object, p_tag_list: *gst.TagList) *gst.Message;
    pub const newTag = gst_message_new_tag;

    /// Create a new TOC message. The message is posted by elements
    /// that discovered or updated a TOC.
    extern fn gst_message_new_toc(p_src: ?*gst.Object, p_toc: *gst.Toc, p_updated: c_int) *gst.Message;
    pub const newToc = gst_message_new_toc;

    /// Create a new warning message. The message will make copies of `error` and
    /// `debug`.
    extern fn gst_message_new_warning(p_src: ?*gst.Object, p_error: *glib.Error, p_debug: [*:0]const u8) *gst.Message;
    pub const newWarning = gst_message_new_warning;

    /// Create a new warning message. The message will make copies of `error` and
    /// `debug`.
    extern fn gst_message_new_warning_with_details(p_src: ?*gst.Object, p_error: *glib.Error, p_debug: [*:0]const u8, p_details: ?*gst.Structure) *gst.Message;
    pub const newWarningWithDetails = gst_message_new_warning_with_details;

    /// Creates and appends a new entry.
    ///
    /// The specified location string is copied. However, ownership over the tag
    /// list and structure are transferred to the message.
    extern fn gst_message_add_redirect_entry(p_message: *Message, p_location: [*:0]const u8, p_tag_list: ?*gst.TagList, p_entry_struct: ?*const gst.Structure) void;
    pub const addRedirectEntry = gst_message_add_redirect_entry;

    /// Creates a copy of the message. Returns a copy of the message.
    extern fn gst_message_copy(p_msg: *const Message) *gst.Message;
    pub const copy = gst_message_copy;

    /// Returns the optional details structure of the message. May be NULL if none.
    ///
    /// The returned structure must not be freed.
    extern fn gst_message_get_details(p_message: *Message) ?*const gst.Structure;
    pub const getDetails = gst_message_get_details;

    extern fn gst_message_get_num_redirect_entries(p_message: *Message) usize;
    pub const getNumRedirectEntries = gst_message_get_num_redirect_entries;

    /// Retrieve the sequence number of a message.
    ///
    /// Messages have ever-incrementing sequence numbers, which may also be set
    /// explicitly via `gst.Message.setSeqnum`. Sequence numbers are typically used
    /// to indicate that a message corresponds to some other set of messages or
    /// events, for example a SEGMENT_DONE message corresponding to a SEEK event. It
    /// is considered good practice to make this correspondence when possible, though
    /// it is not required.
    ///
    /// Note that events and messages share the same sequence number incrementor;
    /// two events or messages will never have the same sequence number unless
    /// that correspondence was made explicitly.
    extern fn gst_message_get_seqnum(p_message: *Message) u32;
    pub const getSeqnum = gst_message_get_seqnum;

    /// Extracts the object managing the streaming thread from `message`.
    extern fn gst_message_get_stream_status_object(p_message: *Message) ?*const gobject.Value;
    pub const getStreamStatusObject = gst_message_get_stream_status_object;

    /// Access the structure of the message.
    extern fn gst_message_get_structure(p_message: *Message) ?*const gst.Structure;
    pub const getStructure = gst_message_get_structure;

    /// Checks if `message` has the given `name`. This function is usually used to
    /// check the name of a custom message.
    extern fn gst_message_has_name(p_message: *Message, p_name: [*:0]const u8) c_int;
    pub const hasName = gst_message_has_name;

    /// Extract the running_time from the async_done message.
    ///
    /// MT safe.
    extern fn gst_message_parse_async_done(p_message: *Message, p_running_time: ?*gst.ClockTime) void;
    pub const parseAsyncDone = gst_message_parse_async_done;

    /// Extracts the buffering percent from the GstMessage. see also
    /// `gst.Message.newBuffering`.
    ///
    /// MT safe.
    extern fn gst_message_parse_buffering(p_message: *Message, p_percent: ?*c_int) void;
    pub const parseBuffering = gst_message_parse_buffering;

    /// Extracts the buffering stats values from `message`.
    extern fn gst_message_parse_buffering_stats(p_message: *Message, p_mode: ?*gst.BufferingMode, p_avg_in: ?*c_int, p_avg_out: ?*c_int, p_buffering_left: ?*i64) void;
    pub const parseBufferingStats = gst_message_parse_buffering_stats;

    /// Extracts the lost clock from the GstMessage.
    /// The clock object returned remains valid until the message is freed.
    ///
    /// MT safe.
    extern fn gst_message_parse_clock_lost(p_message: *Message, p_clock: ?**gst.Clock) void;
    pub const parseClockLost = gst_message_parse_clock_lost;

    /// Extracts the clock and ready flag from the GstMessage.
    /// The clock object returned remains valid until the message is freed.
    ///
    /// MT safe.
    extern fn gst_message_parse_clock_provide(p_message: *Message, p_clock: ?**gst.Clock, p_ready: ?*c_int) void;
    pub const parseClockProvide = gst_message_parse_clock_provide;

    /// Parse a context type from an existing GST_MESSAGE_NEED_CONTEXT message.
    extern fn gst_message_parse_context_type(p_message: *Message, p_context_type: ?*[*:0]const u8) c_int;
    pub const parseContextType = gst_message_parse_context_type;

    /// Parses a device-added message. The device-added message is produced by
    /// `gst.DeviceProvider` or a `gst.DeviceMonitor`. It announces the appearance
    /// of monitored devices.
    extern fn gst_message_parse_device_added(p_message: *Message, p_device: ?**gst.Device) void;
    pub const parseDeviceAdded = gst_message_parse_device_added;

    /// Parses a device-changed message. The device-changed message is produced by
    /// `gst.DeviceProvider` or a `gst.DeviceMonitor`. It announces the
    /// disappearance of monitored devices. * It announce that a device properties has
    /// changed and `device` represents the new modified version of `changed_device`.
    extern fn gst_message_parse_device_changed(p_message: *Message, p_device: ?**gst.Device, p_changed_device: ?**gst.Device) void;
    pub const parseDeviceChanged = gst_message_parse_device_changed;

    /// Parses a device-removed message. The device-removed message is produced by
    /// `gst.DeviceProvider` or a `gst.DeviceMonitor`. It announces the
    /// disappearance of monitored devices.
    extern fn gst_message_parse_device_removed(p_message: *Message, p_device: ?**gst.Device) void;
    pub const parseDeviceRemoved = gst_message_parse_device_removed;

    /// Extracts the GError and debug string from the GstMessage. The values returned
    /// in the output arguments are copies; the caller must free them when done.
    ///
    /// Typical usage of this function might be:
    /// ```
    ///   ...
    ///   switch (GST_MESSAGE_TYPE (msg)) {
    ///     case GST_MESSAGE_ERROR: {
    ///       GError *err = NULL;
    ///       gchar *dbg_info = NULL;
    ///
    ///       gst_message_parse_error (msg, &err, &dbg_info);
    ///       g_printerr ("ERROR from element `s`: `s`\n",
    ///           GST_OBJECT_NAME (msg->src), err->message);
    ///       g_printerr ("Debugging info: `s`\n", (dbg_info) ? dbg_info : "none");
    ///       g_error_free (err);
    ///       g_free (dbg_info);
    ///       break;
    ///     }
    ///     ...
    ///   }
    ///   ...
    /// ```
    ///
    /// MT safe.
    extern fn gst_message_parse_error(p_message: *Message, p_gerror: ?**glib.Error, p_debug: ?*[*:0]u8) void;
    pub const parseError = gst_message_parse_error;

    /// Returns the optional details structure, may be NULL if none.
    /// The returned structure must not be freed.
    extern fn gst_message_parse_error_details(p_message: *Message, p_structure: ?**const gst.Structure) void;
    pub const parseErrorDetails = gst_message_parse_error_details;

    /// Returns the details structure if present or will create one if not present.
    /// The returned structure must not be freed.
    extern fn gst_message_parse_error_writable_details(p_message: *Message, p_structure: ?**gst.Structure) void;
    pub const parseErrorWritableDetails = gst_message_parse_error_writable_details;

    /// Extract the group from the STREAM_START message.
    extern fn gst_message_parse_group_id(p_message: *Message, p_group_id: ?*c_uint) c_int;
    pub const parseGroupId = gst_message_parse_group_id;

    /// Extract the context from the HAVE_CONTEXT message.
    ///
    /// MT safe.
    extern fn gst_message_parse_have_context(p_message: *Message, p_context: ?**gst.Context) void;
    pub const parseHaveContext = gst_message_parse_have_context;

    /// Extracts the GError and debug string from the GstMessage. The values returned
    /// in the output arguments are copies; the caller must free them when done.
    ///
    /// MT safe.
    extern fn gst_message_parse_info(p_message: *Message, p_gerror: ?**glib.Error, p_debug: ?*[*:0]u8) void;
    pub const parseInfo = gst_message_parse_info;

    /// Returns the optional details structure, may be NULL if none
    /// The returned structure must not be freed.
    extern fn gst_message_parse_info_details(p_message: *Message, p_structure: ?**const gst.Structure) void;
    pub const parseInfoDetails = gst_message_parse_info_details;

    /// Returns the details structure if present or will create one if not present.
    /// The returned structure must not be freed.
    extern fn gst_message_parse_info_writable_details(p_message: *Message, p_structure: ?**gst.Structure) void;
    pub const parseInfoWritableDetails = gst_message_parse_info_writable_details;

    /// Parses the rate_multiplier from the instant-rate-request message.
    extern fn gst_message_parse_instant_rate_request(p_message: *Message, p_rate_multiplier: ?*f64) void;
    pub const parseInstantRateRequest = gst_message_parse_instant_rate_request;

    /// Extracts the new clock from the GstMessage.
    /// The clock object returned remains valid until the message is freed.
    ///
    /// MT safe.
    extern fn gst_message_parse_new_clock(p_message: *Message, p_clock: ?**gst.Clock) void;
    pub const parseNewClock = gst_message_parse_new_clock;

    /// Parses the progress `type`, `code` and `text`.
    extern fn gst_message_parse_progress(p_message: *Message, p_type: ?*gst.ProgressType, p_code: ?*[*:0]u8, p_text: ?*[*:0]u8) void;
    pub const parseProgress = gst_message_parse_progress;

    /// Parses a property-notify message. These will be posted on the bus only
    /// when set up with `gst.Element.addPropertyNotifyWatch` or
    /// `gst.Element.addPropertyDeepNotifyWatch`.
    extern fn gst_message_parse_property_notify(p_message: *Message, p_object: ?**gst.Object, p_property_name: ?*[*:0]const u8, p_property_value: ?**const gobject.Value) void;
    pub const parsePropertyNotify = gst_message_parse_property_notify;

    /// Extract the timestamps and live status from the QoS message.
    ///
    /// The returned values give the running_time, stream_time, timestamp and
    /// duration of the dropped buffer. Values of GST_CLOCK_TIME_NONE mean unknown
    /// values.
    ///
    /// MT safe.
    extern fn gst_message_parse_qos(p_message: *Message, p_live: ?*c_int, p_running_time: ?*u64, p_stream_time: ?*u64, p_timestamp: ?*u64, p_duration: ?*u64) void;
    pub const parseQos = gst_message_parse_qos;

    /// Extract the QoS stats representing the history of the current continuous
    /// pipeline playback period.
    ///
    /// When `format` is `GST_FORMAT_UNDEFINED` both `dropped` and `processed` are
    /// invalid. Values of -1 for either `processed` or `dropped` mean unknown values.
    ///
    /// MT safe.
    extern fn gst_message_parse_qos_stats(p_message: *Message, p_format: ?*gst.Format, p_processed: ?*u64, p_dropped: ?*u64) void;
    pub const parseQosStats = gst_message_parse_qos_stats;

    /// Extract the QoS values that have been calculated/analysed from the QoS data
    ///
    /// MT safe.
    extern fn gst_message_parse_qos_values(p_message: *Message, p_jitter: ?*i64, p_proportion: ?*f64, p_quality: ?*c_int) void;
    pub const parseQosValues = gst_message_parse_qos_values;

    /// Parses the location and/or structure from the entry with the given index.
    /// The index must be between 0 and `gst.Message.getNumRedirectEntries` - 1.
    /// Returned pointers are valid for as long as this message exists.
    extern fn gst_message_parse_redirect_entry(p_message: *Message, p_entry_index: usize, p_location: ?*[*:0]const u8, p_tag_list: ?**gst.TagList, p_entry_struct: ?**const gst.Structure) void;
    pub const parseRedirectEntry = gst_message_parse_redirect_entry;

    /// Extract the requested state from the request_state message.
    ///
    /// MT safe.
    extern fn gst_message_parse_request_state(p_message: *Message, p_state: ?*gst.State) void;
    pub const parseRequestState = gst_message_parse_request_state;

    /// Extract the running-time from the RESET_TIME message.
    ///
    /// MT safe.
    extern fn gst_message_parse_reset_time(p_message: *Message, p_running_time: ?*gst.ClockTime) void;
    pub const parseResetTime = gst_message_parse_reset_time;

    /// Extracts the position and format from the segment done message.
    ///
    /// MT safe.
    extern fn gst_message_parse_segment_done(p_message: *Message, p_format: ?*gst.Format, p_position: ?*i64) void;
    pub const parseSegmentDone = gst_message_parse_segment_done;

    /// Extracts the position and format from the segment start message.
    ///
    /// MT safe.
    extern fn gst_message_parse_segment_start(p_message: *Message, p_format: ?*gst.Format, p_position: ?*i64) void;
    pub const parseSegmentStart = gst_message_parse_segment_start;

    /// Extracts the old and new states from the GstMessage.
    ///
    /// Typical usage of this function might be:
    /// ```
    ///   ...
    ///   switch (GST_MESSAGE_TYPE (msg)) {
    ///     case GST_MESSAGE_STATE_CHANGED: {
    ///       GstState old_state, new_state;
    ///
    ///       gst_message_parse_state_changed (msg, &old_state, &new_state, NULL);
    ///       g_print ("Element `s` changed state from `s` to `s`.\n",
    ///           GST_OBJECT_NAME (msg->src),
    ///           gst_element_state_get_name (old_state),
    ///           gst_element_state_get_name (new_state));
    ///       break;
    ///     }
    ///     ...
    ///   }
    ///   ...
    /// ```
    ///
    /// MT safe.
    extern fn gst_message_parse_state_changed(p_message: *Message, p_oldstate: ?*gst.State, p_newstate: ?*gst.State, p_pending: ?*gst.State) void;
    pub const parseStateChanged = gst_message_parse_state_changed;

    /// Extract the values the step_done message.
    ///
    /// MT safe.
    extern fn gst_message_parse_step_done(p_message: *Message, p_format: ?*gst.Format, p_amount: ?*u64, p_rate: ?*f64, p_flush: ?*c_int, p_intermediate: ?*c_int, p_duration: ?*u64, p_eos: ?*c_int) void;
    pub const parseStepDone = gst_message_parse_step_done;

    /// Extract the values from step_start message.
    ///
    /// MT safe.
    extern fn gst_message_parse_step_start(p_message: *Message, p_active: ?*c_int, p_format: ?*gst.Format, p_amount: ?*u64, p_rate: ?*f64, p_flush: ?*c_int, p_intermediate: ?*c_int) void;
    pub const parseStepStart = gst_message_parse_step_start;

    /// Parses a stream-collection message.
    extern fn gst_message_parse_stream_collection(p_message: *Message, p_collection: ?**gst.StreamCollection) void;
    pub const parseStreamCollection = gst_message_parse_stream_collection;

    /// Extracts the stream status type and owner the GstMessage. The returned
    /// owner remains valid for as long as the reference to `message` is valid and
    /// should thus not be unreffed.
    ///
    /// MT safe.
    extern fn gst_message_parse_stream_status(p_message: *Message, p_type: *gst.StreamStatusType, p_owner: **gst.Element) void;
    pub const parseStreamStatus = gst_message_parse_stream_status;

    /// Parses a streams-selected message.
    extern fn gst_message_parse_streams_selected(p_message: *Message, p_collection: ?**gst.StreamCollection) void;
    pub const parseStreamsSelected = gst_message_parse_streams_selected;

    /// Extracts the change type and completion status from the GstMessage.
    ///
    /// MT safe.
    extern fn gst_message_parse_structure_change(p_message: *Message, p_type: *gst.StructureChangeType, p_owner: ?**gst.Element, p_busy: ?*c_int) void;
    pub const parseStructureChange = gst_message_parse_structure_change;

    /// Extracts the tag list from the GstMessage. The tag list returned in the
    /// output argument is a copy; the caller must free it when done.
    ///
    /// Typical usage of this function might be:
    /// ```
    ///   ...
    ///   switch (GST_MESSAGE_TYPE (msg)) {
    ///     case GST_MESSAGE_TAG: {
    ///       GstTagList *tags = NULL;
    ///
    ///       gst_message_parse_tag (msg, &tags);
    ///       g_print ("Got tags from element `s`\n", GST_OBJECT_NAME (msg->src));
    ///       handle_tags (tags);
    ///       gst_tag_list_unref (tags);
    ///       break;
    ///     }
    ///     ...
    ///   }
    ///   ...
    /// ```
    ///
    /// MT safe.
    extern fn gst_message_parse_tag(p_message: *Message, p_tag_list: **gst.TagList) void;
    pub const parseTag = gst_message_parse_tag;

    /// Extract the TOC from the `gst.Message`. The TOC returned in the
    /// output argument is a copy; the caller must free it with
    /// `gst_toc_unref` when done.
    ///
    /// MT safe.
    extern fn gst_message_parse_toc(p_message: *Message, p_toc: **gst.Toc, p_updated: *c_int) void;
    pub const parseToc = gst_message_parse_toc;

    /// Extracts the GError and debug string from the GstMessage. The values returned
    /// in the output arguments are copies; the caller must free them when done.
    ///
    /// MT safe.
    extern fn gst_message_parse_warning(p_message: *Message, p_gerror: ?**glib.Error, p_debug: ?*[*:0]u8) void;
    pub const parseWarning = gst_message_parse_warning;

    /// Returns the optional details structure, may be NULL if none
    /// The returned structure must not be freed.
    extern fn gst_message_parse_warning_details(p_message: *Message, p_structure: ?**const gst.Structure) void;
    pub const parseWarningDetails = gst_message_parse_warning_details;

    /// Returns the details structure if present or will create one if not present.
    /// The returned structure must not be freed.
    extern fn gst_message_parse_warning_writable_details(p_message: *Message, p_structure: ?**gst.Structure) void;
    pub const parseWarningWritableDetails = gst_message_parse_warning_writable_details;

    /// Convenience macro to increase the reference count of the message.
    extern fn gst_message_ref(p_msg: *Message) *gst.Message;
    pub const ref = gst_message_ref;

    /// Configures the buffering stats values in `message`.
    extern fn gst_message_set_buffering_stats(p_message: *Message, p_mode: gst.BufferingMode, p_avg_in: c_int, p_avg_out: c_int, p_buffering_left: i64) void;
    pub const setBufferingStats = gst_message_set_buffering_stats;

    /// Add `details` to `message`. Will fail if the message already has details set on
    /// it or if it is not writable.
    extern fn gst_message_set_details(p_message: *Message, p_details: ?*gst.Structure) void;
    pub const setDetails = gst_message_set_details;

    /// Sets the group id on the stream-start message.
    ///
    /// All streams that have the same group id are supposed to be played
    /// together, i.e. all streams inside a container file should have the
    /// same group id but different stream ids. The group id should change
    /// each time the stream is started, resulting in different group ids
    /// each time a file is played for example.
    ///
    /// MT safe.
    extern fn gst_message_set_group_id(p_message: *Message, p_group_id: c_uint) void;
    pub const setGroupId = gst_message_set_group_id;

    /// Set the QoS stats representing the history of the current continuous pipeline
    /// playback period.
    ///
    /// When `format` is `GST_FORMAT_UNDEFINED` both `dropped` and `processed` are
    /// invalid. Values of -1 for either `processed` or `dropped` mean unknown values.
    ///
    /// MT safe.
    extern fn gst_message_set_qos_stats(p_message: *Message, p_format: gst.Format, p_processed: u64, p_dropped: u64) void;
    pub const setQosStats = gst_message_set_qos_stats;

    /// Set the QoS values that have been calculated/analysed from the QoS data
    ///
    /// MT safe.
    extern fn gst_message_set_qos_values(p_message: *Message, p_jitter: i64, p_proportion: f64, p_quality: c_int) void;
    pub const setQosValues = gst_message_set_qos_values;

    /// Set the sequence number of a message.
    ///
    /// This function might be called by the creator of a message to indicate that
    /// the message relates to other messages or events. See `gst.Message.getSeqnum`
    /// for more information.
    ///
    /// MT safe.
    extern fn gst_message_set_seqnum(p_message: *Message, p_seqnum: u32) void;
    pub const setSeqnum = gst_message_set_seqnum;

    /// Configures the object handling the streaming thread. This is usually a
    /// GstTask object but other objects might be added in the future.
    extern fn gst_message_set_stream_status_object(p_message: *Message, p_object: *const gobject.Value) void;
    pub const setStreamStatusObject = gst_message_set_stream_status_object;

    /// Adds the `stream` to the `message`.
    extern fn gst_message_streams_selected_add(p_message: *Message, p_stream: *gst.Stream) void;
    pub const streamsSelectedAdd = gst_message_streams_selected_add;

    /// Returns the number of streams contained in the `message`.
    extern fn gst_message_streams_selected_get_size(p_message: *Message) c_uint;
    pub const streamsSelectedGetSize = gst_message_streams_selected_get_size;

    /// Retrieves the `gst.Stream` with index `index` from the `message`.
    extern fn gst_message_streams_selected_get_stream(p_message: *Message, p_idx: c_uint) ?*gst.Stream;
    pub const streamsSelectedGetStream = gst_message_streams_selected_get_stream;

    /// Convenience macro to decrease the reference count of the message, possibly
    /// freeing it.
    extern fn gst_message_unref(p_msg: *Message) void;
    pub const unref = gst_message_unref;

    /// Returns the details structure of the `message`. If not present it will be
    /// created. Use this function (instead of `gst.Message.getDetails`) if you
    /// want to write to the `details` structure.
    ///
    /// The returned structure must not be freed.
    extern fn gst_message_writable_details(p_message: *Message) *gst.Structure;
    pub const writableDetails = gst_message_writable_details;

    /// Get a writable version of the structure.
    extern fn gst_message_writable_structure(p_message: *Message) *gst.Structure;
    pub const writableStructure = gst_message_writable_structure;

    extern fn gst_message_get_type() usize;
    pub const getGObjectType = gst_message_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.Meta` structure should be included as the first member of a `gst.Buffer`
/// metadata structure. The structure defines the API of the metadata and should
/// be accessible to all elements using the metadata.
///
/// A metadata API is registered with `gst.metaApiTypeRegister` which takes a
/// name for the metadata API and some tags associated with the metadata.
/// With `gst.metaApiTypeHasTag` one can check if a certain metadata API
/// contains a given tag.
///
/// Multiple implementations of a metadata API can be registered.
/// To implement a metadata API, `gst.metaRegister` should be used. This
/// function takes all parameters needed to create, free and transform metadata
/// along with the size of the metadata. The function returns a `gst.MetaInfo`
/// structure that contains the information for the implementation of the API.
///
/// A specific implementation can be retrieved by name with `gst.metaGetInfo`.
///
/// See `gst.Buffer` for how the metadata can be added, retrieved and removed from
/// buffers.
pub const Meta = extern struct {
    /// extra flags for the metadata
    f_flags: gst.MetaFlags,
    /// pointer to the `gst.MetaInfo`
    f_info: ?*const gst.MetaInfo,

    /// When a element like `tee` decides the allocation, each downstream element may
    /// fill different parameters and pass them to `gst.Query.addAllocationMeta`.
    /// In order to keep these parameters, a merge operation is needed. This
    /// aggregate function can combine the parameters from `params0` and `param1`, and
    /// write the result back into `aggregated_params`.
    extern fn gst_meta_api_type_aggregate_params(p_api: usize, p_aggregated_params: **gst.Structure, p_params0: *const gst.Structure, p_params1: *const gst.Structure) c_int;
    pub const apiTypeAggregateParams = gst_meta_api_type_aggregate_params;

    extern fn gst_meta_api_type_get_tags(p_api: usize) [*]const [*:0]const u8;
    pub const apiTypeGetTags = gst_meta_api_type_get_tags;

    /// Check if `api` was registered with `tag`.
    extern fn gst_meta_api_type_has_tag(p_api: usize, p_tag: glib.Quark) c_int;
    pub const apiTypeHasTag = gst_meta_api_type_has_tag;

    /// Register and return a GType for the `api` and associate it with
    /// `tags`.
    extern fn gst_meta_api_type_register(p_api: [*:0]const u8, p_tags: [*][*:0]const u8) usize;
    pub const apiTypeRegister = gst_meta_api_type_register;

    /// This function sets the aggregator function for a specific API type.
    extern fn gst_meta_api_type_set_params_aggregator(p_api: usize, p_aggregator: gst.AllocationMetaParamsAggregator) void;
    pub const apiTypeSetParamsAggregator = gst_meta_api_type_set_params_aggregator;

    /// Recreate a `gst.Meta` from serialized data returned by
    /// `gst.Meta.serialize` and add it to `buffer`.
    ///
    /// Note that the meta must have been previously registered by calling one of
    /// `gst_*_meta_get_info ()` functions.
    ///
    /// `consumed` is set to the number of bytes that can be skipped from `data` to
    /// find the next meta serialization, if any. In case of parsing error that does
    /// not allow to determine that size, `consumed` is set to 0.
    extern fn gst_meta_deserialize(p_buffer: *gst.Buffer, p_data: *const u8, p_size: usize, p_consumed: *u32) ?*gst.Meta;
    pub const deserialize = gst_meta_deserialize;

    /// Lookup a previously registered meta info structure by its implementation name
    /// `impl`.
    extern fn gst_meta_get_info(p_impl: [*:0]const u8) ?*const gst.MetaInfo;
    pub const getInfo = gst_meta_get_info;

    /// Register a new `gst.Meta` implementation.
    ///
    /// The same `info` can be retrieved later with `gst.metaGetInfo` by using
    /// `impl` as the key.
    extern fn gst_meta_register(p_api: usize, p_impl: [*:0]const u8, p_size: usize, p_init_func: gst.MetaInitFunction, p_free_func: gst.MetaFreeFunction, p_transform_func: gst.MetaTransformFunction) *const gst.MetaInfo;
    pub const register = gst_meta_register;

    /// Register a new custom `gst.Meta` implementation, backed by an opaque
    /// structure holding a `gst.Structure`.
    ///
    /// The registered info can be retrieved later with `gst.metaGetInfo` by using
    /// `name` as the key.
    ///
    /// The backing `gst.Structure` can be retrieved with
    /// `gst.CustomMeta.getStructure`, its mutability is conditioned by the
    /// writability of the buffer the meta is attached to.
    ///
    /// When `transform_func` is `NULL`, the meta and its backing `gst.Structure`
    /// will always be copied when the transform operation is copy, other operations
    /// are discarded, copy regions are ignored.
    extern fn gst_meta_register_custom(p_name: [*:0]const u8, p_tags: [*][*:0]const u8, p_transform_func: ?gst.CustomMetaTransformFunction, p_user_data: ?*anyopaque, p_destroy_data: ?glib.DestroyNotify) *const gst.MetaInfo;
    pub const registerCustom = gst_meta_register_custom;

    /// Simplified version of `gst.metaRegisterCustom`, with no tags and no
    /// transform function.
    extern fn gst_meta_register_custom_simple(p_name: [*:0]const u8) *const gst.MetaInfo;
    pub const registerCustomSimple = gst_meta_register_custom_simple;

    /// Meta sequence number compare function. Can be used as `glib.CompareFunc`
    /// or a `glib.CompareDataFunc`.
    extern fn gst_meta_compare_seqnum(p_meta1: *const Meta, p_meta2: *const gst.Meta) c_int;
    pub const compareSeqnum = gst_meta_compare_seqnum;

    /// Gets seqnum for this meta.
    extern fn gst_meta_get_seqnum(p_meta: *const Meta) u64;
    pub const getSeqnum = gst_meta_get_seqnum;

    /// Serialize `meta` into a format that can be stored or transmitted and later
    /// deserialized by `gst.metaDeserialize`.
    ///
    /// This is only supported for meta that implements `gst.MetaInfo.serialize_func`,
    /// `FALSE` is returned otherwise.
    ///
    /// Upon failure, `data`->data pointer could have been reallocated, but `data`->len
    /// won't be modified. This is intended to be able to append multiple metas
    /// into the same `glib.ByteArray`.
    ///
    /// Since serialization size is often the same for every buffer, caller may want
    /// to remember the size of previous data to preallocate the next.
    extern fn gst_meta_serialize(p_meta: *const Meta, p_data: *gst.ByteArrayInterface) c_int;
    pub const serialize = gst_meta_serialize;

    /// Same as `gst.Meta.serialize` but with a `glib.ByteArray` instead of
    /// `gst.ByteArrayInterface`.
    extern fn gst_meta_serialize_simple(p_meta: *const Meta, p_data: *glib.ByteArray) c_int;
    pub const serializeSimple = gst_meta_serialize_simple;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.MetaInfo` provides information about a specific metadata
/// structure.
pub const MetaInfo = extern struct {
    /// tag identifying the metadata structure and api
    f_api: usize,
    /// type identifying the implementor of the api
    f_type: usize,
    /// size of the metadata
    f_size: usize,
    /// function for initializing the metadata
    f_init_func: ?gst.MetaInitFunction,
    /// function for freeing the metadata
    f_free_func: ?gst.MetaFreeFunction,
    /// function for transforming the metadata
    f_transform_func: ?gst.MetaTransformFunction,
    /// Function for serializing the metadata, or `NULL` if not supported by this
    /// meta.
    f_serialize_func: ?gst.MetaSerializeFunction,
    /// Function for deserializing the metadata, or `NULL` if not supported by this
    /// meta.
    f_deserialize_func: ?gst.MetaDeserializeFunction,
    /// Function for clearing the metadata, or `NULL` if not supported by this
    /// meta. This is called by the buffer pool when a buffer is returned for
    /// pooled metas.
    f_clear_func: ?gst.MetaClearFunction,

    /// Creates a new structure that needs to be filled before being
    /// registered.  This structure should filled and then registered with
    /// `gst.MetaInfo.register`.
    ///
    /// Example:
    /// ```c
    /// const GstMetaInfo *
    /// gst_my_meta_get_info (void)
    /// {
    ///   static const GstMetaInfo *meta_info = NULL;
    ///
    ///   if (g_once_init_enter ((GstMetaInfo **) & meta_info)) {
    ///     GstMetaInfo *info = gst_meta_info_new (
    ///       gst_my_meta_api_get_type (),
    ///         "GstMyMeta",
    ///        sizeof (GstMyMeta));
    ///     const GstMetaInfo *meta = NULL;
    ///
    ///     info->init_func = my_meta_init;
    ///     info->free_func = my_meta_free;
    ///     info->transform_func = my_meta_transform;
    ///     info->serialize_func = my_meta_serialize;
    ///     info->deserialize_func = my_meta_deserialize;
    ///     meta = gst_meta_info_register (info);
    ///     g_once_init_leave ((GstMetaInfo **) & meta_info, (GstMetaInfo *) meta);
    ///   }
    ///
    ///   return meta_info;
    /// }
    /// ```
    extern fn gst_meta_info_new(p_api: usize, p_impl: [*:0]const u8, p_size: usize) *gst.MetaInfo;
    pub const new = gst_meta_info_new;

    extern fn gst_meta_info_is_custom(p_info: *const MetaInfo) c_int;
    pub const isCustom = gst_meta_info_is_custom;

    /// Registers a new meta.
    ///
    /// Use the structure returned by `gst.metaInfoNew`, it consumes it and the
    /// structure shouldnt be used after. The one returned by the function can be
    /// kept.
    extern fn gst_meta_info_register(p_info: *MetaInfo) *const gst.MetaInfo;
    pub const register = gst_meta_info_register;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Extra data passed to a "gst-copy" transform `gst.MetaTransformFunction`.
pub const MetaTransformCopy = extern struct {
    /// `TRUE` if only region is copied
    f_region: c_int,
    /// the offset to copy, 0 if `region` is `FALSE`, otherwise > 0
    f_offset: usize,
    /// the size to copy, -1 or the buffer size when `region` is `FALSE`
    f_size: usize,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.MiniObject` is a simple structure that can be used to implement refcounted
/// types.
///
/// Subclasses will include `gst.MiniObject` as the first member in their structure
/// and then call `gst.MiniObject.init` to initialize the `gst.MiniObject` fields.
///
/// `gst.MiniObject.ref` and `gst.MiniObject.unref` increment and decrement the
/// refcount respectively. When the refcount of a mini-object reaches 0, the
/// dispose function is called first and when this returns `TRUE`, the free
/// function of the miniobject is called.
///
/// A copy can be made with `gst.MiniObject.copy`.
///
/// `gst.MiniObject.isWritable` will return `TRUE` when the refcount of the
/// object is exactly 1 and there is no parent or a single parent exists and is
/// writable itself, meaning the current caller has the only reference to the
/// object. `gst.MiniObject.makeWritable` will return a writable version of
/// the object, which might be a new copy when the refcount was not 1.
///
/// Opaque data can be associated with a `gst.MiniObject` with
/// `gst.MiniObject.setQdata` and `gst.MiniObject.getQdata`. The data is
/// meant to be specific to the particular object and is not automatically copied
/// with `gst.MiniObject.copy` or similar methods.
///
/// A weak reference can be added and remove with `gst.MiniObject.weakRef`
/// and `gst.MiniObject.weakUnref` respectively.
pub const MiniObject = extern struct {
    /// the GType of the object
    f_type: usize,
    /// atomic refcount
    f_refcount: c_int,
    /// atomic state of the locks
    f_lockstate: c_int,
    /// extra flags.
    f_flags: c_uint,
    /// a copy function
    f_copy: ?gst.MiniObjectCopyFunction,
    /// a dispose function
    f_dispose: ?gst.MiniObjectDisposeFunction,
    /// the free function
    f_free: ?gst.MiniObjectFreeFunction,
    f_priv_uint: c_uint,
    f_priv_pointer: ?*anyopaque,

    /// Atomically modifies a pointer to point to a new mini-object.
    /// The reference count of `olddata` is decreased and the reference count of
    /// `newdata` is increased.
    ///
    /// Either `newdata` and the value pointed to by `olddata` may be `NULL`.
    extern fn gst_mini_object_replace(p_olddata: ?**gst.MiniObject, p_newdata: ?*gst.MiniObject) c_int;
    pub const replace = gst_mini_object_replace;

    /// Replace the current `gst.MiniObject` pointer to by `olddata` with `NULL` and
    /// return the old value.
    extern fn gst_mini_object_steal(p_olddata: **gst.MiniObject) ?*gst.MiniObject;
    pub const steal = gst_mini_object_steal;

    /// Modifies a pointer to point to a new mini-object. The modification
    /// is done atomically. This version is similar to `gst.miniObjectReplace`
    /// except that it does not increase the refcount of `newdata` and thus
    /// takes ownership of `newdata`.
    ///
    /// Either `newdata` and the value pointed to by `olddata` may be `NULL`.
    extern fn gst_mini_object_take(p_olddata: **gst.MiniObject, p_newdata: *gst.MiniObject) c_int;
    pub const take = gst_mini_object_take;

    /// This adds `parent` as a parent for `object`. Having one ore more parents affects the
    /// writability of `object`: if a `parent` is not writable, `object` is also not
    /// writable, regardless of its refcount. `object` is only writable if all
    /// the parents are writable and its own refcount is exactly 1.
    ///
    /// Note: This function does not take ownership of `parent` and also does not
    /// take an additional reference. It is the responsibility of the caller to
    /// remove the parent again at a later time.
    extern fn gst_mini_object_add_parent(p_object: *MiniObject, p_parent: *gst.MiniObject) void;
    pub const addParent = gst_mini_object_add_parent;

    /// Creates a copy of the mini-object.
    ///
    /// MT safe
    extern fn gst_mini_object_copy(p_mini_object: *const MiniObject) ?*gst.MiniObject;
    pub const copy = gst_mini_object_copy;

    /// This function gets back user data pointers stored via
    /// `gst.MiniObject.setQdata`.
    extern fn gst_mini_object_get_qdata(p_object: *MiniObject, p_quark: glib.Quark) ?*anyopaque;
    pub const getQdata = gst_mini_object_get_qdata;

    /// Initializes a mini-object with the desired type and copy/dispose/free
    /// functions.
    extern fn gst_mini_object_init(p_mini_object: *MiniObject, p_flags: c_uint, p_type: usize, p_copy_func: ?gst.MiniObjectCopyFunction, p_dispose_func: ?gst.MiniObjectDisposeFunction, p_free_func: ?gst.MiniObjectFreeFunction) void;
    pub const init = gst_mini_object_init;

    /// If `mini_object` has the LOCKABLE flag set, check if the current EXCLUSIVE
    /// lock on `object` is the only one, this means that changes to the object will
    /// not be visible to any other object.
    ///
    /// If the LOCKABLE flag is not set, check if the refcount of `mini_object` is
    /// exactly 1, meaning that no other reference exists to the object and that the
    /// object is therefore writable.
    ///
    /// Modification of a mini-object should only be done after verifying that it
    /// is writable.
    extern fn gst_mini_object_is_writable(p_mini_object: *const MiniObject) c_int;
    pub const isWritable = gst_mini_object_is_writable;

    /// Lock the mini-object with the specified access mode in `flags`.
    extern fn gst_mini_object_lock(p_object: *MiniObject, p_flags: gst.LockFlags) c_int;
    pub const lock = gst_mini_object_lock;

    /// Checks if a mini-object is writable.  If not, a writable copy is made and
    /// returned.  This gives away the reference to the original mini object,
    /// and returns a reference to the new object.
    ///
    /// MT safe
    extern fn gst_mini_object_make_writable(p_mini_object: *MiniObject) ?*gst.MiniObject;
    pub const makeWritable = gst_mini_object_make_writable;

    /// Increase the reference count of the mini-object.
    ///
    /// Note that the refcount affects the writability
    /// of `mini`-object, see `gst.MiniObject.isWritable`. It is
    /// important to note that keeping additional references to
    /// GstMiniObject instances can potentially increase the number
    /// of memcpy operations in a pipeline, especially if the miniobject
    /// is a `gst.Buffer`.
    extern fn gst_mini_object_ref(p_mini_object: *MiniObject) *gst.MiniObject;
    pub const ref = gst_mini_object_ref;

    /// This removes `parent` as a parent for `object`. See
    /// `gst.MiniObject.addParent`.
    extern fn gst_mini_object_remove_parent(p_object: *MiniObject, p_parent: *gst.MiniObject) void;
    pub const removeParent = gst_mini_object_remove_parent;

    /// This sets an opaque, named pointer on a miniobject.
    /// The name is specified through a `glib.Quark` (retrieved e.g. via
    /// `glib.quarkFromStaticString`), and the pointer
    /// can be gotten back from the `object` with `gst.MiniObject.getQdata`
    /// until the `object` is disposed.
    /// Setting a previously set user data pointer, overrides (frees)
    /// the old pointer set, using `NULL` as pointer essentially
    /// removes the data stored.
    ///
    /// `destroy` may be specified which is called with `data` as argument
    /// when the `object` is disposed, or the data is being overwritten by
    /// a call to `gst.MiniObject.setQdata` with the same `quark`.
    extern fn gst_mini_object_set_qdata(p_object: *MiniObject, p_quark: glib.Quark, p_data: ?*anyopaque, p_destroy: glib.DestroyNotify) void;
    pub const setQdata = gst_mini_object_set_qdata;

    /// This function gets back user data pointers stored via `gst.MiniObject.setQdata`
    /// and removes the data from `object` without invoking its ``destroy`` function (if
    /// any was set).
    extern fn gst_mini_object_steal_qdata(p_object: *MiniObject, p_quark: glib.Quark) ?*anyopaque;
    pub const stealQdata = gst_mini_object_steal_qdata;

    /// Unlock the mini-object with the specified access mode in `flags`.
    extern fn gst_mini_object_unlock(p_object: *MiniObject, p_flags: gst.LockFlags) void;
    pub const unlock = gst_mini_object_unlock;

    /// Decreases the reference count of the mini-object, possibly freeing
    /// the mini-object.
    extern fn gst_mini_object_unref(p_mini_object: *MiniObject) void;
    pub const unref = gst_mini_object_unref;

    /// Adds a weak reference callback to a mini object. Weak references are
    /// used for notification when a mini object is finalized. They are called
    /// "weak references" because they allow you to safely hold a pointer
    /// to the mini object without calling `gst.MiniObject.ref`
    /// (`gst.MiniObject.ref` adds a strong reference, that is, forces the object
    /// to stay alive).
    extern fn gst_mini_object_weak_ref(p_object: *MiniObject, p_notify: gst.MiniObjectNotify, p_data: ?*anyopaque) void;
    pub const weakRef = gst_mini_object_weak_ref;

    /// Removes a weak reference callback from a mini object.
    extern fn gst_mini_object_weak_unref(p_object: *MiniObject, p_notify: gst.MiniObjectNotify, p_data: ?*anyopaque) void;
    pub const weakUnref = gst_mini_object_weak_unref;

    extern fn gst_mini_object_get_type() usize;
    pub const getGObjectType = gst_mini_object_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GStreamer base object class.
pub const ObjectClass = extern struct {
    pub const Instance = gst.Object;

    /// parent
    f_parent_class: gobject.InitiallyUnownedClass,
    /// separator used by `gst.Object.getPathString`
    f_path_string_separator: ?[*:0]const u8,
    /// default signal handler
    f_deep_notify: ?*const fn (p_object: *gst.Object, p_orig: *gst.Object, p_pspec: *gobject.ParamSpec) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *ObjectClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PadClass = extern struct {
    pub const Instance = gst.Pad;

    f_parent_class: gst.ObjectClass,
    f_linked: ?*const fn (p_pad: *gst.Pad, p_peer: *gst.Pad) callconv(.c) void,
    f_unlinked: ?*const fn (p_pad: *gst.Pad, p_peer: *gst.Pad) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *PadClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PadPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Info passed in the `gst.PadProbeCallback`.
pub const PadProbeInfo = extern struct {
    /// the current probe type
    f_type: gst.PadProbeType,
    /// the id of the probe
    f_id: c_ulong,
    /// type specific data, check the `type` field to know the
    ///    datatype.  This field can be `NULL`.
    f_data: ?*anyopaque,
    /// offset of pull probe, this field is valid when `type` contains
    ///    `GST_PAD_PROBE_TYPE_PULL`
    f_offset: u64,
    /// size of pull probe, this field is valid when `type` contains
    ///    `GST_PAD_PROBE_TYPE_PULL`
    f_size: c_uint,
    anon0: extern union {
        f__gst_reserved: [4]*anyopaque,
        anon0: extern struct {
            f_flow_ret: gst.FlowReturn,
        },
    },

    extern fn gst_pad_probe_info_get_buffer(p_info: *PadProbeInfo) ?*gst.Buffer;
    pub const getBuffer = gst_pad_probe_info_get_buffer;

    extern fn gst_pad_probe_info_get_buffer_list(p_info: *PadProbeInfo) ?*gst.BufferList;
    pub const getBufferList = gst_pad_probe_info_get_buffer_list;

    extern fn gst_pad_probe_info_get_event(p_info: *PadProbeInfo) ?*gst.Event;
    pub const getEvent = gst_pad_probe_info_get_event;

    extern fn gst_pad_probe_info_get_query(p_info: *PadProbeInfo) ?*gst.Query;
    pub const getQuery = gst_pad_probe_info_get_query;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PadTemplateClass = extern struct {
    pub const Instance = gst.PadTemplate;

    f_parent_class: gst.ObjectClass,
    f_pad_created: ?*const fn (p_templ: *gst.PadTemplate, p_pad: *gst.Pad) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *PadTemplateClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A GParamSpec derived structure for arrays of values.
pub const ParamSpecArray = extern struct {
    /// super class
    f_parent_instance: gobject.ParamSpec,
    /// the `gobject.ParamSpec` of the type of values in the array
    f_element_spec: ?*gobject.ParamSpec,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A GParamSpec derived structure that contains the meta data for fractional
/// properties.
pub const ParamSpecFraction = extern struct {
    /// super class
    f_parent_instance: gobject.ParamSpec,
    /// minimal numerator
    f_min_num: c_int,
    /// minimal denominator
    f_min_den: c_int,
    /// maximal numerator
    f_max_num: c_int,
    /// maximal denominator
    f_max_den: c_int,
    /// default numerator
    f_def_num: c_int,
    /// default denominator
    f_def_den: c_int,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.ParentBufferMeta` is a `gst.Meta` which can be attached to a `gst.Buffer`
/// to hold a reference to another buffer that is only released when the child
/// `gst.Buffer` is released.
///
/// Typically, `gst.ParentBufferMeta` is used when the child buffer is directly
/// using the `gst.Memory` of the parent buffer, and wants to prevent the parent
/// buffer from being returned to a buffer pool until the `gst.Memory` is available
/// for re-use.
pub const ParentBufferMeta = extern struct {
    /// the parent `gst.Meta` structure
    f_parent: gst.Meta,
    /// the `gst.Buffer` on which a reference is being held.
    f_buffer: ?*gst.Buffer,

    /// Gets the global `gst.MetaInfo` describing  the `gst.ParentBufferMeta` meta.
    extern fn gst_parent_buffer_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_parent_buffer_meta_get_info;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Opaque structure.
pub const ParseContext = opaque {
    /// Allocates a parse context for use with `gst.parseLaunchFull` or
    /// `gst.parseLaunchvFull`.
    ///
    /// Free-function: gst_parse_context_free
    extern fn gst_parse_context_new() ?*gst.ParseContext;
    pub const new = gst_parse_context_new;

    /// Copies the `context`.
    extern fn gst_parse_context_copy(p_context: *const ParseContext) ?*gst.ParseContext;
    pub const copy = gst_parse_context_copy;

    /// Frees a parse context previously allocated with `gst.ParseContext.new`.
    extern fn gst_parse_context_free(p_context: *ParseContext) void;
    pub const free = gst_parse_context_free;

    /// Retrieve missing elements from a previous run of `gst.parseLaunchFull`
    /// or `gst.parseLaunchvFull`. Will only return results if an error code
    /// of `GST_PARSE_ERROR_NO_SUCH_ELEMENT` was returned.
    extern fn gst_parse_context_get_missing_elements(p_context: *ParseContext) ?[*][*:0]u8;
    pub const getMissingElements = gst_parse_context_get_missing_elements;

    extern fn gst_parse_context_get_type() usize;
    pub const getGObjectType = gst_parse_context_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PipelineClass = extern struct {
    pub const Instance = gst.Pipeline;

    f_parent_class: gst.BinClass,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *PipelineClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PipelinePrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PluginClass = opaque {
    pub const Instance = gst.Plugin;

    pub fn as(p_instance: *PluginClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A plugin should export a variable of this type called plugin_desc. The plugin
/// loader will use the data provided there to initialize the plugin.
///
/// The `licence` parameter must be one of: LGPL, GPL, QPL, GPL/QPL, MPL,
/// BSD, MIT/X11, Proprietary, unknown.
pub const PluginDesc = extern struct {
    /// the major version number of core that plugin was compiled for
    f_major_version: c_int,
    /// the minor version number of core that plugin was compiled for
    f_minor_version: c_int,
    /// a unique name of the plugin
    f_name: ?[*:0]const u8,
    /// description of plugin
    f_description: ?[*:0]const u8,
    /// pointer to the init function of this plugin.
    f_plugin_init: ?gst.PluginInitFunc,
    /// version of the plugin
    f_version: ?[*:0]const u8,
    /// effective license of plugin
    f_license: ?[*:0]const u8,
    /// source module plugin belongs to
    f_source: ?[*:0]const u8,
    /// shipped package plugin belongs to
    f_package: ?[*:0]const u8,
    /// URL to provider of plugin
    f_origin: ?[*:0]const u8,
    /// date time string in ISO 8601
    ///     format (or rather, a subset thereof), or `NULL`. Allowed are the
    ///     following formats: "YYYY-MM-DD" and "YYY-MM-DDTHH:MMZ" (with
    ///     'T' a separator and 'Z' indicating UTC/Zulu time). This field
    ///     should be set via the GST_PACKAGE_RELEASE_DATETIME
    ///     preprocessor macro.
    f_release_datetime: ?[*:0]const u8,
    f__gst_reserved: [4]*anyopaque,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PluginFeatureClass = opaque {
    pub const Instance = gst.PluginFeature;

    pub fn as(p_instance: *PluginFeatureClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.Poll` keeps track of file descriptors much like fd_set (used with
/// select ()) or a struct pollfd array (used with poll ()). Once created with
/// `gst.pollNew`, the set can be used to wait for file descriptors to be
/// readable and/or writable. It is possible to make this wait be controlled
/// by specifying `TRUE` for the `controllable` flag when creating the set (or
/// later calling `gst.Poll.setControllable`).
///
/// New file descriptors are added to the set using `gst.Poll.addFd`, and
/// removed using `gst.Poll.removeFd`. Controlling which file descriptors
/// should be waited for to become readable and/or writable are done using
/// `gst.Poll.fdCtlRead`, `gst.Poll.fdCtlWrite` and `gst.Poll.fdCtlPri`.
///
/// Use `gst.Poll.wait` to wait for the file descriptors to actually become
/// readable and/or writable, or to timeout if no file descriptor is available
/// in time. The wait can be controlled by calling `gst.Poll.restart` and
/// `gst.Poll.setFlushing`.
///
/// Once the file descriptor set has been waited for, one can use
/// `gst.Poll.fdHasClosed` to see if the file descriptor has been closed,
/// `gst.Poll.fdHasError` to see if it has generated an error,
/// `gst.Poll.fdCanRead` to see if it is possible to read from the file
/// descriptor, and `gst.Poll.fdCanWrite` to see if it is possible to
/// write to it.
pub const Poll = opaque {
    /// Create a new file descriptor set. If `controllable`, it
    /// is possible to restart or flush a call to `gst.Poll.wait` with
    /// `gst.Poll.restart` and `gst.Poll.setFlushing` respectively.
    ///
    /// Free-function: gst_poll_free
    extern fn gst_poll_new(p_controllable: c_int) ?*gst.Poll;
    pub const new = gst_poll_new;

    /// Create a new poll object that can be used for scheduling cancellable
    /// timeouts.
    ///
    /// A timeout is performed with `gst.Poll.wait`. Multiple timeouts can be
    /// performed from different threads.
    ///
    /// Free-function: gst_poll_free
    extern fn gst_poll_new_timer() ?*gst.Poll;
    pub const newTimer = gst_poll_new_timer;

    /// Add a file descriptor to the file descriptor set.
    extern fn gst_poll_add_fd(p_set: *Poll, p_fd: *gst.PollFD) c_int;
    pub const addFd = gst_poll_add_fd;

    /// Check if `fd` in `set` has data to be read.
    extern fn gst_poll_fd_can_read(p_set: *const Poll, p_fd: *gst.PollFD) c_int;
    pub const fdCanRead = gst_poll_fd_can_read;

    /// Check if `fd` in `set` can be used for writing.
    extern fn gst_poll_fd_can_write(p_set: *const Poll, p_fd: *gst.PollFD) c_int;
    pub const fdCanWrite = gst_poll_fd_can_write;

    /// Control whether the descriptor `fd` in `set` will be monitored for
    /// exceptional conditions (POLLPRI).
    ///
    /// Not implemented on Windows (will just return `FALSE` there).
    extern fn gst_poll_fd_ctl_pri(p_set: *Poll, p_fd: *gst.PollFD, p_active: c_int) c_int;
    pub const fdCtlPri = gst_poll_fd_ctl_pri;

    /// Control whether the descriptor `fd` in `set` will be monitored for
    /// readability.
    extern fn gst_poll_fd_ctl_read(p_set: *Poll, p_fd: *gst.PollFD, p_active: c_int) c_int;
    pub const fdCtlRead = gst_poll_fd_ctl_read;

    /// Control whether the descriptor `fd` in `set` will be monitored for
    /// writability.
    extern fn gst_poll_fd_ctl_write(p_set: *Poll, p_fd: *gst.PollFD, p_active: c_int) c_int;
    pub const fdCtlWrite = gst_poll_fd_ctl_write;

    /// Check if `fd` in `set` has closed the connection.
    extern fn gst_poll_fd_has_closed(p_set: *const Poll, p_fd: *gst.PollFD) c_int;
    pub const fdHasClosed = gst_poll_fd_has_closed;

    /// Check if `fd` in `set` has an error.
    extern fn gst_poll_fd_has_error(p_set: *const Poll, p_fd: *gst.PollFD) c_int;
    pub const fdHasError = gst_poll_fd_has_error;

    /// Check if `fd` in `set` has an exceptional condition (POLLPRI).
    ///
    /// Not implemented on Windows (will just return `FALSE` there).
    extern fn gst_poll_fd_has_pri(p_set: *const Poll, p_fd: *gst.PollFD) c_int;
    pub const fdHasPri = gst_poll_fd_has_pri;

    /// Mark `fd` as ignored so that the next call to `gst.Poll.wait` will yield
    /// the same result for `fd` as last time. This function must be called if no
    /// operation (read/write/recv/send/etc.) will be performed on `fd` before
    /// the next call to `gst.Poll.wait`.
    ///
    /// The reason why this is needed is because the underlying implementation
    /// might not allow querying the fd more than once between calls to one of
    /// the re-enabling operations.
    extern fn gst_poll_fd_ignored(p_set: *Poll, p_fd: *gst.PollFD) void;
    pub const fdIgnored = gst_poll_fd_ignored;

    /// Free a file descriptor set.
    extern fn gst_poll_free(p_set: *Poll) void;
    pub const free = gst_poll_free;

    /// Get a GPollFD for the reading part of the control socket. This is useful when
    /// integrating with a GSource and GMainLoop.
    extern fn gst_poll_get_read_gpollfd(p_set: *Poll, p_fd: *glib.PollFD) void;
    pub const getReadGpollfd = gst_poll_get_read_gpollfd;

    /// Read a byte from the control socket of the controllable `set`.
    ///
    /// This function only works for timer `gst.Poll` objects created with
    /// `gst.pollNewTimer`.
    extern fn gst_poll_read_control(p_set: *Poll) c_int;
    pub const readControl = gst_poll_read_control;

    /// Remove a file descriptor from the file descriptor set.
    extern fn gst_poll_remove_fd(p_set: *Poll, p_fd: *gst.PollFD) c_int;
    pub const removeFd = gst_poll_remove_fd;

    /// Restart any `gst.Poll.wait` that is in progress. This function is typically
    /// used after adding or removing descriptors to `set`.
    ///
    /// If `set` is not controllable, then this call will have no effect.
    ///
    /// This function only works for non-timer `gst.Poll` objects created with
    /// `gst.pollNew`.
    extern fn gst_poll_restart(p_set: *Poll) void;
    pub const restart = gst_poll_restart;

    /// When `controllable` is `TRUE`, this function ensures that future calls to
    /// `gst.Poll.wait` will be affected by `gst.Poll.restart` and
    /// `gst.Poll.setFlushing`.
    ///
    /// This function only works for non-timer `gst.Poll` objects created with
    /// `gst.pollNew`.
    extern fn gst_poll_set_controllable(p_set: *Poll, p_controllable: c_int) c_int;
    pub const setControllable = gst_poll_set_controllable;

    /// When `flushing` is `TRUE`, this function ensures that current and future calls
    /// to `gst.Poll.wait` will return -1, with errno set to EBUSY.
    ///
    /// Unsetting the flushing state will restore normal operation of `set`.
    ///
    /// This function only works for non-timer `gst.Poll` objects created with
    /// `gst.pollNew`.
    extern fn gst_poll_set_flushing(p_set: *Poll, p_flushing: c_int) void;
    pub const setFlushing = gst_poll_set_flushing;

    /// Wait for activity on the file descriptors in `set`. This function waits up to
    /// the specified `timeout`.  A timeout of `GST_CLOCK_TIME_NONE` waits forever.
    ///
    /// For `gst.Poll` objects created with `gst.pollNew`, this function can only be
    /// called from a single thread at a time.  If called from multiple threads,
    /// -1 will be returned with errno set to EPERM.
    ///
    /// This is not true for timer `gst.Poll` objects created with
    /// `gst.pollNewTimer`, where it is allowed to have multiple threads waiting
    /// simultaneously.
    extern fn gst_poll_wait(p_set: *Poll, p_timeout: gst.ClockTime) c_int;
    pub const wait = gst_poll_wait;

    /// Write a byte to the control socket of the controllable `set`.
    /// This function is mostly useful for timer `gst.Poll` objects created with
    /// `gst.pollNewTimer`.
    ///
    /// It will make any current and future `gst.Poll.wait` function return with
    /// 1, meaning the control socket is set. After an equal amount of calls to
    /// `gst.Poll.readControl` have been performed, calls to `gst.Poll.wait` will
    /// block again until their timeout expired.
    ///
    /// This function only works for timer `gst.Poll` objects created with
    /// `gst.pollNewTimer`.
    extern fn gst_poll_write_control(p_set: *Poll) c_int;
    pub const writeControl = gst_poll_write_control;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A file descriptor object.
pub const PollFD = extern struct {
    /// a file descriptor
    f_fd: c_int,
    f_idx: c_int,

    /// Initializes `fd`. Alternatively you can initialize it with
    /// `GST_POLL_FD_INIT`.
    extern fn gst_poll_fd_init(p_fd: *PollFD) void;
    pub const init = gst_poll_fd_init;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.Preset` interface.
pub const PresetInterface = extern struct {
    pub const Instance = gst.Preset;

    /// parent interface type.
    f_parent: gobject.TypeInterface,
    /// virtual method to get list of presets
    f_get_preset_names: ?*const fn (p_preset: *gst.Preset) callconv(.c) [*][*:0]u8,
    /// virtual methods to get properties that are persistent
    f_get_property_names: ?*const fn (p_preset: *gst.Preset) callconv(.c) [*][*:0]u8,
    /// virtual methods to load a preset into properties
    f_load_preset: ?*const fn (p_preset: *gst.Preset, p_name: [*:0]const u8) callconv(.c) c_int,
    /// virtual methods to save properties into a preset
    f_save_preset: ?*const fn (p_preset: *gst.Preset, p_name: [*:0]const u8) callconv(.c) c_int,
    /// virtual methods to rename a preset
    f_rename_preset: ?*const fn (p_preset: *gst.Preset, p_old_name: [*:0]const u8, p_new_name: [*:0]const u8) callconv(.c) c_int,
    /// virtual methods to remove a preset
    f_delete_preset: ?*const fn (p_preset: *gst.Preset, p_name: [*:0]const u8) callconv(.c) c_int,
    /// virtual methods to set textual meta data to a preset
    f_set_meta: ?*const fn (p_preset: *gst.Preset, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: ?[*:0]const u8) callconv(.c) c_int,
    /// virtual methods to get textual meta data from a preset
    f_get_meta: ?*const fn (p_preset: *gst.Preset, p_name: [*:0]const u8, p_tag: [*:0]const u8, p_value: *[*:0]u8) callconv(.c) c_int,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *PresetInterface, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.Promise` object implements the container for values that may
/// be available later. i.e. a Future or a Promise in
/// <https://en.wikipedia.org/wiki/Futures_and_promises>.
/// As with all Future/Promise-like functionality, there is the concept of the
/// producer of the value and the consumer of the value.
///
/// A `gst.Promise` is created with `gst.Promise.new` by the consumer and passed
/// to the producer to avoid thread safety issues with the change callback.
/// A `gst.Promise` can be replied to with a value (or an error) by the producer
/// with `gst.Promise.reply`. The exact value returned is defined by the API
/// contract of the producer and `NULL` may be a valid reply.
/// `gst.Promise.interrupt` is for the consumer to
/// indicate to the producer that the value is not needed anymore and producing
/// that value can stop.  The `GST_PROMISE_RESULT_EXPIRED` state set by a call
/// to `gst.Promise.expire` indicates to the consumer that a value will never
/// be produced and is intended to be called by a third party that implements
/// some notion of message handling such as `gst.Bus`.
/// A callback can also be installed at `gst.Promise` creation for
/// result changes with `gst.Promise.newWithChangeFunc`.
/// The change callback can be used to chain `GstPromises`'s together as in the
/// following example.
/// ```
/// const GstStructure *reply;
/// GstPromise *p;
/// if (gst_promise_wait (promise) != GST_PROMISE_RESULT_REPLIED)
///   return; // interrupted or expired value
/// reply = gst_promise_get_reply (promise);
/// if (error in reply)
///   return; // propagate error
/// p = gst_promise_new_with_change_func (another_promise_change_func, user_data, notify);
/// pass p to promise-using API
/// ```
///
/// Each `gst.Promise` starts out with a `gst.PromiseResult` of
/// `GST_PROMISE_RESULT_PENDING` and only ever transitions once
/// into one of the other `gst.PromiseResult`'s.
///
/// In order to support multi-threaded code, `gst.Promise.reply`,
/// `gst.Promise.interrupt` and `gst.Promise.expire` may all be from
/// different threads with some restrictions and the final result of the promise
/// is whichever call is made first.  There are two restrictions on ordering:
///
/// 1. That `gst.Promise.reply` and `gst.Promise.interrupt` cannot be called
/// after `gst.Promise.expire`
/// 2. That `gst.Promise.reply` and `gst.Promise.interrupt`
/// cannot be called twice.
///
/// The change function set with `gst.Promise.newWithChangeFunc` is
/// called directly from either the `gst.Promise.reply`,
/// `gst.Promise.interrupt` or `gst.Promise.expire` and can be called
/// from an arbitrary thread.  `gst.Promise` using APIs can restrict this to
/// a single thread or a subset of threads but that is entirely up to the API
/// that uses `gst.Promise`.
pub const Promise = extern struct {
    /// parent `gst.MiniObject`
    f_parent: gst.MiniObject,

    extern fn gst_promise_new() *gst.Promise;
    pub const new = gst_promise_new;

    /// `func` will be called exactly once when transitioning out of
    /// `GST_PROMISE_RESULT_PENDING` into any of the other `gst.PromiseResult`
    /// states.
    extern fn gst_promise_new_with_change_func(p_func: gst.PromiseChangeFunc, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) *gst.Promise;
    pub const newWithChangeFunc = gst_promise_new_with_change_func;

    /// Expire a `promise`.  This will wake up any waiters with
    /// `GST_PROMISE_RESULT_EXPIRED`.  Called by a message loop when the parent
    /// message is handled and/or destroyed (possibly unanswered).
    extern fn gst_promise_expire(p_promise: *Promise) void;
    pub const expire = gst_promise_expire;

    /// Retrieve the reply set on `promise`.  `promise` must be in
    /// `GST_PROMISE_RESULT_REPLIED` and the returned structure is owned by `promise`
    extern fn gst_promise_get_reply(p_promise: *Promise) ?*const gst.Structure;
    pub const getReply = gst_promise_get_reply;

    /// Interrupt waiting for a `promise`.  This will wake up any waiters with
    /// `GST_PROMISE_RESULT_INTERRUPTED`.  Called when the consumer does not want
    /// the value produced anymore.
    extern fn gst_promise_interrupt(p_promise: *Promise) void;
    pub const interrupt = gst_promise_interrupt;

    /// Increases the refcount of the given `promise` by one.
    extern fn gst_promise_ref(p_promise: *Promise) *gst.Promise;
    pub const ref = gst_promise_ref;

    /// Set a reply on `promise`.  This will wake up any waiters with
    /// `GST_PROMISE_RESULT_REPLIED`.  Called by the producer of the value to
    /// indicate success (or failure).
    ///
    /// If `promise` has already been interrupted by the consumer, then this reply
    /// is not visible to the consumer.
    extern fn gst_promise_reply(p_promise: ?*Promise, p_s: ?*gst.Structure) void;
    pub const reply = gst_promise_reply;

    /// Decreases the refcount of the promise. If the refcount reaches 0, the
    /// promise will be freed.
    extern fn gst_promise_unref(p_promise: *Promise) void;
    pub const unref = gst_promise_unref;

    /// Wait for `promise` to move out of the `GST_PROMISE_RESULT_PENDING` state.
    /// If `promise` is not in `GST_PROMISE_RESULT_PENDING` then it will return
    /// immediately with the current result.
    extern fn gst_promise_wait(p_promise: *Promise) gst.PromiseResult;
    pub const wait = gst_promise_wait;

    extern fn gst_promise_get_type() usize;
    pub const getGObjectType = gst_promise_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Metadata type that holds information about a sample from a protection-protected
/// track, including the information needed to decrypt it (if it is encrypted).
pub const ProtectionMeta = extern struct {
    /// the parent `gst.Meta`.
    f_meta: gst.Meta,
    /// the cryptographic information needed to decrypt the sample.
    f_info: ?*gst.Structure,

    extern fn gst_protection_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_protection_meta_get_info;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ProxyPadClass = extern struct {
    pub const Instance = gst.ProxyPad;

    f_parent_class: gst.PadClass,
    f__gst_reserved: [1]*anyopaque,

    pub fn as(p_instance: *ProxyPadClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const ProxyPadPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Queries can be performed on pads (`gst.Pad.query`) and elements
/// (`gst.Element.query`). Please note that some queries might need a running
/// pipeline to work.
///
/// Queries can be created using the gst_query_new_*() functions.
/// Query values can be set using gst_query_set_*(), and parsed using
/// gst_query_parse_*() helpers.
///
/// The following example shows how to query the duration of a pipeline:
/// ```
///   GstQuery *query;
///   gboolean res;
///   query = gst_query_new_duration (GST_FORMAT_TIME);
///   res = gst_element_query (pipeline, query);
///   if (res) {
///     gint64 duration;
///     gst_query_parse_duration (query, NULL, &duration);
///     g_print ("duration = %"GST_TIME_FORMAT, GST_TIME_ARGS (duration));
///   } else {
///     g_print ("duration query failed...");
///   }
///   gst_query_unref (query);
/// ```
pub const Query = extern struct {
    /// The parent `gst.MiniObject` type
    f_mini_object: gst.MiniObject,
    /// the `gst.QueryType`
    f_type: gst.QueryType,

    /// Modifies a pointer to a `gst.Query` to point to a different `gst.Query`. The
    /// modification is done atomically (so this is useful for ensuring thread safety
    /// in some cases), and the reference counts are updated appropriately (the old
    /// query is unreffed, the new one is reffed).
    ///
    /// Either `new_query` or the `gst.Query` pointed to by `old_query` may be `NULL`.
    extern fn gst_query_replace(p_old_query: ?**gst.Query, p_new_query: ?*gst.Query) c_int;
    pub const replace = gst_query_replace;

    /// Modifies a pointer to a `gst.Query` to point to a different `gst.Query`. This
    /// function is similar to `gst.queryReplace` except that it takes ownership of
    /// `new_query`.
    ///
    /// Either `new_query` or the `gst.Query` pointed to by `old_query` may be `NULL`.
    extern fn gst_query_take(p_old_query: ?**gst.Query, p_new_query: ?*gst.Query) c_int;
    pub const take = gst_query_take;

    /// Constructs a new query object for querying if `caps` are accepted.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_accept_caps(p_caps: *gst.Caps) *gst.Query;
    pub const newAcceptCaps = gst_query_new_accept_caps;

    /// Constructs a new query object for querying the allocation properties.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_allocation(p_caps: ?*gst.Caps, p_need_pool: c_int) *gst.Query;
    pub const newAllocation = gst_query_new_allocation;

    /// Constructs a new query object for querying the bitrate.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_bitrate() *gst.Query;
    pub const newBitrate = gst_query_new_bitrate;

    /// Constructs a new query object for querying the buffering status of
    /// a stream.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_buffering(p_format: gst.Format) *gst.Query;
    pub const newBuffering = gst_query_new_buffering;

    /// Constructs a new query object for querying the caps.
    ///
    /// The CAPS query should return the allowable caps for a pad in the context
    /// of the element's state, its link to other elements, and the devices or files
    /// it has opened. These caps must be a subset of the pad template caps. In the
    /// NULL state with no links, the CAPS query should ideally return the same caps
    /// as the pad template. In rare circumstances, an object property can affect
    /// the caps returned by the CAPS query, but this is discouraged.
    ///
    /// For most filters, the caps returned by CAPS query is directly affected by the
    /// allowed caps on other pads. For demuxers and decoders, the caps returned by
    /// the srcpad's getcaps function is directly related to the stream data. Again,
    /// the CAPS query should return the most specific caps it reasonably can, since this
    /// helps with autoplugging.
    ///
    /// The `filter` is used to restrict the result caps, only the caps matching
    /// `filter` should be returned from the CAPS query. Specifying a filter might
    /// greatly reduce the amount of processing an element needs to do.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_caps(p_filter: *gst.Caps) *gst.Query;
    pub const newCaps = gst_query_new_caps;

    /// Constructs a new query object for querying the pipeline-local context.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_context(p_context_type: [*:0]const u8) *gst.Query;
    pub const newContext = gst_query_new_context;

    /// Constructs a new convert query object. Use `gst.Query.unref`
    /// when done with it. A convert query is used to ask for a conversion between
    /// one format and another.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_convert(p_src_format: gst.Format, p_value: i64, p_dest_format: gst.Format) *gst.Query;
    pub const newConvert = gst_query_new_convert;

    /// Constructs a new custom query object. Use `gst.Query.unref`
    /// when done with it.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_custom(p_type: gst.QueryType, p_structure: ?*gst.Structure) *gst.Query;
    pub const newCustom = gst_query_new_custom;

    /// Constructs a new query object for querying the drain state.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_drain() *gst.Query;
    pub const newDrain = gst_query_new_drain;

    /// Constructs a new stream duration query object to query in the given format.
    /// Use `gst.Query.unref` when done with it. A duration query will give the
    /// total length of the stream.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_duration(p_format: gst.Format) *gst.Query;
    pub const newDuration = gst_query_new_duration;

    /// Constructs a new query object for querying formats of
    /// the stream.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_formats() *gst.Query;
    pub const newFormats = gst_query_new_formats;

    /// Constructs a new latency query object.
    /// Use `gst.Query.unref` when done with it. A latency query is usually performed
    /// by sinks to compensate for additional latency introduced by elements in the
    /// pipeline.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_latency() *gst.Query;
    pub const newLatency = gst_query_new_latency;

    /// Constructs a new query stream position query object. Use `gst.Query.unref`
    /// when done with it. A position query is used to query the current position
    /// of playback in the streams, in some format.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_position(p_format: gst.Format) *gst.Query;
    pub const newPosition = gst_query_new_position;

    /// Constructs a new query object for querying the scheduling properties.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_scheduling() *gst.Query;
    pub const newScheduling = gst_query_new_scheduling;

    /// Constructs a new query object for querying seeking properties of
    /// the stream.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_seeking(p_format: gst.Format) *gst.Query;
    pub const newSeeking = gst_query_new_seeking;

    /// Constructs a new segment query object. Use `gst.Query.unref`
    /// when done with it. A segment query is used to discover information about the
    /// currently configured segment for playback.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_segment(p_format: gst.Format) *gst.Query;
    pub const newSegment = gst_query_new_segment;

    /// Constructs a new query object for querying the stream selection capability.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_selectable() *gst.Query;
    pub const newSelectable = gst_query_new_selectable;

    /// Constructs a new query URI query object. Use `gst.Query.unref`
    /// when done with it. An URI query is used to query the current URI
    /// that is used by the source or sink.
    ///
    /// Free-function: `gst.Query.unref`
    extern fn gst_query_new_uri() *gst.Query;
    pub const newUri = gst_query_new_uri;

    /// Add `api` with `params` as one of the supported metadata API to `query`.
    extern fn gst_query_add_allocation_meta(p_query: *Query, p_api: usize, p_params: ?*const gst.Structure) void;
    pub const addAllocationMeta = gst_query_add_allocation_meta;

    /// Add `allocator` and its `params` as a supported memory allocator.
    extern fn gst_query_add_allocation_param(p_query: *Query, p_allocator: ?*gst.Allocator, p_params: ?*const gst.AllocationParams) void;
    pub const addAllocationParam = gst_query_add_allocation_param;

    /// Set the pool parameters in `query`.
    extern fn gst_query_add_allocation_pool(p_query: *Query, p_pool: ?*gst.BufferPool, p_size: c_uint, p_min_buffers: c_uint, p_max_buffers: c_uint) void;
    pub const addAllocationPool = gst_query_add_allocation_pool;

    /// Set the buffering-ranges array field in `query`. The current last
    /// start position of the array should be inferior to `start`.
    extern fn gst_query_add_buffering_range(p_query: *Query, p_start: i64, p_stop: i64) c_int;
    pub const addBufferingRange = gst_query_add_buffering_range;

    /// Add `mode` as one of the supported scheduling modes to `query`.
    extern fn gst_query_add_scheduling_mode(p_query: *Query, p_mode: gst.PadMode) void;
    pub const addSchedulingMode = gst_query_add_scheduling_mode;

    /// Copies the given query using the copy function of the parent `gst.Structure`.
    ///
    /// Free-function: gst_query_unref
    extern fn gst_query_copy(p_q: *const Query) *gst.Query;
    pub const copy = gst_query_copy;

    /// Check if `query` has metadata `api` set. When this function returns `TRUE`,
    /// `index` will contain the index where the requested API and the parameters
    /// can be found.
    extern fn gst_query_find_allocation_meta(p_query: *Query, p_api: usize, p_index: ?*c_uint) c_int;
    pub const findAllocationMeta = gst_query_find_allocation_meta;

    /// Retrieve the number of values currently stored in the
    /// meta API array of the query's structure.
    extern fn gst_query_get_n_allocation_metas(p_query: *Query) c_uint;
    pub const getNAllocationMetas = gst_query_get_n_allocation_metas;

    /// Retrieve the number of values currently stored in the
    /// allocator params array of the query's structure.
    ///
    /// If no memory allocator is specified, the downstream element can handle
    /// the default memory allocator. The first memory allocator in the query
    /// should be generic and allow mapping to system memory, all following
    /// allocators should be ordered by preference with the preferred one first.
    extern fn gst_query_get_n_allocation_params(p_query: *Query) c_uint;
    pub const getNAllocationParams = gst_query_get_n_allocation_params;

    /// Retrieve the number of values currently stored in the
    /// pool array of the query's structure.
    extern fn gst_query_get_n_allocation_pools(p_query: *Query) c_uint;
    pub const getNAllocationPools = gst_query_get_n_allocation_pools;

    /// Retrieve the number of values currently stored in the
    /// buffered-ranges array of the query's structure.
    extern fn gst_query_get_n_buffering_ranges(p_query: *Query) c_uint;
    pub const getNBufferingRanges = gst_query_get_n_buffering_ranges;

    /// Retrieve the number of values currently stored in the
    /// scheduling mode array of the query's structure.
    extern fn gst_query_get_n_scheduling_modes(p_query: *Query) c_uint;
    pub const getNSchedulingModes = gst_query_get_n_scheduling_modes;

    /// Get the structure of a query.
    extern fn gst_query_get_structure(p_query: *Query) ?*const gst.Structure;
    pub const getStructure = gst_query_get_structure;

    /// Check if `query` has scheduling mode set.
    ///
    /// > When checking if upstream supports pull mode, it is usually not
    /// > enough to just check for GST_PAD_MODE_PULL with this function, you
    /// > also want to check whether the scheduling flags returned by
    /// > `gst.Query.parseScheduling` have the seeking flag set (meaning
    /// > random access is supported, not only sequential pulls).
    extern fn gst_query_has_scheduling_mode(p_query: *Query, p_mode: gst.PadMode) c_int;
    pub const hasSchedulingMode = gst_query_has_scheduling_mode;

    /// Check if `query` has scheduling mode set and `flags` is set in
    /// query scheduling flags.
    extern fn gst_query_has_scheduling_mode_with_flags(p_query: *Query, p_mode: gst.PadMode, p_flags: gst.SchedulingFlags) c_int;
    pub const hasSchedulingModeWithFlags = gst_query_has_scheduling_mode_with_flags;

    /// Get the caps from `query`. The caps remains valid as long as `query` remains
    /// valid.
    extern fn gst_query_parse_accept_caps(p_query: *Query, p_caps: **gst.Caps) void;
    pub const parseAcceptCaps = gst_query_parse_accept_caps;

    /// Parse the result from `query` and store in `result`.
    extern fn gst_query_parse_accept_caps_result(p_query: *Query, p_result: ?*c_int) void;
    pub const parseAcceptCapsResult = gst_query_parse_accept_caps_result;

    /// Parse an allocation query, writing the requested caps in `caps` and
    /// whether a pool is needed in `need_pool`, if the respective parameters
    /// are non-`NULL`.
    ///
    /// Pool details can be retrieved using `gst.Query.getNAllocationPools` and
    /// `gst.Query.parseNthAllocationPool`.
    extern fn gst_query_parse_allocation(p_query: *Query, p_caps: ?**gst.Caps, p_need_pool: ?*c_int) void;
    pub const parseAllocation = gst_query_parse_allocation;

    /// Get the results of a bitrate query. See also `gst.Query.setBitrate`.
    extern fn gst_query_parse_bitrate(p_query: *Query, p_nominal_bitrate: ?*c_uint) void;
    pub const parseBitrate = gst_query_parse_bitrate;

    /// Get the percentage of buffered data. This is a value between 0 and 100.
    /// The `busy` indicator is `TRUE` when the buffering is in progress.
    extern fn gst_query_parse_buffering_percent(p_query: *Query, p_busy: ?*c_int, p_percent: ?*c_int) void;
    pub const parseBufferingPercent = gst_query_parse_buffering_percent;

    /// Parse an available query, writing the format into `format`, and
    /// other results into the passed parameters, if the respective parameters
    /// are non-`NULL`
    extern fn gst_query_parse_buffering_range(p_query: *Query, p_format: ?*gst.Format, p_start: ?*i64, p_stop: ?*i64, p_estimated_total: ?*i64) void;
    pub const parseBufferingRange = gst_query_parse_buffering_range;

    /// Extracts the buffering stats values from `query`.
    extern fn gst_query_parse_buffering_stats(p_query: *Query, p_mode: ?*gst.BufferingMode, p_avg_in: ?*c_int, p_avg_out: ?*c_int, p_buffering_left: ?*i64) void;
    pub const parseBufferingStats = gst_query_parse_buffering_stats;

    /// Get the filter from the caps `query`. The caps remains valid as long as
    /// `query` remains valid.
    extern fn gst_query_parse_caps(p_query: *Query, p_filter: **gst.Caps) void;
    pub const parseCaps = gst_query_parse_caps;

    /// Get the caps result from `query`. The caps remains valid as long as
    /// `query` remains valid.
    extern fn gst_query_parse_caps_result(p_query: *Query, p_caps: ?**gst.Caps) void;
    pub const parseCapsResult = gst_query_parse_caps_result;

    /// Get the context from the context `query`. The context remains valid as long as
    /// `query` remains valid.
    extern fn gst_query_parse_context(p_query: *Query, p_context: ?**gst.Context) void;
    pub const parseContext = gst_query_parse_context;

    /// Parse a context type from an existing GST_QUERY_CONTEXT query.
    extern fn gst_query_parse_context_type(p_query: *Query, p_context_type: ?*[*:0]const u8) c_int;
    pub const parseContextType = gst_query_parse_context_type;

    /// Parse a convert query answer. Any of `src_format`, `src_value`, `dest_format`,
    /// and `dest_value` may be `NULL`, in which case that value is omitted.
    extern fn gst_query_parse_convert(p_query: *Query, p_src_format: ?*gst.Format, p_src_value: ?*i64, p_dest_format: ?*gst.Format, p_dest_value: ?*i64) void;
    pub const parseConvert = gst_query_parse_convert;

    /// Parse a duration query answer. Write the format of the duration into `format`,
    /// and the value into `duration`, if the respective variables are non-`NULL`.
    extern fn gst_query_parse_duration(p_query: *Query, p_format: ?*gst.Format, p_duration: ?*i64) void;
    pub const parseDuration = gst_query_parse_duration;

    /// Parse a latency query answer.
    extern fn gst_query_parse_latency(p_query: *Query, p_live: ?*c_int, p_min_latency: ?*gst.ClockTime, p_max_latency: ?*gst.ClockTime) void;
    pub const parseLatency = gst_query_parse_latency;

    /// Parse the number of formats in the formats `query`.
    extern fn gst_query_parse_n_formats(p_query: *Query, p_n_formats: ?*c_uint) void;
    pub const parseNFormats = gst_query_parse_n_formats;

    /// Parse an available query and get the metadata API
    /// at `index` of the metadata API array.
    extern fn gst_query_parse_nth_allocation_meta(p_query: *Query, p_index: c_uint, p_params: ?**const gst.Structure) usize;
    pub const parseNthAllocationMeta = gst_query_parse_nth_allocation_meta;

    /// Parse an available query and get the allocator and its params
    /// at `index` of the allocator array.
    extern fn gst_query_parse_nth_allocation_param(p_query: *Query, p_index: c_uint, p_allocator: ?**gst.Allocator, p_params: ?*gst.AllocationParams) void;
    pub const parseNthAllocationParam = gst_query_parse_nth_allocation_param;

    /// Get the pool parameters in `query`.
    ///
    /// Unref `pool` with `gst.Object.unref` when it's not needed any more.
    extern fn gst_query_parse_nth_allocation_pool(p_query: *Query, p_index: c_uint, p_pool: ?**gst.BufferPool, p_size: ?*c_uint, p_min_buffers: ?*c_uint, p_max_buffers: ?*c_uint) void;
    pub const parseNthAllocationPool = gst_query_parse_nth_allocation_pool;

    /// Parse an available query and get the start and stop values stored
    /// at the `index` of the buffered ranges array.
    extern fn gst_query_parse_nth_buffering_range(p_query: *Query, p_index: c_uint, p_start: ?*i64, p_stop: ?*i64) c_int;
    pub const parseNthBufferingRange = gst_query_parse_nth_buffering_range;

    /// Parse the format query and retrieve the `nth` format from it into
    /// `format`. If the list contains less elements than `nth`, `format` will be
    /// set to GST_FORMAT_UNDEFINED.
    extern fn gst_query_parse_nth_format(p_query: *Query, p_nth: c_uint, p_format: ?*gst.Format) void;
    pub const parseNthFormat = gst_query_parse_nth_format;

    /// Parse an available query and get the scheduling mode
    /// at `index` of the scheduling modes array.
    extern fn gst_query_parse_nth_scheduling_mode(p_query: *Query, p_index: c_uint) gst.PadMode;
    pub const parseNthSchedulingMode = gst_query_parse_nth_scheduling_mode;

    /// Parse a position query, writing the format into `format`, and the position
    /// into `cur`, if the respective parameters are non-`NULL`.
    extern fn gst_query_parse_position(p_query: *Query, p_format: ?*gst.Format, p_cur: ?*i64) void;
    pub const parsePosition = gst_query_parse_position;

    /// Set the scheduling properties.
    extern fn gst_query_parse_scheduling(p_query: *Query, p_flags: ?*gst.SchedulingFlags, p_minsize: ?*c_int, p_maxsize: ?*c_int, p_align: ?*c_int) void;
    pub const parseScheduling = gst_query_parse_scheduling;

    /// Parse a seeking query, writing the format into `format`, and
    /// other results into the passed parameters, if the respective parameters
    /// are non-`NULL`
    extern fn gst_query_parse_seeking(p_query: *Query, p_format: ?*gst.Format, p_seekable: ?*c_int, p_segment_start: ?*i64, p_segment_end: ?*i64) void;
    pub const parseSeeking = gst_query_parse_seeking;

    /// Parse a segment query answer. Any of `rate`, `format`, `start_value`, and
    /// `stop_value` may be `NULL`, which will cause this value to be omitted.
    ///
    /// See `gst.Query.setSegment` for an explanation of the function arguments.
    extern fn gst_query_parse_segment(p_query: *Query, p_rate: ?*f64, p_format: ?*gst.Format, p_start_value: ?*i64, p_stop_value: ?*i64) void;
    pub const parseSegment = gst_query_parse_segment;

    /// Get the results of a selectable query. See also `gst.Query.setSelectable`.
    extern fn gst_query_parse_selectable(p_query: *Query, p_selectable: ?*c_int) void;
    pub const parseSelectable = gst_query_parse_selectable;

    /// Parse an URI query, writing the URI into `uri` as a newly
    /// allocated string, if the respective parameters are non-`NULL`.
    /// Free the string with `glib.free` after usage.
    extern fn gst_query_parse_uri(p_query: *Query, p_uri: ?*[*:0]u8) void;
    pub const parseUri = gst_query_parse_uri;

    /// Parse an URI query, writing the URI into `uri` as a newly
    /// allocated string, if the respective parameters are non-`NULL`.
    /// Free the string with `glib.free` after usage.
    extern fn gst_query_parse_uri_redirection(p_query: *Query, p_uri: ?*[*:0]u8) void;
    pub const parseUriRedirection = gst_query_parse_uri_redirection;

    /// Parse an URI query, and set `permanent` to `TRUE` if there is a redirection
    /// and it should be considered permanent. If a redirection is permanent,
    /// applications should update their internal storage of the URI, otherwise
    /// they should make all future requests to the original URI.
    extern fn gst_query_parse_uri_redirection_permanent(p_query: *Query, p_permanent: ?*c_int) void;
    pub const parseUriRedirectionPermanent = gst_query_parse_uri_redirection_permanent;

    /// Increases the refcount of the given query by one.
    extern fn gst_query_ref(p_q: *Query) *gst.Query;
    pub const ref = gst_query_ref;

    /// Remove the metadata API at `index` of the metadata API array.
    extern fn gst_query_remove_nth_allocation_meta(p_query: *Query, p_index: c_uint) void;
    pub const removeNthAllocationMeta = gst_query_remove_nth_allocation_meta;

    /// Remove the allocation param at `index` of the allocation param array.
    extern fn gst_query_remove_nth_allocation_param(p_query: *Query, p_index: c_uint) void;
    pub const removeNthAllocationParam = gst_query_remove_nth_allocation_param;

    /// Remove the allocation pool at `index` of the allocation pool array.
    extern fn gst_query_remove_nth_allocation_pool(p_query: *Query, p_index: c_uint) void;
    pub const removeNthAllocationPool = gst_query_remove_nth_allocation_pool;

    /// Set `result` as the result for the `query`.
    extern fn gst_query_set_accept_caps_result(p_query: *Query, p_result: c_int) void;
    pub const setAcceptCapsResult = gst_query_set_accept_caps_result;

    /// Set the results of a bitrate query.  The nominal bitrate is the average
    /// bitrate expected over the length of the stream as advertised in file
    /// headers (or similar).
    extern fn gst_query_set_bitrate(p_query: *Query, p_nominal_bitrate: c_uint) void;
    pub const setBitrate = gst_query_set_bitrate;

    /// Set the percentage of buffered data. This is a value between 0 and 100.
    /// The `busy` indicator is `TRUE` when the buffering is in progress.
    extern fn gst_query_set_buffering_percent(p_query: *Query, p_busy: c_int, p_percent: c_int) void;
    pub const setBufferingPercent = gst_query_set_buffering_percent;

    /// Set the available query result fields in `query`.
    extern fn gst_query_set_buffering_range(p_query: *Query, p_format: gst.Format, p_start: i64, p_stop: i64, p_estimated_total: i64) void;
    pub const setBufferingRange = gst_query_set_buffering_range;

    /// Configures the buffering stats values in `query`.
    extern fn gst_query_set_buffering_stats(p_query: *Query, p_mode: gst.BufferingMode, p_avg_in: c_int, p_avg_out: c_int, p_buffering_left: i64) void;
    pub const setBufferingStats = gst_query_set_buffering_stats;

    /// Set the `caps` result in `query`.
    extern fn gst_query_set_caps_result(p_query: *Query, p_caps: ?*gst.Caps) void;
    pub const setCapsResult = gst_query_set_caps_result;

    /// Answer a context query by setting the requested context.
    extern fn gst_query_set_context(p_query: *Query, p_context: ?*gst.Context) void;
    pub const setContext = gst_query_set_context;

    /// Answer a convert query by setting the requested values.
    extern fn gst_query_set_convert(p_query: *Query, p_src_format: gst.Format, p_src_value: i64, p_dest_format: gst.Format, p_dest_value: i64) void;
    pub const setConvert = gst_query_set_convert;

    /// Answer a duration query by setting the requested value in the given format.
    extern fn gst_query_set_duration(p_query: *Query, p_format: gst.Format, p_duration: i64) void;
    pub const setDuration = gst_query_set_duration;

    /// Set the formats query result fields in `query`. The number of formats passed
    /// must be equal to `n_formats`.
    extern fn gst_query_set_formats(p_query: *Query, p_n_formats: c_int, ...) void;
    pub const setFormats = gst_query_set_formats;

    /// Set the formats query result fields in `query`. The number of formats passed
    /// in the `formats` array must be equal to `n_formats`.
    extern fn gst_query_set_formatsv(p_query: *Query, p_n_formats: c_int, p_formats: [*]const gst.Format) void;
    pub const setFormatsv = gst_query_set_formatsv;

    /// Answer a latency query by setting the requested values in the given format.
    extern fn gst_query_set_latency(p_query: *Query, p_live: c_int, p_min_latency: gst.ClockTime, p_max_latency: gst.ClockTime) void;
    pub const setLatency = gst_query_set_latency;

    /// Parse an available query and get the allocator and its params
    /// at `index` of the allocator array.
    extern fn gst_query_set_nth_allocation_param(p_query: *Query, p_index: c_uint, p_allocator: ?*gst.Allocator, p_params: ?*const gst.AllocationParams) void;
    pub const setNthAllocationParam = gst_query_set_nth_allocation_param;

    /// Set the pool parameters in `query`.
    extern fn gst_query_set_nth_allocation_pool(p_query: *Query, p_index: c_uint, p_pool: ?*gst.BufferPool, p_size: c_uint, p_min_buffers: c_uint, p_max_buffers: c_uint) void;
    pub const setNthAllocationPool = gst_query_set_nth_allocation_pool;

    /// Answer a position query by setting the requested value in the given format.
    extern fn gst_query_set_position(p_query: *Query, p_format: gst.Format, p_cur: i64) void;
    pub const setPosition = gst_query_set_position;

    /// Set the scheduling properties.
    extern fn gst_query_set_scheduling(p_query: *Query, p_flags: gst.SchedulingFlags, p_minsize: c_int, p_maxsize: c_int, p_align: c_int) void;
    pub const setScheduling = gst_query_set_scheduling;

    /// Set the seeking query result fields in `query`.
    extern fn gst_query_set_seeking(p_query: *Query, p_format: gst.Format, p_seekable: c_int, p_segment_start: i64, p_segment_end: i64) void;
    pub const setSeeking = gst_query_set_seeking;

    /// Answer a segment query by setting the requested values. The normal
    /// playback segment of a pipeline is 0 to duration at the default rate of
    /// 1.0. If a seek was performed on the pipeline to play a different
    /// segment, this query will return the range specified in the last seek.
    ///
    /// `start_value` and `stop_value` will respectively contain the configured
    /// playback range start and stop values expressed in `format`.
    /// The values are always between 0 and the duration of the media and
    /// `start_value` <= `stop_value`. `rate` will contain the playback rate. For
    /// negative rates, playback will actually happen from `stop_value` to
    /// `start_value`.
    extern fn gst_query_set_segment(p_query: *Query, p_rate: f64, p_format: gst.Format, p_start_value: i64, p_stop_value: i64) void;
    pub const setSegment = gst_query_set_segment;

    /// Set the results of a selectable query. If the element answering the query can
    /// handle stream selection, `selectable` should be set to `TRUE`.
    extern fn gst_query_set_selectable(p_query: *Query, p_selectable: c_int) void;
    pub const setSelectable = gst_query_set_selectable;

    /// Answer a URI query by setting the requested URI.
    extern fn gst_query_set_uri(p_query: *Query, p_uri: ?[*:0]const u8) void;
    pub const setUri = gst_query_set_uri;

    /// Answer a URI query by setting the requested URI redirection.
    extern fn gst_query_set_uri_redirection(p_query: *Query, p_uri: ?[*:0]const u8) void;
    pub const setUriRedirection = gst_query_set_uri_redirection;

    /// Answer a URI query by setting the requested URI redirection
    /// to permanent or not.
    extern fn gst_query_set_uri_redirection_permanent(p_query: *Query, p_permanent: c_int) void;
    pub const setUriRedirectionPermanent = gst_query_set_uri_redirection_permanent;

    /// Decreases the refcount of the query. If the refcount reaches 0, the query
    /// will be freed.
    extern fn gst_query_unref(p_q: *Query) void;
    pub const unref = gst_query_unref;

    /// Get the structure of a query. This method should be called with a writable
    /// `query` so that the returned structure is guaranteed to be writable.
    extern fn gst_query_writable_structure(p_query: *Query) *gst.Structure;
    pub const writableStructure = gst_query_writable_structure;

    extern fn gst_query_get_type() usize;
    pub const getGObjectType = gst_query_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.ReferenceTimestampMeta` can be used to attach alternative timestamps and
/// possibly durations to a `gst.Buffer`. These are generally not according to
/// the pipeline clock and could be e.g. the NTP timestamp when the media was
/// captured.
///
/// The reference is stored as a `gst.Caps` in `reference`. Examples of valid
/// references would be
///
///  * `timestamp/x-drivername-stream`: for timestamps that are locally
///    generated by some driver named `drivername` when generating the stream,
///    e.g. based on a frame counter
///  * `timestamp/x-ntp, host=pool.ntp.org, port=123`: for timestamps based on a
///    specific NTP server. Note that the host/port parameters might not always
///    be given.
///  * `timestamp/x-ptp, version=IEEE1588-2008, domain=1`: for timestamps based
///    on a given PTP clock.
///  * `timestamp/x-unix`: for timestamps based on the UNIX epoch according to
///    the local clock.
///
/// Since 1.24 it can be serialized using `gst.Meta.serialize` and
/// `gst.metaDeserialize`.
pub const ReferenceTimestampMeta = extern struct {
    /// the parent `gst.Meta` structure
    f_parent: gst.Meta,
    /// identifier for the timestamp reference.
    f_reference: ?*gst.Caps,
    /// timestamp
    f_timestamp: gst.ClockTime,
    /// duration, or `GST_CLOCK_TIME_NONE`
    f_duration: gst.ClockTime,

    /// Gets the global `gst.MetaInfo` describing the `gst.ReferenceTimestampMeta` meta.
    extern fn gst_reference_timestamp_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_reference_timestamp_meta_get_info;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const RegistryClass = extern struct {
    pub const Instance = gst.Registry;

    f_parent_class: gst.ObjectClass,

    pub fn as(p_instance: *RegistryClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const RegistryPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.Sample` is a small object containing data, a type, timing and
/// extra arbitrary information.
pub const Sample = opaque {
    /// Create a new `gst.Sample` with the provided details.
    ///
    /// Free-function: gst_sample_unref
    extern fn gst_sample_new(p_buffer: ?*gst.Buffer, p_caps: ?*gst.Caps, p_segment: ?*const gst.Segment, p_info: ?*gst.Structure) *gst.Sample;
    pub const new = gst_sample_new;

    /// Create a copy of the given sample. This will also make a newly allocated
    /// copy of the data the source sample contains.
    extern fn gst_sample_copy(p_sample: *const Sample) *gst.Sample;
    pub const copy = gst_sample_copy;

    /// Get the buffer associated with `sample`
    extern fn gst_sample_get_buffer(p_sample: *Sample) ?*gst.Buffer;
    pub const getBuffer = gst_sample_get_buffer;

    /// Get the buffer list associated with `sample`
    extern fn gst_sample_get_buffer_list(p_sample: *Sample) ?*gst.BufferList;
    pub const getBufferList = gst_sample_get_buffer_list;

    /// Get the caps associated with `sample`
    extern fn gst_sample_get_caps(p_sample: *Sample) ?*gst.Caps;
    pub const getCaps = gst_sample_get_caps;

    /// Get extra information associated with `sample`.
    extern fn gst_sample_get_info(p_sample: *Sample) ?*const gst.Structure;
    pub const getInfo = gst_sample_get_info;

    /// Get the segment associated with `sample`
    extern fn gst_sample_get_segment(p_sample: *Sample) *gst.Segment;
    pub const getSegment = gst_sample_get_segment;

    /// Increases the refcount of the given sample by one.
    extern fn gst_sample_ref(p_sample: *Sample) *gst.Sample;
    pub const ref = gst_sample_ref;

    /// Set the buffer associated with `sample`. `sample` must be writable.
    extern fn gst_sample_set_buffer(p_sample: *Sample, p_buffer: *gst.Buffer) void;
    pub const setBuffer = gst_sample_set_buffer;

    /// Set the buffer list associated with `sample`. `sample` must be writable.
    extern fn gst_sample_set_buffer_list(p_sample: *Sample, p_buffer_list: *gst.BufferList) void;
    pub const setBufferList = gst_sample_set_buffer_list;

    /// Set the caps associated with `sample`. `sample` must be writable.
    extern fn gst_sample_set_caps(p_sample: *Sample, p_caps: *gst.Caps) void;
    pub const setCaps = gst_sample_set_caps;

    /// Set the info structure associated with `sample`. `sample` must be writable,
    /// and `info` must not have a parent set already.
    extern fn gst_sample_set_info(p_sample: *Sample, p_info: *gst.Structure) c_int;
    pub const setInfo = gst_sample_set_info;

    /// Set the segment associated with `sample`. `sample` must be writable.
    extern fn gst_sample_set_segment(p_sample: *Sample, p_segment: *const gst.Segment) void;
    pub const setSegment = gst_sample_set_segment;

    /// Decreases the refcount of the sample. If the refcount reaches 0, the
    /// sample will be freed.
    extern fn gst_sample_unref(p_sample: *Sample) void;
    pub const unref = gst_sample_unref;

    extern fn gst_sample_get_type() usize;
    pub const getGObjectType = gst_sample_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// This helper structure holds the relevant values for tracking the region of
/// interest in a media file, called a segment.
///
/// The structure can be used for two purposes:
///
///   * performing seeks (handling seek events)
///   * tracking playback regions (handling newsegment events)
///
/// The segment is usually configured by the application with a seek event which
/// is propagated upstream and eventually handled by an element that performs the seek.
///
/// The configured segment is then propagated back downstream with a newsegment event.
/// This information is then used to clip media to the segment boundaries.
///
/// A segment structure is initialized with `gst.Segment.init`, which takes a `gst.Format`
/// that will be used as the format of the segment values. The segment will be configured
/// with a start value of 0 and a stop/duration of -1, which is undefined. The default
/// rate and applied_rate is 1.0.
///
/// The public duration field contains the duration of the segment. When using
/// the segment for seeking, the start and time members should normally be left
/// to their default 0 value. The stop position is left to -1 unless explicitly
/// configured to a different value after a seek event.
///
/// The current position in the segment should be set by changing the position
/// member in the structure.
///
/// For elements that perform seeks, the current segment should be updated with the
/// `gst.Segment.doSeek` and the values from the seek event. This method will update
/// all the segment fields. The position field will contain the new playback position.
/// If the start_type was different from GST_SEEK_TYPE_NONE, playback continues from
/// the position position, possibly with updated flags or rate.
///
/// For elements that want to use `gst.Segment` to track the playback region,
/// update the segment fields with the information from the newsegment event.
/// The `gst.Segment.clip` method can be used to check and clip
/// the media data to the segment boundaries.
///
/// For elements that want to synchronize to the pipeline clock, `gst.Segment.toRunningTime`
/// can be used to convert a timestamp to a value that can be used to synchronize
/// to the clock. This function takes into account the base as well as
/// any rate or applied_rate conversions.
///
/// For elements that need to perform operations on media data in stream_time,
/// `gst.Segment.toStreamTime` can be used to convert a timestamp and the segment
/// info to stream time (which is always between 0 and the duration of the stream).
pub const Segment = extern struct {
    /// flags for this segment
    f_flags: gst.SegmentFlags,
    /// the playback rate of the segment is set in response to a seek
    ///                event and, without any seek, the value should be `1.0`. This
    ///                value is used by elements that synchronize buffer [running
    ///                times](additional/design/synchronisation.md`running`-time) on
    ///                the clock (usually the sink elements), leading to consuming
    ///                buffers faster (for a value `> 1.0`) or slower (for `0.0 <
    ///                value < 1.0`) than normal playback speed. The rate also
    ///                defines the playback direction, meaning that when the value is
    ///                lower than `0.0`, the playback happens in reverse, and the
    ///                [stream-time](additional/design/synchronisation.md`stream`-time)
    ///                is going backward. The `rate` value should never be `0.0`.
    f_rate: f64,
    /// The applied rate is the rate that has been applied to the stream.
    ///                The effective/resulting playback rate of a stream is
    ///                `rate * applied_rate`.
    ///                The applied rate can be set by source elements when a server is
    ///                sending the stream with an already modified playback speed
    ///                rate. Filter elements that modify the stream in a way that
    ///                modifies the playback speed should also modify the applied
    ///                rate. For example the `videorate` element when its
    ///                `videorate.properties.rate` property is set will set the applied rate of
    ///                the segment it pushed downstream. Also `scaletempo` applies the
    ///                input segment rate to the stream and outputs a segment with
    ///                rate=1.0 and applied_rate=<inputsegment.rate>.
    f_applied_rate: f64,
    /// the unit used for all of the segment's values.
    f_format: gst.Format,
    /// the running time (plus elapsed time, see offset) of the
    ///                segment [start](GstSegment.start) ([stop](GstSegment.stop) if
    ///                rate < 0.0).
    f_base: u64,
    /// the offset expresses the elapsed time (in buffer timestamps)
    ///                before a seek with its start (stop if rate < 0.0) seek type
    ///                set to `GST_SEEK_TYPE_NONE`, the value is set to the position
    ///                of the segment at the time of the seek.
    f_offset: u64,
    /// the start time of the segment (in buffer timestamps)
    ///                [(PTS)](GstBuffer.pts), that is the timestamp of the first
    ///                buffer to output inside the segment (last one during
    ///                reverse playback). For example decoders will
    ///                [clip](gst_segment_clip) out the buffers before the start
    ///                time.
    f_start: u64,
    /// the stop time of the segment (in buffer timestamps)
    ///                [(PTS)](GstBuffer.pts), that is the timestamp of the last
    ///                buffer to output inside the segment (first one during
    ///                reverse playback). For example decoders will
    ///                [clip](gst_segment_clip) out buffers after the stop time.
    f_stop: u64,
    /// the stream time of the segment [start](GstSegment.start)
    ///                ([stop](GstSegment.stop) if rate < 0.0).
    f_time: u64,
    /// the buffer timestamp position in the segment is supposed to be
    ///                updated by elements such as sources, demuxers or parsers to
    ///                track progress by setting it to the last pushed buffer' end time
    ///                ([timestamp](GstBuffer.pts) + `gst.Buffer.duration`) for that
    ///                specific segment. The position is used when reconfiguring the
    ///                segment with `gst.Segment.doSeek` when the seek is only
    ///                updating the segment (see [offset](GstSegment.offset)).
    f_position: u64,
    /// the duration of the segment is the maximum absolute difference
    ///                between `gst.Segment.start` and `gst.Segment.stop` if stop is not
    ///                set, otherwise it should be the difference between those
    ///                two values. This should be set by elements that know the
    ///                overall stream duration (like demuxers) and will be used when
    ///                seeking with `GST_SEEK_TYPE_END`.
    f_duration: u64,
    f__gst_reserved: [4]*anyopaque,

    /// Allocate a new `gst.Segment` structure and initialize it using
    /// `gst.Segment.init`.
    ///
    /// Free-function: gst_segment_free
    extern fn gst_segment_new() *gst.Segment;
    pub const new = gst_segment_new;

    /// Clip the given `start` and `stop` values to the segment boundaries given
    /// in `segment`. `start` and `stop` are compared and clipped to `segment`
    /// start and stop values.
    ///
    /// If the function returns `FALSE`, `start` and `stop` are known to fall
    /// outside of `segment` and `clip_start` and `clip_stop` are not updated.
    ///
    /// When the function returns `TRUE`, `clip_start` and `clip_stop` will be
    /// updated. If `clip_start` or `clip_stop` are different from `start` or `stop`
    /// respectively, the region fell partially in the segment.
    ///
    /// Note that when `stop` is -1, `clip_stop` will be set to the end of the
    /// segment. Depending on the use case, this may or may not be what you want.
    extern fn gst_segment_clip(p_segment: *const Segment, p_format: gst.Format, p_start: u64, p_stop: u64, p_clip_start: ?*u64, p_clip_stop: ?*u64) c_int;
    pub const clip = gst_segment_clip;

    /// Create a copy of given `segment`.
    ///
    /// Free-function: gst_segment_free
    extern fn gst_segment_copy(p_segment: *const Segment) *gst.Segment;
    pub const copy = gst_segment_copy;

    /// Copy the contents of `src` into `dest`.
    extern fn gst_segment_copy_into(p_src: *const Segment, p_dest: *gst.Segment) void;
    pub const copyInto = gst_segment_copy_into;

    /// Update the segment structure with the field values of a seek event (see
    /// `gst.Event.newSeek`).
    ///
    /// After calling this method, the segment field position and time will
    /// contain the requested new position in the segment. The new requested
    /// position in the segment depends on `rate` and `start_type` and `stop_type`.
    ///
    /// For positive `rate`, the new position in the segment is the new `segment`
    /// start field when it was updated with a `start_type` different from
    /// `GST_SEEK_TYPE_NONE`. If no update was performed on `segment` start position
    /// (`GST_SEEK_TYPE_NONE`), `start` is ignored and `segment` position is
    /// unmodified.
    ///
    /// For negative `rate`, the new position in the segment is the new `segment`
    /// stop field when it was updated with a `stop_type` different from
    /// `GST_SEEK_TYPE_NONE`. If no stop was previously configured in the segment, the
    /// duration of the segment will be used to update the stop position.
    /// If no update was performed on `segment` stop position (`GST_SEEK_TYPE_NONE`),
    /// `stop` is ignored and `segment` position is unmodified.
    ///
    /// The applied rate of the segment will be set to 1.0 by default.
    /// If the caller can apply a rate change, it should update `segment`
    /// rate and applied_rate after calling this function.
    ///
    /// `update` will be set to `TRUE` if a seek should be performed to the segment
    /// position field. This field can be `FALSE` if, for example, only the `rate`
    /// has been changed but not the playback position.
    extern fn gst_segment_do_seek(p_segment: *Segment, p_rate: f64, p_format: gst.Format, p_flags: gst.SeekFlags, p_start_type: gst.SeekType, p_start: u64, p_stop_type: gst.SeekType, p_stop: u64, p_update: ?*c_int) c_int;
    pub const doSeek = gst_segment_do_seek;

    /// Free the allocated segment `segment`.
    extern fn gst_segment_free(p_segment: *Segment) void;
    pub const free = gst_segment_free;

    /// The start/position fields are set to 0 and the stop/duration
    /// fields are set to -1 (unknown). The default rate of 1.0 and no
    /// flags are set.
    ///
    /// Initialize `segment` to its default values.
    extern fn gst_segment_init(p_segment: *Segment, p_format: gst.Format) void;
    pub const init = gst_segment_init;

    /// Checks for two segments being equal. Equality here is defined
    /// as perfect equality, including floating point values.
    extern fn gst_segment_is_equal(p_s0: *const Segment, p_s1: *const gst.Segment) c_int;
    pub const isEqual = gst_segment_is_equal;

    /// Adjust the values in `segment` so that `offset` is applied to all
    /// future running-time calculations.
    extern fn gst_segment_offset_running_time(p_segment: *Segment, p_format: gst.Format, p_offset: i64) c_int;
    pub const offsetRunningTime = gst_segment_offset_running_time;

    /// Convert `running_time` into a position in the segment so that
    /// `gst.Segment.toRunningTime` with that position returns `running_time`.
    extern fn gst_segment_position_from_running_time(p_segment: *const Segment, p_format: gst.Format, p_running_time: u64) u64;
    pub const positionFromRunningTime = gst_segment_position_from_running_time;

    /// Translate `running_time` to the segment position using the currently configured
    /// segment. Compared to `gst.Segment.positionFromRunningTime` this function can
    /// return negative segment position.
    ///
    /// This function is typically used by elements that need to synchronize buffers
    /// against the clock or each other.
    ///
    /// `running_time` can be any value and the result of this function for values
    /// outside of the segment is extrapolated.
    ///
    /// When 1 is returned, `running_time` resulted in a positive position returned
    /// in `position`.
    ///
    /// When this function returns -1, the returned `position` was < 0, and the value
    /// in the position variable should be negated to get the real negative segment
    /// position.
    extern fn gst_segment_position_from_running_time_full(p_segment: *const Segment, p_format: gst.Format, p_running_time: u64, p_position: *u64) c_int;
    pub const positionFromRunningTimeFull = gst_segment_position_from_running_time_full;

    /// Convert `stream_time` into a position in the segment so that
    /// `gst.Segment.toStreamTime` with that position returns `stream_time`.
    extern fn gst_segment_position_from_stream_time(p_segment: *const Segment, p_format: gst.Format, p_stream_time: u64) u64;
    pub const positionFromStreamTime = gst_segment_position_from_stream_time;

    /// Translate `stream_time` to the segment position using the currently configured
    /// segment. Compared to `gst.Segment.positionFromStreamTime` this function can
    /// return negative segment position.
    ///
    /// This function is typically used by elements that need to synchronize buffers
    /// against the clock or each other.
    ///
    /// `stream_time` can be any value and the result of this function for values outside
    /// of the segment is extrapolated.
    ///
    /// When 1 is returned, `stream_time` resulted in a positive position returned
    /// in `position`.
    ///
    /// When this function returns -1, the returned `position` should be negated
    /// to get the real negative segment position.
    extern fn gst_segment_position_from_stream_time_full(p_segment: *const Segment, p_format: gst.Format, p_stream_time: u64, p_position: *u64) c_int;
    pub const positionFromStreamTimeFull = gst_segment_position_from_stream_time_full;

    /// Adjust the start/stop and base values of `segment` such that the next valid
    /// buffer will be one with `running_time`.
    extern fn gst_segment_set_running_time(p_segment: *Segment, p_format: gst.Format, p_running_time: u64) c_int;
    pub const setRunningTime = gst_segment_set_running_time;

    /// Convert `running_time` into a position in the segment so that
    /// `gst.Segment.toRunningTime` with that position returns `running_time`.
    extern fn gst_segment_to_position(p_segment: *const Segment, p_format: gst.Format, p_running_time: u64) u64;
    pub const toPosition = gst_segment_to_position;

    /// Translate `position` to the total running time using the currently configured
    /// segment. Position is a value between `segment` start and stop time.
    ///
    /// This function is typically used by elements that need to synchronize to the
    /// global clock in a pipeline. The running time is a constantly increasing value
    /// starting from 0. When `gst.Segment.init` is called, this value will reset to
    /// 0.
    ///
    /// This function returns -1 if the position is outside of `segment` start and stop.
    extern fn gst_segment_to_running_time(p_segment: *const Segment, p_format: gst.Format, p_position: u64) u64;
    pub const toRunningTime = gst_segment_to_running_time;

    /// Translate `position` to the total running time using the currently configured
    /// segment. Compared to `gst.Segment.toRunningTime` this function can return
    /// negative running-time.
    ///
    /// This function is typically used by elements that need to synchronize buffers
    /// against the clock or each other.
    ///
    /// `position` can be any value and the result of this function for values outside
    /// of the segment is extrapolated.
    ///
    /// When 1 is returned, `position` resulted in a positive running-time returned
    /// in `running_time`.
    ///
    /// When this function returns -1, the returned `running_time` should be negated
    /// to get the real negative running time.
    extern fn gst_segment_to_running_time_full(p_segment: *const Segment, p_format: gst.Format, p_position: u64, p_running_time: ?*u64) c_int;
    pub const toRunningTimeFull = gst_segment_to_running_time_full;

    /// Translate `position` to stream time using the currently configured
    /// segment. The `position` value must be between `segment` start and
    /// stop value.
    ///
    /// This function is typically used by elements that need to operate on
    /// the stream time of the buffers it receives, such as effect plugins.
    /// In those use cases, `position` is typically the buffer timestamp or
    /// clock time that one wants to convert to the stream time.
    /// The stream time is always between 0 and the total duration of the
    /// media stream.
    extern fn gst_segment_to_stream_time(p_segment: *const Segment, p_format: gst.Format, p_position: u64) u64;
    pub const toStreamTime = gst_segment_to_stream_time;

    /// Translate `position` to the total stream time using the currently configured
    /// segment. Compared to `gst.Segment.toStreamTime` this function can return
    /// negative stream-time.
    ///
    /// This function is typically used by elements that need to synchronize buffers
    /// against the clock or each other.
    ///
    /// `position` can be any value and the result of this function for values outside
    /// of the segment is extrapolated.
    ///
    /// When 1 is returned, `position` resulted in a positive stream-time returned
    /// in `stream_time`.
    ///
    /// When this function returns -1, the returned `stream_time` should be negated
    /// to get the real negative stream time.
    extern fn gst_segment_to_stream_time_full(p_segment: *const Segment, p_format: gst.Format, p_position: u64, p_stream_time: *u64) c_int;
    pub const toStreamTimeFull = gst_segment_to_stream_time_full;

    extern fn gst_segment_get_type() usize;
    pub const getGObjectType = gst_segment_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.SharedTaskPoolClass` object.
pub const SharedTaskPoolClass = extern struct {
    pub const Instance = gst.SharedTaskPool;

    f_parent_class: gst.TaskPoolClass,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *SharedTaskPoolClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SharedTaskPoolPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Data structure to initialize `gst.Caps` from a string description usually
/// used in conjunction with `GST_STATIC_CAPS` and `gst.StaticCaps.get` to
/// instantiate a `gst.Caps`.
pub const StaticCaps = extern struct {
    /// the cached `gst.Caps`
    f_caps: ?*gst.Caps,
    /// a string describing a caps
    f_string: ?[*:0]const u8,
    f__gst_reserved: [4]*anyopaque,

    /// Cleans up the cached caps contained in `static_caps`.
    extern fn gst_static_caps_cleanup(p_static_caps: *StaticCaps) void;
    pub const cleanup = gst_static_caps_cleanup;

    /// Converts a `gst.StaticCaps` to a `gst.Caps`.
    extern fn gst_static_caps_get(p_static_caps: *StaticCaps) ?*gst.Caps;
    pub const get = gst_static_caps_get;

    extern fn gst_static_caps_get_type() usize;
    pub const getGObjectType = gst_static_caps_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Structure describing the `gst.StaticPadTemplate`.
pub const StaticPadTemplate = extern struct {
    /// the name of the template
    f_name_template: ?[*:0]const u8,
    /// the direction of the template
    f_direction: gst.PadDirection,
    /// the presence of the template
    f_presence: gst.PadPresence,
    /// the caps of the template.
    f_static_caps: gst.StaticCaps,

    /// Converts a `gst.StaticPadTemplate` into a `gst.PadTemplate`.
    extern fn gst_static_pad_template_get(p_pad_template: *StaticPadTemplate) ?*gst.PadTemplate;
    pub const get = gst_static_pad_template_get;

    /// Gets the capabilities of the static pad template.
    extern fn gst_static_pad_template_get_caps(p_templ: *StaticPadTemplate) *gst.Caps;
    pub const getCaps = gst_static_pad_template_get_caps;

    extern fn gst_static_pad_template_get_type() usize;
    pub const getGObjectType = gst_static_pad_template_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstStream class structure
pub const StreamClass = extern struct {
    pub const Instance = gst.Stream;

    /// the parent class structure
    f_parent_class: gst.ObjectClass,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *StreamClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstStreamCollection class structure
pub const StreamCollectionClass = extern struct {
    pub const Instance = gst.StreamCollection;

    /// the parent class structure
    f_parent_class: gst.ObjectClass,
    /// default signal handler for the stream-notify signal
    f_stream_notify: ?*const fn (p_collection: *gst.StreamCollection, p_stream: *gst.Stream, p_pspec: *gobject.ParamSpec) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *StreamCollectionClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const StreamCollectionPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const StreamPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.Structure` is a collection of key/value pairs. The keys are expressed as
/// GQuarks and the values can be of any GType.
///
/// In addition to the key/value pairs, a `gst.Structure` also has a name. The name
/// starts with a letter and can be filled by letters, numbers and any of
/// "/-_.:".
///
/// `gst.Structure` is used by various GStreamer subsystems to store information in
/// a flexible and extensible way. A `gst.Structure` does not have a refcount
/// because it usually is part of a higher level object such as `gst.Caps`,
/// `gst.Message`, `gst.Event`, `gst.Query`. It provides a means to enforce mutability
/// using the refcount of the parent with the `gst.Structure.setParentRefcount`
/// method.
///
/// A `gst.Structure` can be created with `gst.Structure.newEmpty` or
/// `gst.Structure.new`, which both take a name and an optional set of key/value
/// pairs along with the types of the values.
///
/// Field values can be changed with `gst.Structure.setValue` or
/// `gst.Structure.set`.
///
/// Field values can be retrieved with `gst.Structure.getValue` or the more
/// convenient gst_structure_get_*() functions.
///
/// Fields can be removed with `gst.Structure.removeField` or
/// `gst.Structure.removeFields`.
///
/// Strings in structures must be ASCII or UTF-8 encoded. Other encodings are not
/// allowed. Strings may be `NULL` however.
///
/// ## The serialization format
///
/// GstStructure serialization format serialize the GstStructure name,
/// keys/GType/values in a comma separated list with the structure name as first
/// field without value followed by separated key/value pairs in the form
/// `key=value`, for example:
///
/// ```
/// a-structure, key=value
/// ````
///
/// The values type will be inferred if not explicitly specified with the
/// `(GTypeName)value` syntax, for example the following struct will have one
/// field called 'is-string' which has the string 'true' as a value:
///
/// ```
/// a-struct, field-is-string=(string)true, field-is-boolean=true
/// ```
///
/// *Note*: without specifying `(string), `field-is-string` type would have been
/// inferred as boolean.
///
/// *Note*: we specified `(string)` as a type even if `gchararray` is the actual
/// GType name as for convenience some well known types have been aliased or
/// abbreviated.
///
/// To avoid specifying the type, you can give some hints to the "type system".
/// For example to specify a value as a double, you should add a decimal (ie. `1`
/// is an `int` while `1.0` is a `double`).
///
/// *Note*: when a structure is serialized with `gst.Structure.toString`, all
/// values are explicitly typed.
///
/// Some types have special delimiters:
///
/// - [GstValueArray](GST_TYPE_ARRAY) are inside "less and greater than" (`<` and
///   `>`). For example `a-structure, array=<1, 2, 3>
/// - Ranges are inside brackets (`[` and `]`). For example `a-structure,
///   range=[1, 6, 2]` 1 being the min value, 6 the maximum and 2 the step. To
///   specify a `GST_TYPE_INT64_RANGE` you need to explicitly specify it like:
///   `a-structure, a-int64-range=(gint64) [1, 5]`
/// - [GstValueList](GST_TYPE_LIST) are inside curly brackets (`{` and `}`).
///   For example `a-structure, list={1, 2, 3}`
/// - [GStrv](G_TYPE_STRV) are inside "less and greater than" (`<` and
///   `>`) and each string is double-quoted.
///   For example `a-structure, strv=(GStrv)<"foo", "bar">`. Since 1.26.0.
///
/// Structures are delimited either by a null character `\0` or a semicolon `;`
/// the latter allowing to store multiple structures in the same string (see
/// `gst.Caps`).
///
/// Quotes are used as "default" delimiters and can be used around any types that
/// don't use other delimiters (for example `a-struct, i=(int)"1"`). They are use
/// to allow adding spaces or special characters (such as delimiters,
/// semicolumns, etc..) inside strings and you can use backslashes `\` to escape
/// characters inside them, for example:
///
/// ```
/// a-struct, special="\"{[(;)]}\" can be used inside quotes"
/// ```
///
/// They also allow for nested structure, such as:
///
/// ```
/// a-struct, nested=(GstStructure)"nested-struct, nested=true"
/// ```
///
/// Since 1.20, nested structures and caps can be specified using brackets (`[`
/// and `]`), for example:
///
/// ```
/// a-struct, nested=[nested-struct, nested=true]
/// ```
///
/// > *note*: `gst.Structure.toString` won't use that syntax for backward
/// > compatibility reason, `gst.Structure.serializeFull` has been added for
/// > that purpose.
pub const Structure = extern struct {
    /// the GType of a structure
    f_type: usize,
    f_name: glib.Quark,

    /// Atomically modifies a pointer to point to a new structure.
    /// The `gst.Structure` `oldstr_ptr` is pointing to is freed and
    /// `newstr` is taken ownership over.
    ///
    /// Either `newstr` and the value pointed to by `oldstr_ptr` may be `NULL`.
    ///
    /// It is a programming error if both `newstr` and the value pointed to by
    /// `oldstr_ptr` refer to the same, non-`NULL` structure.
    extern fn gst_structure_take(p_oldstr_ptr: ?**gst.Structure, p_newstr: ?*gst.Structure) c_int;
    pub const take = gst_structure_take;

    /// Creates a `gst.Structure` from a string representation.
    /// If end is not `NULL`, a pointer to the place inside the given string
    /// where parsing ended will be returned.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_from_string(p_string: [*:0]const u8, p_end: ?*[*:0]u8) ?*gst.Structure;
    pub const fromString = gst_structure_from_string;

    /// Creates a new `gst.Structure` with the given name.  Parses the
    /// list of variable arguments and sets fields to the values listed.
    /// Variable arguments should be passed as field name, field type,
    /// and value.  Last variable argument should be `NULL`.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new(p_name: [*:0]const u8, p_firstfield: [*:0]const u8, ...) *gst.Structure;
    pub const new = gst_structure_new;

    /// Creates a new, empty `gst.Structure` with the given `name`.
    ///
    /// See `gst.Structure.setName` for constraints on the `name` parameter.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_empty(p_name: [*:0]const u8) *gst.Structure;
    pub const newEmpty = gst_structure_new_empty;

    /// Creates a `gst.Structure` from a string representation.
    /// If end is not `NULL`, a pointer to the place inside the given string
    /// where parsing ended will be returned.
    ///
    /// The current implementation of serialization will lead to unexpected results
    /// when there are nested `gst.Caps` / `gst.Structure` deeper than one level unless
    /// the `gst.Structure.serialize` function is used (without
    /// `GST_SERIALIZE_FLAG_BACKWARD_COMPAT`)
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_from_string(p_string: [*:0]const u8) ?*gst.Structure;
    pub const newFromString = gst_structure_new_from_string;

    /// Creates a new `gst.Structure` with the given name as a GQuark, followed by
    /// fieldname quark, GType, argument(s) "triplets" in the same format as
    /// `gst.Structure.idSet`. Basically a convenience wrapper around
    /// `gst.Structure.newIdEmpty` and `gst.Structure.idSet`.
    ///
    /// The last variable argument must be `NULL` (or 0).
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_id(p_name_quark: glib.Quark, p_field_quark: glib.Quark, ...) *gst.Structure;
    pub const newId = gst_structure_new_id;

    /// Creates a new, empty `gst.Structure` with the given name as a GQuark.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_id_empty(p_quark: glib.Quark) *gst.Structure;
    pub const newIdEmpty = gst_structure_new_id_empty;

    /// Creates a new `gst.Structure` with the given name as a GQuark, followed by
    /// fieldname GstIdStr, GType, argument(s) "triplets" in the same format as
    /// `gst.Structure.idStrSet`. Basically a convenience wrapper around
    /// `gst.Structure.newIdStrEmpty` and `gst.Structure.idStrSet`.
    ///
    /// The last variable argument must be `NULL` (or 0).
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_id_str(p_name: *const gst.IdStr, p_fieldname: *const gst.IdStr, ...) *gst.Structure;
    pub const newIdStr = gst_structure_new_id_str;

    /// Creates a new, empty `gst.Structure` with the given name.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_id_str_empty(p_name: *const gst.IdStr) *gst.Structure;
    pub const newIdStrEmpty = gst_structure_new_id_str_empty;

    /// Creates a new `gst.Structure` with the given `name`.  Structure fields
    /// are set according to the varargs in a manner similar to
    /// `gst.Structure.newIdStr`.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_id_str_valist(p_name: *const gst.IdStr, p_firstfield: *const gst.IdStr, p_varargs: std.builtin.VaList) *gst.Structure;
    pub const newIdStrValist = gst_structure_new_id_str_valist;

    /// Creates a new `gst.Structure` with the given name.  Parses the
    /// list of variable arguments and sets fields to the values listed.
    /// Variable arguments should be passed as field name, field type,
    /// and value.  Last variable argument should be `NULL`.
    ///
    /// `name`, `firstfield` and all field names need to be valid for the remaining
    /// lifetime of the process, e.g. have to be a static string.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_static_str(p_name: [*:0]const u8, p_firstfield: [*:0]const u8, ...) *gst.Structure;
    pub const newStaticStr = gst_structure_new_static_str;

    /// Creates a new, empty `gst.Structure` with the given `name`.
    ///
    /// See `gst.Structure.setName` for constraints on the `name` parameter.
    ///
    /// `name` needs to be valid for the remaining lifetime of the process, e.g. has
    /// to be a static string.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_static_str_empty(p_name: [*:0]const u8) *gst.Structure;
    pub const newStaticStrEmpty = gst_structure_new_static_str_empty;

    /// Creates a new `gst.Structure` with the given `name`.  Structure fields
    /// are set according to the varargs in a manner similar to
    /// `gst.Structure.new`.
    ///
    /// See `gst.Structure.setName` for constraints on the `name` parameter.
    ///
    /// `name`, `firstfield` and all field names need to be valid for the remaining
    /// lifetime of the process, e.g. have to be a static string.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_static_str_valist(p_name: [*:0]const u8, p_firstfield: [*:0]const u8, p_varargs: std.builtin.VaList) *gst.Structure;
    pub const newStaticStrValist = gst_structure_new_static_str_valist;

    /// Creates a new `gst.Structure` with the given `name`.  Structure fields
    /// are set according to the varargs in a manner similar to
    /// `gst.Structure.new`.
    ///
    /// See `gst.Structure.setName` for constraints on the `name` parameter.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_new_valist(p_name: [*:0]const u8, p_firstfield: [*:0]const u8, p_varargs: std.builtin.VaList) *gst.Structure;
    pub const newValist = gst_structure_new_valist;

    /// Tries intersecting `struct1` and `struct2` and reports whether the result
    /// would not be empty.
    extern fn gst_structure_can_intersect(p_struct1: *const Structure, p_struct2: *const gst.Structure) c_int;
    pub const canIntersect = gst_structure_can_intersect;

    /// Duplicates a `gst.Structure` and all its fields and values.
    ///
    /// Free-function: gst_structure_free
    extern fn gst_structure_copy(p_structure: *const Structure) *gst.Structure;
    pub const copy = gst_structure_copy;

    /// Calls the provided function once for each field in the `gst.Structure`. In
    /// contrast to `gst.Structure.foreach`, the function may modify the fields.
    /// In contrast to `gst.Structure.mapInPlace`, the field is removed from
    /// the structure if `FALSE` is returned from the function.
    /// The structure must be mutable.
    extern fn gst_structure_filter_and_map_in_place(p_structure: *Structure, p_func: gst.StructureFilterMapFunc, p_user_data: ?*anyopaque) void;
    pub const filterAndMapInPlace = gst_structure_filter_and_map_in_place;

    /// Calls the provided function once for each field in the `gst.Structure`. In
    /// contrast to `gst.Structure.foreachIdStr`, the function may modify the fields.
    /// In contrast to `gst.Structure.mapInPlaceIdStr`, the field is removed from
    /// the structure if `FALSE` is returned from the function.
    /// The structure must be mutable.
    extern fn gst_structure_filter_and_map_in_place_id_str(p_structure: *Structure, p_func: gst.StructureFilterMapIdStrFunc, p_user_data: ?*anyopaque) void;
    pub const filterAndMapInPlaceIdStr = gst_structure_filter_and_map_in_place_id_str;

    /// Fixate all values in `structure` using `gst.valueFixate`.
    /// `structure` will be modified in-place and should be writable.
    extern fn gst_structure_fixate(p_structure: *Structure) void;
    pub const fixate = gst_structure_fixate;

    /// Fixates a `gst.Structure` by changing the given field with its fixated value.
    extern fn gst_structure_fixate_field(p_structure: *Structure, p_field_name: [*:0]const u8) c_int;
    pub const fixateField = gst_structure_fixate_field;

    /// Fixates a `gst.Structure` by changing the given `field_name` field to the given
    /// `target` boolean if that field is not fixed yet.
    extern fn gst_structure_fixate_field_boolean(p_structure: *Structure, p_field_name: [*:0]const u8, p_target: c_int) c_int;
    pub const fixateFieldBoolean = gst_structure_fixate_field_boolean;

    /// Fixates a `gst.Structure` by changing the given field to the nearest
    /// double to `target` that is a subset of the existing field.
    extern fn gst_structure_fixate_field_nearest_double(p_structure: *Structure, p_field_name: [*:0]const u8, p_target: f64) c_int;
    pub const fixateFieldNearestDouble = gst_structure_fixate_field_nearest_double;

    /// Fixates a `gst.Structure` by changing the given field to the nearest
    /// fraction to `target_numerator`/`target_denominator` that is a subset
    /// of the existing field.
    extern fn gst_structure_fixate_field_nearest_fraction(p_structure: *Structure, p_field_name: [*:0]const u8, p_target_numerator: c_int, p_target_denominator: c_int) c_int;
    pub const fixateFieldNearestFraction = gst_structure_fixate_field_nearest_fraction;

    /// Fixates a `gst.Structure` by changing the given field to the nearest
    /// integer to `target` that is a subset of the existing field.
    extern fn gst_structure_fixate_field_nearest_int(p_structure: *Structure, p_field_name: [*:0]const u8, p_target: c_int) c_int;
    pub const fixateFieldNearestInt = gst_structure_fixate_field_nearest_int;

    /// Fixates a `gst.Structure` by changing the given `field_name` field to the given
    /// `target` string if that field is not fixed yet.
    extern fn gst_structure_fixate_field_string(p_structure: *Structure, p_field_name: [*:0]const u8, p_target: [*:0]const u8) c_int;
    pub const fixateFieldString = gst_structure_fixate_field_string;

    /// Calls the provided function once for each field in the `gst.Structure`. The
    /// function must not modify the fields. Also see `gst.Structure.mapInPlace`
    /// and `gst.Structure.filterAndMapInPlace`.
    extern fn gst_structure_foreach(p_structure: *const Structure, p_func: gst.StructureForeachFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreach = gst_structure_foreach;

    /// Calls the provided function once for each field in the `gst.Structure`. The
    /// function must not modify the fields. Also see `gst.Structure.mapInPlaceIdStr`
    /// and `gst.Structure.filterAndMapInPlaceIdStr`.
    extern fn gst_structure_foreach_id_str(p_structure: *const Structure, p_func: gst.StructureForeachIdStrFunc, p_user_data: ?*anyopaque) c_int;
    pub const foreachIdStr = gst_structure_foreach_id_str;

    /// Frees a `gst.Structure` and all its fields and values. The structure must not
    /// have a parent when this function is called.
    extern fn gst_structure_free(p_structure: *Structure) void;
    pub const free = gst_structure_free;

    /// Parses the variable arguments and reads fields from `structure` accordingly.
    /// Variable arguments should be in the form field name, field type
    /// (as a GType), pointer(s) to a variable(s) to hold the return value(s).
    /// The last variable argument should be `NULL`.
    ///
    /// For refcounted (mini)objects you will receive a new reference which
    /// you must release with a suitable _unref\() when no longer needed. For
    /// strings and boxed types you will receive a copy which you will need to
    /// release with either `glib.free` or the suitable function for the boxed type.
    extern fn gst_structure_get(p_structure: *const Structure, p_first_fieldname: [*:0]const u8, ...) c_int;
    pub const get = gst_structure_get;

    /// This is useful in language bindings where unknown `gobject.Value` types are not
    /// supported. This function will convert the `GST_TYPE_ARRAY` into a newly
    /// allocated `gobject.ValueArray` and return it through `array`. Be aware that this is
    /// slower then getting the `gobject.Value` directly.
    extern fn gst_structure_get_array(p_structure: *Structure, p_fieldname: [*:0]const u8, p_array: **gobject.ValueArray) c_int;
    pub const getArray = gst_structure_get_array;

    /// Sets the boolean pointed to by `value` corresponding to the value of the
    /// given field.  Caller is responsible for making sure the field exists
    /// and has the correct type.
    extern fn gst_structure_get_boolean(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: *c_int) c_int;
    pub const getBoolean = gst_structure_get_boolean;

    /// Sets the clock time pointed to by `value` corresponding to the clock time
    /// of the given field.  Caller is responsible for making sure the field exists
    /// and has the correct type.
    extern fn gst_structure_get_clock_time(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: *gst.ClockTime) c_int;
    pub const getClockTime = gst_structure_get_clock_time;

    /// Sets the date pointed to by `value` corresponding to the date of the
    /// given field.  Caller is responsible for making sure the field exists
    /// and has the correct type.
    ///
    /// On success `value` will point to a newly-allocated copy of the date which
    /// should be freed with `glib.Date.free` when no longer needed (note: this is
    /// inconsistent with e.g. `gst.Structure.getString` which doesn't return a
    /// copy of the string).
    extern fn gst_structure_get_date(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: **glib.Date) c_int;
    pub const getDate = gst_structure_get_date;

    /// Sets the datetime pointed to by `value` corresponding to the datetime of the
    /// given field. Caller is responsible for making sure the field exists
    /// and has the correct type.
    ///
    /// On success `value` will point to a reference of the datetime which
    /// should be unreffed with `gst.DateTime.unref` when no longer needed
    /// (note: this is inconsistent with e.g. `gst.Structure.getString`
    /// which doesn't return a copy of the string).
    extern fn gst_structure_get_date_time(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: **gst.DateTime) c_int;
    pub const getDateTime = gst_structure_get_date_time;

    /// Sets the double pointed to by `value` corresponding to the value of the
    /// given field.  Caller is responsible for making sure the field exists
    /// and has the correct type.
    extern fn gst_structure_get_double(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: *f64) c_int;
    pub const getDouble = gst_structure_get_double;

    /// Sets the int pointed to by `value` corresponding to the value of the
    /// given field.  Caller is responsible for making sure the field exists,
    /// has the correct type and that the enumtype is correct.
    extern fn gst_structure_get_enum(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_enumtype: usize, p_value: *c_int) c_int;
    pub const getEnum = gst_structure_get_enum;

    /// Finds the field with the given name, and returns the type of the
    /// value it contains.  If the field is not found, G_TYPE_INVALID is
    /// returned.
    extern fn gst_structure_get_field_type(p_structure: *const Structure, p_fieldname: [*:0]const u8) usize;
    pub const getFieldType = gst_structure_get_field_type;

    /// Sets the unsigned int pointed to by `value` corresponding to the value of the
    /// given field. Caller is responsible for making sure the field exists,
    /// has the correct type and that the flagstype is correct.
    extern fn gst_structure_get_flags(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_flags_type: usize, p_value: *c_uint) c_int;
    pub const getFlags = gst_structure_get_flags;

    /// Read the GstFlagSet flags and mask out of the structure into the
    /// provided pointers.
    extern fn gst_structure_get_flagset(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value_flags: ?*c_uint, p_value_mask: ?*c_uint) c_int;
    pub const getFlagset = gst_structure_get_flagset;

    /// Sets the integers pointed to by `value_numerator` and `value_denominator`
    /// corresponding to the value of the given field.  Caller is responsible
    /// for making sure the field exists and has the correct type.
    extern fn gst_structure_get_fraction(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value_numerator: *c_int, p_value_denominator: *c_int) c_int;
    pub const getFraction = gst_structure_get_fraction;

    /// Sets the int pointed to by `value` corresponding to the value of the
    /// given field.  Caller is responsible for making sure the field exists
    /// and has the correct type.
    extern fn gst_structure_get_int(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: *c_int) c_int;
    pub const getInt = gst_structure_get_int;

    /// Sets the `gint64` pointed to by `value` corresponding to the value of the
    /// given field. Caller is responsible for making sure the field exists
    /// and has the correct type.
    extern fn gst_structure_get_int64(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: *i64) c_int;
    pub const getInt64 = gst_structure_get_int64;

    /// This is useful in language bindings where unknown `gobject.Value` types are not
    /// supported. This function will convert the `GST_TYPE_LIST` into a newly
    /// allocated GValueArray and return it through `array`. Be aware that this is
    /// slower then getting the `gobject.Value` directly.
    extern fn gst_structure_get_list(p_structure: *Structure, p_fieldname: [*:0]const u8, p_array: **gobject.ValueArray) c_int;
    pub const getList = gst_structure_get_list;

    /// Get the name of `structure` as a string.
    extern fn gst_structure_get_name(p_structure: *const Structure) [*:0]const u8;
    pub const getName = gst_structure_get_name;

    /// Get the name of `structure` as a GQuark.
    extern fn gst_structure_get_name_id(p_structure: *const Structure) glib.Quark;
    pub const getNameId = gst_structure_get_name_id;

    /// Get the name of `structure` as a GstIdStr.
    extern fn gst_structure_get_name_id_str(p_structure: *const Structure) *const gst.IdStr;
    pub const getNameIdStr = gst_structure_get_name_id_str;

    /// Finds the field corresponding to `fieldname`, and returns the string
    /// contained in the field's value.  Caller is responsible for making
    /// sure the field exists and has the correct type.
    ///
    /// The string should not be modified, and remains valid until the next
    /// call to a gst_structure_*() function with the given structure.
    extern fn gst_structure_get_string(p_structure: *const Structure, p_fieldname: [*:0]const u8) ?[*:0]const u8;
    pub const getString = gst_structure_get_string;

    /// Sets the uint pointed to by `value` corresponding to the value of the
    /// given field.  Caller is responsible for making sure the field exists
    /// and has the correct type.
    extern fn gst_structure_get_uint(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: *c_uint) c_int;
    pub const getUint = gst_structure_get_uint;

    /// Sets the `guint64` pointed to by `value` corresponding to the value of the
    /// given field. Caller is responsible for making sure the field exists
    /// and has the correct type.
    extern fn gst_structure_get_uint64(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_value: *u64) c_int;
    pub const getUint64 = gst_structure_get_uint64;

    /// Parses the variable arguments and reads fields from `structure` accordingly.
    /// valist-variant of `gst.Structure.get`. Look at the documentation of
    /// `gst.Structure.get` for more details.
    extern fn gst_structure_get_valist(p_structure: *const Structure, p_first_fieldname: [*:0]const u8, p_args: std.builtin.VaList) c_int;
    pub const getValist = gst_structure_get_valist;

    /// Get the value of the field with name `fieldname`.
    extern fn gst_structure_get_value(p_structure: *const Structure, p_fieldname: [*:0]const u8) ?*const gobject.Value;
    pub const getValue = gst_structure_get_value;

    /// Check if `structure` contains a field named `fieldname`.
    extern fn gst_structure_has_field(p_structure: *const Structure, p_fieldname: [*:0]const u8) c_int;
    pub const hasField = gst_structure_has_field;

    /// Check if `structure` contains a field named `fieldname` and with GType `type`.
    extern fn gst_structure_has_field_typed(p_structure: *const Structure, p_fieldname: [*:0]const u8, p_type: usize) c_int;
    pub const hasFieldTyped = gst_structure_has_field_typed;

    /// Checks if the structure has the given name
    extern fn gst_structure_has_name(p_structure: *const Structure, p_name: [*:0]const u8) c_int;
    pub const hasName = gst_structure_has_name;

    /// Parses the variable arguments and reads fields from `structure` accordingly.
    /// Variable arguments should be in the form field id quark, field type
    /// (as a GType), pointer(s) to a variable(s) to hold the return value(s).
    /// The last variable argument should be `NULL` (technically it should be a
    /// 0 quark, but we require `NULL` so compilers that support it can check for
    /// the `NULL` terminator and warn if it's not there).
    ///
    /// This function is just like `gst.Structure.get` only that it is slightly
    /// more efficient since it saves the string-to-quark lookup in the global
    /// quark hashtable.
    ///
    /// For refcounted (mini)objects you will receive a new reference which
    /// you must release with a suitable _unref\() when no longer needed. For
    /// strings and boxed types you will receive a copy which you will need to
    /// release with either `glib.free` or the suitable function for the boxed type.
    extern fn gst_structure_id_get(p_structure: *const Structure, p_first_field_id: glib.Quark, ...) c_int;
    pub const idGet = gst_structure_id_get;

    /// Parses the variable arguments and reads fields from `structure` accordingly.
    /// valist-variant of `gst.Structure.idGet`. Look at the documentation of
    /// `gst.Structure.idGet` for more details.
    extern fn gst_structure_id_get_valist(p_structure: *const Structure, p_first_field_id: glib.Quark, p_args: std.builtin.VaList) c_int;
    pub const idGetValist = gst_structure_id_get_valist;

    /// Get the value of the field with GQuark `field`.
    extern fn gst_structure_id_get_value(p_structure: *const Structure, p_field: glib.Quark) ?*const gobject.Value;
    pub const idGetValue = gst_structure_id_get_value;

    /// Check if `structure` contains a field named `field`.
    extern fn gst_structure_id_has_field(p_structure: *const Structure, p_field: glib.Quark) c_int;
    pub const idHasField = gst_structure_id_has_field;

    /// Check if `structure` contains a field named `field` and with GType `type`.
    extern fn gst_structure_id_has_field_typed(p_structure: *const Structure, p_field: glib.Quark, p_type: usize) c_int;
    pub const idHasFieldTyped = gst_structure_id_has_field_typed;

    /// Identical to gst_structure_set, except that field names are
    /// passed using the GQuark for the field name. This allows more efficient
    /// setting of the structure if the caller already knows the associated
    /// quark values.
    /// The last variable argument must be `NULL`.
    extern fn gst_structure_id_set(p_structure: *Structure, p_fieldname: glib.Quark, ...) void;
    pub const idSet = gst_structure_id_set;

    /// va_list form of `gst.Structure.idSet`.
    extern fn gst_structure_id_set_valist(p_structure: *Structure, p_fieldname: glib.Quark, p_varargs: std.builtin.VaList) void;
    pub const idSetValist = gst_structure_id_set_valist;

    /// Sets the field with the given GQuark `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed.
    extern fn gst_structure_id_set_value(p_structure: *Structure, p_field: glib.Quark, p_value: *const gobject.Value) void;
    pub const idSetValue = gst_structure_id_set_value;

    /// Parses the variable arguments and reads fields from `structure` accordingly.
    /// Variable arguments should be in the form field name (as GstIdStr), field type
    /// (as a GType), pointer(s) to a variable(s) to hold the return value(s). The
    /// last variable argument should be `NULL`.
    ///
    /// For refcounted (mini)objects you will receive a new reference which
    /// you must release with a suitable _unref\() when no longer needed. For
    /// strings and boxed types you will receive a copy which you will need to
    /// release with either `glib.free` or the suitable function for the boxed type.
    extern fn gst_structure_id_str_get(p_structure: *const Structure, p_first_fieldname: *const gst.IdStr, ...) c_int;
    pub const idStrGet = gst_structure_id_str_get;

    /// Finds the field with the given name, and returns the type of the
    /// value it contains.  If the field is not found, G_TYPE_INVALID is
    /// returned.
    extern fn gst_structure_id_str_get_field_type(p_structure: *const Structure, p_fieldname: *const gst.IdStr) usize;
    pub const idStrGetFieldType = gst_structure_id_str_get_field_type;

    /// Parses the variable arguments and reads fields from `structure` accordingly.
    /// valist-variant of `gst.Structure.idStrGet`. Look at the documentation of
    /// `gst.Structure.idStrGet` for more details.
    extern fn gst_structure_id_str_get_valist(p_structure: *const Structure, p_first_fieldname: *const gst.IdStr, p_args: std.builtin.VaList) c_int;
    pub const idStrGetValist = gst_structure_id_str_get_valist;

    /// Get the value of the field with name `fieldname`.
    extern fn gst_structure_id_str_get_value(p_structure: *const Structure, p_fieldname: *const gst.IdStr) ?*const gobject.Value;
    pub const idStrGetValue = gst_structure_id_str_get_value;

    /// Check if `structure` contains a field named `fieldname`.
    extern fn gst_structure_id_str_has_field(p_structure: *const Structure, p_fieldname: *const gst.IdStr) c_int;
    pub const idStrHasField = gst_structure_id_str_has_field;

    /// Check if `structure` contains a field named `fieldname` and with GType `type`.
    extern fn gst_structure_id_str_has_field_typed(p_structure: *const Structure, p_fieldname: *const gst.IdStr, p_type: usize) c_int;
    pub const idStrHasFieldTyped = gst_structure_id_str_has_field_typed;

    /// Get the name (as a GstIdStr) of the given field number,
    /// counting from 0 onwards.
    extern fn gst_structure_id_str_nth_field_name(p_structure: *const Structure, p_index: c_uint) *const gst.IdStr;
    pub const idStrNthFieldName = gst_structure_id_str_nth_field_name;

    /// Removes the field with the given name.  If the field with the given
    /// name does not exist, the structure is unchanged.
    extern fn gst_structure_id_str_remove_field(p_structure: *Structure, p_fieldname: *const gst.IdStr) void;
    pub const idStrRemoveField = gst_structure_id_str_remove_field;

    /// Removes the fields with the given names. If a field does not exist, the
    /// argument is ignored.
    extern fn gst_structure_id_str_remove_fields(p_structure: *Structure, p_fieldname: *const gst.IdStr, ...) void;
    pub const idStrRemoveFields = gst_structure_id_str_remove_fields;

    /// va_list form of `gst.Structure.idStrRemoveFields`.
    extern fn gst_structure_id_str_remove_fields_valist(p_structure: *Structure, p_fieldname: *const gst.IdStr, p_varargs: std.builtin.VaList) void;
    pub const idStrRemoveFieldsValist = gst_structure_id_str_remove_fields_valist;

    /// Identical to gst_structure_set, except that field names are
    /// passed using a GstIdStr for the field name. This allows more efficient
    /// setting of the structure if the caller already owns the associated
    /// GstIdStr values or if they can be built from static literals.
    /// The last variable argument must be `NULL`.
    extern fn gst_structure_id_str_set(p_structure: *Structure, p_fieldname: *const gst.IdStr, ...) void;
    pub const idStrSet = gst_structure_id_str_set;

    /// va_list form of `gst.Structure.idStrSet`.
    extern fn gst_structure_id_str_set_valist(p_structure: *Structure, p_fieldname: *const gst.IdStr, p_varargs: std.builtin.VaList) void;
    pub const idStrSetValist = gst_structure_id_str_set_valist;

    /// Sets the field with the given name `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed.
    extern fn gst_structure_id_str_set_value(p_structure: *Structure, p_fieldname: *const gst.IdStr, p_value: *const gobject.Value) void;
    pub const idStrSetValue = gst_structure_id_str_set_value;

    /// Sets the field with the given GstIdStr `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed.
    extern fn gst_structure_id_str_take_value(p_structure: *Structure, p_fieldname: *const gst.IdStr, p_value: *gobject.Value) void;
    pub const idStrTakeValue = gst_structure_id_str_take_value;

    /// Sets the field with the given GQuark `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed.
    extern fn gst_structure_id_take_value(p_structure: *Structure, p_field: glib.Quark, p_value: *gobject.Value) void;
    pub const idTakeValue = gst_structure_id_take_value;

    /// Intersects `struct1` and `struct2` and returns the intersection.
    extern fn gst_structure_intersect(p_struct1: *const Structure, p_struct2: *const gst.Structure) ?*gst.Structure;
    pub const intersect = gst_structure_intersect;

    /// Tests if the two `gst.Structure` are equal.
    extern fn gst_structure_is_equal(p_structure1: *const Structure, p_structure2: *const gst.Structure) c_int;
    pub const isEqual = gst_structure_is_equal;

    /// Checks if `subset` is a subset of `superset`, i.e. has the same
    /// structure name and for all fields that are existing in `superset`,
    /// `subset` has a value that is a subset of the value in `superset`.
    extern fn gst_structure_is_subset(p_subset: *const Structure, p_superset: *const gst.Structure) c_int;
    pub const isSubset = gst_structure_is_subset;

    /// Checks if the structure is writable. `TRUE` if parent
    /// is not set or its refcount is 1, `FALSE` otherwise.
    extern fn gst_structure_is_writable(p_structure: *const Structure) c_int;
    pub const isWritable = gst_structure_is_writable;

    /// Calls the provided function once for each field in the `gst.Structure`. In
    /// contrast to `gst.Structure.foreach`, the function may modify but not delete the
    /// fields. The structure must be mutable.
    extern fn gst_structure_map_in_place(p_structure: *Structure, p_func: gst.StructureMapFunc, p_user_data: ?*anyopaque) c_int;
    pub const mapInPlace = gst_structure_map_in_place;

    /// Calls the provided function once for each field in the `gst.Structure`. In
    /// contrast to `gst.Structure.foreachIdStr`, the function may modify but not delete the
    /// fields. The structure must be mutable.
    extern fn gst_structure_map_in_place_id_str(p_structure: *Structure, p_func: gst.StructureMapIdStrFunc, p_user_data: ?*anyopaque) c_int;
    pub const mapInPlaceIdStr = gst_structure_map_in_place_id_str;

    /// Get the number of fields in the structure.
    extern fn gst_structure_n_fields(p_structure: *const Structure) c_int;
    pub const nFields = gst_structure_n_fields;

    /// Get the name of the given field number, counting from 0 onwards.
    extern fn gst_structure_nth_field_name(p_structure: *const Structure, p_index: c_uint) [*:0]const u8;
    pub const nthFieldName = gst_structure_nth_field_name;

    /// Removes all fields in a GstStructure.
    extern fn gst_structure_remove_all_fields(p_structure: *Structure) void;
    pub const removeAllFields = gst_structure_remove_all_fields;

    /// Removes the field with the given name.  If the field with the given
    /// name does not exist, the structure is unchanged.
    extern fn gst_structure_remove_field(p_structure: *Structure, p_fieldname: [*:0]const u8) void;
    pub const removeField = gst_structure_remove_field;

    /// Removes the fields with the given names. If a field does not exist, the
    /// argument is ignored.
    extern fn gst_structure_remove_fields(p_structure: *Structure, p_fieldname: [*:0]const u8, ...) void;
    pub const removeFields = gst_structure_remove_fields;

    /// va_list form of `gst.Structure.removeFields`.
    extern fn gst_structure_remove_fields_valist(p_structure: *Structure, p_fieldname: [*:0]const u8, p_varargs: std.builtin.VaList) void;
    pub const removeFieldsValist = gst_structure_remove_fields_valist;

    /// Converts `structure` to a human-readable string representation.
    ///
    /// This version of the caps serialization function introduces support for nested
    /// structures and caps but the resulting strings won't be parsable with
    /// GStreamer prior to 1.20 unless `GST_SERIALIZE_FLAG_BACKWARD_COMPAT` is passed
    /// as `flag`.
    ///
    /// `GST_SERIALIZE_FLAG_STRICT` flags is not allowed because it would make this
    /// function nullable which is an API break for bindings.
    /// Use `gst.Structure.serializeFull` instead.
    ///
    /// Free-function: g_free
    extern fn gst_structure_serialize(p_structure: *const Structure, p_flags: gst.SerializeFlags) [*:0]u8;
    pub const serialize = gst_structure_serialize;

    /// Alias for `gst.Structure.serialize` but with nullable annotation because it
    /// can return `NULL` when `GST_SERIALIZE_FLAG_STRICT` flag is set.
    extern fn gst_structure_serialize_full(p_structure: *const Structure, p_flags: gst.SerializeFlags) ?[*:0]u8;
    pub const serializeFull = gst_structure_serialize_full;

    /// Parses the variable arguments and sets fields accordingly. Fields that
    /// weren't already part of the structure are added as needed.
    /// Variable arguments should be in the form field name, field type
    /// (as a GType), value(s).  The last variable argument should be `NULL`.
    extern fn gst_structure_set(p_structure: *Structure, p_fieldname: [*:0]const u8, ...) void;
    pub const set = gst_structure_set;

    /// This is useful in language bindings where unknown GValue types are not
    /// supported. This function will convert a `array` to `GST_TYPE_ARRAY` and set
    /// the field specified by `fieldname`.  Be aware that this is slower then using
    /// `GST_TYPE_ARRAY` in a `gobject.Value` directly.
    extern fn gst_structure_set_array(p_structure: *Structure, p_fieldname: [*:0]const u8, p_array: *const gobject.ValueArray) void;
    pub const setArray = gst_structure_set_array;

    /// This is useful in language bindings where unknown GValue types are not
    /// supported. This function will convert a `array` to `GST_TYPE_LIST` and set
    /// the field specified by `fieldname`. Be aware that this is slower then using
    /// `GST_TYPE_LIST` in a `gobject.Value` directly.
    extern fn gst_structure_set_list(p_structure: *Structure, p_fieldname: [*:0]const u8, p_array: *const gobject.ValueArray) void;
    pub const setList = gst_structure_set_list;

    /// Sets the name of the structure to the given `name`.  The string
    /// provided is copied before being used. It must not be empty, start with a
    /// letter and can be followed by letters, numbers and any of "/-_.:".
    extern fn gst_structure_set_name(p_structure: *Structure, p_name: [*:0]const u8) void;
    pub const setName = gst_structure_set_name;

    /// Sets the name of the structure to the given `name`.  The string
    /// provided is copied before being used. It must not be empty, start with a
    /// letter and can be followed by letters, numbers and any of "/-_.:".
    extern fn gst_structure_set_name_id_str(p_structure: *Structure, p_name: *const gst.IdStr) void;
    pub const setNameIdStr = gst_structure_set_name_id_str;

    /// Sets the name of the structure to the given `name`.  The string
    /// provided is copied before being used. It must not be empty, start with a
    /// letter and can be followed by letters, numbers and any of "/-_.:".
    ///
    /// `name` needs to be valid for the remaining lifetime of the process, e.g. has
    /// to be a static string.
    extern fn gst_structure_set_name_static_str(p_structure: *Structure, p_name: [*:0]const u8) void;
    pub const setNameStaticStr = gst_structure_set_name_static_str;

    /// Sets the parent_refcount field of `gst.Structure`. This field is used to
    /// determine whether a structure is mutable or not. This function should only be
    /// called by code implementing parent objects of `gst.Structure`, as described in
    /// the MT Refcounting section of the design documents.
    extern fn gst_structure_set_parent_refcount(p_structure: *Structure, p_refcount: *c_int) c_int;
    pub const setParentRefcount = gst_structure_set_parent_refcount;

    /// Parses the variable arguments and sets fields accordingly. Fields that
    /// weren't already part of the structure are added as needed.
    /// Variable arguments should be in the form field name, field type
    /// (as a GType), value(s).  The last variable argument should be `NULL`.
    ///
    /// `fieldname` and all other field names needs to be valid for the remaining
    /// lifetime of the process, e.g. has to be a static string.
    extern fn gst_structure_set_static_str(p_structure: *Structure, p_fieldname: [*:0]const u8, ...) void;
    pub const setStaticStr = gst_structure_set_static_str;

    /// va_list form of `gst.Structure.setStaticStr`.
    ///
    /// `fieldname` and all other field names needs to be valid for the remaining
    /// lifetime of the process, e.g. has to be a static string.
    extern fn gst_structure_set_static_str_valist(p_structure: *Structure, p_fieldname: [*:0]const u8, p_varargs: std.builtin.VaList) void;
    pub const setStaticStrValist = gst_structure_set_static_str_valist;

    /// va_list form of `gst.Structure.set`.
    extern fn gst_structure_set_valist(p_structure: *Structure, p_fieldname: [*:0]const u8, p_varargs: std.builtin.VaList) void;
    pub const setValist = gst_structure_set_valist;

    /// Sets the field with the given name `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed.
    extern fn gst_structure_set_value(p_structure: *Structure, p_fieldname: [*:0]const u8, p_value: *const gobject.Value) void;
    pub const setValue = gst_structure_set_value;

    /// Sets the field with the given name `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed.
    ///
    /// `fieldname` needs to be valid for the remaining lifetime of the process, e.g.
    /// has to be a static string.
    extern fn gst_structure_set_value_static_str(p_structure: *Structure, p_fieldname: [*:0]const u8, p_value: *const gobject.Value) void;
    pub const setValueStaticStr = gst_structure_set_value_static_str;

    /// Sets the field with the given name `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed. The function will take ownership of `value`.
    extern fn gst_structure_take_value(p_structure: *Structure, p_fieldname: [*:0]const u8, p_value: *gobject.Value) void;
    pub const takeValue = gst_structure_take_value;

    /// Sets the field with the given name `field` to `value`.  If the field
    /// does not exist, it is created.  If the field exists, the previous
    /// value is replaced and freed. The function will take ownership of `value`.
    ///
    /// `fieldname` needs to be valid for the remaining lifetime of the process, e.g.
    /// has to be a static string.
    extern fn gst_structure_take_value_static_str(p_structure: *Structure, p_fieldname: [*:0]const u8, p_value: *gobject.Value) void;
    pub const takeValueStaticStr = gst_structure_take_value_static_str;

    /// Converts `structure` to a human-readable string representation.
    ///
    /// For debugging purposes its easier to do something like this: |[<!--
    /// language="C" --> GST_LOG ("structure is %" GST_PTR_FORMAT, structure);
    /// ```
    /// This prints the structure in human readable form.
    ///
    /// This function will lead to unexpected results when there are nested `gst.Caps`
    /// / `gst.Structure` deeper than one level, you should user
    /// `gst.Structure.serializeFull` instead for those cases.
    ///
    /// Free-function: g_free
    extern fn gst_structure_to_string(p_structure: *const Structure) [*:0]u8;
    pub const toString = gst_structure_to_string;

    extern fn gst_structure_get_type() usize;
    pub const getGObjectType = gst_structure_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SystemClockClass = extern struct {
    pub const Instance = gst.SystemClock;

    f_parent_class: gst.ClockClass,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *SystemClockClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SystemClockPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// List of tags and values used to describe media metadata.
///
/// Strings in structures must be ASCII or UTF-8 encoded. Other encodings are
/// not allowed. Strings must not be empty or `NULL`.
pub const TagList = extern struct {
    /// the parent type
    f_mini_object: gst.MiniObject,

    /// Copies the contents for the given tag into the value,
    /// merging multiple values into one if multiple values are associated
    /// with the tag.
    /// You must `gobject.Value.unset` the value after use.
    extern fn gst_tag_list_copy_value(p_dest: *gobject.Value, p_list: *const gst.TagList, p_tag: [*:0]const u8) c_int;
    pub const copyValue = gst_tag_list_copy_value;

    /// Modifies a pointer to a `gst.TagList` to point to a different `gst.TagList`. The
    /// modification is done atomically (so this is useful for ensuring thread
    /// safety in some cases), and the reference counts are updated appropriately
    /// (the old tag list is unreffed, the new is reffed).
    ///
    /// Either `new_taglist` or the `gst.TagList` pointed to by `old_taglist` may be
    /// `NULL`.
    extern fn gst_tag_list_replace(p_old_taglist: ?**gst.TagList, p_new_taglist: ?*gst.TagList) c_int;
    pub const replace = gst_tag_list_replace;

    /// Modifies a pointer to a `gst.TagList` to point to a different `gst.TagList`.
    /// This function is similar to `gst.tagListReplace` except that it takes
    /// ownership of `new_taglist`.
    extern fn gst_tag_list_take(p_old_taglist: **gst.TagList, p_new_taglist: ?*gst.TagList) c_int;
    pub const take = gst_tag_list_take;

    /// Creates a new taglist and appends the values for the given tags. It expects
    /// tag-value pairs like `gst.TagList.add`, and a `NULL` terminator after the
    /// last pair. The type of the values is implicit and is documented in the API
    /// reference, but can also be queried at runtime with `gst.tagGetType`. It
    /// is an error to pass a value of a type not matching the tag type into this
    /// function. The tag list will make copies of any arguments passed
    /// (e.g. strings, buffers).
    ///
    /// After creation you might also want to set a `gst.TagScope` on the returned
    /// taglist to signal if the contained tags are global or stream tags. By
    /// default stream scope is assumes. See `gst.TagList.setScope`.
    ///
    /// Free-function: gst_tag_list_unref
    extern fn gst_tag_list_new(p_tag: [*:0]const u8, ...) *gst.TagList;
    pub const new = gst_tag_list_new;

    /// Creates a new empty GstTagList.
    ///
    /// Free-function: gst_tag_list_unref
    extern fn gst_tag_list_new_empty() *gst.TagList;
    pub const newEmpty = gst_tag_list_new_empty;

    /// Deserializes a tag list.
    extern fn gst_tag_list_new_from_string(p_str: [*:0]const u8) ?*gst.TagList;
    pub const newFromString = gst_tag_list_new_from_string;

    /// Just like `gst.TagList.new`, only that it takes a va_list argument.
    /// Useful mostly for language bindings.
    ///
    /// Free-function: gst_tag_list_unref
    extern fn gst_tag_list_new_valist(p_var_args: std.builtin.VaList) *gst.TagList;
    pub const newValist = gst_tag_list_new_valist;

    /// Sets the values for the given tags using the specified mode.
    extern fn gst_tag_list_add(p_list: *TagList, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, ...) void;
    pub const add = gst_tag_list_add;

    /// Sets the values for the given tags using the specified mode.
    extern fn gst_tag_list_add_valist(p_list: *TagList, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, p_var_args: std.builtin.VaList) void;
    pub const addValist = gst_tag_list_add_valist;

    /// Sets the GValues for the given tags using the specified mode.
    extern fn gst_tag_list_add_valist_values(p_list: *TagList, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, p_var_args: std.builtin.VaList) void;
    pub const addValistValues = gst_tag_list_add_valist_values;

    /// Sets the GValue for a given tag using the specified mode.
    extern fn gst_tag_list_add_value(p_list: *TagList, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, p_value: *const gobject.Value) void;
    pub const addValue = gst_tag_list_add_value;

    /// Sets the GValues for the given tags using the specified mode.
    extern fn gst_tag_list_add_values(p_list: *TagList, p_mode: gst.TagMergeMode, p_tag: [*:0]const u8, ...) void;
    pub const addValues = gst_tag_list_add_values;

    /// Creates a new `gst.TagList` as a copy of the old `taglist`. The new taglist
    /// will have a refcount of 1, owned by the caller, and will be writable as
    /// a result.
    ///
    /// Note that this function is the semantic equivalent of a `gst.TagList.ref`
    /// followed by a `gst_tag_list_make_writable`. If you only want to hold on to a
    /// reference to the data, you should use `gst.TagList.ref`.
    ///
    /// When you are finished with the taglist, call `gst.TagList.unref` on it.
    extern fn gst_tag_list_copy(p_taglist: *const TagList) *gst.TagList;
    pub const copy = gst_tag_list_copy;

    /// Calls the given function for each tag inside the tag list. Note that if there
    /// is no tag, the function won't be called at all.
    extern fn gst_tag_list_foreach(p_list: *const TagList, p_func: gst.TagForeachFunc, p_user_data: ?*anyopaque) void;
    pub const foreach = gst_tag_list_foreach;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_boolean(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *c_int) c_int;
    pub const getBoolean = gst_tag_list_get_boolean;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_boolean_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *c_int) c_int;
    pub const getBooleanIndex = gst_tag_list_get_boolean_index;

    /// Copies the first date for the given tag in the taglist into the variable
    /// pointed to by `value`. Free the date with `glib.Date.free` when it is no longer
    /// needed.
    ///
    /// Free-function: g_date_free
    extern fn gst_tag_list_get_date(p_list: *const TagList, p_tag: [*:0]const u8, p_value: **glib.Date) c_int;
    pub const getDate = gst_tag_list_get_date;

    /// Gets the date that is at the given index for the given tag in the given
    /// list and copies it into the variable pointed to by `value`. Free the date
    /// with `glib.Date.free` when it is no longer needed.
    ///
    /// Free-function: g_date_free
    extern fn gst_tag_list_get_date_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: **glib.Date) c_int;
    pub const getDateIndex = gst_tag_list_get_date_index;

    /// Copies the first datetime for the given tag in the taglist into the variable
    /// pointed to by `value`. Unref the date with `gst.DateTime.unref` when
    /// it is no longer needed.
    ///
    /// Free-function: gst_date_time_unref
    extern fn gst_tag_list_get_date_time(p_list: *const TagList, p_tag: [*:0]const u8, p_value: **gst.DateTime) c_int;
    pub const getDateTime = gst_tag_list_get_date_time;

    /// Gets the datetime that is at the given index for the given tag in the given
    /// list and copies it into the variable pointed to by `value`. Unref the datetime
    /// with `gst.DateTime.unref` when it is no longer needed.
    ///
    /// Free-function: gst_date_time_unref
    extern fn gst_tag_list_get_date_time_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: **gst.DateTime) c_int;
    pub const getDateTimeIndex = gst_tag_list_get_date_time_index;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_double(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *f64) c_int;
    pub const getDouble = gst_tag_list_get_double;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_double_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *f64) c_int;
    pub const getDoubleIndex = gst_tag_list_get_double_index;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_float(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *f32) c_int;
    pub const getFloat = gst_tag_list_get_float;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_float_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *f32) c_int;
    pub const getFloatIndex = gst_tag_list_get_float_index;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_int(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *c_int) c_int;
    pub const getInt = gst_tag_list_get_int;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_int64(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *i64) c_int;
    pub const getInt64 = gst_tag_list_get_int64;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_int64_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *i64) c_int;
    pub const getInt64Index = gst_tag_list_get_int64_index;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_int_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *c_int) c_int;
    pub const getIntIndex = gst_tag_list_get_int_index;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_pointer(p_list: *const TagList, p_tag: [*:0]const u8, p_value: ?*anyopaque) c_int;
    pub const getPointer = gst_tag_list_get_pointer;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_pointer_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: ?*anyopaque) c_int;
    pub const getPointerIndex = gst_tag_list_get_pointer_index;

    /// Copies the first sample for the given tag in the taglist into the variable
    /// pointed to by `sample`. Free the sample with `gst.Sample.unref` when it is
    /// no longer needed. You can retrieve the buffer from the sample using
    /// `gst.Sample.getBuffer` and the associated caps (if any) with
    /// `gst.Sample.getCaps`.
    ///
    /// Free-function: gst_sample_unref
    extern fn gst_tag_list_get_sample(p_list: *const TagList, p_tag: [*:0]const u8, p_sample: **gst.Sample) c_int;
    pub const getSample = gst_tag_list_get_sample;

    /// Gets the sample that is at the given index for the given tag in the given
    /// list and copies it into the variable pointed to by `sample`. Free the sample
    /// with `gst.Sample.unref` when it is no longer needed. You can retrieve the
    /// buffer from the sample using `gst.Sample.getBuffer` and the associated
    /// caps (if any) with `gst.Sample.getCaps`.
    ///
    /// Free-function: gst_sample_unref
    extern fn gst_tag_list_get_sample_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_sample: **gst.Sample) c_int;
    pub const getSampleIndex = gst_tag_list_get_sample_index;

    /// Gets the scope of `list`.
    extern fn gst_tag_list_get_scope(p_list: *const TagList) gst.TagScope;
    pub const getScope = gst_tag_list_get_scope;

    /// Copies the contents for the given tag into the value, possibly merging
    /// multiple values into one if multiple values are associated with the tag.
    ///
    /// Use gst_tag_list_get_string_index (list, tag, 0, value) if you want
    /// to retrieve the first string associated with this tag unmodified.
    ///
    /// The resulting string in `value` will be in UTF-8 encoding and should be
    /// freed by the caller using g_free when no longer needed. The
    /// returned string is also guaranteed to be non-`NULL` and non-empty.
    ///
    /// Free-function: g_free
    extern fn gst_tag_list_get_string(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *[*:0]u8) c_int;
    pub const getString = gst_tag_list_get_string;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    ///
    /// The resulting string in `value` will be in UTF-8 encoding and should be
    /// freed by the caller using g_free when no longer needed. The
    /// returned string is also guaranteed to be non-`NULL` and non-empty.
    ///
    /// Free-function: g_free
    extern fn gst_tag_list_get_string_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *[*:0]u8) c_int;
    pub const getStringIndex = gst_tag_list_get_string_index;

    /// Checks how many value are stored in this tag list for the given tag.
    extern fn gst_tag_list_get_tag_size(p_list: *const TagList, p_tag: [*:0]const u8) c_uint;
    pub const getTagSize = gst_tag_list_get_tag_size;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_uint(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *c_uint) c_int;
    pub const getUint = gst_tag_list_get_uint;

    /// Copies the contents for the given tag into the value, merging multiple values
    /// into one if multiple values are associated with the tag.
    extern fn gst_tag_list_get_uint64(p_list: *const TagList, p_tag: [*:0]const u8, p_value: *u64) c_int;
    pub const getUint64 = gst_tag_list_get_uint64;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_uint64_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *u64) c_int;
    pub const getUint64Index = gst_tag_list_get_uint64_index;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_uint_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *c_uint) c_int;
    pub const getUintIndex = gst_tag_list_get_uint_index;

    /// Gets the value that is at the given index for the given tag in the given
    /// list.
    extern fn gst_tag_list_get_value_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint) ?*const gobject.Value;
    pub const getValueIndex = gst_tag_list_get_value_index;

    /// Inserts the tags of the `from` list into the first list using the given mode.
    extern fn gst_tag_list_insert(p_into: *TagList, p_from: *const gst.TagList, p_mode: gst.TagMergeMode) void;
    pub const insert = gst_tag_list_insert;

    /// Checks if the given taglist is empty.
    extern fn gst_tag_list_is_empty(p_list: *const TagList) c_int;
    pub const isEmpty = gst_tag_list_is_empty;

    /// Checks if the two given taglists are equal.
    extern fn gst_tag_list_is_equal(p_list1: *const TagList, p_list2: *const gst.TagList) c_int;
    pub const isEqual = gst_tag_list_is_equal;

    /// Merges the two given lists into a new list. If one of the lists is `NULL`, a
    /// copy of the other is returned. If both lists are `NULL`, `NULL` is returned.
    ///
    /// Free-function: gst_tag_list_unref
    extern fn gst_tag_list_merge(p_list1: ?*const TagList, p_list2: ?*const gst.TagList, p_mode: gst.TagMergeMode) ?*gst.TagList;
    pub const merge = gst_tag_list_merge;

    /// Get the number of tags in `list`.
    extern fn gst_tag_list_n_tags(p_list: *const TagList) c_int;
    pub const nTags = gst_tag_list_n_tags;

    /// Get the name of the tag in `list` at `index`.
    extern fn gst_tag_list_nth_tag_name(p_list: *const TagList, p_index: c_uint) [*:0]const u8;
    pub const nthTagName = gst_tag_list_nth_tag_name;

    /// Peeks at the value that is at the given index for the given tag in the given
    /// list.
    ///
    /// The resulting string in `value` will be in UTF-8 encoding and doesn't need
    /// to be freed by the caller. The returned string is also guaranteed to
    /// be non-`NULL` and non-empty.
    extern fn gst_tag_list_peek_string_index(p_list: *const TagList, p_tag: [*:0]const u8, p_index: c_uint, p_value: *[*:0]const u8) c_int;
    pub const peekStringIndex = gst_tag_list_peek_string_index;

    /// Add a reference to a `gst.TagList` mini object.
    ///
    /// From this point on, until the caller calls `gst.TagList.unref` or
    /// `gst_tag_list_make_writable`, it is guaranteed that the taglist object will
    /// not change. To use a `gst.TagList` object, you must always have a refcount on
    /// it -- either the one made implicitly by e.g. `gst.TagList.new`, or via
    /// taking one explicitly with this function.
    extern fn gst_tag_list_ref(p_taglist: *TagList) *gst.TagList;
    pub const ref = gst_tag_list_ref;

    /// Removes the given tag from the taglist.
    extern fn gst_tag_list_remove_tag(p_list: *TagList, p_tag: [*:0]const u8) void;
    pub const removeTag = gst_tag_list_remove_tag;

    /// Sets the scope of `list` to `scope`. By default the scope
    /// of a taglist is stream scope.
    extern fn gst_tag_list_set_scope(p_list: *TagList, p_scope: gst.TagScope) void;
    pub const setScope = gst_tag_list_set_scope;

    /// Serializes a tag list to a string.
    extern fn gst_tag_list_to_string(p_list: *const TagList) [*:0]u8;
    pub const toString = gst_tag_list_to_string;

    /// Unref a `gst.TagList`, and and free all its memory when the refcount reaches 0.
    extern fn gst_tag_list_unref(p_taglist: *TagList) void;
    pub const unref = gst_tag_list_unref;

    extern fn gst_tag_list_get_type() usize;
    pub const getGObjectType = gst_tag_list_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.TagSetterInterface` interface.
pub const TagSetterInterface = extern struct {
    pub const Instance = gst.TagSetter;

    /// parent interface type.
    f_g_iface: gobject.TypeInterface,

    pub fn as(p_instance: *TagSetterInterface, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TaskClass = extern struct {
    pub const Instance = gst.Task;

    f_parent_class: gst.ObjectClass,
    f_pool: ?*gst.TaskPool,
    f__gst_reserved: [4]*anyopaque,

    pub fn as(p_instance: *TaskClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The `gst.TaskPoolClass` object.
pub const TaskPoolClass = extern struct {
    pub const Instance = gst.TaskPool;

    /// the parent class structure
    f_parent_class: gst.ObjectClass,
    /// prepare the threadpool
    f_prepare: ?*const fn (p_pool: *gst.TaskPool, p_error: ?*?*glib.Error) callconv(.c) void,
    /// make sure all threads are stopped
    f_cleanup: ?*const fn (p_pool: *gst.TaskPool) callconv(.c) void,
    /// start a new thread
    f_push: ?*const fn (p_pool: *gst.TaskPool, p_func: gst.TaskPoolFunction, p_user_data: ?*anyopaque, p_error: ?*?*glib.Error) callconv(.c) ?*anyopaque,
    /// join a thread
    f_join: ?*const fn (p_pool: *gst.TaskPool, p_id: ?*anyopaque) callconv(.c) void,
    f_dispose_handle: ?*const fn (p_pool: *gst.TaskPool, p_id: ?*anyopaque) callconv(.c) void,
    f__gst_reserved: [3]*anyopaque,

    pub fn as(p_instance: *TaskPoolClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TaskPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Structure for storing a timestamp and a value.
pub const TimedValue = extern struct {
    /// timestamp of the value change
    f_timestamp: gst.ClockTime,
    /// the corresponding value
    f_value: f64,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.Toc` functions are used to create/free `gst.Toc` and `gst.TocEntry` structures.
/// Also they are used to convert `gst.Toc` into `gst.Structure` and vice versa.
///
/// `gst.Toc` lets you to inform other elements in pipeline or application that playing
/// source has some kind of table of contents (TOC). These may be chapters, editions,
/// angles or other types. For example: DVD chapters, Matroska chapters or cue sheet
/// TOC. Such TOC will be useful for applications to display instead of just a
/// playlist.
///
/// Using TOC is very easy. Firstly, create `gst.Toc` structure which represents root
/// contents of the source. You can also attach TOC-specific tags to it. Then fill
/// it with `gst.TocEntry` entries by appending them to the `gst.Toc` using
/// `gst.Toc.appendEntry`, and appending subentries to a `gst.TocEntry` using
/// `gst.TocEntry.appendSubEntry`.
///
/// Note that root level of the TOC can contain only either editions or chapters. You
/// should not mix them together at the same level. Otherwise you will get serialization
/// /deserialization errors. Make sure that no one of the entries has negative start and
///  stop values.
///
/// Use `gst.Event.newToc` to create a new TOC `gst.Event`, and `gst.Event.parseToc` to
/// parse received TOC event. Use `gst.Event.newTocSelect` to create a new TOC select `gst.Event`,
/// and `gst.Event.parseTocSelect` to parse received TOC select event. The same rule for
/// the `gst.Message`: `gst.Message.newToc` to create new TOC `gst.Message`, and
/// `gst.Message.parseToc` to parse received TOC message.
///
/// TOCs can have global scope or current scope. Global scope TOCs contain
/// all entries that can possibly be selected using a toc select event, and
/// are what an application is usually interested in. TOCs with current scope
/// only contain the parts of the TOC relevant to the currently selected/playing
/// stream; the current scope TOC is used by downstream elements such as muxers
/// to write correct TOC entries when transcoding files, for example. When
/// playing a DVD, the global TOC would contain a hierarchy of all titles,
/// chapters and angles, for example, while the current TOC would only contain
/// the chapters for the currently playing title if playback of a specific
/// title was requested.
///
/// Applications and plugins should not rely on TOCs having a certain kind of
/// structure, but should allow for different alternatives. For example, a
/// simple CUE sheet embedded in a file may be presented as a flat list of
/// track entries, or could have a top-level edition node (or some other
/// alternative type entry) with track entries underneath that node; or even
/// multiple top-level edition nodes (or some other alternative type entries)
/// each with track entries underneath, in case the source file has extracted
/// a track listing from different sources).
pub const Toc = opaque {
    /// Create a new `gst.Toc` structure.
    extern fn gst_toc_new(p_scope: gst.TocScope) *gst.Toc;
    pub const new = gst_toc_new;

    /// Appends the `gst.TocEntry` `entry` to `toc`.
    extern fn gst_toc_append_entry(p_toc: *Toc, p_entry: *gst.TocEntry) void;
    pub const appendEntry = gst_toc_append_entry;

    extern fn gst_toc_dump(p_toc: *Toc) void;
    pub const dump = gst_toc_dump;

    /// Find `gst.TocEntry` with given `uid` in the `toc`.
    extern fn gst_toc_find_entry(p_toc: *const Toc, p_uid: [*:0]const u8) ?*gst.TocEntry;
    pub const findEntry = gst_toc_find_entry;

    /// Gets the list of `gst.TocEntry` of `toc`.
    extern fn gst_toc_get_entries(p_toc: *const Toc) *glib.List;
    pub const getEntries = gst_toc_get_entries;

    extern fn gst_toc_get_scope(p_toc: *const Toc) gst.TocScope;
    pub const getScope = gst_toc_get_scope;

    /// Gets the tags for `toc`.
    extern fn gst_toc_get_tags(p_toc: *const Toc) ?*gst.TagList;
    pub const getTags = gst_toc_get_tags;

    /// Merge `tags` into the existing tags of `toc` using `mode`.
    extern fn gst_toc_merge_tags(p_toc: *Toc, p_tags: ?*gst.TagList, p_mode: gst.TagMergeMode) void;
    pub const mergeTags = gst_toc_merge_tags;

    /// Set a `gst.TagList` with tags for the complete `toc`.
    extern fn gst_toc_set_tags(p_toc: *Toc, p_tags: ?*gst.TagList) void;
    pub const setTags = gst_toc_set_tags;

    extern fn gst_toc_get_type() usize;
    pub const getGObjectType = gst_toc_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TocEntry = opaque {
    /// Create new `gst.TocEntry` structure.
    extern fn gst_toc_entry_new(p_type: gst.TocEntryType, p_uid: [*:0]const u8) *gst.TocEntry;
    pub const new = gst_toc_entry_new;

    /// Appends the `gst.TocEntry` `subentry` to `entry`.
    extern fn gst_toc_entry_append_sub_entry(p_entry: *TocEntry, p_subentry: *gst.TocEntry) void;
    pub const appendSubEntry = gst_toc_entry_append_sub_entry;

    extern fn gst_toc_entry_get_entry_type(p_entry: *const TocEntry) gst.TocEntryType;
    pub const getEntryType = gst_toc_entry_get_entry_type;

    /// Get `loop_type` and `repeat_count` values from the `entry` and write them into
    /// appropriate storages. Loops are e.g. used by sampled instruments. GStreamer
    /// is not automatically applying the loop. The application can process this
    /// meta data and use it e.g. to send a seek-event to loop a section.
    extern fn gst_toc_entry_get_loop(p_entry: *const TocEntry, p_loop_type: ?*gst.TocLoopType, p_repeat_count: ?*c_int) c_int;
    pub const getLoop = gst_toc_entry_get_loop;

    /// Gets the parent `gst.TocEntry` of `entry`.
    extern fn gst_toc_entry_get_parent(p_entry: *TocEntry) ?*gst.TocEntry;
    pub const getParent = gst_toc_entry_get_parent;

    /// Get `start` and `stop` values from the `entry` and write them into appropriate
    /// storages.
    extern fn gst_toc_entry_get_start_stop_times(p_entry: *const TocEntry, p_start: ?*i64, p_stop: ?*i64) c_int;
    pub const getStartStopTimes = gst_toc_entry_get_start_stop_times;

    /// Gets the sub-entries of `entry`.
    extern fn gst_toc_entry_get_sub_entries(p_entry: *const TocEntry) *glib.List;
    pub const getSubEntries = gst_toc_entry_get_sub_entries;

    /// Gets the tags for `entry`.
    extern fn gst_toc_entry_get_tags(p_entry: *const TocEntry) ?*gst.TagList;
    pub const getTags = gst_toc_entry_get_tags;

    /// Gets the parent `gst.Toc` of `entry`.
    extern fn gst_toc_entry_get_toc(p_entry: *TocEntry) ?*gst.Toc;
    pub const getToc = gst_toc_entry_get_toc;

    /// Gets the UID of `entry`.
    extern fn gst_toc_entry_get_uid(p_entry: *const TocEntry) [*:0]const u8;
    pub const getUid = gst_toc_entry_get_uid;

    extern fn gst_toc_entry_is_alternative(p_entry: *const TocEntry) c_int;
    pub const isAlternative = gst_toc_entry_is_alternative;

    extern fn gst_toc_entry_is_sequence(p_entry: *const TocEntry) c_int;
    pub const isSequence = gst_toc_entry_is_sequence;

    /// Merge `tags` into the existing tags of `entry` using `mode`.
    extern fn gst_toc_entry_merge_tags(p_entry: *TocEntry, p_tags: ?*gst.TagList, p_mode: gst.TagMergeMode) void;
    pub const mergeTags = gst_toc_entry_merge_tags;

    /// Set `loop_type` and `repeat_count` values for the `entry`.
    extern fn gst_toc_entry_set_loop(p_entry: *TocEntry, p_loop_type: gst.TocLoopType, p_repeat_count: c_int) void;
    pub const setLoop = gst_toc_entry_set_loop;

    /// Set `start` and `stop` values for the `entry`.
    extern fn gst_toc_entry_set_start_stop_times(p_entry: *TocEntry, p_start: i64, p_stop: i64) void;
    pub const setStartStopTimes = gst_toc_entry_set_start_stop_times;

    /// Set a `gst.TagList` with tags for the complete `entry`.
    extern fn gst_toc_entry_set_tags(p_entry: *TocEntry, p_tags: ?*gst.TagList) void;
    pub const setTags = gst_toc_entry_set_tags;

    extern fn gst_toc_entry_get_type() usize;
    pub const getGObjectType = gst_toc_entry_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.TocSetterInterface` interface.
pub const TocSetterInterface = extern struct {
    pub const Instance = gst.TocSetter;

    /// parent interface type.
    f_g_iface: gobject.TypeInterface,

    pub fn as(p_instance: *TocSetterInterface, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TracerClass = extern struct {
    pub const Instance = gst.Tracer;

    f_parent_class: gst.ObjectClass,
    f__gst_reserved: [4]*anyopaque,

    /// Sets whether the tracer should use structure parameters for configuration.
    /// This function configures how parameters should be passed when instantiating
    /// the tracer.
    ///
    /// This is typically called in the tracer's class initialization function to
    /// indicate its parameter handling preference.
    extern fn gst_tracer_class_set_use_structure_params(p_tracer_class: *TracerClass, p_use_structure_params: c_int) void;
    pub const setUseStructureParams = gst_tracer_class_set_use_structure_params;

    /// If set, the tracer subsystem will consider parameters passed to the
    /// `GST_TRACERS` environment variable as a `gst.Structure` and use its
    /// fields as properties to instanciate the tracer.
    extern fn gst_tracer_class_uses_structure_params(p_tracer_class: *TracerClass) c_int;
    pub const usesStructureParams = gst_tracer_class_uses_structure_params;

    pub fn as(p_instance: *TracerClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TracerFactoryClass = opaque {
    pub const Instance = gst.TracerFactory;

    pub fn as(p_instance: *TracerFactoryClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TracerPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TracerRecordClass = opaque {
    pub const Instance = gst.TracerRecord;

    pub fn as(p_instance: *TracerRecordClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The following functions allow you to detect the media type of an unknown
/// stream.
pub const TypeFind = extern struct {
    /// Method to peek data.
    f_peek: ?*const fn (p_data: *anyopaque, p_offset: i64, p_size: c_uint) callconv(.c) *const u8,
    /// Method to suggest `gst.Caps` with a given probability.
    f_suggest: ?*const fn (p_data: *anyopaque, p_probability: c_uint, p_caps: *gst.Caps) callconv(.c) void,
    /// The data used by the caller of the typefinding function.
    f_data: ?*anyopaque,
    /// Returns the length of current data.
    f_get_length: ?*const fn (p_data: *anyopaque) callconv(.c) u64,
    f__gst_reserved: [4]*anyopaque,

    /// Registers a new typefind function to be used for typefinding. After
    /// registering this function will be available for typefinding.
    /// This function is typically called during an element's plugin initialization.
    extern fn gst_type_find_register(p_plugin: ?*gst.Plugin, p_name: [*:0]const u8, p_rank: c_uint, p_func: gst.TypeFindFunction, p_extensions: ?[*:0]const u8, p_possible_caps: ?*gst.Caps, p_data: ?*anyopaque, p_data_notify: ?glib.DestroyNotify) c_int;
    pub const register = gst_type_find_register;

    /// Get the length of the data stream.
    extern fn gst_type_find_get_length(p_find: *TypeFind) u64;
    pub const getLength = gst_type_find_get_length;

    /// Returns the `size` bytes of the stream to identify beginning at offset. If
    /// offset is a positive number, the offset is relative to the beginning of the
    /// stream, if offset is a negative number the offset is relative to the end of
    /// the stream. The returned memory is valid until the typefinding function
    /// returns and must not be freed.
    extern fn gst_type_find_peek(p_find: *TypeFind, p_offset: i64, p_size: c_uint) ?*const u8;
    pub const peek = gst_type_find_peek;

    /// If a `gst.TypeFindFunction` calls this function it suggests the caps with the
    /// given probability. A `gst.TypeFindFunction` may supply different suggestions
    /// in one call.
    /// It is up to the caller of the `gst.TypeFindFunction` to interpret these values.
    extern fn gst_type_find_suggest(p_find: *TypeFind, p_probability: c_uint, p_caps: *gst.Caps) void;
    pub const suggest = gst_type_find_suggest;

    /// If a `gst.TypeFindFunction` calls this function it suggests caps of the
    /// given `media_type` with the given `probability`.
    ///
    /// This function is similar to `gst.TypeFind.suggestSimple`, but uses
    /// a `gst.Caps` with no fields.
    extern fn gst_type_find_suggest_empty_simple(p_find: *TypeFind, p_probability: c_uint, p_media_type: [*:0]const u8) void;
    pub const suggestEmptySimple = gst_type_find_suggest_empty_simple;

    /// If a `gst.TypeFindFunction` calls this function it suggests the caps with the
    /// given probability. A `gst.TypeFindFunction` may supply different suggestions
    /// in one call. It is up to the caller of the `gst.TypeFindFunction` to interpret
    /// these values.
    ///
    /// This function is similar to `gst.TypeFind.suggest`, only that instead of
    /// passing a `gst.Caps` argument you can create the caps on the fly in the same
    /// way as you can with `gst.Caps.newSimple`.
    ///
    /// Make sure you terminate the list of arguments with a `NULL` argument and that
    /// the values passed have the correct type (in terms of width in bytes when
    /// passed to the vararg function - this applies particularly to gdouble and
    /// guint64 arguments).
    extern fn gst_type_find_suggest_simple(p_find: *TypeFind, p_probability: c_uint, p_media_type: [*:0]const u8, p_fieldname: ?[*:0]const u8, ...) void;
    pub const suggestSimple = gst_type_find_suggest_simple;

    extern fn gst_type_find_get_type() usize;
    pub const getGObjectType = gst_type_find_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const TypeFindFactoryClass = opaque {
    pub const Instance = gst.TypeFindFactory;

    pub fn as(p_instance: *TypeFindFactoryClass, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Any `gst.Element` using this interface should implement these methods.
pub const URIHandlerInterface = extern struct {
    pub const Instance = gst.URIHandler;

    /// The parent interface type
    f_parent: gobject.TypeInterface,
    /// Method to tell whether the element handles source or sink URI.
    f_get_type: ?*const fn (p_type: usize) callconv(.c) gst.URIType,
    /// Method to return the list of protocols handled by the element.
    f_get_protocols: ?*const fn (p_type: usize) callconv(.c) [*]const [*:0]const u8,
    /// Method to return the URI currently handled by the element.
    f_get_uri: ?*const fn (p_handler: *gst.URIHandler) callconv(.c) ?[*:0]u8,
    /// Method to set a new URI.
    f_set_uri: ?*const fn (p_handler: *gst.URIHandler, p_uri: [*:0]const u8, p_error: ?*?*glib.Error) callconv(.c) c_int,

    pub fn as(p_instance: *URIHandlerInterface, comptime P_T: type) *P_T {
        return gobject.ext.as(P_T, p_instance);
    }

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A `gst.Uri` object can be used to parse and split a URI string into its
/// constituent parts. Two `gst.Uri` objects can be joined to make a new `gst.Uri`
/// using the algorithm described in RFC3986.
pub const Uri = opaque {
    /// Constructs a URI for a given valid protocol and location.
    ///
    /// Free-function: g_free
    extern fn gst_uri_construct(p_protocol: [*:0]const u8, p_location: [*:0]const u8) [*:0]u8;
    pub const construct = gst_uri_construct;

    /// Parses a URI string into a new `gst.Uri` object. Will return NULL if the URI
    /// cannot be parsed.
    extern fn gst_uri_from_string(p_uri: [*:0]const u8) ?*gst.Uri;
    pub const fromString = gst_uri_from_string;

    /// Parses a URI string into a new `gst.Uri` object. Will return NULL if the URI
    /// cannot be parsed. This is identical to `gst.uriFromString` except that
    /// the userinfo and fragment components of the URI will not be unescaped while
    /// parsing.
    ///
    /// Use this when you need to extract a username and password from the userinfo
    /// such as https://user:password`example`.com since either may contain
    /// a URI-escaped ':' character. `gst.uriFromString` will unescape the entire
    /// userinfo component, which will make it impossible to know which ':'
    /// delineates the username and password.
    ///
    /// The same applies to the fragment component of the URI, such as
    /// https://example.com/path`fragment` which may contain a URI-escaped '#'.
    extern fn gst_uri_from_string_escaped(p_uri: [*:0]const u8) ?*gst.Uri;
    pub const fromStringEscaped = gst_uri_from_string_escaped;

    /// Extracts the location out of a given valid URI, ie. the protocol and "://"
    /// are stripped from the URI, which means that the location returned includes
    /// the hostname if one is specified. The returned string must be freed using
    /// `glib.free`.
    ///
    /// Free-function: g_free
    extern fn gst_uri_get_location(p_uri: [*:0]const u8) ?[*:0]u8;
    pub const getLocation = gst_uri_get_location;

    /// Extracts the protocol out of a given valid URI. The returned string must be
    /// freed using `glib.free`.
    extern fn gst_uri_get_protocol(p_uri: [*:0]const u8) ?[*:0]u8;
    pub const getProtocol = gst_uri_get_protocol;

    /// Checks if the protocol of a given valid URI matches `protocol`.
    extern fn gst_uri_has_protocol(p_uri: [*:0]const u8, p_protocol: [*:0]const u8) c_int;
    pub const hasProtocol = gst_uri_has_protocol;

    /// Tests if the given string is a valid URI identifier. URIs start with a valid
    /// scheme followed by ":" and maybe a string identifying the location.
    extern fn gst_uri_is_valid(p_uri: [*:0]const u8) c_int;
    pub const isValid = gst_uri_is_valid;

    /// This is a convenience function to join two URI strings and return the result.
    /// The returned string should be `glib.free`'d after use.
    extern fn gst_uri_join_strings(p_base_uri: [*:0]const u8, p_ref_uri: [*:0]const u8) ?[*:0]u8;
    pub const joinStrings = gst_uri_join_strings;

    /// Checks if an element exists that supports the given URI protocol. Note
    /// that a positive return value does not imply that a subsequent call to
    /// `gst.Element.makeFromUri` is guaranteed to work.
    extern fn gst_uri_protocol_is_supported(p_type: gst.URIType, p_protocol: [*:0]const u8) c_int;
    pub const protocolIsSupported = gst_uri_protocol_is_supported;

    /// Tests if the given string is a valid protocol identifier. Protocols
    /// must consist of alphanumeric characters, '+', '-' and '.' and must
    /// start with a alphabetic character. See RFC 3986 Section 3.1.
    extern fn gst_uri_protocol_is_valid(p_protocol: [*:0]const u8) c_int;
    pub const protocolIsValid = gst_uri_protocol_is_valid;

    /// Creates a new `gst.Uri` object with the given URI parts. The path and query
    /// strings will be broken down into their elements. All strings should not be
    /// escaped except where indicated.
    extern fn gst_uri_new(p_scheme: ?[*:0]const u8, p_userinfo: ?[*:0]const u8, p_host: ?[*:0]const u8, p_port: c_uint, p_path: ?[*:0]const u8, p_query: ?[*:0]const u8, p_fragment: ?[*:0]const u8) *gst.Uri;
    pub const new = gst_uri_new;

    /// Append a path onto the end of the path in the URI. The path is not
    /// normalized, call `gst.Uri.normalize``gst.Uri.normalize` to normalize the path.
    extern fn gst_uri_append_path(p_uri: ?*Uri, p_relative_path: ?[*:0]const u8) c_int;
    pub const appendPath = gst_uri_append_path;

    /// Append a single path segment onto the end of the URI path.
    extern fn gst_uri_append_path_segment(p_uri: ?*Uri, p_path_segment: ?[*:0]const u8) c_int;
    pub const appendPathSegment = gst_uri_append_path_segment;

    /// Create a new `gst.Uri` object with the same data as this `gst.Uri` object.
    /// If `uri` is `NULL` then returns `NULL`.
    extern fn gst_uri_copy(p_uri: *const Uri) *gst.Uri;
    pub const copy = gst_uri_copy;

    /// Compares two `gst.Uri` objects to see if they represent the same normalized
    /// URI.
    extern fn gst_uri_equal(p_first: *const Uri, p_second: *const gst.Uri) c_int;
    pub const equal = gst_uri_equal;

    /// Like `gst.uriFromString` but also joins with a base URI.
    extern fn gst_uri_from_string_with_base(p_base: ?*Uri, p_uri: [*:0]const u8) ?*gst.Uri;
    pub const fromStringWithBase = gst_uri_from_string_with_base;

    /// Get the fragment name from the URI or `NULL` if it doesn't exist.
    /// If `uri` is `NULL` then returns `NULL`.
    extern fn gst_uri_get_fragment(p_uri: ?*const Uri) ?[*:0]const u8;
    pub const getFragment = gst_uri_get_fragment;

    /// Get the host name from the URI or `NULL` if it doesn't exist.
    /// If `uri` is `NULL` then returns `NULL`.
    extern fn gst_uri_get_host(p_uri: ?*const Uri) ?[*:0]const u8;
    pub const getHost = gst_uri_get_host;

    /// Get the media fragment table from the URI, as defined by "Media Fragments URI 1.0".
    /// Hash table returned by this API is a list of "key-value" pairs, and the each
    /// pair is generated by splitting "URI fragment" per "&" sub-delims, then "key"
    /// and "value" are split by "=" sub-delims. The "key" returned by this API may
    /// be undefined keyword by standard.
    /// A value may be `NULL` to indicate that the key should appear in the fragment
    /// string in the URI, but does not have a value. Free the returned `glib.HashTable`
    /// with `glib.hashTableUnref``glib.hashTableUnref` when it is no longer required.
    /// Modifying this hash table does not affect the fragment in the URI.
    ///
    /// See more about Media Fragments URI 1.0 (W3C) at https://www.w3.org/TR/media-frags/
    extern fn gst_uri_get_media_fragment_table(p_uri: ?*const Uri) ?*glib.HashTable;
    pub const getMediaFragmentTable = gst_uri_get_media_fragment_table;

    /// Extract the path string from the URI object.
    extern fn gst_uri_get_path(p_uri: ?*const Uri) ?[*:0]u8;
    pub const getPath = gst_uri_get_path;

    /// Get a list of path segments from the URI.
    extern fn gst_uri_get_path_segments(p_uri: ?*const Uri) *glib.List;
    pub const getPathSegments = gst_uri_get_path_segments;

    /// Extract the path string from the URI object as a percent encoded URI path.
    extern fn gst_uri_get_path_string(p_uri: ?*const Uri) ?[*:0]u8;
    pub const getPathString = gst_uri_get_path_string;

    /// Get the port number from the URI or `GST_URI_NO_PORT` if it doesn't exist.
    /// If `uri` is `NULL` then returns `GST_URI_NO_PORT`.
    extern fn gst_uri_get_port(p_uri: ?*const Uri) c_uint;
    pub const getPort = gst_uri_get_port;

    /// Get a list of the query keys from the URI.
    extern fn gst_uri_get_query_keys(p_uri: ?*const Uri) *glib.List;
    pub const getQueryKeys = gst_uri_get_query_keys;

    /// Get a percent encoded URI query string from the `uri`.
    extern fn gst_uri_get_query_string(p_uri: ?*const Uri) ?[*:0]u8;
    pub const getQueryString = gst_uri_get_query_string;

    /// Get a percent encoded URI query string from the `uri`, with query parameters
    /// in the order provided by the `keys` list. Only parameter keys in the list will
    /// be added to the resulting URI string. This method can be used by retrieving
    /// the keys with `gst.Uri.getQueryKeys` and then sorting the list, for
    /// example.
    extern fn gst_uri_get_query_string_ordered(p_uri: ?*const Uri, p_keys: ?*const glib.List) ?[*:0]u8;
    pub const getQueryStringOrdered = gst_uri_get_query_string_ordered;

    /// Get the query table from the URI. Keys and values in the table are freed
    /// with g_free when they are deleted. A value may be `NULL` to indicate that
    /// the key should appear in the query string in the URI, but does not have a
    /// value. Free the returned `glib.HashTable` with `glib.hashTableUnref``glib.hashTableUnref` when it is
    /// no longer required. Modifying this hash table will modify the query in the
    /// URI.
    extern fn gst_uri_get_query_table(p_uri: ?*const Uri) ?*glib.HashTable;
    pub const getQueryTable = gst_uri_get_query_table;

    /// Get the value associated with the `query_key` key. Will return `NULL` if the
    /// key has no value or if the key does not exist in the URI query table. Because
    /// `NULL` is returned for both missing keys and keys with no value, you should
    /// use `gst.Uri.queryHasKey` to determine if a key is present in the URI
    /// query.
    extern fn gst_uri_get_query_value(p_uri: ?*const Uri, p_query_key: [*:0]const u8) ?[*:0]const u8;
    pub const getQueryValue = gst_uri_get_query_value;

    /// Get the scheme name from the URI or `NULL` if it doesn't exist.
    /// If `uri` is `NULL` then returns `NULL`.
    extern fn gst_uri_get_scheme(p_uri: ?*const Uri) ?[*:0]const u8;
    pub const getScheme = gst_uri_get_scheme;

    /// Get the userinfo (usually in the form "username:password") from the URI
    /// or `NULL` if it doesn't exist. If `uri` is `NULL` then returns `NULL`.
    extern fn gst_uri_get_userinfo(p_uri: ?*const Uri) ?[*:0]const u8;
    pub const getUserinfo = gst_uri_get_userinfo;

    /// Tests the `uri` to see if it is normalized. A `NULL` `uri` is considered to be
    /// normalized.
    extern fn gst_uri_is_normalized(p_uri: ?*const Uri) c_int;
    pub const isNormalized = gst_uri_is_normalized;

    /// Check if it is safe to write to this `gst.Uri`.
    ///
    /// Check if the refcount of `uri` is exactly 1, meaning that no other
    /// reference exists to the `gst.Uri` and that the `gst.Uri` is therefore writable.
    ///
    /// Modification of a `gst.Uri` should only be done after verifying that it is
    /// writable.
    extern fn gst_uri_is_writable(p_uri: *const Uri) c_int;
    pub const isWritable = gst_uri_is_writable;

    /// Join a reference URI onto a base URI using the method from RFC 3986.
    /// If either URI is `NULL` then the other URI will be returned with the ref count
    /// increased.
    extern fn gst_uri_join(p_base_uri: ?*Uri, p_ref_uri: ?*gst.Uri) ?*gst.Uri;
    pub const join = gst_uri_join;

    /// Make the `gst.Uri` writable.
    ///
    /// Checks if `uri` is writable, and if so the original object is returned. If
    /// not, then a writable copy is made and returned. This gives away the
    /// reference to `uri` and returns a reference to the new `gst.Uri`.
    /// If `uri` is `NULL` then `NULL` is returned.
    extern fn gst_uri_make_writable(p_uri: *Uri) *gst.Uri;
    pub const makeWritable = gst_uri_make_writable;

    /// Like `gst.Uri.new`, but joins the new URI onto a base URI.
    extern fn gst_uri_new_with_base(p_base: ?*Uri, p_scheme: ?[*:0]const u8, p_userinfo: ?[*:0]const u8, p_host: ?[*:0]const u8, p_port: c_uint, p_path: ?[*:0]const u8, p_query: ?[*:0]const u8, p_fragment: ?[*:0]const u8) *gst.Uri;
    pub const newWithBase = gst_uri_new_with_base;

    /// Normalization will remove extra path segments ("." and "..") from the URI. It
    /// will also convert the scheme and host name to lower case and any
    /// percent-encoded values to uppercase.
    ///
    /// The `gst.Uri` object must be writable. Check with `gst.Uri.isWritable` or use
    /// `gst.Uri.makeWritable` first.
    extern fn gst_uri_normalize(p_uri: *Uri) c_int;
    pub const normalize = gst_uri_normalize;

    /// Check if there is a query table entry for the `query_key` key.
    extern fn gst_uri_query_has_key(p_uri: ?*const Uri, p_query_key: [*:0]const u8) c_int;
    pub const queryHasKey = gst_uri_query_has_key;

    /// Add a reference to this `gst.Uri` object. See `gst.MiniObject.ref` for further
    /// info.
    extern fn gst_uri_ref(p_uri: *Uri) *gst.Uri;
    pub const ref = gst_uri_ref;

    /// Remove an entry from the query table by key.
    extern fn gst_uri_remove_query_key(p_uri: ?*Uri, p_query_key: [*:0]const u8) c_int;
    pub const removeQueryKey = gst_uri_remove_query_key;

    /// Sets the fragment string in the URI. Use a value of `NULL` in `fragment` to
    /// unset the fragment string.
    extern fn gst_uri_set_fragment(p_uri: ?*Uri, p_fragment: ?[*:0]const u8) c_int;
    pub const setFragment = gst_uri_set_fragment;

    /// Set or unset the host for the URI.
    extern fn gst_uri_set_host(p_uri: ?*Uri, p_host: [*:0]const u8) c_int;
    pub const setHost = gst_uri_set_host;

    /// Sets or unsets the path in the URI.
    extern fn gst_uri_set_path(p_uri: ?*Uri, p_path: ?[*:0]const u8) c_int;
    pub const setPath = gst_uri_set_path;

    /// Replace the path segments list in the URI.
    extern fn gst_uri_set_path_segments(p_uri: ?*Uri, p_path_segments: ?*glib.List) c_int;
    pub const setPathSegments = gst_uri_set_path_segments;

    /// Sets or unsets the path in the URI.
    extern fn gst_uri_set_path_string(p_uri: ?*Uri, p_path: [*:0]const u8) c_int;
    pub const setPathString = gst_uri_set_path_string;

    /// Set or unset the port number for the URI.
    extern fn gst_uri_set_port(p_uri: ?*Uri, p_port: c_uint) c_int;
    pub const setPort = gst_uri_set_port;

    /// Sets or unsets the query table in the URI.
    extern fn gst_uri_set_query_string(p_uri: ?*Uri, p_query: ?[*:0]const u8) c_int;
    pub const setQueryString = gst_uri_set_query_string;

    /// Set the query table to use in the URI. The old table is unreferenced and a
    /// reference to the new one is used instead. A value if `NULL` for `query_table`
    /// will remove the query string from the URI.
    extern fn gst_uri_set_query_table(p_uri: ?*Uri, p_query_table: ?*glib.HashTable) c_int;
    pub const setQueryTable = gst_uri_set_query_table;

    /// This inserts or replaces a key in the query table. A `query_value` of `NULL`
    /// indicates that the key has no associated value, but will still be present in
    /// the query string.
    extern fn gst_uri_set_query_value(p_uri: ?*Uri, p_query_key: [*:0]const u8, p_query_value: ?[*:0]const u8) c_int;
    pub const setQueryValue = gst_uri_set_query_value;

    /// Set or unset the scheme for the URI.
    extern fn gst_uri_set_scheme(p_uri: ?*Uri, p_scheme: [*:0]const u8) c_int;
    pub const setScheme = gst_uri_set_scheme;

    /// Set or unset the user information for the URI.
    extern fn gst_uri_set_userinfo(p_uri: ?*Uri, p_userinfo: [*:0]const u8) c_int;
    pub const setUserinfo = gst_uri_set_userinfo;

    /// Convert the URI to a string.
    ///
    /// Returns the URI as held in this object as a `gchar`* nul-terminated string.
    /// The caller should `glib.free` the string once they are finished with it.
    /// The string is put together as described in RFC 3986.
    extern fn gst_uri_to_string(p_uri: *const Uri) [*:0]u8;
    pub const toString = gst_uri_to_string;

    /// Convert the URI to a string, with the query arguments in a specific order.
    /// Only the keys in the `keys` list will be added to the resulting string.
    ///
    /// Returns the URI as held in this object as a `gchar`* nul-terminated string.
    /// The caller should `glib.free` the string once they are finished with it.
    /// The string is put together as described in RFC 3986.
    extern fn gst_uri_to_string_with_keys(p_uri: ?*const Uri, p_keys: ?*const glib.List) [*:0]u8;
    pub const toStringWithKeys = gst_uri_to_string_with_keys;

    /// Decrement the reference count to this `gst.Uri` object.
    ///
    /// If the reference count drops to 0 then finalize this object.
    ///
    /// See `gst.MiniObject.unref` for further info.
    extern fn gst_uri_unref(p_uri: *Uri) void;
    pub const unref = gst_uri_unref;

    extern fn gst_uri_get_type() usize;
    pub const getGObjectType = gst_uri_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// VTable for the `gobject.Value` `type`.
pub const ValueTable = extern struct {
    /// a `gobject.Type`
    f_type: usize,
    /// a `gst.ValueCompareFunc`
    f_compare: ?gst.ValueCompareFunc,
    /// a `gst.ValueSerializeFunc`
    f_serialize: ?gst.ValueSerializeFunc,
    /// a `gst.ValueDeserializeFunc`
    f_deserialize: ?gst.ValueDeserializeFunc,
    /// a `gst.ValueDeserializeWithPSpecFunc`
    f_deserialize_with_pspec: ?gst.ValueDeserializeWithPSpecFunc,
    f__gst_reserved: [3]*anyopaque,

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.VecDeque` is an object that provides standard double-ended queue (deque)
/// functionality based on an array instead of linked lists. This reduces the
/// overhead caused by memory management by a large factor.
pub const VecDeque = opaque {
    /// Allocates a new `gst.VecDeque` object with an initial
    /// queue size of `initial_size`.
    extern fn gst_vec_deque_new(p_initial_size: usize) *gst.VecDeque;
    pub const new = gst_vec_deque_new;

    /// Allocates a new `gst.VecDeque` object for elements (e.g. structures)
    /// of size `struct_size`, with an initial queue size of `initial_size`.
    extern fn gst_vec_deque_new_for_struct(p_struct_size: usize, p_initial_size: usize) *gst.VecDeque;
    pub const newForStruct = gst_vec_deque_new_for_struct;

    /// Clears queue `array` and frees all memory associated to it.
    extern fn gst_vec_deque_clear(p_array: *VecDeque) void;
    pub const clear = gst_vec_deque_clear;

    /// Drops the queue element at position `idx` from queue `array`.
    extern fn gst_vec_deque_drop_element(p_array: *VecDeque, p_idx: usize) ?*anyopaque;
    pub const dropElement = gst_vec_deque_drop_element;

    /// Drops the queue element at position `idx` from queue `array` and copies the
    /// data of the element or structure that was removed into `p_struct` if
    /// `p_struct` is set (not NULL).
    extern fn gst_vec_deque_drop_struct(p_array: *VecDeque, p_idx: usize, p_p_struct: ?*anyopaque) c_int;
    pub const dropStruct = gst_vec_deque_drop_struct;

    /// Finds an element in the queue `array`, either by comparing every element
    /// with `func` or by looking up `data` if no compare function `func` is provided,
    /// and returning the index of the found element.
    extern fn gst_vec_deque_find(p_array: *VecDeque, p_func: ?glib.CompareFunc, p_data: ?*anyopaque) usize;
    pub const find = gst_vec_deque_find;

    /// Frees queue `array` and all memory associated to it.
    extern fn gst_vec_deque_free(p_array: *VecDeque) void;
    pub const free = gst_vec_deque_free;

    /// Returns the length of the queue `array`
    extern fn gst_vec_deque_get_length(p_array: *VecDeque) usize;
    pub const getLength = gst_vec_deque_get_length;

    /// Checks if the queue `array` is empty.
    extern fn gst_vec_deque_is_empty(p_array: *VecDeque) c_int;
    pub const isEmpty = gst_vec_deque_is_empty;

    /// Returns the head of the queue `array` and does not
    /// remove it from the queue.
    extern fn gst_vec_deque_peek_head(p_array: *VecDeque) ?*anyopaque;
    pub const peekHead = gst_vec_deque_peek_head;

    /// Returns the head of the queue `array` without removing it from the queue.
    extern fn gst_vec_deque_peek_head_struct(p_array: *VecDeque) ?*anyopaque;
    pub const peekHeadStruct = gst_vec_deque_peek_head_struct;

    /// Returns the item at `idx` in `array`, but does not remove it from the queue.
    extern fn gst_vec_deque_peek_nth(p_array: *VecDeque, p_idx: usize) ?*anyopaque;
    pub const peekNth = gst_vec_deque_peek_nth;

    /// Returns the item at `idx` in `array`, but does not remove it from the queue.
    extern fn gst_vec_deque_peek_nth_struct(p_array: *VecDeque, p_idx: usize) ?*anyopaque;
    pub const peekNthStruct = gst_vec_deque_peek_nth_struct;

    /// Returns the tail of the queue `array`, but does not remove it from the queue.
    extern fn gst_vec_deque_peek_tail(p_array: *VecDeque) ?*anyopaque;
    pub const peekTail = gst_vec_deque_peek_tail;

    /// Returns the tail of the queue `array`, but does not remove it from the queue.
    extern fn gst_vec_deque_peek_tail_struct(p_array: *VecDeque) ?*anyopaque;
    pub const peekTailStruct = gst_vec_deque_peek_tail_struct;

    /// Returns and head of the queue `array` and removes
    /// it from the queue.
    extern fn gst_vec_deque_pop_head(p_array: *VecDeque) ?*anyopaque;
    pub const popHead = gst_vec_deque_pop_head;

    /// Returns the head of the queue `array` and removes it from the queue.
    extern fn gst_vec_deque_pop_head_struct(p_array: *VecDeque) ?*anyopaque;
    pub const popHeadStruct = gst_vec_deque_pop_head_struct;

    /// Returns the tail of the queue `array` and removes
    /// it from the queue.
    extern fn gst_vec_deque_pop_tail(p_array: *VecDeque) ?*anyopaque;
    pub const popTail = gst_vec_deque_pop_tail;

    /// Returns the tail of the queue `array` and removes
    /// it from the queue.
    extern fn gst_vec_deque_pop_tail_struct(p_array: *VecDeque) ?*anyopaque;
    pub const popTailStruct = gst_vec_deque_pop_tail_struct;

    /// Pushes `data` to the queue `array`, finding the correct position
    /// by comparing `data` with each array element using `func`.
    ///
    /// This has a time complexity of O(n), so depending on the size of the queue
    /// and expected access patterns, a different data structure might be better.
    ///
    /// Assumes that the array is already sorted. If it is not, make sure
    /// to call `gst.VecDeque.sort` first.
    extern fn gst_vec_deque_push_sorted(p_array: *VecDeque, p_data: ?*anyopaque, p_func: glib.CompareDataFunc, p_user_data: ?*anyopaque) void;
    pub const pushSorted = gst_vec_deque_push_sorted;

    /// Pushes the element at address `p_struct` into the queue `array`
    /// (copying the contents of a structure of the struct_size specified
    /// when creating the queue into the array), finding the correct position
    /// by comparing the element at `p_struct` with each element in the array using `func`.
    ///
    /// This has a time complexity of O(n), so depending on the size of the queue
    /// and expected access patterns, a different data structure might be better.
    ///
    /// Assumes that the array is already sorted. If it is not, make sure
    /// to call `gst.VecDeque.sort` first.
    extern fn gst_vec_deque_push_sorted_struct(p_array: *VecDeque, p_p_struct: ?*anyopaque, p_func: glib.CompareDataFunc, p_user_data: ?*anyopaque) void;
    pub const pushSortedStruct = gst_vec_deque_push_sorted_struct;

    /// Pushes `data` to the tail of the queue `array`.
    extern fn gst_vec_deque_push_tail(p_array: *VecDeque, p_data: ?*anyopaque) void;
    pub const pushTail = gst_vec_deque_push_tail;

    /// Pushes the element at address `p_struct` to the tail of the queue `array`
    /// (Copies the contents of a structure of the struct_size specified when
    /// creating the queue into the array).
    extern fn gst_vec_deque_push_tail_struct(p_array: *VecDeque, p_p_struct: ?*anyopaque) void;
    pub const pushTailStruct = gst_vec_deque_push_tail_struct;

    /// Sets a function to clear an element of `array`.
    ///
    /// The `clear_func` will be called when an element in the array
    /// data segment is removed and when the array is freed and data
    /// segment is deallocated as well. `clear_func` will be passed a
    /// pointer to the element to clear, rather than the element itself.
    ///
    /// Note that in contrast with other uses of `glib.DestroyNotify`
    /// functions, `clear_func` is expected to clear the contents of
    /// the array element it is given, but not free the element itself.
    extern fn gst_vec_deque_set_clear_func(p_array: *VecDeque, p_clear_func: glib.DestroyNotify) void;
    pub const setClearFunc = gst_vec_deque_set_clear_func;

    /// Sorts the queue `array` by comparing elements against each other using
    /// the provided `compare_func`.
    extern fn gst_vec_deque_sort(p_array: *VecDeque, p_compare_func: glib.CompareDataFunc, p_user_data: ?*anyopaque) void;
    pub const sort = gst_vec_deque_sort;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different types of buffering methods.
pub const BufferingMode = enum(c_int) {
    stream = 0,
    download = 1,
    timeshift = 2,
    live = 3,
    _,

    extern fn gst_buffering_mode_get_type() usize;
    pub const getGObjectType = gst_buffering_mode_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The result values for a GstBusSyncHandler.
pub const BusSyncReply = enum(c_int) {
    drop = 0,
    pass = 1,
    async = 2,
    _,

    extern fn gst_bus_sync_reply_get_type() usize;
    pub const getGObjectType = gst_bus_sync_reply_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Modes of caps intersection
///
/// `GST_CAPS_INTERSECT_ZIG_ZAG` tries to preserve overall order of both caps
/// by iterating on the caps' structures as the following matrix shows:
///
/// ```
///          caps1
///       +-------------
///       | 1  2  4  7
/// caps2 | 3  5  8 10
///       | 6  9 11 12
/// ```
///
/// Used when there is no explicit precedence of one caps over the other. e.g.
/// tee's sink pad getcaps function, it will probe its src pad peers' for their
/// caps and intersect them with this mode.
///
/// `GST_CAPS_INTERSECT_FIRST` is useful when an element wants to preserve
/// another element's caps priority order when intersecting with its own caps.
/// Example: If caps1 is `[A, B, C]` and caps2 is `[E, B, D, A]`, the result
/// would be `[A, B]`, maintaining the first caps priority on the intersection.
pub const CapsIntersectMode = enum(c_int) {
    zig_zag = 0,
    first = 1,
    _,

    extern fn gst_caps_intersect_mode_get_type() usize;
    pub const getGObjectType = gst_caps_intersect_mode_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The type of the clock entry
pub const ClockEntryType = enum(c_int) {
    single = 0,
    periodic = 1,
    _,

    extern fn gst_clock_entry_type_get_type() usize;
    pub const getGObjectType = gst_clock_entry_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The return value of a clock operation.
pub const ClockReturn = enum(c_int) {
    ok = 0,
    early = 1,
    unscheduled = 2,
    busy = 3,
    badtime = 4,
    @"error" = 5,
    unsupported = 6,
    done = 7,
    _,

    extern fn gst_clock_return_get_type() usize;
    pub const getGObjectType = gst_clock_return_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different kind of clocks.
pub const ClockType = enum(c_int) {
    realtime = 0,
    monotonic = 1,
    other = 2,
    tai = 3,
    _,

    extern fn gst_clock_type_get_type() usize;
    pub const getGObjectType = gst_clock_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Core errors are errors inside the core GStreamer library.
pub const CoreError = enum(c_int) {
    failed = 1,
    too_lazy = 2,
    not_implemented = 3,
    state_change = 4,
    pad = 5,
    thread = 6,
    negotiation = 7,
    event = 8,
    seek = 9,
    caps = 10,
    tag = 11,
    missing_plugin = 12,
    clock = 13,
    disabled = 14,
    num_errors = 15,
    _,

    extern fn gst_core_error_quark() glib.Quark;
    pub const quark = gst_core_error_quark;

    extern fn gst_core_error_get_type() usize;
    pub const getGObjectType = gst_core_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const DebugColorMode = enum(c_int) {
    off = 0,
    on = 1,
    unix = 2,
    _,

    extern fn gst_debug_color_mode_get_type() usize;
    pub const getGObjectType = gst_debug_color_mode_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The level defines the importance of a debugging message. The more important a
/// message is, the greater the probability that the debugging system outputs it.
pub const DebugLevel = enum(c_int) {
    none = 0,
    @"error" = 1,
    warning = 2,
    fixme = 3,
    info = 4,
    debug = 5,
    log = 6,
    trace = 7,
    memdump = 9,
    count = 10,
    _,

    /// Get the string representation of a debugging level
    extern fn gst_debug_level_get_name(p_level: gst.DebugLevel) [*:0]const u8;
    pub const getName = gst_debug_level_get_name;

    extern fn gst_debug_level_get_type() usize;
    pub const getGObjectType = gst_debug_level_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.EventType` lists the standard event types that can be sent in a pipeline.
///
/// The custom event types can be used for private messages between elements
/// that can't be expressed using normal
/// GStreamer buffer passing semantics. Custom events carry an arbitrary
/// `gst.Structure`.
/// Specific custom events are distinguished by the name of the structure.
pub const EventType = enum(c_int) {
    unknown = 0,
    flush_start = 2563,
    flush_stop = 5127,
    stream_start = 10254,
    caps = 12814,
    segment = 17934,
    stream_collection = 19230,
    tag = 20510,
    buffersize = 23054,
    sink_message = 25630,
    stream_group_done = 26894,
    eos = 28174,
    toc = 30750,
    protection = 33310,
    segment_done = 38406,
    gap = 40966,
    instant_rate_change = 46090,
    qos = 48641,
    seek = 51201,
    navigation = 53761,
    latency = 56321,
    step = 58881,
    reconfigure = 61441,
    toc_select = 64001,
    select_streams = 66561,
    instant_rate_sync_time = 66817,
    custom_upstream = 69121,
    custom_downstream = 71686,
    custom_downstream_oob = 74242,
    custom_downstream_sticky = 76830,
    custom_both = 79367,
    custom_both_oob = 81923,
    _,

    /// Gets the `gst.EventTypeFlags` associated with `type`.
    extern fn gst_event_type_get_flags(p_type: gst.EventType) gst.EventTypeFlags;
    pub const getFlags = gst_event_type_get_flags;

    /// Get a printable name for the given event type. Do not modify or free.
    extern fn gst_event_type_get_name(p_type: gst.EventType) [*:0]const u8;
    pub const getName = gst_event_type_get_name;

    /// Get the unique quark for the given event type.
    extern fn gst_event_type_to_quark(p_type: gst.EventType) glib.Quark;
    pub const toQuark = gst_event_type_to_quark;

    /// Converts the `gst.EventType` to an unsigned integer that
    /// represents the ordering of sticky events when re-sending them.
    /// A lower value represents a higher-priority event.
    extern fn gst_event_type_to_sticky_ordering(p_type: gst.EventType) c_uint;
    pub const toStickyOrdering = gst_event_type_to_sticky_ordering;

    extern fn gst_event_type_get_type() usize;
    pub const getGObjectType = gst_event_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The result of passing data to a pad.
///
/// Note that the custom return values should not be exposed outside of the
/// element scope.
pub const FlowReturn = enum(c_int) {
    custom_success_2 = 102,
    custom_success_1 = 101,
    custom_success = 100,
    ok = 0,
    not_linked = -1,
    flushing = -2,
    eos = -3,
    not_negotiated = -4,
    @"error" = -5,
    not_supported = -6,
    custom_error = -100,
    custom_error_1 = -101,
    custom_error_2 = -102,
    _,

    extern fn gst_flow_return_get_type() usize;
    pub const getGObjectType = gst_flow_return_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Standard predefined formats
pub const Format = enum(c_int) {
    undefined = 0,
    default = 1,
    bytes = 2,
    time = 3,
    buffers = 4,
    percent = 5,
    _,

    /// Return the format registered with the given nick.
    extern fn gst_format_get_by_nick(p_nick: [*:0]const u8) gst.Format;
    pub const getByNick = gst_format_get_by_nick;

    /// Get details about the given format.
    extern fn gst_format_get_details(p_format: gst.Format) ?*const gst.FormatDefinition;
    pub const getDetails = gst_format_get_details;

    /// Get a printable name for the given format. Do not modify or free.
    extern fn gst_format_get_name(p_format: gst.Format) ?[*:0]const u8;
    pub const getName = gst_format_get_name;

    /// Iterate all the registered formats. The format definition is read
    /// only.
    extern fn gst_format_iterate_definitions() *gst.Iterator;
    pub const iterateDefinitions = gst_format_iterate_definitions;

    /// Create a new GstFormat based on the nick or return an
    /// already registered format with that nick.
    extern fn gst_format_register(p_nick: [*:0]const u8, p_description: [*:0]const u8) gst.Format;
    pub const register = gst_format_register;

    /// Get the unique quark for the given format.
    extern fn gst_format_to_quark(p_format: gst.Format) glib.Quark;
    pub const toQuark = gst_format_to_quark;

    extern fn gst_format_get_type() usize;
    pub const getGObjectType = gst_format_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The result of a `gst.IteratorItemFunction`.
pub const IteratorItem = enum(c_int) {
    skip = 0,
    pass = 1,
    end = 2,
    _,

    extern fn gst_iterator_item_get_type() usize;
    pub const getGObjectType = gst_iterator_item_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The result of `gst.Iterator.next`.
pub const IteratorResult = enum(c_int) {
    done = 0,
    ok = 1,
    resync = 2,
    @"error" = 3,
    _,

    extern fn gst_iterator_result_get_type() usize;
    pub const getGObjectType = gst_iterator_result_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Library errors are for errors from the library being used by elements
/// (initializing, finalizing, settings, ...)
pub const LibraryError = enum(c_int) {
    failed = 1,
    too_lazy = 2,
    init = 3,
    shutdown = 4,
    settings = 5,
    encode = 6,
    num_errors = 7,
    _,

    extern fn gst_library_error_quark() glib.Quark;
    pub const quark = gst_library_error_quark;

    extern fn gst_library_error_get_type() usize;
    pub const getGObjectType = gst_library_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The direction of a pad.
pub const PadDirection = enum(c_int) {
    unknown = 0,
    src = 1,
    sink = 2,
    _,

    extern fn gst_pad_direction_get_type() usize;
    pub const getGObjectType = gst_pad_direction_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Result values from gst_pad_link and friends.
pub const PadLinkReturn = enum(c_int) {
    ok = 0,
    wrong_hierarchy = -1,
    was_linked = -2,
    wrong_direction = -3,
    noformat = -4,
    nosched = -5,
    refused = -6,
    _,

    extern fn gst_pad_link_return_get_type() usize;
    pub const getGObjectType = gst_pad_link_return_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The status of a GstPad. After activating a pad, which usually happens when the
/// parent element goes from READY to PAUSED, the GstPadMode defines if the
/// pad operates in push or pull mode.
pub const PadMode = enum(c_int) {
    none = 0,
    push = 1,
    pull = 2,
    _,

    /// Return the name of a pad mode, for use in debug messages mostly.
    extern fn gst_pad_mode_get_name(p_mode: gst.PadMode) [*:0]const u8;
    pub const getName = gst_pad_mode_get_name;

    extern fn gst_pad_mode_get_type() usize;
    pub const getGObjectType = gst_pad_mode_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Indicates when this pad will become available.
pub const PadPresence = enum(c_int) {
    always = 0,
    sometimes = 1,
    request = 2,
    _,

    extern fn gst_pad_presence_get_type() usize;
    pub const getGObjectType = gst_pad_presence_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Different return values for the `gst.PadProbeCallback`.
pub const PadProbeReturn = enum(c_int) {
    drop = 0,
    ok = 1,
    remove = 2,
    pass = 3,
    handled = 4,
    _,

    extern fn gst_pad_probe_return_get_type() usize;
    pub const getGObjectType = gst_pad_probe_return_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different parsing errors that can occur.
pub const ParseError = enum(c_int) {
    syntax = 0,
    no_such_element = 1,
    no_such_property = 2,
    link = 3,
    could_not_set_property = 4,
    empty_bin = 5,
    empty = 6,
    delayed_link = 7,
    _,

    /// Get the error quark used by the parsing subsystem.
    extern fn gst_parse_error_quark() glib.Quark;
    pub const quark = gst_parse_error_quark;

    extern fn gst_parse_error_get_type() usize;
    pub const getGObjectType = gst_parse_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The plugin loading errors
pub const PluginError = enum(c_int) {
    module = 0,
    dependencies = 1,
    name_mismatch = 2,
    _,

    /// Get the error quark.
    extern fn gst_plugin_error_quark() glib.Quark;
    pub const quark = gst_plugin_error_quark;

    extern fn gst_plugin_error_get_type() usize;
    pub const getGObjectType = gst_plugin_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The type of a `GST_MESSAGE_PROGRESS`. The progress messages inform the
/// application of the status of asynchronous tasks.
pub const ProgressType = enum(c_int) {
    start = 0,
    @"continue" = 1,
    complete = 2,
    canceled = 3,
    @"error" = 4,
    _,

    extern fn gst_progress_type_get_type() usize;
    pub const getGObjectType = gst_progress_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The result of a `gst.Promise`
pub const PromiseResult = enum(c_int) {
    pending = 0,
    interrupted = 1,
    replied = 2,
    expired = 3,
    _,

    extern fn gst_promise_result_get_type() usize;
    pub const getGObjectType = gst_promise_result_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different types of QoS events that can be given to the
/// `gst.Event.newQos` method.
pub const QOSType = enum(c_int) {
    overflow = 0,
    underflow = 1,
    throttle = 2,
    _,

    extern fn gst_qos_type_get_type() usize;
    pub const getGObjectType = gst_qos_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Standard predefined Query types
pub const QueryType = enum(c_int) {
    unknown = 0,
    position = 2563,
    duration = 5123,
    latency = 7683,
    jitter = 10243,
    rate = 12803,
    seeking = 15363,
    segment = 17923,
    convert = 20483,
    formats = 23043,
    buffering = 28163,
    custom = 30723,
    uri = 33283,
    allocation = 35846,
    scheduling = 38401,
    accept_caps = 40963,
    caps = 43523,
    drain = 46086,
    context = 48643,
    bitrate = 51202,
    selectable = 53763,
    _,

    /// Gets the `gst.QueryTypeFlags` associated with `type`.
    extern fn gst_query_type_get_flags(p_type: gst.QueryType) gst.QueryTypeFlags;
    pub const getFlags = gst_query_type_get_flags;

    /// Get a printable name for the given query type. Do not modify or free.
    extern fn gst_query_type_get_name(p_type: gst.QueryType) [*:0]const u8;
    pub const getName = gst_query_type_get_name;

    /// Get the unique quark for the given query type.
    extern fn gst_query_type_to_quark(p_type: gst.QueryType) glib.Quark;
    pub const toQuark = gst_query_type_to_quark;

    extern fn gst_query_type_get_type() usize;
    pub const getGObjectType = gst_query_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Element priority ranks. Defines the order in which the autoplugger (or
/// similar rank-picking mechanisms, such as e.g. `gst.Element.makeFromUri`)
/// will choose this element over an alternative one with the same function.
///
/// These constants serve as a rough guidance for defining the rank of a
/// `gst.PluginFeature`. Any value is valid, including values bigger than
/// `GST_RANK_PRIMARY`.
pub const Rank = enum(c_int) {
    none = 0,
    marginal = 64,
    secondary = 128,
    primary = 256,
    _,

    extern fn gst_rank_get_type() usize;
    pub const getGObjectType = gst_rank_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Resource errors are for any resource used by an element:
/// memory, files, network connections, process space, ...
/// They're typically used by source and sink elements.
pub const ResourceError = enum(c_int) {
    failed = 1,
    too_lazy = 2,
    not_found = 3,
    busy = 4,
    open_read = 5,
    open_write = 6,
    open_read_write = 7,
    close = 8,
    read = 9,
    write = 10,
    seek = 11,
    sync = 12,
    settings = 13,
    no_space_left = 14,
    not_authorized = 15,
    num_errors = 16,
    _,

    extern fn gst_resource_error_quark() glib.Quark;
    pub const quark = gst_resource_error_quark;

    extern fn gst_resource_error_get_type() usize;
    pub const getGObjectType = gst_resource_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different search modes.
pub const SearchMode = enum(c_int) {
    exact = 0,
    before = 1,
    after = 2,
    _,

    extern fn gst_search_mode_get_type() usize;
    pub const getGObjectType = gst_search_mode_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different types of seek events. When constructing a seek event with
/// `gst.Event.newSeek` or when doing gst_segment_do_seek ().
pub const SeekType = enum(c_int) {
    none = 0,
    set = 1,
    end = 2,
    _,

    extern fn gst_seek_type_get_type() usize;
    pub const getGObjectType = gst_seek_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The possible states an element can be in. States can be changed using
/// `gst.Element.setState` and checked using `gst.Element.getState`.
pub const State = enum(c_int) {
    void_pending = 0,
    null = 1,
    ready = 2,
    paused = 3,
    playing = 4,
    _,

    extern fn gst_state_get_type() usize;
    pub const getGObjectType = gst_state_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// These are the different state changes an element goes through.
/// `GST_STATE_NULL` &rArr; `GST_STATE_PLAYING` is called an upwards state change
/// and `GST_STATE_PLAYING` &rArr; `GST_STATE_NULL` a downwards state change.
pub const StateChange = enum(c_int) {
    null_to_ready = 10,
    ready_to_paused = 19,
    paused_to_playing = 28,
    playing_to_paused = 35,
    paused_to_ready = 26,
    ready_to_null = 17,
    null_to_null = 9,
    ready_to_ready = 18,
    paused_to_paused = 27,
    playing_to_playing = 36,
    _,

    /// Gets a string representing the given state transition.
    extern fn gst_state_change_get_name(p_transition: gst.StateChange) [*:0]const u8;
    pub const getName = gst_state_change_get_name;

    extern fn gst_state_change_get_type() usize;
    pub const getGObjectType = gst_state_change_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The possible return values from a state change function such as
/// `gst.Element.setState`. Only `GST_STATE_CHANGE_FAILURE` is a real failure.
pub const StateChangeReturn = enum(c_int) {
    failure = 0,
    success = 1,
    async = 2,
    no_preroll = 3,
    _,

    extern fn gst_state_change_return_get_type() usize;
    pub const getGObjectType = gst_state_change_return_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Stream errors are for anything related to the stream being processed:
/// format errors, media type errors, ...
/// They're typically used by decoders, demuxers, converters, ...
pub const StreamError = enum(c_int) {
    failed = 1,
    too_lazy = 2,
    not_implemented = 3,
    type_not_found = 4,
    wrong_type = 5,
    codec_not_found = 6,
    decode = 7,
    encode = 8,
    demux = 9,
    mux = 10,
    format = 11,
    decrypt = 12,
    decrypt_nokey = 13,
    num_errors = 14,
    _,

    extern fn gst_stream_error_quark() glib.Quark;
    pub const quark = gst_stream_error_quark;

    extern fn gst_stream_error_get_type() usize;
    pub const getGObjectType = gst_stream_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The type of a `GST_MESSAGE_STREAM_STATUS`. The stream status messages inform the
/// application of new streaming threads and their status.
pub const StreamStatusType = enum(c_int) {
    create = 0,
    enter = 1,
    leave = 2,
    destroy = 3,
    start = 8,
    pause = 9,
    stop = 10,
    _,

    extern fn gst_stream_status_type_get_type() usize;
    pub const getGObjectType = gst_stream_status_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The type of a `GST_MESSAGE_STRUCTURE_CHANGE`.
pub const StructureChangeType = enum(c_int) {
    link = 0,
    unlink = 1,
    _,

    extern fn gst_structure_change_type_get_type() usize;
    pub const getGObjectType = gst_structure_change_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Extra tag flags used when registering tags.
pub const TagFlag = enum(c_int) {
    undefined = 0,
    meta = 1,
    encoded = 2,
    decoded = 3,
    count = 4,
    _,

    extern fn gst_tag_flag_get_type() usize;
    pub const getGObjectType = gst_tag_flag_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different tag merging modes are basically replace, overwrite and append,
/// but they can be seen from two directions. Given two taglists: (A) the tags
/// already in the element and (B) the ones that are supplied to the element (
/// e.g. via `gst.TagSetter.mergeTags` / `gst.TagSetter.addTags` or a
/// `GST_EVENT_TAG`), how are these tags merged?
/// In the table below this is shown for the cases that a tag exists in the list
/// (A) or does not exists (!A) and combinations thereof.
///
/// | merge mode  | A + B | A + !B | !A + B | !A + !B |
/// | ----------- | ----- | ------ | ------ | ------- |
/// | REPLACE_ALL | B     | ø      | B      | ø       |
/// | REPLACE     | B     | A      | B      | ø       |
/// | APPEND      | A, B  | A      | B      | ø       |
/// | PREPEND     | B, A  | A      | B      | ø       |
/// | KEEP        | A     | A      | B      | ø       |
/// | KEEP_ALL    | A     | A      | ø      | ø       |
pub const TagMergeMode = enum(c_int) {
    undefined = 0,
    replace_all = 1,
    replace = 2,
    append = 3,
    prepend = 4,
    keep = 5,
    keep_all = 6,
    count = 7,
    _,

    extern fn gst_tag_merge_mode_get_type() usize;
    pub const getGObjectType = gst_tag_merge_mode_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstTagScope specifies if a taglist applies to the complete
/// medium or only to one single stream.
pub const TagScope = enum(c_int) {
    stream = 0,
    global = 1,
    _,

    extern fn gst_tag_scope_get_type() usize;
    pub const getGObjectType = gst_tag_scope_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different states a task can be in
pub const TaskState = enum(c_int) {
    started = 0,
    stopped = 1,
    paused = 2,
    _,

    extern fn gst_task_state_get_type() usize;
    pub const getGObjectType = gst_task_state_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different types of TOC entries (see `gst.TocEntry`).
///
/// There are two types of TOC entries: alternatives or parts in a sequence.
pub const TocEntryType = enum(c_int) {
    angle = -3,
    version = -2,
    edition = -1,
    invalid = 0,
    title = 1,
    track = 2,
    chapter = 3,
    _,

    /// Converts `type` to a string representation.
    extern fn gst_toc_entry_type_get_nick(p_type: gst.TocEntryType) [*:0]const u8;
    pub const getNick = gst_toc_entry_type_get_nick;

    extern fn gst_toc_entry_type_get_type() usize;
    pub const getGObjectType = gst_toc_entry_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// How a `gst.TocEntry` should be repeated. By default, entries are played a
/// single time.
pub const TocLoopType = enum(c_int) {
    none = 0,
    forward = 1,
    reverse = 2,
    ping_pong = 3,
    _,

    extern fn gst_toc_loop_type_get_type() usize;
    pub const getGObjectType = gst_toc_loop_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The scope of a TOC.
pub const TocScope = enum(c_int) {
    global = 1,
    current = 2,
    _,

    extern fn gst_toc_scope_get_type() usize;
    pub const getGObjectType = gst_toc_scope_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Tracing record will contain fields that contain a measured value or extra
/// meta-data. One such meta data are values that tell where a measurement was
/// taken. This enumerating declares to which scope such a meta data field
/// relates to. If it is e.g. `GST_TRACER_VALUE_SCOPE_PAD`, then each of the log
/// events may contain values for different `GstPads`.
pub const TracerValueScope = enum(c_int) {
    process = 0,
    thread = 1,
    element = 2,
    pad = 3,
    _,

    extern fn gst_tracer_value_scope_get_type() usize;
    pub const getGObjectType = gst_tracer_value_scope_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The probability of the typefind function. Higher values have more certainty
/// in doing a reliable typefind.
pub const TypeFindProbability = enum(c_int) {
    none = 0,
    minimum = 1,
    possible = 50,
    likely = 80,
    nearly_certain = 99,
    maximum = 100,
    _,

    extern fn gst_type_find_probability_get_type() usize;
    pub const getGObjectType = gst_type_find_probability_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Different URI-related errors that can occur.
pub const URIError = enum(c_int) {
    unsupported_protocol = 0,
    bad_uri = 1,
    bad_state = 2,
    bad_reference = 3,
    _,

    extern fn gst_uri_error_quark() glib.Quark;
    pub const quark = gst_uri_error_quark;

    extern fn gst_uri_error_get_type() usize;
    pub const getGObjectType = gst_uri_error_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different types of URI direction.
pub const URIType = enum(c_int) {
    unknown = 0,
    sink = 1,
    src = 2,
    _,

    extern fn gst_uri_type_get_type() usize;
    pub const getGObjectType = gst_uri_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags for allocators.
pub const AllocatorFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    custom_alloc: bool = false,
    no_copy: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    last: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_custom_alloc: AllocatorFlags = @bitCast(@as(c_uint, 16));
    pub const flags_no_copy: AllocatorFlags = @bitCast(@as(c_uint, 32));
    pub const flags_last: AllocatorFlags = @bitCast(@as(c_uint, 1048576));
    extern fn gst_allocator_flags_get_type() usize;
    pub const getGObjectType = gst_allocator_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// GstBinFlags are a set of flags specific to bins. Most are set/used
/// internally. They can be checked using the `GST_OBJECT_FLAG_IS_SET` macro,
/// and (un)set using `GST_OBJECT_FLAG_SET` and `GST_OBJECT_FLAG_UNSET`.
pub const BinFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    no_resync: bool = false,
    streams_aware: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    last: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_no_resync: BinFlags = @bitCast(@as(c_uint, 16384));
    pub const flags_streams_aware: BinFlags = @bitCast(@as(c_uint, 32768));
    pub const flags_last: BinFlags = @bitCast(@as(c_uint, 524288));
    extern fn gst_bin_flags_get_type() usize;
    pub const getGObjectType = gst_bin_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A set of flags that can be provided to the `gst.Buffer.copyInto`
/// function to specify which items should be copied.
pub const BufferCopyFlags = packed struct(c_uint) {
    flags: bool = false,
    timestamps: bool = false,
    meta: bool = false,
    memory: bool = false,
    merge: bool = false,
    deep: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: BufferCopyFlags = @bitCast(@as(c_uint, 0));
    pub const flags_flags: BufferCopyFlags = @bitCast(@as(c_uint, 1));
    pub const flags_timestamps: BufferCopyFlags = @bitCast(@as(c_uint, 2));
    pub const flags_meta: BufferCopyFlags = @bitCast(@as(c_uint, 4));
    pub const flags_memory: BufferCopyFlags = @bitCast(@as(c_uint, 8));
    pub const flags_merge: BufferCopyFlags = @bitCast(@as(c_uint, 16));
    pub const flags_deep: BufferCopyFlags = @bitCast(@as(c_uint, 32));
    extern fn gst_buffer_copy_flags_get_type() usize;
    pub const getGObjectType = gst_buffer_copy_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// A set of buffer flags used to describe properties of a `gst.Buffer`.
pub const BufferFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    live: bool = false,
    decode_only: bool = false,
    discont: bool = false,
    resync: bool = false,
    corrupted: bool = false,
    marker: bool = false,
    header: bool = false,
    gap: bool = false,
    droppable: bool = false,
    delta_unit: bool = false,
    tag_memory: bool = false,
    sync_after: bool = false,
    non_droppable: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    last: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_live: BufferFlags = @bitCast(@as(c_uint, 16));
    pub const flags_decode_only: BufferFlags = @bitCast(@as(c_uint, 32));
    pub const flags_discont: BufferFlags = @bitCast(@as(c_uint, 64));
    pub const flags_resync: BufferFlags = @bitCast(@as(c_uint, 128));
    pub const flags_corrupted: BufferFlags = @bitCast(@as(c_uint, 256));
    pub const flags_marker: BufferFlags = @bitCast(@as(c_uint, 512));
    pub const flags_header: BufferFlags = @bitCast(@as(c_uint, 1024));
    pub const flags_gap: BufferFlags = @bitCast(@as(c_uint, 2048));
    pub const flags_droppable: BufferFlags = @bitCast(@as(c_uint, 4096));
    pub const flags_delta_unit: BufferFlags = @bitCast(@as(c_uint, 8192));
    pub const flags_tag_memory: BufferFlags = @bitCast(@as(c_uint, 16384));
    pub const flags_sync_after: BufferFlags = @bitCast(@as(c_uint, 32768));
    pub const flags_non_droppable: BufferFlags = @bitCast(@as(c_uint, 65536));
    pub const flags_last: BufferFlags = @bitCast(@as(c_uint, 1048576));
    extern fn gst_buffer_flags_get_type() usize;
    pub const getGObjectType = gst_buffer_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Additional flags to control the allocation of a buffer
pub const BufferPoolAcquireFlags = packed struct(c_uint) {
    key_unit: bool = false,
    dontwait: bool = false,
    discont: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    last: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: BufferPoolAcquireFlags = @bitCast(@as(c_uint, 0));
    pub const flags_key_unit: BufferPoolAcquireFlags = @bitCast(@as(c_uint, 1));
    pub const flags_dontwait: BufferPoolAcquireFlags = @bitCast(@as(c_uint, 2));
    pub const flags_discont: BufferPoolAcquireFlags = @bitCast(@as(c_uint, 4));
    pub const flags_last: BufferPoolAcquireFlags = @bitCast(@as(c_uint, 65536));
    extern fn gst_buffer_pool_acquire_flags_get_type() usize;
    pub const getGObjectType = gst_buffer_pool_acquire_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The standard flags that a bus may have.
pub const BusFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    flushing: bool = false,
    flag_last: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_flushing: BusFlags = @bitCast(@as(c_uint, 16));
    pub const flags_flag_last: BusFlags = @bitCast(@as(c_uint, 32));
    extern fn gst_bus_flags_get_type() usize;
    pub const getGObjectType = gst_bus_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Extra flags for a caps.
pub const CapsFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    any: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_any: CapsFlags = @bitCast(@as(c_uint, 16));
    extern fn gst_caps_flags_get_type() usize;
    pub const getGObjectType = gst_caps_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The capabilities of this clock
pub const ClockFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    can_do_single_sync: bool = false,
    can_do_single_async: bool = false,
    can_do_periodic_sync: bool = false,
    can_do_periodic_async: bool = false,
    can_set_resolution: bool = false,
    can_set_master: bool = false,
    needs_startup_sync: bool = false,
    _padding11: bool = false,
    last: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_can_do_single_sync: ClockFlags = @bitCast(@as(c_uint, 16));
    pub const flags_can_do_single_async: ClockFlags = @bitCast(@as(c_uint, 32));
    pub const flags_can_do_periodic_sync: ClockFlags = @bitCast(@as(c_uint, 64));
    pub const flags_can_do_periodic_async: ClockFlags = @bitCast(@as(c_uint, 128));
    pub const flags_can_set_resolution: ClockFlags = @bitCast(@as(c_uint, 256));
    pub const flags_can_set_master: ClockFlags = @bitCast(@as(c_uint, 512));
    pub const flags_needs_startup_sync: ClockFlags = @bitCast(@as(c_uint, 1024));
    pub const flags_last: ClockFlags = @bitCast(@as(c_uint, 4096));
    extern fn gst_clock_flags_get_type() usize;
    pub const getGObjectType = gst_clock_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// These are some terminal style flags you can use when creating your
/// debugging categories to make them stand out in debugging output.
pub const DebugColorFlags = packed struct(c_uint) {
    fg_red: bool = false,
    fg_green: bool = false,
    fg_blue: bool = false,
    _padding3: bool = false,
    bg_red: bool = false,
    bg_green: bool = false,
    bg_blue: bool = false,
    _padding7: bool = false,
    bold: bool = false,
    underline: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_fg_black: DebugColorFlags = @bitCast(@as(c_uint, 0));
    pub const flags_fg_red: DebugColorFlags = @bitCast(@as(c_uint, 1));
    pub const flags_fg_green: DebugColorFlags = @bitCast(@as(c_uint, 2));
    pub const flags_fg_yellow: DebugColorFlags = @bitCast(@as(c_uint, 3));
    pub const flags_fg_blue: DebugColorFlags = @bitCast(@as(c_uint, 4));
    pub const flags_fg_magenta: DebugColorFlags = @bitCast(@as(c_uint, 5));
    pub const flags_fg_cyan: DebugColorFlags = @bitCast(@as(c_uint, 6));
    pub const flags_fg_white: DebugColorFlags = @bitCast(@as(c_uint, 7));
    pub const flags_bg_black: DebugColorFlags = @bitCast(@as(c_uint, 0));
    pub const flags_bg_red: DebugColorFlags = @bitCast(@as(c_uint, 16));
    pub const flags_bg_green: DebugColorFlags = @bitCast(@as(c_uint, 32));
    pub const flags_bg_yellow: DebugColorFlags = @bitCast(@as(c_uint, 48));
    pub const flags_bg_blue: DebugColorFlags = @bitCast(@as(c_uint, 64));
    pub const flags_bg_magenta: DebugColorFlags = @bitCast(@as(c_uint, 80));
    pub const flags_bg_cyan: DebugColorFlags = @bitCast(@as(c_uint, 96));
    pub const flags_bg_white: DebugColorFlags = @bitCast(@as(c_uint, 112));
    pub const flags_bold: DebugColorFlags = @bitCast(@as(c_uint, 256));
    pub const flags_underline: DebugColorFlags = @bitCast(@as(c_uint, 512));
    extern fn gst_debug_color_flags_get_type() usize;
    pub const getGObjectType = gst_debug_color_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Available details for pipeline graphs produced by `GST_DEBUG_BIN_TO_DOT_FILE`
/// and `GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS`.
pub const DebugGraphDetails = packed struct(c_uint) {
    media_type: bool = false,
    caps_details: bool = false,
    non_default_params: bool = false,
    states: bool = false,
    full_params: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_media_type: DebugGraphDetails = @bitCast(@as(c_uint, 1));
    pub const flags_caps_details: DebugGraphDetails = @bitCast(@as(c_uint, 2));
    pub const flags_non_default_params: DebugGraphDetails = @bitCast(@as(c_uint, 4));
    pub const flags_states: DebugGraphDetails = @bitCast(@as(c_uint, 8));
    pub const flags_full_params: DebugGraphDetails = @bitCast(@as(c_uint, 16));
    pub const flags_all: DebugGraphDetails = @bitCast(@as(c_uint, 15));
    pub const flags_verbose: DebugGraphDetails = @bitCast(@as(c_uint, 4294967295));
    extern fn gst_debug_graph_details_get_type() usize;
    pub const getGObjectType = gst_debug_graph_details_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The standard flags that an element may have.
pub const ElementFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    locked_state: bool = false,
    sink: bool = false,
    source: bool = false,
    provide_clock: bool = false,
    require_clock: bool = false,
    indexable: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    last: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_locked_state: ElementFlags = @bitCast(@as(c_uint, 16));
    pub const flags_sink: ElementFlags = @bitCast(@as(c_uint, 32));
    pub const flags_source: ElementFlags = @bitCast(@as(c_uint, 64));
    pub const flags_provide_clock: ElementFlags = @bitCast(@as(c_uint, 128));
    pub const flags_require_clock: ElementFlags = @bitCast(@as(c_uint, 256));
    pub const flags_indexable: ElementFlags = @bitCast(@as(c_uint, 512));
    pub const flags_last: ElementFlags = @bitCast(@as(c_uint, 16384));
    extern fn gst_element_flags_get_type() usize;
    pub const getGObjectType = gst_element_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.EventTypeFlags` indicate the aspects of the different `gst.EventType`
/// values. You can get the type flags of a `gst.EventType` with the
/// `gst.eventTypeGetFlags` function.
pub const EventTypeFlags = packed struct(c_uint) {
    upstream: bool = false,
    downstream: bool = false,
    serialized: bool = false,
    sticky: bool = false,
    sticky_multi: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_upstream: EventTypeFlags = @bitCast(@as(c_uint, 1));
    pub const flags_downstream: EventTypeFlags = @bitCast(@as(c_uint, 2));
    pub const flags_serialized: EventTypeFlags = @bitCast(@as(c_uint, 4));
    pub const flags_sticky: EventTypeFlags = @bitCast(@as(c_uint, 8));
    pub const flags_sticky_multi: EventTypeFlags = @bitCast(@as(c_uint, 16));
    extern fn gst_event_type_flags_get_type() usize;
    pub const getGObjectType = gst_event_type_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different flags that can be set on `GST_EVENT_GAP` events. See
/// `gst.Event.setGapFlags` for details.
pub const GapFlags = packed struct(c_uint) {
    data: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_data: GapFlags = @bitCast(@as(c_uint, 1));
    extern fn gst_gap_flags_get_type() usize;
    pub const getGObjectType = gst_gap_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags used when locking miniobjects
pub const LockFlags = packed struct(c_uint) {
    read: bool = false,
    write: bool = false,
    exclusive: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    last: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_read: LockFlags = @bitCast(@as(c_uint, 1));
    pub const flags_write: LockFlags = @bitCast(@as(c_uint, 2));
    pub const flags_exclusive: LockFlags = @bitCast(@as(c_uint, 4));
    pub const flags_last: LockFlags = @bitCast(@as(c_uint, 256));
    extern fn gst_lock_flags_get_type() usize;
    pub const getGObjectType = gst_lock_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags used when mapping memory
pub const MapFlags = packed struct(c_uint) {
    read: bool = false,
    write: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    flag_last: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_read: MapFlags = @bitCast(@as(c_uint, 1));
    pub const flags_write: MapFlags = @bitCast(@as(c_uint, 2));
    pub const flags_flag_last: MapFlags = @bitCast(@as(c_uint, 65536));
    extern fn gst_map_flags_get_type() usize;
    pub const getGObjectType = gst_map_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags for wrapped memory.
pub const MemoryFlags = packed struct(c_uint) {
    _padding0: bool = false,
    readonly: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    no_share: bool = false,
    zero_prefixed: bool = false,
    zero_padded: bool = false,
    physically_contiguous: bool = false,
    not_mappable: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    last: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_readonly: MemoryFlags = @bitCast(@as(c_uint, 2));
    pub const flags_no_share: MemoryFlags = @bitCast(@as(c_uint, 16));
    pub const flags_zero_prefixed: MemoryFlags = @bitCast(@as(c_uint, 32));
    pub const flags_zero_padded: MemoryFlags = @bitCast(@as(c_uint, 64));
    pub const flags_physically_contiguous: MemoryFlags = @bitCast(@as(c_uint, 128));
    pub const flags_not_mappable: MemoryFlags = @bitCast(@as(c_uint, 256));
    pub const flags_last: MemoryFlags = @bitCast(@as(c_uint, 1048576));
    extern fn gst_memory_flags_get_type() usize;
    pub const getGObjectType = gst_memory_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different message types that are available.
pub const MessageType = packed struct(c_uint) {
    eos: bool = false,
    @"error": bool = false,
    warning: bool = false,
    info: bool = false,
    tag: bool = false,
    buffering: bool = false,
    state_changed: bool = false,
    state_dirty: bool = false,
    step_done: bool = false,
    clock_provide: bool = false,
    clock_lost: bool = false,
    new_clock: bool = false,
    structure_change: bool = false,
    stream_status: bool = false,
    application: bool = false,
    element: bool = false,
    segment_start: bool = false,
    segment_done: bool = false,
    duration_changed: bool = false,
    latency: bool = false,
    async_start: bool = false,
    async_done: bool = false,
    request_state: bool = false,
    step_start: bool = false,
    qos: bool = false,
    progress: bool = false,
    toc: bool = false,
    reset_time: bool = false,
    stream_start: bool = false,
    need_context: bool = false,
    have_context: bool = false,
    extended: bool = false,

    pub const flags_unknown: MessageType = @bitCast(@as(c_uint, 0));
    pub const flags_eos: MessageType = @bitCast(@as(c_uint, 1));
    pub const flags_error: MessageType = @bitCast(@as(c_uint, 2));
    pub const flags_warning: MessageType = @bitCast(@as(c_uint, 4));
    pub const flags_info: MessageType = @bitCast(@as(c_uint, 8));
    pub const flags_tag: MessageType = @bitCast(@as(c_uint, 16));
    pub const flags_buffering: MessageType = @bitCast(@as(c_uint, 32));
    pub const flags_state_changed: MessageType = @bitCast(@as(c_uint, 64));
    pub const flags_state_dirty: MessageType = @bitCast(@as(c_uint, 128));
    pub const flags_step_done: MessageType = @bitCast(@as(c_uint, 256));
    pub const flags_clock_provide: MessageType = @bitCast(@as(c_uint, 512));
    pub const flags_clock_lost: MessageType = @bitCast(@as(c_uint, 1024));
    pub const flags_new_clock: MessageType = @bitCast(@as(c_uint, 2048));
    pub const flags_structure_change: MessageType = @bitCast(@as(c_uint, 4096));
    pub const flags_stream_status: MessageType = @bitCast(@as(c_uint, 8192));
    pub const flags_application: MessageType = @bitCast(@as(c_uint, 16384));
    pub const flags_element: MessageType = @bitCast(@as(c_uint, 32768));
    pub const flags_segment_start: MessageType = @bitCast(@as(c_uint, 65536));
    pub const flags_segment_done: MessageType = @bitCast(@as(c_uint, 131072));
    pub const flags_duration_changed: MessageType = @bitCast(@as(c_uint, 262144));
    pub const flags_latency: MessageType = @bitCast(@as(c_uint, 524288));
    pub const flags_async_start: MessageType = @bitCast(@as(c_uint, 1048576));
    pub const flags_async_done: MessageType = @bitCast(@as(c_uint, 2097152));
    pub const flags_request_state: MessageType = @bitCast(@as(c_uint, 4194304));
    pub const flags_step_start: MessageType = @bitCast(@as(c_uint, 8388608));
    pub const flags_qos: MessageType = @bitCast(@as(c_uint, 16777216));
    pub const flags_progress: MessageType = @bitCast(@as(c_uint, 33554432));
    pub const flags_toc: MessageType = @bitCast(@as(c_uint, 67108864));
    pub const flags_reset_time: MessageType = @bitCast(@as(c_uint, 134217728));
    pub const flags_stream_start: MessageType = @bitCast(@as(c_uint, 268435456));
    pub const flags_need_context: MessageType = @bitCast(@as(c_uint, 536870912));
    pub const flags_have_context: MessageType = @bitCast(@as(c_uint, 1073741824));
    pub const flags_extended: MessageType = @bitCast(@as(c_uint, 2147483648));
    pub const flags_device_added: MessageType = @bitCast(@as(c_uint, 2147483649));
    pub const flags_device_removed: MessageType = @bitCast(@as(c_uint, 2147483650));
    pub const flags_property_notify: MessageType = @bitCast(@as(c_uint, 2147483651));
    pub const flags_stream_collection: MessageType = @bitCast(@as(c_uint, 2147483652));
    pub const flags_streams_selected: MessageType = @bitCast(@as(c_uint, 2147483653));
    pub const flags_redirect: MessageType = @bitCast(@as(c_uint, 2147483654));
    pub const flags_device_changed: MessageType = @bitCast(@as(c_uint, 2147483655));
    pub const flags_instant_rate_request: MessageType = @bitCast(@as(c_uint, 2147483656));
    pub const flags_any: MessageType = @bitCast(@as(c_uint, 4294967295));
    /// Get a printable name for the given message type. Do not modify or free.
    extern fn gst_message_type_get_name(p_type: gst.MessageType) [*:0]const u8;
    pub const getName = gst_message_type_get_name;

    /// Get the unique quark for the given message type.
    extern fn gst_message_type_to_quark(p_type: gst.MessageType) glib.Quark;
    pub const toQuark = gst_message_type_to_quark;

    extern fn gst_message_type_get_type() usize;
    pub const getGObjectType = gst_message_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Extra metadata flags.
pub const MetaFlags = packed struct(c_uint) {
    readonly: bool = false,
    pooled: bool = false,
    locked: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    last: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: MetaFlags = @bitCast(@as(c_uint, 0));
    pub const flags_readonly: MetaFlags = @bitCast(@as(c_uint, 1));
    pub const flags_pooled: MetaFlags = @bitCast(@as(c_uint, 2));
    pub const flags_locked: MetaFlags = @bitCast(@as(c_uint, 4));
    pub const flags_last: MetaFlags = @bitCast(@as(c_uint, 65536));
    extern fn gst_meta_flags_get_type() usize;
    pub const getGObjectType = gst_meta_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags for the mini object
pub const MiniObjectFlags = packed struct(c_uint) {
    lockable: bool = false,
    lock_readonly: bool = false,
    may_be_leaked: bool = false,
    _padding3: bool = false,
    last: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_lockable: MiniObjectFlags = @bitCast(@as(c_uint, 1));
    pub const flags_lock_readonly: MiniObjectFlags = @bitCast(@as(c_uint, 2));
    pub const flags_may_be_leaked: MiniObjectFlags = @bitCast(@as(c_uint, 4));
    pub const flags_last: MiniObjectFlags = @bitCast(@as(c_uint, 16));
    extern fn gst_mini_object_flags_get_type() usize;
    pub const getGObjectType = gst_mini_object_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The standard flags that an gstobject may have.
pub const ObjectFlags = packed struct(c_uint) {
    may_be_leaked: bool = false,
    constructed: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    last: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_may_be_leaked: ObjectFlags = @bitCast(@as(c_uint, 1));
    pub const flags_constructed: ObjectFlags = @bitCast(@as(c_uint, 2));
    pub const flags_last: ObjectFlags = @bitCast(@as(c_uint, 16));
    extern fn gst_object_flags_get_type() usize;
    pub const getGObjectType = gst_object_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Pad state flags
pub const PadFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    blocked: bool = false,
    flushing: bool = false,
    eos: bool = false,
    blocking: bool = false,
    need_parent: bool = false,
    need_reconfigure: bool = false,
    pending_events: bool = false,
    fixed_caps: bool = false,
    proxy_caps: bool = false,
    proxy_allocation: bool = false,
    proxy_scheduling: bool = false,
    accept_intersect: bool = false,
    accept_template: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    last: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_blocked: PadFlags = @bitCast(@as(c_uint, 16));
    pub const flags_flushing: PadFlags = @bitCast(@as(c_uint, 32));
    pub const flags_eos: PadFlags = @bitCast(@as(c_uint, 64));
    pub const flags_blocking: PadFlags = @bitCast(@as(c_uint, 128));
    pub const flags_need_parent: PadFlags = @bitCast(@as(c_uint, 256));
    pub const flags_need_reconfigure: PadFlags = @bitCast(@as(c_uint, 512));
    pub const flags_pending_events: PadFlags = @bitCast(@as(c_uint, 1024));
    pub const flags_fixed_caps: PadFlags = @bitCast(@as(c_uint, 2048));
    pub const flags_proxy_caps: PadFlags = @bitCast(@as(c_uint, 4096));
    pub const flags_proxy_allocation: PadFlags = @bitCast(@as(c_uint, 8192));
    pub const flags_proxy_scheduling: PadFlags = @bitCast(@as(c_uint, 16384));
    pub const flags_accept_intersect: PadFlags = @bitCast(@as(c_uint, 32768));
    pub const flags_accept_template: PadFlags = @bitCast(@as(c_uint, 65536));
    pub const flags_last: PadFlags = @bitCast(@as(c_uint, 1048576));
    extern fn gst_pad_flags_get_type() usize;
    pub const getGObjectType = gst_pad_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The amount of checking to be done when linking pads. `GST_PAD_LINK_CHECK_CAPS`
/// and `GST_PAD_LINK_CHECK_TEMPLATE_CAPS` are mutually exclusive. If both are
/// specified, expensive but safe `GST_PAD_LINK_CHECK_CAPS` are performed.
///
/// > Only disable some of the checks if you are 100% certain you know the link
/// > will not fail because of hierarchy/caps compatibility failures. If uncertain,
/// > use the default checks (`GST_PAD_LINK_CHECK_DEFAULT`) or the regular methods
/// > for linking the pads.
pub const PadLinkCheck = packed struct(c_uint) {
    hierarchy: bool = false,
    template_caps: bool = false,
    caps: bool = false,
    no_reconfigure: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_nothing: PadLinkCheck = @bitCast(@as(c_uint, 0));
    pub const flags_hierarchy: PadLinkCheck = @bitCast(@as(c_uint, 1));
    pub const flags_template_caps: PadLinkCheck = @bitCast(@as(c_uint, 2));
    pub const flags_caps: PadLinkCheck = @bitCast(@as(c_uint, 4));
    pub const flags_no_reconfigure: PadLinkCheck = @bitCast(@as(c_uint, 8));
    pub const flags_default: PadLinkCheck = @bitCast(@as(c_uint, 5));
    extern fn gst_pad_link_check_get_type() usize;
    pub const getGObjectType = gst_pad_link_check_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different probing types that can occur. When either one of
/// `GST_PAD_PROBE_TYPE_IDLE` or `GST_PAD_PROBE_TYPE_BLOCK` is used, the probe will be a
/// blocking probe.
pub const PadProbeType = packed struct(c_uint) {
    idle: bool = false,
    block: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    buffer: bool = false,
    buffer_list: bool = false,
    event_downstream: bool = false,
    event_upstream: bool = false,
    event_flush: bool = false,
    query_downstream: bool = false,
    query_upstream: bool = false,
    _padding11: bool = false,
    push: bool = false,
    pull: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_invalid: PadProbeType = @bitCast(@as(c_uint, 0));
    pub const flags_idle: PadProbeType = @bitCast(@as(c_uint, 1));
    pub const flags_block: PadProbeType = @bitCast(@as(c_uint, 2));
    pub const flags_buffer: PadProbeType = @bitCast(@as(c_uint, 16));
    pub const flags_buffer_list: PadProbeType = @bitCast(@as(c_uint, 32));
    pub const flags_event_downstream: PadProbeType = @bitCast(@as(c_uint, 64));
    pub const flags_event_upstream: PadProbeType = @bitCast(@as(c_uint, 128));
    pub const flags_event_flush: PadProbeType = @bitCast(@as(c_uint, 256));
    pub const flags_query_downstream: PadProbeType = @bitCast(@as(c_uint, 512));
    pub const flags_query_upstream: PadProbeType = @bitCast(@as(c_uint, 1024));
    pub const flags_push: PadProbeType = @bitCast(@as(c_uint, 4096));
    pub const flags_pull: PadProbeType = @bitCast(@as(c_uint, 8192));
    pub const flags_blocking: PadProbeType = @bitCast(@as(c_uint, 3));
    pub const flags_data_downstream: PadProbeType = @bitCast(@as(c_uint, 112));
    pub const flags_data_upstream: PadProbeType = @bitCast(@as(c_uint, 128));
    pub const flags_data_both: PadProbeType = @bitCast(@as(c_uint, 240));
    pub const flags_block_downstream: PadProbeType = @bitCast(@as(c_uint, 114));
    pub const flags_block_upstream: PadProbeType = @bitCast(@as(c_uint, 130));
    pub const flags_event_both: PadProbeType = @bitCast(@as(c_uint, 192));
    pub const flags_query_both: PadProbeType = @bitCast(@as(c_uint, 1536));
    pub const flags_all_both: PadProbeType = @bitCast(@as(c_uint, 1776));
    pub const flags_scheduling: PadProbeType = @bitCast(@as(c_uint, 12288));
    extern fn gst_pad_probe_type_get_type() usize;
    pub const getGObjectType = gst_pad_probe_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags for the padtemplate
pub const PadTemplateFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    last: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_last: PadTemplateFlags = @bitCast(@as(c_uint, 256));
    extern fn gst_pad_template_flags_get_type() usize;
    pub const getGObjectType = gst_pad_template_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Parsing options.
pub const ParseFlags = packed struct(c_uint) {
    fatal_errors: bool = false,
    no_single_element_bins: bool = false,
    place_in_bin: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: ParseFlags = @bitCast(@as(c_uint, 0));
    pub const flags_fatal_errors: ParseFlags = @bitCast(@as(c_uint, 1));
    pub const flags_no_single_element_bins: ParseFlags = @bitCast(@as(c_uint, 2));
    pub const flags_place_in_bin: ParseFlags = @bitCast(@as(c_uint, 4));
    extern fn gst_parse_flags_get_type() usize;
    pub const getGObjectType = gst_parse_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Pipeline flags
pub const PipelineFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    fixed_clock: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    last: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_fixed_clock: PipelineFlags = @bitCast(@as(c_uint, 524288));
    pub const flags_last: PipelineFlags = @bitCast(@as(c_uint, 8388608));
    extern fn gst_pipeline_flags_get_type() usize;
    pub const getGObjectType = gst_pipeline_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const PluginAPIFlags = packed struct(c_uint) {
    members: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_members: PluginAPIFlags = @bitCast(@as(c_uint, 1));
    extern fn gst_plugin_api_flags_get_type() usize;
    pub const getGObjectType = gst_plugin_api_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags used in connection with `gst.Plugin.addDependency`.
pub const PluginDependencyFlags = packed struct(c_uint) {
    recurse: bool = false,
    paths_are_default_only: bool = false,
    file_name_is_suffix: bool = false,
    file_name_is_prefix: bool = false,
    paths_are_relative_to_exe: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: PluginDependencyFlags = @bitCast(@as(c_uint, 0));
    pub const flags_recurse: PluginDependencyFlags = @bitCast(@as(c_uint, 1));
    pub const flags_paths_are_default_only: PluginDependencyFlags = @bitCast(@as(c_uint, 2));
    pub const flags_file_name_is_suffix: PluginDependencyFlags = @bitCast(@as(c_uint, 4));
    pub const flags_file_name_is_prefix: PluginDependencyFlags = @bitCast(@as(c_uint, 8));
    pub const flags_paths_are_relative_to_exe: PluginDependencyFlags = @bitCast(@as(c_uint, 16));
    extern fn gst_plugin_dependency_flags_get_type() usize;
    pub const getGObjectType = gst_plugin_dependency_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The plugin loading state
pub const PluginFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    cached: bool = false,
    blacklisted: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_cached: PluginFlags = @bitCast(@as(c_uint, 16));
    pub const flags_blacklisted: PluginFlags = @bitCast(@as(c_uint, 32));
    extern fn gst_plugin_flags_get_type() usize;
    pub const getGObjectType = gst_plugin_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.QueryTypeFlags` indicate the aspects of the different `gst.QueryType`
/// values. You can get the type flags of a `gst.QueryType` with the
/// `gst.queryTypeGetFlags` function.
pub const QueryTypeFlags = packed struct(c_uint) {
    upstream: bool = false,
    downstream: bool = false,
    serialized: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_upstream: QueryTypeFlags = @bitCast(@as(c_uint, 1));
    pub const flags_downstream: QueryTypeFlags = @bitCast(@as(c_uint, 2));
    pub const flags_serialized: QueryTypeFlags = @bitCast(@as(c_uint, 4));
    extern fn gst_query_type_flags_get_type() usize;
    pub const getGObjectType = gst_query_type_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The different scheduling flags.
pub const SchedulingFlags = packed struct(c_uint) {
    seekable: bool = false,
    sequential: bool = false,
    bandwidth_limited: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_seekable: SchedulingFlags = @bitCast(@as(c_uint, 1));
    pub const flags_sequential: SchedulingFlags = @bitCast(@as(c_uint, 2));
    pub const flags_bandwidth_limited: SchedulingFlags = @bitCast(@as(c_uint, 4));
    extern fn gst_scheduling_flags_get_type() usize;
    pub const getGObjectType = gst_scheduling_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags to be used with `gst.Element.seek` or `gst.Event.newSeek`. All flags
/// can be used together.
///
/// A non flushing seek might take some time to perform as the currently
/// playing data in the pipeline will not be cleared.
///
/// An accurate seek might be slower for formats that don't have any indexes
/// or timestamp markers in the stream. Specifying this flag might require a
/// complete scan of the file in those cases.
///
/// When performing a segment seek: after the playback of the segment completes,
/// no EOS will be emitted by the element that performed the seek, but a
/// `GST_MESSAGE_SEGMENT_DONE` message will be posted on the bus by the element.
/// When this message is posted, it is possible to send a new seek event to
/// continue playback. With this seek method it is possible to perform seamless
/// looping or simple linear editing.
///
/// When only changing the playback rate and not the direction, the
/// `GST_SEEK_FLAG_INSTANT_RATE_CHANGE` flag can be used for a non-flushing seek
/// to signal that the rate change should be applied immediately. This requires
/// special support in the seek handlers (e.g. demuxers) and any elements
/// synchronizing to the clock, and in general can't work in all cases (for example
/// UDP streaming where the delivery rate is controlled by a remote server). The
/// instant-rate-change mode supports changing the trickmode-related GST_SEEK_ flags,
/// but can't be used in conjunction with other seek flags that affect the new
/// playback position - as the playback position will not be changing.
///
/// When doing fast forward (rate > 1.0) or fast reverse (rate < -1.0) trickmode
/// playback, the `GST_SEEK_FLAG_TRICKMODE` flag can be used to instruct decoders
/// and demuxers to adjust the playback rate by skipping frames. This can improve
/// performance and decrease CPU usage because not all frames need to be decoded.
///
/// Beyond that, the `GST_SEEK_FLAG_TRICKMODE_KEY_UNITS` flag can be used to
/// request that decoders skip all frames except key units, and
/// `GST_SEEK_FLAG_TRICKMODE_NO_AUDIO` flags can be used to request that audio
/// decoders do no decoding at all, and simple output silence.
///
/// The `GST_SEEK_FLAG_SNAP_BEFORE` flag can be used to snap to the previous
/// relevant location, and the `GST_SEEK_FLAG_SNAP_AFTER` flag can be used to
/// select the next relevant location. If `GST_SEEK_FLAG_KEY_UNIT` is specified,
/// the relevant location is a keyframe. If both flags are specified, the nearest
/// of these locations will be selected. If none are specified, the implementation is
/// free to select whichever it wants.
///
/// The before and after here are in running time, so when playing backwards,
/// the next location refers to the one that will played in next, and not the
/// one that is located after in the actual source stream.
///
/// Also see part-seeking.txt in the GStreamer design documentation for more
/// details on the meaning of these flags and the behaviour expected of
/// elements that handle them.
pub const SeekFlags = packed struct(c_uint) {
    flush: bool = false,
    accurate: bool = false,
    key_unit: bool = false,
    segment: bool = false,
    trickmode: bool = false,
    snap_before: bool = false,
    snap_after: bool = false,
    trickmode_key_units: bool = false,
    trickmode_no_audio: bool = false,
    trickmode_forward_predicted: bool = false,
    instant_rate_change: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: SeekFlags = @bitCast(@as(c_uint, 0));
    pub const flags_flush: SeekFlags = @bitCast(@as(c_uint, 1));
    pub const flags_accurate: SeekFlags = @bitCast(@as(c_uint, 2));
    pub const flags_key_unit: SeekFlags = @bitCast(@as(c_uint, 4));
    pub const flags_segment: SeekFlags = @bitCast(@as(c_uint, 8));
    pub const flags_trickmode: SeekFlags = @bitCast(@as(c_uint, 16));
    pub const flags_skip: SeekFlags = @bitCast(@as(c_uint, 16));
    pub const flags_snap_before: SeekFlags = @bitCast(@as(c_uint, 32));
    pub const flags_snap_after: SeekFlags = @bitCast(@as(c_uint, 64));
    pub const flags_snap_nearest: SeekFlags = @bitCast(@as(c_uint, 96));
    pub const flags_trickmode_key_units: SeekFlags = @bitCast(@as(c_uint, 128));
    pub const flags_trickmode_no_audio: SeekFlags = @bitCast(@as(c_uint, 256));
    pub const flags_trickmode_forward_predicted: SeekFlags = @bitCast(@as(c_uint, 512));
    pub const flags_instant_rate_change: SeekFlags = @bitCast(@as(c_uint, 1024));
    extern fn gst_seek_flags_get_type() usize;
    pub const getGObjectType = gst_seek_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flags for the GstSegment structure. Currently mapped to the corresponding
/// values of the seek flags.
pub const SegmentFlags = packed struct(c_uint) {
    reset: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    segment: bool = false,
    trickmode: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    trickmode_key_units: bool = false,
    trickmode_no_audio: bool = false,
    trickmode_forward_predicted: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: SegmentFlags = @bitCast(@as(c_uint, 0));
    pub const flags_reset: SegmentFlags = @bitCast(@as(c_uint, 1));
    pub const flags_trickmode: SegmentFlags = @bitCast(@as(c_uint, 16));
    pub const flags_skip: SegmentFlags = @bitCast(@as(c_uint, 16));
    pub const flags_segment: SegmentFlags = @bitCast(@as(c_uint, 8));
    pub const flags_trickmode_key_units: SegmentFlags = @bitCast(@as(c_uint, 128));
    pub const flags_trickmode_forward_predicted: SegmentFlags = @bitCast(@as(c_uint, 512));
    pub const flags_trickmode_no_audio: SegmentFlags = @bitCast(@as(c_uint, 256));
    extern fn gst_segment_flags_get_type() usize;
    pub const getGObjectType = gst_segment_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const SerializeFlags = packed struct(c_uint) {
    backward_compat: bool = false,
    strict: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: SerializeFlags = @bitCast(@as(c_uint, 0));
    pub const flags_backward_compat: SerializeFlags = @bitCast(@as(c_uint, 1));
    pub const flags_strict: SerializeFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_serialize_flags_get_type() usize;
    pub const getGObjectType = gst_serialize_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const StackTraceFlags = packed struct(c_uint) {
    full: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: StackTraceFlags = @bitCast(@as(c_uint, 0));
    pub const flags_full: StackTraceFlags = @bitCast(@as(c_uint, 1));
    extern fn gst_stack_trace_flags_get_type() usize;
    pub const getGObjectType = gst_stack_trace_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const StreamFlags = packed struct(c_uint) {
    sparse: bool = false,
    select: bool = false,
    unselect: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: StreamFlags = @bitCast(@as(c_uint, 0));
    pub const flags_sparse: StreamFlags = @bitCast(@as(c_uint, 1));
    pub const flags_select: StreamFlags = @bitCast(@as(c_uint, 2));
    pub const flags_unselect: StreamFlags = @bitCast(@as(c_uint, 4));
    extern fn gst_stream_flags_get_type() usize;
    pub const getGObjectType = gst_stream_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gst.StreamType` describes a high level classification set for
/// flows of data in `gst.Stream` objects.
///
/// Note that this is a flag, and therefore users should not assume it
/// will be a single value. Do not use the equality operator for checking
/// whether a stream is of a certain type.
pub const StreamType = packed struct(c_uint) {
    unknown: bool = false,
    audio: bool = false,
    video: bool = false,
    container: bool = false,
    text: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_unknown: StreamType = @bitCast(@as(c_uint, 1));
    pub const flags_audio: StreamType = @bitCast(@as(c_uint, 2));
    pub const flags_video: StreamType = @bitCast(@as(c_uint, 4));
    pub const flags_container: StreamType = @bitCast(@as(c_uint, 8));
    pub const flags_text: StreamType = @bitCast(@as(c_uint, 16));
    /// Get a descriptive string for a given `gst.StreamType`
    extern fn gst_stream_type_get_name(p_stype: gst.StreamType) [*:0]const u8;
    pub const getName = gst_stream_type_get_name;

    extern fn gst_stream_type_get_type() usize;
    pub const getGObjectType = gst_stream_type_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Flag that describe the value. These flags help applications processing the
/// logs to understand the values.
pub const TracerValueFlags = packed struct(c_uint) {
    optional: bool = false,
    aggregated: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: TracerValueFlags = @bitCast(@as(c_uint, 0));
    pub const flags_optional: TracerValueFlags = @bitCast(@as(c_uint, 1));
    pub const flags_aggregated: TracerValueFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_tracer_value_flags_get_type() usize;
    pub const getGObjectType = gst_tracer_value_flags_get_type;

    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Calculates the linear regression of the values `xy` and places the
/// result in `m_num`, `m_denom`, `b` and `xbase`, representing the function
///   y(x) = m_num/m_denom * (x - xbase) + b
/// that has the least-square distance from all points `x` and `y`.
///
/// `r_squared` will contain the remaining error.
///
/// If `temp` is not `NULL`, it will be used as temporary space for the function,
/// in which case the function works without any allocation at all. If `temp` is
/// `NULL`, an allocation will take place. `temp` should have at least the same
/// amount of memory allocated as `xy`, i.e. 2*n*sizeof(GstClockTime).
///
/// > This function assumes (x,y) values with reasonable large differences
/// > between them. It will not calculate the exact results if the differences
/// > between neighbouring values are too small due to not being able to
/// > represent sub-integer values during the calculations.
extern fn gst_calculate_linear_regression(p_xy: *const gst.ClockTime, p_temp: *gst.ClockTime, p_n: c_uint, p_m_num: *gst.ClockTime, p_m_denom: *gst.ClockTime, p_b: *gst.ClockTime, p_xbase: *gst.ClockTime, p_r_squared: *f64) c_int;
pub const calculateLinearRegression = gst_calculate_linear_regression;

/// Clears a reference to a `gst.Buffer`.
///
/// `buf_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the buffer is decreased and the pointer is set to `NULL`.
extern fn gst_clear_buffer(p_buf_ptr: **gst.Buffer) void;
pub const clearBuffer = gst_clear_buffer;

/// Clears a reference to a `gst.BufferList`.
///
/// `list_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the list is decreased and the pointer is set to `NULL`.
extern fn gst_clear_buffer_list(p_list_ptr: **gst.BufferList) void;
pub const clearBufferList = gst_clear_buffer_list;

/// Clears a reference to a `gst.Caps`.
///
/// `caps_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the caps is decreased and the pointer is set to `NULL`.
extern fn gst_clear_caps(p_caps_ptr: **gst.Caps) void;
pub const clearCaps = gst_clear_caps;

/// Clears a reference to a `gst.Context`.
///
/// `context_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the context is decreased and the pointer is set to `NULL`.
extern fn gst_clear_context(p_context_ptr: **gst.Context) void;
pub const clearContext = gst_clear_context;

/// Clears a reference to a `gst.Event`.
///
/// `event_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the event is decreased and the pointer is set to `NULL`.
extern fn gst_clear_event(p_event_ptr: **gst.Event) void;
pub const clearEvent = gst_clear_event;

/// Clears a reference to a `gst.Message`.
///
/// `msg_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the message is decreased and the pointer is set to `NULL`.
extern fn gst_clear_message(p_msg_ptr: **gst.Message) void;
pub const clearMessage = gst_clear_message;

/// Clears a reference to a `gst.MiniObject`.
///
/// `object_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing.
/// Otherwise, the reference count of the object is decreased using
/// `gst.MiniObject.unref` and the pointer is set to `NULL`.
///
/// A macro is also included that allows this function to be used without
/// pointer casts.
extern fn gst_clear_mini_object(p_object_ptr: **gst.MiniObject) void;
pub const clearMiniObject = gst_clear_mini_object;

/// Clears a reference to a `gst.Object`.
///
/// `object_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing.
/// Otherwise, the reference count of the object is decreased using
/// `gst.Object.unref` and the pointer is set to `NULL`.
///
/// A macro is also included that allows this function to be used without
/// pointer casts.
extern fn gst_clear_object(p_object_ptr: **gst.Object) void;
pub const clearObject = gst_clear_object;

/// Clears a reference to a `gst.Promise`.
///
/// `promise_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the promise is decreased and the pointer is set to `NULL`.
extern fn gst_clear_promise(p_promise_ptr: **gst.Promise) void;
pub const clearPromise = gst_clear_promise;

/// Clears a reference to a `gst.Query`.
///
/// `query_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the query is decreased and the pointer is set to `NULL`.
extern fn gst_clear_query(p_query_ptr: **gst.Query) void;
pub const clearQuery = gst_clear_query;

/// Clears a reference to a `gst.Sample`
///
/// `sample_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the sample is decreased and the pointer is set to `NULL`.
extern fn gst_clear_sample(p_sample_ptr: **gst.Sample) void;
pub const clearSample = gst_clear_sample;

/// Clears a reference to a `gst.Structure`.
///
/// `structure_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing.
/// Otherwise, the structure is free'd using `gst.Structure.free` and the
/// pointer is set to `NULL`.
///
/// A macro is also included that allows this function to be used without
/// pointer casts.
extern fn gst_clear_structure(p_structure_ptr: **gst.Structure) void;
pub const clearStructure = gst_clear_structure;

/// Clears a reference to a `gst.TagList`.
///
/// `taglist_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the taglist is decreased and the pointer is set to `NULL`.
extern fn gst_clear_tag_list(p_taglist_ptr: **gst.TagList) void;
pub const clearTagList = gst_clear_tag_list;

/// Clears a reference to a `gst.Uri`.
///
/// `uri_ptr` must not be `NULL`.
///
/// If the reference is `NULL` then this function does nothing. Otherwise, the
/// reference count of the uri is decreased and the pointer is set to `NULL`.
extern fn gst_clear_uri(p_uri_ptr: **gst.Uri) void;
pub const clearUri = gst_clear_uri;

/// Adds the logging function to the list of logging functions.
/// Be sure to use `G_GNUC_NO_INSTRUMENT` on that function, it is needed.
extern fn gst_debug_add_log_function(p_func: gst.LogFunction, p_user_data: ?*anyopaque, p_notify: ?glib.DestroyNotify) void;
pub const debugAddLogFunction = gst_debug_add_log_function;

/// Adds a memory ringbuffer based debug logger that stores up to
/// `max_size_per_thread` bytes of logs per thread and times out threads after
/// `thread_timeout` seconds of inactivity.
///
/// Logs can be fetched with `gst.debugRingBufferLoggerGetLogs` and the
/// logger can be removed again with `gst.debugRemoveRingBufferLogger`.
/// Only one logger at a time is possible.
extern fn gst_debug_add_ring_buffer_logger(p_max_size_per_thread: c_uint, p_thread_timeout: c_uint) void;
pub const debugAddRingBufferLogger = gst_debug_add_ring_buffer_logger;

/// To aid debugging applications one can use this method to obtain the whole
/// network of gstreamer elements that form the pipeline into a dot file.
/// This data can be processed with graphviz to get an image.
extern fn gst_debug_bin_to_dot_data(p_bin: *gst.Bin, p_details: gst.DebugGraphDetails) [*:0]u8;
pub const debugBinToDotData = gst_debug_bin_to_dot_data;

/// To aid debugging applications one can use this method to write out the whole
/// network of gstreamer elements that form the pipeline into a dot file.
/// This file can be processed with graphviz to get an image.
///
/// ``` shell
///  dot -Tpng -oimage.png graph_lowlevel.dot
/// ```
extern fn gst_debug_bin_to_dot_file(p_bin: *gst.Bin, p_details: gst.DebugGraphDetails, p_file_name: [*:0]const u8) void;
pub const debugBinToDotFile = gst_debug_bin_to_dot_file;

/// This works like `gst.debugBinToDotFile`, but adds the current timestamp
/// to the filename, so that it can be used to take multiple snapshots.
extern fn gst_debug_bin_to_dot_file_with_ts(p_bin: *gst.Bin, p_details: gst.DebugGraphDetails, p_file_name: [*:0]const u8) void;
pub const debugBinToDotFileWithTs = gst_debug_bin_to_dot_file_with_ts;

/// Constructs a string that can be used for getting the desired color in color
/// terminals.
/// You need to free the string after use.
extern fn gst_debug_construct_term_color(p_colorinfo: c_uint) [*:0]u8;
pub const debugConstructTermColor = gst_debug_construct_term_color;

/// Constructs an integer that can be used for getting the desired color in
/// windows' terminals (cmd.exe). As there is no mean to underline, we simply
/// ignore this attribute.
///
/// This function returns 0 on non-windows machines.
extern fn gst_debug_construct_win_color(p_colorinfo: c_uint) c_int;
pub const debugConstructWinColor = gst_debug_construct_win_color;

/// Returns a snapshot of a all categories that are currently in use . This list
/// may change anytime.
/// The caller has to free the list after use.
extern fn gst_debug_get_all_categories() *glib.SList;
pub const debugGetAllCategories = gst_debug_get_all_categories;

/// Changes the coloring mode for debug output.
extern fn gst_debug_get_color_mode() gst.DebugColorMode;
pub const debugGetColorMode = gst_debug_get_color_mode;

/// Returns the default threshold that is used for new categories.
extern fn gst_debug_get_default_threshold() gst.DebugLevel;
pub const debugGetDefaultThreshold = gst_debug_get_default_threshold;

extern fn gst_debug_get_stack_trace(p_flags: gst.StackTraceFlags) ?[*:0]u8;
pub const debugGetStackTrace = gst_debug_get_stack_trace;

/// Checks if debugging output is activated.
extern fn gst_debug_is_active() c_int;
pub const debugIsActive = gst_debug_is_active;

/// Checks if the debugging output should be colored.
extern fn gst_debug_is_colored() c_int;
pub const debugIsColored = gst_debug_is_colored;

/// Logs the given message using the currently registered debugging handlers.
extern fn gst_debug_log(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: ?*gobject.Object, p_format: [*:0]const u8, ...) void;
pub const debugLog = gst_debug_log;

/// The default logging handler used by GStreamer. Logging functions get called
/// whenever a macro like GST_DEBUG or similar is used. By default this function
/// is setup to output the message and additional info to stderr (or the log file
/// specified via the GST_DEBUG_FILE environment variable) as received via
/// `user_data`.
///
/// You can add other handlers by using `gst.debugAddLogFunction`.
/// And you can remove this handler by calling
/// gst_debug_remove_log_function(gst_debug_log_default);
extern fn gst_debug_log_default(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: ?*gobject.Object, p_message: *gst.DebugMessage, p_user_data: ?*anyopaque) void;
pub const debugLogDefault = gst_debug_log_default;

/// Returns the string representation for the specified debug log message
/// formatted in the same way as `gst.debugLogDefault` (the default handler),
/// without color. The purpose is to make it easy for custom log output
/// handlers to get a log output that is identical to what the default handler
/// would write out.
extern fn gst_debug_log_get_line(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: ?*gobject.Object, p_message: *gst.DebugMessage) [*:0]u8;
pub const debugLogGetLine = gst_debug_log_get_line;

/// Logs the given message using the currently registered debugging handlers.
extern fn gst_debug_log_id(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_id: ?[*:0]const u8, p_format: [*:0]const u8, ...) void;
pub const debugLogId = gst_debug_log_id;

/// Logs the given message using the currently registered debugging handlers.
extern fn gst_debug_log_id_literal(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_id: ?[*:0]const u8, p_message_string: [*:0]const u8) void;
pub const debugLogIdLiteral = gst_debug_log_id_literal;

/// Logs the given message using the currently registered debugging handlers.
extern fn gst_debug_log_id_valist(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_id: ?[*:0]const u8, p_format: [*:0]const u8, p_args: std.builtin.VaList) void;
pub const debugLogIdValist = gst_debug_log_id_valist;

/// Logs the given message using the currently registered debugging handlers.
extern fn gst_debug_log_literal(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: ?*gobject.Object, p_message_string: [*:0]const u8) void;
pub const debugLogLiteral = gst_debug_log_literal;

/// Logs the given message using the currently registered debugging handlers.
extern fn gst_debug_log_valist(p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: ?*gobject.Object, p_format: [*:0]const u8, p_args: std.builtin.VaList) void;
pub const debugLogValist = gst_debug_log_valist;

/// Returns a string that represents `ptr`. This is safe to call with
/// `gst.Structure`, `gst.CapsFeatures`, `gst.MiniObject` s (e.g. `gst.Caps`,
/// `gst.Buffer` or `gst.Message`), and `GObjects` (e.g. `gst.Element` or `gst.Pad`).
///
/// The string representation is meant to be used for debugging purposes and
/// might change between GStreamer versions.
///
/// Passing other kind of pointers might or might not work and is generally
/// unsafe to do.
extern fn gst_debug_print_object(p_ptr: ?*const anyopaque) [*:0]u8;
pub const debugPrintObject = gst_debug_print_object;

/// Returns a string that represents `segments`.
///
/// The string representation is meant to be used for debugging purposes and
/// might change between GStreamer versions.
extern fn gst_debug_print_segment(p_segment: ?*const gst.Segment) [*:0]u8;
pub const debugPrintSegment = gst_debug_print_segment;

/// If libunwind, glibc backtrace or DbgHelp are present
/// a stack trace is printed.
extern fn gst_debug_print_stack_trace() void;
pub const debugPrintStackTrace = gst_debug_print_stack_trace;

/// Removes all registered instances of the given logging functions.
extern fn gst_debug_remove_log_function(p_func: ?gst.LogFunction) c_uint;
pub const debugRemoveLogFunction = gst_debug_remove_log_function;

/// Removes all registered instances of log functions with the given user data.
extern fn gst_debug_remove_log_function_by_data(p_data: ?*anyopaque) c_uint;
pub const debugRemoveLogFunctionByData = gst_debug_remove_log_function_by_data;

/// Removes any previously added ring buffer logger with
/// `gst.debugAddRingBufferLogger`.
extern fn gst_debug_remove_ring_buffer_logger() void;
pub const debugRemoveRingBufferLogger = gst_debug_remove_ring_buffer_logger;

/// Fetches the current logs per thread from the ring buffer logger. See
/// `gst.debugAddRingBufferLogger` for details.
extern fn gst_debug_ring_buffer_logger_get_logs() [*][*:0]u8;
pub const debugRingBufferLoggerGetLogs = gst_debug_ring_buffer_logger_get_logs;

/// If activated, debugging messages are sent to the debugging
/// handlers.
/// It makes sense to deactivate it for speed issues.
/// > This function is not threadsafe. It makes sense to only call it
/// during initialization.
extern fn gst_debug_set_active(p_active: c_int) void;
pub const debugSetActive = gst_debug_set_active;

/// Changes the coloring mode for debug output.
///
/// This function may be called before `gst.init`.
extern fn gst_debug_set_color_mode(p_mode: gst.DebugColorMode) void;
pub const debugSetColorMode = gst_debug_set_color_mode;

/// Changes the coloring mode for debug output.
///
/// This function may be called before `gst.init`.
extern fn gst_debug_set_color_mode_from_string(p_mode: [*:0]const u8) void;
pub const debugSetColorModeFromString = gst_debug_set_color_mode_from_string;

/// Sets or unsets the use of coloured debugging output.
/// Same as gst_debug_set_color_mode () with the argument being
/// being GST_DEBUG_COLOR_MODE_ON or GST_DEBUG_COLOR_MODE_OFF.
///
/// This function may be called before `gst.init`.
extern fn gst_debug_set_colored(p_colored: c_int) void;
pub const debugSetColored = gst_debug_set_colored;

/// Sets the default threshold to the given level and updates all categories to
/// use this threshold.
///
/// This function may be called before `gst.init`.
extern fn gst_debug_set_default_threshold(p_level: gst.DebugLevel) void;
pub const debugSetDefaultThreshold = gst_debug_set_default_threshold;

/// Sets all categories which match the given glob style pattern to the given
/// level.
extern fn gst_debug_set_threshold_for_name(p_name: [*:0]const u8, p_level: gst.DebugLevel) void;
pub const debugSetThresholdForName = gst_debug_set_threshold_for_name;

/// Sets the debug logging wanted in the same form as with the GST_DEBUG
/// environment variable. You can use wildcards such as `*`, but note that
/// the order matters when you use wild cards, e.g. `foosrc:6,*src:3,*:2` sets
/// everything to log level 2.
extern fn gst_debug_set_threshold_from_string(p_list: [*:0]const u8, p_reset: c_int) void;
pub const debugSetThresholdFromString = gst_debug_set_threshold_from_string;

/// Resets all categories with the given name back to the default level.
extern fn gst_debug_unset_threshold_for_name(p_name: [*:0]const u8) void;
pub const debugUnsetThresholdForName = gst_debug_unset_threshold_for_name;

/// Clean up any resources created by GStreamer in `gst.init`.
///
/// It is normally not needed to call this function in a normal application
/// as the resources will automatically be freed when the program terminates.
/// This function is therefore mostly used by testsuites and other memory
/// profiling tools.
///
/// After this call GStreamer (including this method) should not be used anymore.
extern fn gst_deinit() void;
pub const deinit = gst_deinit;

/// Registers a new `gst.DynamicTypeFactory` in the registry
extern fn gst_dynamic_type_register(p_plugin: *gst.Plugin, p_type: usize) c_int;
pub const dynamicTypeRegister = gst_dynamic_type_register;

/// Get a string describing the error message in the current locale.
extern fn gst_error_get_message(p_domain: glib.Quark, p_code: c_int) [*:0]u8;
pub const errorGetMessage = gst_error_get_message;

/// Similar to `glib.filenameToUri`, but attempts to handle relative file paths
/// as well. Before converting `filename` into an URI, it will be prefixed by
/// the current working directory if it is a relative path, and then the path
/// will be canonicalised so that it doesn't contain any './' or '../' segments.
///
/// On Windows `filename` should be in UTF-8 encoding.
extern fn gst_filename_to_uri(p_filename: [*:0]const u8, p_error: ?*?*glib.Error) ?[*:0]u8;
pub const filenameToUri = gst_filename_to_uri;

/// Gets a string representing the given flow return.
extern fn gst_flow_get_name(p_ret: gst.FlowReturn) [*:0]const u8;
pub const flowGetName = gst_flow_get_name;

/// Get the unique quark for the given GstFlowReturn.
extern fn gst_flow_to_quark(p_ret: gst.FlowReturn) glib.Quark;
pub const flowToQuark = gst_flow_to_quark;

/// See if the given format is inside the format array.
extern fn gst_formats_contains(p_formats: [*]const gst.Format, p_format: gst.Format) c_int;
pub const formatsContains = gst_formats_contains;

/// This helper is mostly helpful for plugins that need to
/// inspect the folder of the main executable to determine
/// their set of features.
///
/// When a plugin is initialized from the gst-plugin-scanner
/// external process, the returned path will be the same as from the
/// parent process.
extern fn gst_get_main_executable_path() ?[*:0]const u8;
pub const getMainExecutablePath = gst_get_main_executable_path;

/// Allocates, fills and returns a 0-terminated string from the printf style
/// `format` string and corresponding arguments.
///
/// See `gst.infoVasprintf` for when this function is required.
///
/// Free with `glib.free`.
extern fn gst_info_strdup_printf(p_format: [*:0]const u8, ...) ?[*:0]u8;
pub const infoStrdupPrintf = gst_info_strdup_printf;

/// Allocates, fills and returns a null terminated string from the printf style
/// `format` string and `args`.
///
/// See `gst.infoVasprintf` for when this function is required.
///
/// Free with `glib.free`.
extern fn gst_info_strdup_vprintf(p_format: [*:0]const u8, p_args: std.builtin.VaList) ?[*:0]u8;
pub const infoStrdupVprintf = gst_info_strdup_vprintf;

/// Allocates and fills a string large enough (including the terminating null
/// byte) to hold the specified printf style `format` and `args`.
///
/// This function deals with the GStreamer specific printf specifiers
/// `GST_PTR_FORMAT` and `GST_SEGMENT_FORMAT`.  If you do not have these specifiers
/// in your `format` string, you do not need to use this function and can use
/// alternatives such as `glib.vasprintf`.
///
/// Free `result` with `glib.free`.
extern fn gst_info_vasprintf(p_result: *[*:0]u8, p_format: [*:0]const u8, p_args: std.builtin.VaList) c_int;
pub const infoVasprintf = gst_info_vasprintf;

/// Initializes the GStreamer library, setting up internal path lists,
/// registering built-in elements, and loading standard plugins.
///
/// Unless the plugin registry is disabled at compile time, the registry will be
/// loaded. By default this will also check if the registry cache needs to be
/// updated and rescan all plugins if needed. See `gst.updateRegistry` for
/// details and section
/// <link linkend="gst-running">Running GStreamer Applications</link>
/// for how to disable automatic registry updates.
///
/// WARNING: This function will terminate your program if it was unable to
/// initialize GStreamer for some reason. If you want your program to fall back,
/// use `gst.initCheck` instead.
extern fn gst_init(p_argc: ?*c_int, p_argv: ?*[*][*:0]u8) void;
pub const init = gst_init;

/// Initializes the GStreamer library, setting up internal path lists,
/// registering built-in elements, and loading standard plugins.
///
/// This function will return `FALSE` if GStreamer could not be initialized
/// for some reason.  If you want your program to fail fatally,
/// use `gst.init` instead.
extern fn gst_init_check(p_argc: ?*c_int, p_argv: ?*[*][*:0]u8, p_error: ?*?*glib.Error) c_int;
pub const initCheck = gst_init_check;

/// Returns a `glib.OptionGroup` with GStreamer's argument specifications. The
/// group is set up to use standard GOption callbacks, so when using this
/// group in combination with GOption parsing methods, all argument parsing
/// and initialization is automated.
///
/// This function is useful if you want to integrate GStreamer with other
/// libraries that use GOption (see `glib.OptionContext.addGroup` ).
///
/// If you use this function, you should make sure you initialise the GLib
/// threading system as one of the very first things in your program
/// (see the example at the beginning of this section).
extern fn gst_init_get_option_group() ?*glib.OptionGroup;
pub const initGetOptionGroup = gst_init_get_option_group;

/// Checks if `obj` is a `gst.CapsFeatures`
extern fn gst_is_caps_features(p_obj: ?*const anyopaque) c_int;
pub const isCapsFeatures = gst_is_caps_features;

/// Use this function to check if GStreamer has been initialized with `gst.init`
/// or `gst.initCheck`.
extern fn gst_is_initialized() c_int;
pub const isInitialized = gst_is_initialized;

/// Create a `gst.Structure` to be used with `gst.Element.messageFullWithDetails`.
/// `NULL` terminator required.
extern fn gst_make_element_message_details(p_name: [*:0]const u8, ...) *gst.Structure;
pub const makeElementMessageDetails = gst_make_element_message_details;

/// This function creates a GstArray GParamSpec for use by objects/elements
/// that want to expose properties of GstArray type. This function is
/// typically * used in connection with `gobject.ObjectClass.installProperty` in a
/// GObjects's instance_init function.
extern fn gst_param_spec_array(p_name: [*:0]const u8, p_nick: [*:0]const u8, p_blurb: [*:0]const u8, p_element_spec: *gobject.ParamSpec, p_flags: gobject.ParamFlags) *gobject.ParamSpec;
pub const paramSpecArray = gst_param_spec_array;

/// This function creates a fraction GParamSpec for use by objects/elements
/// that want to expose properties of fraction type. This function is typically
/// used in connection with `gobject.ObjectClass.installProperty` in a GObjects's
/// instance_init function.
extern fn gst_param_spec_fraction(p_name: [*:0]const u8, p_nick: [*:0]const u8, p_blurb: [*:0]const u8, p_min_num: c_int, p_min_denom: c_int, p_max_num: c_int, p_max_denom: c_int, p_default_num: c_int, p_default_denom: c_int, p_flags: gobject.ParamFlags) ?*gobject.ParamSpec;
pub const paramSpecFraction = gst_param_spec_fraction;

extern fn gst_parent_buffer_meta_api_get_type() usize;
pub const parentBufferMetaApiGetType = gst_parent_buffer_meta_api_get_type;

/// This is a convenience wrapper around `gst.parseLaunch` to create a
/// `gst.Bin` from a gst-launch-style pipeline description. See
/// `gst.parseLaunch` and the gst-launch man page for details about the
/// syntax. Ghost pads on the bin for unlinked source or sink pads
/// within the bin can automatically be created (but only a maximum of
/// one ghost pad for each direction will be created; if you expect
/// multiple unlinked source pads or multiple unlinked sink pads
/// and want them all ghosted, you will have to create the ghost pads
/// yourself).
extern fn gst_parse_bin_from_description(p_bin_description: [*:0]const u8, p_ghost_unlinked_pads: c_int, p_error: ?*?*glib.Error) ?*gst.Bin;
pub const parseBinFromDescription = gst_parse_bin_from_description;

/// This is a convenience wrapper around `gst.parseLaunch` to create a
/// `gst.Bin` from a gst-launch-style pipeline description. See
/// `gst.parseLaunch` and the gst-launch man page for details about the
/// syntax. Ghost pads on the bin for unlinked source or sink pads
/// within the bin can automatically be created (but only a maximum of
/// one ghost pad for each direction will be created; if you expect
/// multiple unlinked source pads or multiple unlinked sink pads
/// and want them all ghosted, you will have to create the ghost pads
/// yourself).
extern fn gst_parse_bin_from_description_full(p_bin_description: [*:0]const u8, p_ghost_unlinked_pads: c_int, p_context: ?*gst.ParseContext, p_flags: gst.ParseFlags, p_error: ?*?*glib.Error) ?*gst.Element;
pub const parseBinFromDescriptionFull = gst_parse_bin_from_description_full;

/// Create a new pipeline based on command line syntax.
/// Please note that you might get a return value that is not `NULL` even though
/// the `error` is set. In this case there was a recoverable parsing error and you
/// can try to play the pipeline.
///
/// To create a sub-pipeline (bin) for embedding into an existing pipeline
/// use `gst.parseBinFromDescription`.
extern fn gst_parse_launch(p_pipeline_description: [*:0]const u8, p_error: ?*?*glib.Error) ?*gst.Element;
pub const parseLaunch = gst_parse_launch;

/// Create a new pipeline based on command line syntax.
/// Please note that you might get a return value that is not `NULL` even though
/// the `error` is set. In this case there was a recoverable parsing error and you
/// can try to play the pipeline.
///
/// To create a sub-pipeline (bin) for embedding into an existing pipeline
/// use `gst.parseBinFromDescriptionFull`.
extern fn gst_parse_launch_full(p_pipeline_description: [*:0]const u8, p_context: ?*gst.ParseContext, p_flags: gst.ParseFlags, p_error: ?*?*glib.Error) ?*gst.Element;
pub const parseLaunchFull = gst_parse_launch_full;

/// Create a new element based on command line syntax.
/// `error` will contain an error message if an erroneous pipeline is specified.
/// An error does not mean that the pipeline could not be constructed.
extern fn gst_parse_launchv(p_argv: [*][*:0]const u8, p_error: ?*?*glib.Error) ?*gst.Element;
pub const parseLaunchv = gst_parse_launchv;

/// Create a new element based on command line syntax.
/// `error` will contain an error message if an erroneous pipeline is specified.
/// An error does not mean that the pipeline could not be constructed.
extern fn gst_parse_launchv_full(p_argv: [*][*:0]const u8, p_context: ?*gst.ParseContext, p_flags: gst.ParseFlags, p_error: ?*?*glib.Error) ?*gst.Element;
pub const parseLaunchvFull = gst_parse_launchv_full;

/// Outputs a formatted message via the GLib print handler. The default print
/// handler simply outputs the message to stdout.
///
/// This function will not append a new-line character at the end, unlike
/// `gst.println` which will.
///
/// All strings must be in ASCII or UTF-8 encoding.
///
/// This function differs from `glib.print` in that it supports all the additional
/// printf specifiers that are supported by GStreamer's debug logging system,
/// such as `GST_PTR_FORMAT` and `GST_SEGMENT_FORMAT`.
///
/// This function is primarily for printing debug output.
extern fn gst_print(p_format: [*:0]const u8, ...) void;
pub const print = gst_print;

/// Outputs a formatted message via the GLib error message handler. The default
/// handler simply outputs the message to stderr.
///
/// This function will not append a new-line character at the end, unlike
/// `gst.printerrln` which will.
///
/// All strings must be in ASCII or UTF-8 encoding.
///
/// This function differs from `glib.printerr` in that it supports the additional
/// printf specifiers that are supported by GStreamer's debug logging system,
/// such as `GST_PTR_FORMAT` and `GST_SEGMENT_FORMAT`.
///
/// This function is primarily for printing debug output.
extern fn gst_printerr(p_format: [*:0]const u8, ...) void;
pub const printerr = gst_printerr;

/// Outputs a formatted message via the GLib error message handler. The default
/// handler simply outputs the message to stderr.
///
/// This function will append a new-line character at the end, unlike
/// `gst.printerr` which will not.
///
/// All strings must be in ASCII or UTF-8 encoding.
///
/// This function differs from `glib.printerr` in that it supports the additional
/// printf specifiers that are supported by GStreamer's debug logging system,
/// such as `GST_PTR_FORMAT` and `GST_SEGMENT_FORMAT`.
///
/// This function is primarily for printing debug output.
extern fn gst_printerrln(p_format: [*:0]const u8, ...) void;
pub const printerrln = gst_printerrln;

/// Outputs a formatted message via the GLib print handler. The default print
/// handler simply outputs the message to stdout.
///
/// This function will append a new-line character at the end, unlike
/// `gst.print` which will not.
///
/// All strings must be in ASCII or UTF-8 encoding.
///
/// This function differs from `glib.print` in that it supports all the additional
/// printf specifiers that are supported by GStreamer's debug logging system,
/// such as `GST_PTR_FORMAT` and `GST_SEGMENT_FORMAT`.
///
/// This function is primarily for printing debug output.
extern fn gst_println(p_format: [*:0]const u8, ...) void;
pub const println = gst_println;

/// Iterates the supplied list of UUIDs and checks the GstRegistry for
/// all the decryptors supporting one of the supplied UUIDs.
extern fn gst_protection_filter_systems_by_available_decryptors(p_system_identifiers: [*][*:0]const u8) ?[*][*:0]u8;
pub const protectionFilterSystemsByAvailableDecryptors = gst_protection_filter_systems_by_available_decryptors;

extern fn gst_protection_meta_api_get_type() usize;
pub const protectionMetaApiGetType = gst_protection_meta_api_get_type;

/// Iterates the supplied list of UUIDs and checks the GstRegistry for
/// an element that supports one of the supplied UUIDs. If more than one
/// element matches, the system ID of the highest ranked element is selected.
extern fn gst_protection_select_system(p_system_identifiers: [*][*:0]const u8) ?[*:0]const u8;
pub const protectionSelectSystem = gst_protection_select_system;

extern fn gst_reference_timestamp_meta_api_get_type() usize;
pub const referenceTimestampMetaApiGetType = gst_reference_timestamp_meta_api_get_type;

/// Some functions in the GStreamer core might install a custom SIGSEGV handler
/// to better catch and report errors to the application. Currently this feature
/// is enabled by default when loading plugins.
///
/// Applications might want to disable this behaviour with the
/// `gst.segtrapSetEnabled` function. This is typically done if the application
/// wants to install its own handler without GStreamer interfering.
extern fn gst_segtrap_is_enabled() c_int;
pub const segtrapIsEnabled = gst_segtrap_is_enabled;

/// Applications might want to disable/enable the SIGSEGV handling of
/// the GStreamer core. See `gst.segtrapIsEnabled` for more information.
extern fn gst_segtrap_set_enabled(p_enabled: c_int) void;
pub const segtrapSetEnabled = gst_segtrap_set_enabled;

/// Checks if the given type is already registered.
extern fn gst_tag_exists(p_tag: [*:0]const u8) c_int;
pub const tagExists = gst_tag_exists;

/// Returns the human-readable description of this tag, You must not change or
/// free this string.
extern fn gst_tag_get_description(p_tag: [*:0]const u8) [*:0]const u8;
pub const tagGetDescription = gst_tag_get_description;

/// Gets the flag of `tag`.
extern fn gst_tag_get_flag(p_tag: [*:0]const u8) gst.TagFlag;
pub const tagGetFlag = gst_tag_get_flag;

/// Returns the human-readable name of this tag, You must not change or free
/// this string.
extern fn gst_tag_get_nick(p_tag: [*:0]const u8) [*:0]const u8;
pub const tagGetNick = gst_tag_get_nick;

/// Gets the `gobject.Type` used for this tag.
extern fn gst_tag_get_type(p_tag: [*:0]const u8) usize;
pub const tagGetType = gst_tag_get_type;

/// Checks if the given tag is fixed. A fixed tag can only contain one value.
/// Unfixed tags can contain lists of values.
extern fn gst_tag_is_fixed(p_tag: [*:0]const u8) c_int;
pub const tagIsFixed = gst_tag_is_fixed;

/// This is a convenience function for the func argument of `gst.tagRegister`.
/// It concatenates all given strings using a comma. The tag must be registered
/// as a G_TYPE_STRING or this function will fail.
extern fn gst_tag_merge_strings_with_comma(p_dest: *gobject.Value, p_src: *const gobject.Value) void;
pub const tagMergeStringsWithComma = gst_tag_merge_strings_with_comma;

/// This is a convenience function for the func argument of `gst.tagRegister`.
/// It creates a copy of the first value from the list.
extern fn gst_tag_merge_use_first(p_dest: *gobject.Value, p_src: *const gobject.Value) void;
pub const tagMergeUseFirst = gst_tag_merge_use_first;

/// Registers a new tag type for the use with GStreamer's type system. If a type
/// with that name is already registered, that one is used.
/// The old registration may have used a different type however. So don't rely
/// on your supplied values.
///
/// Important: if you do not supply a merge function the implication will be
/// that there can only be one single value for this tag in a tag list and
/// any additional values will silently be discarded when being added (unless
/// `GST_TAG_MERGE_REPLACE`, `GST_TAG_MERGE_REPLACE_ALL`, or
/// `GST_TAG_MERGE_PREPEND` is used as merge mode, in which case the new
/// value will replace the old one in the list).
///
/// The merge function will be called from `gst.tagListCopyValue` when
/// it is required that one or more values for a tag be condensed into
/// one single value. This may happen from `gst.TagList.getString`,
/// `gst.TagList.getInt`, `gst.TagList.getDouble` etc. What will happen
/// exactly in that case depends on how the tag was registered and if a
/// merge function was supplied and if so which one.
///
/// Two default merge functions are provided: `gst.tagMergeUseFirst` and
/// `gst.tagMergeStringsWithComma`.
extern fn gst_tag_register(p_name: [*:0]const u8, p_flag: gst.TagFlag, p_type: usize, p_nick: [*:0]const u8, p_blurb: [*:0]const u8, p_func: ?gst.TagMergeFunc) void;
pub const tagRegister = gst_tag_register;

/// Registers a new tag type for the use with GStreamer's type system.
///
/// Same as `gst.tagRegister`, but `name`, `nick`, and `blurb` must be
/// static strings or inlined strings, as they will not be copied. (GStreamer
/// plugins will be made resident once loaded, so this function can be used
/// even from dynamically loaded plugins.)
extern fn gst_tag_register_static(p_name: [*:0]const u8, p_flag: gst.TagFlag, p_type: usize, p_nick: [*:0]const u8, p_blurb: [*:0]const u8, p_func: ?gst.TagMergeFunc) void;
pub const tagRegisterStatic = gst_tag_register_static;

/// Get a list of all active tracer objects owned by the tracing framework for
/// the entirety of the run-time of the process or till `gst.deinit` is called.
extern fn gst_tracing_get_active_tracers() *glib.List;
pub const tracingGetActiveTracers = gst_tracing_get_active_tracers;

/// Register `func` to be called when the trace hook `detail` is getting invoked.
/// Use `NULL` for `detail` to register to all hooks.
extern fn gst_tracing_register_hook(p_tracer: *gst.Tracer, p_detail: [*:0]const u8, p_func: gobject.Callback) void;
pub const tracingRegisterHook = gst_tracing_register_hook;

/// Checks if `type` is plugin API. See `gst.typeMarkAsPluginApi` for
/// details.
extern fn gst_type_is_plugin_api(p_type: usize, p_flags: ?*gst.PluginAPIFlags) c_int;
pub const typeIsPluginApi = gst_type_is_plugin_api;

/// Marks `type` as plugin API. This should be called in `class_init` of
/// elements that expose new types (i.e. enums, flags or internal GObjects) via
/// properties, signals or pad templates.
///
/// Types exposed by plugins are not automatically added to the documentation
/// as they might originate from another library and should in that case be
/// documented via that library instead.
///
/// By marking a type as plugin API it will be included in the documentation of
/// the plugin that defines it.
extern fn gst_type_mark_as_plugin_api(p_type: usize, p_flags: gst.PluginAPIFlags) void;
pub const typeMarkAsPluginApi = gst_type_mark_as_plugin_api;

/// Forces GStreamer to re-scan its plugin paths and update the default
/// plugin registry.
///
/// Applications will almost never need to call this function, it is only
/// useful if the application knows new plugins have been installed (or old
/// ones removed) since the start of the application (or, to be precise, the
/// first call to `gst.init`) and the application wants to make use of any
/// newly-installed plugins without restarting the application.
///
/// Applications should assume that the registry update is neither atomic nor
/// thread-safe and should therefore not have any dynamic pipelines running
/// (including the playbin and decodebin elements) and should also not create
/// any elements or access the GStreamer registry while the update is in
/// progress.
///
/// Note that this function may block for a significant amount of time.
extern fn gst_update_registry() c_int;
pub const updateRegistry = gst_update_registry;

/// Searches inside `array` for `search_data` by using the comparison function
/// `search_func`. `array` must be sorted ascending.
///
/// As `search_data` is always passed as second argument to `search_func` it's
/// not required that `search_data` has the same type as the array elements.
///
/// The complexity of this search function is O(log (num_elements)).
extern fn gst_util_array_binary_search(p_array: ?*anyopaque, p_num_elements: c_uint, p_element_size: usize, p_search_func: glib.CompareDataFunc, p_mode: gst.SearchMode, p_search_data: ?*const anyopaque, p_user_data: ?*anyopaque) ?*anyopaque;
pub const utilArrayBinarySearch = gst_util_array_binary_search;

/// Returns smallest integral value not less than log2(v).
extern fn gst_util_ceil_log2(p_v: u32) c_uint;
pub const utilCeilLog2 = gst_util_ceil_log2;

/// Transforms a `gdouble` to a fraction and simplifies
/// the result.
extern fn gst_util_double_to_fraction(p_src: f64, p_dest_n: *c_int, p_dest_d: *c_int) void;
pub const utilDoubleToFraction = gst_util_double_to_fraction;

/// Dumps the buffer memory into a hex representation. Useful for debugging.
extern fn gst_util_dump_buffer(p_buf: *gst.Buffer) void;
pub const utilDumpBuffer = gst_util_dump_buffer;

/// Dumps the memory block into a hex representation. Useful for debugging.
extern fn gst_util_dump_mem(p_mem: [*]const u8, p_size: c_uint) void;
pub const utilDumpMem = gst_util_dump_mem;

/// Compares the given filenames using natural ordering.
extern fn gst_util_filename_compare(p_a: [*:0]const u8, p_b: [*:0]const u8) c_int;
pub const utilFilenameCompare = gst_util_filename_compare;

/// Returns smallest integral value not bigger than log2(v).
extern fn gst_util_floor_log2(p_v: u32) c_uint;
pub const utilFloorLog2 = gst_util_floor_log2;

/// Adds the fractions `a_n`/`a_d` and `b_n`/`b_d` and stores
/// the result in `res_n` and `res_d`.
extern fn gst_util_fraction_add(p_a_n: c_int, p_a_d: c_int, p_b_n: c_int, p_b_d: c_int, p_res_n: *c_int, p_res_d: *c_int) c_int;
pub const utilFractionAdd = gst_util_fraction_add;

/// Compares the fractions `a_n`/`a_d` and `b_n`/`b_d` and returns
/// -1 if a < b, 0 if a = b and 1 if a > b.
extern fn gst_util_fraction_compare(p_a_n: c_int, p_a_d: c_int, p_b_n: c_int, p_b_d: c_int) c_int;
pub const utilFractionCompare = gst_util_fraction_compare;

/// Multiplies the fractions `a_n`/`a_d` and `b_n`/`b_d` and stores
/// the result in `res_n` and `res_d`.
extern fn gst_util_fraction_multiply(p_a_n: c_int, p_a_d: c_int, p_b_n: c_int, p_b_d: c_int, p_res_n: *c_int, p_res_d: *c_int) c_int;
pub const utilFractionMultiply = gst_util_fraction_multiply;

/// Multiplies the fractions `a_n`/`a_d` and `b_n`/`b_d` and stores
/// the result in `res_n` and `res_d`.
extern fn gst_util_fraction_multiply_int64(p_a_n: i64, p_a_d: i64, p_b_n: i64, p_b_d: i64, p_res_n: *i64, p_res_d: *i64) c_int;
pub const utilFractionMultiplyInt64 = gst_util_fraction_multiply_int64;

/// Transforms a fraction to a `gdouble`.
extern fn gst_util_fraction_to_double(p_src_n: c_int, p_src_d: c_int, p_dest: *f64) void;
pub const utilFractionToDouble = gst_util_fraction_to_double;

extern fn gst_util_gdouble_to_guint64(p_value: f64) u64;
pub const utilGdoubleToGuint64 = gst_util_gdouble_to_guint64;

/// Get a property of type `GST_TYPE_ARRAY` and transform it into a
/// `gobject.ValueArray`. This allow language bindings to get GST_TYPE_ARRAY
/// properties which are otherwise not an accessible type.
extern fn gst_util_get_object_array(p_object: *gobject.Object, p_name: [*:0]const u8, p_array: **gobject.ValueArray) c_int;
pub const utilGetObjectArray = gst_util_get_object_array;

/// Get a timestamp as GstClockTime to be used for interval measurements.
/// The timestamp should not be interpreted in any other way.
extern fn gst_util_get_timestamp() gst.ClockTime;
pub const utilGetTimestamp = gst_util_get_timestamp;

/// Calculates the greatest common divisor of `a`
/// and `b`.
extern fn gst_util_greatest_common_divisor(p_a: c_int, p_b: c_int) c_int;
pub const utilGreatestCommonDivisor = gst_util_greatest_common_divisor;

/// Calculates the greatest common divisor of `a`
/// and `b`.
extern fn gst_util_greatest_common_divisor_int64(p_a: i64, p_b: i64) i64;
pub const utilGreatestCommonDivisorInt64 = gst_util_greatest_common_divisor_int64;

/// Return a constantly incrementing group id.
///
/// This function is used to generate a new group-id for the
/// stream-start event.
///
/// This function never returns `GST_GROUP_ID_INVALID` (which is 0)
extern fn gst_util_group_id_next() c_uint;
pub const utilGroupIdNext = gst_util_group_id_next;

extern fn gst_util_guint64_to_gdouble(p_value: u64) f64;
pub const utilGuint64ToGdouble = gst_util_guint64_to_gdouble;

/// Compare two sequence numbers, handling wraparound.
///
/// The current implementation just returns (gint32)(`s1` - `s2`).
extern fn gst_util_seqnum_compare(p_s1: u32, p_s2: u32) i32;
pub const utilSeqnumCompare = gst_util_seqnum_compare;

/// Return a constantly incrementing sequence number.
///
/// This function is used internally to GStreamer to be able to determine which
/// events and messages are "the same". For example, elements may set the seqnum
/// on a segment-done message to be the same as that of the last seek event, to
/// indicate that event and the message correspond to the same segment.
///
/// This function never returns `GST_SEQNUM_INVALID` (which is 0).
extern fn gst_util_seqnum_next() u32;
pub const utilSeqnumNext = gst_util_seqnum_next;

/// Converts the string value to the type of the objects argument and
/// sets the argument with it.
///
/// Note that this function silently returns if `object` has no property named
/// `name` or when `value` cannot be converted to the type of the property.
extern fn gst_util_set_object_arg(p_object: *gobject.Object, p_name: [*:0]const u8, p_value: [*:0]const u8) void;
pub const utilSetObjectArg = gst_util_set_object_arg;

/// Transfer a `gobject.ValueArray` to `GST_TYPE_ARRAY` and set this value on the
/// specified property name. This allow language bindings to set GST_TYPE_ARRAY
/// properties which are otherwise not an accessible type.
extern fn gst_util_set_object_array(p_object: *gobject.Object, p_name: [*:0]const u8, p_array: *const gobject.ValueArray) c_int;
pub const utilSetObjectArray = gst_util_set_object_array;

/// Converts the string to the type of the value and
/// sets the value with it.
///
/// Note that this function is dangerous as it does not return any indication
/// if the conversion worked or not.
extern fn gst_util_set_value_from_string(p_value: *gobject.Value, p_value_str: [*:0]const u8) void;
pub const utilSetValueFromString = gst_util_set_value_from_string;

/// Calculates the simpler representation of `numerator` and `denominator` and
/// update both values with the resulting simplified fraction.
///
/// Simplify a fraction using a simple continued fraction decomposition.
/// The idea here is to convert fractions such as 333333/10000000 to 1/30
/// using 32 bit arithmetic only. The algorithm is not perfect and relies
/// upon two arbitrary parameters to remove non-significative terms from
/// the simple continued fraction decomposition. Using 8 and 333 for
/// `n_terms` and `threshold` respectively seems to give nice results.
extern fn gst_util_simplify_fraction(p_numerator: *c_int, p_denominator: *c_int, p_n_terms: c_uint, p_threshold: c_uint) void;
pub const utilSimplifyFraction = gst_util_simplify_fraction;

/// Scale `val` by the rational number `num` / `denom`, avoiding overflows and
/// underflows and without loss of precision.
///
/// This function can potentially be very slow if val and num are both
/// greater than G_MAXUINT32.
extern fn gst_util_uint64_scale(p_val: u64, p_num: u64, p_denom: u64) u64;
pub const utilUint64Scale = gst_util_uint64_scale;

/// Scale `val` by the rational number `num` / `denom`, avoiding overflows and
/// underflows and without loss of precision.
///
/// This function can potentially be very slow if val and num are both
/// greater than G_MAXUINT32.
extern fn gst_util_uint64_scale_ceil(p_val: u64, p_num: u64, p_denom: u64) u64;
pub const utilUint64ScaleCeil = gst_util_uint64_scale_ceil;

/// Scale `val` by the rational number `num` / `denom`, avoiding overflows and
/// underflows and without loss of precision.  `num` must be non-negative and
/// `denom` must be positive.
extern fn gst_util_uint64_scale_int(p_val: u64, p_num: c_int, p_denom: c_int) u64;
pub const utilUint64ScaleInt = gst_util_uint64_scale_int;

/// Scale `val` by the rational number `num` / `denom`, avoiding overflows and
/// underflows and without loss of precision.  `num` must be non-negative and
/// `denom` must be positive.
extern fn gst_util_uint64_scale_int_ceil(p_val: u64, p_num: c_int, p_denom: c_int) u64;
pub const utilUint64ScaleIntCeil = gst_util_uint64_scale_int_ceil;

/// Scale `val` by the rational number `num` / `denom`, avoiding overflows and
/// underflows and without loss of precision.  `num` must be non-negative and
/// `denom` must be positive.
extern fn gst_util_uint64_scale_int_round(p_val: u64, p_num: c_int, p_denom: c_int) u64;
pub const utilUint64ScaleIntRound = gst_util_uint64_scale_int_round;

/// Scale `val` by the rational number `num` / `denom`, avoiding overflows and
/// underflows and without loss of precision.
///
/// This function can potentially be very slow if val and num are both
/// greater than G_MAXUINT32.
extern fn gst_util_uint64_scale_round(p_val: u64, p_num: u64, p_denom: u64) u64;
pub const utilUint64ScaleRound = gst_util_uint64_scale_round;

/// Determines if `value1` and `value2` can be compared.
extern fn gst_value_can_compare(p_value1: *const gobject.Value, p_value2: *const gobject.Value) c_int;
pub const valueCanCompare = gst_value_can_compare;

/// Determines if intersecting two values will produce a valid result.
/// Two values will produce a valid intersection if they have the same
/// type.
extern fn gst_value_can_intersect(p_value1: *const gobject.Value, p_value2: *const gobject.Value) c_int;
pub const valueCanIntersect = gst_value_can_intersect;

/// Checks if it's possible to subtract `subtrahend` from `minuend`.
extern fn gst_value_can_subtract(p_minuend: *const gobject.Value, p_subtrahend: *const gobject.Value) c_int;
pub const valueCanSubtract = gst_value_can_subtract;

/// Determines if `value1` and `value2` can be non-trivially unioned.
/// Any two values can be trivially unioned by adding both of them
/// to a GstValueList.  However, certain types have the possibility
/// to be unioned in a simpler way.  For example, an integer range
/// and an integer can be unioned if the integer is a subset of the
/// integer range.  If there is the possibility that two values can
/// be unioned, this function returns `TRUE`.
extern fn gst_value_can_union(p_value1: *const gobject.Value, p_value2: *const gobject.Value) c_int;
pub const valueCanUnion = gst_value_can_union;

/// Compares `value1` and `value2`.  If `value1` and `value2` cannot be
/// compared, the function returns GST_VALUE_UNORDERED.  Otherwise,
/// if `value1` is greater than `value2`, GST_VALUE_GREATER_THAN is returned.
/// If `value1` is less than `value2`, GST_VALUE_LESS_THAN is returned.
/// If the values are equal, GST_VALUE_EQUAL is returned.
extern fn gst_value_compare(p_value1: *const gobject.Value, p_value2: *const gobject.Value) c_int;
pub const valueCompare = gst_value_compare;

/// Tries to deserialize a string into the type specified by the given GValue.
/// If the operation succeeds, `TRUE` is returned, `FALSE` otherwise.
extern fn gst_value_deserialize(p_dest: *gobject.Value, p_src: [*:0]const u8) c_int;
pub const valueDeserialize = gst_value_deserialize;

/// Tries to deserialize a string into the type specified by the given GValue.
/// `pspec` may be used to guide the deserializing of nested members.
/// If the operation succeeds, `TRUE` is returned, `FALSE` otherwise.
extern fn gst_value_deserialize_with_pspec(p_dest: *gobject.Value, p_src: [*:0]const u8, p_pspec: ?*gobject.ParamSpec) c_int;
pub const valueDeserializeWithPspec = gst_value_deserialize_with_pspec;

/// Fixate `src` into a new value `dest`.
/// For ranges, the first element is taken. For lists and arrays, the
/// first item is fixated and returned.
/// If `src` is already fixed, this function returns `FALSE`.
extern fn gst_value_fixate(p_dest: *gobject.Value, p_src: *const gobject.Value) c_int;
pub const valueFixate = gst_value_fixate;

/// Multiplies the two `gobject.Value` items containing a `GST_TYPE_FRACTION` and sets
/// `product` to the product of the two fractions.
extern fn gst_value_fraction_multiply(p_product: *gobject.Value, p_factor1: *const gobject.Value, p_factor2: *const gobject.Value) c_int;
pub const valueFractionMultiply = gst_value_fraction_multiply;

/// Subtracts the `subtrahend` from the `minuend` and sets `dest` to the result.
extern fn gst_value_fraction_subtract(p_dest: *gobject.Value, p_minuend: *const gobject.Value, p_subtrahend: *const gobject.Value) c_int;
pub const valueFractionSubtract = gst_value_fraction_subtract;

/// Gets the bitmask specified by `value`.
extern fn gst_value_get_bitmask(p_value: *const gobject.Value) u64;
pub const valueGetBitmask = gst_value_get_bitmask;

/// Gets the contents of `value`. The reference count of the returned
/// `gst.Caps` will not be modified, therefore the caller must take one
/// before getting rid of the `value`.
extern fn gst_value_get_caps(p_value: *const gobject.Value) *const gst.Caps;
pub const valueGetCaps = gst_value_get_caps;

/// Gets the contents of `value`.
extern fn gst_value_get_caps_features(p_value: *const gobject.Value) *const gst.CapsFeatures;
pub const valueGetCapsFeatures = gst_value_get_caps_features;

/// Gets the maximum of the range specified by `value`.
extern fn gst_value_get_double_range_max(p_value: *const gobject.Value) f64;
pub const valueGetDoubleRangeMax = gst_value_get_double_range_max;

/// Gets the minimum of the range specified by `value`.
extern fn gst_value_get_double_range_min(p_value: *const gobject.Value) f64;
pub const valueGetDoubleRangeMin = gst_value_get_double_range_min;

/// Retrieve the flags field of a GstFlagSet `value`.
extern fn gst_value_get_flagset_flags(p_value: *const gobject.Value) c_uint;
pub const valueGetFlagsetFlags = gst_value_get_flagset_flags;

/// Retrieve the mask field of a GstFlagSet `value`.
extern fn gst_value_get_flagset_mask(p_value: *const gobject.Value) c_uint;
pub const valueGetFlagsetMask = gst_value_get_flagset_mask;

/// Gets the denominator of the fraction specified by `value`.
extern fn gst_value_get_fraction_denominator(p_value: *const gobject.Value) c_int;
pub const valueGetFractionDenominator = gst_value_get_fraction_denominator;

/// Gets the numerator of the fraction specified by `value`.
extern fn gst_value_get_fraction_numerator(p_value: *const gobject.Value) c_int;
pub const valueGetFractionNumerator = gst_value_get_fraction_numerator;

/// Gets the maximum of the range specified by `value`.
extern fn gst_value_get_fraction_range_max(p_value: *const gobject.Value) ?*const gobject.Value;
pub const valueGetFractionRangeMax = gst_value_get_fraction_range_max;

/// Gets the minimum of the range specified by `value`.
extern fn gst_value_get_fraction_range_min(p_value: *const gobject.Value) ?*const gobject.Value;
pub const valueGetFractionRangeMin = gst_value_get_fraction_range_min;

/// Gets the maximum of the range specified by `value`.
extern fn gst_value_get_int64_range_max(p_value: *const gobject.Value) i64;
pub const valueGetInt64RangeMax = gst_value_get_int64_range_max;

/// Gets the minimum of the range specified by `value`.
extern fn gst_value_get_int64_range_min(p_value: *const gobject.Value) i64;
pub const valueGetInt64RangeMin = gst_value_get_int64_range_min;

/// Gets the step of the range specified by `value`.
extern fn gst_value_get_int64_range_step(p_value: *const gobject.Value) i64;
pub const valueGetInt64RangeStep = gst_value_get_int64_range_step;

/// Gets the maximum of the range specified by `value`.
extern fn gst_value_get_int_range_max(p_value: *const gobject.Value) c_int;
pub const valueGetIntRangeMax = gst_value_get_int_range_max;

/// Gets the minimum of the range specified by `value`.
extern fn gst_value_get_int_range_min(p_value: *const gobject.Value) c_int;
pub const valueGetIntRangeMin = gst_value_get_int_range_min;

/// Gets the step of the range specified by `value`.
extern fn gst_value_get_int_range_step(p_value: *const gobject.Value) c_int;
pub const valueGetIntRangeStep = gst_value_get_int_range_step;

/// Gets the contents of `value`.
extern fn gst_value_get_structure(p_value: *const gobject.Value) *const gst.Structure;
pub const valueGetStructure = gst_value_get_structure;

/// Initialises the target value to be of the same type as source and then copies
/// the contents from source to target.
extern fn gst_value_init_and_copy(p_dest: *gobject.Value, p_src: *const gobject.Value) void;
pub const valueInitAndCopy = gst_value_init_and_copy;

/// Calculates the intersection of two values.  If the values have
/// a non-empty intersection, the value representing the intersection
/// is placed in `dest`, unless `NULL`.  If the intersection is non-empty,
/// `dest` is not modified.
extern fn gst_value_intersect(p_dest: ?*gobject.Value, p_value1: *const gobject.Value, p_value2: *const gobject.Value) c_int;
pub const valueIntersect = gst_value_intersect;

/// Tests if the given GValue, if available in a GstStructure (or any other
/// container) contains a "fixed" (which means: one value) or an "unfixed"
/// (which means: multiple possible values, such as data lists or data
/// ranges) value.
extern fn gst_value_is_fixed(p_value: *const gobject.Value) c_int;
pub const valueIsFixed = gst_value_is_fixed;

/// Check that `value1` is a subset of `value2`.
extern fn gst_value_is_subset(p_value1: *const gobject.Value, p_value2: *const gobject.Value) c_int;
pub const valueIsSubset = gst_value_is_subset;

/// Registers functions to perform calculations on `gobject.Value` items of a given
/// type. Each type can only be added once.
extern fn gst_value_register(p_table: *const gst.ValueTable) void;
pub const valueRegister = gst_value_register;

/// tries to transform the given `value` into a string representation that allows
/// getting back this string later on using `gst.valueDeserialize`.
///
/// Free-function: g_free
extern fn gst_value_serialize(p_value: *const gobject.Value) ?[*:0]u8;
pub const valueSerialize = gst_value_serialize;

/// Sets `value` to the bitmask specified by `bitmask`.
extern fn gst_value_set_bitmask(p_value: *gobject.Value, p_bitmask: u64) void;
pub const valueSetBitmask = gst_value_set_bitmask;

/// Sets the contents of `value` to `caps`. A reference to the
/// provided `caps` will be taken by the `value`.
extern fn gst_value_set_caps(p_value: *gobject.Value, p_caps: *const gst.Caps) void;
pub const valueSetCaps = gst_value_set_caps;

/// Sets the contents of `value` to `features`.
extern fn gst_value_set_caps_features(p_value: *gobject.Value, p_features: *const gst.CapsFeatures) void;
pub const valueSetCapsFeatures = gst_value_set_caps_features;

/// Sets `value` to the range specified by `start` and `end`.
extern fn gst_value_set_double_range(p_value: *gobject.Value, p_start: f64, p_end: f64) void;
pub const valueSetDoubleRange = gst_value_set_double_range;

/// Sets `value` to the flags and mask values provided in `flags` and `mask`.
/// The `flags` value indicates the values of flags, the `mask` represents
/// which bits in the flag value have been set, and which are "don't care"
extern fn gst_value_set_flagset(p_value: *gobject.Value, p_flags: c_uint, p_mask: c_uint) void;
pub const valueSetFlagset = gst_value_set_flagset;

/// Sets `value` to the fraction specified by `numerator` over `denominator`.
/// The fraction gets reduced to the smallest numerator and denominator,
/// and if necessary the sign is moved to the numerator.
extern fn gst_value_set_fraction(p_value: *gobject.Value, p_numerator: c_int, p_denominator: c_int) void;
pub const valueSetFraction = gst_value_set_fraction;

/// Sets `value` to the range specified by `start` and `end`.
extern fn gst_value_set_fraction_range(p_value: *gobject.Value, p_start: *const gobject.Value, p_end: *const gobject.Value) void;
pub const valueSetFractionRange = gst_value_set_fraction_range;

/// Sets `value` to the range specified by `numerator_start`/`denominator_start`
/// and `numerator_end`/`denominator_end`.
extern fn gst_value_set_fraction_range_full(p_value: *gobject.Value, p_numerator_start: c_int, p_denominator_start: c_int, p_numerator_end: c_int, p_denominator_end: c_int) void;
pub const valueSetFractionRangeFull = gst_value_set_fraction_range_full;

/// Sets `value` to the range specified by `start` and `end`.
extern fn gst_value_set_int64_range(p_value: *gobject.Value, p_start: i64, p_end: i64) void;
pub const valueSetInt64Range = gst_value_set_int64_range;

/// Sets `value` to the range specified by `start`, `end` and `step`.
extern fn gst_value_set_int64_range_step(p_value: *gobject.Value, p_start: i64, p_end: i64, p_step: i64) void;
pub const valueSetInt64RangeStep = gst_value_set_int64_range_step;

/// Sets `value` to the range specified by `start` and `end`.
extern fn gst_value_set_int_range(p_value: *gobject.Value, p_start: c_int, p_end: c_int) void;
pub const valueSetIntRange = gst_value_set_int_range;

/// Sets `value` to the range specified by `start`, `end` and `step`.
extern fn gst_value_set_int_range_step(p_value: *gobject.Value, p_start: c_int, p_end: c_int, p_step: c_int) void;
pub const valueSetIntRangeStep = gst_value_set_int_range_step;

/// Sets the contents of `value` to `structure`.
extern fn gst_value_set_structure(p_value: *gobject.Value, p_structure: *const gst.Structure) void;
pub const valueSetStructure = gst_value_set_structure;

/// Subtracts `subtrahend` from `minuend` and stores the result in `dest`.
/// Note that this means subtraction as in sets, not as in mathematics.
extern fn gst_value_subtract(p_dest: ?*gobject.Value, p_minuend: *const gobject.Value, p_subtrahend: *const gobject.Value) c_int;
pub const valueSubtract = gst_value_subtract;

/// Creates a GValue corresponding to the union of `value1` and `value2`.
extern fn gst_value_union(p_dest: *gobject.Value, p_value1: *const gobject.Value, p_value2: *const gobject.Value) c_int;
pub const valueUnion = gst_value_union;

/// Gets the version number of the GStreamer library.
extern fn gst_version(p_major: *c_uint, p_minor: *c_uint, p_micro: *c_uint, p_nano: *c_uint) void;
pub const version = gst_version;

/// This function returns a string that is useful for describing this version
/// of GStreamer to the outside world: user agent strings, logging, ...
extern fn gst_version_string() [*:0]u8;
pub const versionString = gst_version_string;

/// The aggregator function will combine the parameters from `params0` and `param1`
/// and write the result back into `aggregated_params`.
pub const AllocationMetaParamsAggregator = *const fn (p_aggregated_params: **gst.Structure, p_params0: *const gst.Structure, p_params1: *const gst.Structure) callconv(.c) c_int;

/// A function that will be called from `gst.Buffer.foreachMeta`. The `meta`
/// field will point to a the reference of the meta.
///
/// `buffer` should not be modified from this callback.
///
/// When this function returns `TRUE`, the next meta will be
/// returned. When `FALSE` is returned, `gst.Buffer.foreachMeta` will return.
///
/// When `meta` is set to `NULL`, the item will be removed from the buffer.
pub const BufferForeachMetaFunc = *const fn (p_buffer: *gst.Buffer, p_meta: ?**gst.Meta, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called from `gst.BufferList.foreach`. The `buffer`
/// field will point to a the reference of the buffer at `idx`.
///
/// When this function returns `TRUE`, the next buffer will be
/// returned. When `FALSE` is returned, `gst.BufferList.foreach` will return.
///
/// When `buffer` is set to `NULL`, the item will be removed from the bufferlist.
/// When `buffer` has been made writable, the new buffer reference can be assigned
/// to `buffer`. This function is responsible for unreffing the old buffer when
/// removing or modifying.
pub const BufferListFunc = *const fn (p_buffer: ?**gst.Buffer, p_idx: c_uint, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// Specifies the type of function passed to `gst.Bus.addWatch` or
/// `gst.Bus.addWatchFull`, which is called from the mainloop when a message
/// is available on the bus.
///
/// The message passed to the function will be unreffed after execution of this
/// function so it should not be freed in the function.
///
/// Note that this function is used as a `glib.SourceFunc` which means that returning
/// `FALSE` will remove the `glib.Source` from the mainloop.
pub const BusFunc = *const fn (p_bus: *gst.Bus, p_message: *gst.Message, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// Handler will be invoked synchronously, when a new message has been injected
/// into the bus. This function is mostly used internally. Only one sync handler
/// can be attached to a given bus.
///
/// If the handler returns `GST_BUS_DROP`, it should unref the message, else the
/// message should not be unreffed by the sync handler.
pub const BusSyncHandler = *const fn (p_bus: *gst.Bus, p_message: *gst.Message, p_user_data: ?*anyopaque) callconv(.c) gst.BusSyncReply;

/// A function that will be called in `gst.Caps.filterAndMapInPlace`.
/// The function may modify `features` and `structure`, and both will be
/// removed from the caps if `FALSE` is returned.
pub const CapsFilterMapFunc = *const fn (p_features: *gst.CapsFeatures, p_structure: *gst.Structure, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.Caps.foreach`. The function may
/// not modify `features` or `structure`.
pub const CapsForeachFunc = *const fn (p_features: *gst.CapsFeatures, p_structure: *gst.Structure, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.Caps.mapInPlace`. The function
/// may modify `features` and `structure`.
pub const CapsMapFunc = *const fn (p_features: *gst.CapsFeatures, p_structure: *gst.Structure, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// The function prototype of the callback.
pub const ClockCallback = *const fn (p_clock: *gst.Clock, p_time: gst.ClockTime, p_id: gst.ClockID, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// FIXME(2.0): remove, this is unused
pub const ControlBindingConvert = *const fn (p_binding: *gst.ControlBinding, p_src_value: f64, p_dest_value: *gobject.Value) callconv(.c) void;

/// Function for returning a value for a given timestamp.
pub const ControlSourceGetValue = *const fn (p_self: *anyopaque, p_timestamp: gst.ClockTime, p_value: *f64) callconv(.c) c_int;

/// Function for returning an array of values starting at a given timestamp.
pub const ControlSourceGetValueArray = *const fn (p_self: *anyopaque, p_timestamp: gst.ClockTime, p_interval: gst.ClockTime, p_n_values: c_uint, p_values: *f64) callconv(.c) c_int;

/// Function called for each `meta` in `buffer` as a result of performing a
/// transformation that yields `transbuf`. Additional `type` specific transform
/// data is passed to the function as `data`.
///
/// Implementations should check the `type` of the transform and parse
/// additional type specific fields in `data` that should be used to update
/// the metadata on `transbuf`.
pub const CustomMetaTransformFunction = *const fn (p_transbuf: *gst.Buffer, p_meta: *gst.CustomMeta, p_buffer: *gst.Buffer, p_type: glib.Quark, p_data: ?*anyopaque, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// we define this to avoid a compiler warning regarding a cast from a function
/// pointer to a void pointer
/// (see https://bugzilla.gnome.org/show_bug.cgi?id=309253)
pub const DebugFuncPtr = *const fn () callconv(.c) void;

/// Callback prototype used in `gst.Element.callAsync`
pub const ElementCallAsyncFunc = *const fn (p_element: *gst.Element, p_user_data: ?*anyopaque) callconv(.c) void;

/// Function called for each pad when using `gst.Element.foreachSinkPad`,
/// `gst.Element.foreachSrcPad`, or `gst.Element.foreachPad`.
pub const ElementForeachPadFunc = *const fn (p_element: *gst.Element, p_pad: *gst.Pad, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// This function will be called when creating a copy of `it` and should
/// create a copy of all custom iterator fields or increase their
/// reference counts.
pub const IteratorCopyFunction = *const fn (p_it: *const gst.Iterator, p_copy: *gst.Iterator) callconv(.c) void;

/// A function to be passed to `gst.Iterator.fold`.
pub const IteratorFoldFunction = *const fn (p_item: *const gobject.Value, p_ret: *gobject.Value, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that is called by `gst.Iterator.foreach` for every element.
pub const IteratorForeachFunction = *const fn (p_item: *const gobject.Value, p_user_data: ?*anyopaque) callconv(.c) void;

/// This function will be called when the iterator is freed.
///
/// Implementors of a `gst.Iterator` should implement this
/// function and pass it to the constructor of the custom iterator.
/// The function will be called with the iterator lock held.
pub const IteratorFreeFunction = *const fn (p_it: *gst.Iterator) callconv(.c) void;

/// The function that will be called after the next item of the iterator
/// has been retrieved. This function can be used to skip items or stop
/// the iterator.
///
/// The function will be called with the iterator lock held.
pub const IteratorItemFunction = *const fn (p_it: *gst.Iterator, p_item: *const gobject.Value) callconv(.c) gst.IteratorItem;

/// The function that will be called when the next element of the iterator
/// should be retrieved.
///
/// Implementors of a `gst.Iterator` should implement this
/// function and pass it to the constructor of the custom iterator.
/// The function will be called with the iterator lock held.
pub const IteratorNextFunction = *const fn (p_it: *gst.Iterator, p_result: *gobject.Value) callconv(.c) gst.IteratorResult;

/// This function will be called whenever a concurrent update happened
/// to the iterated datastructure. The implementor of the iterator should
/// restart the iterator from the beginning and clean up any state it might
/// have.
///
/// Implementors of a `gst.Iterator` should implement this
/// function and pass it to the constructor of the custom iterator.
/// The function will be called with the iterator lock held.
pub const IteratorResyncFunction = *const fn (p_it: *gst.Iterator) callconv(.c) void;

/// Function prototype for a logging function that can be registered with
/// `gst.debugAddLogFunction`.
/// Use G_GNUC_NO_INSTRUMENT on that function.
pub const LogFunction = *const fn (p_category: *gst.DebugCategory, p_level: gst.DebugLevel, p_file: [*:0]const u8, p_function: [*:0]const u8, p_line: c_int, p_object: *gobject.Object, p_message: *gst.DebugMessage, p_user_data: ?*anyopaque) callconv(.c) void;

/// Copy `size` bytes from `mem` starting at `offset` and return them wrapped in a
/// new GstMemory object.
/// If `size` is set to -1, all bytes starting at `offset` are copied.
pub const MemoryCopyFunction = *const fn (p_mem: *anyopaque, p_offset: isize, p_size: isize) callconv(.c) *anyopaque;

/// Check if `mem1` and `mem2` occupy contiguous memory and return the offset of
/// `mem1` in the parent buffer in `offset`.
pub const MemoryIsSpanFunction = *const fn (p_mem1: *anyopaque, p_mem2: *anyopaque, p_offset: *usize) callconv(.c) c_int;

/// Get the memory of `mem` that can be accessed according to the mode specified
/// in `info`'s flags. The function should return a pointer that contains at least
/// `maxsize` bytes.
pub const MemoryMapFullFunction = *const fn (p_mem: *anyopaque, p_info: *anyopaque, p_maxsize: usize) callconv(.c) ?*anyopaque;

/// Get the memory of `mem` that can be accessed according to the mode specified
/// in `flags`. The function should return a pointer that contains at least
/// `maxsize` bytes.
pub const MemoryMapFunction = *const fn (p_mem: *anyopaque, p_maxsize: usize, p_flags: gst.MapFlags) callconv(.c) ?*anyopaque;

/// Share `size` bytes from `mem` starting at `offset` and return them wrapped in a
/// new GstMemory object. If `size` is set to -1, all bytes starting at `offset` are
/// shared. This function does not make a copy of the bytes in `mem`.
pub const MemoryShareFunction = *const fn (p_mem: *anyopaque, p_offset: isize, p_size: isize) callconv(.c) *anyopaque;

/// Release the pointer previously retrieved with `gst.Memory.map` with `info`.
pub const MemoryUnmapFullFunction = *const fn (p_mem: *anyopaque, p_info: *anyopaque) callconv(.c) void;

/// Release the pointer previously retrieved with `gst.Memory.map`.
pub const MemoryUnmapFunction = *const fn (p_mem: *anyopaque) callconv(.c) void;

/// Clears the content of the meta. This will be called by the GstBufferPool
/// when a pooled buffer is returned.
pub const MetaClearFunction = *const fn (p_buffer: *gst.Buffer, p_meta: *gst.Meta) callconv(.c) void;

/// Recreate a `gst.Meta` from serialized data returned by
/// `gst.MetaSerializeFunction` and add it to `buffer`.
pub const MetaDeserializeFunction = *const fn (p_info: *const gst.MetaInfo, p_buffer: *gst.Buffer, p_data: *const u8, p_size: usize, p_version: u8) callconv(.c) ?*gst.Meta;

/// Function called when `meta` is freed in `buffer`.
pub const MetaFreeFunction = *const fn (p_meta: *gst.Meta, p_buffer: *gst.Buffer) callconv(.c) void;

/// Function called when `meta` is initialized in `buffer`.
pub const MetaInitFunction = *const fn (p_meta: *gst.Meta, p_params: ?*anyopaque, p_buffer: *gst.Buffer) callconv(.c) c_int;

/// Serialize `meta` into a format that can be stored or transmitted and later
/// deserialized by `gst.MetaDeserializeFunction`.
///
/// By default version is set to 0, it should be bumped if incompatible changes
/// are made to the format so `gst.MetaDeserializeFunction` can deserialize each
/// version.
pub const MetaSerializeFunction = *const fn (p_meta: *const gst.Meta, p_data: *gst.ByteArrayInterface, p_version: *u8) callconv(.c) c_int;

/// Function called for each `meta` in `buffer` as a result of performing a
/// transformation on `transbuf`. Additional `type` specific transform data
/// is passed to the function as `data`.
///
/// Implementations should check the `type` of the transform and parse
/// additional type specific fields in `data` that should be used to update
/// the metadata on `transbuf`.
pub const MetaTransformFunction = *const fn (p_transbuf: *gst.Buffer, p_meta: *gst.Meta, p_buffer: *gst.Buffer, p_type: glib.Quark, p_data: ?*anyopaque) callconv(.c) c_int;

/// Function prototype for methods to create copies of instances.
pub const MiniObjectCopyFunction = *const fn (p_obj: *const gst.MiniObject) callconv(.c) *gst.MiniObject;

/// Function prototype for when a miniobject has lost its last refcount.
/// Implementation of the mini object are allowed to revive the
/// passed object by doing a `gst.MiniObject.ref`. If the object is not
/// revived after the dispose function, the function should return `TRUE`
/// and the memory associated with the object is freed.
pub const MiniObjectDisposeFunction = *const fn (p_obj: *gst.MiniObject) callconv(.c) c_int;

/// Virtual function prototype for methods to free resources used by
/// mini-objects.
pub const MiniObjectFreeFunction = *const fn (p_obj: *gst.MiniObject) callconv(.c) void;

/// A `gst.MiniObjectNotify` function can be added to a mini object as a
/// callback that gets triggered when `gst.MiniObject.unref` drops the
/// last ref and `obj` is about to be freed.
pub const MiniObjectNotify = *const fn (p_user_data: ?*anyopaque, p_obj: *gst.MiniObject) callconv(.c) void;

/// This function is called when the pad is activated during the element
/// READY to PAUSED state change. By default this function will call the
/// activate function that puts the pad in push mode but elements can
/// override this function to activate the pad in pull mode if they wish.
pub const PadActivateFunction = *const fn (p_pad: *gst.Pad, p_parent: *gst.Object) callconv(.c) c_int;

/// The prototype of the push and pull activate functions.
pub const PadActivateModeFunction = *const fn (p_pad: *gst.Pad, p_parent: *gst.Object, p_mode: gst.PadMode, p_active: c_int) callconv(.c) c_int;

/// A function that will be called on sinkpads when chaining buffers.
/// The function typically processes the data contained in the buffer and
/// either consumes the data or passes it on to the internally linked pad(s).
///
/// The implementer of this function receives a refcount to `buffer` and should
/// `gst.Buffer.unref` when the buffer is no longer needed.
///
/// When a chain function detects an error in the data stream, it must post an
/// error on the bus and return an appropriate `gst.FlowReturn` value.
pub const PadChainFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object, p_buffer: *gst.Buffer) callconv(.c) gst.FlowReturn;

/// A function that will be called on sinkpads when chaining buffer lists.
/// The function typically processes the data contained in the buffer list and
/// either consumes the data or passes it on to the internally linked pad(s).
///
/// The implementer of this function receives a refcount to `list` and
/// should `gst.BufferList.unref` when the list is no longer needed.
///
/// When a chainlist function detects an error in the data stream, it must
/// post an error on the bus and return an appropriate `gst.FlowReturn` value.
pub const PadChainListFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object, p_list: *gst.BufferList) callconv(.c) gst.FlowReturn;

/// Function signature to handle an event for the pad.
///
/// This variant is for specific elements that will take into account the
/// last downstream flow return (from a pad push), in which case they can
/// return it.
pub const PadEventFullFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object, p_event: *gst.Event) callconv(.c) gst.FlowReturn;

/// Function signature to handle an event for the pad.
pub const PadEventFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object, p_event: *gst.Event) callconv(.c) c_int;

/// A forward function is called for all internally linked pads, see
/// `gst.Pad.forward`.
pub const PadForwardFunction = *const fn (p_pad: *gst.Pad, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// This function will be called on source pads when a peer element
/// request a buffer at the specified `offset` and `length`. If this function
/// returns `GST_FLOW_OK`, the result buffer will be stored in `buffer`. The
/// contents of `buffer` is invalid for any other return value.
///
/// This function is installed on a source pad with
/// `gst_pad_set_getrange_function` and can only be called on source pads after
/// they are successfully activated with `gst.Pad.activateMode` with the
/// `GST_PAD_MODE_PULL`.
///
/// `offset` and `length` are always given in byte units. `offset` must normally be a value
/// between 0 and the length in bytes of the data available on `pad`. The
/// length (duration in bytes) can be retrieved with a `GST_QUERY_DURATION` or with a
/// `GST_QUERY_SEEKING`.
///
/// Any `offset` larger or equal than the length will make the function return
/// `GST_FLOW_EOS`, which corresponds to EOS. In this case `buffer` does not
/// contain a valid buffer.
///
/// The buffer size of `buffer` will only be smaller than `length` when `offset` is
/// near the end of the stream. In all other cases, the size of `buffer` must be
/// exactly the requested size.
///
/// It is allowed to call this function with a 0 `length` and valid `offset`, in
/// which case `buffer` will contain a 0-sized buffer and the function returns
/// `GST_FLOW_OK`.
///
/// When this function is called with a -1 `offset`, the sequentially next buffer
/// of length `length` in the stream is returned.
///
/// When this function is called with a -1 `length`, a buffer with a default
/// optimal length is returned in `buffer`. The length might depend on the value
/// of `offset`.
pub const PadGetRangeFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object, p_offset: u64, p_length: c_uint, p_buffer: **gst.Buffer) callconv(.c) gst.FlowReturn;

/// The signature of the internal pad link iterator function.
pub const PadIterIntLinkFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object) callconv(.c) *gst.Iterator;

/// Function signature to handle a new link on the pad.
pub const PadLinkFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object, p_peer: *gst.Pad) callconv(.c) gst.PadLinkReturn;

/// Callback used by `gst.Pad.addProbe`. Gets called to notify about the current
/// blocking type.
///
/// The callback is allowed to modify the data pointer in `info`.
pub const PadProbeCallback = *const fn (p_pad: *gst.Pad, p_info: *gst.PadProbeInfo, p_user_data: ?*anyopaque) callconv(.c) gst.PadProbeReturn;

/// The signature of the query function.
pub const PadQueryFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object, p_query: *gst.Query) callconv(.c) c_int;

/// Callback used by `gst.Pad.stickyEventsForeach`.
///
/// When this function returns `TRUE`, the next event will be
/// returned. When `FALSE` is returned, `gst.Pad.stickyEventsForeach` will return.
///
/// When `event` is set to `NULL`, the item will be removed from the list of sticky events.
/// `event` can be replaced by assigning a new reference to it.
/// This function is responsible for unreffing the old event when
/// removing or modifying.
pub const PadStickyEventsForeachFunction = *const fn (p_pad: *gst.Pad, p_event: ?**gst.Event, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// Function signature to handle a unlinking the pad prom its peer.
///
/// The pad's lock is already held when the unlink function is called, so most
/// pad functions cannot be called from within the callback.
pub const PadUnlinkFunction = *const fn (p_pad: *gst.Pad, p_parent: ?*gst.Object) callconv(.c) void;

/// A function that can be used with e.g. `gst.Registry.featureFilter`
/// to get a list of pluginfeature that match certain criteria.
pub const PluginFeatureFilter = *const fn (p_feature: *gst.PluginFeature, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that can be used with e.g. `gst.Registry.pluginFilter`
/// to get a list of plugins that match certain criteria.
pub const PluginFilter = *const fn (p_plugin: *gst.Plugin, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A plugin should provide a pointer to a function of either `gst.PluginInitFunc`
/// or this type in the plugin_desc struct.
/// The function will be called by the loader at startup. One would then
/// register each `gst.PluginFeature`. This version allows
/// user data to be passed to init function (useful for bindings).
pub const PluginInitFullFunc = *const fn (p_plugin: *gst.Plugin, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A plugin should provide a pointer to a function of this type in the
/// plugin_desc struct.
/// This function will be called by the loader at startup. One would then
/// register each `gst.PluginFeature`.
pub const PluginInitFunc = *const fn (p_plugin: *gst.Plugin) callconv(.c) c_int;

pub const PromiseChangeFunc = *const fn (p_promise: *gst.Promise, p_user_data: ?*anyopaque) callconv(.c) void;

/// A function that will be called in `gst.Structure.filterAndMapInPlace`.
/// The function may modify `value`, and the value will be removed from
/// the structure if `FALSE` is returned.
pub const StructureFilterMapFunc = *const fn (p_field_id: glib.Quark, p_value: *gobject.Value, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.Structure.filterAndMapInPlaceIdStr`.
/// The function may modify `value`, and the value will be removed from the
/// structure if `FALSE` is returned.
pub const StructureFilterMapIdStrFunc = *const fn (p_fieldname: *const gst.IdStr, p_value: *gobject.Value, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.Structure.foreach`. The function may
/// not modify `value`.
pub const StructureForeachFunc = *const fn (p_field_id: glib.Quark, p_value: *const gobject.Value, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.Structure.foreachIdStr`. The
/// function may not modify `value`.
pub const StructureForeachIdStrFunc = *const fn (p_fieldname: *const gst.IdStr, p_value: *const gobject.Value, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.Structure.mapInPlace`. The function
/// may modify `value`.
pub const StructureMapFunc = *const fn (p_field_id: glib.Quark, p_value: *gobject.Value, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.Structure.mapInPlaceIdStr`. The
/// function may modify `value`.
pub const StructureMapIdStrFunc = *const fn (p_fieldname: *const gst.IdStr, p_value: *gobject.Value, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// A function that will be called in `gst.TagList.foreach`. The function may
/// not modify the tag list.
pub const TagForeachFunc = *const fn (p_list: *const gst.TagList, p_tag: [*:0]const u8, p_user_data: ?*anyopaque) callconv(.c) void;

/// A function for merging multiple values of a tag used when registering
/// tags.
pub const TagMergeFunc = *const fn (p_dest: *gobject.Value, p_src: *const gobject.Value) callconv(.c) void;

/// A function that will repeatedly be called in the thread created by
/// a `gst.Task`.
pub const TaskFunction = *const fn (p_user_data: ?*anyopaque) callconv(.c) void;

/// Task function, see `gst.TaskPool.push`.
pub const TaskPoolFunction = *const fn (p_user_data: ?*anyopaque) callconv(.c) void;

/// Custom GstTask thread callback functions that can be installed.
pub const TaskThreadFunc = *const fn (p_task: *gst.Task, p_thread: *glib.Thread, p_user_data: ?*anyopaque) callconv(.c) void;

/// A function that will be called by typefinding.
pub const TypeFindFunction = *const fn (p_find: *gst.TypeFind, p_user_data: ?*anyopaque) callconv(.c) void;

/// Used together with `gst.valueCompare` to compare `gobject.Value` items.
pub const ValueCompareFunc = *const fn (p_value1: *const gobject.Value, p_value2: *const gobject.Value) callconv(.c) c_int;

/// Used by `gst.valueDeserialize` to parse a non-binary form into the `gobject.Value`.
pub const ValueDeserializeFunc = *const fn (p_dest: *gobject.Value, p_s: [*:0]const u8) callconv(.c) c_int;

/// Used by `gst.valueDeserializeWithPspec` to parse a non-binary form into the `gobject.Value`.
pub const ValueDeserializeWithPSpecFunc = *const fn (p_dest: *gobject.Value, p_s: [*:0]const u8, p_pspec: *gobject.ParamSpec) callconv(.c) c_int;

/// Used by `gst.valueSerialize` to obtain a non-binary form of the `gobject.Value`.
///
/// Free-function: g_free
pub const ValueSerializeFunc = *const fn (p_value1: *const gobject.Value) callconv(.c) [*:0]u8;

/// The allocator name for the default system memory allocator
pub const ALLOCATOR_SYSMEM = "SystemMemory";
/// Combination of all possible fields that can be copied with
/// `gst.Buffer.copyInto`.
pub const BUFFER_COPY_ALL = 15;
/// Combination of all possible metadata fields that can be copied with
/// `gst.Buffer.copyInto`.
pub const BUFFER_COPY_METADATA = 7;
/// Constant for no-offset return results.
pub const BUFFER_OFFSET_NONE = 18446744073709551615;
pub const CAN_INLINE = 1;
pub const CAPS_FEATURE_MEMORY_SYSTEM_MEMORY = "memory:SystemMemory";
/// Constant to define an undefined clock time.
pub const CLOCK_TIME_NONE = 18446744073709551615;
pub const DEBUG_BG_MASK = 240;
pub const DEBUG_FG_MASK = 15;
pub const DEBUG_FORMAT_MASK = 65280;
pub const ELEMENT_FACTORY_KLASS_DECODER = "Decoder";
pub const ELEMENT_FACTORY_KLASS_DECRYPTOR = "Decryptor";
pub const ELEMENT_FACTORY_KLASS_DEMUXER = "Demuxer";
pub const ELEMENT_FACTORY_KLASS_DEPAYLOADER = "Depayloader";
pub const ELEMENT_FACTORY_KLASS_ENCODER = "Encoder";
pub const ELEMENT_FACTORY_KLASS_ENCRYPTOR = "Encryptor";
pub const ELEMENT_FACTORY_KLASS_FORMATTER = "Formatter";
/// Elements interacting with hardware devices should specify this classifier in
/// their metadata. You may need to put the element in "READY" state to test if
/// the hardware is present in the system.
pub const ELEMENT_FACTORY_KLASS_HARDWARE = "Hardware";
pub const ELEMENT_FACTORY_KLASS_MEDIA_AUDIO = "Audio";
pub const ELEMENT_FACTORY_KLASS_MEDIA_IMAGE = "Image";
pub const ELEMENT_FACTORY_KLASS_MEDIA_METADATA = "Metadata";
pub const ELEMENT_FACTORY_KLASS_MEDIA_SUBTITLE = "Subtitle";
pub const ELEMENT_FACTORY_KLASS_MEDIA_VIDEO = "Video";
pub const ELEMENT_FACTORY_KLASS_MUXER = "Muxer";
pub const ELEMENT_FACTORY_KLASS_PARSER = "Parser";
pub const ELEMENT_FACTORY_KLASS_PAYLOADER = "Payloader";
pub const ELEMENT_FACTORY_KLASS_SINK = "Sink";
pub const ELEMENT_FACTORY_KLASS_SRC = "Source";
/// Elements of any of the defined GST_ELEMENT_FACTORY_LIST types
pub const ELEMENT_FACTORY_TYPE_ANY = 562949953421311;
/// All sinks handling audio, video or image media types
pub const ELEMENT_FACTORY_TYPE_AUDIOVIDEO_SINKS = 3940649673949188;
/// All encoders handling audio media types
pub const ELEMENT_FACTORY_TYPE_AUDIO_ENCODER = 1125899906842626;
/// All elements used to 'decode' streams (decoders, demuxers, parsers, depayloaders)
pub const ELEMENT_FACTORY_TYPE_DECODABLE = 1377;
pub const ELEMENT_FACTORY_TYPE_DECODER = 1;
pub const ELEMENT_FACTORY_TYPE_DECRYPTOR = 1024;
pub const ELEMENT_FACTORY_TYPE_DEMUXER = 32;
pub const ELEMENT_FACTORY_TYPE_DEPAYLOADER = 256;
pub const ELEMENT_FACTORY_TYPE_ENCODER = 2;
pub const ELEMENT_FACTORY_TYPE_ENCRYPTOR = 2048;
pub const ELEMENT_FACTORY_TYPE_FORMATTER = 512;
pub const ELEMENT_FACTORY_TYPE_HARDWARE = 4096;
pub const ELEMENT_FACTORY_TYPE_MAX_ELEMENTS = 281474976710656;
/// Elements matching any of the defined GST_ELEMENT_FACTORY_TYPE_MEDIA types
///
/// Note: Do not use this if you wish to not filter against any of the defined
/// media types. If you wish to do this, simply don't specify any
/// GST_ELEMENT_FACTORY_TYPE_MEDIA flag.
pub const ELEMENT_FACTORY_TYPE_MEDIA_ANY = 18446462598732840960;
pub const ELEMENT_FACTORY_TYPE_MEDIA_AUDIO = 1125899906842624;
pub const ELEMENT_FACTORY_TYPE_MEDIA_IMAGE = 2251799813685248;
pub const ELEMENT_FACTORY_TYPE_MEDIA_METADATA = 9007199254740992;
pub const ELEMENT_FACTORY_TYPE_MEDIA_SUBTITLE = 4503599627370496;
pub const ELEMENT_FACTORY_TYPE_MEDIA_VIDEO = 562949953421312;
pub const ELEMENT_FACTORY_TYPE_MUXER = 16;
pub const ELEMENT_FACTORY_TYPE_PARSER = 64;
pub const ELEMENT_FACTORY_TYPE_PAYLOADER = 128;
pub const ELEMENT_FACTORY_TYPE_SINK = 4;
pub const ELEMENT_FACTORY_TYPE_SRC = 8;
/// Timestamp correcting elements
pub const ELEMENT_FACTORY_TYPE_TIMESTAMPER = 8192;
/// All encoders handling video or image media types
pub const ELEMENT_FACTORY_TYPE_VIDEO_ENCODER = 2814749767106562;
/// Name and contact details of the author(s). Use \n to separate
/// multiple author details.
/// E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
pub const ELEMENT_METADATA_AUTHOR = "author";
/// Sentence describing the purpose of the element.
/// E.g: "Write stream to a file"
pub const ELEMENT_METADATA_DESCRIPTION = "description";
/// Set uri pointing to user documentation. Applications can use this to show
/// help for e.g. effects to users.
pub const ELEMENT_METADATA_DOC_URI = "doc-uri";
/// Elements that bridge to certain other products can include an icon of that
/// used product. Application can show the icon in menus/selectors to help
/// identifying specific elements.
pub const ELEMENT_METADATA_ICON_NAME = "icon-name";
/// String describing the type of element, as an unordered list
/// separated with slashes ('/'). See draft-klass.txt of the design docs
/// for more details and common types. E.g: "Sink/File"
pub const ELEMENT_METADATA_KLASS = "klass";
/// The long English name of the element. E.g. "File Sink"
pub const ELEMENT_METADATA_LONGNAME = "long-name";
/// Builds a string using errno describing the previously failed system
/// call.  To be used as the debug argument in `GST_ELEMENT_ERROR`.
pub const ERROR_SYSTEM = "system error: %s";
pub const EVENT_NUM_SHIFT = 8;
/// The same thing as `GST_EVENT_TYPE_UPSTREAM` | `GST_EVENT_TYPE_DOWNSTREAM`.
pub const EVENT_TYPE_BOTH = 3;
/// A mask value with all bits set, for use as a
/// GstFlagSet mask where all flag bits must match
/// exactly
pub const FLAG_SET_MASK_EXACT = 4294967295;
/// The PERCENT format is between 0 and this value
pub const FORMAT_PERCENT_MAX = 1000000;
/// The value used to scale down the reported PERCENT format value to
/// its real value.
pub const FORMAT_PERCENT_SCALE = 10000;
/// Can be used together with `GST_FOURCC_ARGS` to properly output a
/// `guint32` fourcc value in a printf\()-style text message.
///
/// ```
/// printf ("fourcc: %" GST_FOURCC_FORMAT "\n", GST_FOURCC_ARGS (fcc));
/// ```
pub const FOURCC_FORMAT = "c%c%c%c";
/// A value which is guaranteed to never be returned by
/// `gst.utilGroupIdNext`.
///
/// Can be used as a default value in variables used to store group_id.
pub const GROUP_ID_INVALID = 0;
/// To be used in GST_PLUGIN_DEFINE if unsure about the licence.
pub const LICENSE_UNKNOWN = "unknown";
/// GstLockFlags value alias for GST_LOCK_FLAG_READ | GST_LOCK_FLAG_WRITE
pub const LOCK_FLAG_READWRITE = 3;
/// GstMapFlags value alias for GST_MAP_READ | GST_MAP_WRITE
pub const MAP_READWRITE = 3;
/// This metadata stays relevant until a deep copy is made.
pub const META_TAG_MEMORY_REFERENCE_STR = "memory-reference";
/// This metadata stays relevant as long as memory layout is unchanged.
/// In hindsight, this tag should have been called "memory-layout".
pub const META_TAG_MEMORY_STR = "memory";
/// Constant that defines one GStreamer millisecond.
pub const MSECOND = 1000000;
/// Constant that defines one GStreamer nanosecond
pub const NSECOND = 1;
/// Use this flag on GObject properties of GstObject to indicate that
/// they might not be available depending on environment such as OS, device, etc,
/// so such properties will be installed conditionally only if the GstObject is
/// able to support it.
pub const PARAM_CONDITIONALLY_AVAILABLE = 16384;
/// Use this flag on GObject properties to signal they can make sense to be.
/// controlled over time. This hint is used by the GstController.
pub const PARAM_CONTROLLABLE = 512;
/// Use this flag on GObject properties of GstObject to indicate that
/// during `gst-inspect` and friends, the default value should be used
/// as default instead of the current value.
pub const PARAM_DOC_SHOW_DEFAULT = 8192;
/// Use this flag on GObject properties of GstElements to indicate that
/// they can be changed when the element is in the PAUSED or lower state.
/// This flag implies GST_PARAM_MUTABLE_READY.
pub const PARAM_MUTABLE_PAUSED = 2048;
/// Use this flag on GObject properties of GstElements to indicate that
/// they can be changed when the element is in the PLAYING or lower state.
/// This flag implies GST_PARAM_MUTABLE_PAUSED.
pub const PARAM_MUTABLE_PLAYING = 4096;
/// Use this flag on GObject properties of GstElements to indicate that
/// they can be changed when the element is in the READY or lower state.
pub const PARAM_MUTABLE_READY = 1024;
/// Bits based on GST_PARAM_USER_SHIFT can be used by 3rd party applications.
pub const PARAM_USER_SHIFT = 65536;
/// The field name in a GstCaps that is used to signal the UUID of the protection
/// system.
pub const PROTECTION_SYSTEM_ID_CAPS_FIELD = "protection-system";
/// The protection system value of the unspecified UUID.
/// In some cases the system protection ID is not present in the contents or in their
/// metadata, as encrypted WebM.
/// This define is used to set the value of the "system_id" field in GstProtectionEvent,
/// with this value, the application will use an external information to choose which
/// protection system to use.
///
/// Example: The matroskademux uses this value in the case of encrypted WebM,
/// the application will choose the appropriate protection system based on the information
/// received through EME API.
pub const PROTECTION_UNSPECIFIED_SYSTEM_ID = "unspecified-system-id";
/// printf format type used to debug GStreamer types. You can use this in
/// combination with GStreamer's debug logging system as well as the functions
/// `gst.infoVasprintf`, `gst.infoStrdupVprintf` and `gst.infoStrdupPrintf`
/// to pretty-print the following types: `gst.Caps`, `gst.Structure`,
/// `gst.CapsFeatures`, `gst.TagList`, `gst.DateTime`, `gst.Buffer`, `gst.BufferList`,
/// `gst.Message`, `gst.Event`, `gst.Query`, `gst.Context`, `gst.Pad`, `gst.Object`. All
/// `gobject.Object` types will be printed as typename plus pointer, and everything
/// else will simply be printed as pointer address.
///
/// This can only be used on types whose size is >= sizeof(gpointer).
pub const PTR_FORMAT = "paA";
pub const QUERY_NUM_SHIFT = 8;
/// The same thing as `GST_QUERY_TYPE_UPSTREAM` | `GST_QUERY_TYPE_DOWNSTREAM`.
pub const QUERY_TYPE_BOTH = 3;
/// Constant that defines one GStreamer second.
pub const SECOND = 1000000000;
/// printf format type used to debug GStreamer segments. You can use this in
/// combination with GStreamer's debug logging system as well as the functions
/// `gst.infoVasprintf`, `gst.infoStrdupVprintf` and `gst.infoStrdupPrintf`
/// to pretty-print `gst.Segment` structures.
/// This can only be used on pointers to GstSegment structures.
pub const SEGMENT_FORMAT = "paB";
pub const SEGMENT_INSTANT_FLAGS = 912;
/// A value which is guaranteed to never be returned by
/// `gst.utilSeqnumNext`.
///
/// Can be used as a default value in variables used to store seqnum.
pub const SEQNUM_INVALID = 0;
/// printf format type used to debug GStreamer signed time value pointers. You
/// can use this in combination with GStreamer's debug logging system as well as
/// the functions `gst.infoVasprintf`, `gst.infoStrdupVprintf` and
/// `gst.infoStrdupPrintf` to pretty-print signed time (pointers to
/// `gst.ClockTimeDiff` or `gint64`).
pub const STIMEP_FORMAT = "paS";
/// A string that can be used in printf-like format strings to display a signed
/// `gst.ClockTimeDiff` or `gint64` value in `h:m:s` format.  Use `GST_TIME_ARGS` to
/// construct the matching arguments.
///
/// Example:
///
/// ``` C
/// printf("%" GST_STIME_FORMAT "\n", GST_STIME_ARGS(ts));
/// ```
pub const STIME_FORMAT = "c%";
/// album containing this data (string)
///
/// The album name as it should be displayed, e.g. 'The Jazz Guitar'
pub const TAG_ALBUM = "album";
/// The artist of the entire album, as it should be displayed.
pub const TAG_ALBUM_ARTIST = "album-artist";
/// The artist of the entire album, as it should be sorted.
pub const TAG_ALBUM_ARTIST_SORTNAME = "album-artist-sortname";
/// album gain in db (double)
pub const TAG_ALBUM_GAIN = "replaygain-album-gain";
/// peak of the album (double)
pub const TAG_ALBUM_PEAK = "replaygain-album-peak";
/// album containing this data, as used for sorting (string)
///
/// The album name as it should be sorted, e.g. 'Jazz Guitar, The'
pub const TAG_ALBUM_SORTNAME = "album-sortname";
/// count of discs inside collection this disc belongs to (unsigned integer)
pub const TAG_ALBUM_VOLUME_COUNT = "album-disc-count";
/// disc number inside a collection (unsigned integer)
pub const TAG_ALBUM_VOLUME_NUMBER = "album-disc-number";
/// Arbitrary application data (sample)
///
/// Some formats allow applications to add their own arbitrary data
/// into files. This data is application dependent.
pub const TAG_APPLICATION_DATA = "application-data";
/// Name of the application used to create the media (string)
pub const TAG_APPLICATION_NAME = "application-name";
/// person(s) responsible for the recording (string)
///
/// The artist name as it should be displayed, e.g. 'Jimi Hendrix' or
/// 'The Guitar Heroes'
pub const TAG_ARTIST = "artist";
/// person(s) responsible for the recording, as used for sorting (string)
///
/// The artist name as it should be sorted, e.g. 'Hendrix, Jimi' or
/// 'Guitar Heroes, The'
pub const TAG_ARTIST_SORTNAME = "artist-sortname";
/// generic file attachment (sample) (sample taglist should specify the content
/// type and if possible set "filename" to the file name of the
/// attachment)
pub const TAG_ATTACHMENT = "attachment";
/// codec the audio data is stored in (string)
pub const TAG_AUDIO_CODEC = "audio-codec";
/// number of beats per minute in audio (double)
pub const TAG_BEATS_PER_MINUTE = "beats-per-minute";
/// exact or average bitrate in bits/s (unsigned integer)
pub const TAG_BITRATE = "bitrate";
/// codec the data is stored in (string)
pub const TAG_CODEC = "codec";
/// free text commenting the data (string)
pub const TAG_COMMENT = "comment";
/// person(s) who composed the recording (string)
pub const TAG_COMPOSER = "composer";
/// The composer's name, used for sorting (string)
pub const TAG_COMPOSER_SORTNAME = "composer-sortname";
/// conductor/performer refinement (string)
pub const TAG_CONDUCTOR = "conductor";
/// contact information (string)
pub const TAG_CONTACT = "contact";
/// container format the data is stored in (string)
pub const TAG_CONTAINER_FORMAT = "container-format";
/// Unique identifier for the audio, video or text track this tag is associated
/// with. The mappings for several container formats are defined in the [Sourcing
/// In-band Media Resource Tracks from Media Containers into HTML
/// specification](https://dev.w3.org/html5/html-sourcing-inband-tracks/).
pub const TAG_CONTAINER_SPECIFIC_TRACK_ID = "container-specific-track-id";
/// copyright notice of the data (string)
pub const TAG_COPYRIGHT = "copyright";
/// URI to location where copyright details can be found (string)
pub const TAG_COPYRIGHT_URI = "copyright-uri";
/// date the data was created (`glib.Date` structure)
pub const TAG_DATE = "date";
/// date and time the data was created (`gst.DateTime` structure)
pub const TAG_DATE_TIME = "datetime";
/// short text describing the content of the data (string)
pub const TAG_DESCRIPTION = "description";
/// Manufacturer of the device used to create the media (string)
pub const TAG_DEVICE_MANUFACTURER = "device-manufacturer";
/// Model of the device used to create the media (string)
pub const TAG_DEVICE_MODEL = "device-model";
/// length in GStreamer time units (nanoseconds) (unsigned 64-bit integer)
pub const TAG_DURATION = "duration";
/// name of the person or organisation that encoded the file. May contain a
/// copyright message if the person or organisation also holds the copyright
/// (string)
///
/// Note: do not use this field to describe the encoding application. Use
/// `GST_TAG_APPLICATION_NAME` or `GST_TAG_COMMENT` for that.
pub const TAG_ENCODED_BY = "encoded-by";
/// encoder used to encode this stream (string)
pub const TAG_ENCODER = "encoder";
/// version of the encoder used to encode this stream (unsigned integer)
pub const TAG_ENCODER_VERSION = "encoder-version";
/// key/value text commenting the data (string)
///
/// Must be in the form of 'key=comment' or
/// 'key[lc]=comment' where 'lc' is an ISO-639
/// language code.
///
/// This tag is used for unknown Vorbis comment tags,
/// unknown APE tags and certain ID3v2 comment fields.
pub const TAG_EXTENDED_COMMENT = "extended-comment";
/// genre this data belongs to (string)
pub const TAG_GENRE = "genre";
/// Indicates the direction the device is pointing to when capturing
/// a media. It is represented as degrees in floating point representation,
/// 0 means the geographic north, and increases clockwise (double from 0 to 360)
///
/// See also `GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION`
pub const TAG_GEO_LOCATION_CAPTURE_DIRECTION = "geo-location-capture-direction";
/// The city (english name) where the media has been produced (string).
pub const TAG_GEO_LOCATION_CITY = "geo-location-city";
/// The country (english name) where the media has been produced (string).
pub const TAG_GEO_LOCATION_COUNTRY = "geo-location-country";
/// geo elevation of where the media has been recorded or produced in meters
/// according to WGS84 (zero is average sea level) (double).
pub const TAG_GEO_LOCATION_ELEVATION = "geo-location-elevation";
/// Represents the expected error on the horizontal positioning in
/// meters (double).
pub const TAG_GEO_LOCATION_HORIZONTAL_ERROR = "geo-location-horizontal-error";
/// geo latitude location of where the media has been recorded or produced in
/// degrees according to WGS84 (zero at the equator, negative values for southern
/// latitudes) (double).
pub const TAG_GEO_LOCATION_LATITUDE = "geo-location-latitude";
/// geo longitude location of where the media has been recorded or produced in
/// degrees according to WGS84 (zero at the prime meridian in Greenwich/UK,
/// negative values for western longitudes). (double).
pub const TAG_GEO_LOCATION_LONGITUDE = "geo-location-longitude";
/// Indicates the movement direction of the device performing the capture
/// of a media. It is represented as degrees in floating point representation,
/// 0 means the geographic north, and increases clockwise (double from 0 to 360)
///
/// See also `GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION`
pub const TAG_GEO_LOCATION_MOVEMENT_DIRECTION = "geo-location-movement-direction";
/// Speed of the capturing device when performing the capture.
/// Represented in m/s. (double)
///
/// See also `GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION`
pub const TAG_GEO_LOCATION_MOVEMENT_SPEED = "geo-location-movement-speed";
/// human readable descriptive location of where the media has been recorded or
/// produced. (string).
pub const TAG_GEO_LOCATION_NAME = "geo-location-name";
/// A location 'smaller' than GST_TAG_GEO_LOCATION_CITY that specifies better
/// where the media has been produced. (e.g. the neighborhood) (string).
///
/// This tag has been added as this is how it is handled/named in XMP's
/// Iptc4xmpcore schema.
pub const TAG_GEO_LOCATION_SUBLOCATION = "geo-location-sublocation";
/// Groups together media that are related and spans multiple tracks. An
/// example are multiple pieces of a concerto. (string)
pub const TAG_GROUPING = "grouping";
/// Homepage for this media (i.e. artist or movie homepage) (string)
pub const TAG_HOMEPAGE = "homepage";
/// image (sample) (sample taglist should specify the content type and preferably
/// also set "image-type" field as `GstTagImageType`)
pub const TAG_IMAGE = "image";
/// Represents the 'Orientation' tag from EXIF. Defines how the image
/// should be rotated and mirrored for display. (string)
///
/// This tag has a predefined set of allowed values:
///   "rotate-0"
///   "rotate-90"
///   "rotate-180"
///   "rotate-270"
///   "flip-rotate-0"
///   "flip-rotate-90"
///   "flip-rotate-180"
///   "flip-rotate-270"
///
/// The naming is adopted according to a possible transformation to perform
/// on the image to fix its orientation, obviously equivalent operations will
/// yield the same result.
///
/// Rotations indicated by the values are in clockwise direction and
/// 'flip' means an horizontal mirroring.
pub const TAG_IMAGE_ORIENTATION = "image-orientation";
/// Information about the people behind a remix and similar
/// interpretations of another existing piece (string)
pub const TAG_INTERPRETED_BY = "interpreted-by";
/// International Standard Recording Code - see http://www.ifpi.org/isrc/ (string)
pub const TAG_ISRC = "isrc";
/// comma separated keywords describing the content (string).
pub const TAG_KEYWORDS = "keywords";
/// ISO-639-2 or ISO-639-1 code for the language the content is in (string)
///
/// There is utility API in libgsttag in gst-plugins-base to obtain a translated
/// language name from the language code: ``gst_tag_get_language_name``
pub const TAG_LANGUAGE_CODE = "language-code";
/// Name of the language the content is in (string)
///
/// Free-form name of the language the content is in, if a language code
/// is not available. This tag should not be set in addition to a language
/// code. It is undefined what language or locale the language name is in.
pub const TAG_LANGUAGE_NAME = "language-name";
/// license of data (string)
pub const TAG_LICENSE = "license";
/// URI to location where license details can be found (string)
pub const TAG_LICENSE_URI = "license-uri";
/// Origin of media as a URI (location, where the original of the file or stream
/// is hosted) (string)
pub const TAG_LOCATION = "location";
/// The lyrics of the media (string)
pub const TAG_LYRICS = "lyrics";
/// maximum bitrate in bits/s (unsigned integer)
pub const TAG_MAXIMUM_BITRATE = "maximum-bitrate";
/// [Midi note number](http://en.wikipedia.org/wiki/Note`Note_designation_in_accordance_with_octave_name`)
/// of the audio track. This is useful for sample instruments and in particular
/// for multi-samples.
pub const TAG_MIDI_BASE_NOTE = "midi-base-note";
/// minimum bitrate in bits/s (unsigned integer)
pub const TAG_MINIMUM_BITRATE = "minimum-bitrate";
/// nominal bitrate in bits/s (unsigned integer). The actual bitrate might be
/// different from this target bitrate.
pub const TAG_NOMINAL_BITRATE = "nominal-bitrate";
/// organization (string)
pub const TAG_ORGANIZATION = "organization";
/// person(s) performing (string)
pub const TAG_PERFORMER = "performer";
/// image that is meant for preview purposes, e.g. small icon-sized version
/// (sample) (sample taglist should specify the content type)
pub const TAG_PREVIEW_IMAGE = "preview-image";
/// Any private data that may be contained in tags (sample).
///
/// It is represented by `gst.Sample` in which `gst.Buffer` contains the
/// binary data and the sample's info `gst.Structure` may contain any
/// extra information that identifies the origin or meaning of the data.
///
/// Private frames in ID3v2 tags ('PRIV' frames) will be represented
/// using this tag, in which case the GstStructure will be named
/// "ID3PrivateFrame" and contain a field named "owner" of type string
/// which contains the owner-identification string from the tag.
pub const TAG_PRIVATE_DATA = "private-data";
/// Name of the label or publisher (string)
pub const TAG_PUBLISHER = "publisher";
/// reference level of track and album gain values (double)
pub const TAG_REFERENCE_LEVEL = "replaygain-reference-level";
/// serial number of track (unsigned integer)
pub const TAG_SERIAL = "serial";
/// Number of the episode within a season/show (unsigned integer)
pub const TAG_SHOW_EPISODE_NUMBER = "show-episode-number";
/// Name of the show, used for displaying (string)
pub const TAG_SHOW_NAME = "show-name";
/// Number of the season of a show/series (unsigned integer)
pub const TAG_SHOW_SEASON_NUMBER = "show-season-number";
/// Name of the show, used for sorting (string)
pub const TAG_SHOW_SORTNAME = "show-sortname";
/// codec/format the subtitle data is stored in (string)
pub const TAG_SUBTITLE_CODEC = "subtitle-codec";
/// commonly used title (string)
///
/// The title as it should be displayed, e.g. 'The Doll House'
pub const TAG_TITLE = "title";
/// commonly used title, as used for sorting (string)
///
/// The title as it should be sorted, e.g. 'Doll House, The'
pub const TAG_TITLE_SORTNAME = "title-sortname";
/// count of tracks inside collection this track belongs to (unsigned integer)
pub const TAG_TRACK_COUNT = "track-count";
/// track gain in db (double)
pub const TAG_TRACK_GAIN = "replaygain-track-gain";
/// track number inside a collection (unsigned integer)
pub const TAG_TRACK_NUMBER = "track-number";
/// peak of the track (double)
pub const TAG_TRACK_PEAK = "replaygain-track-peak";
/// Rating attributed by a person (likely the application user).
/// The higher the value, the more the user likes this media
/// (unsigned int from 0 to 100)
pub const TAG_USER_RATING = "user-rating";
/// version of this data (string)
pub const TAG_VERSION = "version";
/// codec the video data is stored in (string)
pub const TAG_VIDEO_CODEC = "video-codec";
/// printf format type used to debug GStreamer ClockTime pointers. You can use
/// this in combination with GStreamer's debug logging system as well as the
/// functions `gst.infoVasprintf`, `gst.infoStrdupVprintf` and
/// `gst.infoStrdupPrintf` to pretty-print `gst.ClockTime` pointers. This can
/// only be used on pointers to GstClockTime values.
pub const TIMEP_FORMAT = "paT";
/// A string that can be used in printf-like format strings to display a
/// `gst.ClockTime` value in `h:m:s` format.  Use `GST_TIME_ARGS` to construct
/// the matching arguments.
///
/// Example:
///
/// ``` C
/// printf("%" GST_TIME_FORMAT "\n", GST_TIME_ARGS(ts));
/// ```
pub const TIME_FORMAT = "u:%02u:%02u.%09u";
/// Special value for the repeat_count set in `gst.TocEntry.setLoop` or
/// returned by `gst.TocEntry.setLoop` to indicate infinite looping.
pub const TOC_REPEAT_COUNT_INFINITE = -1;
/// Value for `gst.Uri`<!-- -->.port to indicate no port number.
pub const URI_NO_PORT = 0;
/// Constant that defines one GStreamer microsecond.
pub const USECOND = 1000;
/// Indicates that the first value provided to a comparison function
/// (`gst.valueCompare`) is equal to the second one.
pub const VALUE_EQUAL = 0;
/// Indicates that the first value provided to a comparison function
/// (`gst.valueCompare`) is greater than the second one.
pub const VALUE_GREATER_THAN = 1;
/// Indicates that the first value provided to a comparison function
/// (`gst.valueCompare`) is lesser than the second one.
pub const VALUE_LESS_THAN = -1;
/// Indicates that the comparison function (`gst.valueCompare`) can not
/// determine a order for the two provided values.
pub const VALUE_UNORDERED = 2;
/// The major version of GStreamer at compile time:
pub const VERSION_MAJOR = 1;
/// The micro version of GStreamer at compile time:
pub const VERSION_MICRO = 11;
/// The minor version of GStreamer at compile time:
pub const VERSION_MINOR = 26;
/// The nano version of GStreamer at compile time:
/// Actual releases have 0, GIT versions have 1, prerelease versions have 2-...
pub const VERSION_NANO = 0;

test {
    @setEvalBranchQuota(100_000);
    std.testing.refAllDecls(@This());
    std.testing.refAllDecls(ext);
}
