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

const std = @import("std");
const compat = @import("compat");
const gstvideo = @import("gstvideo1");
const gstbase = @import("gstbase1");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
const gsttag = @import("gsttag1");
const gstpbutils = @import("gstpbutils1");
const gstaudio = @import("gstaudio1");
/// Starting from GStreamer 1.20, application developers are strongly advised to migrate to `GstPlay`.
/// `gstplayer.Player` will be deprecated in 1.20 and most likely removed by 1.24.
pub const Player = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gstplayer.PlayerClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const audio_video_offset = struct {
            pub const name = "audio-video-offset";

            pub const Type = i64;
        };

        pub const current_audio_track = struct {
            pub const name = "current-audio-track";

            pub const Type = ?*gstplayer.PlayerAudioInfo;
        };

        pub const current_subtitle_track = struct {
            pub const name = "current-subtitle-track";

            pub const Type = ?*gstplayer.PlayerSubtitleInfo;
        };

        pub const current_video_track = struct {
            pub const name = "current-video-track";

            pub const Type = ?*gstplayer.PlayerVideoInfo;
        };

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

            pub const Type = u64;
        };

        pub const media_info = struct {
            pub const name = "media-info";

            pub const Type = ?*gstplayer.PlayerMediaInfo;
        };

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

            pub const Type = c_int;
        };

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

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

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

            pub const Type = u64;
        };

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

            pub const Type = f64;
        };

        pub const signal_dispatcher = struct {
            pub const name = "signal-dispatcher";

            pub const Type = ?*gstplayer.PlayerSignalDispatcher;
        };

        pub const subtitle_video_offset = struct {
            pub const name = "subtitle-video-offset";

            pub const Type = i64;
        };

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

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

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

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

        pub const video_multiview_flags = struct {
            pub const name = "video-multiview-flags";

            pub const Type = gstvideo.VideoMultiviewFlags;
        };

        pub const video_multiview_mode = struct {
            pub const name = "video-multiview-mode";

            pub const Type = gstvideo.VideoMultiviewFramePacking;
        };

        pub const video_renderer = struct {
            pub const name = "video-renderer";

            pub const Type = ?*gstplayer.PlayerVideoRenderer;
        };

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

            pub const Type = f64;
        };
    };

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

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

        pub const duration_changed = struct {
            pub const name = "duration-changed";

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

        pub const end_of_stream = struct {
            pub const name = "end-of-stream";

            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(Player, p_instance))),
                    gobject.signalLookup("end-of-stream", Player.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        pub const @"error" = struct {
            pub const name = "error";

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

        pub const media_info_updated = struct {
            pub const name = "media-info-updated";

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

        pub const mute_changed = struct {
            pub const name = "mute-changed";

            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(Player, p_instance))),
                    gobject.signalLookup("mute-changed", Player.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

        pub const position_updated = struct {
            pub const name = "position-updated";

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

        pub const seek_done = struct {
            pub const name = "seek-done";

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

        pub const state_changed = struct {
            pub const name = "state-changed";

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

        pub const uri_loaded = struct {
            pub const name = "uri-loaded";

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

        pub const video_dimensions_changed = struct {
            pub const name = "video-dimensions-changed";

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

        pub const volume_changed = struct {
            pub const name = "volume-changed";

            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(Player, p_instance))),
                    gobject.signalLookup("volume-changed", Player.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };

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

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_object: *glib.Error, 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(Player, p_instance))),
                    gobject.signalLookup("warning", Player.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_player_config_get_position_update_interval(p_config: *const gst.Structure) c_uint;
    pub const configGetPositionUpdateInterval = gst_player_config_get_position_update_interval;

    extern fn gst_player_config_get_seek_accurate(p_config: *const gst.Structure) c_int;
    pub const configGetSeekAccurate = gst_player_config_get_seek_accurate;

    /// Return the user agent which has been configured using
    /// `gstplayer.Player.configSetUserAgent` if any.
    extern fn gst_player_config_get_user_agent(p_config: *const gst.Structure) ?[*:0]u8;
    pub const configGetUserAgent = gst_player_config_get_user_agent;

    /// set interval in milliseconds between two position-updated signals.
    /// pass 0 to stop updating the position.
    extern fn gst_player_config_set_position_update_interval(p_config: *gst.Structure, p_interval: c_uint) void;
    pub const configSetPositionUpdateInterval = gst_player_config_set_position_update_interval;

    /// Enable or disable accurate seeking. When enabled, elements will try harder
    /// to seek as accurately as possible to the requested seek position. Generally
    /// it will be slower especially for formats that don't have any indexes or
    /// timestamp markers in the stream.
    ///
    /// If accurate seeking is disabled, elements will seek as close as the request
    /// position without slowing down seeking too much.
    ///
    /// Accurate seeking is disabled by default.
    extern fn gst_player_config_set_seek_accurate(p_config: *gst.Structure, p_accurate: c_int) void;
    pub const configSetSeekAccurate = gst_player_config_set_seek_accurate;

    /// Set the user agent to pass to the server if `player` needs to connect
    /// to a server during playback. This is typically used when playing HTTP
    /// or RTSP streams.
    extern fn gst_player_config_set_user_agent(p_config: *gst.Structure, p_agent: ?[*:0]const u8) void;
    pub const configSetUserAgent = gst_player_config_set_user_agent;

    extern fn gst_player_get_audio_streams(p_info: *const gstplayer.PlayerMediaInfo) *glib.List;
    pub const getAudioStreams = gst_player_get_audio_streams;

    extern fn gst_player_get_subtitle_streams(p_info: *const gstplayer.PlayerMediaInfo) *glib.List;
    pub const getSubtitleStreams = gst_player_get_subtitle_streams;

    extern fn gst_player_get_video_streams(p_info: *const gstplayer.PlayerMediaInfo) *glib.List;
    pub const getVideoStreams = gst_player_get_video_streams;

    /// Frees a `NULL` terminated array of `gstplayer.PlayerVisualization`.
    extern fn gst_player_visualizations_free(p_viss: **gstplayer.PlayerVisualization) void;
    pub const visualizationsFree = gst_player_visualizations_free;

    extern fn gst_player_visualizations_get() [*]*gstplayer.PlayerVisualization;
    pub const visualizationsGet = gst_player_visualizations_get;

    /// Creates a new `gstplayer.Player` instance that uses `signal_dispatcher` to dispatch
    /// signals to some event loop system, or emits signals directly if NULL is
    /// passed. See `gstplayer.PlayerGMainContextSignalDispatcher.new`.
    ///
    /// Video is going to be rendered by `video_renderer`, or if `NULL` is provided
    /// no special video set up will be done and some default handling will be
    /// performed.
    ///
    /// This also initializes GStreamer via ``gst.init`` on the first call if this
    /// didn't happen before.
    extern fn gst_player_new(p_video_renderer: ?*gstplayer.PlayerVideoRenderer, p_signal_dispatcher: ?*gstplayer.PlayerSignalDispatcher) *gstplayer.Player;
    pub const new = gst_player_new;

    /// Retrieve the current value of audio-video-offset property
    extern fn gst_player_get_audio_video_offset(p_player: *Player) i64;
    pub const getAudioVideoOffset = gst_player_get_audio_video_offset;

    /// Retrieve the current value of the indicated `type`.
    extern fn gst_player_get_color_balance(p_player: *Player, p_type: gstplayer.PlayerColorBalanceType) f64;
    pub const getColorBalance = gst_player_get_color_balance;

    /// Get a copy of the current configuration of the player. This configuration
    /// can either be modified and used for the `gstplayer.Player.setConfig` call
    /// or it must be freed after usage.
    extern fn gst_player_get_config(p_player: *Player) *gst.Structure;
    pub const getConfig = gst_player_get_config;

    /// A Function to get current audio `gstplayer.PlayerAudioInfo` instance.
    extern fn gst_player_get_current_audio_track(p_player: *Player) ?*gstplayer.PlayerAudioInfo;
    pub const getCurrentAudioTrack = gst_player_get_current_audio_track;

    /// A Function to get current subtitle `gstplayer.PlayerSubtitleInfo` instance.
    extern fn gst_player_get_current_subtitle_track(p_player: *Player) ?*gstplayer.PlayerSubtitleInfo;
    pub const getCurrentSubtitleTrack = gst_player_get_current_subtitle_track;

    /// A Function to get current video `gstplayer.PlayerVideoInfo` instance.
    extern fn gst_player_get_current_video_track(p_player: *Player) ?*gstplayer.PlayerVideoInfo;
    pub const getCurrentVideoTrack = gst_player_get_current_video_track;

    extern fn gst_player_get_current_visualization(p_player: *Player) ?[*:0]u8;
    pub const getCurrentVisualization = gst_player_get_current_visualization;

    /// Retrieves the duration of the media stream that self represents.
    extern fn gst_player_get_duration(p_player: *Player) gst.ClockTime;
    pub const getDuration = gst_player_get_duration;

    /// A Function to get the current media info `gstplayer.PlayerMediaInfo` instance.
    extern fn gst_player_get_media_info(p_player: *Player) ?*gstplayer.PlayerMediaInfo;
    pub const getMediaInfo = gst_player_get_media_info;

    /// Retrieve the current value of the indicated `type`.
    extern fn gst_player_get_multiview_flags(p_player: *Player) gstvideo.VideoMultiviewFlags;
    pub const getMultiviewFlags = gst_player_get_multiview_flags;

    /// Retrieve the current value of the indicated `type`.
    extern fn gst_player_get_multiview_mode(p_player: *Player) gstvideo.VideoMultiviewFramePacking;
    pub const getMultiviewMode = gst_player_get_multiview_mode;

    extern fn gst_player_get_mute(p_player: *Player) c_int;
    pub const getMute = gst_player_get_mute;

    extern fn gst_player_get_pipeline(p_player: *Player) *gst.Element;
    pub const getPipeline = gst_player_get_pipeline;

    extern fn gst_player_get_position(p_player: *Player) gst.ClockTime;
    pub const getPosition = gst_player_get_position;

    extern fn gst_player_get_rate(p_player: *Player) f64;
    pub const getRate = gst_player_get_rate;

    /// current subtitle URI
    extern fn gst_player_get_subtitle_uri(p_player: *Player) ?[*:0]u8;
    pub const getSubtitleUri = gst_player_get_subtitle_uri;

    /// Retrieve the current value of subtitle-video-offset property
    extern fn gst_player_get_subtitle_video_offset(p_player: *Player) i64;
    pub const getSubtitleVideoOffset = gst_player_get_subtitle_video_offset;

    /// Gets the URI of the currently-playing stream.
    extern fn gst_player_get_uri(p_player: *Player) ?[*:0]u8;
    pub const getUri = gst_player_get_uri;

    /// Get a snapshot of the currently selected video stream, if any. The format can be
    /// selected with `format` and optional configuration is possible with `config`
    /// Currently supported settings are:
    /// - width, height of type G_TYPE_INT
    /// - pixel-aspect-ratio of type GST_TYPE_FRACTION
    ///  Except for GST_PLAYER_THUMBNAIL_RAW_NATIVE format, if no config is set, pixel-aspect-ratio would be 1/1
    extern fn gst_player_get_video_snapshot(p_player: *Player, p_format: gstplayer.PlayerSnapshotFormat, p_config: ?*const gst.Structure) ?*gst.Sample;
    pub const getVideoSnapshot = gst_player_get_video_snapshot;

    /// Returns the current volume level, as a percentage between 0 and 1.
    extern fn gst_player_get_volume(p_player: *Player) f64;
    pub const getVolume = gst_player_get_volume;

    /// Checks whether the `player` has color balance support available.
    extern fn gst_player_has_color_balance(p_player: *Player) c_int;
    pub const hasColorBalance = gst_player_has_color_balance;

    /// Pauses the current stream.
    extern fn gst_player_pause(p_player: *Player) void;
    pub const pause = gst_player_pause;

    /// Request to play the loaded stream.
    extern fn gst_player_play(p_player: *Player) void;
    pub const play = gst_player_play;

    /// Seeks the currently-playing stream to the absolute `position` time
    /// in nanoseconds.
    extern fn gst_player_seek(p_player: *Player, p_position: gst.ClockTime) void;
    pub const seek = gst_player_seek;

    extern fn gst_player_set_audio_track(p_player: *Player, p_stream_index: c_int) c_int;
    pub const setAudioTrack = gst_player_set_audio_track;

    /// Enable or disable the current audio track.
    extern fn gst_player_set_audio_track_enabled(p_player: *Player, p_enabled: c_int) void;
    pub const setAudioTrackEnabled = gst_player_set_audio_track_enabled;

    /// Sets audio-video-offset property by value of `offset`
    extern fn gst_player_set_audio_video_offset(p_player: *Player, p_offset: i64) void;
    pub const setAudioVideoOffset = gst_player_set_audio_video_offset;

    /// Sets the current value of the indicated channel `type` to the passed
    /// value.
    extern fn gst_player_set_color_balance(p_player: *Player, p_type: gstplayer.PlayerColorBalanceType, p_value: f64) void;
    pub const setColorBalance = gst_player_set_color_balance;

    /// Set the configuration of the player. If the player is already configured, and
    /// the configuration haven't change, this function will return `TRUE`. If the
    /// player is not in the GST_PLAYER_STATE_STOPPED, this method will return `FALSE`
    /// and active configuration will remain.
    ///
    /// `config` is a `gst.Structure` that contains the configuration parameters for
    /// the player.
    ///
    /// This function takes ownership of `config`.
    extern fn gst_player_set_config(p_player: *Player, p_config: *gst.Structure) c_int;
    pub const setConfig = gst_player_set_config;

    /// Sets the current value of the indicated mode `type` to the passed
    /// value.
    extern fn gst_player_set_multiview_flags(p_player: *Player, p_flags: gstvideo.VideoMultiviewFlags) void;
    pub const setMultiviewFlags = gst_player_set_multiview_flags;

    /// Sets the current value of the indicated mode `type` to the passed
    /// value.
    extern fn gst_player_set_multiview_mode(p_player: *Player, p_mode: gstvideo.VideoMultiviewFramePacking) void;
    pub const setMultiviewMode = gst_player_set_multiview_mode;

    /// `TRUE` if the currently-playing stream should be muted.
    extern fn gst_player_set_mute(p_player: *Player, p_val: c_int) void;
    pub const setMute = gst_player_set_mute;

    /// Playback at specified rate
    extern fn gst_player_set_rate(p_player: *Player, p_rate: f64) void;
    pub const setRate = gst_player_set_rate;

    extern fn gst_player_set_subtitle_track(p_player: *Player, p_stream_index: c_int) c_int;
    pub const setSubtitleTrack = gst_player_set_subtitle_track;

    /// Enable or disable the current subtitle track.
    extern fn gst_player_set_subtitle_track_enabled(p_player: *Player, p_enabled: c_int) void;
    pub const setSubtitleTrackEnabled = gst_player_set_subtitle_track_enabled;

    /// Sets the external subtitle URI. This should be combined with a call to
    /// gst_player_set_subtitle_track_enabled(`player`, TRUE) so the subtitles are actually
    /// rendered.
    extern fn gst_player_set_subtitle_uri(p_player: *Player, p_uri: ?[*:0]const u8) void;
    pub const setSubtitleUri = gst_player_set_subtitle_uri;

    /// Sets subtitle-video-offset property by value of `offset`
    extern fn gst_player_set_subtitle_video_offset(p_player: *Player, p_offset: i64) void;
    pub const setSubtitleVideoOffset = gst_player_set_subtitle_video_offset;

    /// Sets the next URI to play.
    extern fn gst_player_set_uri(p_player: *Player, p_uri: ?[*:0]const u8) void;
    pub const setUri = gst_player_set_uri;

    extern fn gst_player_set_video_track(p_player: *Player, p_stream_index: c_int) c_int;
    pub const setVideoTrack = gst_player_set_video_track;

    /// Enable or disable the current video track.
    extern fn gst_player_set_video_track_enabled(p_player: *Player, p_enabled: c_int) void;
    pub const setVideoTrackEnabled = gst_player_set_video_track_enabled;

    extern fn gst_player_set_visualization(p_player: *Player, p_name: ?[*:0]const u8) c_int;
    pub const setVisualization = gst_player_set_visualization;

    /// Enable or disable the visualization.
    extern fn gst_player_set_visualization_enabled(p_player: *Player, p_enabled: c_int) void;
    pub const setVisualizationEnabled = gst_player_set_visualization_enabled;

    /// Sets the volume level of the stream as a percentage between 0 and 1.
    ///
    /// This volume is a linear factor. For showing the volume in a GUI it
    /// might make sense to first convert from a different format. Volume sliders
    /// should usually use a cubic volume. See `gstaudio.streamVolumeConvertVolume`.
    extern fn gst_player_set_volume(p_player: *Player, p_val: f64) void;
    pub const setVolume = gst_player_set_volume;

    /// Stops playing the current stream and resets to the first position
    /// in the stream.
    extern fn gst_player_stop(p_player: *Player) void;
    pub const stop = gst_player_stop;

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

    extern fn g_object_ref(p_self: *gstplayer.Player) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.Player) void;
    pub const unref = g_object_unref;

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

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

/// `gstplayer.PlayerStreamInfo` specific to audio streams.
pub const PlayerAudioInfo = opaque {
    pub const Parent = gstplayer.PlayerStreamInfo;
    pub const Implements = [_]type{};
    pub const Class = gstplayer.PlayerAudioInfoClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_player_audio_info_get_bitrate(p_info: *const PlayerAudioInfo) c_int;
    pub const getBitrate = gst_player_audio_info_get_bitrate;

    extern fn gst_player_audio_info_get_channels(p_info: *const PlayerAudioInfo) c_int;
    pub const getChannels = gst_player_audio_info_get_channels;

    extern fn gst_player_audio_info_get_language(p_info: *const PlayerAudioInfo) ?[*:0]const u8;
    pub const getLanguage = gst_player_audio_info_get_language;

    extern fn gst_player_audio_info_get_max_bitrate(p_info: *const PlayerAudioInfo) c_int;
    pub const getMaxBitrate = gst_player_audio_info_get_max_bitrate;

    extern fn gst_player_audio_info_get_sample_rate(p_info: *const PlayerAudioInfo) c_int;
    pub const getSampleRate = gst_player_audio_info_get_sample_rate;

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerAudioInfo) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerAudioInfo) void;
    pub const unref = g_object_unref;

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

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

pub const PlayerGMainContextSignalDispatcher = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{gstplayer.PlayerSignalDispatcher};
    pub const Class = gstplayer.PlayerGMainContextSignalDispatcherClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const application_context = struct {
            pub const name = "application-context";

            pub const Type = ?*glib.MainContext;
        };
    };

    pub const signals = struct {};

    /// Creates a new GstPlayerSignalDispatcher that uses `application_context`,
    /// or the thread default one if `NULL` is used. See `gstplayer.Player.new`.
    extern fn gst_player_g_main_context_signal_dispatcher_new(p_application_context: ?*glib.MainContext) *gstplayer.PlayerSignalDispatcher;
    pub const new = gst_player_g_main_context_signal_dispatcher_new;

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerGMainContextSignalDispatcher) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerGMainContextSignalDispatcher) void;
    pub const unref = g_object_unref;

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

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

/// Structure containing the media information of a URI.
pub const PlayerMediaInfo = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gstplayer.PlayerMediaInfoClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_player_media_info_get_audio_streams(p_info: *const PlayerMediaInfo) *glib.List;
    pub const getAudioStreams = gst_player_media_info_get_audio_streams;

    extern fn gst_player_media_info_get_container_format(p_info: *const PlayerMediaInfo) ?[*:0]const u8;
    pub const getContainerFormat = gst_player_media_info_get_container_format;

    extern fn gst_player_media_info_get_duration(p_info: *const PlayerMediaInfo) gst.ClockTime;
    pub const getDuration = gst_player_media_info_get_duration;

    /// Function to get the image (or preview-image) stored in taglist.
    /// Application can use `gst_sample_*`_`` API's to get caps, buffer etc.
    extern fn gst_player_media_info_get_image_sample(p_info: *const PlayerMediaInfo) ?*gst.Sample;
    pub const getImageSample = gst_player_media_info_get_image_sample;

    extern fn gst_player_media_info_get_number_of_audio_streams(p_info: *const PlayerMediaInfo) c_uint;
    pub const getNumberOfAudioStreams = gst_player_media_info_get_number_of_audio_streams;

    extern fn gst_player_media_info_get_number_of_streams(p_info: *const PlayerMediaInfo) c_uint;
    pub const getNumberOfStreams = gst_player_media_info_get_number_of_streams;

    extern fn gst_player_media_info_get_number_of_subtitle_streams(p_info: *const PlayerMediaInfo) c_uint;
    pub const getNumberOfSubtitleStreams = gst_player_media_info_get_number_of_subtitle_streams;

    extern fn gst_player_media_info_get_number_of_video_streams(p_info: *const PlayerMediaInfo) c_uint;
    pub const getNumberOfVideoStreams = gst_player_media_info_get_number_of_video_streams;

    extern fn gst_player_media_info_get_stream_list(p_info: *const PlayerMediaInfo) *glib.List;
    pub const getStreamList = gst_player_media_info_get_stream_list;

    extern fn gst_player_media_info_get_subtitle_streams(p_info: *const PlayerMediaInfo) *glib.List;
    pub const getSubtitleStreams = gst_player_media_info_get_subtitle_streams;

    extern fn gst_player_media_info_get_tags(p_info: *const PlayerMediaInfo) ?*gst.TagList;
    pub const getTags = gst_player_media_info_get_tags;

    extern fn gst_player_media_info_get_title(p_info: *const PlayerMediaInfo) ?[*:0]const u8;
    pub const getTitle = gst_player_media_info_get_title;

    extern fn gst_player_media_info_get_uri(p_info: *const PlayerMediaInfo) [*:0]const u8;
    pub const getUri = gst_player_media_info_get_uri;

    extern fn gst_player_media_info_get_video_streams(p_info: *const PlayerMediaInfo) *glib.List;
    pub const getVideoStreams = gst_player_media_info_get_video_streams;

    extern fn gst_player_media_info_is_live(p_info: *const PlayerMediaInfo) c_int;
    pub const isLive = gst_player_media_info_is_live;

    extern fn gst_player_media_info_is_seekable(p_info: *const PlayerMediaInfo) c_int;
    pub const isSeekable = gst_player_media_info_is_seekable;

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerMediaInfo) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerMediaInfo) void;
    pub const unref = g_object_unref;

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

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

/// Base structure for information concerning a media stream. Depending on
/// the stream type, one can find more media-specific information in
/// `gstplayer.PlayerVideoInfo`, `gstplayer.PlayerAudioInfo`, `gstplayer.PlayerSubtitleInfo`.
pub const PlayerStreamInfo = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gstplayer.PlayerStreamInfoClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_player_stream_info_get_caps(p_info: *const PlayerStreamInfo) ?*gst.Caps;
    pub const getCaps = gst_player_stream_info_get_caps;

    /// A string describing codec used in `gstplayer.PlayerStreamInfo`.
    extern fn gst_player_stream_info_get_codec(p_info: *const PlayerStreamInfo) ?[*:0]const u8;
    pub const getCodec = gst_player_stream_info_get_codec;

    /// Function to get stream index from `gstplayer.PlayerStreamInfo` instance or -1 if
    /// unknown.
    extern fn gst_player_stream_info_get_index(p_info: *const PlayerStreamInfo) c_int;
    pub const getIndex = gst_player_stream_info_get_index;

    /// Function to return human readable name for the stream type
    /// of the given `info` (ex: "audio", "video", "subtitle")
    extern fn gst_player_stream_info_get_stream_type(p_info: *const PlayerStreamInfo) [*:0]const u8;
    pub const getStreamType = gst_player_stream_info_get_stream_type;

    extern fn gst_player_stream_info_get_tags(p_info: *const PlayerStreamInfo) ?*gst.TagList;
    pub const getTags = gst_player_stream_info_get_tags;

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerStreamInfo) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerStreamInfo) void;
    pub const unref = g_object_unref;

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

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

/// `gstplayer.PlayerStreamInfo` specific to subtitle streams.
pub const PlayerSubtitleInfo = opaque {
    pub const Parent = gstplayer.PlayerStreamInfo;
    pub const Implements = [_]type{};
    pub const Class = gstplayer.PlayerSubtitleInfoClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_player_subtitle_info_get_language(p_info: *const PlayerSubtitleInfo) ?[*:0]const u8;
    pub const getLanguage = gst_player_subtitle_info_get_language;

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerSubtitleInfo) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerSubtitleInfo) void;
    pub const unref = g_object_unref;

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

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

/// `gstplayer.PlayerStreamInfo` specific to video streams.
pub const PlayerVideoInfo = opaque {
    pub const Parent = gstplayer.PlayerStreamInfo;
    pub const Implements = [_]type{};
    pub const Class = gstplayer.PlayerVideoInfoClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_player_video_info_get_bitrate(p_info: *const PlayerVideoInfo) c_int;
    pub const getBitrate = gst_player_video_info_get_bitrate;

    extern fn gst_player_video_info_get_framerate(p_info: *const PlayerVideoInfo, p_fps_n: *c_int, p_fps_d: *c_int) void;
    pub const getFramerate = gst_player_video_info_get_framerate;

    extern fn gst_player_video_info_get_height(p_info: *const PlayerVideoInfo) c_int;
    pub const getHeight = gst_player_video_info_get_height;

    extern fn gst_player_video_info_get_max_bitrate(p_info: *const PlayerVideoInfo) c_int;
    pub const getMaxBitrate = gst_player_video_info_get_max_bitrate;

    /// Returns the pixel aspect ratio in `par_n` and `par_d`
    extern fn gst_player_video_info_get_pixel_aspect_ratio(p_info: *const PlayerVideoInfo, p_par_n: *c_uint, p_par_d: *c_uint) void;
    pub const getPixelAspectRatio = gst_player_video_info_get_pixel_aspect_ratio;

    extern fn gst_player_video_info_get_width(p_info: *const PlayerVideoInfo) c_int;
    pub const getWidth = gst_player_video_info_get_width;

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerVideoInfo) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerVideoInfo) void;
    pub const unref = g_object_unref;

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

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

pub const PlayerVideoOverlayVideoRenderer = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{gstplayer.PlayerVideoRenderer};
    pub const Class = gstplayer.PlayerVideoOverlayVideoRendererClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const video_sink = struct {
            pub const name = "video-sink";

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

        pub const window_handle = struct {
            pub const name = "window-handle";

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

    pub const signals = struct {};

    extern fn gst_player_video_overlay_video_renderer_new(p_window_handle: ?*anyopaque) *gstplayer.PlayerVideoRenderer;
    pub const new = gst_player_video_overlay_video_renderer_new;

    extern fn gst_player_video_overlay_video_renderer_new_with_sink(p_window_handle: ?*anyopaque, p_video_sink: *gst.Element) *gstplayer.PlayerVideoRenderer;
    pub const newWithSink = gst_player_video_overlay_video_renderer_new_with_sink;

    /// 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_player_video_overlay_video_renderer_expose(p_self: *PlayerVideoOverlayVideoRenderer) void;
    pub const expose = gst_player_video_overlay_video_renderer_expose;

    /// Return the currently configured render rectangle. See `gstplayer.PlayerVideoOverlayVideoRenderer.setRenderRectangle`
    /// for details.
    extern fn gst_player_video_overlay_video_renderer_get_render_rectangle(p_self: *PlayerVideoOverlayVideoRenderer, p_x: ?*c_int, p_y: ?*c_int, p_width: ?*c_int, p_height: ?*c_int) void;
    pub const getRenderRectangle = gst_player_video_overlay_video_renderer_get_render_rectangle;

    extern fn gst_player_video_overlay_video_renderer_get_window_handle(p_self: *PlayerVideoOverlayVideoRenderer) ?*anyopaque;
    pub const getWindowHandle = gst_player_video_overlay_video_renderer_get_window_handle;

    /// Configure a subregion as a video target within the window set by
    /// `gstplayer.PlayerVideoOverlayVideoRenderer.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 overlaid to
    /// a specific region of that window only. After setting the new rectangle one
    /// should call `gstplayer.PlayerVideoOverlayVideoRenderer.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_player_video_overlay_video_renderer_set_render_rectangle(p_self: *PlayerVideoOverlayVideoRenderer, p_x: c_int, p_y: c_int, p_width: c_int, p_height: c_int) void;
    pub const setRenderRectangle = gst_player_video_overlay_video_renderer_set_render_rectangle;

    /// Sets the platform specific window handle into which the video
    /// should be rendered
    extern fn gst_player_video_overlay_video_renderer_set_window_handle(p_self: *PlayerVideoOverlayVideoRenderer, p_window_handle: ?*anyopaque) void;
    pub const setWindowHandle = gst_player_video_overlay_video_renderer_set_window_handle;

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerVideoOverlayVideoRenderer) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerVideoOverlayVideoRenderer) void;
    pub const unref = g_object_unref;

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

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

pub const PlayerSignalDispatcher = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstplayer.PlayerSignalDispatcherInterface;
    pub const virtual_methods = struct {
        pub const dispatch = struct {
            pub fn call(p_class: anytype, p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_player: *gstplayer.Player, p_emitter: gstplayer.PlayerSignalDispatcherFunc, p_data: ?*anyopaque, p_destroy: ?glib.DestroyNotify) void {
                return gobject.ext.as(PlayerSignalDispatcher.Iface, p_class).f_dispatch.?(gobject.ext.as(PlayerSignalDispatcher, p_self), p_player, p_emitter, p_data, p_destroy);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_player: *gstplayer.Player, p_emitter: gstplayer.PlayerSignalDispatcherFunc, p_data: ?*anyopaque, p_destroy: ?glib.DestroyNotify) callconv(.c) void) void {
                gobject.ext.as(PlayerSignalDispatcher.Iface, p_class).f_dispatch = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerSignalDispatcher) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerSignalDispatcher) void;
    pub const unref = g_object_unref;

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

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

pub const PlayerVideoRenderer = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstplayer.PlayerVideoRendererInterface;
    pub const virtual_methods = struct {
        pub const create_video_sink = struct {
            pub fn call(p_class: anytype, p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_player: *gstplayer.Player) *gst.Element {
                return gobject.ext.as(PlayerVideoRenderer.Iface, p_class).f_create_video_sink.?(gobject.ext.as(PlayerVideoRenderer, p_self), p_player);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_self: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_player: *gstplayer.Player) callconv(.c) *gst.Element) void {
                gobject.ext.as(PlayerVideoRenderer.Iface, p_class).f_create_video_sink = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

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

    extern fn g_object_ref(p_self: *gstplayer.PlayerVideoRenderer) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstplayer.PlayerVideoRenderer) void;
    pub const unref = g_object_unref;

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

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

pub const PlayerAudioInfoClass = opaque {
    pub const Instance = gstplayer.PlayerAudioInfo;

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

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

pub const PlayerClass = opaque {
    pub const Instance = gstplayer.Player;

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

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

pub const PlayerGMainContextSignalDispatcherClass = opaque {
    pub const Instance = gstplayer.PlayerGMainContextSignalDispatcher;

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

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

pub const PlayerMediaInfoClass = opaque {
    pub const Instance = gstplayer.PlayerMediaInfo;

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

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

pub const PlayerSignalDispatcherInterface = extern struct {
    pub const Instance = gstplayer.PlayerSignalDispatcher;

    f_parent_iface: gobject.TypeInterface,
    f_dispatch: ?*const fn (p_self: *gstplayer.PlayerSignalDispatcher, p_player: *gstplayer.Player, p_emitter: gstplayer.PlayerSignalDispatcherFunc, p_data: ?*anyopaque, p_destroy: ?glib.DestroyNotify) callconv(.c) void,

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

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

pub const PlayerStreamInfoClass = opaque {
    pub const Instance = gstplayer.PlayerStreamInfo;

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

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

pub const PlayerSubtitleInfoClass = opaque {
    pub const Instance = gstplayer.PlayerSubtitleInfo;

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

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

pub const PlayerVideoInfoClass = opaque {
    pub const Instance = gstplayer.PlayerVideoInfo;

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

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

pub const PlayerVideoOverlayVideoRendererClass = opaque {
    pub const Instance = gstplayer.PlayerVideoOverlayVideoRenderer;

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

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

pub const PlayerVideoRendererInterface = extern struct {
    pub const Instance = gstplayer.PlayerVideoRenderer;

    f_parent_iface: gobject.TypeInterface,
    f_create_video_sink: ?*const fn (p_self: *gstplayer.PlayerVideoRenderer, p_player: *gstplayer.Player) callconv(.c) *gst.Element,

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

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

/// A `gstplayer.PlayerVisualization` descriptor.
pub const PlayerVisualization = extern struct {
    /// name of the visualization.
    f_name: ?[*:0]u8,
    /// description of the visualization.
    f_description: ?[*:0]u8,

    /// Makes a copy of the `gstplayer.PlayerVisualization`. The result must be
    /// freed using `gstplayer.PlayerVisualization.free`.
    extern fn gst_player_visualization_copy(p_vis: *const PlayerVisualization) *gstplayer.PlayerVisualization;
    pub const copy = gst_player_visualization_copy;

    /// Frees a `gstplayer.PlayerVisualization`.
    extern fn gst_player_visualization_free(p_vis: *PlayerVisualization) void;
    pub const free = gst_player_visualization_free;

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

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

pub const PlayerColorBalanceType = enum(c_int) {
    hue = 3,
    brightness = 0,
    saturation = 2,
    contrast = 1,
    _,

    /// Gets a string representing the given color balance type.
    extern fn gst_player_color_balance_type_get_name(p_type: gstplayer.PlayerColorBalanceType) [*:0]const u8;
    pub const getName = gst_player_color_balance_type_get_name;

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

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

pub const PlayerError = enum(c_int) {
    failed = 0,
    _,

    /// Gets a string representing the given error.
    extern fn gst_player_error_get_name(p_error: gstplayer.PlayerError) [*:0]const u8;
    pub const getName = gst_player_error_get_name;

    extern fn gst_player_error_quark() glib.Quark;
    pub const quark = gst_player_error_quark;

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

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

pub const PlayerSnapshotFormat = enum(c_int) {
    raw_native = 0,
    raw_xrgb = 1,
    raw_bgrx = 2,
    jpg = 3,
    png = 4,
    _,

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

pub const PlayerState = enum(c_int) {
    stopped = 0,
    buffering = 1,
    paused = 2,
    playing = 3,
    _,

    /// Gets a string representing the given state.
    extern fn gst_player_state_get_name(p_state: gstplayer.PlayerState) [*:0]const u8;
    pub const getName = gst_player_state_get_name;

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

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

pub const PlayerSignalDispatcherFunc = *const fn (p_data: ?*anyopaque) callconv(.c) void;

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