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

const std = @import("std");
const compat = @import("compat");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
/// `gstmse.MediaSource` is the entry point into the W3C Media Source API. It offers
/// functionality similar to `GstAppSrc` for client-side web or JavaScript
/// applications decoupling the source of media from its processing and playback.
///
/// To interact with a Media Source, connect it to a `gstmse.MseSrc` that is in some
/// `gst.Pipeline` using `gstmse.MediaSource.attach`. Then create at least one
/// `gstmse.SourceBuffer` using `gstmse.MediaSource.addSourceBuffer`. Finally, feed
/// some media data to the Source Buffer(s) using
/// `gstmse.SourceBuffer.appendBuffer` and play the pipeline.
pub const MediaSource = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstmse.MediaSourceClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// A `gstmse.SourceBufferList` of every `gstmse.SourceBuffer` in this Media Source that
        /// is considered active
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-activesourcebuffers)
        pub const active_source_buffers = struct {
            pub const name = "active-source-buffers";

            pub const Type = ?*gstmse.SourceBufferList;
        };

        /// The Duration of the Media Source as a `gst.ClockTime`
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-duration)
        pub const duration = struct {
            pub const name = "duration";

            pub const Type = u64;
        };

        /// The position of the player consuming from the Media Source
        pub const position = struct {
            pub const name = "position";

            pub const Type = u64;
        };

        /// The Ready State of the Media Source
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-readystate)
        pub const ready_state = struct {
            pub const name = "ready-state";

            pub const Type = gstmse.MediaSourceReadyState;
        };

        /// A `gstmse.SourceBufferList` of every `gstmse.SourceBuffer` in this Media Source
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-sourcebuffers)
        pub const source_buffers = struct {
            pub const name = "source-buffers";

            pub const Type = ?*gstmse.SourceBufferList;
        };
    };

    pub const signals = struct {
        pub const on_source_close = struct {
            pub const name = "on-source-close";

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

        /// Emitted when `self` has ended, normally through
        /// `gstmse.MediaSource.endOfStream`.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-onsourceended)
        pub const on_source_ended = struct {
            pub const name = "on-source-ended";

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

        /// Emitted when `self` has been opened.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-onsourceopen)
        pub const on_source_open = struct {
            pub const name = "on-source-open";

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

    /// Determines whether the current Media Source configuration can process media
    /// of the supplied `type`.
    extern fn gst_media_source_is_type_supported(p_type: [*:0]const u8) c_int;
    pub const isTypeSupported = gst_media_source_is_type_supported;

    /// Creates a new `gstmse.MediaSource` instance. The instance is in the
    /// `GST_MEDIA_SOURCE_READY_STATE_CLOSED` state and is not associated with any
    /// media player.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-constructor)
    extern fn gst_media_source_new() *gstmse.MediaSource;
    pub const new = gst_media_source_new;

    /// Add a `gstmse.SourceBuffer` to this `gstmse.MediaSource` of the specified media type.
    /// The Media Source must be in the `gstmse.MediaSourceReadyState` `GST_MEDIA_SOURCE_READY_STATE_OPEN`.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-addsourcebuffer)
    extern fn gst_media_source_add_source_buffer(p_self: *MediaSource, p_type: [*:0]const u8, p_error: ?*?*glib.Error) ?*gstmse.SourceBuffer;
    pub const addSourceBuffer = gst_media_source_add_source_buffer;

    /// Associates `self` with `element`.
    /// Normally, the Element will be part of a `gst.Pipeline` that plays back the data
    /// submitted to the Media Source's Source Buffers.
    ///
    /// `gstmse.MseSrc` is a special source element that is designed to consume media from
    /// a `gstmse.MediaSource`.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dfn`-attaching-to-a-media-element)
    extern fn gst_media_source_attach(p_self: *MediaSource, p_element: *gstmse.MseSrc) void;
    pub const attach = gst_media_source_attach;

    /// Clear the live seekable range for `self`. This will inform the component
    /// playing this Media Source that there is no seekable time range.
    ///
    /// If the ready state is not `GST_MEDIA_SOURCE_READY_STATE_OPEN`, it will fail
    /// and set an error.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-clearliveseekablerange)
    extern fn gst_media_source_clear_live_seekable_range(p_self: *MediaSource, p_error: ?*?*glib.Error) c_int;
    pub const clearLiveSeekableRange = gst_media_source_clear_live_seekable_range;

    /// Detaches `self` from any `gstmse.MseSrc` element that it may be associated with.
    extern fn gst_media_source_detach(p_self: *MediaSource) void;
    pub const detach = gst_media_source_detach;

    /// Mark `self` as reaching the end of stream, disallowing new data inputs.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-endofstream)
    extern fn gst_media_source_end_of_stream(p_self: *MediaSource, p_eos_error: gstmse.MediaSourceEOSError, p_error: ?*?*glib.Error) c_int;
    pub const endOfStream = gst_media_source_end_of_stream;

    /// Gets a `gstmse.SourceBufferList` containing all the Source Buffers currently
    /// associated with this Media Source that are considered "active."
    /// For a Source Buffer to be considered active, either its video track is
    /// selected, its audio track is enabled, or its text track is visible or hidden.
    /// This object will reflect any future changes to the parent Media Source as
    /// well.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-activesourcebuffers)
    extern fn gst_media_source_get_active_source_buffers(p_self: *MediaSource) *gstmse.SourceBufferList;
    pub const getActiveSourceBuffers = gst_media_source_get_active_source_buffers;

    /// Gets the current duration of `self`.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-duration)
    extern fn gst_media_source_get_duration(p_self: *MediaSource) gst.ClockTime;
    pub const getDuration = gst_media_source_get_duration;

    /// Get the live seekable range of `self`. Will fill in the supplied `range` with
    /// the current live seekable range.
    extern fn gst_media_source_get_live_seekable_range(p_self: *MediaSource, p_range: *gstmse.MediaSourceRange) void;
    pub const getLiveSeekableRange = gst_media_source_get_live_seekable_range;

    /// Gets the current playback position of the Media Source.
    extern fn gst_media_source_get_position(p_self: *MediaSource) gst.ClockTime;
    pub const getPosition = gst_media_source_get_position;

    /// Gets the current Ready State of the Media Source.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-readystate)
    extern fn gst_media_source_get_ready_state(p_self: *MediaSource) gstmse.MediaSourceReadyState;
    pub const getReadyState = gst_media_source_get_ready_state;

    /// Gets a `gstmse.SourceBufferList` containing all the Source Buffers currently
    /// associated with this Media Source. This object will reflect any future
    /// changes to the parent Media Source as well.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-sourcebuffers)
    extern fn gst_media_source_get_source_buffers(p_self: *MediaSource) *gstmse.SourceBufferList;
    pub const getSourceBuffers = gst_media_source_get_source_buffers;

    /// Remove `buffer` from `self`.
    ///
    /// `buffer` must have been created as a child of `self` and `self` must be in the
    /// `gstmse.MediaSourceReadyState` `GST_MEDIA_SOURCE_READY_STATE_OPEN`.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-removesourcebuffer)
    extern fn gst_media_source_remove_source_buffer(p_self: *MediaSource, p_buffer: *gstmse.SourceBuffer, p_error: ?*?*glib.Error) c_int;
    pub const removeSourceBuffer = gst_media_source_remove_source_buffer;

    /// Sets the duration of `self`.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-duration)
    extern fn gst_media_source_set_duration(p_self: *MediaSource, p_duration: gst.ClockTime, p_error: ?*?*glib.Error) c_int;
    pub const setDuration = gst_media_source_set_duration;

    /// Set the live seekable range for `self`. This range informs the component
    /// playing this Media Source what it can allow the user to seek through.
    ///
    /// If the ready state is not `GST_MEDIA_SOURCE_READY_STATE_OPEN`, or the supplied
    /// `start` time is later than `end` it will fail and set an error.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-mediasource-setliveseekablerange)
    extern fn gst_media_source_set_live_seekable_range(p_self: *MediaSource, p_start: gst.ClockTime, p_end: gst.ClockTime, p_error: ?*?*glib.Error) c_int;
    pub const setLiveSeekableRange = gst_media_source_set_live_seekable_range;

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

    extern fn g_object_ref(p_self: *gstmse.MediaSource) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstmse.MediaSource) void;
    pub const unref = g_object_unref;

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

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

/// `gstmse.MseSrc` is a source Element that interacts with a `gstmse.MediaSource` to
/// consume `gst.Sample`<!-- -->s processed by the Media Source and supplies them
/// to the containing `gst.Pipeline`. In the perspective of the Media Source API,
/// this element fulfills the basis of the Media Element's role relating to
/// working with a Media Source. The remaining responsibilities are meant to be
/// fulfilled by the application and `GstPlay` can be used to satisfy many of
/// them.
///
/// Once added to a Pipeline, this element should be attached to a Media Source
/// using `gstmse.MediaSource.attach`.
pub const MseSrc = opaque {
    pub const Parent = gst.Element;
    pub const Implements = [_]type{gst.URIHandler};
    pub const Class = gstmse.MseSrcClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The duration of the stream as a `gst.ClockTime`
        ///
        /// [Specification](https://html.spec.whatwg.org/multipage/media.html`dom`-media-duration)
        pub const duration = struct {
            pub const name = "duration";

            pub const Type = u64;
        };

        /// The number of audio tracks in the Media Source
        pub const n_audio = struct {
            pub const name = "n-audio";

            pub const Type = c_uint;
        };

        /// The number of text tracks in the Media Source
        pub const n_text = struct {
            pub const name = "n-text";

            pub const Type = c_uint;
        };

        /// The number of video tracks in the Media Source
        pub const n_video = struct {
            pub const name = "n-video";

            pub const Type = c_uint;
        };

        /// The playback position as a `gst.ClockTime`
        ///
        /// [Specification](https://html.spec.whatwg.org/multipage/media.html`current`-playback-position)
        pub const position = struct {
            pub const name = "position";

            pub const Type = u64;
        };

        /// The Ready State of this element, describing to what level it can supply
        /// content for the current `gstmse.MseSrc.properties.position`. This is a separate concept
        /// from `gstmse.MediaSource.properties.ready`-state: and corresponds to the HTML Media
        /// Element's Ready State.
        ///
        /// [Specification](https://html.spec.whatwg.org/multipage/media.html`ready`-states)
        pub const ready_state = struct {
            pub const name = "ready-state";

            pub const Type = gstmse.MseSrcReadyState;
        };
    };

    pub const signals = struct {};

    /// Gets the duration of `self`.
    ///
    /// [Specification](https://html.spec.whatwg.org/multipage/media.html`dom`-media-duration)
    extern fn gst_mse_src_get_duration(p_self: *MseSrc) gst.ClockTime;
    pub const getDuration = gst_mse_src_get_duration;

    extern fn gst_mse_src_get_n_audio(p_self: *MseSrc) c_uint;
    pub const getNAudio = gst_mse_src_get_n_audio;

    extern fn gst_mse_src_get_n_text(p_self: *MseSrc) c_uint;
    pub const getNText = gst_mse_src_get_n_text;

    extern fn gst_mse_src_get_n_video(p_self: *MseSrc) c_uint;
    pub const getNVideo = gst_mse_src_get_n_video;

    /// Gets the current playback position of `self`.
    ///
    /// [Specification](https://html.spec.whatwg.org/multipage/media.html`current`-playback-position)
    extern fn gst_mse_src_get_position(p_self: *MseSrc) gst.ClockTime;
    pub const getPosition = gst_mse_src_get_position;

    /// The Ready State of `self`, describing to what level it can supply content for
    /// the current `gstmse.MseSrc.properties.position`. This is a separate concept from
    /// `gstmse.MediaSource.properties.ready`-state: and corresponds to the HTML Media Element's
    /// Ready State.
    ///
    /// [Specification](https://html.spec.whatwg.org/multipage/media.html`ready`-states)
    extern fn gst_mse_src_get_ready_state(p_self: *MseSrc) gstmse.MseSrcReadyState;
    pub const getReadyState = gst_mse_src_get_ready_state;

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

    extern fn g_object_ref(p_self: *gstmse.MseSrc) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstmse.MseSrc) void;
    pub const unref = g_object_unref;

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

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

pub const MseSrcPad = opaque {
    pub const Parent = gst.Pad;
    pub const Implements = [_]type{};
    pub const Class = gstmse.MseSrcPadClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

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

    extern fn g_object_ref(p_self: *gstmse.MseSrcPad) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstmse.MseSrcPad) void;
    pub const unref = g_object_unref;

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

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

/// The Source Buffer is the primary means of data flow between an application
/// and the Media Source API. It represents a single timeline of media,
/// containing some combination of audio, video, and text tracks.
/// An application is responsible for feeding raw data into the Source Buffer
/// using `gstmse.SourceBuffer.appendBuffer` and the Source Buffer will
/// asynchronously process the data into tracks of time-coded multimedia samples.
///
/// The application as well as the associated playback component can then select
/// to play media from any subset of tracks across all Source Buffers of a Media
/// Source.
///
/// A few control points are also provided to customize the behavior.
///
///  - `gstmse.SourceBuffer.properties.append`-mode controls how timestamps of processed samples are
///  interpreted. They are either inserted in the timeline directly where the
///  decoded media states they should, or inserted directly after the previously
///  encountered sample.
///
///  - `gstmse.SourceBuffer.properties.append`-window-start / `gstmse.SourceBuffer.properties.append`-window-end
///  control the planned time window where media from appended data can be added
///  to the current timeline. Any samples outside that range may be ignored.
///
///  - `gstmse.SourceBuffer.properties.timestamp`-offset is added to the start time of any sample
///  processed.
pub const SourceBuffer = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstmse.SourceBufferClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// Affects how timestamps of processed media segments are interpreted.
        /// In `GST_SOURCE_BUFFER_APPEND_MODE_SEGMENTS`, the start timestamp of a
        /// processed media segment is used directly along with
        /// `gstmse.SourceBuffer.properties.timestamp`-offset .
        /// In `GST_SOURCE_BUFFER_APPEND_MODE_SEQUENCE`, the timestamp of a
        /// processed media segment is ignored and replaced with the end time of the
        /// most recently appended segment.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-mode)
        pub const append_mode = struct {
            pub const name = "append-mode";

            pub const Type = gstmse.SourceBufferAppendMode;
        };

        /// Any segments processed which have a start time greater than this value will
        /// be ignored by this Source Buffer.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-appendwindowend)
        pub const append_window_end = struct {
            pub const name = "append-window-end";

            pub const Type = u64;
        };

        /// Any segments processed which end before this value will be ignored by this
        /// Source Buffer.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-appendwindowstart)
        pub const append_window_start = struct {
            pub const name = "append-window-start";

            pub const Type = u64;
        };

        /// The set of Time Intervals that have been loaded into the current Source
        /// Buffer
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-buffered)
        pub const buffered = struct {
            pub const name = "buffered";

            pub const Type = ?[*]*anyopaque;
        };

        /// The MIME content-type of the data stream
        pub const content_type = struct {
            pub const name = "content-type";

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

        /// The next media segment appended to the current Source Buffer will have its
        /// start timestamp increased by this amount.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-timestampoffset)
        pub const timestamp_offset = struct {
            pub const name = "timestamp-offset";

            pub const Type = i64;
        };

        /// Whether the current source buffer is still asynchronously processing
        /// previously issued commands.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-updating)
        pub const updating = struct {
            pub const name = "updating";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {
        /// Emitted when `self` was aborted after a call to `gstmse.SourceBuffer.abort`.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-onabort)
        pub const on_abort = struct {
            pub const name = "on-abort";

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

        /// Emitted when `self` has encountered an error after a call to
        /// `gstmse.SourceBuffer.appendBuffer`.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-onerror)
        pub const on_error = struct {
            pub const name = "on-error";

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

        /// Emitted when `self` has successfully processed data after a call to
        /// `gstmse.SourceBuffer.appendBuffer`.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-onupdate)
        pub const on_update = struct {
            pub const name = "on-update";

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

        /// Emitted when `self` is no longer in the updating state after a call to
        /// `gstmse.SourceBuffer.appendBuffer`. This can happen after a successful or
        /// unsuccessful append.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-onupdateend)
        pub const on_update_end = struct {
            pub const name = "on-update-end";

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

        /// Emitted when `self` has begun to process data after a call to
        /// `gstmse.SourceBuffer.appendBuffer`.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-onupdatestart)
        pub const on_update_start = struct {
            pub const name = "on-update-start";

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

    /// Attempts to end any processing of the currently pending data and reset the
    /// media parser.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-abort)
    extern fn gst_source_buffer_abort(p_self: *SourceBuffer, p_error: ?*?*glib.Error) c_int;
    pub const abort = gst_source_buffer_abort;

    /// Schedules the bytes inside `buf` to be processed by `self`. When it is possible
    /// to accept the supplied data, it will be processed asynchronously and fill in
    /// the track buffers for playback purposes.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-appendbuffer)
    extern fn gst_source_buffer_append_buffer(p_self: *SourceBuffer, p_buf: *gst.Buffer, p_error: ?*?*glib.Error) c_int;
    pub const appendBuffer = gst_source_buffer_append_buffer;

    /// Attempts to change the content type of `self` to `type`. Any new data appended
    /// to the Source Buffer must be of the supplied `type` afterward.
    extern fn gst_source_buffer_change_content_type(p_self: *SourceBuffer, p_type: [*:0]const u8, p_error: ?*?*glib.Error) c_int;
    pub const changeContentType = gst_source_buffer_change_content_type;

    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-mode)
    extern fn gst_source_buffer_get_append_mode(p_self: *SourceBuffer) gstmse.SourceBufferAppendMode;
    pub const getAppendMode = gst_source_buffer_get_append_mode;

    /// Returns the current append window end time. Any segment processed that starts
    /// after this value will be ignored.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-appendwindowend)
    extern fn gst_source_buffer_get_append_window_end(p_self: *SourceBuffer) gst.ClockTime;
    pub const getAppendWindowEnd = gst_source_buffer_get_append_window_end;

    /// Returns the current append window start time. Any segment processed that ends
    /// earlier than this value will be ignored.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-appendwindowstart)
    extern fn gst_source_buffer_get_append_window_start(p_self: *SourceBuffer) gst.ClockTime;
    pub const getAppendWindowStart = gst_source_buffer_get_append_window_start;

    /// Returns a sequence of `gstmse.MediaSourceRange` values representing which segments
    /// of `self` are buffered in memory.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-buffered)
    extern fn gst_source_buffer_get_buffered(p_self: *SourceBuffer, p_error: ?*?*glib.Error) ?*glib.Array;
    pub const getBuffered = gst_source_buffer_get_buffered;

    /// Returns the current content type of `self`.
    extern fn gst_source_buffer_get_content_type(p_self: *SourceBuffer) [*:0]u8;
    pub const getContentType = gst_source_buffer_get_content_type;

    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-timestampoffset)
    extern fn gst_source_buffer_get_timestamp_offset(p_self: *SourceBuffer) gst.ClockTime;
    pub const getTimestampOffset = gst_source_buffer_get_timestamp_offset;

    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-updating)
    extern fn gst_source_buffer_get_updating(p_self: *SourceBuffer) c_int;
    pub const getUpdating = gst_source_buffer_get_updating;

    /// Attempts to remove any parsed data between `start` and `end` from `self`.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-remove)
    extern fn gst_source_buffer_remove(p_self: *SourceBuffer, p_start: gst.ClockTime, p_end: gst.ClockTime, p_error: ?*?*glib.Error) c_int;
    pub const remove = gst_source_buffer_remove;

    /// Changes the Append Mode of `self`. This influences what timestamps will be
    /// assigned to media processed by this Source Buffer. In Segment mode, the
    /// timestamps in each segment determine the position of each sample after it
    /// is processed. In Sequence mode, the timestamp of each processed sample is
    /// generated based on the end of the most recently processed segment.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-mode)
    extern fn gst_source_buffer_set_append_mode(p_self: *SourceBuffer, p_mode: gstmse.SourceBufferAppendMode, p_error: ?*?*glib.Error) c_int;
    pub const setAppendMode = gst_source_buffer_set_append_mode;

    /// Modifies the current append window end of `self`. If successful, samples
    /// processed after setting this value that start after this point will be
    /// ignored.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-appendwindowend)
    extern fn gst_source_buffer_set_append_window_end(p_self: *SourceBuffer, p_end: gst.ClockTime, p_error: ?*?*glib.Error) c_int;
    pub const setAppendWindowEnd = gst_source_buffer_set_append_window_end;

    /// Modifies the current append window start of `self`. If successful, samples
    /// processed after setting this value that end before this point will be
    /// ignored.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-appendwindowstart)
    extern fn gst_source_buffer_set_append_window_start(p_self: *SourceBuffer, p_start: gst.ClockTime, p_error: ?*?*glib.Error) c_int;
    pub const setAppendWindowStart = gst_source_buffer_set_append_window_start;

    /// Attempt to set the timestamp offset of `self`. Any media processed after this
    /// value is set will have this value added to its start time.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebuffer-timestampoffset)
    extern fn gst_source_buffer_set_timestamp_offset(p_self: *SourceBuffer, p_offset: gst.ClockTime, p_error: ?*?*glib.Error) c_int;
    pub const setTimestampOffset = gst_source_buffer_set_timestamp_offset;

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

    extern fn g_object_ref(p_self: *gstmse.SourceBuffer) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstmse.SourceBuffer) void;
    pub const unref = g_object_unref;

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

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

/// The Source Buffer List is a list of `gstmse.SourceBuffer`<!-- -->s that can be
/// indexed numerically and monitored for changes. The list itself cannot be
/// modified through this interface, though the Source Buffers it holds can be
/// modified after retrieval.
///
/// It is used by `gstmse.MediaSource` to provide direct access to its child
/// `gstmse.SourceBuffer`<!-- -->s through `gstmse.MediaSource.properties.source`-buffers as well as
/// informing clients which of the Source Buffers are active through
/// `gstmse.MediaSource.properties.active`-source-buffers.
pub const SourceBufferList = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstmse.SourceBufferListClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The number of `gstmse.SourceBuffer`<!-- -->s contained by this structure
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebufferlist-length)
        pub const length = struct {
            pub const name = "length";

            pub const Type = c_ulong;
        };
    };

    pub const signals = struct {
        /// Emitted when a `gstmse.SourceBuffer` has been added to this list.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebufferlist-onaddsourcebuffer)
        pub const on_sourcebuffer_added = struct {
            pub const name = "on-sourcebuffer-added";

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

        /// Emitted when a `gstmse.SourceBuffer` has been removed from this list.
        ///
        /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebufferlist-onremovesourcebuffer)
        pub const on_sourcebuffer_removed = struct {
            pub const name = "on-sourcebuffer-removed";

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

    /// [Specification](https://www.w3.org/TR/media-source-2/`dom`-sourcebufferlist-length)
    extern fn gst_source_buffer_list_get_length(p_self: *SourceBufferList) c_uint;
    pub const getLength = gst_source_buffer_list_get_length;

    /// Retrieves the `gstmse.SourceBuffer` at `index` from `self`. If `index` is greater than
    /// the highest index in the list, it will return `NULL`.
    ///
    /// [Specification](https://www.w3.org/TR/media-source-2/`dfn`-sourcebufferlist-getter)
    extern fn gst_source_buffer_list_index(p_self: *SourceBufferList, p_index: c_uint) ?*gstmse.SourceBuffer;
    pub const index = gst_source_buffer_list_index;

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

    extern fn g_object_ref(p_self: *gstmse.SourceBufferList) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstmse.SourceBufferList) void;
    pub const unref = g_object_unref;

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

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

pub const MediaSourceClass = extern struct {
    pub const Instance = gstmse.MediaSource;

    f_parent_class: gst.ObjectClass,

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

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

/// A structure describing a simplified version of the TimeRanges concept in the
/// HTML specification, only representing a single `start` and `end` time.
///
/// [Specification](https://html.spec.whatwg.org/multipage/media.html`timeranges`)
pub const MediaSourceRange = extern struct {
    /// The start of this range.
    f_start: gst.ClockTime,
    /// The end of this range.
    f_end: gst.ClockTime,

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

pub const MseSrcClass = extern struct {
    pub const Instance = gstmse.MseSrc;

    f_parent_class: gst.ElementClass,

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

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

pub const MseSrcPadClass = extern struct {
    pub const Instance = gstmse.MseSrcPad;

    f_parent_class: gst.PadClass,

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

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

pub const SourceBufferClass = extern struct {
    pub const Instance = gstmse.SourceBuffer;

    f_parent_class: gst.ObjectClass,

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

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

pub const SourceBufferInterval = extern struct {
    f_start: gst.ClockTime,
    f_end: gst.ClockTime,

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

pub const SourceBufferListClass = extern struct {
    pub const Instance = gstmse.SourceBufferList;

    f_parent_class: gst.ObjectClass,

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

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

/// Reasons for ending a `gstmse.MediaSource` using `gstmse.MediaSource.endOfStream`.
///
/// [Specification](https://www.w3.org/TR/media-source-2/`dom`-endofstreamerror)
pub const MediaSourceEOSError = enum(c_int) {
    none = 0,
    network = 1,
    decode = 2,
    _,

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

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

/// Any error that can occur within `gstmse.MediaSource` or `gstmse.SourceBuffer` APIs.
/// These values correspond directly to those in the Web IDL specification.
///
/// [Specification](https://webidl.spec.whatwg.org/`idl`-DOMException-error-names)
pub const MediaSourceError = enum(c_int) {
    invalid_state = 0,
    type = 1,
    not_supported = 2,
    not_found = 3,
    quota_exceeded = 4,
    _,

    /// Any error type that can be reported by the Media Source API.
    extern fn gst_media_source_error_quark() glib.Quark;
    pub const quark = gst_media_source_error_quark;

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

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

/// Describes the possible states of the Media Source.
///
/// [Specification](https://www.w3.org/TR/media-source-2/`dom`-readystate)
pub const MediaSourceReadyState = enum(c_int) {
    closed = 0,
    open = 1,
    ended = 2,
    _,

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

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

/// Describes how much information a `gstmse.MseSrc` has about the media it is playing
/// back at the current playback `gstmse.MseSrc.properties.position`. This type corresponds
/// directly to the ready state of a HTML Media Element and is a separate concept
/// from `gstmse.MediaSourceReadyState`.
///
/// [Specification](https://html.spec.whatwg.org/multipage/media.html`ready`-states)
pub const MseSrcReadyState = enum(c_int) {
    nothing = 0,
    metadata = 1,
    current_data = 2,
    future_data = 3,
    enough_data = 4,
    _,

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

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

/// [Specification](https://www.w3.org/TR/media-source-2/`dom`-appendmode)
pub const SourceBufferAppendMode = enum(c_int) {
    segments = 0,
    sequence = 1,
    _,

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

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

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