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

const std = @import("std");
const compat = @import("compat");
const gstbase = @import("gstbase1");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
/// The `gstvideo.ColorBalanceChannel` object represents a parameter
/// for modifying the color balance implemented by an element providing the
/// `gstvideo.ColorBalance` interface. For example, Hue or Saturation.
pub const ColorBalanceChannel = extern struct {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.ColorBalanceChannelClass;
    f_parent: gobject.Object,
    /// A string containing a descriptive name for this channel
    f_label: ?[*:0]u8,
    /// The minimum valid value for this channel.
    f_min_value: c_int,
    /// The maximum valid value for this channel.
    f_max_value: c_int,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// default handler for value changed notification
        pub const value_changed = struct {
            pub fn call(p_class: anytype, p_channel: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_value: c_int) void {
                return gobject.ext.as(ColorBalanceChannel.Class, p_class).f_value_changed.?(gobject.ext.as(ColorBalanceChannel, p_channel), p_value);
            }

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

    pub const properties = struct {};

    pub const signals = struct {
        /// Fired when the value of the indicated channel has changed.
        pub const value_changed = struct {
            pub const name = "value-changed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_value: 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(ColorBalanceChannel, p_instance))),
                    gobject.signalLookup("value-changed", ColorBalanceChannel.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

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

    extern fn g_object_ref(p_self: *gstvideo.ColorBalanceChannel) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.ColorBalanceChannel) void;
    pub const unref = g_object_unref;

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

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

/// VideoAggregator can accept AYUV, ARGB and BGRA video streams. For each of the requested
/// sink pads it will compare the incoming geometry and framerate to define the
/// output parameters. Indeed output video frames will have the geometry of the
/// biggest incoming video stream and the framerate of the fastest incoming one.
///
/// VideoAggregator will do colorspace conversion.
///
/// Zorder for each input stream can be configured on the
/// `gstvideo.VideoAggregatorPad`.
pub const VideoAggregator = extern struct {
    pub const Parent = gstbase.Aggregator;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoAggregatorClass;
    f_aggregator: gstbase.Aggregator,
    /// The `gstvideo.VideoInfo` representing the currently set
    /// srcpad caps.
    f_info: gstvideo.VideoInfo,
    f_priv: ?*gstvideo.VideoAggregatorPrivate,
    f__gst_reserved: [20]*anyopaque,

    pub const virtual_methods = struct {
        /// Lets subclasses aggregate frames that are ready. Subclasses
        ///                            should iterate the GstElement.sinkpads and use the already
        ///                            mapped `gstvideo.VideoFrame` from `gstvideo.VideoAggregatorPad.getPreparedFrame`
        ///                            or directly use the `gst.Buffer` from `gstvideo.VideoAggregatorPad.getCurrentBuffer`
        ///                            if it needs to map the buffer in a special way. The result of the
        ///                            aggregation should land in `outbuffer`.
        pub const aggregate_frames = struct {
            pub fn call(p_class: anytype, p_videoaggregator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_outbuffer: *gst.Buffer) gst.FlowReturn {
                return gobject.ext.as(VideoAggregator.Class, p_class).f_aggregate_frames.?(gobject.ext.as(VideoAggregator, p_videoaggregator), p_outbuffer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_videoaggregator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_outbuffer: *gst.Buffer) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoAggregator.Class, p_class).f_aggregate_frames = @ptrCast(p_implementation);
            }
        };

        /// Optional.
        ///                            Lets subclasses provide a `gst.Buffer` to be used as `outbuffer` of
        ///                            the `aggregate_frames` vmethod.
        pub const create_output_buffer = struct {
            pub fn call(p_class: anytype, p_videoaggregator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_outbuffer: **gst.Buffer) gst.FlowReturn {
                return gobject.ext.as(VideoAggregator.Class, p_class).f_create_output_buffer.?(gobject.ext.as(VideoAggregator, p_videoaggregator), p_outbuffer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_videoaggregator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_outbuffer: **gst.Buffer) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoAggregator.Class, p_class).f_create_output_buffer = @ptrCast(p_implementation);
            }
        };

        pub const find_best_format = struct {
            pub fn call(p_class: anytype, p_vagg: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_downstream_caps: *gst.Caps, p_best_info: *gstvideo.VideoInfo, p_at_least_one_alpha: *c_int) void {
                return gobject.ext.as(VideoAggregator.Class, p_class).f_find_best_format.?(gobject.ext.as(VideoAggregator, p_vagg), p_downstream_caps, p_best_info, p_at_least_one_alpha);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_vagg: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_downstream_caps: *gst.Caps, p_best_info: *gstvideo.VideoInfo, p_at_least_one_alpha: *c_int) callconv(.c) void) void {
                gobject.ext.as(VideoAggregator.Class, p_class).f_find_best_format = @ptrCast(p_implementation);
            }
        };

        /// Optional.
        ///                            Lets subclasses update the `gst.Caps` representing
        ///                            the src pad caps before usage.  Return `NULL` to indicate failure.
        pub const update_caps = struct {
            pub fn call(p_class: anytype, p_videoaggregator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps) *gst.Caps {
                return gobject.ext.as(VideoAggregator.Class, p_class).f_update_caps.?(gobject.ext.as(VideoAggregator, p_videoaggregator), p_caps);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_videoaggregator: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps) callconv(.c) *gst.Caps) void {
                gobject.ext.as(VideoAggregator.Class, p_class).f_update_caps = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// Causes the element to aggregate on a timeout even when no live source is
        /// connected to its sinks. See `gstbase.Aggregator.properties.min`-upstream-latency for a
        /// companion property: in the vast majority of cases where you plan to plug in
        /// live sources with a non-zero latency, you should set it to a non-zero value.
        pub const force_live = struct {
            pub const name = "force-live";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    /// The returned `gst.TaskPool` is used internally for performing parallel
    /// video format conversions/scaling/etc during the
    /// `gstvideo.VideoAggregatorPadClass.signals.prepare_frame_start``prepare_frame_start` process.
    /// Subclasses can add their own operation to perform using the returned
    /// `gst.TaskPool` during `gstvideo.VideoAggregatorClass.signals.aggregate_frames``aggregate_frames`.
    extern fn gst_video_aggregator_get_execution_task_pool(p_vagg: *VideoAggregator) *gst.TaskPool;
    pub const getExecutionTaskPool = gst_video_aggregator_get_execution_task_pool;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoAggregator) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoAggregator) void;
    pub const unref = g_object_unref;

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

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

/// An implementation of GstPad that can be used with `gstvideo.VideoAggregator`.
///
/// See `gstvideo.VideoAggregator` for more details.
pub const VideoAggregatorConvertPad = extern struct {
    pub const Parent = gstvideo.VideoAggregatorPad;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoAggregatorConvertPadClass;
    f_parent: gstvideo.VideoAggregatorPad,
    f_priv: ?*gstvideo.VideoAggregatorConvertPadPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        pub const create_conversion_info = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_agg: *gstvideo.VideoAggregator, p_conversion_info: *gstvideo.VideoInfo) void {
                return gobject.ext.as(VideoAggregatorConvertPad.Class, p_class).f_create_conversion_info.?(gobject.ext.as(VideoAggregatorConvertPad, p_pad), p_agg, p_conversion_info);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_agg: *gstvideo.VideoAggregator, p_conversion_info: *gstvideo.VideoInfo) callconv(.c) void) void {
                gobject.ext.as(VideoAggregatorConvertPad.Class, p_class).f_create_conversion_info = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        pub const converter_config = struct {
            pub const name = "converter-config";

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

    pub const signals = struct {};

    /// Requests the pad to check and update the converter before the next usage to
    /// update for any changes that have happened.
    extern fn gst_video_aggregator_convert_pad_update_conversion_info(p_pad: *VideoAggregatorConvertPad) void;
    pub const updateConversionInfo = gst_video_aggregator_convert_pad_update_conversion_info;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoAggregatorConvertPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoAggregatorConvertPad) void;
    pub const unref = g_object_unref;

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

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

pub const VideoAggregatorPad = extern struct {
    pub const Parent = gstbase.AggregatorPad;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoAggregatorPadClass;
    f_parent: gstbase.AggregatorPad,
    /// The `gstvideo.VideoInfo` currently set on the pad
    f_info: gstvideo.VideoInfo,
    f_priv: ?*gstvideo.VideoAggregatorPadPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// clean the frame previously prepared in prepare_frame
        pub const clean_frame = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_prepared_frame: *gstvideo.VideoFrame) void {
                return gobject.ext.as(VideoAggregatorPad.Class, p_class).f_clean_frame.?(gobject.ext.as(VideoAggregatorPad, p_pad), p_videoaggregator, p_prepared_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) void) void {
                gobject.ext.as(VideoAggregatorPad.Class, p_class).f_clean_frame = @ptrCast(p_implementation);
            }
        };

        /// Prepare the frame from the pad buffer and sets it to prepared_frame.
        ///      Implementations should always return TRUE.  Returning FALSE will cease
        ///      iteration over subsequent pads.
        pub const prepare_frame = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_buffer: *gst.Buffer, p_prepared_frame: *gstvideo.VideoFrame) c_int {
                return gobject.ext.as(VideoAggregatorPad.Class, p_class).f_prepare_frame.?(gobject.ext.as(VideoAggregatorPad, p_pad), p_videoaggregator, p_buffer, p_prepared_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_buffer: *gst.Buffer, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) c_int) void {
                gobject.ext.as(VideoAggregatorPad.Class, p_class).f_prepare_frame = @ptrCast(p_implementation);
            }
        };

        /// Finish preparing `prepared_frame`.
        ///
        /// If overriden, `prepare_frame_start` must also be overriden.
        pub const prepare_frame_finish = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_prepared_frame: *gstvideo.VideoFrame) void {
                return gobject.ext.as(VideoAggregatorPad.Class, p_class).f_prepare_frame_finish.?(gobject.ext.as(VideoAggregatorPad, p_pad), p_videoaggregator, p_prepared_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) void) void {
                gobject.ext.as(VideoAggregatorPad.Class, p_class).f_prepare_frame_finish = @ptrCast(p_implementation);
            }
        };

        /// Begin preparing the frame from the pad buffer and sets it to prepared_frame.
        ///
        /// If overriden, `prepare_frame_finish` must also be overriden.
        pub const prepare_frame_start = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_buffer: *gst.Buffer, p_prepared_frame: *gstvideo.VideoFrame) void {
                return gobject.ext.as(VideoAggregatorPad.Class, p_class).f_prepare_frame_start.?(gobject.ext.as(VideoAggregatorPad, p_pad), p_videoaggregator, p_buffer, p_prepared_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_videoaggregator: *gstvideo.VideoAggregator, p_buffer: *gst.Buffer, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) void) void {
                gobject.ext.as(VideoAggregatorPad.Class, p_class).f_prepare_frame_start = @ptrCast(p_implementation);
            }
        };

        /// Called when either the input or output formats
        ///                          have changed.
        pub const update_conversion_info = struct {
            pub fn call(p_class: anytype, p_pad: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(VideoAggregatorPad.Class, p_class).f_update_conversion_info.?(gobject.ext.as(VideoAggregatorPad, p_pad));
            }

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

    pub const properties = struct {
        pub const max_last_buffer_repeat = struct {
            pub const name = "max-last-buffer-repeat";

            pub const Type = u64;
        };

        pub const repeat_after_eos = struct {
            pub const name = "repeat-after-eos";

            pub const Type = c_int;
        };

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

            pub const Type = c_uint;
        };
    };

    pub const signals = struct {};

    /// Returns the currently queued buffer that is going to be used
    /// for the current output frame.
    ///
    /// This must only be called from the `gstvideo.VideoAggregatorClass.signals.aggregate_frames` virtual method,
    /// or from the `gstvideo.VideoAggregatorPadClass.signals.prepare_frame` virtual method of the aggregator pads.
    ///
    /// The return value is only valid until `gstvideo.VideoAggregatorClass.signals.aggregate_frames` or `gstvideo.VideoAggregatorPadClass.signals.prepare_frame`
    /// returns.
    extern fn gst_video_aggregator_pad_get_current_buffer(p_pad: *VideoAggregatorPad) *gst.Buffer;
    pub const getCurrentBuffer = gst_video_aggregator_pad_get_current_buffer;

    /// Returns the currently prepared video frame that has to be aggregated into
    /// the current output frame.
    ///
    /// This must only be called from the `gstvideo.VideoAggregatorClass.signals.aggregate_frames` virtual method,
    /// or from the `gstvideo.VideoAggregatorPadClass.signals.prepare_frame` virtual method of the aggregator pads.
    ///
    /// The return value is only valid until `gstvideo.VideoAggregatorClass.signals.aggregate_frames` or `gstvideo.VideoAggregatorPadClass.signals.prepare_frame`
    /// returns.
    extern fn gst_video_aggregator_pad_get_prepared_frame(p_pad: *VideoAggregatorPad) *gstvideo.VideoFrame;
    pub const getPreparedFrame = gst_video_aggregator_pad_get_prepared_frame;

    /// Checks if the pad currently has a buffer queued that is going to be used
    /// for the current output frame.
    ///
    /// This must only be called from the `gstvideo.VideoAggregatorClass.signals.aggregate_frames` virtual method,
    /// or from the `gstvideo.VideoAggregatorPadClass.signals.prepare_frame` virtual method of the aggregator pads.
    extern fn gst_video_aggregator_pad_has_current_buffer(p_pad: *VideoAggregatorPad) c_int;
    pub const hasCurrentBuffer = gst_video_aggregator_pad_has_current_buffer;

    /// Allows selecting that this pad requires an output format with alpha
    extern fn gst_video_aggregator_pad_set_needs_alpha(p_pad: *VideoAggregatorPad, p_needs_alpha: c_int) void;
    pub const setNeedsAlpha = gst_video_aggregator_pad_set_needs_alpha;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoAggregatorPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoAggregatorPad) void;
    pub const unref = g_object_unref;

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

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

/// An implementation of GstPad that can be used with `gstvideo.VideoAggregator`.
///
/// See `gstvideo.VideoAggregator` for more details.
pub const VideoAggregatorParallelConvertPad = extern struct {
    pub const Parent = gstvideo.VideoAggregatorConvertPad;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoAggregatorParallelConvertPadClass;
    f_parent_instance: gstvideo.VideoAggregatorConvertPad,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

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

    extern fn g_object_ref(p_self: *gstvideo.VideoAggregatorParallelConvertPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoAggregatorParallelConvertPad) void;
    pub const unref = g_object_unref;

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

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

pub const VideoBufferPool = extern struct {
    pub const Parent = gst.BufferPool;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoBufferPoolClass;
    f_bufferpool: gst.BufferPool,
    f_priv: ?*gstvideo.VideoBufferPoolPrivate,

    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    /// Create a new bufferpool that can allocate video frames. This bufferpool
    /// supports all the video bufferpool options.
    extern fn gst_video_buffer_pool_new() *gstvideo.VideoBufferPool;
    pub const new = gst_video_buffer_pool_new;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoBufferPool) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoBufferPool) void;
    pub const unref = g_object_unref;

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

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

/// This base class is for video decoders turning encoded data into raw video
/// frames.
///
/// The GstVideoDecoder base class and derived subclasses should cooperate as
/// follows:
///
/// ## Configuration
///
///   * Initially, GstVideoDecoder calls `start` when the decoder element
///     is activated, which allows the subclass to perform any global setup.
///
///   * GstVideoDecoder calls `set_format` to inform the subclass of caps
///     describing input video data that it is about to receive, including
///     possibly configuration data.
///     While unlikely, it might be called more than once, if changing input
///     parameters require reconfiguration.
///
///   * Incoming data buffers are processed as needed, described in Data
///     Processing below.
///
///   * GstVideoDecoder calls `stop` at end of all processing.
///
/// ## Data processing
///
///   * The base class gathers input data, and optionally allows subclass
///     to parse this into subsequently manageable chunks, typically
///     corresponding to and referred to as 'frames'.
///
///   * Each input frame is provided in turn to the subclass' `handle_frame`
///     callback.
///   * When the subclass enables the subframe mode with `gst_video_decoder_set_subframe_mode`,
///     the base class will provide to the subclass the same input frame with
///     different input buffers to the subclass `handle_frame`
///     callback. During this call, the subclass needs to take
///     ownership of the input_buffer as `GstVideoCodecFrame`.input_buffer
///     will have been changed before the next subframe buffer is received.
///     The subclass will call `gst_video_decoder_have_last_subframe`
///     when a new input frame can be created by the base class.
///     Every subframe will share the same `GstVideoCodecFrame`.output_buffer
///     to write the decoding result. The subclass is responsible to protect
///     its access.
///
///   * If codec processing results in decoded data, the subclass should call
///     `gst_video_decoder_finish_frame` to have decoded data pushed
///     downstream. In subframe mode
///     the subclass should call `gst_video_decoder_finish_subframe` until the
///     last subframe where it should call `gst_video_decoder_finish_frame`.
///     The subclass can detect the last subframe using GST_VIDEO_BUFFER_FLAG_MARKER
///     on buffers or using its own logic to collect the subframes.
///     In case of decoding failure, the subclass must call
///     `gst_video_decoder_drop_frame` or `gst_video_decoder_drop_subframe`,
///     to allow the base class to do timestamp and offset tracking, and possibly
///     to requeue the frame for a later attempt in the case of reverse playback.
///
/// ## Shutdown phase
///
///   * The GstVideoDecoder class calls `stop` to inform the subclass that data
///     parsing will be stopped.
///
/// ## Additional Notes
///
///   * Seeking/Flushing
///
///     * When the pipeline is seeked or otherwise flushed, the subclass is
///       informed via a call to its `reset` callback, with the hard parameter
///       set to true. This indicates the subclass should drop any internal data
///       queues and timestamps and prepare for a fresh set of buffers to arrive
///       for parsing and decoding.
///
///   * End Of Stream
///
///     * At end-of-stream, the subclass `parse` function may be called some final
///       times with the at_eos parameter set to true, indicating that the element
///       should not expect any more data to be arriving, and it should parse and
///       remaining frames and call `gstvideo.VideoDecoder.haveFrame` if possible.
///
/// The subclass is responsible for providing pad template caps for
/// source and sink pads. The pads need to be named "sink" and "src". It also
/// needs to provide information about the output caps, when they are known.
/// This may be when the base class calls the subclass' `set_format` function,
/// though it might be during decoding, before calling
/// `gst_video_decoder_finish_frame`. This is done via
/// `gst_video_decoder_set_output_state`
///
/// The subclass is also responsible for providing (presentation) timestamps
/// (likely based on corresponding input ones).  If that is not applicable
/// or possible, the base class provides limited framerate based interpolation.
///
/// Similarly, the base class provides some limited (legacy) seeking support
/// if specifically requested by the subclass, as full-fledged support
/// should rather be left to upstream demuxer, parser or alike.  This simple
/// approach caters for seeking and duration reporting using estimated input
/// bitrates. To enable it, a subclass should call
/// `gst_video_decoder_set_estimate_rate` to enable handling of incoming
/// byte-streams.
///
/// The base class provides some support for reverse playback, in particular
/// in case incoming data is not packetized or upstream does not provide
/// fragments on keyframe boundaries.  However, the subclass should then be
/// prepared for the parsing and frame processing stage to occur separately
/// (in normal forward processing, the latter immediately follows the former),
/// The subclass also needs to ensure the parsing stage properly marks
/// keyframes, unless it knows the upstream elements will do so properly for
/// incoming data.
///
/// The bare minimum that a functional subclass needs to implement is:
///
///   * Provide pad templates
///   * Inform the base class of output caps via
///      `gst_video_decoder_set_output_state`
///
///   * Parse input data, if it is not considered packetized from upstream
///      Data will be provided to `parse` which should invoke
///      `gst_video_decoder_add_to_frame` and `gst_video_decoder_have_frame` to
///      separate the data belonging to each video frame.
///
///   * Accept data in `handle_frame` and provide decoded results to
///      `gst_video_decoder_finish_frame`, or call `gst_video_decoder_drop_frame`.
pub const VideoDecoder = extern struct {
    pub const Parent = gst.Element;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoDecoderClass;
    f_element: gst.Element,
    f_sinkpad: ?*gst.Pad,
    f_srcpad: ?*gst.Pad,
    f_stream_lock: glib.RecMutex,
    f_input_segment: gst.Segment,
    f_output_segment: gst.Segment,
    f_priv: ?*gstvideo.VideoDecoderPrivate,
    f_padding: [20]*anyopaque,

    pub const virtual_methods = struct {
        /// Optional.
        ///                  Called when the element changes to GST_STATE_NULL.
        ///                  Allows closing external resources.
        pub const close = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_close.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Optional.
        ///                     Setup the allocation parameters for allocating output
        ///                     buffers. The passed in query contains the result of the
        ///                     downstream allocation query.
        ///                     Subclasses should chain up to the parent implementation to
        ///                     invoke the default handler.
        pub const decide_allocation = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_decide_allocation.?(gobject.ext.as(VideoDecoder, p_decoder), p_query);
            }

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

        /// Optional.
        ///                  Called to request subclass to decode any data it can at this
        ///                  point, but that more data may arrive after. (e.g. at segment end).
        ///                  Sub-classes should be prepared to handle new data afterward,
        ///                  or seamless segment processing will break. Since: 1.6
        pub const drain = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gst.FlowReturn {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_drain.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Optional.
        ///                  Called to request subclass to dispatch any pending remaining
        ///                  data at EOS. Sub-classes can refuse to decode new data after.
        pub const finish = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gst.FlowReturn {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_finish.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Optional.
        ///                      Flush all remaining data from the decoder without
        ///                      pushing it downstream. Since: 1.2
        pub const flush = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_flush.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Optional.
        ///                  Allows for a custom sink getcaps implementation.
        ///                  If not implemented, default returns
        ///                  gst_video_decoder_proxy_getcaps
        ///                  applied to sink template caps.
        pub const getcaps = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_filter: *gst.Caps) *gst.Caps {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_getcaps.?(gobject.ext.as(VideoDecoder, p_decoder), p_filter);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_filter: *gst.Caps) callconv(.c) *gst.Caps) void {
                gobject.ext.as(VideoDecoder.Class, p_class).f_getcaps = @ptrCast(p_implementation);
            }
        };

        pub const handle_frame = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_handle_frame.?(gobject.ext.as(VideoDecoder, p_decoder), p_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoDecoder.Class, p_class).f_handle_frame = @ptrCast(p_implementation);
            }
        };

        pub const handle_missing_data = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime, p_duration: gst.ClockTime) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_handle_missing_data.?(gobject.ext.as(VideoDecoder, p_decoder), p_timestamp, p_duration);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_timestamp: gst.ClockTime, p_duration: gst.ClockTime) callconv(.c) c_int) void {
                gobject.ext.as(VideoDecoder.Class, p_class).f_handle_missing_data = @ptrCast(p_implementation);
            }
        };

        /// Negotiate with downstream elements to currently configured `gstvideo.VideoCodecState`.
        /// Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
        /// negotiate fails.
        pub const negotiate = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_negotiate.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Optional.
        ///                  Called when the element changes to GST_STATE_READY.
        ///                  Allows opening external resources.
        pub const open = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_open.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Required for non-packetized input.
        ///                  Allows chopping incoming data into manageable units (frames)
        ///                  for subsequent decoding.
        pub const parse = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame, p_adapter: *gstbase.Adapter, p_at_eos: c_int) gst.FlowReturn {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_parse.?(gobject.ext.as(VideoDecoder, p_decoder), p_frame, p_adapter, p_at_eos);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame, p_adapter: *gstbase.Adapter, p_at_eos: c_int) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoDecoder.Class, p_class).f_parse = @ptrCast(p_implementation);
            }
        };

        /// Optional.
        ///                      Propose buffer allocation parameters for upstream elements.
        ///                      Subclasses should chain up to the parent implementation to
        ///                      invoke the default handler.
        pub const propose_allocation = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_propose_allocation.?(gobject.ext.as(VideoDecoder, p_decoder), p_query);
            }

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

        /// Optional.
        ///                  Allows subclass (decoder) to perform post-seek semantics reset.
        ///                  Deprecated.
        pub const reset = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_hard: c_int) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_reset.?(gobject.ext.as(VideoDecoder, p_decoder), p_hard);
            }

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

        /// Notifies subclass of incoming data format (caps).
        pub const set_format = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: *gstvideo.VideoCodecState) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_set_format.?(gobject.ext.as(VideoDecoder, p_decoder), p_state);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: *gstvideo.VideoCodecState) callconv(.c) c_int) void {
                gobject.ext.as(VideoDecoder.Class, p_class).f_set_format = @ptrCast(p_implementation);
            }
        };

        /// Optional.
        ///                  Event handler on the sink pad. This function should return
        ///                  TRUE if the event was handled and should be discarded
        ///                  (i.e. not unref'ed).
        ///                  Subclasses should chain up to the parent implementation to
        ///                  invoke the default handler.
        pub const sink_event = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_sink_event.?(gobject.ext.as(VideoDecoder, p_decoder), p_event);
            }

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

        /// Optional.
        ///                  Query handler on the sink pad. This function should
        ///                  return TRUE if the query could be performed. Subclasses
        ///                  should chain up to the parent implementation to invoke the
        ///                  default handler. Since: 1.4
        pub const sink_query = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_sink_query.?(gobject.ext.as(VideoDecoder, p_decoder), p_query);
            }

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

        /// Optional.
        ///                  Event handler on the source pad. This function should return
        ///                  TRUE if the event was handled and should be discarded
        ///                  (i.e. not unref'ed).
        ///                  Subclasses should chain up to the parent implementation to
        ///                  invoke the default handler.
        pub const src_event = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_src_event.?(gobject.ext.as(VideoDecoder, p_decoder), p_event);
            }

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

        /// Optional.
        ///                  Query handler on the source pad. This function should
        ///                  return TRUE if the query could be performed. Subclasses
        ///                  should chain up to the parent implementation to invoke the
        ///                  default handler. Since: 1.4
        pub const src_query = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_src_query.?(gobject.ext.as(VideoDecoder, p_decoder), p_query);
            }

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

        /// Optional.
        ///                  Called when the element starts processing.
        ///                  Allows opening external resources.
        pub const start = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_start.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Optional.
        ///                  Called when the element stops processing.
        ///                  Allows closing external resources.
        pub const stop = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_stop.?(gobject.ext.as(VideoDecoder, p_decoder));
            }

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

        /// Optional. Transform the metadata on the input buffer to the
        ///                  output buffer. By default this method is copies all meta without
        ///                  tags and meta with only the "video" tag. subclasses can
        ///                  implement this method and return `TRUE` if the metadata is to be
        ///                  copied. Since: 1.6
        pub const transform_meta = struct {
            pub fn call(p_class: anytype, p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame, p_meta: *gst.Meta) c_int {
                return gobject.ext.as(VideoDecoder.Class, p_class).f_transform_meta.?(gobject.ext.as(VideoDecoder, p_decoder), p_frame, p_meta);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_decoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame, p_meta: *gst.Meta) callconv(.c) c_int) void {
                gobject.ext.as(VideoDecoder.Class, p_class).f_transform_meta = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// GstVideoDecoderRequestSyncPointFlags to use for the automatically
        /// requested sync points if `automatic-request-sync-points` is enabled.
        pub const automatic_request_sync_point_flags = struct {
            pub const name = "automatic-request-sync-point-flags";

            pub const Type = gstvideo.VideoDecoderRequestSyncPointFlags;
        };

        /// If set to `TRUE` the decoder will automatically request sync points when
        /// it seems like a good idea, e.g. if the first frames are not key frames or
        /// if packet loss was reported by upstream.
        pub const automatic_request_sync_points = struct {
            pub const name = "automatic-request-sync-points";

            pub const Type = c_int;
        };

        /// If set to `TRUE` the decoder will discard frames that are marked as
        /// corrupted instead of outputting them.
        pub const discard_corrupted_frames = struct {
            pub const name = "discard-corrupted-frames";

            pub const Type = c_int;
        };

        /// Maximum number of tolerated consecutive decode errors. See
        /// `gstvideo.VideoDecoder.setMaxErrors` for more details.
        pub const max_errors = struct {
            pub const name = "max-errors";

            pub const Type = c_int;
        };

        /// Minimum interval between force-key-unit events sent upstream by the
        /// decoder. Setting this to 0 will cause every event to be handled, setting
        /// this to `GST_CLOCK_TIME_NONE` will cause every event to be ignored.
        ///
        /// See `gstvideo.videoEventNewUpstreamForceKeyUnit` for more details about
        /// force-key-unit events.
        pub const min_force_key_unit_interval = struct {
            pub const name = "min-force-key-unit-interval";

            pub const Type = u64;
        };

        /// If set to `TRUE` the decoder will handle QoS events received
        /// from downstream elements.
        /// This includes dropping output frames which are detected as late
        /// using the metrics reported by those events.
        pub const qos = struct {
            pub const name = "qos";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    /// Removes next `n_bytes` of input data and adds it to currently parsed frame.
    extern fn gst_video_decoder_add_to_frame(p_decoder: *VideoDecoder, p_n_bytes: c_int) void;
    pub const addToFrame = gst_video_decoder_add_to_frame;

    /// Helper function that allocates a buffer to hold a video frame for `decoder`'s
    /// current `gstvideo.VideoCodecState`.
    ///
    /// You should use `gstvideo.VideoDecoder.allocateOutputFrame` instead of this
    /// function, if possible at all.
    extern fn gst_video_decoder_allocate_output_buffer(p_decoder: *VideoDecoder) ?*gst.Buffer;
    pub const allocateOutputBuffer = gst_video_decoder_allocate_output_buffer;

    /// Helper function that allocates a buffer to hold a video frame for `decoder`'s
    /// current `gstvideo.VideoCodecState`.  Subclass should already have configured video
    /// state and set src pad caps.
    ///
    /// The buffer allocated here is owned by the frame and you should only
    /// keep references to the frame, not the buffer.
    extern fn gst_video_decoder_allocate_output_frame(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const allocateOutputFrame = gst_video_decoder_allocate_output_frame;

    /// Same as `gstvideo.VideoDecoder.allocateOutputFrame` except it allows passing
    /// `gst.BufferPoolAcquireParams` to the sub call gst_buffer_pool_acquire_buffer.
    extern fn gst_video_decoder_allocate_output_frame_with_params(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame, p_params: *gst.BufferPoolAcquireParams) gst.FlowReturn;
    pub const allocateOutputFrameWithParams = gst_video_decoder_allocate_output_frame_with_params;

    /// Similar to `gstvideo.VideoDecoder.finishFrame`, but drops `frame` in any
    /// case and posts a QoS message with the frame's details on the bus.
    /// In any case, the frame is considered finished and released.
    extern fn gst_video_decoder_drop_frame(p_dec: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const dropFrame = gst_video_decoder_drop_frame;

    /// Drops input data.
    /// The frame is not considered finished until the whole frame
    /// is finished or dropped by the subclass.
    extern fn gst_video_decoder_drop_subframe(p_dec: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const dropSubframe = gst_video_decoder_drop_subframe;

    /// `frame` should have a valid decoded data buffer, whose metadata fields
    /// are then appropriately set according to frame data and pushed downstream.
    /// If no output data is provided, `frame` is considered skipped.
    /// In any case, the frame is considered finished and released.
    ///
    /// After calling this function the output buffer of the frame is to be
    /// considered read-only. This function will also change the metadata
    /// of the buffer.
    extern fn gst_video_decoder_finish_frame(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const finishFrame = gst_video_decoder_finish_frame;

    /// Indicate that a subframe has been finished to be decoded
    /// by the subclass. This method should be called for all subframes
    /// except the last subframe where `gst_video_decoder_finish_frame`
    /// should be called instead.
    extern fn gst_video_decoder_finish_subframe(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const finishSubframe = gst_video_decoder_finish_subframe;

    /// Lets `gstvideo.VideoDecoder` sub-classes to know the memory `allocator`
    /// used by the base class and its `params`.
    ///
    /// Unref the `allocator` after use it.
    extern fn gst_video_decoder_get_allocator(p_decoder: *VideoDecoder, p_allocator: ?**gst.Allocator, p_params: ?*gst.AllocationParams) void;
    pub const getAllocator = gst_video_decoder_get_allocator;

    extern fn gst_video_decoder_get_buffer_pool(p_decoder: *VideoDecoder) ?*gst.BufferPool;
    pub const getBufferPool = gst_video_decoder_get_buffer_pool;

    extern fn gst_video_decoder_get_estimate_rate(p_dec: *VideoDecoder) c_int;
    pub const getEstimateRate = gst_video_decoder_get_estimate_rate;

    /// Get a pending unfinished `gstvideo.VideoCodecFrame`
    extern fn gst_video_decoder_get_frame(p_decoder: *VideoDecoder, p_frame_number: c_int) ?*gstvideo.VideoCodecFrame;
    pub const getFrame = gst_video_decoder_get_frame;

    /// Get all pending unfinished `gstvideo.VideoCodecFrame`
    extern fn gst_video_decoder_get_frames(p_decoder: *VideoDecoder) *glib.List;
    pub const getFrames = gst_video_decoder_get_frames;

    /// Queries the number of the last subframe received by
    /// the decoder baseclass in the `frame`.
    extern fn gst_video_decoder_get_input_subframe_index(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) c_uint;
    pub const getInputSubframeIndex = gst_video_decoder_get_input_subframe_index;

    /// Query the configured decoder latency. Results will be returned via
    /// `min_latency` and `max_latency`.
    extern fn gst_video_decoder_get_latency(p_decoder: *VideoDecoder, p_min_latency: ?*gst.ClockTime, p_max_latency: ?*gst.ClockTime) void;
    pub const getLatency = gst_video_decoder_get_latency;

    /// Determines maximum possible decoding time for `frame` that will
    /// allow it to decode and arrive in time (as determined by QoS events).
    /// In particular, a negative result means decoding in time is no longer possible
    /// and should therefore occur as soon/skippy as possible.
    extern fn gst_video_decoder_get_max_decode_time(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) gst.ClockTimeDiff;
    pub const getMaxDecodeTime = gst_video_decoder_get_max_decode_time;

    extern fn gst_video_decoder_get_max_errors(p_dec: *VideoDecoder) c_int;
    pub const getMaxErrors = gst_video_decoder_get_max_errors;

    /// Queries decoder required format handling.
    extern fn gst_video_decoder_get_needs_format(p_dec: *VideoDecoder) c_int;
    pub const getNeedsFormat = gst_video_decoder_get_needs_format;

    /// Queries if the decoder requires a sync point before it starts outputting
    /// data in the beginning.
    extern fn gst_video_decoder_get_needs_sync_point(p_dec: *VideoDecoder) c_int;
    pub const getNeedsSyncPoint = gst_video_decoder_get_needs_sync_point;

    /// Get the oldest pending unfinished `gstvideo.VideoCodecFrame`
    extern fn gst_video_decoder_get_oldest_frame(p_decoder: *VideoDecoder) ?*gstvideo.VideoCodecFrame;
    pub const getOldestFrame = gst_video_decoder_get_oldest_frame;

    /// Get the `gstvideo.VideoCodecState` currently describing the output stream.
    extern fn gst_video_decoder_get_output_state(p_decoder: *VideoDecoder) ?*gstvideo.VideoCodecState;
    pub const getOutputState = gst_video_decoder_get_output_state;

    /// Queries whether input data is considered packetized or not by the
    /// base class.
    extern fn gst_video_decoder_get_packetized(p_decoder: *VideoDecoder) c_int;
    pub const getPacketized = gst_video_decoder_get_packetized;

    /// Returns the number of bytes previously added to the current frame
    /// by calling `gstvideo.VideoDecoder.addToFrame`.
    extern fn gst_video_decoder_get_pending_frame_size(p_decoder: *VideoDecoder) usize;
    pub const getPendingFrameSize = gst_video_decoder_get_pending_frame_size;

    /// Queries the number of subframes in the frame processed by
    /// the decoder baseclass.
    extern fn gst_video_decoder_get_processed_subframe_index(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) c_uint;
    pub const getProcessedSubframeIndex = gst_video_decoder_get_processed_subframe_index;

    extern fn gst_video_decoder_get_qos_proportion(p_decoder: *VideoDecoder) f64;
    pub const getQosProportion = gst_video_decoder_get_qos_proportion;

    /// Queries whether input data is considered as subframes or not by the
    /// base class. If FALSE, each input buffer will be considered as a full
    /// frame.
    extern fn gst_video_decoder_get_subframe_mode(p_decoder: *VideoDecoder) c_int;
    pub const getSubframeMode = gst_video_decoder_get_subframe_mode;

    /// Gathers all data collected for currently parsed frame, gathers corresponding
    /// metadata and passes it along for further processing, i.e. `handle_frame`.
    extern fn gst_video_decoder_have_frame(p_decoder: *VideoDecoder) gst.FlowReturn;
    pub const haveFrame = gst_video_decoder_have_frame;

    /// Indicates that the last subframe has been processed by the decoder
    /// in `frame`. This will release the current frame in video decoder
    /// allowing to receive new frames from upstream elements. This method
    /// must be called in the subclass `handle_frame` callback.
    extern fn gst_video_decoder_have_last_subframe(p_decoder: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const haveLastSubframe = gst_video_decoder_have_last_subframe;

    /// Sets the audio decoder tags and how they should be merged with any
    /// upstream stream tags. This will override any tags previously-set
    /// with `gst_audio_decoder_merge_tags`.
    ///
    /// Note that this is provided for convenience, and the subclass is
    /// not required to use this and can still do tag handling on its own.
    ///
    /// MT safe.
    extern fn gst_video_decoder_merge_tags(p_decoder: *VideoDecoder, p_tags: ?*const gst.TagList, p_mode: gst.TagMergeMode) void;
    pub const mergeTags = gst_video_decoder_merge_tags;

    /// Negotiate with downstream elements to currently configured `gstvideo.VideoCodecState`.
    /// Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
    /// negotiate fails.
    extern fn gst_video_decoder_negotiate(p_decoder: *VideoDecoder) c_int;
    pub const negotiate = gst_video_decoder_negotiate;

    /// Returns caps that express `caps` (or sink template caps if `caps` == NULL)
    /// restricted to resolution/format/... combinations supported by downstream
    /// elements.
    extern fn gst_video_decoder_proxy_getcaps(p_decoder: *VideoDecoder, p_caps: ?*gst.Caps, p_filter: ?*gst.Caps) *gst.Caps;
    pub const proxyGetcaps = gst_video_decoder_proxy_getcaps;

    /// Similar to `gstvideo.VideoDecoder.dropFrame`, but simply releases `frame`
    /// without any processing other than removing it from list of pending frames,
    /// after which it is considered finished and released.
    extern fn gst_video_decoder_release_frame(p_dec: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) void;
    pub const releaseFrame = gst_video_decoder_release_frame;

    /// Allows the `gstvideo.VideoDecoder` subclass to request from the base class that
    /// a new sync should be requested from upstream, and that `frame` was the frame
    /// when the subclass noticed that a new sync point is required. A reason for
    /// the subclass to do this could be missing reference frames, for example.
    ///
    /// The base class will then request a new sync point from upstream as long as
    /// the time that passed since the last one is exceeding
    /// `gstvideo.VideoDecoder.properties.min`-force-key-unit-interval.
    ///
    /// The subclass can signal via `flags` how the frames until the next sync point
    /// should be handled:
    ///
    ///   * If `GST_VIDEO_DECODER_REQUEST_SYNC_POINT_DISCARD_INPUT` is selected then
    ///     all following input frames until the next sync point are discarded.
    ///     This can be useful if the lack of a sync point will prevent all further
    ///     decoding and the decoder implementation is not very robust in handling
    ///     missing references frames.
    ///   * If `GST_VIDEO_DECODER_REQUEST_SYNC_POINT_CORRUPT_OUTPUT` is selected
    ///     then all output frames following `frame` are marked as corrupted via
    ///     `GST_BUFFER_FLAG_CORRUPTED`. Corrupted frames can be automatically
    ///     dropped by the base class, see `gstvideo.VideoDecoder.properties.discard`-corrupted-frames.
    ///     Subclasses can manually mark frames as corrupted via `GST_VIDEO_CODEC_FRAME_FLAG_CORRUPTED`
    ///     before calling `gstvideo.VideoDecoder.finishFrame`.
    extern fn gst_video_decoder_request_sync_point(p_dec: *VideoDecoder, p_frame: *gstvideo.VideoCodecFrame, p_flags: gstvideo.VideoDecoderRequestSyncPointFlags) void;
    pub const requestSyncPoint = gst_video_decoder_request_sync_point;

    /// Allows baseclass to perform byte to time estimated conversion.
    extern fn gst_video_decoder_set_estimate_rate(p_dec: *VideoDecoder, p_enabled: c_int) void;
    pub const setEstimateRate = gst_video_decoder_set_estimate_rate;

    /// Same as `gstvideo.VideoDecoder.setOutputState``gstvideo.VideoDecoder.setOutputState` but also allows you to also set
    /// the interlacing mode.
    extern fn gst_video_decoder_set_interlaced_output_state(p_decoder: *VideoDecoder, p_fmt: gstvideo.VideoFormat, p_interlace_mode: gstvideo.VideoInterlaceMode, p_width: c_uint, p_height: c_uint, p_reference: ?*gstvideo.VideoCodecState) ?*gstvideo.VideoCodecState;
    pub const setInterlacedOutputState = gst_video_decoder_set_interlaced_output_state;

    /// Lets `gstvideo.VideoDecoder` sub-classes tell the baseclass what the decoder latency
    /// is. If the provided values changed from previously provided ones, this will
    /// also post a LATENCY message on the bus so the pipeline can reconfigure its
    /// global latency.
    extern fn gst_video_decoder_set_latency(p_decoder: *VideoDecoder, p_min_latency: gst.ClockTime, p_max_latency: gst.ClockTime) void;
    pub const setLatency = gst_video_decoder_set_latency;

    /// Sets numbers of tolerated decoder errors, where a tolerated one is then only
    /// warned about, but more than tolerated will lead to fatal error.  You can set
    /// -1 for never returning fatal errors. Default is set to
    /// GST_VIDEO_DECODER_MAX_ERRORS.
    ///
    /// The '-1' option was added in 1.4
    extern fn gst_video_decoder_set_max_errors(p_dec: *VideoDecoder, p_num: c_int) void;
    pub const setMaxErrors = gst_video_decoder_set_max_errors;

    /// Configures decoder format needs.  If enabled, subclass needs to be
    /// negotiated with format caps before it can process any data.  It will then
    /// never be handed any data before it has been configured.
    /// Otherwise, it might be handed data without having been configured and
    /// is then expected being able to do so either by default
    /// or based on the input data.
    extern fn gst_video_decoder_set_needs_format(p_dec: *VideoDecoder, p_enabled: c_int) void;
    pub const setNeedsFormat = gst_video_decoder_set_needs_format;

    /// Configures whether the decoder requires a sync point before it starts
    /// outputting data in the beginning. If enabled, the base class will discard
    /// all non-sync point frames in the beginning and after a flush and does not
    /// pass it to the subclass.
    ///
    /// If the first frame is not a sync point, the base class will request a sync
    /// point via the force-key-unit event.
    extern fn gst_video_decoder_set_needs_sync_point(p_dec: *VideoDecoder, p_enabled: c_int) void;
    pub const setNeedsSyncPoint = gst_video_decoder_set_needs_sync_point;

    /// Creates a new `gstvideo.VideoCodecState` with the specified `fmt`, `width` and `height`
    /// as the output state for the decoder.
    /// Any previously set output state on `decoder` will be replaced by the newly
    /// created one.
    ///
    /// If the subclass wishes to copy over existing fields (like pixel aspec ratio,
    /// or framerate) from an existing `gstvideo.VideoCodecState`, it can be provided as a
    /// `reference`.
    ///
    /// If the subclass wishes to override some fields from the output state (like
    /// pixel-aspect-ratio or framerate) it can do so on the returned `gstvideo.VideoCodecState`.
    ///
    /// The new output state will only take effect (set on pads and buffers) starting
    /// from the next call to `gstvideo.VideoDecoder.finishFrame``gstvideo.VideoDecoder.finishFrame`.
    extern fn gst_video_decoder_set_output_state(p_decoder: *VideoDecoder, p_fmt: gstvideo.VideoFormat, p_width: c_uint, p_height: c_uint, p_reference: ?*gstvideo.VideoCodecState) ?*gstvideo.VideoCodecState;
    pub const setOutputState = gst_video_decoder_set_output_state;

    /// Allows baseclass to consider input data as packetized or not. If the
    /// input is packetized, then the `parse` method will not be called.
    extern fn gst_video_decoder_set_packetized(p_decoder: *VideoDecoder, p_packetized: c_int) void;
    pub const setPacketized = gst_video_decoder_set_packetized;

    /// If this is set to TRUE, it informs the base class that the subclass
    /// can receive the data at a granularity lower than one frame.
    ///
    /// Note that in this mode, the subclass has two options. It can either
    /// require the presence of a GST_VIDEO_BUFFER_FLAG_MARKER to mark the
    /// end of a frame. Or it can operate in such a way that it will decode
    /// a single frame at a time. In this second case, every buffer that
    /// arrives to the element is considered part of the same frame until
    /// `gstvideo.VideoDecoder.finishFrame` is called.
    ///
    /// In either case, the same `gstvideo.VideoCodecFrame` will be passed to the
    /// GstVideoDecoderClass:handle_frame vmethod repeatedly with a
    /// different GstVideoCodecFrame:input_buffer every time until the end of the
    /// frame has been signaled using either method.
    /// This method must be called during the decoder subclass `set_format` call.
    extern fn gst_video_decoder_set_subframe_mode(p_decoder: *VideoDecoder, p_subframe_mode: c_int) void;
    pub const setSubframeMode = gst_video_decoder_set_subframe_mode;

    /// Lets `gstvideo.VideoDecoder` sub-classes decide if they want the sink pad
    /// to use the default pad query handler to reply to accept-caps queries.
    ///
    /// By setting this to true it is possible to further customize the default
    /// handler with `GST_PAD_SET_ACCEPT_INTERSECT` and
    /// `GST_PAD_SET_ACCEPT_TEMPLATE`
    extern fn gst_video_decoder_set_use_default_pad_acceptcaps(p_decoder: *VideoDecoder, p_use: c_int) void;
    pub const setUseDefaultPadAcceptcaps = gst_video_decoder_set_use_default_pad_acceptcaps;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoDecoder) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoDecoder) void;
    pub const unref = g_object_unref;

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

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

/// This base class is for video encoders turning raw video into
/// encoded video data.
///
/// GstVideoEncoder and subclass should cooperate as follows.
///
/// ## Configuration
///
///   * Initially, GstVideoEncoder calls `start` when the encoder element
///     is activated, which allows subclass to perform any global setup.
///   * GstVideoEncoder calls `set_format` to inform subclass of the format
///     of input video data that it is about to receive.  Subclass should
///     setup for encoding and configure base class as appropriate
///     (e.g. latency). While unlikely, it might be called more than once,
///     if changing input parameters require reconfiguration.  Baseclass
///     will ensure that processing of current configuration is finished.
///   * GstVideoEncoder calls `stop` at end of all processing.
///
/// ## Data processing
///
///     * Base class collects input data and metadata into a frame and hands
///       this to subclass' `handle_frame`.
///
///     * If codec processing results in encoded data, subclass should call
///       `gst_video_encoder_finish_frame` to have encoded data pushed
///       downstream.
///
///     * If implemented, baseclass calls subclass `pre_push` just prior to
///       pushing to allow subclasses to modify some metadata on the buffer.
///       If it returns GST_FLOW_OK, the buffer is pushed downstream.
///
///     * GstVideoEncoderClass will handle both srcpad and sinkpad events.
///       Sink events will be passed to subclass if `event` callback has been
///       provided.
///
/// ## Shutdown phase
///
///   * GstVideoEncoder class calls `stop` to inform the subclass that data
///     parsing will be stopped.
///
/// Subclass is responsible for providing pad template caps for
/// source and sink pads. The pads need to be named "sink" and "src". It should
/// also be able to provide fixed src pad caps in `getcaps` by the time it calls
/// `gst_video_encoder_finish_frame`.
///
/// Things that subclass need to take care of:
///
///   * Provide pad templates
///   * Provide source pad caps before pushing the first buffer
///   * Accept data in `handle_frame` and provide encoded results to
///      `gst_video_encoder_finish_frame`.
///
///
/// The `gstvideo.VideoEncoder.properties.qos` property will enable the Quality-of-Service
/// features of the encoder which gather statistics about the real-time
/// performance of the downstream elements. If enabled, subclasses can
/// use `gstvideo.VideoEncoder.getMaxEncodeTime` to check if input frames
/// are already late and drop them right away to give a chance to the
/// pipeline to catch up.
pub const VideoEncoder = extern struct {
    pub const Parent = gst.Element;
    pub const Implements = [_]type{gst.Preset};
    pub const Class = gstvideo.VideoEncoderClass;
    f_element: gst.Element,
    f_sinkpad: ?*gst.Pad,
    f_srcpad: ?*gst.Pad,
    f_stream_lock: glib.RecMutex,
    f_input_segment: gst.Segment,
    f_output_segment: gst.Segment,
    f_priv: ?*gstvideo.VideoEncoderPrivate,
    f_padding: [20]*anyopaque,

    pub const virtual_methods = struct {
        /// Optional.
        ///                  Called when the element changes to GST_STATE_NULL.
        ///                  Allows closing external resources.
        pub const close = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_close.?(gobject.ext.as(VideoEncoder, p_encoder));
            }

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

        /// Optional.
        ///                     Setup the allocation parameters for allocating output
        ///                     buffers. The passed in query contains the result of the
        ///                     downstream allocation query.
        ///                     Subclasses should chain up to the parent implementation to
        ///                     invoke the default handler.
        pub const decide_allocation = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_decide_allocation.?(gobject.ext.as(VideoEncoder, p_encoder), p_query);
            }

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

        /// Optional.
        ///                  Called to request subclass to dispatch any pending remaining
        ///                  data (e.g. at EOS).
        pub const finish = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gst.FlowReturn {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_finish.?(gobject.ext.as(VideoEncoder, p_encoder));
            }

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

        /// Optional.
        ///                      Flush all remaining data from the encoder without
        ///                      pushing it downstream. Since: 1.2
        pub const flush = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_flush.?(gobject.ext.as(VideoEncoder, p_encoder));
            }

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

        /// Optional.
        ///                  Allows for a custom sink getcaps implementation (e.g.
        ///                  for multichannel input specification).  If not implemented,
        ///                  default returns gst_video_encoder_proxy_getcaps
        ///                  applied to sink template caps.
        pub const getcaps = struct {
            pub fn call(p_class: anytype, p_enc: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_filter: *gst.Caps) *gst.Caps {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_getcaps.?(gobject.ext.as(VideoEncoder, p_enc), p_filter);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_enc: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_filter: *gst.Caps) callconv(.c) *gst.Caps) void {
                gobject.ext.as(VideoEncoder.Class, p_class).f_getcaps = @ptrCast(p_implementation);
            }
        };

        /// Provides input frame to subclass.
        pub const handle_frame = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_handle_frame.?(gobject.ext.as(VideoEncoder, p_encoder), p_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoEncoder.Class, p_class).f_handle_frame = @ptrCast(p_implementation);
            }
        };

        /// Negotiate with downstream elements to currently configured `gstvideo.VideoCodecState`.
        /// Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
        /// negotiate fails.
        pub const negotiate = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_negotiate.?(gobject.ext.as(VideoEncoder, p_encoder));
            }

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

        /// Optional.
        ///                  Called when the element changes to GST_STATE_READY.
        ///                  Allows opening external resources.
        pub const open = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_open.?(gobject.ext.as(VideoEncoder, p_encoder));
            }

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

        /// Optional.
        ///                  Allows subclass to push frame downstream in whatever
        ///                  shape or form it deems appropriate.  If not provided,
        ///                  provided encoded frame data is simply pushed downstream.
        pub const pre_push = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_pre_push.?(gobject.ext.as(VideoEncoder, p_encoder), p_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoEncoder.Class, p_class).f_pre_push = @ptrCast(p_implementation);
            }
        };

        /// Optional.
        ///                      Propose buffer allocation parameters for upstream elements.
        ///                      Subclasses should chain up to the parent implementation to
        ///                      invoke the default handler.
        pub const propose_allocation = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_propose_allocation.?(gobject.ext.as(VideoEncoder, p_encoder), p_query);
            }

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

        /// Optional.
        ///                  Allows subclass (encoder) to perform post-seek semantics reset.
        ///                  Deprecated.
        pub const reset = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_hard: c_int) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_reset.?(gobject.ext.as(VideoEncoder, p_encoder), p_hard);
            }

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

        /// Optional.
        ///                  Notifies subclass of incoming data format.
        ///                  GstVideoCodecState fields have already been
        ///                  set according to provided caps.
        pub const set_format = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: *gstvideo.VideoCodecState) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_set_format.?(gobject.ext.as(VideoEncoder, p_encoder), p_state);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_state: *gstvideo.VideoCodecState) callconv(.c) c_int) void {
                gobject.ext.as(VideoEncoder.Class, p_class).f_set_format = @ptrCast(p_implementation);
            }
        };

        /// Optional.
        ///                  Event handler on the sink pad. This function should return
        ///                  TRUE if the event was handled and should be discarded
        ///                  (i.e. not unref'ed).
        ///                  Subclasses should chain up to the parent implementation to
        ///                  invoke the default handler.
        pub const sink_event = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_sink_event.?(gobject.ext.as(VideoEncoder, p_encoder), p_event);
            }

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

        /// Optional.
        ///                  Query handler on the sink pad. This function should
        ///                  return TRUE if the query could be performed. Subclasses
        ///                  should chain up to the parent implementation to invoke the
        ///                  default handler. Since: 1.4
        pub const sink_query = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_sink_query.?(gobject.ext.as(VideoEncoder, p_encoder), p_query);
            }

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

        /// Optional.
        ///                  Event handler on the source pad. This function should return
        ///                  TRUE if the event was handled and should be discarded
        ///                  (i.e. not unref'ed).
        ///                  Subclasses should chain up to the parent implementation to
        ///                  invoke the default handler.
        pub const src_event = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_src_event.?(gobject.ext.as(VideoEncoder, p_encoder), p_event);
            }

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

        /// Optional.
        ///                  Query handler on the source pad. This function should
        ///                  return TRUE if the query could be performed. Subclasses
        ///                  should chain up to the parent implementation to invoke the
        ///                  default handler. Since: 1.4
        pub const src_query = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_query: *gst.Query) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_src_query.?(gobject.ext.as(VideoEncoder, p_encoder), p_query);
            }

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

        /// Optional.
        ///                  Called when the element starts processing.
        ///                  Allows opening external resources.
        pub const start = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_start.?(gobject.ext.as(VideoEncoder, p_encoder));
            }

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

        /// Optional.
        ///                  Called when the element stops processing.
        ///                  Allows closing external resources.
        pub const stop = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_stop.?(gobject.ext.as(VideoEncoder, p_encoder));
            }

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

        /// Optional. Transform the metadata on the input buffer to the
        ///                  output buffer. By default this method is copies all meta without
        ///                  tags and meta with only the "video" tag. subclasses can
        ///                  implement this method and return `TRUE` if the metadata is to be
        ///                  copied. Since: 1.6
        pub const transform_meta = struct {
            pub fn call(p_class: anytype, p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame, p_meta: *gst.Meta) c_int {
                return gobject.ext.as(VideoEncoder.Class, p_class).f_transform_meta.?(gobject.ext.as(VideoEncoder, p_encoder), p_frame, p_meta);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_encoder: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoCodecFrame, p_meta: *gst.Meta) callconv(.c) c_int) void {
                gobject.ext.as(VideoEncoder.Class, p_class).f_transform_meta = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// Minimum interval between force-keyunit requests in nanoseconds. See
        /// `gstvideo.VideoEncoder.setMinForceKeyUnitInterval` for more details.
        pub const min_force_key_unit_interval = struct {
            pub const name = "min-force-key-unit-interval";

            pub const Type = u64;
        };

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

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    /// Helper function that allocates a buffer to hold an encoded video frame
    /// for `encoder`'s current `gstvideo.VideoCodecState`.
    extern fn gst_video_encoder_allocate_output_buffer(p_encoder: *VideoEncoder, p_size: usize) *gst.Buffer;
    pub const allocateOutputBuffer = gst_video_encoder_allocate_output_buffer;

    /// Helper function that allocates a buffer to hold an encoded video frame for `encoder`'s
    /// current `gstvideo.VideoCodecState`.  Subclass should already have configured video
    /// state and set src pad caps.
    ///
    /// The buffer allocated here is owned by the frame and you should only
    /// keep references to the frame, not the buffer.
    extern fn gst_video_encoder_allocate_output_frame(p_encoder: *VideoEncoder, p_frame: *gstvideo.VideoCodecFrame, p_size: usize) gst.FlowReturn;
    pub const allocateOutputFrame = gst_video_encoder_allocate_output_frame;

    /// Removes `frame` from the list of pending frames, releases it
    /// and posts a QoS message with the frame's details on the bus.
    /// Similar to calling `gstvideo.VideoEncoder.finishFrame` without a buffer
    /// attached to `frame`, but this function additionally stores events
    /// from `frame` as pending, to be pushed out alongside the next frame
    /// submitted via `gstvideo.VideoEncoder.finishFrame`.
    extern fn gst_video_encoder_drop_frame(p_encoder: *VideoEncoder, p_frame: *gstvideo.VideoCodecFrame) void;
    pub const dropFrame = gst_video_encoder_drop_frame;

    /// `frame` must have a valid encoded data buffer, whose metadata fields
    /// are then appropriately set according to frame data or no buffer at
    /// all if the frame should be dropped.
    /// It is subsequently pushed downstream or provided to `pre_push`.
    /// In any case, the frame is considered finished and released.
    ///
    /// If `frame` does not have a buffer attached, it will be dropped, and
    /// a QoS message will be posted on the bus. Events from `frame` will be
    /// pushed out immediately.
    ///
    /// After calling this function the output buffer of the frame is to be
    /// considered read-only. This function will also change the metadata
    /// of the buffer.
    extern fn gst_video_encoder_finish_frame(p_encoder: *VideoEncoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const finishFrame = gst_video_encoder_finish_frame;

    /// If multiple subframes are produced for one input frame then use this method
    /// for each subframe, except for the last one. Before calling this function,
    /// you need to fill frame->output_buffer with the encoded buffer to push.
    ///
    /// You must call `gstvideo.VideoEncoder.finishFrame``gstvideo.VideoEncoder.finishFrame` for the last sub-frame
    /// to tell the encoder that the frame has been fully encoded.
    ///
    /// This function will change the metadata of `frame` and frame->output_buffer
    /// will be pushed downstream.
    extern fn gst_video_encoder_finish_subframe(p_encoder: *VideoEncoder, p_frame: *gstvideo.VideoCodecFrame) gst.FlowReturn;
    pub const finishSubframe = gst_video_encoder_finish_subframe;

    /// Lets `gstvideo.VideoEncoder` sub-classes to know the memory `allocator`
    /// used by the base class and its `params`.
    ///
    /// Unref the `allocator` after use it.
    extern fn gst_video_encoder_get_allocator(p_encoder: *VideoEncoder, p_allocator: ?**gst.Allocator, p_params: ?*gst.AllocationParams) void;
    pub const getAllocator = gst_video_encoder_get_allocator;

    /// Get a pending unfinished `gstvideo.VideoCodecFrame`
    extern fn gst_video_encoder_get_frame(p_encoder: *VideoEncoder, p_frame_number: c_int) ?*gstvideo.VideoCodecFrame;
    pub const getFrame = gst_video_encoder_get_frame;

    /// Get all pending unfinished `gstvideo.VideoCodecFrame`
    extern fn gst_video_encoder_get_frames(p_encoder: *VideoEncoder) *glib.List;
    pub const getFrames = gst_video_encoder_get_frames;

    /// Query the configured encoding latency. Results will be returned via
    /// `min_latency` and `max_latency`.
    extern fn gst_video_encoder_get_latency(p_encoder: *VideoEncoder, p_min_latency: ?*gst.ClockTime, p_max_latency: ?*gst.ClockTime) void;
    pub const getLatency = gst_video_encoder_get_latency;

    /// Determines maximum possible encoding time for `frame` that will
    /// allow it to encode and arrive in time (as determined by QoS events).
    /// In particular, a negative result means encoding in time is no longer possible
    /// and should therefore occur as soon/skippy as possible.
    ///
    /// If no QoS events have been received from downstream, or if
    /// `gstvideo.VideoEncoder.properties.qos` is disabled this function returns `G_MAXINT64`.
    extern fn gst_video_encoder_get_max_encode_time(p_encoder: *VideoEncoder, p_frame: *gstvideo.VideoCodecFrame) gst.ClockTimeDiff;
    pub const getMaxEncodeTime = gst_video_encoder_get_max_encode_time;

    /// Returns the minimum force-keyunit interval, see `gstvideo.VideoEncoder.setMinForceKeyUnitInterval`
    /// for more details.
    extern fn gst_video_encoder_get_min_force_key_unit_interval(p_encoder: *VideoEncoder) gst.ClockTime;
    pub const getMinForceKeyUnitInterval = gst_video_encoder_get_min_force_key_unit_interval;

    /// Get the oldest unfinished pending `gstvideo.VideoCodecFrame`
    extern fn gst_video_encoder_get_oldest_frame(p_encoder: *VideoEncoder) ?*gstvideo.VideoCodecFrame;
    pub const getOldestFrame = gst_video_encoder_get_oldest_frame;

    /// Get the current `gstvideo.VideoCodecState`
    extern fn gst_video_encoder_get_output_state(p_encoder: *VideoEncoder) ?*gstvideo.VideoCodecState;
    pub const getOutputState = gst_video_encoder_get_output_state;

    /// Checks if `encoder` is currently configured to handle Quality-of-Service
    /// events from downstream.
    extern fn gst_video_encoder_is_qos_enabled(p_encoder: *VideoEncoder) c_int;
    pub const isQosEnabled = gst_video_encoder_is_qos_enabled;

    /// Sets the video encoder tags and how they should be merged with any
    /// upstream stream tags. This will override any tags previously-set
    /// with `gstvideo.VideoEncoder.mergeTags`.
    ///
    /// Note that this is provided for convenience, and the subclass is
    /// not required to use this and can still do tag handling on its own.
    ///
    /// MT safe.
    extern fn gst_video_encoder_merge_tags(p_encoder: *VideoEncoder, p_tags: ?*const gst.TagList, p_mode: gst.TagMergeMode) void;
    pub const mergeTags = gst_video_encoder_merge_tags;

    /// Negotiate with downstream elements to currently configured `gstvideo.VideoCodecState`.
    /// Unmark GST_PAD_FLAG_NEED_RECONFIGURE in any case. But mark it again if
    /// negotiate fails.
    extern fn gst_video_encoder_negotiate(p_encoder: *VideoEncoder) c_int;
    pub const negotiate = gst_video_encoder_negotiate;

    /// Returns caps that express `caps` (or sink template caps if `caps` == NULL)
    /// restricted to resolution/format/... combinations supported by downstream
    /// elements (e.g. muxers).
    extern fn gst_video_encoder_proxy_getcaps(p_enc: *VideoEncoder, p_caps: ?*gst.Caps, p_filter: ?*gst.Caps) *gst.Caps;
    pub const proxyGetcaps = gst_video_encoder_proxy_getcaps;

    /// Removes `frame` from list of pending frames and releases it, similar
    /// to calling `gstvideo.VideoEncoder.finishFrame` without a buffer attached
    /// to the frame, but does not post a QoS message or do any additional
    /// processing. Events from `frame` are moved to the pending events list.
    extern fn gst_video_encoder_release_frame(p_encoder: *VideoEncoder, p_frame: *gstvideo.VideoCodecFrame) void;
    pub const releaseFrame = gst_video_encoder_release_frame;

    /// Set the codec headers to be sent downstream whenever requested.
    extern fn gst_video_encoder_set_headers(p_encoder: *VideoEncoder, p_headers: *glib.List) void;
    pub const setHeaders = gst_video_encoder_set_headers;

    /// Informs baseclass of encoding latency. If the provided values changed from
    /// previously provided ones, this will also post a LATENCY message on the bus
    /// so the pipeline can reconfigure its global latency.
    extern fn gst_video_encoder_set_latency(p_encoder: *VideoEncoder, p_min_latency: gst.ClockTime, p_max_latency: gst.ClockTime) void;
    pub const setLatency = gst_video_encoder_set_latency;

    /// Sets the minimum interval for requesting keyframes based on force-keyunit
    /// events. Setting this to 0 will allow to handle every event, setting this to
    /// `GST_CLOCK_TIME_NONE` causes force-keyunit events to be ignored.
    extern fn gst_video_encoder_set_min_force_key_unit_interval(p_encoder: *VideoEncoder, p_interval: gst.ClockTime) void;
    pub const setMinForceKeyUnitInterval = gst_video_encoder_set_min_force_key_unit_interval;

    /// Request minimal value for PTS passed to handle_frame.
    ///
    /// For streams with reordered frames this can be used to ensure that there
    /// is enough time to accommodate first DTS, which may be less than first PTS
    extern fn gst_video_encoder_set_min_pts(p_encoder: *VideoEncoder, p_min_pts: gst.ClockTime) void;
    pub const setMinPts = gst_video_encoder_set_min_pts;

    /// Creates a new `gstvideo.VideoCodecState` with the specified caps as the output state
    /// for the encoder.
    /// Any previously set output state on `encoder` will be replaced by the newly
    /// created one.
    ///
    /// The specified `caps` should not contain any resolution, pixel-aspect-ratio,
    /// framerate, codec-data, .... Those should be specified instead in the returned
    /// `gstvideo.VideoCodecState`.
    ///
    /// If the subclass wishes to copy over existing fields (like pixel aspect ratio,
    /// or framerate) from an existing `gstvideo.VideoCodecState`, it can be provided as a
    /// `reference`.
    ///
    /// If the subclass wishes to override some fields from the output state (like
    /// pixel-aspect-ratio or framerate) it can do so on the returned `gstvideo.VideoCodecState`.
    ///
    /// The new output state will only take effect (set on pads and buffers) starting
    /// from the next call to `gstvideo.VideoEncoder.finishFrame``gstvideo.VideoEncoder.finishFrame`.
    extern fn gst_video_encoder_set_output_state(p_encoder: *VideoEncoder, p_caps: *gst.Caps, p_reference: ?*gstvideo.VideoCodecState) ?*gstvideo.VideoCodecState;
    pub const setOutputState = gst_video_encoder_set_output_state;

    /// Configures `encoder` to handle Quality-of-Service events from downstream.
    extern fn gst_video_encoder_set_qos_enabled(p_encoder: *VideoEncoder, p_enabled: c_int) void;
    pub const setQosEnabled = gst_video_encoder_set_qos_enabled;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoEncoder) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoEncoder) void;
    pub const unref = g_object_unref;

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

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

/// Provides useful functions and a base class for video filters.
///
/// The videofilter will by default enable QoS on the parent GstBaseTransform
/// to implement frame dropping.
pub const VideoFilter = extern struct {
    pub const Parent = gstbase.BaseTransform;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoFilterClass;
    f_element: gstbase.BaseTransform,
    f_negotiated: c_int,
    f_in_info: gstvideo.VideoInfo,
    f_out_info: gstvideo.VideoInfo,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// function to be called with the negotiated caps and video infos
        pub const set_info = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_incaps: *gst.Caps, p_in_info: *gstvideo.VideoInfo, p_outcaps: *gst.Caps, p_out_info: *gstvideo.VideoInfo) c_int {
                return gobject.ext.as(VideoFilter.Class, p_class).f_set_info.?(gobject.ext.as(VideoFilter, p_filter), p_incaps, p_in_info, p_outcaps, p_out_info);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_incaps: *gst.Caps, p_in_info: *gstvideo.VideoInfo, p_outcaps: *gst.Caps, p_out_info: *gstvideo.VideoInfo) callconv(.c) c_int) void {
                gobject.ext.as(VideoFilter.Class, p_class).f_set_info = @ptrCast(p_implementation);
            }
        };

        /// transform a video frame
        pub const transform_frame = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_inframe: *gstvideo.VideoFrame, p_outframe: *gstvideo.VideoFrame) gst.FlowReturn {
                return gobject.ext.as(VideoFilter.Class, p_class).f_transform_frame.?(gobject.ext.as(VideoFilter, p_filter), p_inframe, p_outframe);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_inframe: *gstvideo.VideoFrame, p_outframe: *gstvideo.VideoFrame) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoFilter.Class, p_class).f_transform_frame = @ptrCast(p_implementation);
            }
        };

        /// transform a video frame in place
        pub const transform_frame_ip = struct {
            pub fn call(p_class: anytype, p_trans: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoFrame) gst.FlowReturn {
                return gobject.ext.as(VideoFilter.Class, p_class).f_transform_frame_ip.?(gobject.ext.as(VideoFilter, p_trans), p_frame);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_trans: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_frame: *gstvideo.VideoFrame) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoFilter.Class, p_class).f_transform_frame_ip = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

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

    extern fn g_object_ref(p_self: *gstvideo.VideoFilter) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoFilter) void;
    pub const unref = g_object_unref;

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

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

/// See `gstvideo.VideoMultiviewFlags`.
pub const VideoMultiviewFlagsSet = opaque {
    pub const Parent = gst.FlagSet;
    pub const Implements = [_]type{};
    pub const Class = opaque {
        pub const Instance = VideoMultiviewFlagsSet;
    };
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

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

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

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

/// Provides useful functions and a base class for video sinks.
///
/// GstVideoSink will configure the default base sink to drop frames that
/// arrive later than 20ms as this is considered the default threshold for
/// observing out-of-sync frames.
pub const VideoSink = extern struct {
    pub const Parent = gstbase.BaseSink;
    pub const Implements = [_]type{};
    pub const Class = gstvideo.VideoSinkClass;
    f_element: gstbase.BaseSink,
    /// video width (derived class needs to set this)
    f_width: c_int,
    /// video height (derived class needs to set this)
    f_height: c_int,
    f_priv: ?*gstvideo.VideoSinkPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// Notifies the subclass of changed `gstvideo.VideoInfo`.
        pub const set_info = struct {
            pub fn call(p_class: anytype, p_video_sink: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps, p_info: *const gstvideo.VideoInfo) c_int {
                return gobject.ext.as(VideoSink.Class, p_class).f_set_info.?(gobject.ext.as(VideoSink, p_video_sink), p_caps, p_info);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_sink: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps, p_info: *const gstvideo.VideoInfo) callconv(.c) c_int) void {
                gobject.ext.as(VideoSink.Class, p_class).f_set_info = @ptrCast(p_implementation);
            }
        };

        /// render a video frame. Maps to `gstbase.BaseSinkClass.virtual_methods.render` and
        ///     `gstbase.BaseSinkClass.virtual_methods.preroll` vfuncs. Rendering during preroll will be
        ///     suppressed if the `gstvideo.VideoSink.properties.show`-preroll-frame property is set to
        ///     `FALSE`.
        pub const show_frame = struct {
            pub fn call(p_class: anytype, p_video_sink: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buf: *gst.Buffer) gst.FlowReturn {
                return gobject.ext.as(VideoSink.Class, p_class).f_show_frame.?(gobject.ext.as(VideoSink, p_video_sink), p_buf);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_sink: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buf: *gst.Buffer) callconv(.c) gst.FlowReturn) void {
                gobject.ext.as(VideoSink.Class, p_class).f_show_frame = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {
        /// Whether to show video frames during preroll. If set to `FALSE`, video
        /// frames will only be rendered in PLAYING state.
        pub const show_preroll_frame = struct {
            pub const name = "show-preroll-frame";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    extern fn gst_video_sink_center_rect(p_src: gstvideo.VideoRectangle, p_dst: gstvideo.VideoRectangle, p_result: *gstvideo.VideoRectangle, p_scaling: c_int) void;
    pub const centerRect = gst_video_sink_center_rect;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoSink) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoSink) void;
    pub const unref = g_object_unref;

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

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

/// This interface is implemented by elements which can perform some color
/// balance operation on video frames they process. For example, modifying
/// the brightness, contrast, hue or saturation.
///
/// Example elements are 'xvimagesink' and 'colorbalance'
pub const ColorBalance = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstvideo.ColorBalanceInterface;
    pub const virtual_methods = struct {
        /// Get the `gstvideo.ColorBalanceType` of this implementation.
        pub const get_balance_type = struct {
            pub fn call(p_class: anytype, p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gstvideo.ColorBalanceType {
                return gobject.ext.as(ColorBalance.Iface, p_class).f_get_balance_type.?(gobject.ext.as(ColorBalance, p_balance));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) gstvideo.ColorBalanceType) void {
                gobject.ext.as(ColorBalance.Iface, p_class).f_get_balance_type = @ptrCast(p_implementation);
            }
        };

        /// Retrieve the current value of the indicated channel, between min_value
        /// and max_value.
        ///
        /// See Also: The `gstvideo.ColorBalanceChannel.min_value` and
        ///         `gstvideo.ColorBalanceChannel.max_value` members of the
        ///         `gstvideo.ColorBalanceChannel` object.
        pub const get_value = struct {
            pub fn call(p_class: anytype, p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_channel: *gstvideo.ColorBalanceChannel) c_int {
                return gobject.ext.as(ColorBalance.Iface, p_class).f_get_value.?(gobject.ext.as(ColorBalance, p_balance), p_channel);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_channel: *gstvideo.ColorBalanceChannel) callconv(.c) c_int) void {
                gobject.ext.as(ColorBalance.Iface, p_class).f_get_value = @ptrCast(p_implementation);
            }
        };

        /// Retrieve a list of the available channels.
        pub const list_channels = struct {
            pub fn call(p_class: anytype, p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) *const glib.List {
                return gobject.ext.as(ColorBalance.Iface, p_class).f_list_channels.?(gobject.ext.as(ColorBalance, p_balance));
            }

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

        /// Sets the current value of the channel to the passed value, which must
        /// be between min_value and max_value.
        ///
        /// See Also: The `gstvideo.ColorBalanceChannel.min_value` and
        ///         `gstvideo.ColorBalanceChannel.max_value` members of the
        ///         `gstvideo.ColorBalanceChannel` object.
        pub const set_value = struct {
            pub fn call(p_class: anytype, p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) void {
                return gobject.ext.as(ColorBalance.Iface, p_class).f_set_value.?(gobject.ext.as(ColorBalance, p_balance), p_channel, p_value);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) callconv(.c) void) void {
                gobject.ext.as(ColorBalance.Iface, p_class).f_set_value = @ptrCast(p_implementation);
            }
        };

        /// A helper function called by implementations of the GstColorBalance
        /// interface. It fires the `gstvideo.ColorBalance.signals.value`-changed signal on the
        /// instance, and the `gstvideo.ColorBalanceChannel.signals.value`-changed signal on the
        /// channel object.
        pub const value_changed = struct {
            pub fn call(p_class: anytype, p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) void {
                return gobject.ext.as(ColorBalance.Iface, p_class).f_value_changed.?(gobject.ext.as(ColorBalance, p_balance), p_channel, p_value);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_balance: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) callconv(.c) void) void {
                gobject.ext.as(ColorBalance.Iface, p_class).f_value_changed = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {
        /// Fired when the value of the indicated channel has changed.
        pub const value_changed = struct {
            pub const name = "value-changed";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_channel: *gstvideo.ColorBalanceChannel, p_value: 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(ColorBalance, p_instance))),
                    gobject.signalLookup("value-changed", ColorBalance.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Get the `gstvideo.ColorBalanceType` of this implementation.
    extern fn gst_color_balance_get_balance_type(p_balance: *ColorBalance) gstvideo.ColorBalanceType;
    pub const getBalanceType = gst_color_balance_get_balance_type;

    /// Retrieve the current value of the indicated channel, between min_value
    /// and max_value.
    ///
    /// See Also: The `gstvideo.ColorBalanceChannel.min_value` and
    ///         `gstvideo.ColorBalanceChannel.max_value` members of the
    ///         `gstvideo.ColorBalanceChannel` object.
    extern fn gst_color_balance_get_value(p_balance: *ColorBalance, p_channel: *gstvideo.ColorBalanceChannel) c_int;
    pub const getValue = gst_color_balance_get_value;

    /// Retrieve a list of the available channels.
    extern fn gst_color_balance_list_channels(p_balance: *ColorBalance) *const glib.List;
    pub const listChannels = gst_color_balance_list_channels;

    /// Sets the current value of the channel to the passed value, which must
    /// be between min_value and max_value.
    ///
    /// See Also: The `gstvideo.ColorBalanceChannel.min_value` and
    ///         `gstvideo.ColorBalanceChannel.max_value` members of the
    ///         `gstvideo.ColorBalanceChannel` object.
    extern fn gst_color_balance_set_value(p_balance: *ColorBalance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) void;
    pub const setValue = gst_color_balance_set_value;

    /// A helper function called by implementations of the GstColorBalance
    /// interface. It fires the `gstvideo.ColorBalance.signals.value`-changed signal on the
    /// instance, and the `gstvideo.ColorBalanceChannel.signals.value`-changed signal on the
    /// channel object.
    extern fn gst_color_balance_value_changed(p_balance: *ColorBalance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) void;
    pub const valueChanged = gst_color_balance_value_changed;

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

    extern fn g_object_ref(p_self: *gstvideo.ColorBalance) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.ColorBalance) void;
    pub const unref = g_object_unref;

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

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

/// The Navigation interface is used for creating and injecting navigation
/// related events such as mouse button presses, cursor motion and key presses.
/// The associated library also provides methods for parsing received events, and
/// for sending and receiving navigation related bus events. One main usecase is
/// DVD menu navigation.
///
/// The main parts of the API are:
///
/// * The GstNavigation interface, implemented by elements which provide an
///   application with the ability to create and inject navigation events into
///   the pipeline.
/// * GstNavigation event handling API. GstNavigation events are created in
///   response to calls on a GstNavigation interface implementation, and sent in
///   the pipeline. Upstream elements can use the navigation event API functions
///   to parse the contents of received messages.
///
/// * GstNavigation message handling API. GstNavigation messages may be sent on
///   the message bus to inform applications of navigation related changes in the
///   pipeline, such as the mouse moving over a clickable region, or the set of
///   available angles changing.
///
/// The GstNavigation message functions provide functions for creating and
/// parsing custom bus messages for signaling GstNavigation changes.
pub const Navigation = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstvideo.NavigationInterface;
    pub const virtual_methods = struct {
        /// sending a navigation event.
        pub const send_event = struct {
            pub fn call(p_class: anytype, p_navigation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_structure: *gst.Structure) void {
                return gobject.ext.as(Navigation.Iface, p_class).f_send_event.?(gobject.ext.as(Navigation, p_navigation), p_structure);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_navigation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_structure: *gst.Structure) callconv(.c) void) void {
                gobject.ext.as(Navigation.Iface, p_class).f_send_event = @ptrCast(p_implementation);
            }
        };

        /// Sends an event to the navigation interface.
        pub const send_event_simple = struct {
            pub fn call(p_class: anytype, p_navigation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) void {
                return gobject.ext.as(Navigation.Iface, p_class).f_send_event_simple.?(gobject.ext.as(Navigation, p_navigation), p_event);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_navigation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) callconv(.c) void) void {
                gobject.ext.as(Navigation.Iface, p_class).f_send_event_simple = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// Try to retrieve x and y coordinates of a `gstvideo.Navigation` event.
    extern fn gst_navigation_event_get_coordinates(p_event: *gst.Event, p_x: ?*f64, p_y: ?*f64) c_int;
    pub const eventGetCoordinates = gst_navigation_event_get_coordinates;

    /// Inspect a `gst.Event` and return the `gstvideo.NavigationEventType` of the event, or
    /// `GST_NAVIGATION_EVENT_INVALID` if the event is not a `gstvideo.Navigation` event.
    extern fn gst_navigation_event_get_type(p_event: *gst.Event) gstvideo.NavigationEventType;
    pub const eventGetType = gst_navigation_event_get_type;

    /// Create a new navigation event given navigation command..
    extern fn gst_navigation_event_new_command(p_command: gstvideo.NavigationCommand) *gst.Event;
    pub const eventNewCommand = gst_navigation_event_new_command;

    /// Create a new navigation event for the given key press.
    extern fn gst_navigation_event_new_key_press(p_key: [*:0]const u8, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewKeyPress = gst_navigation_event_new_key_press;

    /// Create a new navigation event for the given key release.
    extern fn gst_navigation_event_new_key_release(p_key: [*:0]const u8, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewKeyRelease = gst_navigation_event_new_key_release;

    /// Create a new navigation event for the given key mouse button press.
    extern fn gst_navigation_event_new_mouse_button_press(p_button: c_int, p_x: f64, p_y: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewMouseButtonPress = gst_navigation_event_new_mouse_button_press;

    /// Create a new navigation event for the given key mouse button release.
    extern fn gst_navigation_event_new_mouse_button_release(p_button: c_int, p_x: f64, p_y: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewMouseButtonRelease = gst_navigation_event_new_mouse_button_release;

    /// Create a new navigation event for the given key mouse double click.
    extern fn gst_navigation_event_new_mouse_double_click(p_button: c_int, p_x: f64, p_y: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewMouseDoubleClick = gst_navigation_event_new_mouse_double_click;

    /// Create a new navigation event for the new mouse location.
    extern fn gst_navigation_event_new_mouse_move(p_x: f64, p_y: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewMouseMove = gst_navigation_event_new_mouse_move;

    /// Create a new navigation event for the mouse scroll.
    extern fn gst_navigation_event_new_mouse_scroll(p_x: f64, p_y: f64, p_delta_x: f64, p_delta_y: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewMouseScroll = gst_navigation_event_new_mouse_scroll;

    /// Create a new navigation event signalling that all currently active touch
    /// points are cancelled and should be discarded. For example, under Wayland
    /// this event might be sent when a swipe passes the threshold to be recognized
    /// as a gesture by the compositor.
    extern fn gst_navigation_event_new_touch_cancel(p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewTouchCancel = gst_navigation_event_new_touch_cancel;

    /// Create a new navigation event for an added touch point.
    extern fn gst_navigation_event_new_touch_down(p_identifier: c_uint, p_x: f64, p_y: f64, p_pressure: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewTouchDown = gst_navigation_event_new_touch_down;

    /// Create a new navigation event signalling the end of a touch frame. Touch
    /// frames signal that all previous down, motion and up events not followed by
    /// another touch frame event already should be considered simultaneous.
    extern fn gst_navigation_event_new_touch_frame(p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewTouchFrame = gst_navigation_event_new_touch_frame;

    /// Create a new navigation event for a moved touch point.
    extern fn gst_navigation_event_new_touch_motion(p_identifier: c_uint, p_x: f64, p_y: f64, p_pressure: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewTouchMotion = gst_navigation_event_new_touch_motion;

    /// Create a new navigation event for a removed touch point.
    extern fn gst_navigation_event_new_touch_up(p_identifier: c_uint, p_x: f64, p_y: f64, p_state: gstvideo.NavigationModifierType) *gst.Event;
    pub const eventNewTouchUp = gst_navigation_event_new_touch_up;

    /// Inspect a `gstvideo.Navigation` command event and retrieve the enum value of the
    /// associated command.
    extern fn gst_navigation_event_parse_command(p_event: *gst.Event, p_command: ?*gstvideo.NavigationCommand) c_int;
    pub const eventParseCommand = gst_navigation_event_parse_command;

    /// Note: Modifier keys (as defined in `gstvideo.NavigationModifierType`)
    /// [press](GST_NAVIGATION_EVENT_KEY_PRESS) and
    /// [release](GST_NAVIGATION_KEY_PRESS) events are generated even if those states are
    /// present on all other related events
    extern fn gst_navigation_event_parse_key_event(p_event: *gst.Event, p_key: ?*[*:0]const u8) c_int;
    pub const eventParseKeyEvent = gst_navigation_event_parse_key_event;

    extern fn gst_navigation_event_parse_modifier_state(p_event: *gst.Event, p_state: *gstvideo.NavigationModifierType) c_int;
    pub const eventParseModifierState = gst_navigation_event_parse_modifier_state;

    /// Retrieve the details of either a `gstvideo.Navigation` mouse button press event or
    /// a mouse button release event. Determine which type the event is using
    /// `gstvideo.navigationEventGetType` to retrieve the `gstvideo.NavigationEventType`.
    extern fn gst_navigation_event_parse_mouse_button_event(p_event: *gst.Event, p_button: ?*c_int, p_x: ?*f64, p_y: ?*f64) c_int;
    pub const eventParseMouseButtonEvent = gst_navigation_event_parse_mouse_button_event;

    /// Inspect a `gstvideo.Navigation` mouse movement event and extract the coordinates
    /// of the event.
    extern fn gst_navigation_event_parse_mouse_move_event(p_event: *gst.Event, p_x: ?*f64, p_y: ?*f64) c_int;
    pub const eventParseMouseMoveEvent = gst_navigation_event_parse_mouse_move_event;

    /// Inspect a `gstvideo.Navigation` mouse scroll event and extract the coordinates
    /// of the event.
    extern fn gst_navigation_event_parse_mouse_scroll_event(p_event: *gst.Event, p_x: ?*f64, p_y: ?*f64, p_delta_x: ?*f64, p_delta_y: ?*f64) c_int;
    pub const eventParseMouseScrollEvent = gst_navigation_event_parse_mouse_scroll_event;

    /// Retrieve the details of a `gstvideo.Navigation` touch-down or touch-motion event.
    /// Determine which type the event is using `gstvideo.navigationEventGetType`
    /// to retrieve the `gstvideo.NavigationEventType`.
    extern fn gst_navigation_event_parse_touch_event(p_event: *gst.Event, p_identifier: ?*c_uint, p_x: ?*f64, p_y: ?*f64, p_pressure: ?*f64) c_int;
    pub const eventParseTouchEvent = gst_navigation_event_parse_touch_event;

    /// Retrieve the details of a `gstvideo.Navigation` touch-up event.
    extern fn gst_navigation_event_parse_touch_up_event(p_event: *gst.Event, p_identifier: ?*c_uint, p_x: ?*f64, p_y: ?*f64) c_int;
    pub const eventParseTouchUpEvent = gst_navigation_event_parse_touch_up_event;

    /// Try to set x and y coordinates on a `gstvideo.Navigation` event. The event must
    /// be writable.
    extern fn gst_navigation_event_set_coordinates(p_event: *gst.Event, p_x: f64, p_y: f64) c_int;
    pub const eventSetCoordinates = gst_navigation_event_set_coordinates;

    /// Check a bus message to see if it is a `gstvideo.Navigation` event, and return
    /// the `gstvideo.NavigationMessageType` identifying the type of the message if so.
    extern fn gst_navigation_message_get_type(p_message: *gst.Message) gstvideo.NavigationMessageType;
    pub const messageGetType = gst_navigation_message_get_type;

    /// Creates a new `gstvideo.Navigation` message with type
    /// `GST_NAVIGATION_MESSAGE_ANGLES_CHANGED` for notifying an application
    /// that the current angle, or current number of angles available in a
    /// multiangle video has changed.
    extern fn gst_navigation_message_new_angles_changed(p_src: *gst.Object, p_cur_angle: c_uint, p_n_angles: c_uint) *gst.Message;
    pub const messageNewAnglesChanged = gst_navigation_message_new_angles_changed;

    /// Creates a new `gstvideo.Navigation` message with type
    /// `GST_NAVIGATION_MESSAGE_COMMANDS_CHANGED`
    extern fn gst_navigation_message_new_commands_changed(p_src: *gst.Object) *gst.Message;
    pub const messageNewCommandsChanged = gst_navigation_message_new_commands_changed;

    /// Creates a new `gstvideo.Navigation` message with type
    /// `GST_NAVIGATION_MESSAGE_EVENT`.
    extern fn gst_navigation_message_new_event(p_src: *gst.Object, p_event: *gst.Event) *gst.Message;
    pub const messageNewEvent = gst_navigation_message_new_event;

    /// Creates a new `gstvideo.Navigation` message with type
    /// `GST_NAVIGATION_MESSAGE_MOUSE_OVER`.
    extern fn gst_navigation_message_new_mouse_over(p_src: *gst.Object, p_active: c_int) *gst.Message;
    pub const messageNewMouseOver = gst_navigation_message_new_mouse_over;

    /// Parse a `gstvideo.Navigation` message of type GST_NAVIGATION_MESSAGE_ANGLES_CHANGED
    /// and extract the `cur_angle` and `n_angles` parameters.
    extern fn gst_navigation_message_parse_angles_changed(p_message: *gst.Message, p_cur_angle: ?*c_uint, p_n_angles: ?*c_uint) c_int;
    pub const messageParseAnglesChanged = gst_navigation_message_parse_angles_changed;

    /// Parse a `gstvideo.Navigation` message of type `GST_NAVIGATION_MESSAGE_EVENT`
    /// and extract contained `gst.Event`. The caller must unref the `event` when done
    /// with it.
    extern fn gst_navigation_message_parse_event(p_message: *gst.Message, p_event: ?**gst.Event) c_int;
    pub const messageParseEvent = gst_navigation_message_parse_event;

    /// Parse a `gstvideo.Navigation` message of type `GST_NAVIGATION_MESSAGE_MOUSE_OVER`
    /// and extract the active/inactive flag. If the mouse over event is marked
    /// active, it indicates that the mouse is over a clickable area.
    extern fn gst_navigation_message_parse_mouse_over(p_message: *gst.Message, p_active: ?*c_int) c_int;
    pub const messageParseMouseOver = gst_navigation_message_parse_mouse_over;

    /// Inspect a `gst.Query` and return the `gstvideo.NavigationQueryType` associated with
    /// it if it is a `gstvideo.Navigation` query.
    extern fn gst_navigation_query_get_type(p_query: *gst.Query) gstvideo.NavigationQueryType;
    pub const queryGetType = gst_navigation_query_get_type;

    /// Create a new `gstvideo.Navigation` angles query. When executed, it will
    /// query the pipeline for the set of currently available angles, which may be
    /// greater than one in a multiangle video.
    extern fn gst_navigation_query_new_angles() *gst.Query;
    pub const queryNewAngles = gst_navigation_query_new_angles;

    /// Create a new `gstvideo.Navigation` commands query. When executed, it will
    /// query the pipeline for the set of currently available commands.
    extern fn gst_navigation_query_new_commands() *gst.Query;
    pub const queryNewCommands = gst_navigation_query_new_commands;

    /// Parse the current angle number in the `gstvideo.Navigation` angles `query` into the
    /// `guint` pointed to by the `cur_angle` variable, and the number of available
    /// angles into the `guint` pointed to by the `n_angles` variable.
    extern fn gst_navigation_query_parse_angles(p_query: *gst.Query, p_cur_angle: ?*c_uint, p_n_angles: ?*c_uint) c_int;
    pub const queryParseAngles = gst_navigation_query_parse_angles;

    /// Parse the number of commands in the `gstvideo.Navigation` commands `query`.
    extern fn gst_navigation_query_parse_commands_length(p_query: *gst.Query, p_n_cmds: ?*c_uint) c_int;
    pub const queryParseCommandsLength = gst_navigation_query_parse_commands_length;

    /// Parse the `gstvideo.Navigation` command query and retrieve the `nth` command from
    /// it into `cmd`. If the list contains less elements than `nth`, `cmd` will be
    /// set to `GST_NAVIGATION_COMMAND_INVALID`.
    extern fn gst_navigation_query_parse_commands_nth(p_query: *gst.Query, p_nth: c_uint, p_cmd: ?*gstvideo.NavigationCommand) c_int;
    pub const queryParseCommandsNth = gst_navigation_query_parse_commands_nth;

    /// Set the `gstvideo.Navigation` angles query result field in `query`.
    extern fn gst_navigation_query_set_angles(p_query: *gst.Query, p_cur_angle: c_uint, p_n_angles: c_uint) void;
    pub const querySetAngles = gst_navigation_query_set_angles;

    /// Set the `gstvideo.Navigation` command query result fields in `query`. The number
    /// of commands passed must be equal to `n_commands`.
    extern fn gst_navigation_query_set_commands(p_query: *gst.Query, p_n_cmds: c_int, ...) void;
    pub const querySetCommands = gst_navigation_query_set_commands;

    /// Set the `gstvideo.Navigation` command query result fields in `query`. The number
    /// of commands passed must be equal to `n_commands`.
    extern fn gst_navigation_query_set_commandsv(p_query: *gst.Query, p_n_cmds: c_int, p_cmds: [*]gstvideo.NavigationCommand) void;
    pub const querySetCommandsv = gst_navigation_query_set_commandsv;

    /// Sends the indicated command to the navigation interface.
    extern fn gst_navigation_send_command(p_navigation: *Navigation, p_command: gstvideo.NavigationCommand) void;
    pub const sendCommand = gst_navigation_send_command;

    extern fn gst_navigation_send_event(p_navigation: *Navigation, p_structure: *gst.Structure) void;
    pub const sendEvent = gst_navigation_send_event;

    /// Sends an event to the navigation interface.
    extern fn gst_navigation_send_event_simple(p_navigation: *Navigation, p_event: *gst.Event) void;
    pub const sendEventSimple = gst_navigation_send_event_simple;

    extern fn gst_navigation_send_key_event(p_navigation: *Navigation, p_event: [*:0]const u8, p_key: [*:0]const u8) void;
    pub const sendKeyEvent = gst_navigation_send_key_event;

    /// Sends a mouse event to the navigation interface. Mouse event coordinates
    /// are sent relative to the display space of the related output area. This is
    /// usually the size in pixels of the window associated with the element
    /// implementing the `gstvideo.Navigation` interface.
    extern fn gst_navigation_send_mouse_event(p_navigation: *Navigation, p_event: [*:0]const u8, p_button: c_int, p_x: f64, p_y: f64) void;
    pub const sendMouseEvent = gst_navigation_send_mouse_event;

    /// Sends a mouse scroll event to the navigation interface. Mouse event coordinates
    /// are sent relative to the display space of the related output area. This is
    /// usually the size in pixels of the window associated with the element
    /// implementing the `gstvideo.Navigation` interface.
    extern fn gst_navigation_send_mouse_scroll_event(p_navigation: *Navigation, p_x: f64, p_y: f64, p_delta_x: f64, p_delta_y: f64) void;
    pub const sendMouseScrollEvent = gst_navigation_send_mouse_scroll_event;

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

    extern fn g_object_ref(p_self: *gstvideo.Navigation) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.Navigation) void;
    pub const unref = g_object_unref;

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

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

/// The interface allows unified access to control flipping and rotation
/// operations of video-sources or operators.
pub const VideoDirection = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstvideo.VideoDirectionInterface;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const video_direction = struct {
            pub const name = "video-direction";

            pub const Type = gstvideo.VideoOrientationMethod;
        };
    };

    pub const signals = struct {};

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

    extern fn g_object_ref(p_self: *gstvideo.VideoDirection) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoDirection) void;
    pub const unref = g_object_unref;

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

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

/// The interface allows unified access to control flipping and autocenter
/// operation of video-sources or operators.
pub const VideoOrientation = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstvideo.VideoOrientationInterface;
    pub const virtual_methods = struct {
        /// Get the horizontal centering offset from the given object.
        pub const get_hcenter = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: *c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_get_hcenter.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_center);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: *c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_get_hcenter = @ptrCast(p_implementation);
            }
        };

        /// Get the horizontal flipping state (`TRUE` for flipped) from the given object.
        pub const get_hflip = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: *c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_get_hflip.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_flip);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: *c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_get_hflip = @ptrCast(p_implementation);
            }
        };

        /// Get the vertical centering offset from the given object.
        pub const get_vcenter = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: *c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_get_vcenter.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_center);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: *c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_get_vcenter = @ptrCast(p_implementation);
            }
        };

        /// Get the vertical flipping state (`TRUE` for flipped) from the given object.
        pub const get_vflip = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: *c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_get_vflip.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_flip);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: *c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_get_vflip = @ptrCast(p_implementation);
            }
        };

        /// Set the horizontal centering offset for the given object.
        pub const set_hcenter = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_set_hcenter.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_center);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_set_hcenter = @ptrCast(p_implementation);
            }
        };

        /// Set the horizontal flipping state (`TRUE` for flipped) for the given object.
        pub const set_hflip = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_set_hflip.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_flip);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_set_hflip = @ptrCast(p_implementation);
            }
        };

        /// Set the vertical centering offset for the given object.
        pub const set_vcenter = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_set_vcenter.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_center);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_center: c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_set_vcenter = @ptrCast(p_implementation);
            }
        };

        /// Set the vertical flipping state (`TRUE` for flipped) for the given object.
        pub const set_vflip = struct {
            pub fn call(p_class: anytype, p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: c_int) c_int {
                return gobject.ext.as(VideoOrientation.Iface, p_class).f_set_vflip.?(gobject.ext.as(VideoOrientation, p_video_orientation), p_flip);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_video_orientation: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_flip: c_int) callconv(.c) c_int) void {
                gobject.ext.as(VideoOrientation.Iface, p_class).f_set_vflip = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// Parses the "image-orientation" tag and transforms it into the
    /// `gstvideo.VideoOrientationMethod` enum.
    extern fn gst_video_orientation_from_tag(p_taglist: *gst.TagList, p_method: *gstvideo.VideoOrientationMethod) c_int;
    pub const fromTag = gst_video_orientation_from_tag;

    /// Get the horizontal centering offset from the given object.
    extern fn gst_video_orientation_get_hcenter(p_video_orientation: *VideoOrientation, p_center: *c_int) c_int;
    pub const getHcenter = gst_video_orientation_get_hcenter;

    /// Get the horizontal flipping state (`TRUE` for flipped) from the given object.
    extern fn gst_video_orientation_get_hflip(p_video_orientation: *VideoOrientation, p_flip: *c_int) c_int;
    pub const getHflip = gst_video_orientation_get_hflip;

    /// Get the vertical centering offset from the given object.
    extern fn gst_video_orientation_get_vcenter(p_video_orientation: *VideoOrientation, p_center: *c_int) c_int;
    pub const getVcenter = gst_video_orientation_get_vcenter;

    /// Get the vertical flipping state (`TRUE` for flipped) from the given object.
    extern fn gst_video_orientation_get_vflip(p_video_orientation: *VideoOrientation, p_flip: *c_int) c_int;
    pub const getVflip = gst_video_orientation_get_vflip;

    /// Set the horizontal centering offset for the given object.
    extern fn gst_video_orientation_set_hcenter(p_video_orientation: *VideoOrientation, p_center: c_int) c_int;
    pub const setHcenter = gst_video_orientation_set_hcenter;

    /// Set the horizontal flipping state (`TRUE` for flipped) for the given object.
    extern fn gst_video_orientation_set_hflip(p_video_orientation: *VideoOrientation, p_flip: c_int) c_int;
    pub const setHflip = gst_video_orientation_set_hflip;

    /// Set the vertical centering offset for the given object.
    extern fn gst_video_orientation_set_vcenter(p_video_orientation: *VideoOrientation, p_center: c_int) c_int;
    pub const setVcenter = gst_video_orientation_set_vcenter;

    /// Set the vertical flipping state (`TRUE` for flipped) for the given object.
    extern fn gst_video_orientation_set_vflip(p_video_orientation: *VideoOrientation, p_flip: c_int) c_int;
    pub const setVflip = gst_video_orientation_set_vflip;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoOrientation) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoOrientation) void;
    pub const unref = g_object_unref;

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

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

/// The `gstvideo.VideoOverlay` interface is used for 2 main purposes :
///
/// * To get a grab on the Window where the video sink element is going to render.
///   This is achieved by either being informed about the Window identifier that
///   the video sink element generated, or by forcing the video sink element to use
///   a specific Window identifier for rendering.
/// * To force a redrawing of the latest video frame the video sink element
///   displayed on the Window. Indeed if the `gst.Pipeline` is in `GST_STATE_PAUSED`
///   state, moving the Window around will damage its content. Application
///   developers will want to handle the Expose events themselves and force the
///   video sink element to refresh the Window's content.
///
/// Using the Window created by the video sink is probably the simplest scenario,
/// in some cases, though, it might not be flexible enough for application
/// developers if they need to catch events such as mouse moves and button
/// clicks.
///
/// Setting a specific Window identifier on the video sink element is the most
/// flexible solution but it has some issues. Indeed the application needs to set
/// its Window identifier at the right time to avoid internal Window creation
/// from the video sink element. To solve this issue a `gst.Message` is posted on
/// the bus to inform the application that it should set the Window identifier
/// immediately. Here is an example on how to do that correctly:
/// ```
/// static GstBusSyncReply
/// create_window (GstBus * bus, GstMessage * message, GstPipeline * pipeline)
/// {
///  // ignore anything but 'prepare-window-handle' element messages
///  if (!gst_is_video_overlay_prepare_window_handle_message (message))
///    return GST_BUS_PASS;
///
///  win = XCreateSimpleWindow (disp, root, 0, 0, 320, 240, 0, 0, 0);
///
///  XSetWindowBackgroundPixmap (disp, win, None);
///
///  XMapRaised (disp, win);
///
///  XSync (disp, FALSE);
///
///  gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message)),
///      win);
///
///  gst_message_unref (message);
///
///  return GST_BUS_DROP;
/// }
/// ...
/// int
/// main (int argc, char **argv)
/// {
/// ...
///  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
///  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) create_window, pipeline,
///         NULL);
/// ...
/// }
/// ```
///
/// ## Two basic usage scenarios
///
/// There are two basic usage scenarios: in the simplest case, the application
/// uses `playbin` or `playsink` or knows exactly what particular element is used
/// for video output, which is usually the case when the application creates
/// the videosink to use (e.g. `xvimagesink`, `ximagesink`, etc.) itself; in this
/// case, the application can just create the videosink element, create and
/// realize the window to render the video on and then
/// call `gstvideo.VideoOverlay.setWindowHandle` directly with the XID or native
/// window handle, before starting up the pipeline.
/// As `playbin` and `playsink` implement the video overlay interface and proxy
/// it transparently to the actual video sink even if it is created later, this
/// case also applies when using these elements.
///
/// In the other and more common case, the application does not know in advance
/// what GStreamer video sink element will be used for video output. This is
/// usually the case when an element such as `autovideosink` is used.
/// In this case, the video sink element itself is created
/// asynchronously from a GStreamer streaming thread some time after the
/// pipeline has been started up. When that happens, however, the video sink
/// will need to know right then whether to render onto an already existing
/// application window or whether to create its own window. This is when it
/// posts a prepare-window-handle message, and that is also why this message needs
/// to be handled in a sync bus handler which will be called from the streaming
/// thread directly (because the video sink will need an answer right then).
///
/// As response to the prepare-window-handle element message in the bus sync
/// handler, the application may use `gstvideo.VideoOverlay.setWindowHandle` to tell
/// the video sink to render onto an existing window surface. At this point the
/// application should already have obtained the window handle / XID, so it
/// just needs to set it. It is generally not advisable to call any GUI toolkit
/// functions or window system functions from the streaming thread in which the
/// prepare-window-handle message is handled, because most GUI toolkits and
/// windowing systems are not thread-safe at all and a lot of care would be
/// required to co-ordinate the toolkit and window system calls of the
/// different threads (Gtk+ users please note: prior to Gtk+ 2.18
/// `GDK_WINDOW_XID` was just a simple structure access, so generally fine to do
/// within the bus sync handler; this macro was changed to a function call in
/// Gtk+ 2.18 and later, which is likely to cause problems when called from a
/// sync handler; see below for a better approach without `GDK_WINDOW_XID`
/// used in the callback).
///
/// ## GstVideoOverlay and Gtk+
///
/// ```
/// `include` <gst/video/videooverlay.h>
/// `include` <gtk/gtk.h>
/// `ifdef` GDK_WINDOWING_X11
/// `include` <gdk/gdkx.h>  // for GDK_WINDOW_XID
/// `endif`
/// `ifdef` GDK_WINDOWING_WIN32
/// `include` <gdk/gdkwin32.h>  // for GDK_WINDOW_HWND
/// `endif`
/// ...
/// static guintptr video_window_handle = 0;
/// ...
/// static GstBusSyncReply
/// bus_sync_handler (GstBus * bus, GstMessage * message, gpointer user_data)
/// {
///  // ignore anything but 'prepare-window-handle' element messages
///  if (!gst_is_video_overlay_prepare_window_handle_message (message))
///    return GST_BUS_PASS;
///
///  if (video_window_handle != 0) {
///    GstVideoOverlay *overlay;
///
///    // GST_MESSAGE_SRC (message) will be the video sink element
///    overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
///    gst_video_overlay_set_window_handle (overlay, video_window_handle);
///  } else {
///    g_warning ("Should have obtained video_window_handle by now!");
///  }
///
///  gst_message_unref (message);
///  return GST_BUS_DROP;
/// }
/// ...
/// static void
/// video_widget_realize_cb (GtkWidget * widget, gpointer data)
/// {
/// `@"if"` GTK_CHECK_VERSION(2,18,0)
///   // Tell Gtk+/Gdk to create a native window for this widget instead of
///   // drawing onto the parent widget.
///   // This is here just for pedagogical purposes, GDK_WINDOW_XID will call
///   // it as well in newer Gtk versions
///   if (!gdk_window_ensure_native (widget->window))
///     g_error ("Couldn't create native window needed for GstVideoOverlay!");
/// `endif`
///
/// `ifdef` GDK_WINDOWING_X11
///   {
///     gulong xid = GDK_WINDOW_XID (gtk_widget_get_window (video_window));
///     video_window_handle = xid;
///   }
/// `endif`
/// `ifdef` GDK_WINDOWING_WIN32
///   {
///     HWND wnd = GDK_WINDOW_HWND (gtk_widget_get_window (video_window));
///     video_window_handle = (guintptr) wnd;
///   }
/// `endif`
/// }
/// ...
/// int
/// main (int argc, char **argv)
/// {
///   GtkWidget *video_window;
///   GtkWidget *app_window;
///   ...
///   app_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
///   ...
///   video_window = gtk_drawing_area_new ();
///   g_signal_connect (video_window, "realize",
///       G_CALLBACK (video_widget_realize_cb), NULL);
///   gtk_widget_set_double_buffered (video_window, FALSE);
///   ...
///   // usually the video_window will not be directly embedded into the
///   // application window like this, but there will be many other widgets
///   // and the video window will be embedded in one of them instead
///   gtk_container_add (GTK_CONTAINER (ap_window), video_window);
///   ...
///   // show the GUI
///   gtk_widget_show_all (app_window);
///
///   // realize window now so that the video window gets created and we can
///   // obtain its XID/HWND before the pipeline is started up and the videosink
///   // asks for the XID/HWND of the window to render onto
///   gtk_widget_realize (video_window);
///
///   // we should have the XID/HWND now
///   g_assert (video_window_handle != 0);
///   ...
///   // set up sync handler for setting the xid once the pipeline is started
///   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
///   gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, NULL,
///       NULL);
///   gst_object_unref (bus);
///   ...
///   gst_element_set_state (pipeline, GST_STATE_PLAYING);
///   ...
/// }
/// ```
///
/// ## GstVideoOverlay and Qt
///
/// ```
/// `include` <glib.h>;
/// `include` <gst/gst.h>;
/// `include` <gst/video/videooverlay.h>;
///
/// `include` <QApplication>;
/// `include` <QTimer>;
/// `include` <QWidget>;
///
/// int main(int argc, char *argv[])
/// {
///   if (!g_thread_supported ())
///     g_thread_init (NULL);
///
///   gst_init (&argc, &argv);
///   QApplication app(argc, argv);
///   app.connect(&app, SIGNAL(`lastWindowClosed`), &app, SLOT(quit ()));
///
///   // prepare the pipeline
///
///   GstElement *pipeline = gst_pipeline_new ("xvoverlay");
///   GstElement *src = gst_element_factory_make ("videotestsrc", NULL);
///   GstElement *sink = gst_element_factory_make ("xvimagesink", NULL);
///   gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
///   gst_element_link (src, sink);
///
///   // prepare the ui
///
///   QWidget window;
///   window.resize(320, 240);
///   window.`show`;
///
///   WId xwinid = window.`winId`;
///   gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid);
///
///   // run the pipeline
///
///   GstStateChangeReturn sret = gst_element_set_state (pipeline,
///       GST_STATE_PLAYING);
///   if (sret == GST_STATE_CHANGE_FAILURE) {
///     gst_element_set_state (pipeline, GST_STATE_NULL);
///     gst_object_unref (pipeline);
///     // Exit application
///     QTimer::singleShot(0, QApplication::`activeWindow`, SLOT(`quit`));
///   }
///
///   int ret = app.`exec`;
///
///   window.`hide`;
///   gst_element_set_state (pipeline, GST_STATE_NULL);
///   gst_object_unref (pipeline);
///
///   return ret;
/// }
/// ```
pub const VideoOverlay = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstvideo.VideoOverlayInterface;
    pub const virtual_methods = struct {
        /// Tell an overlay that it has been exposed. This will redraw the current frame
        /// in the drawable even if the pipeline is PAUSED.
        pub const expose = struct {
            pub fn call(p_class: anytype, p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) void {
                return gobject.ext.as(VideoOverlay.Iface, p_class).f_expose.?(gobject.ext.as(VideoOverlay, p_overlay));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) void) void {
                gobject.ext.as(VideoOverlay.Iface, p_class).f_expose = @ptrCast(p_implementation);
            }
        };

        /// Tell an overlay that it should handle events from the window system. These
        /// events are forwarded upstream as navigation events. In some window system,
        /// events are not propagated in the window hierarchy if a client is listening
        /// for them. This method allows you to disable events handling completely
        /// from the `gstvideo.VideoOverlay`.
        pub const handle_events = struct {
            pub fn call(p_class: anytype, p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle_events: c_int) void {
                return gobject.ext.as(VideoOverlay.Iface, p_class).f_handle_events.?(gobject.ext.as(VideoOverlay, p_overlay), p_handle_events);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle_events: c_int) callconv(.c) void) void {
                gobject.ext.as(VideoOverlay.Iface, p_class).f_handle_events = @ptrCast(p_implementation);
            }
        };

        /// virtual method to set the render rectangle
        pub const set_render_rectangle = struct {
            pub fn call(p_class: anytype, p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) void {
                return gobject.ext.as(VideoOverlay.Iface, p_class).f_set_render_rectangle.?(gobject.ext.as(VideoOverlay, p_overlay), p_x, p_y, p_width, p_height);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) callconv(.c) void) void {
                gobject.ext.as(VideoOverlay.Iface, p_class).f_set_render_rectangle = @ptrCast(p_implementation);
            }
        };

        /// This will call the video overlay's set_window_handle method. You
        /// should use this method to tell to an overlay to display video output to a
        /// specific window (e.g. an XWindow on X11). Passing 0 as the  `handle` will
        /// tell the overlay to stop using that window and create an internal one.
        pub const set_window_handle = struct {
            pub fn call(p_class: anytype, p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle: usize) void {
                return gobject.ext.as(VideoOverlay.Iface, p_class).f_set_window_handle.?(gobject.ext.as(VideoOverlay, p_overlay), p_handle);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_overlay: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_handle: usize) callconv(.c) void) void {
                gobject.ext.as(VideoOverlay.Iface, p_class).f_set_window_handle = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    /// This helper shall be used by classes implementing the `gstvideo.VideoOverlay`
    /// interface that want the render rectangle to be controllable using
    /// properties. This helper will install "render-rectangle" property into the
    /// class.
    extern fn gst_video_overlay_install_properties(p_oclass: *gobject.ObjectClass, p_last_prop_id: c_int) void;
    pub const installProperties = gst_video_overlay_install_properties;

    /// This helper shall be used by classes implementing the `gstvideo.VideoOverlay`
    /// interface that want the render rectangle to be controllable using
    /// properties. This helper will parse and set the render rectangle calling
    /// `gstvideo.VideoOverlay.setRenderRectangle`.
    extern fn gst_video_overlay_set_property(p_object: *gobject.Object, p_last_prop_id: c_int, p_property_id: c_uint, p_value: *const gobject.Value) c_int;
    pub const setProperty = gst_video_overlay_set_property;

    /// Tell an overlay that it has been exposed. This will redraw the current frame
    /// in the drawable even if the pipeline is PAUSED.
    extern fn gst_video_overlay_expose(p_overlay: *VideoOverlay) void;
    pub const expose = gst_video_overlay_expose;

    /// This will post a "have-window-handle" element message on the bus.
    ///
    /// This function should only be used by video overlay plugin developers.
    extern fn gst_video_overlay_got_window_handle(p_overlay: *VideoOverlay, p_handle: usize) void;
    pub const gotWindowHandle = gst_video_overlay_got_window_handle;

    /// Tell an overlay that it should handle events from the window system. These
    /// events are forwarded upstream as navigation events. In some window system,
    /// events are not propagated in the window hierarchy if a client is listening
    /// for them. This method allows you to disable events handling completely
    /// from the `gstvideo.VideoOverlay`.
    extern fn gst_video_overlay_handle_events(p_overlay: *VideoOverlay, p_handle_events: c_int) void;
    pub const handleEvents = gst_video_overlay_handle_events;

    /// This will post a "prepare-window-handle" element message on the bus
    /// to give applications an opportunity to call
    /// `gstvideo.VideoOverlay.setWindowHandle` before a plugin creates its own
    /// window.
    ///
    /// This function should only be used by video overlay plugin developers.
    extern fn gst_video_overlay_prepare_window_handle(p_overlay: *VideoOverlay) void;
    pub const prepareWindowHandle = gst_video_overlay_prepare_window_handle;

    /// Configure a subregion as a video target within the window set by
    /// `gstvideo.VideoOverlay.setWindowHandle`. If this is not used or not supported
    /// the video will fill the area of the window set as the overlay to 100%.
    /// By specifying the rectangle, the video can be overlayed to a specific region
    /// of that window only. After setting the new rectangle one should call
    /// `gstvideo.VideoOverlay.expose` to force a redraw. To unset the region pass -1 for
    /// the `width` and `height` parameters.
    ///
    /// This method is needed for non fullscreen video overlay in UI toolkits that
    /// do not support subwindows.
    extern fn gst_video_overlay_set_render_rectangle(p_overlay: *VideoOverlay, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) c_int;
    pub const setRenderRectangle = gst_video_overlay_set_render_rectangle;

    /// This will call the video overlay's set_window_handle method. You
    /// should use this method to tell to an overlay to display video output to a
    /// specific window (e.g. an XWindow on X11). Passing 0 as the  `handle` will
    /// tell the overlay to stop using that window and create an internal one.
    extern fn gst_video_overlay_set_window_handle(p_overlay: *VideoOverlay, p_handle: usize) void;
    pub const setWindowHandle = gst_video_overlay_set_window_handle;

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

    extern fn g_object_ref(p_self: *gstvideo.VideoOverlay) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstvideo.VideoOverlay) void;
    pub const unref = g_object_unref;

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

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

/// `gst.Meta` for carrying SMPTE-291M Ancillary data. Note that all the ADF fields
///    (`DID` to `checksum`) are 10bit values with parity/non-parity high-bits set.
pub const AncillaryMeta = extern struct {
    /// Parent `gst.Meta`
    f_meta: gst.Meta,
    /// The field where the ancillary data is located
    f_field: gstvideo.AncillaryMetaField,
    /// Which channel (luminance or chrominance) the ancillary
    ///    data is located. 0 if content is SD or stored in the luminance channel
    ///    (default). 1 if HD and stored in the chrominance channel.
    f_c_not_y_channel: c_int,
    /// The line on which the ancillary data is located (max 11bit). There
    ///    are two special values: 0x7ff if no line is specified (default), 0x7fe
    ///    to specify the ancillary data is on any valid line before active video
    f_line: u16,
    /// The location of the ancillary data packet in a SDI raster relative
    ///    to the start of active video (max 12bits). A value of 0 means the ADF of
    ///    the ancillary packet starts immediately following SAV. There are 3
    ///    special values: 0xfff: No specified location (default), 0xffe: within
    ///    HANC data space, 0xffd: within the ancillary data space located between
    ///    SAV and EAV
    f_offset: u16,
    /// Data Identified
    f_DID: u16,
    /// Secondary Data identification (if type 2) or Data block
    ///    number (if type 1)
    f_SDID_block_number: u16,
    /// The amount of user data
    f_data_count: u16,
    /// The User data
    f_data: ?*u16,
    /// The checksum of the ADF
    f_checksum: u16,

    extern fn gst_ancillary_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_ancillary_meta_get_info;

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

/// Color-balance channel class.
pub const ColorBalanceChannelClass = extern struct {
    pub const Instance = gstvideo.ColorBalanceChannel;

    /// the parent class
    f_parent: gobject.ObjectClass,
    /// default handler for value changed notification
    f_value_changed: ?*const fn (p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

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

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

/// Color-balance interface.
pub const ColorBalanceInterface = extern struct {
    pub const Instance = gstvideo.ColorBalance;

    /// the parent interface
    f_iface: gobject.TypeInterface,
    /// list handled channels
    f_list_channels: ?*const fn (p_balance: *gstvideo.ColorBalance) callconv(.c) *const glib.List,
    /// set a channel value
    f_set_value: ?*const fn (p_balance: *gstvideo.ColorBalance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) callconv(.c) void,
    /// get a channel value
    f_get_value: ?*const fn (p_balance: *gstvideo.ColorBalance, p_channel: *gstvideo.ColorBalanceChannel) callconv(.c) c_int,
    /// implementation type
    f_get_balance_type: ?*const fn (p_balance: *gstvideo.ColorBalance) callconv(.c) gstvideo.ColorBalanceType,
    /// default handler for value changed notification
    f_value_changed: ?*const fn (p_balance: *gstvideo.ColorBalance, p_channel: *gstvideo.ColorBalanceChannel, p_value: c_int) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

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

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

/// Navigation interface.
pub const NavigationInterface = extern struct {
    pub const Instance = gstvideo.Navigation;

    /// the parent interface
    f_iface: gobject.TypeInterface,
    /// sending a navigation event
    f_send_event: ?*const fn (p_navigation: *gstvideo.Navigation, p_structure: *gst.Structure) callconv(.c) void,
    /// sending a navigation event (Since: 1.22)
    f_send_event_simple: ?*const fn (p_navigation: *gstvideo.Navigation, p_event: *gst.Event) callconv(.c) void,

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

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

/// Active Format Description (AFD)
///
/// For details, see Table 6.14 Active Format in:
///
/// ATSC Digital Television Standard:
/// Part 4 – MPEG-2 Video System Characteristics
///
/// https://www.atsc.org/wp-content/uploads/2015/03/a_53-Part-4-2009.pdf
///
/// and Active Format Description in Complete list of AFD codes
///
/// https://en.wikipedia.org/wiki/Active_Format_Description`Complete_list_of_AFD_codes`
///
/// and SMPTE ST2016-1
pub const VideoAFDMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// 0 for progressive or field 1 and 1 for field 2
    f_field: u8,
    /// `gstvideo.VideoAFDSpec` that applies to `afd`
    f_spec: gstvideo.VideoAFDSpec,
    /// `gstvideo.VideoAFDValue` AFD value
    f_afd: gstvideo.VideoAFDValue,

    extern fn gst_video_afd_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_afd_meta_get_info;

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

/// Extra buffer metadata for performing an affine transformation using a 4x4
/// matrix. The transformation matrix can be composed with
/// `gstvideo.VideoAffineTransformationMeta.applyMatrix`.
///
/// The vertices operated on are all in the range 0 to 1, not in
/// Normalized Device Coordinates (-1 to +1). Transforming points in this space
/// are assumed to have an origin at (0.5, 0.5, 0.5) in a left-handed coordinate
/// system with the x-axis moving horizontally (positive values to the right),
/// the y-axis moving vertically (positive values up the screen) and the z-axis
/// perpendicular to the screen (positive values into the screen).
pub const VideoAffineTransformationMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// the column-major 4x4 transformation matrix
    f_matrix: [16]f32,

    extern fn gst_video_affine_transformation_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_affine_transformation_meta_get_info;

    /// Apply a transformation using the given 4x4 transformation matrix.
    /// Performs the multiplication, meta->matrix X matrix.
    extern fn gst_video_affine_transformation_meta_apply_matrix(p_meta: *VideoAffineTransformationMeta, p_matrix: *const [16]f32) void;
    pub const applyMatrix = gst_video_affine_transformation_meta_apply_matrix;

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

pub const VideoAggregatorClass = extern struct {
    pub const Instance = gstvideo.VideoAggregator;

    f_parent_class: gstbase.AggregatorClass,
    /// Optional.
    ///                            Lets subclasses update the `gst.Caps` representing
    ///                            the src pad caps before usage.  Return `NULL` to indicate failure.
    f_update_caps: ?*const fn (p_videoaggregator: *gstvideo.VideoAggregator, p_caps: *gst.Caps) callconv(.c) *gst.Caps,
    /// Lets subclasses aggregate frames that are ready. Subclasses
    ///                            should iterate the GstElement.sinkpads and use the already
    ///                            mapped `gstvideo.VideoFrame` from `gstvideo.VideoAggregatorPad.getPreparedFrame`
    ///                            or directly use the `gst.Buffer` from `gstvideo.VideoAggregatorPad.getCurrentBuffer`
    ///                            if it needs to map the buffer in a special way. The result of the
    ///                            aggregation should land in `outbuffer`.
    f_aggregate_frames: ?*const fn (p_videoaggregator: *gstvideo.VideoAggregator, p_outbuffer: *gst.Buffer) callconv(.c) gst.FlowReturn,
    /// Optional.
    ///                            Lets subclasses provide a `gst.Buffer` to be used as `outbuffer` of
    ///                            the `aggregate_frames` vmethod.
    f_create_output_buffer: ?*const fn (p_videoaggregator: *gstvideo.VideoAggregator, p_outbuffer: **gst.Buffer) callconv(.c) gst.FlowReturn,
    /// Optional.
    ///                            Lets subclasses decide of the best common format to use.
    f_find_best_format: ?*const fn (p_vagg: *gstvideo.VideoAggregator, p_downstream_caps: *gst.Caps, p_best_info: *gstvideo.VideoInfo, p_at_least_one_alpha: *c_int) callconv(.c) void,
    f__gst_reserved: [20]*anyopaque,

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

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

pub const VideoAggregatorConvertPadClass = extern struct {
    pub const Instance = gstvideo.VideoAggregatorConvertPad;

    f_parent_class: gstvideo.VideoAggregatorPadClass,
    f_create_conversion_info: ?*const fn (p_pad: *gstvideo.VideoAggregatorConvertPad, p_agg: *gstvideo.VideoAggregator, p_conversion_info: *gstvideo.VideoInfo) callconv(.c) void,
    f__gst_reserved: [4]*anyopaque,

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

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

pub const VideoAggregatorConvertPadPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const VideoAggregatorPadClass = extern struct {
    pub const Instance = gstvideo.VideoAggregatorPad;

    f_parent_class: gstbase.AggregatorPadClass,
    /// Called when either the input or output formats
    ///                          have changed.
    f_update_conversion_info: ?*const fn (p_pad: *gstvideo.VideoAggregatorPad) callconv(.c) void,
    /// Prepare the frame from the pad buffer and sets it to prepared_frame.
    ///      Implementations should always return TRUE.  Returning FALSE will cease
    ///      iteration over subsequent pads.
    f_prepare_frame: ?*const fn (p_pad: *gstvideo.VideoAggregatorPad, p_videoaggregator: *gstvideo.VideoAggregator, p_buffer: *gst.Buffer, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) c_int,
    /// clean the frame previously prepared in prepare_frame
    f_clean_frame: ?*const fn (p_pad: *gstvideo.VideoAggregatorPad, p_videoaggregator: *gstvideo.VideoAggregator, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) void,
    f_prepare_frame_start: ?*const fn (p_pad: *gstvideo.VideoAggregatorPad, p_videoaggregator: *gstvideo.VideoAggregator, p_buffer: *gst.Buffer, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) void,
    f_prepare_frame_finish: ?*const fn (p_pad: *gstvideo.VideoAggregatorPad, p_videoaggregator: *gstvideo.VideoAggregator, p_prepared_frame: *gstvideo.VideoFrame) callconv(.c) void,
    f__gst_reserved: [18]*anyopaque,

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

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

pub const VideoAggregatorPadPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

pub const VideoAggregatorParallelConvertPadClass = extern struct {
    pub const Instance = gstvideo.VideoAggregatorParallelConvertPad;

    f_parent_class: gstvideo.VideoAggregatorConvertPadClass,
    f__gst_reserved: [4]*anyopaque,

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

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

pub const VideoAggregatorPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Extra alignment parameters for the memory of video buffers. This
/// structure is usually used to configure the bufferpool if it supports the
/// `GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT`.
pub const VideoAlignment = extern struct {
    /// extra pixels on the top
    f_padding_top: c_uint,
    /// extra pixels on the bottom
    f_padding_bottom: c_uint,
    /// extra pixels on the left side
    f_padding_left: c_uint,
    /// extra pixels on the right side
    f_padding_right: c_uint,
    /// array with extra alignment requirements for the strides
    f_stride_align: [4]c_uint,

    /// Set `align` to its default values with no padding and no alignment.
    extern fn gst_video_alignment_reset(p_align: *VideoAlignment) void;
    pub const reset = gst_video_alignment_reset;

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

/// Video Ancillary data, according to SMPTE-291M specification.
///
/// Note that the contents of the data are always stored as 8bit data (i.e. do not contain
/// the parity check bits).
pub const VideoAncillary = extern struct {
    /// The Data Identifier
    f_DID: u8,
    /// The Secondary Data Identifier (if type 2) or the Data
    ///                     Block Number (if type 1)
    f_SDID_block_number: u8,
    /// The amount of data (in bytes) in `data` (max 255 bytes)
    f_data_count: u8,
    /// The user data content of the Ancillary packet.
    ///    Does not contain the ADF, DID, SDID nor CS.
    f_data: ?[*]u8,
    f__gst_reserved: [4]*anyopaque,

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

/// Bar data should be included in video user data
/// whenever the rectangular picture area containing useful information
/// does not extend to the full height or width of the coded frame
/// and AFD alone is insufficient to describe the extent of the image.
///
/// Note: either vertical or horizontal bars are specified, but not both.
///
/// For more details, see:
///
/// https://www.atsc.org/wp-content/uploads/2015/03/a_53-Part-4-2009.pdf
///
/// and SMPTE ST2016-1
pub const VideoBarMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// 0 for progressive or field 1 and 1 for field 2
    f_field: u8,
    /// if true then bar data specifies letterbox, otherwise pillarbox
    f_is_letterbox: c_int,
    /// If `is_letterbox` is true, then the value specifies the
    ///      last line of a horizontal letterbox bar area at top of reconstructed frame.
    ///      Otherwise, it specifies the last horizontal luminance sample of a vertical pillarbox
    ///      bar area at the left side of the reconstructed frame
    f_bar_data1: c_uint,
    /// If `is_letterbox` is true, then the value specifies the
    ///      first line of a horizontal letterbox bar area at bottom of reconstructed frame.
    ///      Otherwise, it specifies the first horizontal
    ///      luminance sample of a vertical pillarbox bar area at the right side of the reconstructed frame.
    f_bar_data2: c_uint,

    extern fn gst_video_bar_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_bar_meta_get_info;

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

pub const VideoBufferPoolClass = extern struct {
    pub const Instance = gstvideo.VideoBufferPool;

    f_parent_class: gst.BufferPoolClass,

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

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

pub const VideoBufferPoolPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Extra buffer metadata providing Closed Caption.
pub const VideoCaptionMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// The type of Closed Caption contained in the meta.
    f_caption_type: gstvideo.VideoCaptionType,
    /// The Closed Caption data.
    f_data: ?[*]u8,
    /// The size in bytes of `data`
    f_size: usize,

    extern fn gst_video_caption_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_caption_meta_get_info;

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

pub const VideoChromaResample = opaque {
    /// Create a new resampler object for the given parameters. When `h_factor` or
    /// `v_factor` is > 0, upsampling will be used, otherwise subsampling is
    /// performed.
    extern fn gst_video_chroma_resample_new(p_method: gstvideo.VideoChromaMethod, p_site: gstvideo.VideoChromaSite, p_flags: gstvideo.VideoChromaFlags, p_format: gstvideo.VideoFormat, p_h_factor: c_int, p_v_factor: c_int) *gstvideo.VideoChromaResample;
    pub const new = gst_video_chroma_resample_new;

    /// Free `resample`
    extern fn gst_video_chroma_resample_free(p_resample: *VideoChromaResample) void;
    pub const free = gst_video_chroma_resample_free;

    /// The resampler must be fed `n_lines` at a time. The first line should be
    /// at `offset`.
    extern fn gst_video_chroma_resample_get_info(p_resample: *VideoChromaResample, p_n_lines: ?*c_uint, p_offset: ?*c_int) void;
    pub const getInfo = gst_video_chroma_resample_get_info;

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

/// This meta is primarily for internal use in GStreamer elements to support
/// VP8/VP9 transparent video stored into WebM or Matroska containers, or
/// transparent static AV1 images. Nothing prevents you from using this meta
/// for custom purposes, but it generally can't be used to easily to add support
/// for alpha channels to CODECs or formats that don't support that out of the
/// box.
pub const VideoCodecAlphaMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// the encoded alpha frame
    f_buffer: ?*gst.Buffer,

    extern fn gst_video_codec_alpha_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_codec_alpha_meta_get_info;

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

/// A `gstvideo.VideoCodecFrame` represents a video frame both in raw and
/// encoded form.
pub const VideoCodecFrame = extern struct {
    f_ref_count: c_int,
    f_flags: u32,
    /// Unique identifier for the frame. Use this if you need
    ///       to get hold of the frame later (like when data is being decoded).
    ///       Typical usage in decoders is to set this on the opaque value provided
    ///       to the library and get back the frame using `gstvideo.VideoDecoder.getFrame`
    f_system_frame_number: u32,
    f_decode_frame_number: u32,
    f_presentation_frame_number: u32,
    /// Decoding timestamp
    f_dts: gst.ClockTime,
    /// Presentation timestamp
    f_pts: gst.ClockTime,
    /// Duration of the frame
    f_duration: gst.ClockTime,
    /// Distance in frames from the last synchronization point.
    f_distance_from_sync: c_int,
    /// the input `gst.Buffer` that created this frame. The buffer is owned
    ///           by the frame and references to the frame instead of the buffer should
    ///           be kept.
    f_input_buffer: ?*gst.Buffer,
    /// the output `gst.Buffer`. Implementations should set this either
    ///           directly, or by using the
    ///           `gstvideo.VideoDecoder.allocateOutputFrame` or
    ///           `gstvideo.VideoDecoder.allocateOutputBuffer` methods. The buffer is
    ///           owned by the frame and references to the frame instead of the
    ///           buffer should be kept.
    f_output_buffer: ?*gst.Buffer,
    /// Running time when the frame will be used.
    f_deadline: gst.ClockTime,
    f_events: ?*glib.List,
    f_user_data: ?*anyopaque,
    f_user_data_destroy_notify: ?glib.DestroyNotify,
    anon0: extern union {
        anon0: extern struct {
            f_ts: gst.ClockTime,
            f_ts2: gst.ClockTime,
            f_num_subframes: c_uint,
            f_subframes_processed: c_uint,
        },
        f_padding: [20]*anyopaque,
    },

    /// Gets private data set on the frame by the subclass via
    /// `gstvideo.VideoCodecFrame.setUserData` previously.
    extern fn gst_video_codec_frame_get_user_data(p_frame: *VideoCodecFrame) ?*anyopaque;
    pub const getUserData = gst_video_codec_frame_get_user_data;

    /// Increases the refcount of the given frame by one.
    extern fn gst_video_codec_frame_ref(p_frame: *VideoCodecFrame) *gstvideo.VideoCodecFrame;
    pub const ref = gst_video_codec_frame_ref;

    /// Sets `user_data` on the frame and the `glib.DestroyNotify` that will be called when
    /// the frame is freed. Allows to attach private data by the subclass to frames.
    ///
    /// If a `user_data` was previously set, then the previous set `notify` will be called
    /// before the `user_data` is replaced.
    extern fn gst_video_codec_frame_set_user_data(p_frame: *VideoCodecFrame, p_user_data: ?*anyopaque, p_notify: glib.DestroyNotify) void;
    pub const setUserData = gst_video_codec_frame_set_user_data;

    /// Decreases the refcount of the frame. If the refcount reaches 0, the frame
    /// will be freed.
    extern fn gst_video_codec_frame_unref(p_frame: *VideoCodecFrame) void;
    pub const unref = gst_video_codec_frame_unref;

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

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

/// Structure representing the state of an incoming or outgoing video
/// stream for encoders and decoders.
///
/// Decoders and encoders will receive such a state through their
/// respective `set_format` vmethods.
///
/// Decoders and encoders can set the downstream state, by using the
/// `gstvideo.VideoDecoder.setOutputState` or
/// `gstvideo.VideoEncoder.setOutputState` methods.
pub const VideoCodecState = extern struct {
    f_ref_count: c_int,
    /// The `gstvideo.VideoInfo` describing the stream
    f_info: gstvideo.VideoInfo,
    /// The `gst.Caps` used in the caps negotiation of the pad.
    f_caps: ?*gst.Caps,
    /// a `gst.Buffer` corresponding to the
    ///     'codec_data' field of a stream, or NULL.
    f_codec_data: ?*gst.Buffer,
    /// The `gst.Caps` for allocation query and pool
    ///     negotiation. Since: 1.10
    f_allocation_caps: ?*gst.Caps,
    /// Mastering display color volume information (HDR metadata) for the stream.
    f_mastering_display_info: ?*gstvideo.VideoMasteringDisplayInfo,
    /// Content light level information for the stream.
    f_content_light_level: ?*gstvideo.VideoContentLightLevel,
    f_padding: [17]*anyopaque,

    /// Increases the refcount of the given state by one.
    extern fn gst_video_codec_state_ref(p_state: *VideoCodecState) *gstvideo.VideoCodecState;
    pub const ref = gst_video_codec_state_ref;

    /// Decreases the refcount of the state. If the refcount reaches 0, the state
    /// will be freed.
    extern fn gst_video_codec_state_unref(p_state: *VideoCodecState) void;
    pub const unref = gst_video_codec_state_unref;

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

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

/// Structure describing the chromaticity coordinates of an RGB system. These
/// values can be used to construct a matrix to transform RGB to and from the
/// XYZ colorspace.
pub const VideoColorPrimariesInfo = extern struct {
    /// a `gstvideo.VideoColorPrimaries`
    f_primaries: gstvideo.VideoColorPrimaries,
    /// reference white x coordinate
    f_Wx: f64,
    /// reference white y coordinate
    f_Wy: f64,
    /// red x coordinate
    f_Rx: f64,
    /// red y coordinate
    f_Ry: f64,
    /// green x coordinate
    f_Gx: f64,
    /// green y coordinate
    f_Gy: f64,
    /// blue x coordinate
    f_Bx: f64,
    /// blue y coordinate
    f_By: f64,

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

/// Structure describing the color info.
pub const VideoColorimetry = extern struct {
    /// the color range. This is the valid range for the samples.
    ///         It is used to convert the samples to Y'PbPr values.
    f_range: gstvideo.VideoColorRange,
    /// the color matrix. Used to convert between Y'PbPr and
    ///          non-linear RGB (R'G'B')
    f_matrix: gstvideo.VideoColorMatrix,
    /// the transfer function. used to convert between R'G'B' and RGB
    f_transfer: gstvideo.VideoTransferFunction,
    /// color primaries. used to convert between R'G'B' and CIE XYZ
    f_primaries: gstvideo.VideoColorPrimaries,

    /// Parse the colorimetry string and update `cinfo` with the parsed
    /// values.
    extern fn gst_video_colorimetry_from_string(p_cinfo: *VideoColorimetry, p_color: [*:0]const u8) c_int;
    pub const fromString = gst_video_colorimetry_from_string;

    /// Compare the 2 colorimetry sets for equality
    extern fn gst_video_colorimetry_is_equal(p_cinfo: *const VideoColorimetry, p_other: *const gstvideo.VideoColorimetry) c_int;
    pub const isEqual = gst_video_colorimetry_is_equal;

    /// Compare the 2 colorimetry sets for functionally equality
    extern fn gst_video_colorimetry_is_equivalent(p_cinfo: *const VideoColorimetry, p_bitdepth: c_uint, p_other: *const gstvideo.VideoColorimetry, p_other_bitdepth: c_uint) c_int;
    pub const isEquivalent = gst_video_colorimetry_is_equivalent;

    /// Check if the colorimetry information in `info` matches that of the
    /// string `color`.
    extern fn gst_video_colorimetry_matches(p_cinfo: *const VideoColorimetry, p_color: [*:0]const u8) c_int;
    pub const matches = gst_video_colorimetry_matches;

    /// Make a string representation of `cinfo`.
    extern fn gst_video_colorimetry_to_string(p_cinfo: *const VideoColorimetry) ?[*:0]u8;
    pub const toString = gst_video_colorimetry_to_string;

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

/// Content light level information specified in CEA-861.3, Appendix A.
pub const VideoContentLightLevel = extern struct {
    /// the maximum content light level
    ///   (abbreviated to MaxCLL) in candelas per square meter (cd/m^2 and nit)
    f_max_content_light_level: u16,
    /// the maximum frame average light level
    ///   (abbreviated to MaxFLL) in candelas per square meter (cd/m^2 and nit)
    f_max_frame_average_light_level: u16,
    f__gst_reserved: [4]*anyopaque,

    /// Parse `caps` and update `linfo`
    extern fn gst_video_content_light_level_add_to_caps(p_linfo: *const VideoContentLightLevel, p_caps: *gst.Caps) c_int;
    pub const addToCaps = gst_video_content_light_level_add_to_caps;

    /// Parse `caps` and update `linfo`
    extern fn gst_video_content_light_level_from_caps(p_linfo: *VideoContentLightLevel, p_caps: *const gst.Caps) c_int;
    pub const fromCaps = gst_video_content_light_level_from_caps;

    /// Parse the value of content-light-level caps field and update `minfo`
    /// with the parsed values.
    extern fn gst_video_content_light_level_from_string(p_linfo: *VideoContentLightLevel, p_level: [*:0]const u8) c_int;
    pub const fromString = gst_video_content_light_level_from_string;

    /// Initialize `linfo`
    extern fn gst_video_content_light_level_init(p_linfo: *VideoContentLightLevel) void;
    pub const init = gst_video_content_light_level_init;

    /// Checks equality between `linfo` and `other`.
    extern fn gst_video_content_light_level_is_equal(p_linfo: *const VideoContentLightLevel, p_other: *const gstvideo.VideoContentLightLevel) c_int;
    pub const isEqual = gst_video_content_light_level_is_equal;

    /// Convert `linfo` to its string representation.
    extern fn gst_video_content_light_level_to_string(p_linfo: *const VideoContentLightLevel) [*:0]u8;
    pub const toString = gst_video_content_light_level_to_string;

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

pub const VideoConverter = opaque {
    /// Create a new converter object to convert between `in_info` and `out_info`
    /// with `config`.
    ///
    /// Returns (nullable): a `gstvideo.VideoConverter` or `NULL` if conversion is not possible.
    extern fn gst_video_converter_new(p_in_info: *const gstvideo.VideoInfo, p_out_info: *const gstvideo.VideoInfo, p_config: *gst.Structure) *gstvideo.VideoConverter;
    pub const new = gst_video_converter_new;

    /// Create a new converter object to convert between `in_info` and `out_info`
    /// with `config`.
    ///
    /// The optional `pool` can be used to spawn threads, this is useful when
    /// creating new converters rapidly, for example when updating cropping.
    ///
    /// Returns (nullable): a `gstvideo.VideoConverter` or `NULL` if conversion is not possible.
    extern fn gst_video_converter_new_with_pool(p_in_info: *const gstvideo.VideoInfo, p_out_info: *const gstvideo.VideoInfo, p_config: *gst.Structure, p_pool: ?*gst.TaskPool) *gstvideo.VideoConverter;
    pub const newWithPool = gst_video_converter_new_with_pool;

    /// Convert the pixels of `src` into `dest` using `convert`.
    ///
    /// If `GST_VIDEO_CONVERTER_OPT_ASYNC_TASKS` is `TRUE` then this function will
    /// return immediately and needs to be followed by a call to
    /// `gstvideo.VideoConverter.frameFinish`.
    extern fn gst_video_converter_frame(p_convert: *VideoConverter, p_src: *const gstvideo.VideoFrame, p_dest: *gstvideo.VideoFrame) void;
    pub const frame = gst_video_converter_frame;

    /// Wait for a previous async conversion performed using
    /// `gstvideo.VideoConverter.frame` to complete.
    extern fn gst_video_converter_frame_finish(p_convert: *VideoConverter) void;
    pub const frameFinish = gst_video_converter_frame_finish;

    /// Free `convert`
    extern fn gst_video_converter_free(p_convert: *VideoConverter) void;
    pub const free = gst_video_converter_free;

    /// Get the current configuration of `convert`.
    extern fn gst_video_converter_get_config(p_convert: *VideoConverter) *const gst.Structure;
    pub const getConfig = gst_video_converter_get_config;

    /// Retrieve the input format of `convert`.
    extern fn gst_video_converter_get_in_info(p_convert: *VideoConverter) *const gstvideo.VideoInfo;
    pub const getInInfo = gst_video_converter_get_in_info;

    /// Retrieve the output format of `convert`.
    extern fn gst_video_converter_get_out_info(p_convert: *VideoConverter) *const gstvideo.VideoInfo;
    pub const getOutInfo = gst_video_converter_get_out_info;

    /// Set `config` as extra configuration for `convert`.
    ///
    /// 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 `gstvideo.VideoConverter.getConfig`.
    ///
    /// Look at the `GST_VIDEO_CONVERTER_OPT_*` fields to check valid configuration
    /// option and values.
    extern fn gst_video_converter_set_config(p_convert: *VideoConverter, p_config: *gst.Structure) c_int;
    pub const setConfig = gst_video_converter_set_config;

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

/// Extra buffer metadata describing image cropping.
pub const VideoCropMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// the horizontal offset
    f_x: c_uint,
    /// the vertical offset
    f_y: c_uint,
    /// the cropped width
    f_width: c_uint,
    /// the cropped height
    f_height: c_uint,

    extern fn gst_video_crop_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_crop_meta_get_info;

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

/// Subclasses can override any of the available virtual methods or not, as
/// needed. At minimum `handle_frame` needs to be overridden, and `set_format`
/// and likely as well.  If non-packetized input is supported or expected,
/// `parse` needs to be overridden as well.
pub const VideoDecoderClass = extern struct {
    pub const Instance = gstvideo.VideoDecoder;

    f_element_class: gst.ElementClass,
    /// Optional.
    ///                  Called when the element changes to GST_STATE_READY.
    ///                  Allows opening external resources.
    f_open: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) c_int,
    /// Optional.
    ///                  Called when the element changes to GST_STATE_NULL.
    ///                  Allows closing external resources.
    f_close: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) c_int,
    /// Optional.
    ///                  Called when the element starts processing.
    ///                  Allows opening external resources.
    f_start: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) c_int,
    /// Optional.
    ///                  Called when the element stops processing.
    ///                  Allows closing external resources.
    f_stop: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) c_int,
    /// Required for non-packetized input.
    ///                  Allows chopping incoming data into manageable units (frames)
    ///                  for subsequent decoding.
    f_parse: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_frame: *gstvideo.VideoCodecFrame, p_adapter: *gstbase.Adapter, p_at_eos: c_int) callconv(.c) gst.FlowReturn,
    /// Notifies subclass of incoming data format (caps).
    f_set_format: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_state: *gstvideo.VideoCodecState) callconv(.c) c_int,
    /// Optional.
    ///                  Allows subclass (decoder) to perform post-seek semantics reset.
    ///                  Deprecated.
    f_reset: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_hard: c_int) callconv(.c) c_int,
    /// Optional.
    ///                  Called to request subclass to dispatch any pending remaining
    ///                  data at EOS. Sub-classes can refuse to decode new data after.
    f_finish: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) gst.FlowReturn,
    /// Provides input data frame to subclass. In subframe mode, the subclass needs
    ///                  to take ownership of `GstVideoCodecFrame`.input_buffer as it will be modified
    ///                  by the base class on the next subframe buffer receiving.
    f_handle_frame: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_frame: *gstvideo.VideoCodecFrame) callconv(.c) gst.FlowReturn,
    /// Optional.
    ///                  Event handler on the sink pad. This function should return
    ///                  TRUE if the event was handled and should be discarded
    ///                  (i.e. not unref'ed).
    ///                  Subclasses should chain up to the parent implementation to
    ///                  invoke the default handler.
    f_sink_event: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_event: *gst.Event) callconv(.c) c_int,
    /// Optional.
    ///                  Event handler on the source pad. This function should return
    ///                  TRUE if the event was handled and should be discarded
    ///                  (i.e. not unref'ed).
    ///                  Subclasses should chain up to the parent implementation to
    ///                  invoke the default handler.
    f_src_event: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_event: *gst.Event) callconv(.c) c_int,
    /// Optional.
    ///                  Negotiate with downstream and configure buffer pools, etc.
    ///                  Subclasses should chain up to the parent implementation to
    ///                  invoke the default handler.
    f_negotiate: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) c_int,
    /// Optional.
    ///                     Setup the allocation parameters for allocating output
    ///                     buffers. The passed in query contains the result of the
    ///                     downstream allocation query.
    ///                     Subclasses should chain up to the parent implementation to
    ///                     invoke the default handler.
    f_decide_allocation: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional.
    ///                      Propose buffer allocation parameters for upstream elements.
    ///                      Subclasses should chain up to the parent implementation to
    ///                      invoke the default handler.
    f_propose_allocation: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional.
    ///                      Flush all remaining data from the decoder without
    ///                      pushing it downstream. Since: 1.2
    f_flush: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) c_int,
    /// Optional.
    ///                  Query handler on the sink pad. This function should
    ///                  return TRUE if the query could be performed. Subclasses
    ///                  should chain up to the parent implementation to invoke the
    ///                  default handler. Since: 1.4
    f_sink_query: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional.
    ///                  Query handler on the source pad. This function should
    ///                  return TRUE if the query could be performed. Subclasses
    ///                  should chain up to the parent implementation to invoke the
    ///                  default handler. Since: 1.4
    f_src_query: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional.
    ///                  Allows for a custom sink getcaps implementation.
    ///                  If not implemented, default returns
    ///                  gst_video_decoder_proxy_getcaps
    ///                  applied to sink template caps.
    f_getcaps: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_filter: *gst.Caps) callconv(.c) *gst.Caps,
    /// Optional.
    ///                  Called to request subclass to decode any data it can at this
    ///                  point, but that more data may arrive after. (e.g. at segment end).
    ///                  Sub-classes should be prepared to handle new data afterward,
    ///                  or seamless segment processing will break. Since: 1.6
    f_drain: ?*const fn (p_decoder: *gstvideo.VideoDecoder) callconv(.c) gst.FlowReturn,
    /// Optional. Transform the metadata on the input buffer to the
    ///                  output buffer. By default this method is copies all meta without
    ///                  tags and meta with only the "video" tag. subclasses can
    ///                  implement this method and return `TRUE` if the metadata is to be
    ///                  copied. Since: 1.6
    f_transform_meta: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_frame: *gstvideo.VideoCodecFrame, p_meta: *gst.Meta) callconv(.c) c_int,
    f_handle_missing_data: ?*const fn (p_decoder: *gstvideo.VideoDecoder, p_timestamp: gst.ClockTime, p_duration: gst.ClockTime) callconv(.c) c_int,
    f_padding: [13]*anyopaque,

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

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

pub const VideoDecoderPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// `gstvideo.VideoDirectionInterface` interface.
pub const VideoDirectionInterface = extern struct {
    pub const Instance = gstvideo.VideoDirection;

    /// parent interface type.
    f_iface: gobject.TypeInterface,

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

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

/// GstVideoDither provides implementations of several dithering algorithms
/// that can be applied to lines of video pixels to quantize and dither them.
pub const VideoDither = opaque {
    /// Make a new dither object for dithering lines of `format` using the
    /// algorithm described by `method`.
    ///
    /// Each component will be quantized to a multiple of `quantizer`. Better
    /// performance is achieved when `quantizer` is a power of 2.
    ///
    /// `width` is the width of the lines that this ditherer will handle.
    extern fn gst_video_dither_new(p_method: gstvideo.VideoDitherMethod, p_flags: gstvideo.VideoDitherFlags, p_format: gstvideo.VideoFormat, p_quantizer: *c_uint, p_width: c_uint) *gstvideo.VideoDither;
    pub const new = gst_video_dither_new;

    /// Free `dither`
    extern fn gst_video_dither_free(p_dither: *VideoDither) void;
    pub const free = gst_video_dither_free;

    /// Dither `width` pixels starting from offset `x` in `line` using `dither`.
    ///
    /// `y` is the line number of `line` in the output image.
    extern fn gst_video_dither_line(p_dither: *VideoDither, p_line: ?*anyopaque, p_x: c_uint, p_y: c_uint, p_width: c_uint) void;
    pub const line = gst_video_dither_line;

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

/// Subclasses can override any of the available virtual methods or not, as
/// needed. At minimum `handle_frame` needs to be overridden, and `set_format`
/// and `get_caps` are likely needed as well.
pub const VideoEncoderClass = extern struct {
    pub const Instance = gstvideo.VideoEncoder;

    f_element_class: gst.ElementClass,
    /// Optional.
    ///                  Called when the element changes to GST_STATE_READY.
    ///                  Allows opening external resources.
    f_open: ?*const fn (p_encoder: *gstvideo.VideoEncoder) callconv(.c) c_int,
    /// Optional.
    ///                  Called when the element changes to GST_STATE_NULL.
    ///                  Allows closing external resources.
    f_close: ?*const fn (p_encoder: *gstvideo.VideoEncoder) callconv(.c) c_int,
    /// Optional.
    ///                  Called when the element starts processing.
    ///                  Allows opening external resources.
    f_start: ?*const fn (p_encoder: *gstvideo.VideoEncoder) callconv(.c) c_int,
    /// Optional.
    ///                  Called when the element stops processing.
    ///                  Allows closing external resources.
    f_stop: ?*const fn (p_encoder: *gstvideo.VideoEncoder) callconv(.c) c_int,
    /// Optional.
    ///                  Notifies subclass of incoming data format.
    ///                  GstVideoCodecState fields have already been
    ///                  set according to provided caps.
    f_set_format: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_state: *gstvideo.VideoCodecState) callconv(.c) c_int,
    /// Provides input frame to subclass.
    f_handle_frame: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_frame: *gstvideo.VideoCodecFrame) callconv(.c) gst.FlowReturn,
    /// Optional.
    ///                  Allows subclass (encoder) to perform post-seek semantics reset.
    ///                  Deprecated.
    f_reset: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_hard: c_int) callconv(.c) c_int,
    /// Optional.
    ///                  Called to request subclass to dispatch any pending remaining
    ///                  data (e.g. at EOS).
    f_finish: ?*const fn (p_encoder: *gstvideo.VideoEncoder) callconv(.c) gst.FlowReturn,
    /// Optional.
    ///                  Allows subclass to push frame downstream in whatever
    ///                  shape or form it deems appropriate.  If not provided,
    ///                  provided encoded frame data is simply pushed downstream.
    f_pre_push: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_frame: *gstvideo.VideoCodecFrame) callconv(.c) gst.FlowReturn,
    /// Optional.
    ///                  Allows for a custom sink getcaps implementation (e.g.
    ///                  for multichannel input specification).  If not implemented,
    ///                  default returns gst_video_encoder_proxy_getcaps
    ///                  applied to sink template caps.
    f_getcaps: ?*const fn (p_enc: *gstvideo.VideoEncoder, p_filter: *gst.Caps) callconv(.c) *gst.Caps,
    /// Optional.
    ///                  Event handler on the sink pad. This function should return
    ///                  TRUE if the event was handled and should be discarded
    ///                  (i.e. not unref'ed).
    ///                  Subclasses should chain up to the parent implementation to
    ///                  invoke the default handler.
    f_sink_event: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_event: *gst.Event) callconv(.c) c_int,
    /// Optional.
    ///                  Event handler on the source pad. This function should return
    ///                  TRUE if the event was handled and should be discarded
    ///                  (i.e. not unref'ed).
    ///                  Subclasses should chain up to the parent implementation to
    ///                  invoke the default handler.
    f_src_event: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_event: *gst.Event) callconv(.c) c_int,
    /// Optional.
    ///                  Negotiate with downstream and configure buffer pools, etc.
    ///                  Subclasses should chain up to the parent implementation to
    ///                  invoke the default handler.
    f_negotiate: ?*const fn (p_encoder: *gstvideo.VideoEncoder) callconv(.c) c_int,
    /// Optional.
    ///                     Setup the allocation parameters for allocating output
    ///                     buffers. The passed in query contains the result of the
    ///                     downstream allocation query.
    ///                     Subclasses should chain up to the parent implementation to
    ///                     invoke the default handler.
    f_decide_allocation: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional.
    ///                      Propose buffer allocation parameters for upstream elements.
    ///                      Subclasses should chain up to the parent implementation to
    ///                      invoke the default handler.
    f_propose_allocation: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional.
    ///                      Flush all remaining data from the encoder without
    ///                      pushing it downstream. Since: 1.2
    f_flush: ?*const fn (p_encoder: *gstvideo.VideoEncoder) callconv(.c) c_int,
    /// Optional.
    ///                  Query handler on the sink pad. This function should
    ///                  return TRUE if the query could be performed. Subclasses
    ///                  should chain up to the parent implementation to invoke the
    ///                  default handler. Since: 1.4
    f_sink_query: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional.
    ///                  Query handler on the source pad. This function should
    ///                  return TRUE if the query could be performed. Subclasses
    ///                  should chain up to the parent implementation to invoke the
    ///                  default handler. Since: 1.4
    f_src_query: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_query: *gst.Query) callconv(.c) c_int,
    /// Optional. Transform the metadata on the input buffer to the
    ///                  output buffer. By default this method is copies all meta without
    ///                  tags and meta with only the "video" tag. subclasses can
    ///                  implement this method and return `TRUE` if the metadata is to be
    ///                  copied. Since: 1.6
    f_transform_meta: ?*const fn (p_encoder: *gstvideo.VideoEncoder, p_frame: *gstvideo.VideoCodecFrame, p_meta: *gst.Meta) callconv(.c) c_int,
    f__gst_reserved: [16]*anyopaque,

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

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

pub const VideoEncoderPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// The video filter class structure.
pub const VideoFilterClass = extern struct {
    pub const Instance = gstvideo.VideoFilter;

    /// the parent class structure
    f_parent_class: gstbase.BaseTransformClass,
    /// function to be called with the negotiated caps and video infos
    f_set_info: ?*const fn (p_filter: *gstvideo.VideoFilter, p_incaps: *gst.Caps, p_in_info: *gstvideo.VideoInfo, p_outcaps: *gst.Caps, p_out_info: *gstvideo.VideoInfo) callconv(.c) c_int,
    /// transform a video frame
    f_transform_frame: ?*const fn (p_filter: *gstvideo.VideoFilter, p_inframe: *gstvideo.VideoFrame, p_outframe: *gstvideo.VideoFrame) callconv(.c) gst.FlowReturn,
    /// transform a video frame in place
    f_transform_frame_ip: ?*const fn (p_trans: *gstvideo.VideoFilter, p_frame: *gstvideo.VideoFrame) callconv(.c) gst.FlowReturn,
    f__gst_reserved: [4]*anyopaque,

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

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

/// Information for a video format.
pub const VideoFormatInfo = extern struct {
    /// `gstvideo.VideoFormat`
    f_format: gstvideo.VideoFormat,
    /// string representation of the format
    f_name: ?[*:0]const u8,
    /// use readable description of the format
    f_description: ?[*:0]const u8,
    /// `gstvideo.VideoFormatFlags`
    f_flags: gstvideo.VideoFormatFlags,
    /// The number of bits used to pack data items. This can be less than 8
    ///    when multiple pixels are stored in a byte. for values > 8 multiple bytes
    ///    should be read according to the endianness flag before applying the shift
    ///    and mask.
    f_bits: c_uint,
    /// the number of components in the video format.
    f_n_components: c_uint,
    /// the number of bits to shift away to get the component data
    f_shift: [4]c_uint,
    /// the depth in bits for each component
    f_depth: [4]c_uint,
    /// the pixel stride of each component. This is the amount of
    ///    bytes to the pixel immediately to the right. When bits < 8, the stride is
    ///    expressed in bits. For 24-bit RGB, this would be 3 bytes, for example,
    ///    while it would be 4 bytes for RGBx or ARGB.
    f_pixel_stride: [4]c_int,
    /// the number of planes for this format. The number of planes can be
    ///    less than the amount of components when multiple components are packed into
    ///    one plane.
    f_n_planes: c_uint,
    /// the plane number where a component can be found
    f_plane: [4]c_uint,
    /// the offset in the plane where the first pixel of the components
    ///    can be found.
    f_poffset: [4]c_uint,
    /// subsampling factor of the width for the component. Use
    ///     GST_VIDEO_SUB_SCALE to scale a width.
    f_w_sub: [4]c_uint,
    /// subsampling factor of the height for the component. Use
    ///     GST_VIDEO_SUB_SCALE to scale a height.
    f_h_sub: [4]c_uint,
    /// the format of the unpacked pixels. This format must have the
    ///     `GST_VIDEO_FORMAT_FLAG_UNPACK` flag set.
    f_unpack_format: gstvideo.VideoFormat,
    /// an unpack function for this format
    f_unpack_func: ?gstvideo.VideoFormatUnpack,
    /// the amount of lines that will be packed
    f_pack_lines: c_int,
    /// an pack function for this format
    f_pack_func: ?gstvideo.VideoFormatPack,
    /// The tiling mode
    f_tile_mode: gstvideo.VideoTileMode,
    /// The width of a tile, in bytes, represented as a shift. DEPRECATED,
    /// use tile_info[] array instead.
    f_tile_ws: c_uint,
    /// The height of a tile, in bytes, represented as a shift. DEPREACTED,
    /// use tile_info[] array instead.
    f_tile_hs: c_uint,
    /// Information about the tiles for each of the planes.
    f_tile_info: [4]gstvideo.VideoTileInfo,

    /// Fill `components` with the number of all the components packed in plane `p`
    /// for the format `info`. A value of -1 in `components` indicates that no more
    /// components are packed in the plane.
    extern fn gst_video_format_info_component(p_info: *const VideoFormatInfo, p_plane: c_uint, p_components: *c_int) void;
    pub const component = gst_video_format_info_component;

    /// Extrapolate `plane` stride from the first stride of an image. This helper is
    /// useful to support legacy API were only one stride is supported.
    extern fn gst_video_format_info_extrapolate_stride(p_finfo: *const VideoFormatInfo, p_plane: c_int, p_stride: c_int) c_int;
    pub const extrapolateStride = gst_video_format_info_extrapolate_stride;

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

/// A video frame obtained from `gstvideo.videoFrameMap`
pub const VideoFrame = extern struct {
    /// the `gstvideo.VideoInfo`
    f_info: gstvideo.VideoInfo,
    /// `gstvideo.VideoFrameFlags` for the frame
    f_flags: gstvideo.VideoFrameFlags,
    /// the mapped buffer
    f_buffer: ?*gst.Buffer,
    /// pointer to metadata if any
    f_meta: ?*anyopaque,
    /// id of the mapped frame. the id can for example be used to
    ///   identify the frame in case of multiview video.
    f_id: c_int,
    /// pointers to the plane data
    f_data: [4]*anyopaque,
    /// mappings of the planes
    f_map: [4]gst.MapInfo,
    f__gst_reserved: [4]*anyopaque,

    /// Use `info` and `buffer` to fill in the values of `frame`. `frame` is usually
    /// allocated on the stack, and you will pass the address to the `gstvideo.VideoFrame`
    /// structure allocated on the stack; `gstvideo.videoFrameMap` will then fill in
    /// the structures with the various video-specific information you need to access
    /// the pixels of the video buffer. You can then use accessor macros such as
    /// `GST_VIDEO_FRAME_COMP_DATA`, `GST_VIDEO_FRAME_PLANE_DATA`,
    /// `GST_VIDEO_FRAME_COMP_STRIDE`, `GST_VIDEO_FRAME_PLANE_STRIDE` etc.
    /// to get to the pixels.
    ///
    /// ```
    ///   GstVideoFrame vframe;
    ///   ...
    ///   // set RGB pixels to black one at a time
    ///   if (gst_video_frame_map (&vframe, video_info, video_buffer, GST_MAP_WRITE)) {
    ///     guint8 *pixels = GST_VIDEO_FRAME_PLANE_DATA (vframe, 0);
    ///     guint stride = GST_VIDEO_FRAME_PLANE_STRIDE (vframe, 0);
    ///     guint pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (vframe, 0);
    ///
    ///     for (h = 0; h < height; ++h) {
    ///       for (w = 0; w < width; ++w) {
    ///         guint8 *pixel = pixels + h * stride + w * pixel_stride;
    ///
    ///         memset (pixel, 0, pixel_stride);
    ///       }
    ///     }
    ///
    ///     gst_video_frame_unmap (&vframe);
    ///   }
    ///   ...
    /// ```
    ///
    /// All video planes of `buffer` will be mapped and the pointers will be set in
    /// `frame`->data.
    ///
    /// The purpose of this function is to make it easy for you to get to the video
    /// pixels in a generic way, without you having to worry too much about details
    /// such as whether the video data is allocated in one contiguous memory chunk
    /// or multiple memory chunks (e.g. one for each plane); or if custom strides
    /// and custom plane offsets are used or not (as signalled by GstVideoMeta on
    /// each buffer). This function will just fill the `gstvideo.VideoFrame` structure
    /// with the right values and if you use the accessor macros everything will
    /// just work and you can access the data easily. It also maps the underlying
    /// memory chunks for you.
    extern fn gst_video_frame_map(p_frame: *gstvideo.VideoFrame, p_info: *const gstvideo.VideoInfo, p_buffer: *gst.Buffer, p_flags: gst.MapFlags) c_int;
    pub const map = gst_video_frame_map;

    /// Use `info` and `buffer` to fill in the values of `frame` with the video frame
    /// information of frame `id`.
    ///
    /// When `id` is -1, the default frame is mapped. When `id` != -1, this function
    /// will return `FALSE` when there is no GstVideoMeta with that id.
    ///
    /// All video planes of `buffer` will be mapped and the pointers will be set in
    /// `frame`->data.
    extern fn gst_video_frame_map_id(p_frame: *gstvideo.VideoFrame, p_info: *const gstvideo.VideoInfo, p_buffer: *gst.Buffer, p_id: c_int, p_flags: gst.MapFlags) c_int;
    pub const mapId = gst_video_frame_map_id;

    /// Copy the contents from `src` to `dest`.
    ///
    /// Note: Since: 1.18, `dest` dimensions are allowed to be
    /// smaller than `src` dimensions.
    extern fn gst_video_frame_copy(p_dest: *VideoFrame, p_src: *const gstvideo.VideoFrame) c_int;
    pub const copy = gst_video_frame_copy;

    /// Copy the plane with index `plane` from `src` to `dest`.
    ///
    /// Note: Since: 1.18, `dest` dimensions are allowed to be
    /// smaller than `src` dimensions.
    extern fn gst_video_frame_copy_plane(p_dest: *VideoFrame, p_src: *const gstvideo.VideoFrame, p_plane: c_uint) c_int;
    pub const copyPlane = gst_video_frame_copy_plane;

    /// Unmap the memory previously mapped with gst_video_frame_map.
    extern fn gst_video_frame_unmap(p_frame: *VideoFrame) void;
    pub const unmap = gst_video_frame_unmap;

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

/// Extra buffer metadata for uploading a buffer to an OpenGL texture
/// ID. The caller of `gstvideo.VideoGLTextureUploadMeta.upload` must
/// have OpenGL set up and call this from a thread where it is valid
/// to upload something to an OpenGL texture.
pub const VideoGLTextureUploadMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// Orientation of the textures
    f_texture_orientation: gstvideo.VideoGLTextureOrientation,
    /// Number of textures that are generated
    f_n_textures: c_uint,
    /// Type of each texture
    f_texture_type: [4]gstvideo.VideoGLTextureType,
    f_buffer: ?*gst.Buffer,
    f_upload: ?gstvideo.VideoGLTextureUpload,
    f_user_data: ?*anyopaque,
    f_user_data_copy: ?gobject.BoxedCopyFunc,
    f_user_data_free: ?gobject.BoxedFreeFunc,

    extern fn gst_video_gl_texture_upload_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_gl_texture_upload_meta_get_info;

    /// Uploads the buffer which owns the meta to a specific texture ID.
    extern fn gst_video_gl_texture_upload_meta_upload(p_meta: *VideoGLTextureUploadMeta, p_texture_id: *c_uint) c_int;
    pub const upload = gst_video_gl_texture_upload_meta_upload;

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

/// Information describing image properties. This information can be filled
/// in from GstCaps with `gstvideo.videoInfoFromCaps`. The information is also used
/// to store the specific video info when mapping a video frame with
/// `gstvideo.videoFrameMap`.
///
/// Use the provided macros to access the info in this structure.
pub const VideoInfo = extern struct {
    /// the format info of the video
    f_finfo: ?*const gstvideo.VideoFormatInfo,
    /// the interlace mode
    f_interlace_mode: gstvideo.VideoInterlaceMode,
    /// additional video flags
    f_flags: gstvideo.VideoFlags,
    /// the width of the video
    f_width: c_int,
    /// the height of the video
    f_height: c_int,
    /// the default size of one frame
    f_size: usize,
    /// the number of views for multiview video
    f_views: c_int,
    /// a `gstvideo.VideoChromaSite`.
    f_chroma_site: gstvideo.VideoChromaSite,
    /// the colorimetry info
    f_colorimetry: gstvideo.VideoColorimetry,
    /// the pixel-aspect-ratio numerator
    f_par_n: c_int,
    /// the pixel-aspect-ratio denominator
    f_par_d: c_int,
    /// the framerate numerator
    f_fps_n: c_int,
    /// the framerate denominator
    f_fps_d: c_int,
    /// offsets of the planes
    f_offset: [4]usize,
    /// strides of the planes
    f_stride: [4]c_int,
    anon0: extern union {
        anon0: extern struct {
            f_multiview_mode: gstvideo.VideoMultiviewMode,
            f_multiview_flags: gstvideo.VideoMultiviewFlags,
            f_field_order: gstvideo.VideoFieldOrder,
        },
        f__gst_reserved: [4]*anyopaque,
    },

    /// Parse `caps` and update `info`.
    extern fn gst_video_info_from_caps(p_info: *gstvideo.VideoInfo, p_caps: *const gst.Caps) c_int;
    pub const fromCaps = gst_video_info_from_caps;

    /// Initialize `info` with default values.
    extern fn gst_video_info_init(p_info: *gstvideo.VideoInfo) void;
    pub const init = gst_video_info_init;

    /// Allocate a new `gstvideo.VideoInfo` that is also initialized with
    /// `gstvideo.videoInfoInit`.
    extern fn gst_video_info_new() *gstvideo.VideoInfo;
    pub const new = gst_video_info_new;

    /// Parse `caps` to generate a `gstvideo.VideoInfo`.
    extern fn gst_video_info_new_from_caps(p_caps: *const gst.Caps) ?*gstvideo.VideoInfo;
    pub const newFromCaps = gst_video_info_new_from_caps;

    /// Adjust the offset and stride fields in `info` so that the padding and
    /// stride alignment in `align` is respected.
    ///
    /// Extra padding will be added to the right side when stride alignment padding
    /// is required and `align` will be updated with the new padding values.
    extern fn gst_video_info_align(p_info: *VideoInfo, p_align: *gstvideo.VideoAlignment) c_int;
    pub const @"align" = gst_video_info_align;

    /// Extra padding will be added to the right side when stride alignment padding
    /// is required and `align` will be updated with the new padding values.
    ///
    /// This variant of `gstvideo.VideoInfo.@"align"` provides the updated size, in bytes,
    /// of each video plane after the alignment, including all horizontal and vertical
    /// paddings.
    ///
    /// In case of GST_VIDEO_INTERLACE_MODE_ALTERNATE info, the returned sizes are the
    /// ones used to hold a single field, not the full frame.
    extern fn gst_video_info_align_full(p_info: *VideoInfo, p_align: *gstvideo.VideoAlignment, p_plane_size: ?*usize) c_int;
    pub const alignFull = gst_video_info_align_full;

    /// Converts among various `gst.Format` types.  This function handles
    /// GST_FORMAT_BYTES, GST_FORMAT_TIME, and GST_FORMAT_DEFAULT.  For
    /// raw video, GST_FORMAT_DEFAULT corresponds to video frames.  This
    /// function can be used to handle pad queries of the type GST_QUERY_CONVERT.
    extern fn gst_video_info_convert(p_info: *const VideoInfo, p_src_format: gst.Format, p_src_value: i64, p_dest_format: gst.Format, p_dest_value: *i64) c_int;
    pub const convert = gst_video_info_convert;

    /// Copy a GstVideoInfo structure.
    extern fn gst_video_info_copy(p_info: *const VideoInfo) *gstvideo.VideoInfo;
    pub const copy = gst_video_info_copy;

    /// Free a GstVideoInfo structure previously allocated with `gstvideo.VideoInfo.new`
    /// or `gstvideo.VideoInfo.copy`.
    extern fn gst_video_info_free(p_info: *VideoInfo) void;
    pub const free = gst_video_info_free;

    /// Compares two `gstvideo.VideoInfo` and returns whether they are equal or not
    extern fn gst_video_info_is_equal(p_info: *const VideoInfo, p_other: *const gstvideo.VideoInfo) c_int;
    pub const isEqual = gst_video_info_is_equal;

    /// Set the default info for a video frame of `format` and `width` and `height`.
    ///
    /// Note: This initializes `info` first, no values are preserved. This function
    /// does not set the offsets correctly for interlaced vertically
    /// subsampled formats.
    extern fn gst_video_info_set_format(p_info: *VideoInfo, p_format: gstvideo.VideoFormat, p_width: c_uint, p_height: c_uint) c_int;
    pub const setFormat = gst_video_info_set_format;

    /// Same as `gstvideo.VideoInfo.setFormat` but also allowing to set the interlaced
    /// mode.
    extern fn gst_video_info_set_interlaced_format(p_info: *VideoInfo, p_format: gstvideo.VideoFormat, p_mode: gstvideo.VideoInterlaceMode, p_width: c_uint, p_height: c_uint) c_int;
    pub const setInterlacedFormat = gst_video_info_set_interlaced_format;

    /// Convert the values of `info` into a `gst.Caps`.
    extern fn gst_video_info_to_caps(p_info: *const VideoInfo) *gst.Caps;
    pub const toCaps = gst_video_info_to_caps;

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

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

/// Information describing a DMABuf image properties. It wraps `gstvideo.VideoInfo` and
/// adds DRM information such as drm-fourcc and drm-modifier, required for
/// negotiation and mapping.
pub const VideoInfoDmaDrm = extern struct {
    /// the associated `gstvideo.VideoInfo`
    f_vinfo: gstvideo.VideoInfo,
    /// the fourcc defined by drm
    f_drm_fourcc: u32,
    /// the drm modifier
    f_drm_modifier: u64,
    f__gst_reserved: [20]u32,

    /// Parse `caps` and update `info`. Please note that the `caps` should be
    /// a dma drm caps. The `gstvideo.videoIsDmaDrmCaps` can be used to verify
    /// it before calling this function.
    extern fn gst_video_info_dma_drm_from_caps(p_drm_info: *gstvideo.VideoInfoDmaDrm, p_caps: *const gst.Caps) c_int;
    pub const fromCaps = gst_video_info_dma_drm_from_caps;

    /// Fills `drm_info` if `info`'s format has a valid drm format and `modifier` is also
    /// valid
    extern fn gst_video_info_dma_drm_from_video_info(p_drm_info: *gstvideo.VideoInfoDmaDrm, p_info: *const gstvideo.VideoInfo, p_modifier: u64) c_int;
    pub const fromVideoInfo = gst_video_info_dma_drm_from_video_info;

    /// Initialize `drm_info` with default values.
    extern fn gst_video_info_dma_drm_init(p_drm_info: *gstvideo.VideoInfoDmaDrm) void;
    pub const init = gst_video_info_dma_drm_init;

    /// Allocate a new `gstvideo.VideoInfoDmaDrm` that is also initialized with
    /// `gstvideo.videoInfoDmaDrmInit`.
    extern fn gst_video_info_dma_drm_new() *gstvideo.VideoInfoDmaDrm;
    pub const new = gst_video_info_dma_drm_new;

    /// Parse `caps` to generate a `gstvideo.VideoInfoDmaDrm`. Please note that the
    /// `caps` should be a dma drm caps. The `gstvideo.videoIsDmaDrmCaps` can
    /// be used to verify it before calling this function.
    extern fn gst_video_info_dma_drm_new_from_caps(p_caps: *const gst.Caps) ?*gstvideo.VideoInfoDmaDrm;
    pub const newFromCaps = gst_video_info_dma_drm_new_from_caps;

    /// Free a `gstvideo.VideoInfoDmaDrm` structure previously allocated with
    /// `gstvideo.VideoInfoDmaDrm.new`
    extern fn gst_video_info_dma_drm_free(p_drm_info: *VideoInfoDmaDrm) void;
    pub const free = gst_video_info_dma_drm_free;

    /// Convert the values of `drm_info` into a `gst.Caps`. Please note that the
    /// `caps` returned will be a dma drm caps which sets format field to DMA_DRM,
    /// and contains a new drm-format field. The value of drm-format field is
    /// composed of a drm fourcc and a modifier, such as NV12:0x0100000000000002.
    extern fn gst_video_info_dma_drm_to_caps(p_drm_info: *const VideoInfoDmaDrm) ?*gst.Caps;
    pub const toCaps = gst_video_info_dma_drm_to_caps;

    /// Convert the `gstvideo.VideoInfoDmaDrm` into a traditional `gstvideo.VideoInfo` with
    /// recognized video format. For DMA kind memory, the non linear DMA format
    /// should be recognized as `GST_VIDEO_FORMAT_DMA_DRM`. This helper function
    /// sets `info`'s video format into the default value according to `drm_info`'s
    /// drm_fourcc field.
    extern fn gst_video_info_dma_drm_to_video_info(p_drm_info: *const VideoInfoDmaDrm, p_info: *gstvideo.VideoInfo) c_int;
    pub const toVideoInfo = gst_video_info_dma_drm_to_video_info;

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

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

/// Mastering display color volume information defined by SMPTE ST 2086
/// (a.k.a static HDR metadata).
pub const VideoMasteringDisplayInfo = extern struct {
    /// the xy coordinates of primaries in the CIE 1931 color space.
    ///   the index 0 contains red, 1 is for green and 2 is for blue.
    ///   each value is normalized to 50000 (meaning that in unit of 0.00002)
    f_display_primaries: [3]gstvideo.VideoMasteringDisplayInfoCoordinates,
    /// the xy coordinates of white point in the CIE 1931 color space.
    ///   each value is normalized to 50000 (meaning that in unit of 0.00002)
    f_white_point: gstvideo.VideoMasteringDisplayInfoCoordinates,
    /// the maximum value of display luminance
    ///   in unit of 0.0001 candelas per square metre (cd/m^2 and nit)
    f_max_display_mastering_luminance: u32,
    /// the minimum value of display luminance
    ///   in unit of 0.0001 candelas per square metre (cd/m^2 and nit)
    f_min_display_mastering_luminance: u32,
    f__gst_reserved: [4]*anyopaque,

    /// Extract `gstvideo.VideoMasteringDisplayInfo` from `mastering`
    extern fn gst_video_mastering_display_info_from_string(p_minfo: *gstvideo.VideoMasteringDisplayInfo, p_mastering: [*:0]const u8) c_int;
    pub const fromString = gst_video_mastering_display_info_from_string;

    /// Set string representation of `minfo` to `caps`
    extern fn gst_video_mastering_display_info_add_to_caps(p_minfo: *const VideoMasteringDisplayInfo, p_caps: *gst.Caps) c_int;
    pub const addToCaps = gst_video_mastering_display_info_add_to_caps;

    /// Parse `caps` and update `minfo`
    extern fn gst_video_mastering_display_info_from_caps(p_minfo: *VideoMasteringDisplayInfo, p_caps: *const gst.Caps) c_int;
    pub const fromCaps = gst_video_mastering_display_info_from_caps;

    /// Initialize `minfo`
    extern fn gst_video_mastering_display_info_init(p_minfo: *VideoMasteringDisplayInfo) void;
    pub const init = gst_video_mastering_display_info_init;

    /// Checks equality between `minfo` and `other`.
    extern fn gst_video_mastering_display_info_is_equal(p_minfo: *const VideoMasteringDisplayInfo, p_other: *const gstvideo.VideoMasteringDisplayInfo) c_int;
    pub const isEqual = gst_video_mastering_display_info_is_equal;

    /// Convert `minfo` to its string representation
    extern fn gst_video_mastering_display_info_to_string(p_minfo: *const VideoMasteringDisplayInfo) [*:0]u8;
    pub const toString = gst_video_mastering_display_info_to_string;

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

/// Used to represent display_primaries and white_point of
/// `gstvideo.VideoMasteringDisplayInfo` struct. See `gstvideo.VideoMasteringDisplayInfo`
pub const VideoMasteringDisplayInfoCoordinates = extern struct {
    /// the x coordinate of CIE 1931 color space in unit of 0.00002.
    f_x: u16,
    /// the y coordinate of CIE 1931 color space in unit of 0.00002.
    f_y: u16,

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

/// Extra buffer metadata describing image properties
///
/// This meta can also be used by downstream elements to specifiy their
/// buffer layout requirements for upstream. Upstream should try to
/// fit those requirements, if possible, in order to prevent buffer copies.
///
/// This is done by passing a custom `gst.Structure` to
/// `gst.Query.addAllocationMeta` when handling the ALLOCATION query.
/// This structure should be named 'video-meta' and can have the following
/// fields:
/// - padding-top (uint): extra pixels on the top
/// - padding-bottom (uint): extra pixels on the bottom
/// - padding-left (uint): extra pixels on the left side
/// - padding-right (uint): extra pixels on the right side
/// - stride-align0 (uint): stride align requirements for plane 0
/// - stride-align1 (uint): stride align requirements for plane 1
/// - stride-align2 (uint): stride align requirements for plane 2
/// - stride-align3 (uint): stride align requirements for plane 3
/// The padding and stride-align fields have the same semantic as `gstvideo.VideoMeta.alignment`
/// and so represent the paddings and stride-align requested on produced video buffers.
///
/// Since 1.24 it can be serialized using `gst.Meta.serialize` and
/// `gst.metaDeserialize`.
pub const VideoMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// the buffer this metadata belongs to
    f_buffer: ?*gst.Buffer,
    /// additional video flags
    f_flags: gstvideo.VideoFrameFlags,
    /// the video format
    f_format: gstvideo.VideoFormat,
    /// identifier of the frame
    f_id: c_int,
    /// the video width
    f_width: c_uint,
    /// the video height
    f_height: c_uint,
    /// the number of planes in the image
    f_n_planes: c_uint,
    /// array of offsets for the planes. This field might not always be
    ///          valid, it is used by the default implementation of `map`.
    f_offset: [4]usize,
    /// array of strides for the planes. This field might not always be
    ///          valid, it is used by the default implementation of `map`.
    f_stride: [4]c_int,
    /// map the memory of a plane
    f_map: ?*const fn (p_meta: *gstvideo.VideoMeta, p_plane: c_uint, p_info: *gst.MapInfo, p_data: *anyopaque, p_stride: *c_int, p_flags: gst.MapFlags) callconv(.c) c_int,
    /// unmap the memory of a plane
    f_unmap: ?*const fn (p_meta: *gstvideo.VideoMeta, p_plane: c_uint, p_info: *gst.MapInfo) callconv(.c) c_int,
    /// the paddings and alignment constraints of the video buffer.
    /// It is up to the caller of ``gstvideo.bufferAddVideoMetaFull`` to set it
    /// using `gstvideo.VideoMeta.setAlignment`, if they did not it defaults
    /// to no padding and no alignment. Since: 1.18
    f_alignment: gstvideo.VideoAlignment,

    extern fn gst_video_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_meta_get_info;

    /// Compute the padded height of each plane from `meta` (padded size
    /// divided by stride).
    ///
    /// It is not valid to call this function with a meta associated to a
    /// TILED video format.
    extern fn gst_video_meta_get_plane_height(p_meta: *VideoMeta, p_plane_height: *[4]c_uint) c_int;
    pub const getPlaneHeight = gst_video_meta_get_plane_height;

    /// Compute the size, in bytes, of each video plane described in `meta` including
    /// any padding and alignment constraint defined in `meta`->alignment.
    extern fn gst_video_meta_get_plane_size(p_meta: *VideoMeta, p_plane_size: *[4]usize) c_int;
    pub const getPlaneSize = gst_video_meta_get_plane_size;

    /// Map the video plane with index `plane` in `meta` and return a pointer to the
    /// first byte of the plane and the stride of the plane.
    extern fn gst_video_meta_map(p_meta: *VideoMeta, p_plane: c_uint, p_info: *gst.MapInfo, p_data: ?*anyopaque, p_stride: *c_int, p_flags: gst.MapFlags) c_int;
    pub const map = gst_video_meta_map;

    /// Set the alignment of `meta` to `alignment`. This function checks that
    /// the paddings defined in `alignment` are compatible with the strides
    /// defined in `meta` and will fail to update if they are not.
    extern fn gst_video_meta_set_alignment(p_meta: *VideoMeta, p_alignment: gstvideo.VideoAlignment) c_int;
    pub const setAlignment = gst_video_meta_set_alignment;

    /// Unmap a previously mapped plane with `gstvideo.VideoMeta.map`.
    extern fn gst_video_meta_unmap(p_meta: *VideoMeta, p_plane: c_uint, p_info: *gst.MapInfo) c_int;
    pub const unmap = gst_video_meta_unmap;

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

/// Extra data passed to a video transform `gst.MetaTransformFunction` such as:
/// "gst-video-scale".
pub const VideoMetaTransform = extern struct {
    /// the input `gstvideo.VideoInfo`
    f_in_info: ?*gstvideo.VideoInfo,
    /// the output `gstvideo.VideoInfo`
    f_out_info: ?*gstvideo.VideoInfo,

    /// Get the `glib.Quark` for the "gst-video-scale" metadata transform operation.
    extern fn gst_video_meta_transform_scale_get_quark() glib.Quark;
    pub const scaleGetQuark = gst_video_meta_transform_scale_get_quark;

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

/// `gstvideo.VideoOrientationInterface` interface.
pub const VideoOrientationInterface = extern struct {
    pub const Instance = gstvideo.VideoOrientation;

    /// parent interface type.
    f_iface: gobject.TypeInterface,
    /// virtual method to get horizontal flipping state
    f_get_hflip: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_flip: *c_int) callconv(.c) c_int,
    /// virtual method to get vertical flipping state
    f_get_vflip: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_flip: *c_int) callconv(.c) c_int,
    /// virtual method to get horizontal centering state
    f_get_hcenter: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_center: *c_int) callconv(.c) c_int,
    /// virtual method to get vertical centering state
    f_get_vcenter: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_center: *c_int) callconv(.c) c_int,
    /// virtual method to set horizontal flipping state
    f_set_hflip: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_flip: c_int) callconv(.c) c_int,
    /// virtual method to set vertical flipping state
    f_set_vflip: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_flip: c_int) callconv(.c) c_int,
    /// virtual method to set horizontal centering state
    f_set_hcenter: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_center: c_int) callconv(.c) c_int,
    /// virtual method to set vertical centering state
    f_set_vcenter: ?*const fn (p_video_orientation: *gstvideo.VideoOrientation, p_center: c_int) callconv(.c) c_int,

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

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

/// Functions to create and handle overlay compositions on video buffers.
///
/// An overlay composition describes one or more overlay rectangles to be
/// blended on top of a video buffer.
///
/// This API serves two main purposes:
///
/// * it can be used to attach overlay information (subtitles or logos)
///   to non-raw video buffers such as GL/VAAPI/VDPAU surfaces. The actual
///   blending of the overlay can then be done by e.g. the video sink that
///   processes these non-raw buffers.
///
/// * it can also be used to blend overlay rectangles on top of raw video
///   buffers, thus consolidating blending functionality for raw video in
///   one place.
///
/// Together, this allows existing overlay elements to easily handle raw
/// and non-raw video as input in without major changes (once the overlays
/// have been put into a `gstvideo.VideoOverlayComposition` object anyway) - for raw
/// video the overlay can just use the blending function to blend the data
/// on top of the video, and for surface buffers it can just attach them to
/// the buffer and let the sink render the overlays.
pub const VideoOverlayComposition = opaque {
    /// Creates a new video overlay composition object to hold one or more
    /// overlay rectangles.
    ///
    /// Note that since 1.20 this allows to pass `NULL` for `rectangle`.
    extern fn gst_video_overlay_composition_new(p_rectangle: ?*gstvideo.VideoOverlayRectangle) *gstvideo.VideoOverlayComposition;
    pub const new = gst_video_overlay_composition_new;

    /// Adds an overlay rectangle to an existing overlay composition object. This
    /// must be done right after creating the overlay composition.
    extern fn gst_video_overlay_composition_add_rectangle(p_comp: *VideoOverlayComposition, p_rectangle: *gstvideo.VideoOverlayRectangle) void;
    pub const addRectangle = gst_video_overlay_composition_add_rectangle;

    /// Blends the overlay rectangles in `comp` on top of the raw video data
    /// contained in `video_buf`. The data in `video_buf` must be writable and
    /// mapped appropriately.
    ///
    /// Since `video_buf` data is read and will be modified, it ought be
    /// mapped with flag GST_MAP_READWRITE.
    extern fn gst_video_overlay_composition_blend(p_comp: *VideoOverlayComposition, p_video_buf: *gstvideo.VideoFrame) c_int;
    pub const blend = gst_video_overlay_composition_blend;

    /// Makes a copy of `comp` and all contained rectangles, so that it is possible
    /// to modify the composition and contained rectangles (e.g. add additional
    /// rectangles or change the render co-ordinates or render dimension). The
    /// actual overlay pixel data buffers contained in the rectangles are not
    /// copied.
    extern fn gst_video_overlay_composition_copy(p_comp: *VideoOverlayComposition) *gstvideo.VideoOverlayComposition;
    pub const copy = gst_video_overlay_composition_copy;

    /// Returns the `n`-th `gstvideo.VideoOverlayRectangle` contained in `comp`.
    extern fn gst_video_overlay_composition_get_rectangle(p_comp: *VideoOverlayComposition, p_n: c_uint) ?*gstvideo.VideoOverlayRectangle;
    pub const getRectangle = gst_video_overlay_composition_get_rectangle;

    /// Returns the sequence number of this composition. Sequence numbers are
    /// monotonically increasing and unique for overlay compositions and rectangles
    /// (meaning there will never be a rectangle with the same sequence number as
    /// a composition).
    extern fn gst_video_overlay_composition_get_seqnum(p_comp: *VideoOverlayComposition) c_uint;
    pub const getSeqnum = gst_video_overlay_composition_get_seqnum;

    /// Takes ownership of `comp` and returns a version of `comp` that is writable
    /// (i.e. can be modified). Will either return `comp` right away, or create a
    /// new writable copy of `comp` and unref `comp` itself. All the contained
    /// rectangles will also be copied, but the actual overlay pixel data buffers
    /// contained in the rectangles are not copied.
    extern fn gst_video_overlay_composition_make_writable(p_comp: *VideoOverlayComposition) *gstvideo.VideoOverlayComposition;
    pub const makeWritable = gst_video_overlay_composition_make_writable;

    /// Returns the number of `gstvideo.VideoOverlayRectangle`<!-- -->s contained in `comp`.
    extern fn gst_video_overlay_composition_n_rectangles(p_comp: *VideoOverlayComposition) c_uint;
    pub const nRectangles = gst_video_overlay_composition_n_rectangles;

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

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

/// Extra buffer metadata describing image overlay data.
pub const VideoOverlayCompositionMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// the attached `gstvideo.VideoOverlayComposition`
    f_overlay: ?*gstvideo.VideoOverlayComposition,

    extern fn gst_video_overlay_composition_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_overlay_composition_meta_get_info;

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

/// `gstvideo.VideoOverlay` interface
pub const VideoOverlayInterface = extern struct {
    pub const Instance = gstvideo.VideoOverlay;

    /// parent interface type.
    f_iface: gobject.TypeInterface,
    /// virtual method to handle expose events
    f_expose: ?*const fn (p_overlay: *gstvideo.VideoOverlay) callconv(.c) void,
    /// virtual method to handle events
    f_handle_events: ?*const fn (p_overlay: *gstvideo.VideoOverlay, p_handle_events: c_int) callconv(.c) void,
    /// virtual method to set the render rectangle
    f_set_render_rectangle: ?*const fn (p_overlay: *gstvideo.VideoOverlay, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) callconv(.c) void,
    /// virtual method to configure the window handle
    f_set_window_handle: ?*const fn (p_overlay: *gstvideo.VideoOverlay, p_handle: usize) callconv(.c) void,

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

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

/// An opaque video overlay rectangle object. A rectangle contains a single
/// overlay rectangle which can be added to a composition.
pub const VideoOverlayRectangle = opaque {
    /// Creates a new video overlay rectangle with ARGB or AYUV pixel data.
    /// The layout in case of ARGB of the components in memory is B-G-R-A
    /// on little-endian platforms
    /// (corresponding to `GST_VIDEO_FORMAT_BGRA`) and A-R-G-B on big-endian
    /// platforms (corresponding to `GST_VIDEO_FORMAT_ARGB`). In other words,
    /// pixels are treated as 32-bit words and the lowest 8 bits then contain
    /// the blue component value and the highest 8 bits contain the alpha
    /// component value. Unless specified in the flags, the RGB values are
    /// non-premultiplied. This is the format that is used by most hardware,
    /// and also many rendering libraries such as Cairo, for example.
    /// The pixel data buffer must have `gstvideo.VideoMeta` set.
    extern fn gst_video_overlay_rectangle_new_raw(p_pixels: *gst.Buffer, p_render_x: c_int, p_render_y: c_int, p_render_width: c_uint, p_render_height: c_uint, p_flags: gstvideo.VideoOverlayFormatFlags) *gstvideo.VideoOverlayRectangle;
    pub const newRaw = gst_video_overlay_rectangle_new_raw;

    /// Makes a copy of `rectangle`, so that it is possible to modify it
    /// (e.g. to change the render co-ordinates or render dimension). The
    /// actual overlay pixel data buffers contained in the rectangle are not
    /// copied.
    extern fn gst_video_overlay_rectangle_copy(p_rectangle: *VideoOverlayRectangle) *gstvideo.VideoOverlayRectangle;
    pub const copy = gst_video_overlay_rectangle_copy;

    /// Retrieves the flags associated with a `gstvideo.VideoOverlayRectangle`.
    /// This is useful if the caller can handle both premultiplied alpha and
    /// non premultiplied alpha, for example. By knowing whether the rectangle
    /// uses premultiplied or not, it can request the pixel data in the format
    /// it is stored in, to avoid unnecessary conversion.
    extern fn gst_video_overlay_rectangle_get_flags(p_rectangle: *VideoOverlayRectangle) gstvideo.VideoOverlayFormatFlags;
    pub const getFlags = gst_video_overlay_rectangle_get_flags;

    /// Retrieves the global-alpha value associated with a `gstvideo.VideoOverlayRectangle`.
    extern fn gst_video_overlay_rectangle_get_global_alpha(p_rectangle: *VideoOverlayRectangle) f32;
    pub const getGlobalAlpha = gst_video_overlay_rectangle_get_global_alpha;

    extern fn gst_video_overlay_rectangle_get_pixels_argb(p_rectangle: *VideoOverlayRectangle, p_flags: gstvideo.VideoOverlayFormatFlags) *gst.Buffer;
    pub const getPixelsArgb = gst_video_overlay_rectangle_get_pixels_argb;

    extern fn gst_video_overlay_rectangle_get_pixels_ayuv(p_rectangle: *VideoOverlayRectangle, p_flags: gstvideo.VideoOverlayFormatFlags) *gst.Buffer;
    pub const getPixelsAyuv = gst_video_overlay_rectangle_get_pixels_ayuv;

    extern fn gst_video_overlay_rectangle_get_pixels_raw(p_rectangle: *VideoOverlayRectangle, p_flags: gstvideo.VideoOverlayFormatFlags) *gst.Buffer;
    pub const getPixelsRaw = gst_video_overlay_rectangle_get_pixels_raw;

    /// Retrieves the pixel data as it is. This is useful if the caller can
    /// do the scaling itself when handling the overlaying. The rectangle will
    /// need to be scaled to the render dimensions, which can be retrieved using
    /// `gstvideo.VideoOverlayRectangle.getRenderRectangle`.
    extern fn gst_video_overlay_rectangle_get_pixels_unscaled_argb(p_rectangle: *VideoOverlayRectangle, p_flags: gstvideo.VideoOverlayFormatFlags) *gst.Buffer;
    pub const getPixelsUnscaledArgb = gst_video_overlay_rectangle_get_pixels_unscaled_argb;

    /// Retrieves the pixel data as it is. This is useful if the caller can
    /// do the scaling itself when handling the overlaying. The rectangle will
    /// need to be scaled to the render dimensions, which can be retrieved using
    /// `gstvideo.VideoOverlayRectangle.getRenderRectangle`.
    extern fn gst_video_overlay_rectangle_get_pixels_unscaled_ayuv(p_rectangle: *VideoOverlayRectangle, p_flags: gstvideo.VideoOverlayFormatFlags) *gst.Buffer;
    pub const getPixelsUnscaledAyuv = gst_video_overlay_rectangle_get_pixels_unscaled_ayuv;

    /// Retrieves the pixel data as it is. This is useful if the caller can
    /// do the scaling itself when handling the overlaying. The rectangle will
    /// need to be scaled to the render dimensions, which can be retrieved using
    /// `gstvideo.VideoOverlayRectangle.getRenderRectangle`.
    extern fn gst_video_overlay_rectangle_get_pixels_unscaled_raw(p_rectangle: *VideoOverlayRectangle, p_flags: gstvideo.VideoOverlayFormatFlags) *gst.Buffer;
    pub const getPixelsUnscaledRaw = gst_video_overlay_rectangle_get_pixels_unscaled_raw;

    /// Retrieves the render position and render dimension of the overlay
    /// rectangle on the video.
    extern fn gst_video_overlay_rectangle_get_render_rectangle(p_rectangle: *VideoOverlayRectangle, p_render_x: ?*c_int, p_render_y: ?*c_int, p_render_width: ?*c_uint, p_render_height: ?*c_uint) c_int;
    pub const getRenderRectangle = gst_video_overlay_rectangle_get_render_rectangle;

    /// Returns the sequence number of this rectangle. Sequence numbers are
    /// monotonically increasing and unique for overlay compositions and rectangles
    /// (meaning there will never be a rectangle with the same sequence number as
    /// a composition).
    ///
    /// Using the sequence number of a rectangle as an indicator for changed
    /// pixel-data of a rectangle is dangereous. Some API calls, like e.g.
    /// `gstvideo.VideoOverlayRectangle.setGlobalAlpha`, automatically update
    /// the per rectangle sequence number, which is misleading for renderers/
    /// consumers, that handle global-alpha themselves. For them  the
    /// pixel-data returned by gst_video_overlay_rectangle_get_pixels_*()
    /// won't be different for different global-alpha values. In this case a
    /// renderer could also use the GstBuffer pointers as a hint for changed
    /// pixel-data.
    extern fn gst_video_overlay_rectangle_get_seqnum(p_rectangle: *VideoOverlayRectangle) c_uint;
    pub const getSeqnum = gst_video_overlay_rectangle_get_seqnum;

    /// Sets the global alpha value associated with a `gstvideo.VideoOverlayRectangle`. Per-
    /// pixel alpha values are multiplied with this value. Valid
    /// values: 0 <= global_alpha <= 1; 1 to deactivate.
    ///
    /// `rectangle` must be writable, meaning its refcount must be 1. You can
    /// make the rectangles inside a `gstvideo.VideoOverlayComposition` writable using
    /// `gstvideo.VideoOverlayComposition.makeWritable` or
    /// `gstvideo.VideoOverlayComposition.copy`.
    extern fn gst_video_overlay_rectangle_set_global_alpha(p_rectangle: *VideoOverlayRectangle, p_global_alpha: f32) void;
    pub const setGlobalAlpha = gst_video_overlay_rectangle_set_global_alpha;

    /// Sets the render position and dimensions of the rectangle on the video.
    /// This function is mainly for elements that modify the size of the video
    /// in some way (e.g. through scaling or cropping) and need to adjust the
    /// details of any overlays to match the operation that changed the size.
    ///
    /// `rectangle` must be writable, meaning its refcount must be 1. You can
    /// make the rectangles inside a `gstvideo.VideoOverlayComposition` writable using
    /// `gstvideo.VideoOverlayComposition.makeWritable` or
    /// `gstvideo.VideoOverlayComposition.copy`.
    extern fn gst_video_overlay_rectangle_set_render_rectangle(p_rectangle: *VideoOverlayRectangle, p_render_x: c_int, p_render_y: c_int, p_render_width: c_uint, p_render_height: c_uint) void;
    pub const setRenderRectangle = gst_video_overlay_rectangle_set_render_rectangle;

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

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

/// Helper structure representing a rectangular area.
pub const VideoRectangle = extern struct {
    /// X coordinate of rectangle's top-left point
    f_x: c_int,
    /// Y coordinate of rectangle's top-left point
    f_y: c_int,
    /// width of the rectangle
    f_w: c_int,
    /// height of the rectangle
    f_h: c_int,

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

/// Extra buffer metadata describing an image region of interest
pub const VideoRegionOfInterestMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// GQuark describing the semantic of the Roi (f.i. a face, a pedestrian)
    f_roi_type: glib.Quark,
    /// identifier of this particular ROI
    f_id: c_int,
    /// identifier of its parent ROI, used f.i. for ROI hierarchisation.
    f_parent_id: c_int,
    /// x component of upper-left corner
    f_x: c_uint,
    /// y component of upper-left corner
    f_y: c_uint,
    /// bounding box width
    f_w: c_uint,
    /// bounding box height
    f_h: c_uint,
    /// list of `gst.Structure` containing element-specific params for downstream,
    ///          see `gstvideo.VideoRegionOfInterestMeta.addParam`. (Since: 1.14)
    f_params: ?*glib.List,

    extern fn gst_video_region_of_interest_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_region_of_interest_meta_get_info;

    /// Attach element-specific parameters to `meta` meant to be used by downstream
    /// elements which may handle this ROI.
    /// The name of `s` is used to identify the element these parameters are meant for.
    ///
    /// This is typically used to tell encoders how they should encode this specific region.
    /// For example, a structure named "roi/x264enc" could be used to give the
    /// QP offsets this encoder should use when encoding the region described in `meta`.
    /// Multiple parameters can be defined for the same meta so different encoders
    /// can be supported by cross platform applications).
    extern fn gst_video_region_of_interest_meta_add_param(p_meta: *VideoRegionOfInterestMeta, p_s: *gst.Structure) void;
    pub const addParam = gst_video_region_of_interest_meta_add_param;

    /// Retrieve the parameter for `meta` having `name` as structure name,
    /// or `NULL` if there is none.
    extern fn gst_video_region_of_interest_meta_get_param(p_meta: *VideoRegionOfInterestMeta, p_name: [*:0]const u8) ?*gst.Structure;
    pub const getParam = gst_video_region_of_interest_meta_get_param;

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

/// `gstvideo.VideoResampler` is a structure which holds the information
/// required to perform various kinds of resampling filtering.
pub const VideoResampler = extern struct {
    /// the input size
    f_in_size: c_int,
    /// the output size
    f_out_size: c_int,
    /// the maximum number of taps
    f_max_taps: c_uint,
    /// the number of phases
    f_n_phases: c_uint,
    /// array with the source offset for each output element
    f_offset: ?*u32,
    /// array with the phase to use for each output element
    f_phase: ?*u32,
    /// array with new number of taps for each phase
    f_n_taps: ?*u32,
    /// the taps for all phases
    f_taps: ?*f64,
    f__gst_reserved: [4]*anyopaque,

    /// Clear a previously initialized `gstvideo.VideoResampler` `resampler`.
    extern fn gst_video_resampler_clear(p_resampler: *VideoResampler) void;
    pub const clear = gst_video_resampler_clear;

    extern fn gst_video_resampler_init(p_resampler: *VideoResampler, p_method: gstvideo.VideoResamplerMethod, p_flags: gstvideo.VideoResamplerFlags, p_n_phases: c_uint, p_n_taps: c_uint, p_shift: f64, p_in_size: c_uint, p_out_size: c_uint, p_options: *gst.Structure) c_int;
    pub const init = gst_video_resampler_init;

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

/// H.264 H.265 metadata from SEI User Data Unregistered messages
pub const VideoSEIUserDataUnregisteredMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// User Data Unregistered UUID
    f_uuid: [16]u8,
    /// Unparsed data buffer
    f_data: ?*u8,
    /// Size of the data buffer
    f_size: usize,

    extern fn gst_video_sei_user_data_unregistered_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_sei_user_data_unregistered_meta_get_info;

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

/// `gstvideo.VideoScaler` is a utility object for rescaling and resampling
/// video frames using various interpolation / sampling methods.
pub const VideoScaler = opaque {
    /// Make a new `method` video scaler. `in_size` source lines/pixels will
    /// be scaled to `out_size` destination lines/pixels.
    ///
    /// `n_taps` specifies the amount of pixels to use from the source for one output
    /// pixel. If n_taps is 0, this function chooses a good value automatically based
    /// on the `method` and `in_size`/`out_size`.
    extern fn gst_video_scaler_new(p_method: gstvideo.VideoResamplerMethod, p_flags: gstvideo.VideoScalerFlags, p_n_taps: c_uint, p_in_size: c_uint, p_out_size: c_uint, p_options: ?*gst.Structure) *gstvideo.VideoScaler;
    pub const new = gst_video_scaler_new;

    /// Scale a rectangle of pixels in `src` with `src_stride` to `dest` with
    /// `dest_stride` using the horizontal scaler `hscaler` and the vertical
    /// scaler `vscale`.
    ///
    /// One or both of `hscale` and `vscale` can be NULL to only perform scaling in
    /// one dimension or do a copy without scaling.
    ///
    /// `x` and `y` are the coordinates in the destination image to process.
    extern fn gst_video_scaler_2d(p_hscale: *VideoScaler, p_vscale: *gstvideo.VideoScaler, p_format: gstvideo.VideoFormat, p_src: ?*anyopaque, p_src_stride: c_int, p_dest: ?*anyopaque, p_dest_stride: c_int, p_x: c_uint, p_y: c_uint, p_width: c_uint, p_height: c_uint) void;
    pub const @"2d" = gst_video_scaler_2d;

    /// Combine a scaler for Y and UV into one scaler for the packed `format`.
    extern fn gst_video_scaler_combine_packed_YUV(p_y_scale: *VideoScaler, p_uv_scale: *gstvideo.VideoScaler, p_in_format: gstvideo.VideoFormat, p_out_format: gstvideo.VideoFormat) *gstvideo.VideoScaler;
    pub const combinePackedYUV = gst_video_scaler_combine_packed_YUV;

    /// Free a previously allocated `gstvideo.VideoScaler` `scale`.
    extern fn gst_video_scaler_free(p_scale: *VideoScaler) void;
    pub const free = gst_video_scaler_free;

    /// For a given pixel at `out_offset`, get the first required input pixel at
    /// `in_offset` and the `n_taps` filter coefficients.
    ///
    /// Note that for interlaced content, `in_offset` needs to be incremented with
    /// 2 to get the next input line.
    extern fn gst_video_scaler_get_coeff(p_scale: *VideoScaler, p_out_offset: c_uint, p_in_offset: ?*c_uint, p_n_taps: ?*c_uint) *const f64;
    pub const getCoeff = gst_video_scaler_get_coeff;

    /// Get the maximum number of taps for `scale`.
    extern fn gst_video_scaler_get_max_taps(p_scale: *VideoScaler) c_uint;
    pub const getMaxTaps = gst_video_scaler_get_max_taps;

    /// Horizontally scale the pixels in `src` to `dest`, starting from `dest_offset`
    /// for `width` samples.
    extern fn gst_video_scaler_horizontal(p_scale: *VideoScaler, p_format: gstvideo.VideoFormat, p_src: ?*anyopaque, p_dest: ?*anyopaque, p_dest_offset: c_uint, p_width: c_uint) void;
    pub const horizontal = gst_video_scaler_horizontal;

    /// Vertically combine `width` pixels in the lines in `src_lines` to `dest`.
    /// `dest` is the location of the target line at `dest_offset` and
    /// `srcs` are the input lines for `dest_offset`.
    extern fn gst_video_scaler_vertical(p_scale: *VideoScaler, p_format: gstvideo.VideoFormat, p_src_lines: ?*anyopaque, p_dest: ?*anyopaque, p_dest_offset: c_uint, p_width: c_uint) void;
    pub const vertical = gst_video_scaler_vertical;

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

/// The video sink class structure. Derived classes should override the
/// `show_frame` virtual function.
pub const VideoSinkClass = extern struct {
    pub const Instance = gstvideo.VideoSink;

    /// the parent class structure
    f_parent_class: gstbase.BaseSinkClass,
    /// render a video frame. Maps to `gstbase.BaseSinkClass.virtual_methods.render` and
    ///     `gstbase.BaseSinkClass.virtual_methods.preroll` vfuncs. Rendering during preroll will be
    ///     suppressed if the `gstvideo.VideoSink.properties.show`-preroll-frame property is set to
    ///     `FALSE`.
    f_show_frame: ?*const fn (p_video_sink: *gstvideo.VideoSink, p_buf: *gst.Buffer) callconv(.c) gst.FlowReturn,
    f_set_info: ?*const fn (p_video_sink: *gstvideo.VideoSink, p_caps: *gst.Caps, p_info: *const gstvideo.VideoInfo) callconv(.c) c_int,
    f__gst_reserved: [3]*anyopaque,

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

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

pub const VideoSinkPrivate = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

/// Description of a tile. This structure allow to describe arbitrary tile
/// dimensions and sizes.
pub const VideoTileInfo = extern struct {
    /// The width in pixels of a tile. This value can be zero if the number of
    /// pixels per line is not an integer value.
    f_width: c_uint,
    f_height: c_uint,
    /// The stride (in bytes) of a tile line. Regardless if the tile have sub-tiles
    /// this stride multiplied by the height should be equal to
    /// `gstvideo.VideoTileInfo.size`. This value is used to translate into linear stride
    /// when older APIs are being used to expose this format.
    f_stride: c_uint,
    /// The size in bytes of a tile. This value must be divisible by
    /// `gstvideo.VideoTileInfo.stride`.
    f_size: c_uint,
    f_padding: [4]u32,

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

/// `field_count` must be 0 for progressive video and 1 or 2 for interlaced.
///
/// A representation of a SMPTE time code.
///
/// `hours` must be positive and less than 24. Will wrap around otherwise.
/// `minutes` and `seconds` must be positive and less than 60.
/// `frames` must be less than or equal to `config`.fps_n / `config`.fps_d
/// These values are *NOT* automatically normalized.
pub const VideoTimeCode = extern struct {
    /// the corresponding `gstvideo.VideoTimeCodeConfig`
    f_config: gstvideo.VideoTimeCodeConfig,
    /// the hours field of `gstvideo.VideoTimeCode`
    f_hours: c_uint,
    /// the minutes field of `gstvideo.VideoTimeCode`
    f_minutes: c_uint,
    /// the seconds field of `gstvideo.VideoTimeCode`
    f_seconds: c_uint,
    /// the frames field of `gstvideo.VideoTimeCode`
    f_frames: c_uint,
    /// Interlaced video field count
    f_field_count: c_uint,

    /// `field_count` is 0 for progressive, 1 or 2 for interlaced.
    /// `latest_daiy_jam` reference is stolen from caller.
    extern fn gst_video_time_code_new(p_fps_n: c_uint, p_fps_d: c_uint, p_latest_daily_jam: *glib.DateTime, p_flags: gstvideo.VideoTimeCodeFlags, p_hours: c_uint, p_minutes: c_uint, p_seconds: c_uint, p_frames: c_uint, p_field_count: c_uint) *gstvideo.VideoTimeCode;
    pub const new = gst_video_time_code_new;

    extern fn gst_video_time_code_new_empty() *gstvideo.VideoTimeCode;
    pub const newEmpty = gst_video_time_code_new_empty;

    /// The resulting config->latest_daily_jam is set to
    /// midnight, and timecode is set to the given time.
    ///
    /// This might return a completely invalid timecode, use
    /// `gstvideo.VideoTimeCode.newFromDateTimeFull` to ensure
    /// that you would get `NULL` instead in that case.
    extern fn gst_video_time_code_new_from_date_time(p_fps_n: c_uint, p_fps_d: c_uint, p_dt: *glib.DateTime, p_flags: gstvideo.VideoTimeCodeFlags, p_field_count: c_uint) *gstvideo.VideoTimeCode;
    pub const newFromDateTime = gst_video_time_code_new_from_date_time;

    /// The resulting config->latest_daily_jam is set to
    /// midnight, and timecode is set to the given time.
    extern fn gst_video_time_code_new_from_date_time_full(p_fps_n: c_uint, p_fps_d: c_uint, p_dt: *glib.DateTime, p_flags: gstvideo.VideoTimeCodeFlags, p_field_count: c_uint) ?*gstvideo.VideoTimeCode;
    pub const newFromDateTimeFull = gst_video_time_code_new_from_date_time_full;

    extern fn gst_video_time_code_new_from_string(p_tc_str: [*:0]const u8) ?*gstvideo.VideoTimeCode;
    pub const newFromString = gst_video_time_code_new_from_string;

    /// Adds or subtracts `frames` amount of frames to `tc`. tc needs to
    /// contain valid data, as verified by `gstvideo.VideoTimeCode.isValid`.
    extern fn gst_video_time_code_add_frames(p_tc: *VideoTimeCode, p_frames: i64) void;
    pub const addFrames = gst_video_time_code_add_frames;

    /// This makes a component-wise addition of `tc_inter` to `tc`. For example,
    /// adding ("01:02:03:04", "00:01:00:00") will return "01:03:03:04".
    /// When it comes to drop-frame timecodes,
    /// adding ("00:00:00;00", "00:01:00:00") will return "00:01:00;02"
    /// because of drop-frame oddities. However,
    /// adding ("00:09:00;02", "00:01:00:00") will return "00:10:00;00"
    /// because this time we can have an exact minute.
    extern fn gst_video_time_code_add_interval(p_tc: *const VideoTimeCode, p_tc_inter: *const gstvideo.VideoTimeCodeInterval) ?*gstvideo.VideoTimeCode;
    pub const addInterval = gst_video_time_code_add_interval;

    /// Initializes `tc` with empty/zero/NULL values and frees any memory
    /// it might currently use.
    extern fn gst_video_time_code_clear(p_tc: *VideoTimeCode) void;
    pub const clear = gst_video_time_code_clear;

    /// Compares `tc1` and `tc2`. If both have latest daily jam information, it is
    /// taken into account. Otherwise, it is assumed that the daily jam of both
    /// `tc1` and `tc2` was at the same time. Both time codes must be valid.
    extern fn gst_video_time_code_compare(p_tc1: *const VideoTimeCode, p_tc2: *const gstvideo.VideoTimeCode) c_int;
    pub const compare = gst_video_time_code_compare;

    extern fn gst_video_time_code_copy(p_tc: *const VideoTimeCode) *gstvideo.VideoTimeCode;
    pub const copy = gst_video_time_code_copy;

    extern fn gst_video_time_code_frames_since_daily_jam(p_tc: *const VideoTimeCode) u64;
    pub const framesSinceDailyJam = gst_video_time_code_frames_since_daily_jam;

    /// Frees `tc`.
    extern fn gst_video_time_code_free(p_tc: *VideoTimeCode) void;
    pub const free = gst_video_time_code_free;

    /// Adds one frame to `tc`.
    extern fn gst_video_time_code_increment_frame(p_tc: *VideoTimeCode) void;
    pub const incrementFrame = gst_video_time_code_increment_frame;

    /// `field_count` is 0 for progressive, 1 or 2 for interlaced.
    /// `latest_daiy_jam` reference is stolen from caller.
    ///
    /// Initializes `tc` with the given values.
    /// The values are not checked for being in a valid range. To see if your
    /// timecode actually has valid content, use `gstvideo.VideoTimeCode.isValid`.
    extern fn gst_video_time_code_init(p_tc: *VideoTimeCode, p_fps_n: c_uint, p_fps_d: c_uint, p_latest_daily_jam: ?*glib.DateTime, p_flags: gstvideo.VideoTimeCodeFlags, p_hours: c_uint, p_minutes: c_uint, p_seconds: c_uint, p_frames: c_uint, p_field_count: c_uint) void;
    pub const init = gst_video_time_code_init;

    /// The resulting config->latest_daily_jam is set to midnight, and timecode is
    /// set to the given time.
    ///
    /// Will assert on invalid parameters, use `gstvideo.VideoTimeCode.initFromDateTimeFull`
    /// for being able to handle invalid parameters.
    extern fn gst_video_time_code_init_from_date_time(p_tc: *VideoTimeCode, p_fps_n: c_uint, p_fps_d: c_uint, p_dt: *glib.DateTime, p_flags: gstvideo.VideoTimeCodeFlags, p_field_count: c_uint) void;
    pub const initFromDateTime = gst_video_time_code_init_from_date_time;

    /// The resulting config->latest_daily_jam is set to
    /// midnight, and timecode is set to the given time.
    extern fn gst_video_time_code_init_from_date_time_full(p_tc: *VideoTimeCode, p_fps_n: c_uint, p_fps_d: c_uint, p_dt: *glib.DateTime, p_flags: gstvideo.VideoTimeCodeFlags, p_field_count: c_uint) c_int;
    pub const initFromDateTimeFull = gst_video_time_code_init_from_date_time_full;

    extern fn gst_video_time_code_is_valid(p_tc: *const VideoTimeCode) c_int;
    pub const isValid = gst_video_time_code_is_valid;

    extern fn gst_video_time_code_nsec_since_daily_jam(p_tc: *const VideoTimeCode) u64;
    pub const nsecSinceDailyJam = gst_video_time_code_nsec_since_daily_jam;

    /// The `tc`.config->latest_daily_jam is required to be non-NULL.
    extern fn gst_video_time_code_to_date_time(p_tc: *const VideoTimeCode) ?*glib.DateTime;
    pub const toDateTime = gst_video_time_code_to_date_time;

    extern fn gst_video_time_code_to_string(p_tc: *const VideoTimeCode) [*:0]u8;
    pub const toString = gst_video_time_code_to_string;

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

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

/// Supported frame rates: 30000/1001, 60000/1001 (both with and without drop
/// frame), and integer frame rates e.g. 25/1, 30/1, 50/1, 60/1.
///
/// The configuration of the time code.
pub const VideoTimeCodeConfig = extern struct {
    /// Numerator of the frame rate
    f_fps_n: c_uint,
    /// Denominator of the frame rate
    f_fps_d: c_uint,
    /// the corresponding `gstvideo.VideoTimeCodeFlags`
    f_flags: gstvideo.VideoTimeCodeFlags,
    /// The latest daily jam information, if present, or NULL
    f_latest_daily_jam: ?*glib.DateTime,

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

/// A representation of a difference between two `gstvideo.VideoTimeCode` instances.
/// Will not necessarily correspond to a real timecode (e.g. 00:00:10;00)
pub const VideoTimeCodeInterval = extern struct {
    /// the hours field of `gstvideo.VideoTimeCodeInterval`
    f_hours: c_uint,
    /// the minutes field of `gstvideo.VideoTimeCodeInterval`
    f_minutes: c_uint,
    /// the seconds field of `gstvideo.VideoTimeCodeInterval`
    f_seconds: c_uint,
    /// the frames field of `gstvideo.VideoTimeCodeInterval`
    f_frames: c_uint,

    extern fn gst_video_time_code_interval_new(p_hours: c_uint, p_minutes: c_uint, p_seconds: c_uint, p_frames: c_uint) *gstvideo.VideoTimeCodeInterval;
    pub const new = gst_video_time_code_interval_new;

    /// `tc_inter_str` must only have ":" as separators.
    extern fn gst_video_time_code_interval_new_from_string(p_tc_inter_str: [*:0]const u8) ?*gstvideo.VideoTimeCodeInterval;
    pub const newFromString = gst_video_time_code_interval_new_from_string;

    /// Initializes `tc` with empty/zero/NULL values.
    extern fn gst_video_time_code_interval_clear(p_tc: *VideoTimeCodeInterval) void;
    pub const clear = gst_video_time_code_interval_clear;

    extern fn gst_video_time_code_interval_copy(p_tc: *const VideoTimeCodeInterval) *gstvideo.VideoTimeCodeInterval;
    pub const copy = gst_video_time_code_interval_copy;

    /// Frees `tc`.
    extern fn gst_video_time_code_interval_free(p_tc: *VideoTimeCodeInterval) void;
    pub const free = gst_video_time_code_interval_free;

    /// Initializes `tc` with the given values.
    extern fn gst_video_time_code_interval_init(p_tc: *VideoTimeCodeInterval, p_hours: c_uint, p_minutes: c_uint, p_seconds: c_uint, p_frames: c_uint) void;
    pub const init = gst_video_time_code_interval_init;

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

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

/// Extra buffer metadata describing the GstVideoTimeCode of the frame.
///
/// Each frame is assumed to have its own timecode, i.e. they are not
/// automatically incremented/interpolated.
pub const VideoTimeCodeMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// the GstVideoTimeCode to attach
    f_tc: gstvideo.VideoTimeCode,

    extern fn gst_video_time_code_meta_get_info() *const gst.MetaInfo;
    pub const getInfo = gst_video_time_code_meta_get_info;

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

/// An encoder for writing ancillary data to the
/// Vertical Blanking Interval lines of component signals.
pub const VideoVBIEncoder = opaque {
    /// Create a new `gstvideo.VideoVBIEncoder` for the specified `format` and `pixel_width`.
    extern fn gst_video_vbi_encoder_new(p_format: gstvideo.VideoFormat, p_pixel_width: u32) ?*gstvideo.VideoVBIEncoder;
    pub const new = gst_video_vbi_encoder_new;

    /// Stores Video Ancillary data, according to SMPTE-291M specification.
    ///
    /// Note that the contents of the data are always read as 8bit data (i.e. do not contain
    /// the parity check bits).
    extern fn gst_video_vbi_encoder_add_ancillary(p_encoder: *VideoVBIEncoder, p_composite: c_int, p_DID: u8, p_SDID_block_number: u8, p_data: [*]const u8, p_data_count: c_uint) c_int;
    pub const addAncillary = gst_video_vbi_encoder_add_ancillary;

    extern fn gst_video_vbi_encoder_copy(p_encoder: *const VideoVBIEncoder) *gstvideo.VideoVBIEncoder;
    pub const copy = gst_video_vbi_encoder_copy;

    /// Frees the `encoder`.
    extern fn gst_video_vbi_encoder_free(p_encoder: *VideoVBIEncoder) void;
    pub const free = gst_video_vbi_encoder_free;

    extern fn gst_video_vbi_encoder_write_line(p_encoder: *VideoVBIEncoder, p_data: *u8) void;
    pub const writeLine = gst_video_vbi_encoder_write_line;

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

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

/// A parser for detecting and extracting `GstVideoAncillary` data from
/// Vertical Blanking Interval lines of component signals.
pub const VideoVBIParser = opaque {
    /// Create a new `gstvideo.VideoVBIParser` for the specified `format` and `pixel_width`.
    extern fn gst_video_vbi_parser_new(p_format: gstvideo.VideoFormat, p_pixel_width: u32) ?*gstvideo.VideoVBIParser;
    pub const new = gst_video_vbi_parser_new;

    /// Provide a new line of data to the `parser`. Call `gstvideo.VideoVBIParser.getAncillary`
    /// to get the Ancillary data that might be present on that line.
    extern fn gst_video_vbi_parser_add_line(p_parser: *VideoVBIParser, p_data: [*]const u8) void;
    pub const addLine = gst_video_vbi_parser_add_line;

    extern fn gst_video_vbi_parser_copy(p_parser: *const VideoVBIParser) *gstvideo.VideoVBIParser;
    pub const copy = gst_video_vbi_parser_copy;

    /// Frees the `parser`.
    extern fn gst_video_vbi_parser_free(p_parser: *VideoVBIParser) void;
    pub const free = gst_video_vbi_parser_free;

    /// Parse the line provided previously by `gstvideo.VideoVBIParser.addLine`.
    extern fn gst_video_vbi_parser_get_ancillary(p_parser: *VideoVBIParser, p_anc: *gstvideo.VideoAncillary) gstvideo.VideoVBIParserResult;
    pub const getAncillary = gst_video_vbi_parser_get_ancillary;

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

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

/// Location of a `GstAncillaryMeta`.
pub const AncillaryMetaField = enum(c_int) {
    progressive = 0,
    interlaced_first = 16,
    interlaced_second = 17,
    _,

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

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

/// An enumeration indicating whether an element implements color balancing
/// operations in software or in dedicated hardware. In general, dedicated
/// hardware implementations (such as those provided by xvimagesink) are
/// preferred.
pub const ColorBalanceType = enum(c_int) {
    hardware = 0,
    software = 1,
    _,

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

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

/// A set of commands that may be issued to an element providing the
/// `gstvideo.Navigation` interface. The available commands can be queried via
/// the `gstvideo.navigationQueryNewCommands` query.
///
/// For convenience in handling DVD navigation, the MENU commands are aliased as:
///    GST_NAVIGATION_COMMAND_DVD_MENU            = `GST_NAVIGATION_COMMAND_MENU1`
///    GST_NAVIGATION_COMMAND_DVD_TITLE_MENU      = `GST_NAVIGATION_COMMAND_MENU2`
///    GST_NAVIGATION_COMMAND_DVD_ROOT_MENU       = `GST_NAVIGATION_COMMAND_MENU3`
///    GST_NAVIGATION_COMMAND_DVD_SUBPICTURE_MENU = `GST_NAVIGATION_COMMAND_MENU4`
///    GST_NAVIGATION_COMMAND_DVD_AUDIO_MENU      = `GST_NAVIGATION_COMMAND_MENU5`
///    GST_NAVIGATION_COMMAND_DVD_ANGLE_MENU      = `GST_NAVIGATION_COMMAND_MENU6`
///    GST_NAVIGATION_COMMAND_DVD_CHAPTER_MENU    = `GST_NAVIGATION_COMMAND_MENU7`
pub const NavigationCommand = enum(c_int) {
    invalid = 0,
    menu1 = 1,
    menu2 = 2,
    menu3 = 3,
    menu4 = 4,
    menu5 = 5,
    menu6 = 6,
    menu7 = 7,
    left = 20,
    right = 21,
    up = 22,
    down = 23,
    activate = 24,
    prev_angle = 30,
    next_angle = 31,
    _,

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

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

/// Enum values for the various events that an element implementing the
/// GstNavigation interface might send up the pipeline. Touch events have been
/// inspired by the libinput API, and have the same meaning here.
pub const NavigationEventType = enum(c_int) {
    invalid = 0,
    key_press = 1,
    key_release = 2,
    mouse_button_press = 3,
    mouse_button_release = 4,
    mouse_move = 5,
    command = 6,
    mouse_scroll = 7,
    touch_down = 8,
    touch_motion = 9,
    touch_up = 10,
    touch_frame = 11,
    touch_cancel = 12,
    mouse_double_click = 13,
    _,

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

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

/// A set of notifications that may be received on the bus when navigation
/// related status changes.
pub const NavigationMessageType = enum(c_int) {
    invalid = 0,
    mouse_over = 1,
    commands_changed = 2,
    angles_changed = 3,
    event = 4,
    _,

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

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

/// Types of navigation interface queries.
pub const NavigationQueryType = enum(c_int) {
    invalid = 0,
    commands = 1,
    angles = 2,
    _,

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

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

/// Enumeration of the different standards that may apply to AFD data:
///
/// 0) ETSI/DVB:
/// https://www.etsi.org/deliver/etsi_ts/101100_101199/101154/02.01.01_60/ts_101154v020101p.pdf
///
/// 1) ATSC A/53:
/// https://www.atsc.org/wp-content/uploads/2015/03/a_53-Part-4-2009.pdf
///
/// 2) SMPTE ST2016-1:
pub const VideoAFDSpec = enum(c_int) {
    dvb_etsi = 0,
    atsc_a53 = 1,
    smpte_st2016_1 = 2,
    _,

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

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

/// Enumeration of the various values for Active Format Description (AFD)
///
/// AFD should be included in video user data whenever the rectangular
/// picture area containing useful information does not extend to the full height or width of the coded
/// frame. AFD data may also be included in user data when the rectangular picture area containing
/// useful information extends to the full height and width of the coded frame.
///
/// For details, see Table 6.14 Active Format in:
///
/// ATSC Digital Television Standard:
/// Part 4 – MPEG-2 Video System Characteristics
///
/// https://www.atsc.org/wp-content/uploads/2015/03/a_53-Part-4-2009.pdf
///
/// and Active Format Description in Complete list of AFD codes
///
/// https://en.wikipedia.org/wiki/Active_Format_Description`Complete_list_of_AFD_codes`
///
/// and SMPTE ST2016-1
///
/// Notes:
///
/// 1) AFD 0 is undefined for ATSC and SMPTE ST2016-1, indicating that AFD data is not available:
/// If Bar Data is not present, AFD '0000' indicates that exact information
/// is not available and the active image should be assumed to be the same as the coded frame. AFD '0000'.
/// AFD '0000' accompanied by Bar Data signals that the active image’s aspect ratio is narrower than 16:9,
/// but is not 4:3 or 14:9. As the exact aspect ratio cannot be conveyed by AFD alone, wherever possible,
/// AFD ‘0000’ should be accompanied by Bar Data to define the exact vertical or horizontal extent
/// of the active image.
/// 2) AFD 0 is reserved for DVB/ETSI
/// 3) values 1, 5, 6, 7, and 12 are reserved for both ATSC and DVB/ETSI
/// 4) values 2 and 3 are not recommended for ATSC, but are valid for DVB/ETSI
pub const VideoAFDValue = enum(c_int) {
    unavailable = 0,
    @"16_9_top_aligned" = 2,
    @"14_9_top_aligned" = 3,
    greater_than_16_9 = 4,
    @"4_3_full_16_9_full" = 8,
    @"4_3_full_4_3_pillar" = 9,
    @"16_9_letter_16_9_full" = 10,
    @"14_9_letter_14_9_pillar" = 11,
    @"4_3_full_14_9_center" = 13,
    @"16_9_letter_14_9_center" = 14,
    @"16_9_letter_4_3_center" = 15,
    _,

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

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

/// Different alpha modes.
pub const VideoAlphaMode = enum(c_int) {
    copy = 0,
    set = 1,
    mult = 2,
    _,

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

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

pub const VideoAncillaryDID = enum(c_int) {
    undefined = 0,
    deletion = 128,
    hanc_3g_audio_data_first = 160,
    hanc_3g_audio_data_last = 167,
    hanc_hdtv_audio_data_first = 224,
    hanc_hdtv_audio_data_last = 231,
    hanc_sdtv_audio_data_1_first = 236,
    hanc_sdtv_audio_data_1_last = 239,
    camera_position = 240,
    hanc_error_detection = 244,
    hanc_sdtv_audio_data_2_first = 248,
    hanc_sdtv_audio_data_2_last = 255,
    _,

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

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

/// Some know types of Ancillary Data identifiers.
pub const VideoAncillaryDID16 = enum(c_int) {
    s334_eia_708 = 24833,
    s334_eia_608 = 24834,
    s2016_3_afd_bar = 16645,
    _,

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

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

/// The various known types of Closed Caption (CC).
pub const VideoCaptionType = enum(c_int) {
    unknown = 0,
    cea608_raw = 1,
    cea608_s334_1a = 2,
    cea708_raw = 3,
    cea708_cdp = 4,
    _,

    /// Parses fixed Closed Caption `gst.Caps` and returns the corresponding caption
    /// type, or `GST_VIDEO_CAPTION_TYPE_UNKNOWN`.
    extern fn gst_video_caption_type_from_caps(p_caps: *const gst.Caps) gstvideo.VideoCaptionType;
    pub const fromCaps = gst_video_caption_type_from_caps;

    /// Creates new caps corresponding to `type`.
    extern fn gst_video_caption_type_to_caps(p_type: gstvideo.VideoCaptionType) *gst.Caps;
    pub const toCaps = gst_video_caption_type_to_caps;

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

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

/// Different subsampling and upsampling methods
pub const VideoChromaMethod = enum(c_int) {
    nearest = 0,
    linear = 1,
    _,

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

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

/// Different chroma downsampling and upsampling modes
pub const VideoChromaMode = enum(c_int) {
    full = 0,
    upsample_only = 1,
    downsample_only = 2,
    none = 3,
    _,

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

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

/// The color matrix is used to convert between Y'PbPr and
/// non-linear RGB (R'G'B')
pub const VideoColorMatrix = enum(c_int) {
    unknown = 0,
    rgb = 1,
    fcc = 2,
    bt709 = 3,
    bt601 = 4,
    smpte240m = 5,
    bt2020 = 6,
    _,

    /// Converts the `value` to the `gstvideo.VideoColorMatrix`
    /// The matrix coefficients (MatrixCoefficients) value is
    /// defined by "ISO/IEC 23001-8 Section 7.3 Table 4"
    /// and "ITU-T H.273 Table 4".
    /// "H.264 Table E-5" and "H.265 Table E.5" share the identical values.
    extern fn gst_video_color_matrix_from_iso(p_value: c_uint) gstvideo.VideoColorMatrix;
    pub const fromIso = gst_video_color_matrix_from_iso;

    /// Get the coefficients used to convert between Y'PbPr and R'G'B' using `matrix`.
    ///
    /// When:
    ///
    /// ```
    ///   0.0 <= [Y',R',G',B'] <= 1.0)
    ///   (-0.5 <= [Pb,Pr] <= 0.5)
    /// ```
    ///
    /// the general conversion is given by:
    ///
    /// ```
    ///   Y' = Kr*R' + (1-Kr-Kb)*G' + Kb*B'
    ///   Pb = (B'-Y')/(2*(1-Kb))
    ///   Pr = (R'-Y')/(2*(1-Kr))
    /// ```
    ///
    /// and the other way around:
    ///
    /// ```
    ///   R' = Y' + Cr*2*(1-Kr)
    ///   G' = Y' - Cb*2*(1-Kb)*Kb/(1-Kr-Kb) - Cr*2*(1-Kr)*Kr/(1-Kr-Kb)
    ///   B' = Y' + Cb*2*(1-Kb)
    /// ```
    extern fn gst_video_color_matrix_get_Kr_Kb(p_matrix: gstvideo.VideoColorMatrix, p_Kr: *f64, p_Kb: *f64) c_int;
    pub const getKrKb = gst_video_color_matrix_get_Kr_Kb;

    /// Converts `gstvideo.VideoColorMatrix` to the "matrix coefficients"
    /// (MatrixCoefficients) value defined by "ISO/IEC 23001-8 Section 7.3 Table 4"
    /// and "ITU-T H.273 Table 4".
    /// "H.264 Table E-5" and "H.265 Table E.5" share the identical values.
    extern fn gst_video_color_matrix_to_iso(p_matrix: gstvideo.VideoColorMatrix) c_uint;
    pub const toIso = gst_video_color_matrix_to_iso;

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

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

/// The color primaries define the how to transform linear RGB values to and from
/// the CIE XYZ colorspace.
pub const VideoColorPrimaries = enum(c_int) {
    unknown = 0,
    bt709 = 1,
    bt470m = 2,
    bt470bg = 3,
    smpte170m = 4,
    smpte240m = 5,
    film = 6,
    bt2020 = 7,
    adobergb = 8,
    smptest428 = 9,
    smpterp431 = 10,
    smpteeg432 = 11,
    ebu3213 = 12,
    _,

    /// Converts the `value` to the `gstvideo.VideoColorPrimaries`
    /// The colour primaries (ColourPrimaries) value is
    /// defined by "ISO/IEC 23001-8 Section 7.1 Table 2" and "ITU-T H.273 Table 2".
    /// "H.264 Table E-3" and "H.265 Table E.3" share the identical values.
    extern fn gst_video_color_primaries_from_iso(p_value: c_uint) gstvideo.VideoColorPrimaries;
    pub const fromIso = gst_video_color_primaries_from_iso;

    /// Get information about the chromaticity coordinates of `primaries`.
    extern fn gst_video_color_primaries_get_info(p_primaries: gstvideo.VideoColorPrimaries) *const gstvideo.VideoColorPrimariesInfo;
    pub const getInfo = gst_video_color_primaries_get_info;

    /// Checks whether `primaries` and `other` are functionally equivalent
    extern fn gst_video_color_primaries_is_equivalent(p_primaries: gstvideo.VideoColorPrimaries, p_other: gstvideo.VideoColorPrimaries) c_int;
    pub const isEquivalent = gst_video_color_primaries_is_equivalent;

    /// Converts `gstvideo.VideoColorPrimaries` to the "colour primaries" (ColourPrimaries)
    /// value defined by "ISO/IEC 23001-8 Section 7.1 Table 2"
    /// and "ITU-T H.273 Table 2".
    /// "H.264 Table E-3" and "H.265 Table E.3" share the identical values.
    extern fn gst_video_color_primaries_to_iso(p_primaries: gstvideo.VideoColorPrimaries) c_uint;
    pub const toIso = gst_video_color_primaries_to_iso;

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

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

/// Possible color range values. These constants are defined for 8 bit color
/// values and can be scaled for other bit depths.
pub const VideoColorRange = enum(c_int) {
    unknown = 0,
    @"0_255" = 1,
    @"16_235" = 2,
    _,

    /// Compute the offset and scale values for each component of `info`. For each
    /// component, (c[i] - offset[i]) / scale[i] will scale the component c[i] to the
    /// range [0.0 .. 1.0].
    ///
    /// The reverse operation (c[i] * scale[i]) + offset[i] can be used to convert
    /// the component values in range [0.0 .. 1.0] back to their representation in
    /// `info` and `range`.
    extern fn gst_video_color_range_offsets(p_range: gstvideo.VideoColorRange, p_info: *const gstvideo.VideoFormatInfo, p_offset: *[4]c_int, p_scale: *[4]c_int) void;
    pub const offsets = gst_video_color_range_offsets;

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

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

/// Different dithering methods to use.
pub const VideoDitherMethod = enum(c_int) {
    none = 0,
    verterr = 1,
    floyd_steinberg = 2,
    sierra_lite = 3,
    bayer = 4,
    _,

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

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

/// Field order of interlaced content. This is only valid for
/// interlace-mode=interleaved and not interlace-mode=mixed. In the case of
/// mixed or GST_VIDEO_FIELD_ORDER_UNKOWN, the field order is signalled via
/// buffer flags.
pub const VideoFieldOrder = enum(c_int) {
    unknown = 0,
    top_field_first = 1,
    bottom_field_first = 2,
    _,

    /// Convert `order` to a `gstvideo.VideoFieldOrder`
    extern fn gst_video_field_order_from_string(p_order: [*:0]const u8) gstvideo.VideoFieldOrder;
    pub const fromString = gst_video_field_order_from_string;

    /// Convert `order` to its string representation.
    extern fn gst_video_field_order_to_string(p_order: gstvideo.VideoFieldOrder) [*:0]const u8;
    pub const toString = gst_video_field_order_to_string;

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

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

/// Enum value describing the most common video formats.
///
/// See the [GStreamer raw video format design document](https://gstreamer.freedesktop.org/documentation/additional/design/mediatype-video-raw.html`formats`)
/// for details about the layout and packing of these formats in memory.
pub const VideoFormat = enum(c_int) {
    unknown = 0,
    encoded = 1,
    i420 = 2,
    yv12 = 3,
    yuy2 = 4,
    uyvy = 5,
    ayuv = 6,
    rgbx = 7,
    bgrx = 8,
    xrgb = 9,
    xbgr = 10,
    rgba = 11,
    bgra = 12,
    argb = 13,
    abgr = 14,
    rgb = 15,
    bgr = 16,
    y41b = 17,
    y42b = 18,
    yvyu = 19,
    y444 = 20,
    v210 = 21,
    v216 = 22,
    nv12 = 23,
    nv21 = 24,
    gray8 = 25,
    gray16_be = 26,
    gray16_le = 27,
    v308 = 28,
    rgb16 = 29,
    bgr16 = 30,
    rgb15 = 31,
    bgr15 = 32,
    uyvp = 33,
    a420 = 34,
    rgb8p = 35,
    yuv9 = 36,
    yvu9 = 37,
    iyu1 = 38,
    argb64 = 39,
    ayuv64 = 40,
    r210 = 41,
    i420_10be = 42,
    i420_10le = 43,
    i422_10be = 44,
    i422_10le = 45,
    y444_10be = 46,
    y444_10le = 47,
    gbr = 48,
    gbr_10be = 49,
    gbr_10le = 50,
    nv16 = 51,
    nv24 = 52,
    nv12_64z32 = 53,
    a420_10be = 54,
    a420_10le = 55,
    a422_10be = 56,
    a422_10le = 57,
    a444_10be = 58,
    a444_10le = 59,
    nv61 = 60,
    p010_10be = 61,
    p010_10le = 62,
    iyu2 = 63,
    vyuy = 64,
    gbra = 65,
    gbra_10be = 66,
    gbra_10le = 67,
    gbr_12be = 68,
    gbr_12le = 69,
    gbra_12be = 70,
    gbra_12le = 71,
    i420_12be = 72,
    i420_12le = 73,
    i422_12be = 74,
    i422_12le = 75,
    y444_12be = 76,
    y444_12le = 77,
    gray10_le32 = 78,
    nv12_10le32 = 79,
    nv16_10le32 = 80,
    nv12_10le40 = 81,
    y210 = 82,
    y410 = 83,
    vuya = 84,
    bgr10a2_le = 85,
    rgb10a2_le = 86,
    y444_16be = 87,
    y444_16le = 88,
    p016_be = 89,
    p016_le = 90,
    p012_be = 91,
    p012_le = 92,
    y212_be = 93,
    y212_le = 94,
    y412_be = 95,
    y412_le = 96,
    nv12_4l4 = 97,
    nv12_32l32 = 98,
    rgbp = 99,
    bgrp = 100,
    av12 = 101,
    argb64_le = 102,
    argb64_be = 103,
    rgba64_le = 104,
    rgba64_be = 105,
    bgra64_le = 106,
    bgra64_be = 107,
    abgr64_le = 108,
    abgr64_be = 109,
    nv12_16l32s = 110,
    nv12_8l128 = 111,
    nv12_10be_8l128 = 112,
    nv12_10le40_4l4 = 113,
    dma_drm = 114,
    mt2110t = 115,
    mt2110r = 116,
    a422 = 117,
    a444 = 118,
    a444_12le = 119,
    a444_12be = 120,
    a422_12le = 121,
    a422_12be = 122,
    a420_12le = 123,
    a420_12be = 124,
    a444_16le = 125,
    a444_16be = 126,
    a422_16le = 127,
    a422_16be = 128,
    a420_16le = 129,
    a420_16be = 130,
    gbr_16le = 131,
    gbr_16be = 132,
    rbga = 133,
    y216_le = 134,
    y216_be = 135,
    y416_le = 136,
    y416_be = 137,
    gray10_le16 = 138,
    _,

    /// Converts a FOURCC value into the corresponding `gstvideo.VideoFormat`.
    /// If the FOURCC cannot be represented by `gstvideo.VideoFormat`,
    /// `GST_VIDEO_FORMAT_UNKNOWN` is returned.
    extern fn gst_video_format_from_fourcc(p_fourcc: u32) gstvideo.VideoFormat;
    pub const fromFourcc = gst_video_format_from_fourcc;

    /// Find the `gstvideo.VideoFormat` for the given parameters.
    extern fn gst_video_format_from_masks(p_depth: c_int, p_bpp: c_int, p_endianness: c_int, p_red_mask: c_uint, p_green_mask: c_uint, p_blue_mask: c_uint, p_alpha_mask: c_uint) gstvideo.VideoFormat;
    pub const fromMasks = gst_video_format_from_masks;

    /// Convert the `format` string to its `gstvideo.VideoFormat`.
    extern fn gst_video_format_from_string(p_format: [*:0]const u8) gstvideo.VideoFormat;
    pub const fromString = gst_video_format_from_string;

    /// Get the `gstvideo.VideoFormatInfo` for `format`
    extern fn gst_video_format_get_info(p_format: gstvideo.VideoFormat) *const gstvideo.VideoFormatInfo;
    pub const getInfo = gst_video_format_get_info;

    /// Get the default palette of `format`. This the palette used in the pack
    /// function for paletted formats.
    extern fn gst_video_format_get_palette(p_format: gstvideo.VideoFormat, p_size: *usize) ?*const anyopaque;
    pub const getPalette = gst_video_format_get_palette;

    /// Converts a `gstvideo.VideoFormat` value into the corresponding FOURCC.  Only
    /// a few YUV formats have corresponding FOURCC values.  If `format` has
    /// no corresponding FOURCC value, 0 is returned.
    extern fn gst_video_format_to_fourcc(p_format: gstvideo.VideoFormat) u32;
    pub const toFourcc = gst_video_format_to_fourcc;

    /// Returns a string containing a descriptive name for the `gstvideo.VideoFormat`.
    ///
    /// Since 1.26 this can also be used with `GST_VIDEO_FORMAT_UNKNOWN`, previous
    /// versions were printing a critical warning and returned `NULL`.
    extern fn gst_video_format_to_string(p_format: gstvideo.VideoFormat) [*:0]const u8;
    pub const toString = gst_video_format_to_string;

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

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

/// The orientation of the GL texture.
pub const VideoGLTextureOrientation = enum(c_int) {
    normal_y_normal = 0,
    normal_y_flip = 1,
    flip_y_normal = 2,
    flip_y_flip = 3,
    _,

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

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

/// The GL texture type.
pub const VideoGLTextureType = enum(c_int) {
    luminance = 0,
    luminance_alpha = 1,
    rgb16 = 2,
    rgb = 3,
    rgba = 4,
    r = 5,
    rg = 6,
    _,

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

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

pub const VideoGammaMode = enum(c_int) {
    none = 0,
    remap = 1,
    _,

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

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

/// The possible values of the `gstvideo.VideoInterlaceMode` describing the interlace
/// mode of the stream.
pub const VideoInterlaceMode = enum(c_int) {
    progressive = 0,
    interleaved = 1,
    mixed = 2,
    fields = 3,
    alternate = 4,
    _,

    /// Convert `mode` to a `gstvideo.VideoInterlaceMode`
    extern fn gst_video_interlace_mode_from_string(p_mode: [*:0]const u8) gstvideo.VideoInterlaceMode;
    pub const fromString = gst_video_interlace_mode_from_string;

    /// Convert `mode` to its string representation.
    extern fn gst_video_interlace_mode_to_string(p_mode: gstvideo.VideoInterlaceMode) [*:0]const u8;
    pub const toString = gst_video_interlace_mode_to_string;

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

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

/// Different color matrix conversion modes
pub const VideoMatrixMode = enum(c_int) {
    full = 0,
    input_only = 1,
    output_only = 2,
    none = 3,
    _,

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

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

/// `gstvideo.VideoMultiviewFramePacking` represents the subset of `gstvideo.VideoMultiviewMode`
/// values that can be applied to any video frame without needing extra metadata.
/// It can be used by elements that provide a property to override the
/// multiview interpretation of a video stream when the video doesn't contain
/// any markers.
///
/// This enum is used (for example) on playbin, to re-interpret a played
/// video stream as a stereoscopic video. The individual enum values are
/// equivalent to and have the same value as the matching `gstvideo.VideoMultiviewMode`.
pub const VideoMultiviewFramePacking = enum(c_int) {
    none = -1,
    mono = 0,
    left = 1,
    right = 2,
    side_by_side = 3,
    side_by_side_quincunx = 4,
    column_interleaved = 5,
    row_interleaved = 6,
    top_bottom = 7,
    checkerboard = 8,
    _,

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

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

/// All possible stereoscopic 3D and multiview representations.
/// In conjunction with `gstvideo.VideoMultiviewFlags`, describes how
/// multiview content is being transported in the stream.
pub const VideoMultiviewMode = enum(c_int) {
    none = -1,
    mono = 0,
    left = 1,
    right = 2,
    side_by_side = 3,
    side_by_side_quincunx = 4,
    column_interleaved = 5,
    row_interleaved = 6,
    top_bottom = 7,
    checkerboard = 8,
    frame_by_frame = 32,
    multiview_frame_by_frame = 33,
    separated = 34,
    _,

    extern fn gst_video_multiview_mode_from_caps_string(p_caps_mview_mode: [*:0]const u8) gstvideo.VideoMultiviewMode;
    pub const fromCapsString = gst_video_multiview_mode_from_caps_string;

    /// Given a `gstvideo.VideoMultiviewMode` returns the multiview-mode caps string
    /// for insertion into a caps structure
    extern fn gst_video_multiview_mode_to_caps_string(p_mview_mode: gstvideo.VideoMultiviewMode) ?[*:0]const u8;
    pub const toCapsString = gst_video_multiview_mode_to_caps_string;

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

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

/// The different video orientation methods.
pub const VideoOrientationMethod = enum(c_int) {
    identity = 0,
    @"90r" = 1,
    @"180" = 2,
    @"90l" = 3,
    horiz = 4,
    vert = 5,
    ul_lr = 6,
    ur_ll = 7,
    auto = 8,
    custom = 9,
    _,

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

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

/// Different primaries conversion modes
pub const VideoPrimariesMode = enum(c_int) {
    none = 0,
    merge_only = 1,
    fast = 2,
    _,

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

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

/// Different subsampling and upsampling methods
pub const VideoResamplerMethod = enum(c_int) {
    nearest = 0,
    linear = 1,
    cubic = 2,
    sinc = 3,
    lanczos = 4,
    _,

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

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

/// Enum value describing the available tiling modes.
pub const VideoTileMode = enum(c_int) {
    unknown = 0,
    zflipz_2x2 = 65536,
    linear = 131072,
    _,

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

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

/// Enum value describing the most common tiling types.
pub const VideoTileType = enum(c_int) {
    indexed = 0,
    _,

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

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

/// The video transfer function defines the formula for converting between
/// non-linear RGB (R'G'B') and linear RGB
pub const VideoTransferFunction = enum(c_int) {
    unknown = 0,
    gamma10 = 1,
    gamma18 = 2,
    gamma20 = 3,
    gamma22 = 4,
    bt709 = 5,
    smpte240m = 6,
    srgb = 7,
    gamma28 = 8,
    log100 = 9,
    log316 = 10,
    bt2020_12 = 11,
    adobergb = 12,
    bt2020_10 = 13,
    smpte2084 = 14,
    arib_std_b67 = 15,
    bt601 = 16,
    _,

    /// Convert `val` to its gamma decoded value. This is the inverse operation of
    /// `gstvideo.videoColorTransferEncode`.
    ///
    /// For a non-linear value L' in the range [0..1], conversion to the linear
    /// L is in general performed with a power function like:
    ///
    /// ```
    ///    L = L' ^ gamma
    /// ```
    ///
    /// Depending on `func`, different formulas might be applied. Some formulas
    /// encode a linear segment in the lower range.
    extern fn gst_video_transfer_function_decode(p_func: gstvideo.VideoTransferFunction, p_val: f64) f64;
    pub const decode = gst_video_transfer_function_decode;

    /// Convert `val` to its gamma encoded value.
    ///
    /// For a linear value L in the range [0..1], conversion to the non-linear
    /// (gamma encoded) L' is in general performed with a power function like:
    ///
    /// ```
    ///    L' = L ^ (1 / gamma)
    /// ```
    ///
    /// Depending on `func`, different formulas might be applied. Some formulas
    /// encode a linear segment in the lower range.
    extern fn gst_video_transfer_function_encode(p_func: gstvideo.VideoTransferFunction, p_val: f64) f64;
    pub const encode = gst_video_transfer_function_encode;

    /// Converts the `value` to the `gstvideo.VideoTransferFunction`
    /// The transfer characteristics (TransferCharacteristics) value is
    /// defined by "ISO/IEC 23001-8 Section 7.2 Table 3"
    /// and "ITU-T H.273 Table 3".
    /// "H.264 Table E-4" and "H.265 Table E.4" share the identical values.
    extern fn gst_video_transfer_function_from_iso(p_value: c_uint) gstvideo.VideoTransferFunction;
    pub const fromIso = gst_video_transfer_function_from_iso;

    /// Returns whether `from_func` and `to_func` are equivalent. There are cases
    /// (e.g. BT601, BT709, and BT2020_10) where several functions are functionally
    /// identical. In these cases, when doing conversion, we should consider them
    /// as equivalent. Also, BT2020_12 is the same as the aforementioned three for
    /// less than 12 bits per pixel.
    extern fn gst_video_transfer_function_is_equivalent(p_from_func: gstvideo.VideoTransferFunction, p_from_bpp: c_uint, p_to_func: gstvideo.VideoTransferFunction, p_to_bpp: c_uint) c_int;
    pub const isEquivalent = gst_video_transfer_function_is_equivalent;

    /// Converts `gstvideo.VideoTransferFunction` to the "transfer characteristics"
    /// (TransferCharacteristics) value defined by "ISO/IEC 23001-8 Section 7.2 Table 3"
    /// and "ITU-T H.273 Table 3".
    /// "H.264 Table E-4" and "H.265 Table E.4" share the identical values.
    extern fn gst_video_transfer_function_to_iso(p_func: gstvideo.VideoTransferFunction) c_uint;
    pub const toIso = gst_video_transfer_function_to_iso;

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

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

/// Return values for `gstvideo.VideoVBIParser`
pub const VideoVBIParserResult = enum(c_int) {
    done = 0,
    ok = 1,
    @"error" = 2,
    _,

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

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

/// Flags to indicate the state of modifier keys and mouse buttons
/// in events.
///
/// Typical modifier keys are Shift, Control, Meta, Super, Hyper, Alt, Compose,
/// Apple, CapsLock or ShiftLock.
pub const NavigationModifierType = packed struct(c_uint) {
    shift_mask: bool = false,
    lock_mask: bool = false,
    control_mask: bool = false,
    mod1_mask: bool = false,
    mod2_mask: bool = false,
    mod3_mask: bool = false,
    mod4_mask: bool = false,
    mod5_mask: bool = false,
    button1_mask: bool = false,
    button2_mask: bool = false,
    button3_mask: bool = false,
    button4_mask: bool = false,
    button5_mask: 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,
    super_mask: bool = false,
    hyper_mask: bool = false,
    meta_mask: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_none: NavigationModifierType = @bitCast(@as(c_uint, 0));
    pub const flags_shift_mask: NavigationModifierType = @bitCast(@as(c_uint, 1));
    pub const flags_lock_mask: NavigationModifierType = @bitCast(@as(c_uint, 2));
    pub const flags_control_mask: NavigationModifierType = @bitCast(@as(c_uint, 4));
    pub const flags_mod1_mask: NavigationModifierType = @bitCast(@as(c_uint, 8));
    pub const flags_mod2_mask: NavigationModifierType = @bitCast(@as(c_uint, 16));
    pub const flags_mod3_mask: NavigationModifierType = @bitCast(@as(c_uint, 32));
    pub const flags_mod4_mask: NavigationModifierType = @bitCast(@as(c_uint, 64));
    pub const flags_mod5_mask: NavigationModifierType = @bitCast(@as(c_uint, 128));
    pub const flags_button1_mask: NavigationModifierType = @bitCast(@as(c_uint, 256));
    pub const flags_button2_mask: NavigationModifierType = @bitCast(@as(c_uint, 512));
    pub const flags_button3_mask: NavigationModifierType = @bitCast(@as(c_uint, 1024));
    pub const flags_button4_mask: NavigationModifierType = @bitCast(@as(c_uint, 2048));
    pub const flags_button5_mask: NavigationModifierType = @bitCast(@as(c_uint, 4096));
    pub const flags_super_mask: NavigationModifierType = @bitCast(@as(c_uint, 67108864));
    pub const flags_hyper_mask: NavigationModifierType = @bitCast(@as(c_uint, 134217728));
    pub const flags_meta_mask: NavigationModifierType = @bitCast(@as(c_uint, 268435456));
    pub const flags_mask: NavigationModifierType = @bitCast(@as(c_uint, 469770239));
    extern fn gst_navigation_modifier_type_get_type() usize;
    pub const getGObjectType = gst_navigation_modifier_type_get_type;

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

/// Additional video buffer flags. These flags can potentially be used on any
/// buffers carrying closed caption data, or video data - even encoded data.
///
/// Note that these are only valid for `gst.Caps` of type: video/... and caption/...
/// They can conflict with other extended buffer flags.
pub const VideoBufferFlags = 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,
    marker: 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,
    interlaced: bool = false,
    tff: bool = false,
    rff: bool = false,
    onefield: bool = false,
    multiple_view: bool = false,
    first_in_bundle: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    last: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_interlaced: VideoBufferFlags = @bitCast(@as(c_uint, 1048576));
    pub const flags_tff: VideoBufferFlags = @bitCast(@as(c_uint, 2097152));
    pub const flags_rff: VideoBufferFlags = @bitCast(@as(c_uint, 4194304));
    pub const flags_onefield: VideoBufferFlags = @bitCast(@as(c_uint, 8388608));
    pub const flags_multiple_view: VideoBufferFlags = @bitCast(@as(c_uint, 16777216));
    pub const flags_first_in_bundle: VideoBufferFlags = @bitCast(@as(c_uint, 33554432));
    pub const flags_top_field: VideoBufferFlags = @bitCast(@as(c_uint, 10485760));
    pub const flags_bottom_field: VideoBufferFlags = @bitCast(@as(c_uint, 8388608));
    pub const flags_marker: VideoBufferFlags = @bitCast(@as(c_uint, 512));
    pub const flags_last: VideoBufferFlags = @bitCast(@as(c_uint, 268435456));
    extern fn gst_video_buffer_flags_get_type() usize;
    pub const getGObjectType = gst_video_buffer_flags_get_type;

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

/// Extra flags that influence the result from `gstvideo.videoChromaResampleNew`.
pub const VideoChromaFlags = packed struct(c_uint) {
    interlaced: 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: VideoChromaFlags = @bitCast(@as(c_uint, 0));
    pub const flags_interlaced: VideoChromaFlags = @bitCast(@as(c_uint, 1));
    extern fn gst_video_chroma_flags_get_type() usize;
    pub const getGObjectType = gst_video_chroma_flags_get_type;

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

/// Various Chroma sitings.
pub const VideoChromaSite = packed struct(c_uint) {
    none: bool = false,
    h_cosited: bool = false,
    v_cosited: bool = false,
    alt_line: 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_unknown: VideoChromaSite = @bitCast(@as(c_uint, 0));
    pub const flags_none: VideoChromaSite = @bitCast(@as(c_uint, 1));
    pub const flags_h_cosited: VideoChromaSite = @bitCast(@as(c_uint, 2));
    pub const flags_v_cosited: VideoChromaSite = @bitCast(@as(c_uint, 4));
    pub const flags_alt_line: VideoChromaSite = @bitCast(@as(c_uint, 8));
    pub const flags_cosited: VideoChromaSite = @bitCast(@as(c_uint, 6));
    pub const flags_jpeg: VideoChromaSite = @bitCast(@as(c_uint, 1));
    pub const flags_mpeg2: VideoChromaSite = @bitCast(@as(c_uint, 2));
    pub const flags_dv: VideoChromaSite = @bitCast(@as(c_uint, 14));
    /// Convert `s` to a `gstvideo.VideoChromaSite`
    extern fn gst_video_chroma_site_from_string(p_s: [*:0]const u8) gstvideo.VideoChromaSite;
    pub const fromString = gst_video_chroma_site_from_string;

    /// Converts `site` to its string representation.
    extern fn gst_video_chroma_site_to_string(p_site: gstvideo.VideoChromaSite) ?[*:0]u8;
    pub const toString = gst_video_chroma_site_to_string;

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

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

/// Flags for `gstvideo.VideoCodecFrame`
pub const VideoCodecFrameFlags = packed struct(c_uint) {
    decode_only: bool = false,
    sync_point: bool = false,
    force_keyframe: bool = false,
    force_keyframe_headers: bool = false,
    corrupted: 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_decode_only: VideoCodecFrameFlags = @bitCast(@as(c_uint, 1));
    pub const flags_sync_point: VideoCodecFrameFlags = @bitCast(@as(c_uint, 2));
    pub const flags_force_keyframe: VideoCodecFrameFlags = @bitCast(@as(c_uint, 4));
    pub const flags_force_keyframe_headers: VideoCodecFrameFlags = @bitCast(@as(c_uint, 8));
    pub const flags_corrupted: VideoCodecFrameFlags = @bitCast(@as(c_uint, 16));
    extern fn gst_video_codec_frame_flags_get_type() usize;
    pub const getGObjectType = gst_video_codec_frame_flags_get_type;

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

/// Flags to be used in combination with `gstvideo.VideoDecoder.requestSyncPoint`.
/// See the function documentation for more details.
pub const VideoDecoderRequestSyncPointFlags = packed struct(c_uint) {
    discard_input: bool = false,
    corrupt_output: 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_discard_input: VideoDecoderRequestSyncPointFlags = @bitCast(@as(c_uint, 1));
    pub const flags_corrupt_output: VideoDecoderRequestSyncPointFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_video_decoder_request_sync_point_flags_get_type() usize;
    pub const getGObjectType = gst_video_decoder_request_sync_point_flags_get_type;

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

/// Extra flags that influence the result from `gstvideo.videoChromaResampleNew`.
pub const VideoDitherFlags = packed struct(c_uint) {
    interlaced: bool = false,
    quantize: 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: VideoDitherFlags = @bitCast(@as(c_uint, 0));
    pub const flags_interlaced: VideoDitherFlags = @bitCast(@as(c_uint, 1));
    pub const flags_quantize: VideoDitherFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_video_dither_flags_get_type() usize;
    pub const getGObjectType = gst_video_dither_flags_get_type;

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

/// Extra video flags
pub const VideoFlags = packed struct(c_uint) {
    variable_fps: bool = false,
    premultiplied_alpha: 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: VideoFlags = @bitCast(@as(c_uint, 0));
    pub const flags_variable_fps: VideoFlags = @bitCast(@as(c_uint, 1));
    pub const flags_premultiplied_alpha: VideoFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_video_flags_get_type() usize;
    pub const getGObjectType = gst_video_flags_get_type;

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

/// The different video flags that a format info can have.
pub const VideoFormatFlags = packed struct(c_uint) {
    yuv: bool = false,
    rgb: bool = false,
    gray: bool = false,
    alpha: bool = false,
    le: bool = false,
    palette: bool = false,
    complex: bool = false,
    unpack: bool = false,
    tiled: bool = false,
    subtiles: 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_yuv: VideoFormatFlags = @bitCast(@as(c_uint, 1));
    pub const flags_rgb: VideoFormatFlags = @bitCast(@as(c_uint, 2));
    pub const flags_gray: VideoFormatFlags = @bitCast(@as(c_uint, 4));
    pub const flags_alpha: VideoFormatFlags = @bitCast(@as(c_uint, 8));
    pub const flags_le: VideoFormatFlags = @bitCast(@as(c_uint, 16));
    pub const flags_palette: VideoFormatFlags = @bitCast(@as(c_uint, 32));
    pub const flags_complex: VideoFormatFlags = @bitCast(@as(c_uint, 64));
    pub const flags_unpack: VideoFormatFlags = @bitCast(@as(c_uint, 128));
    pub const flags_tiled: VideoFormatFlags = @bitCast(@as(c_uint, 256));
    pub const flags_subtiles: VideoFormatFlags = @bitCast(@as(c_uint, 512));
    extern fn gst_video_format_flags_get_type() usize;
    pub const getGObjectType = gst_video_format_flags_get_type;

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

/// Extra video frame flags
pub const VideoFrameFlags = packed struct(c_uint) {
    interlaced: bool = false,
    tff: bool = false,
    rff: bool = false,
    onefield: bool = false,
    multiple_view: bool = false,
    first_in_bundle: 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: VideoFrameFlags = @bitCast(@as(c_uint, 0));
    pub const flags_interlaced: VideoFrameFlags = @bitCast(@as(c_uint, 1));
    pub const flags_tff: VideoFrameFlags = @bitCast(@as(c_uint, 2));
    pub const flags_rff: VideoFrameFlags = @bitCast(@as(c_uint, 4));
    pub const flags_onefield: VideoFrameFlags = @bitCast(@as(c_uint, 8));
    pub const flags_multiple_view: VideoFrameFlags = @bitCast(@as(c_uint, 16));
    pub const flags_first_in_bundle: VideoFrameFlags = @bitCast(@as(c_uint, 32));
    pub const flags_top_field: VideoFrameFlags = @bitCast(@as(c_uint, 10));
    pub const flags_bottom_field: VideoFrameFlags = @bitCast(@as(c_uint, 8));
    extern fn gst_video_frame_flags_get_type() usize;
    pub const getGObjectType = gst_video_frame_flags_get_type;

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

/// Additional mapping flags for `gstvideo.videoFrameMap`.
pub const VideoFrameMapFlags = 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,
    no_ref: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    last: 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_ref: VideoFrameMapFlags = @bitCast(@as(c_uint, 65536));
    pub const flags_last: VideoFrameMapFlags = @bitCast(@as(c_uint, 16777216));
    extern fn gst_video_frame_map_flags_get_type() usize;
    pub const getGObjectType = gst_video_frame_map_flags_get_type;

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

/// GstVideoMultiviewFlags are used to indicate extra properties of a
/// stereo/multiview stream beyond the frame layout and buffer mapping
/// that is conveyed in the `gstvideo.VideoMultiviewMode`.
pub const VideoMultiviewFlags = packed struct(c_uint) {
    right_view_first: bool = false,
    left_flipped: bool = false,
    left_flopped: bool = false,
    right_flipped: bool = false,
    right_flopped: 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,
    half_aspect: bool = false,
    mixed_mono: 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: VideoMultiviewFlags = @bitCast(@as(c_uint, 0));
    pub const flags_right_view_first: VideoMultiviewFlags = @bitCast(@as(c_uint, 1));
    pub const flags_left_flipped: VideoMultiviewFlags = @bitCast(@as(c_uint, 2));
    pub const flags_left_flopped: VideoMultiviewFlags = @bitCast(@as(c_uint, 4));
    pub const flags_right_flipped: VideoMultiviewFlags = @bitCast(@as(c_uint, 8));
    pub const flags_right_flopped: VideoMultiviewFlags = @bitCast(@as(c_uint, 16));
    pub const flags_half_aspect: VideoMultiviewFlags = @bitCast(@as(c_uint, 16384));
    pub const flags_mixed_mono: VideoMultiviewFlags = @bitCast(@as(c_uint, 32768));
    extern fn gst_video_multiview_flags_get_type() usize;
    pub const getGObjectType = gst_video_multiview_flags_get_type;

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

/// Overlay format flags.
pub const VideoOverlayFormatFlags = packed struct(c_uint) {
    premultiplied_alpha: bool = false,
    global_alpha: 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: VideoOverlayFormatFlags = @bitCast(@as(c_uint, 0));
    pub const flags_premultiplied_alpha: VideoOverlayFormatFlags = @bitCast(@as(c_uint, 1));
    pub const flags_global_alpha: VideoOverlayFormatFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_video_overlay_format_flags_get_type() usize;
    pub const getGObjectType = gst_video_overlay_format_flags_get_type;

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

/// The different flags that can be used when packing and unpacking.
pub const VideoPackFlags = packed struct(c_uint) {
    truncate_range: bool = false,
    interlaced: 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: VideoPackFlags = @bitCast(@as(c_uint, 0));
    pub const flags_truncate_range: VideoPackFlags = @bitCast(@as(c_uint, 1));
    pub const flags_interlaced: VideoPackFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_video_pack_flags_get_type() usize;
    pub const getGObjectType = gst_video_pack_flags_get_type;

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

/// Different resampler flags.
pub const VideoResamplerFlags = packed struct(c_uint) {
    half_taps: 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: VideoResamplerFlags = @bitCast(@as(c_uint, 0));
    pub const flags_half_taps: VideoResamplerFlags = @bitCast(@as(c_uint, 1));
    extern fn gst_video_resampler_flags_get_type() usize;
    pub const getGObjectType = gst_video_resampler_flags_get_type;

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

/// Different scale flags.
pub const VideoScalerFlags = packed struct(c_uint) {
    interlaced: 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: VideoScalerFlags = @bitCast(@as(c_uint, 0));
    pub const flags_interlaced: VideoScalerFlags = @bitCast(@as(c_uint, 1));
    extern fn gst_video_scaler_flags_get_type() usize;
    pub const getGObjectType = gst_video_scaler_flags_get_type;

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

/// Flags related to the time code information.
/// For drop frame, only 30000/1001 and 60000/1001 frame rates are supported.
pub const VideoTimeCodeFlags = packed struct(c_uint) {
    drop_frame: bool = false,
    interlaced: 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: VideoTimeCodeFlags = @bitCast(@as(c_uint, 0));
    pub const flags_drop_frame: VideoTimeCodeFlags = @bitCast(@as(c_uint, 1));
    pub const flags_interlaced: VideoTimeCodeFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_video_time_code_flags_get_type() usize;
    pub const getGObjectType = gst_video_time_code_flags_get_type;

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

extern fn gst_ancillary_meta_api_get_type() usize;
pub const ancillaryMetaApiGetType = gst_ancillary_meta_api_get_type;

/// Adds a new `gstvideo.AncillaryMeta` to the `buffer`. The caller is responsible for setting the appropriate
/// fields.
extern fn gst_buffer_add_ancillary_meta(p_buffer: *gst.Buffer) *gstvideo.AncillaryMeta;
pub const bufferAddAncillaryMeta = gst_buffer_add_ancillary_meta;

/// Attaches `gstvideo.VideoAFDMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_afd_meta(p_buffer: *gst.Buffer, p_field: u8, p_spec: gstvideo.VideoAFDSpec, p_afd: gstvideo.VideoAFDValue) *gstvideo.VideoAFDMeta;
pub const bufferAddVideoAfdMeta = gst_buffer_add_video_afd_meta;

/// Attaches GstVideoAffineTransformationMeta metadata to `buffer` with
/// the given parameters.
extern fn gst_buffer_add_video_affine_transformation_meta(p_buffer: *gst.Buffer) *gstvideo.VideoAffineTransformationMeta;
pub const bufferAddVideoAffineTransformationMeta = gst_buffer_add_video_affine_transformation_meta;

/// Attaches `gstvideo.VideoBarMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_bar_meta(p_buffer: *gst.Buffer, p_field: u8, p_is_letterbox: c_int, p_bar_data1: c_uint, p_bar_data2: c_uint) *gstvideo.VideoBarMeta;
pub const bufferAddVideoBarMeta = gst_buffer_add_video_bar_meta;

/// Attaches `gstvideo.VideoCaptionMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_caption_meta(p_buffer: *gst.Buffer, p_caption_type: gstvideo.VideoCaptionType, p_data: [*]const u8, p_size: usize) *gstvideo.VideoCaptionMeta;
pub const bufferAddVideoCaptionMeta = gst_buffer_add_video_caption_meta;

/// Attaches a `gstvideo.VideoCodecAlphaMeta` metadata to `buffer` with
/// the given alpha buffer.
extern fn gst_buffer_add_video_codec_alpha_meta(p_buffer: *gst.Buffer, p_alpha_buffer: *gst.Buffer) *gstvideo.VideoCodecAlphaMeta;
pub const bufferAddVideoCodecAlphaMeta = gst_buffer_add_video_codec_alpha_meta;

/// Attaches GstVideoGLTextureUploadMeta metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_gl_texture_upload_meta(p_buffer: *gst.Buffer, p_texture_orientation: gstvideo.VideoGLTextureOrientation, p_n_textures: c_uint, p_texture_type: *gstvideo.VideoGLTextureType, p_upload: gstvideo.VideoGLTextureUpload, p_user_data: ?*anyopaque, p_user_data_copy: gobject.BoxedCopyFunc, p_user_data_free: gobject.BoxedFreeFunc) *gstvideo.VideoGLTextureUploadMeta;
pub const bufferAddVideoGlTextureUploadMeta = gst_buffer_add_video_gl_texture_upload_meta;

/// Attaches GstVideoMeta metadata to `buffer` with the given parameters and the
/// default offsets and strides for `format` and `width` x `height`.
///
/// This function calculates the default offsets and strides and then calls
/// `gstvideo.bufferAddVideoMetaFull` with them.
extern fn gst_buffer_add_video_meta(p_buffer: *gst.Buffer, p_flags: gstvideo.VideoFrameFlags, p_format: gstvideo.VideoFormat, p_width: c_uint, p_height: c_uint) *gstvideo.VideoMeta;
pub const bufferAddVideoMeta = gst_buffer_add_video_meta;

/// Attaches GstVideoMeta metadata to `buffer` with the given parameters.
extern fn gst_buffer_add_video_meta_full(p_buffer: *gst.Buffer, p_flags: gstvideo.VideoFrameFlags, p_format: gstvideo.VideoFormat, p_width: c_uint, p_height: c_uint, p_n_planes: c_uint, p_offset: *const [4]usize, p_stride: *const [4]c_int) *gstvideo.VideoMeta;
pub const bufferAddVideoMetaFull = gst_buffer_add_video_meta_full;

/// Sets an overlay composition on a buffer. The buffer will obtain its own
/// reference to the composition, meaning this function does not take ownership
/// of `comp`.
extern fn gst_buffer_add_video_overlay_composition_meta(p_buf: *gst.Buffer, p_comp: ?*gstvideo.VideoOverlayComposition) *gstvideo.VideoOverlayCompositionMeta;
pub const bufferAddVideoOverlayCompositionMeta = gst_buffer_add_video_overlay_composition_meta;

/// Attaches `gstvideo.VideoRegionOfInterestMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_region_of_interest_meta(p_buffer: *gst.Buffer, p_roi_type: [*:0]const u8, p_x: c_uint, p_y: c_uint, p_w: c_uint, p_h: c_uint) *gstvideo.VideoRegionOfInterestMeta;
pub const bufferAddVideoRegionOfInterestMeta = gst_buffer_add_video_region_of_interest_meta;

/// Attaches `gstvideo.VideoRegionOfInterestMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_region_of_interest_meta_id(p_buffer: *gst.Buffer, p_roi_type: glib.Quark, p_x: c_uint, p_y: c_uint, p_w: c_uint, p_h: c_uint) *gstvideo.VideoRegionOfInterestMeta;
pub const bufferAddVideoRegionOfInterestMetaId = gst_buffer_add_video_region_of_interest_meta_id;

/// Attaches `gstvideo.VideoSEIUserDataUnregisteredMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_sei_user_data_unregistered_meta(p_buffer: *gst.Buffer, p_uuid: *u8, p_data: ?*u8, p_size: usize) *gstvideo.VideoSEIUserDataUnregisteredMeta;
pub const bufferAddVideoSeiUserDataUnregisteredMeta = gst_buffer_add_video_sei_user_data_unregistered_meta;

/// Attaches `gstvideo.VideoTimeCodeMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_time_code_meta(p_buffer: *gst.Buffer, p_tc: *const gstvideo.VideoTimeCode) ?*gstvideo.VideoTimeCodeMeta;
pub const bufferAddVideoTimeCodeMeta = gst_buffer_add_video_time_code_meta;

/// Attaches `gstvideo.VideoTimeCodeMeta` metadata to `buffer` with the given
/// parameters.
extern fn gst_buffer_add_video_time_code_meta_full(p_buffer: *gst.Buffer, p_fps_n: c_uint, p_fps_d: c_uint, p_latest_daily_jam: *glib.DateTime, p_flags: gstvideo.VideoTimeCodeFlags, p_hours: c_uint, p_minutes: c_uint, p_seconds: c_uint, p_frames: c_uint, p_field_count: c_uint) ?*gstvideo.VideoTimeCodeMeta;
pub const bufferAddVideoTimeCodeMetaFull = gst_buffer_add_video_time_code_meta_full;

/// Find the `gstvideo.VideoMeta` on `buffer` with the lowest `id`.
///
/// Buffers can contain multiple `gstvideo.VideoMeta` metadata items when dealing with
/// multiview buffers.
extern fn gst_buffer_get_video_meta(p_buffer: *gst.Buffer) ?*gstvideo.VideoMeta;
pub const bufferGetVideoMeta = gst_buffer_get_video_meta;

/// Find the `gstvideo.VideoMeta` on `buffer` with the given `id`.
///
/// Buffers can contain multiple `gstvideo.VideoMeta` metadata items when dealing with
/// multiview buffers.
extern fn gst_buffer_get_video_meta_id(p_buffer: *gst.Buffer, p_id: c_int) ?*gstvideo.VideoMeta;
pub const bufferGetVideoMetaId = gst_buffer_get_video_meta_id;

/// Find the `gstvideo.VideoRegionOfInterestMeta` on `buffer` with the given `id`.
///
/// Buffers can contain multiple `gstvideo.VideoRegionOfInterestMeta` metadata items if
/// multiple regions of interests are marked on a frame.
extern fn gst_buffer_get_video_region_of_interest_meta_id(p_buffer: *gst.Buffer, p_id: c_int) ?*gstvideo.VideoRegionOfInterestMeta;
pub const bufferGetVideoRegionOfInterestMetaId = gst_buffer_get_video_region_of_interest_meta_id;

/// Get the video alignment from the bufferpool configuration `config` in
/// in `align`
extern fn gst_buffer_pool_config_get_video_alignment(p_config: *const gst.Structure, p_align: *gstvideo.VideoAlignment) c_int;
pub const bufferPoolConfigGetVideoAlignment = gst_buffer_pool_config_get_video_alignment;

/// Set the video alignment in `align` to the bufferpool configuration
/// `config`
extern fn gst_buffer_pool_config_set_video_alignment(p_config: *gst.Structure, p_align: *const gstvideo.VideoAlignment) void;
pub const bufferPoolConfigSetVideoAlignment = gst_buffer_pool_config_set_video_alignment;

/// Convenience function to check if the given message is a
/// "prepare-window-handle" message from a `gstvideo.VideoOverlay`.
extern fn gst_is_video_overlay_prepare_window_handle_message(p_msg: *gst.Message) c_int;
pub const isVideoOverlayPrepareWindowHandleMessage = gst_is_video_overlay_prepare_window_handle_message;

extern fn gst_video_afd_meta_api_get_type() usize;
pub const videoAfdMetaApiGetType = gst_video_afd_meta_api_get_type;

extern fn gst_video_affine_transformation_meta_api_get_type() usize;
pub const videoAffineTransformationMetaApiGetType = gst_video_affine_transformation_meta_api_get_type;

extern fn gst_video_bar_meta_api_get_type() usize;
pub const videoBarMetaApiGetType = gst_video_bar_meta_api_get_type;

/// Lets you blend the `src` image into the `dest` image
extern fn gst_video_blend(p_dest: *gstvideo.VideoFrame, p_src: *gstvideo.VideoFrame, p_x: c_int, p_y: c_int, p_global_alpha: f32) c_int;
pub const videoBlend = gst_video_blend;

/// Scales a buffer containing RGBA (or AYUV) video. This is an internal
/// helper function which is used to scale subtitle overlays, and may be
/// deprecated in the near future. Use `gstvideo.VideoScaler` to scale video buffers
/// instead.
extern fn gst_video_blend_scale_linear_RGBA(p_src: *gstvideo.VideoInfo, p_src_buffer: *gst.Buffer, p_dest_height: c_int, p_dest_width: c_int, p_dest: *gstvideo.VideoInfo, p_dest_buffer: **gst.Buffer) void;
pub const videoBlendScaleLinearRGBA = gst_video_blend_scale_linear_RGBA;

/// Given the Pixel Aspect Ratio and size of an input video frame, and the
/// pixel aspect ratio of the intended display device, calculates the actual
/// display ratio the video will be rendered with.
extern fn gst_video_calculate_display_ratio(p_dar_n: *c_uint, p_dar_d: *c_uint, p_video_width: c_uint, p_video_height: c_uint, p_video_par_n: c_uint, p_video_par_d: c_uint, p_display_par_n: c_uint, p_display_par_d: c_uint) c_int;
pub const videoCalculateDisplayRatio = gst_video_calculate_display_ratio;

extern fn gst_video_caption_meta_api_get_type() usize;
pub const videoCaptionMetaApiGetType = gst_video_caption_meta_api_get_type;

/// Takes `src` rectangle and position it at the center of `dst` rectangle with or
/// without `scaling`. It handles clipping if the `src` rectangle is bigger than
/// the `dst` one and `scaling` is set to FALSE.
extern fn gst_video_center_rect(p_src: *const gstvideo.VideoRectangle, p_dst: *const gstvideo.VideoRectangle, p_result: *gstvideo.VideoRectangle, p_scaling: c_int) void;
pub const videoCenterRect = gst_video_center_rect;

/// Convert `s` to a `gstvideo.VideoChromaSite`
extern fn gst_video_chroma_from_string(p_s: [*:0]const u8) gstvideo.VideoChromaSite;
pub const videoChromaFromString = gst_video_chroma_from_string;

/// Perform resampling of `width` chroma pixels in `lines`.
extern fn gst_video_chroma_resample(p_resample: *gstvideo.VideoChromaResample, p_lines: ?*anyopaque, p_width: c_int) void;
pub const videoChromaResample = gst_video_chroma_resample;

/// Converts `site` to its string representation.
extern fn gst_video_chroma_to_string(p_site: gstvideo.VideoChromaSite) [*:0]const u8;
pub const videoChromaToString = gst_video_chroma_to_string;

extern fn gst_video_codec_alpha_meta_api_get_type() usize;
pub const videoCodecAlphaMetaApiGetType = gst_video_codec_alpha_meta_api_get_type;

extern fn gst_video_color_transfer_decode(p_func: gstvideo.VideoTransferFunction, p_val: f64) f64;
pub const videoColorTransferDecode = gst_video_color_transfer_decode;

extern fn gst_video_color_transfer_encode(p_func: gstvideo.VideoTransferFunction, p_val: f64) f64;
pub const videoColorTransferEncode = gst_video_color_transfer_encode;

/// Converts a raw video buffer into the specified output caps.
///
/// The output caps can be any raw video formats or any image formats (jpeg, png, ...).
///
/// The width, height and pixel-aspect-ratio can also be specified in the output caps.
extern fn gst_video_convert_sample(p_sample: *gst.Sample, p_to_caps: *const gst.Caps, p_timeout: gst.ClockTime, p_error: ?*?*glib.Error) ?*gst.Sample;
pub const videoConvertSample = gst_video_convert_sample;

/// Converts a raw video buffer into the specified output caps.
///
/// The output caps can be any raw video formats or any image formats (jpeg, png, ...).
///
/// The width, height and pixel-aspect-ratio can also be specified in the output caps.
///
/// `callback` will be called after conversion, when an error occurred or if conversion didn't
/// finish after `timeout`. `callback` will always be called from the thread default
/// `glib.MainContext`, see `glib.mainContextGetThreadDefault`. If GLib before 2.22 is used,
/// this will always be the global default main context.
///
/// `destroy_notify` will be called after the callback was called and `user_data` is not needed
/// anymore.
extern fn gst_video_convert_sample_async(p_sample: *gst.Sample, p_to_caps: *const gst.Caps, p_timeout: gst.ClockTime, p_callback: gstvideo.VideoConvertSampleCallback, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
pub const videoConvertSampleAsync = gst_video_convert_sample_async;

extern fn gst_video_crop_meta_api_get_type() usize;
pub const videoCropMetaApiGetType = gst_video_crop_meta_api_get_type;

/// Converting the video format into dma drm fourcc/modifier pair.
/// If no matching fourcc found, then DRM_FORMAT_INVALID is returned
/// and `modifier` will be set to DRM_FORMAT_MOD_INVALID.
extern fn gst_video_dma_drm_format_from_gst_format(p_format: gstvideo.VideoFormat, p_modifier: ?*u64) u32;
pub const videoDmaDrmFormatFromGstFormat = gst_video_dma_drm_format_from_gst_format;

/// Converting a dma drm fourcc and modifier pair into a `gstvideo.VideoFormat`. If
/// no matching video format is found, then GST_VIDEO_FORMAT_UNKNOWN is returned.
extern fn gst_video_dma_drm_format_to_gst_format(p_fourcc: u32, p_modifier: u64) gstvideo.VideoFormat;
pub const videoDmaDrmFormatToGstFormat = gst_video_dma_drm_format_to_gst_format;

/// Converting the video format into dma drm fourcc. If no
/// matching fourcc found, then DRM_FORMAT_INVALID is returned.
extern fn gst_video_dma_drm_fourcc_from_format(p_format: gstvideo.VideoFormat) u32;
pub const videoDmaDrmFourccFromFormat = gst_video_dma_drm_fourcc_from_format;

/// Convert the `format_str` string into the drm fourcc value. The `modifier` is
/// also parsed if we want. Please note that the `format_str` should follow the
/// fourcc:modifier kind style, such as NV12:0x0100000000000002
extern fn gst_video_dma_drm_fourcc_from_string(p_format_str: [*:0]const u8, p_modifier: ?*u64) u32;
pub const videoDmaDrmFourccFromString = gst_video_dma_drm_fourcc_from_string;

/// Converting a dma drm fourcc into the video format. If no matching
/// video format found, then GST_VIDEO_FORMAT_UNKNOWN is returned.
extern fn gst_video_dma_drm_fourcc_to_format(p_fourcc: u32) gstvideo.VideoFormat;
pub const videoDmaDrmFourccToFormat = gst_video_dma_drm_fourcc_to_format;

/// Returns a string containing drm kind format, such as
/// NV12:0x0100000000000002, or NULL otherwise.
extern fn gst_video_dma_drm_fourcc_to_string(p_fourcc: u32, p_modifier: u64) ?[*:0]u8;
pub const videoDmaDrmFourccToString = gst_video_dma_drm_fourcc_to_string;

/// Checks if an event is a force key unit event. Returns true for both upstream
/// and downstream force key unit events.
extern fn gst_video_event_is_force_key_unit(p_event: *gst.Event) c_int;
pub const videoEventIsForceKeyUnit = gst_video_event_is_force_key_unit;

/// Creates a new downstream force key unit event. A downstream force key unit
/// event can be sent down the pipeline to request downstream elements to produce
/// a key unit. A downstream force key unit event must also be sent when handling
/// an upstream force key unit event to notify downstream that the latter has been
/// handled.
///
/// To parse an event created by `gstvideo.videoEventNewDownstreamForceKeyUnit` use
/// `gstvideo.videoEventParseDownstreamForceKeyUnit`.
extern fn gst_video_event_new_downstream_force_key_unit(p_timestamp: gst.ClockTime, p_stream_time: gst.ClockTime, p_running_time: gst.ClockTime, p_all_headers: c_int, p_count: c_uint) *gst.Event;
pub const videoEventNewDownstreamForceKeyUnit = gst_video_event_new_downstream_force_key_unit;

/// Creates a new Still Frame event. If `in_still` is `TRUE`, then the event
/// represents the start of a still frame sequence. If it is `FALSE`, then
/// the event ends a still frame sequence.
///
/// To parse an event created by `gstvideo.videoEventNewStillFrame` use
/// `gstvideo.videoEventParseStillFrame`.
extern fn gst_video_event_new_still_frame(p_in_still: c_int) *gst.Event;
pub const videoEventNewStillFrame = gst_video_event_new_still_frame;

/// Creates a new upstream force key unit event. An upstream force key unit event
/// can be sent to request upstream elements to produce a key unit.
///
/// `running_time` can be set to request a new key unit at a specific
/// running_time. If set to GST_CLOCK_TIME_NONE, upstream elements will produce a
/// new key unit as soon as possible.
///
/// To parse an event created by `gstvideo.videoEventNewDownstreamForceKeyUnit` use
/// `gstvideo.videoEventParseDownstreamForceKeyUnit`.
extern fn gst_video_event_new_upstream_force_key_unit(p_running_time: gst.ClockTime, p_all_headers: c_int, p_count: c_uint) *gst.Event;
pub const videoEventNewUpstreamForceKeyUnit = gst_video_event_new_upstream_force_key_unit;

/// Get timestamp, stream-time, running-time, all-headers and count in the force
/// key unit event. See `gstvideo.videoEventNewDownstreamForceKeyUnit` for a
/// full description of the downstream force key unit event.
///
/// `running_time` will be adjusted for any pad offsets of pads it was passing through.
extern fn gst_video_event_parse_downstream_force_key_unit(p_event: *gst.Event, p_timestamp: *gst.ClockTime, p_stream_time: *gst.ClockTime, p_running_time: *gst.ClockTime, p_all_headers: *c_int, p_count: *c_uint) c_int;
pub const videoEventParseDownstreamForceKeyUnit = gst_video_event_parse_downstream_force_key_unit;

/// Parse a `gst.Event`, identify if it is a Still Frame event, and
/// return the still-frame state from the event if it is.
/// If the event represents the start of a still frame, the in_still
/// variable will be set to TRUE, otherwise FALSE. It is OK to pass NULL for the
/// in_still variable order to just check whether the event is a valid still-frame
/// event.
///
/// Create a still frame event using `gstvideo.videoEventNewStillFrame`
extern fn gst_video_event_parse_still_frame(p_event: *gst.Event, p_in_still: *c_int) c_int;
pub const videoEventParseStillFrame = gst_video_event_parse_still_frame;

/// Get running-time, all-headers and count in the force key unit event. See
/// `gstvideo.videoEventNewUpstreamForceKeyUnit` for a full description of the
/// upstream force key unit event.
///
/// Create an upstream force key unit event using  `gstvideo.videoEventNewUpstreamForceKeyUnit`
///
/// `running_time` will be adjusted for any pad offsets of pads it was passing through.
extern fn gst_video_event_parse_upstream_force_key_unit(p_event: *gst.Event, p_running_time: *gst.ClockTime, p_all_headers: *c_int, p_count: *c_uint) c_int;
pub const videoEventParseUpstreamForceKeyUnit = gst_video_event_parse_upstream_force_key_unit;

/// Return all the raw video formats supported by GStreamer including
/// special opaque formats such as `GST_VIDEO_FORMAT_DMA_DRM` for which
/// no software conversion exists. This should be use for passthrough
/// template cpas.
extern fn gst_video_formats_any(p_len: *c_uint) [*]const gstvideo.VideoFormat;
pub const videoFormatsAny = gst_video_formats_any;

/// Return all the raw video formats supported by GStreamer.
extern fn gst_video_formats_raw(p_len: *c_uint) [*]const gstvideo.VideoFormat;
pub const videoFormatsRaw = gst_video_formats_raw;

extern fn gst_video_gl_texture_upload_meta_api_get_type() usize;
pub const videoGlTextureUploadMetaApiGetType = gst_video_gl_texture_upload_meta_api_get_type;

/// Given the nominal duration of one video frame,
/// this function will check some standard framerates for
/// a close match (within 0.1%) and return one if possible,
///
/// It will calculate an arbitrary framerate if no close
/// match was found, and return `FALSE`.
///
/// It returns `FALSE` if a duration of 0 is passed.
extern fn gst_video_guess_framerate(p_duration: gst.ClockTime, p_dest_n: ?*c_int, p_dest_d: ?*c_int) c_int;
pub const videoGuessFramerate = gst_video_guess_framerate;

/// Given a frame's dimensions and pixel aspect ratio, this function will
/// calculate the frame's aspect ratio and compare it against a set of
/// common well-known "standard" aspect ratios.
extern fn gst_video_is_common_aspect_ratio(p_width: c_int, p_height: c_int, p_par_n: c_int, p_par_d: c_int) c_int;
pub const videoIsCommonAspectRatio = gst_video_is_common_aspect_ratio;

/// Check whether the `caps` is a dma drm kind caps. Please note that
/// the caps should be fixed.
extern fn gst_video_is_dma_drm_caps(p_caps: *const gst.Caps) c_int;
pub const videoIsDmaDrmCaps = gst_video_is_dma_drm_caps;

/// Return a generic raw video caps for formats defined in `formats`.
/// If `formats` is `NULL` returns a caps for all the supported raw video formats,
/// see `gstvideo.videoFormatsRaw`.
extern fn gst_video_make_raw_caps(p_formats: ?[*]const gstvideo.VideoFormat, p_len: c_uint) *gst.Caps;
pub const videoMakeRawCaps = gst_video_make_raw_caps;

/// Return a generic raw video caps for formats defined in `formats` with features
/// `features`.
/// If `formats` is `NULL` returns a caps for all the supported video formats,
/// see `gstvideo.videoFormatsRaw`.
extern fn gst_video_make_raw_caps_with_features(p_formats: ?[*]const gstvideo.VideoFormat, p_len: c_uint, p_features: ?*gst.CapsFeatures) *gst.Caps;
pub const videoMakeRawCapsWithFeatures = gst_video_make_raw_caps_with_features;

extern fn gst_video_meta_api_get_type() usize;
pub const videoMetaApiGetType = gst_video_meta_api_get_type;

extern fn gst_video_multiview_get_doubled_height_modes() *const gobject.Value;
pub const videoMultiviewGetDoubledHeightModes = gst_video_multiview_get_doubled_height_modes;

extern fn gst_video_multiview_get_doubled_size_modes() *const gobject.Value;
pub const videoMultiviewGetDoubledSizeModes = gst_video_multiview_get_doubled_size_modes;

extern fn gst_video_multiview_get_doubled_width_modes() *const gobject.Value;
pub const videoMultiviewGetDoubledWidthModes = gst_video_multiview_get_doubled_width_modes;

extern fn gst_video_multiview_get_mono_modes() *const gobject.Value;
pub const videoMultiviewGetMonoModes = gst_video_multiview_get_mono_modes;

extern fn gst_video_multiview_get_unpacked_modes() *const gobject.Value;
pub const videoMultiviewGetUnpackedModes = gst_video_multiview_get_unpacked_modes;

extern fn gst_video_multiview_guess_half_aspect(p_mv_mode: gstvideo.VideoMultiviewMode, p_width: c_uint, p_height: c_uint, p_par_n: c_uint, p_par_d: c_uint) c_int;
pub const videoMultiviewGuessHalfAspect = gst_video_multiview_guess_half_aspect;

/// Utility function that transforms the width/height/PAR
/// and multiview mode and flags of a `gstvideo.VideoInfo` into
/// the requested mode.
extern fn gst_video_multiview_video_info_change_mode(p_info: *gstvideo.VideoInfo, p_out_mview_mode: gstvideo.VideoMultiviewMode, p_out_mview_flags: gstvideo.VideoMultiviewFlags) void;
pub const videoMultiviewVideoInfoChangeMode = gst_video_multiview_video_info_change_mode;

extern fn gst_video_overlay_composition_meta_api_get_type() usize;
pub const videoOverlayCompositionMetaApiGetType = gst_video_overlay_composition_meta_api_get_type;

extern fn gst_video_region_of_interest_meta_api_get_type() usize;
pub const videoRegionOfInterestMetaApiGetType = gst_video_region_of_interest_meta_api_get_type;

extern fn gst_video_sei_user_data_unregistered_meta_api_get_type() usize;
pub const videoSeiUserDataUnregisteredMetaApiGetType = gst_video_sei_user_data_unregistered_meta_api_get_type;

/// Parses and returns the Precision Time Stamp (ST 0604) from the SEI User Data Unregistered buffer
extern fn gst_video_sei_user_data_unregistered_parse_precision_time_stamp(p_user_data: *gstvideo.VideoSEIUserDataUnregisteredMeta, p_status: *u8, p_precision_time_stamp: *u64) c_int;
pub const videoSeiUserDataUnregisteredParsePrecisionTimeStamp = gst_video_sei_user_data_unregistered_parse_precision_time_stamp;

/// Get the tile index of the tile at coordinates `x` and `y` in the tiled
/// image of `x_tiles` by `y_tiles`.
///
/// Use this method when `mode` is of type `GST_VIDEO_TILE_TYPE_INDEXED`.
extern fn gst_video_tile_get_index(p_mode: gstvideo.VideoTileMode, p_x: c_int, p_y: c_int, p_x_tiles: c_int, p_y_tiles: c_int) c_uint;
pub const videoTileGetIndex = gst_video_tile_get_index;

extern fn gst_video_time_code_meta_api_get_type() usize;
pub const videoTimeCodeMetaApiGetType = gst_video_time_code_meta_api_get_type;

pub const VideoAffineTransformationGetMatrix = *const fn (p_meta: *gstvideo.VideoAffineTransformationMeta, p_matrix: *f32) callconv(.c) c_int;

pub const VideoConvertSampleCallback = *const fn (p_sample: *gst.Sample, p_error: *glib.Error, p_user_data: ?*anyopaque) callconv(.c) void;

/// Packs `width` pixels from `src` to the given planes and strides in the
/// format `info`. The pixels from source have each component interleaved
/// and will be packed into the planes in `data`.
///
/// This function operates on pack_lines lines, meaning that `src` should
/// contain at least pack_lines lines with a stride of `sstride` and `y`
/// should be a multiple of pack_lines.
///
/// Subsampled formats will use the horizontally and vertically cosited
/// component from the source. Subsampling should be performed before
/// packing.
///
/// Because this function does not have a x coordinate, it is not possible to
/// pack pixels starting from an unaligned position. For tiled images this
/// means that packing should start from a tile coordinate. For subsampled
/// formats this means that a complete pixel needs to be packed.
pub const VideoFormatPack = *const fn (p_info: *const gstvideo.VideoFormatInfo, p_flags: gstvideo.VideoPackFlags, p_src: ?*anyopaque, p_sstride: c_int, p_data: ?*anyopaque, p_stride: *const c_int, p_chroma_site: gstvideo.VideoChromaSite, p_y: c_int, p_width: c_int) callconv(.c) void;

/// Unpacks `width` pixels from the given planes and strides containing data of
/// format `info`. The pixels will be unpacked into `dest` with each component
/// interleaved as per `info`'s unpack_format, which will usually be one of
/// `GST_VIDEO_FORMAT_ARGB`, `GST_VIDEO_FORMAT_AYUV`, `GST_VIDEO_FORMAT_ARGB64` or
/// `GST_VIDEO_FORMAT_AYUV64` depending on the format to unpack.
/// `dest` should at least be big enough to hold `width` * bytes_per_pixel bytes
/// where bytes_per_pixel relates to the unpack format and will usually be
/// either 4 or 8 depending on the unpack format. bytes_per_pixel will be
/// the same as the pixel stride for plane 0 for the above formats.
///
/// For subsampled formats, the components will be duplicated in the destination
/// array. Reconstruction of the missing components can be performed in a
/// separate step after unpacking.
pub const VideoFormatUnpack = *const fn (p_info: *const gstvideo.VideoFormatInfo, p_flags: gstvideo.VideoPackFlags, p_dest: ?*anyopaque, p_data: ?*anyopaque, p_stride: *const c_int, p_x: c_int, p_y: c_int, p_width: c_int) callconv(.c) void;

pub const VideoGLTextureUpload = *const fn (p_meta: *anyopaque, p_texture_id: *c_uint) callconv(.c) c_int;

pub const BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META = "GstBufferPoolOptionVideoAffineTransformation";
/// A bufferpool option to enable extra padding. When a bufferpool supports this
/// option, `gstvideo.bufferPoolConfigSetVideoAlignment` can be called.
///
/// When this option is enabled on the bufferpool,
/// `GST_BUFFER_POOL_OPTION_VIDEO_META` should also be enabled.
pub const BUFFER_POOL_OPTION_VIDEO_ALIGNMENT = "GstBufferPoolOptionVideoAlignment";
/// An option that can be activated on a bufferpool to request gl texture upload
/// meta on buffers from the pool.
///
/// When this option is enabled on the bufferpool,
/// `GST_BUFFER_POOL_OPTION_VIDEO_META` should also be enabled.
pub const BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META = "GstBufferPoolOptionVideoGLTextureUploadMeta";
/// An option that can be activated on bufferpool to request video metadata
/// on buffers from the pool.
pub const BUFFER_POOL_OPTION_VIDEO_META = "GstBufferPoolOptionVideoMeta";
/// Name of the caps feature indicating that the stream is interlaced.
///
/// Currently it is only used for video with 'interlace-mode=alternate'
/// to ensure backwards compatibility for this new mode.
/// In this mode each buffer carries a single field of interlaced video.
/// `GST_VIDEO_BUFFER_FLAG_TOP_FIELD` and `GST_VIDEO_BUFFER_FLAG_BOTTOM_FIELD`
/// indicate whether the buffer carries a top or bottom field. The order of
/// buffers/fields in the stream and the timestamps on the buffers indicate the
/// temporal order of the fields.
/// Top and bottom fields are expected to alternate in this mode.
/// The frame rate in the caps still signals the frame rate, so the notional field
/// rate will be twice the frame rate from the caps
/// (see `GST_VIDEO_INFO_FIELD_RATE_N`).
pub const CAPS_FEATURE_FORMAT_INTERLACED = "format:Interlaced";
pub const CAPS_FEATURE_META_GST_VIDEO_AFFINE_TRANSFORMATION_META = "meta:GstVideoAffineTransformation";
pub const CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META = "meta:GstVideoGLTextureUploadMeta";
pub const CAPS_FEATURE_META_GST_VIDEO_META = "meta:GstVideoMeta";
pub const CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION = "meta:GstVideoOverlayComposition";
/// This metadata stays relevant as long as video colorspace is unchanged.
pub const META_TAG_VIDEO_COLORSPACE_STR = "colorspace";
/// This metadata stays relevant as long as video orientation is unchanged.
pub const META_TAG_VIDEO_ORIENTATION_STR = "orientation";
/// This metadata stays relevant as long as video size is unchanged.
pub const META_TAG_VIDEO_SIZE_STR = "size";
/// This metadata is relevant for video streams.
pub const META_TAG_VIDEO_STR = "video";
pub const VIDEO_COLORIMETRY_BT2020 = "bt2020";
pub const VIDEO_COLORIMETRY_BT2020_10 = "bt2020-10";
pub const VIDEO_COLORIMETRY_BT2100_HLG = "bt2100-hlg";
pub const VIDEO_COLORIMETRY_BT2100_PQ = "bt2100-pq";
pub const VIDEO_COLORIMETRY_BT601 = "bt601";
pub const VIDEO_COLORIMETRY_BT709 = "bt709";
pub const VIDEO_COLORIMETRY_SMPTE240M = "smpte240m";
pub const VIDEO_COLORIMETRY_SRGB = "sRGB";
pub const VIDEO_COMP_A = 3;
pub const VIDEO_COMP_B = 2;
pub const VIDEO_COMP_G = 1;
pub const VIDEO_COMP_INDEX = 0;
pub const VIDEO_COMP_PALETTE = 1;
pub const VIDEO_COMP_R = 0;
pub const VIDEO_COMP_U = 1;
pub const VIDEO_COMP_V = 2;
pub const VIDEO_COMP_Y = 0;
/// `gstvideo.VideoAlphaMode`, the alpha mode to use.
/// Default is `GST_VIDEO_ALPHA_MODE_COPY`.
pub const VIDEO_CONVERTER_OPT_ALPHA_MODE = "GstVideoConverter.alpha-mode";
/// `G_TYPE_DOUBLE`, the alpha color value to use.
/// Default to 1.0
pub const VIDEO_CONVERTER_OPT_ALPHA_VALUE = "GstVideoConverter.alpha-value";
/// `G_TYPE_BOOLEAN`, whether `gstvideo.VideoConverter.frame` will return immediately
/// without waiting for the conversion to complete.  A subsequent
/// `gstvideo.VideoConverter.frameFinish` must be performed to ensure completion of the
/// conversion before subsequent use.  Default `FALSE`
pub const VIDEO_CONVERTER_OPT_ASYNC_TASKS = "GstVideoConverter.async-tasks";
/// `G_TYPE_UINT`, the border color to use if `GST_VIDEO_CONVERTER_OPT_FILL_BORDER`
/// is set to `TRUE`. The color is in ARGB format.
/// Default 0xff000000
pub const VIDEO_CONVERTER_OPT_BORDER_ARGB = "GstVideoConverter.border-argb";
/// `gstvideo.VideoChromaMode`, set the chroma resample mode subsampled
/// formats. Default is `GST_VIDEO_CHROMA_MODE_FULL`.
pub const VIDEO_CONVERTER_OPT_CHROMA_MODE = "GstVideoConverter.chroma-mode";
/// `gstvideo.VideoChromaMethod`, The resampler method to use for
/// chroma resampling. Other options for the resampler can be used, see
/// the `gstvideo.VideoResampler`. Default is `GST_VIDEO_RESAMPLER_METHOD_LINEAR`
pub const VIDEO_CONVERTER_OPT_CHROMA_RESAMPLER_METHOD = "GstVideoConverter.chroma-resampler-method";
/// `G_TYPE_INT`, height in the destination frame, default destination height
pub const VIDEO_CONVERTER_OPT_DEST_HEIGHT = "GstVideoConverter.dest-height";
/// `G_TYPE_INT`, width in the destination frame, default destination width
pub const VIDEO_CONVERTER_OPT_DEST_WIDTH = "GstVideoConverter.dest-width";
/// `G_TYPE_INT`, x position in the destination frame, default 0
pub const VIDEO_CONVERTER_OPT_DEST_X = "GstVideoConverter.dest-x";
/// `G_TYPE_INT`, y position in the destination frame, default 0
pub const VIDEO_CONVERTER_OPT_DEST_Y = "GstVideoConverter.dest-y";
/// `gstvideo.VideoDitherMethod`, The dither method to use when
/// changing bit depth.
/// Default is `GST_VIDEO_DITHER_BAYER`.
pub const VIDEO_CONVERTER_OPT_DITHER_METHOD = "GstVideoConverter.dither-method";
/// `G_TYPE_UINT`, The quantization amount to dither to. Components will be
/// quantized to multiples of this value.
/// Default is 1
pub const VIDEO_CONVERTER_OPT_DITHER_QUANTIZATION = "GstVideoConverter.dither-quantization";
/// `G_TYPE_BOOLEAN`, if the destination rectangle does not fill the complete
/// destination image, render a border with
/// `GST_VIDEO_CONVERTER_OPT_BORDER_ARGB`. Otherwise the unusded pixels in the
/// destination are untouched. Default `TRUE`.
pub const VIDEO_CONVERTER_OPT_FILL_BORDER = "GstVideoConverter.fill-border";
/// `gstvideo.VideoGammaMode`, set the gamma mode.
/// Default is `GST_VIDEO_GAMMA_MODE_NONE`.
pub const VIDEO_CONVERTER_OPT_GAMMA_MODE = "GstVideoConverter.gamma-mode";
/// `gstvideo.VideoMatrixMode`, set the color matrix conversion mode for
/// converting between Y'PbPr and non-linear RGB (R'G'B').
/// Default is `GST_VIDEO_MATRIX_MODE_FULL`.
pub const VIDEO_CONVERTER_OPT_MATRIX_MODE = "GstVideoConverter.matrix-mode";
/// `gstvideo.VideoPrimariesMode`, set the primaries conversion mode.
/// Default is `GST_VIDEO_PRIMARIES_MODE_NONE`.
pub const VIDEO_CONVERTER_OPT_PRIMARIES_MODE = "GstVideoConverter.primaries-mode";
/// `gstvideo.VideoResamplerMethod`, The resampler method to use for
/// resampling. Other options for the resampler can be used, see
/// the `gstvideo.VideoResampler`. Default is `GST_VIDEO_RESAMPLER_METHOD_CUBIC`
pub const VIDEO_CONVERTER_OPT_RESAMPLER_METHOD = "GstVideoConverter.resampler-method";
/// `G_TYPE_UINT`, The number of taps for the resampler.
/// Default is 0: let the resampler choose a good value.
pub const VIDEO_CONVERTER_OPT_RESAMPLER_TAPS = "GstVideoConverter.resampler-taps";
/// `G_TYPE_INT`, source height to convert, default source height
pub const VIDEO_CONVERTER_OPT_SRC_HEIGHT = "GstVideoConverter.src-height";
/// `G_TYPE_INT`, source width to convert, default source width
pub const VIDEO_CONVERTER_OPT_SRC_WIDTH = "GstVideoConverter.src-width";
/// `G_TYPE_INT`, source x position to start conversion, default 0
pub const VIDEO_CONVERTER_OPT_SRC_X = "GstVideoConverter.src-x";
/// `G_TYPE_INT`, source y position to start conversion, default 0
pub const VIDEO_CONVERTER_OPT_SRC_Y = "GstVideoConverter.src-y";
/// `G_TYPE_UINT`, maximum number of threads to use. Default 1, 0 for the number
/// of cores.
pub const VIDEO_CONVERTER_OPT_THREADS = "GstVideoConverter.threads";
/// Default maximum number of errors tolerated before signaling error.
pub const VIDEO_DECODER_MAX_ERRORS = -1;
/// The name of the templates for the sink pad.
pub const VIDEO_DECODER_SINK_NAME = "sink";
/// The name of the templates for the source pad.
pub const VIDEO_DECODER_SRC_NAME = "src";
/// Generic caps string for video wit DMABuf(GST_CAPS_FEATURE_MEMORY_DMABUF)
/// feature, for use in pad templates. As drm-format is supposed to be defined
/// at run-time it's not predefined here.
pub const VIDEO_DMA_DRM_CAPS_MAKE = "video/x-raw(memory:DMABuf), format = (string) DMA_DRM, width = ";
/// The name of the templates for the sink pad.
pub const VIDEO_ENCODER_SINK_NAME = "sink";
/// The name of the templates for the source pad.
pub const VIDEO_ENCODER_SRC_NAME = "src";
/// List of all video formats, for use in template caps strings.
///
/// Formats are sorted by decreasing "quality", using these criteria by priority:
///   - number of components
///   - depth
///   - subsampling factor of the width
///   - subsampling factor of the height
///   - number of planes
///   - native endianness preferred
///   - pixel stride
///   - poffset
///   - prefer non-complex formats
///   - prefer YUV formats over RGB ones
///   - prefer I420 over YV12
///   - format name
pub const VIDEO_FORMATS_ALL = "{ ";
/// Declare all video formats as a string.
///
/// Formats are sorted by decreasing "quality", using these criteria by priority:
///   - number of components
///   - depth
///   - subsampling factor of the width
///   - subsampling factor of the height
///   - number of planes
///   - native endianness preferred
///   - pixel stride
///   - poffset
///   - prefer non-complex formats
///   - prefer YUV formats over RGB ones
///   - prefer I420 over YV12
///   - format name
pub const VIDEO_FORMATS_ALL_STR = "A444_16BE, A444_16LE, AYUV64, ARGB64, Y416_BE, RGBA64_BE, ARGB64_BE, BGRA64_BE, ABGR64_BE, Y416_LE, RGBA64_LE, ARGB64_LE, BGRA64_LE, ABGR64_LE, A422_16BE, A422_16LE, A420_16BE, A420_16LE, A444_12BE, GBRA_12BE, A444_12LE, GBRA_12LE, Y412_BE, Y412_LE, A422_12BE, A422_12LE, A420_12BE, A420_12LE, A444_10BE, GBRA_10BE, A444_10LE, GBRA_10LE, A422_10BE, A422_10LE, A420_10BE, A420_10LE, Y410, BGR10A2_LE, RGB10A2_LE, A444, GBRA, AYUV, VUYA, RGBA, RBGA, ARGB, BGRA, ABGR, A422, A420, AV12, Y444_16BE, GBR_16BE, Y444_16LE, GBR_16LE, Y216_BE, v216, Y216_LE, P016_BE, P016_LE, Y444_12BE, GBR_12BE, Y444_12LE, GBR_12LE, I422_12BE, I422_12LE, Y212_BE, Y212_LE, I420_12BE, I420_12LE, P012_BE, P012_LE, Y444_10BE, GBR_10BE, Y444_10LE, GBR_10LE, r210, I422_10BE, I422_10LE, NV16_10LE32, Y210, UYVP, v210, I420_10BE, I420_10LE, P010_10BE, MT2110R, MT2110T, NV12_10BE_8L128, NV12_10LE40_4L4, P010_10LE, NV12_10LE40, NV12_10LE32, Y444, BGRP, GBR, RGBP, NV24, v308, IYU2, RGBx, xRGB, BGRx, xBGR, RGB, BGR, Y42B, NV16, NV61, YUY2, YVYU, UYVY, VYUY, I420, YV12, NV12, NV21, NV12_16L32S, NV12_32L32, NV12_4L4, NV12_64Z32, NV12_8L128, Y41B, IYU1, YUV9, YVU9, BGR16, RGB16, BGR15, RGB15, RGB8P, GRAY16_BE, GRAY16_LE, GRAY10_LE16, GRAY10_LE32, GRAY8";
/// This is similar to `GST_VIDEO_FORMATS_ALL` but includes formats like DMA_DRM
/// that do not have a software converter. This should be used for passthrough
/// template caps.
pub const VIDEO_FORMATS_ANY = "{ ";
/// This is similar to `GST_VIDEO_FORMATS_ALL_STR` but includes formats like
/// DMA_DRM for which no software converter exists. This should be used for
/// passthrough template caps.
pub const VIDEO_FORMATS_ANY_STR = "DMA_DRM, ";
/// Number of video formats in `gstvideo.VideoFormat`.
pub const VIDEO_FORMAT_LAST = 139;
pub const VIDEO_FPS_RANGE = "(fraction) [ 0, max ]";
pub const VIDEO_MAX_COMPONENTS = 4;
pub const VIDEO_MAX_PLANES = 4;
/// G_TYPE_DOUBLE, B parameter of the cubic filter. The B
/// parameter controls the bluriness. Values between 0.0 and
/// 2.0 are accepted. 1/3 is the default.
///
/// Below are some values of popular filters:
///                    B       C
/// Hermite           0.0     0.0
/// Spline            1.0     0.0
/// Catmull-Rom       0.0     1/2
/// Mitchell          1/3     1/3
/// Robidoux          0.3782  0.3109
/// Robidoux
///  Sharp            0.2620  0.3690
/// Robidoux
///  Soft             0.6796  0.1602
pub const VIDEO_RESAMPLER_OPT_CUBIC_B = "GstVideoResampler.cubic-b";
/// G_TYPE_DOUBLE, C parameter of the cubic filter. The C
/// parameter controls the Keys alpha value. Values between 0.0 and
/// 2.0 are accepted. 1/3 is the default.
///
/// See `GST_VIDEO_RESAMPLER_OPT_CUBIC_B` for some more common values
pub const VIDEO_RESAMPLER_OPT_CUBIC_C = "GstVideoResampler.cubic-c";
/// G_TYPE_DOUBLE, specifies the size of filter envelope for
/// `GST_VIDEO_RESAMPLER_METHOD_LANCZOS`. values are clamped between
/// 1.0 and 5.0. 2.0 is the default.
pub const VIDEO_RESAMPLER_OPT_ENVELOPE = "GstVideoResampler.envelope";
/// G_TYPE_INT, limits the maximum number of taps to use.
/// 16 is the default.
pub const VIDEO_RESAMPLER_OPT_MAX_TAPS = "GstVideoResampler.max-taps";
/// G_TYPE_DOUBLE, specifies sharpening of the filter for
/// `GST_VIDEO_RESAMPLER_METHOD_LANCZOS`. values are clamped between
/// 0.0 and 1.0. 0.0 is the default.
pub const VIDEO_RESAMPLER_OPT_SHARPEN = "GstVideoResampler.sharpen";
/// G_TYPE_DOUBLE, specifies sharpness of the filter for
/// `GST_VIDEO_RESAMPLER_METHOD_LANCZOS`. values are clamped between
/// 0.5 and 1.5. 1.0 is the default.
pub const VIDEO_RESAMPLER_OPT_SHARPNESS = "GstVideoResampler.sharpness";
/// `gstvideo.VideoDitherMethod`, The dither method to use for propagating
/// quatization errors.
pub const VIDEO_SCALER_OPT_DITHER_METHOD = "GstVideoScaler.dither-method";
pub const VIDEO_SIZE_RANGE = "(int) [ 1, max ]";
pub const VIDEO_TILE_TYPE_MASK = 65535;
pub const VIDEO_TILE_TYPE_SHIFT = 16;
pub const VIDEO_TILE_X_TILES_MASK = 65535;
pub const VIDEO_TILE_Y_TILES_SHIFT = 16;

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