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

const std = @import("std");
const compat = @import("compat");
const gstsdp = @import("gstsdp1");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
const gstbase = @import("gstbase1");
const gio = @import("gio2");
/// This interface is implemented e.g. by the Windows Media Streaming RTSP
///  exentension (rtspwms) and the RealMedia RTSP extension (rtspreal).
pub const RTSPExtension = opaque {
    pub const Prerequisites = [_]type{gobject.Object};
    pub const Iface = gstrtsp.RTSPExtensionInterface;
    pub const virtual_methods = struct {
        pub const after_send = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_after_send.?(gobject.ext.as(RTSPExtension, p_ext), p_req, p_resp);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_after_send = @ptrCast(p_implementation);
            }
        };

        pub const before_send = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_before_send.?(gobject.ext.as(RTSPExtension, p_ext), p_req);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_before_send = @ptrCast(p_implementation);
            }
        };

        pub const configure_stream = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps) c_int {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_configure_stream.?(gobject.ext.as(RTSPExtension, p_ext), p_caps);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps) callconv(.c) c_int) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_configure_stream = @ptrCast(p_implementation);
            }
        };

        pub const detect_server = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_resp: *gstrtsp.RTSPMessage) c_int {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_detect_server.?(gobject.ext.as(RTSPExtension, p_ext), p_resp);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_resp: *gstrtsp.RTSPMessage) callconv(.c) c_int) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_detect_server = @ptrCast(p_implementation);
            }
        };

        pub const get_transports = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_protocols: gstrtsp.RTSPLowerTrans, p_transport: *[*:0]u8) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_get_transports.?(gobject.ext.as(RTSPExtension, p_ext), p_protocols, p_transport);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_protocols: gstrtsp.RTSPLowerTrans, p_transport: *[*:0]u8) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_get_transports = @ptrCast(p_implementation);
            }
        };

        pub const parse_sdp = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_sdp: *gstsdp.SDPMessage, p_s: *gst.Structure) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_parse_sdp.?(gobject.ext.as(RTSPExtension, p_ext), p_sdp, p_s);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_sdp: *gstsdp.SDPMessage, p_s: *gst.Structure) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_parse_sdp = @ptrCast(p_implementation);
            }
        };

        pub const receive_request = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_receive_request.?(gobject.ext.as(RTSPExtension, p_ext), p_req);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_receive_request = @ptrCast(p_implementation);
            }
        };

        pub const send = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_send.?(gobject.ext.as(RTSPExtension, p_ext), p_req, p_resp);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_send = @ptrCast(p_implementation);
            }
        };

        pub const setup_media = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_media: *gstsdp.SDPMedia) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_setup_media.?(gobject.ext.as(RTSPExtension, p_ext), p_media);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_media: *gstsdp.SDPMedia) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_setup_media = @ptrCast(p_implementation);
            }
        };

        pub const stream_select = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_url: *gstrtsp.RTSPUrl) gstrtsp.RTSPResult {
                return gobject.ext.as(RTSPExtension.Iface, p_class).f_stream_select.?(gobject.ext.as(RTSPExtension, p_ext), p_url);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_url: *gstrtsp.RTSPUrl) callconv(.c) gstrtsp.RTSPResult) void {
                gobject.ext.as(RTSPExtension.Iface, p_class).f_stream_select = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

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

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_object: ?*anyopaque, p_p0: ?*anyopaque, P_Data) callconv(.c) gstrtsp.RTSPResult, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(RTSPExtension, p_instance))),
                    gobject.signalLookup("send", RTSPExtension.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_rtsp_extension_after_send(p_ext: *RTSPExtension, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const afterSend = gst_rtsp_extension_after_send;

    extern fn gst_rtsp_extension_before_send(p_ext: *RTSPExtension, p_req: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const beforeSend = gst_rtsp_extension_before_send;

    extern fn gst_rtsp_extension_configure_stream(p_ext: *RTSPExtension, p_caps: *gst.Caps) c_int;
    pub const configureStream = gst_rtsp_extension_configure_stream;

    extern fn gst_rtsp_extension_detect_server(p_ext: *RTSPExtension, p_resp: *gstrtsp.RTSPMessage) c_int;
    pub const detectServer = gst_rtsp_extension_detect_server;

    extern fn gst_rtsp_extension_get_transports(p_ext: *RTSPExtension, p_protocols: gstrtsp.RTSPLowerTrans, p_transport: *[*:0]u8) gstrtsp.RTSPResult;
    pub const getTransports = gst_rtsp_extension_get_transports;

    extern fn gst_rtsp_extension_parse_sdp(p_ext: *RTSPExtension, p_sdp: *gstsdp.SDPMessage, p_s: *gst.Structure) gstrtsp.RTSPResult;
    pub const parseSdp = gst_rtsp_extension_parse_sdp;

    extern fn gst_rtsp_extension_receive_request(p_ext: *RTSPExtension, p_req: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const receiveRequest = gst_rtsp_extension_receive_request;

    extern fn gst_rtsp_extension_send(p_ext: *RTSPExtension, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const send = gst_rtsp_extension_send;

    extern fn gst_rtsp_extension_setup_media(p_ext: *RTSPExtension, p_media: *gstsdp.SDPMedia) gstrtsp.RTSPResult;
    pub const setupMedia = gst_rtsp_extension_setup_media;

    extern fn gst_rtsp_extension_stream_select(p_ext: *RTSPExtension, p_url: *gstrtsp.RTSPUrl) gstrtsp.RTSPResult;
    pub const streamSelect = gst_rtsp_extension_stream_select;

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

    extern fn g_object_ref(p_self: *gstrtsp.RTSPExtension) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstrtsp.RTSPExtension) void;
    pub const unref = g_object_unref;

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

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

/// RTSP Authentication credentials
pub const RTSPAuthCredential = extern struct {
    /// a `gstrtsp.RTSPAuthMethod`
    f_scheme: gstrtsp.RTSPAuthMethod,
    /// A NULL-terminated array of `gstrtsp.RTSPAuthParam`
    f_params: ?**gstrtsp.RTSPAuthParam,
    /// The authorization for the basic schem
    f_authorization: ?[*:0]u8,

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

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

/// RTSP Authentication parameter
pub const RTSPAuthParam = extern struct {
    /// The name of the parameter
    f_name: ?[*:0]u8,
    /// The value of the parameter
    f_value: ?[*:0]u8,

    extern fn gst_rtsp_auth_param_copy(p_param: *RTSPAuthParam) *gstrtsp.RTSPAuthParam;
    pub const copy = gst_rtsp_auth_param_copy;

    extern fn gst_rtsp_auth_param_free(p_param: *RTSPAuthParam) void;
    pub const free = gst_rtsp_auth_param_free;

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

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

/// This object manages the RTSP connection to the server. It provides function
/// to receive and send bytes and messages.
pub const RTSPConnection = opaque {
    /// Accept a new connection on `socket` and create a new `gstrtsp.RTSPConnection` for
    /// handling communication on new socket.
    extern fn gst_rtsp_connection_accept(p_socket: *gio.Socket, p_conn: ?**gstrtsp.RTSPConnection, p_cancellable: ?*gio.Cancellable) gstrtsp.RTSPResult;
    pub const accept = gst_rtsp_connection_accept;

    /// Create a newly allocated `gstrtsp.RTSPConnection` from `url` and store it in `conn`.
    /// The connection will not yet attempt to connect to `url`, use
    /// `gstrtsp.RTSPConnection.connect`.
    ///
    /// A copy of `url` will be made.
    extern fn gst_rtsp_connection_create(p_url: *const gstrtsp.RTSPUrl, p_conn: **gstrtsp.RTSPConnection) gstrtsp.RTSPResult;
    pub const create = gst_rtsp_connection_create;

    /// Create a new `gstrtsp.RTSPConnection` for handling communication on the existing
    /// socket `socket`. The `initial_buffer` contains zero terminated data already
    /// read from `socket` which should be used before starting to read new data.
    extern fn gst_rtsp_connection_create_from_socket(p_socket: *gio.Socket, p_ip: [*:0]const u8, p_port: u16, p_initial_buffer: [*:0]const u8, p_conn: ?**gstrtsp.RTSPConnection) gstrtsp.RTSPResult;
    pub const createFromSocket = gst_rtsp_connection_create_from_socket;

    /// Add header to be appended to any HTTP request made by connection.
    /// If the header already exists then the old header is replaced by the new header.
    ///
    /// Only applicable in HTTP tunnel mode.
    extern fn gst_rtsp_connection_add_extra_http_request_header(p_conn: *RTSPConnection, p_key: [*:0]const u8, p_value: [*:0]const u8) void;
    pub const addExtraHttpRequestHeader = gst_rtsp_connection_add_extra_http_request_header;

    /// Clear the list of authentication directives stored in `conn`.
    extern fn gst_rtsp_connection_clear_auth_params(p_conn: *RTSPConnection) void;
    pub const clearAuthParams = gst_rtsp_connection_clear_auth_params;

    /// Close the connected `conn`. After this call, the connection is in the same
    /// state as when it was first created.
    extern fn gst_rtsp_connection_close(p_conn: *RTSPConnection) gstrtsp.RTSPResult;
    pub const close = gst_rtsp_connection_close;

    /// Attempt to connect to the url of `conn` made with
    /// `gstrtsp.rtspConnectionCreate`. If `timeout` is `NULL` this function can block
    /// forever. If `timeout` contains a valid timeout, this function will return
    /// `GST_RTSP_ETIMEOUT` after the timeout expired.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_connect(p_conn: *RTSPConnection, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const connect = gst_rtsp_connection_connect;

    /// Attempt to connect to the url of `conn` made with
    /// `gstrtsp.rtspConnectionCreate`. If `timeout` is 0 this function can block
    /// forever. If `timeout` contains a valid timeout, this function will return
    /// `GST_RTSP_ETIMEOUT` after the timeout expired.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_connect_usec(p_conn: *RTSPConnection, p_timeout: i64) gstrtsp.RTSPResult;
    pub const connectUsec = gst_rtsp_connection_connect_usec;

    /// Attempt to connect to the url of `conn` made with
    /// `gstrtsp.rtspConnectionCreate`. If `timeout` is `NULL` this function can block
    /// forever. If `timeout` contains a valid timeout, this function will return
    /// `GST_RTSP_ETIMEOUT` after the timeout expired.  If `conn` is set to tunneled,
    /// `response` will contain a response to the tunneling request messages.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_connect_with_response(p_conn: *RTSPConnection, p_timeout: *glib.TimeVal, p_response: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const connectWithResponse = gst_rtsp_connection_connect_with_response;

    /// Attempt to connect to the url of `conn` made with
    /// `gstrtsp.rtspConnectionCreate`. If `timeout` is 0 this function can block
    /// forever. If `timeout` contains a valid timeout, this function will return
    /// `GST_RTSP_ETIMEOUT` after the timeout expired.  If `conn` is set to tunneled,
    /// `response` will contain a response to the tunneling request messages.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_connect_with_response_usec(p_conn: *RTSPConnection, p_timeout: i64, p_response: *gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const connectWithResponseUsec = gst_rtsp_connection_connect_with_response_usec;

    /// If `conn` received the first tunnel connection and `conn2` received
    /// the second tunnel connection, link the two connections together so that
    /// `conn` manages the tunneled connection.
    ///
    /// After this call, `conn2` cannot be used anymore and must be freed with
    /// `gstrtsp.RTSPConnection.free`.
    ///
    /// If `conn2` is `NULL` then only the base64 decoding context will be setup for
    /// `conn`.
    extern fn gst_rtsp_connection_do_tunnel(p_conn: *RTSPConnection, p_conn2: ?*gstrtsp.RTSPConnection) gstrtsp.RTSPResult;
    pub const doTunnel = gst_rtsp_connection_do_tunnel;

    /// Start or stop the flushing action on `conn`. When flushing, all current
    /// and future actions on `conn` will return `GST_RTSP_EINTR` until the connection
    /// is set to non-flushing mode again.
    extern fn gst_rtsp_connection_flush(p_conn: *RTSPConnection, p_flush: c_int) gstrtsp.RTSPResult;
    pub const flush = gst_rtsp_connection_flush;

    /// Close and free `conn`.
    extern fn gst_rtsp_connection_free(p_conn: *RTSPConnection) gstrtsp.RTSPResult;
    pub const free = gst_rtsp_connection_free;

    /// Get the ignore_x_server_reply value.
    extern fn gst_rtsp_connection_get_ignore_x_server_reply(p_conn: *const RTSPConnection) c_int;
    pub const getIgnoreXServerReply = gst_rtsp_connection_get_ignore_x_server_reply;

    /// Retrieve the IP address of the other end of `conn`.
    extern fn gst_rtsp_connection_get_ip(p_conn: *const RTSPConnection) ?[*:0]const u8;
    pub const getIp = gst_rtsp_connection_get_ip;

    /// Get the file descriptor for reading.
    extern fn gst_rtsp_connection_get_read_socket(p_conn: *const RTSPConnection) ?*gio.Socket;
    pub const getReadSocket = gst_rtsp_connection_get_read_socket;

    extern fn gst_rtsp_connection_get_remember_session_id(p_conn: *RTSPConnection) c_int;
    pub const getRememberSessionId = gst_rtsp_connection_get_remember_session_id;

    /// Get the TLS connection of `conn`.
    ///
    /// For client side this will return the `gio.TlsClientConnection` when connected
    /// over TLS.
    ///
    /// For server side connections, this function will create a GTlsServerConnection
    /// when called the first time and will return that same connection on subsequent
    /// calls. The server is then responsible for configuring the TLS connection.
    extern fn gst_rtsp_connection_get_tls(p_conn: *RTSPConnection, p_error: ?*?*glib.Error) ?*gio.TlsConnection;
    pub const getTls = gst_rtsp_connection_get_tls;

    /// Gets the anchor certificate authorities database that will be used
    /// after a server certificate can't be verified with the default
    /// certificate database.
    extern fn gst_rtsp_connection_get_tls_database(p_conn: *RTSPConnection) ?*gio.TlsDatabase;
    pub const getTlsDatabase = gst_rtsp_connection_get_tls_database;

    /// Gets a `gio.TlsInteraction` object to be used when the connection or certificate
    /// database need to interact with the user. This will be used to prompt the
    /// user for passwords where necessary.
    extern fn gst_rtsp_connection_get_tls_interaction(p_conn: *RTSPConnection) ?*gio.TlsInteraction;
    pub const getTlsInteraction = gst_rtsp_connection_get_tls_interaction;

    /// Gets the TLS validation flags used to verify the peer certificate
    /// when a TLS connection is established.
    ///
    /// GLib guarantees that if certificate verification fails, at least one error
    /// will be set, but it does not guarantee that all possible errors will be
    /// set. Accordingly, you may not safely decide to ignore any particular type
    /// of error.
    ///
    /// For example, it would be incorrect to ignore `G_TLS_CERTIFICATE_EXPIRED` if
    /// you want to allow expired certificates, because this could potentially be
    /// the only error flag set even if other problems exist with the certificate.
    extern fn gst_rtsp_connection_get_tls_validation_flags(p_conn: *RTSPConnection) gio.TlsCertificateFlags;
    pub const getTlsValidationFlags = gst_rtsp_connection_get_tls_validation_flags;

    /// Get the tunnel session id the connection.
    extern fn gst_rtsp_connection_get_tunnelid(p_conn: *const RTSPConnection) ?[*:0]const u8;
    pub const getTunnelid = gst_rtsp_connection_get_tunnelid;

    /// Retrieve the URL of the other end of `conn`.
    extern fn gst_rtsp_connection_get_url(p_conn: *const RTSPConnection) *gstrtsp.RTSPUrl;
    pub const getUrl = gst_rtsp_connection_get_url;

    /// Get the file descriptor for writing.
    extern fn gst_rtsp_connection_get_write_socket(p_conn: *const RTSPConnection) ?*gio.Socket;
    pub const getWriteSocket = gst_rtsp_connection_get_write_socket;

    /// Get the tunneling state of the connection.
    extern fn gst_rtsp_connection_is_tunneled(p_conn: *const RTSPConnection) c_int;
    pub const isTunneled = gst_rtsp_connection_is_tunneled;

    /// Calculate the next timeout for `conn`, storing the result in `timeout`.
    extern fn gst_rtsp_connection_next_timeout(p_conn: *RTSPConnection, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const nextTimeout = gst_rtsp_connection_next_timeout;

    /// Calculate the next timeout for `conn`
    extern fn gst_rtsp_connection_next_timeout_usec(p_conn: *RTSPConnection) i64;
    pub const nextTimeoutUsec = gst_rtsp_connection_next_timeout_usec;

    /// Wait up to the specified `timeout` for the connection to become available for
    /// at least one of the operations specified in `events`. When the function returns
    /// with `GST_RTSP_OK`, `revents` will contain a bitmask of available operations on
    /// `conn`.
    ///
    /// `timeout` can be `NULL`, in which case this function might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_poll(p_conn: *RTSPConnection, p_events: gstrtsp.RTSPEvent, p_revents: *gstrtsp.RTSPEvent, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const poll = gst_rtsp_connection_poll;

    /// Wait up to the specified `timeout` for the connection to become available for
    /// at least one of the operations specified in `events`. When the function returns
    /// with `GST_RTSP_OK`, `revents` will contain a bitmask of available operations on
    /// `conn`.
    ///
    /// `timeout` can be 0, in which case this function might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_poll_usec(p_conn: *RTSPConnection, p_events: gstrtsp.RTSPEvent, p_revents: *gstrtsp.RTSPEvent, p_timeout: i64) gstrtsp.RTSPResult;
    pub const pollUsec = gst_rtsp_connection_poll_usec;

    /// Attempt to read `size` bytes into `data` from the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be `NULL`, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_read(p_conn: *RTSPConnection, p_data: [*]u8, p_size: c_uint, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const read = gst_rtsp_connection_read;

    /// Attempt to read `size` bytes into `data` from the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be 0, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_read_usec(p_conn: *RTSPConnection, p_data: [*]u8, p_size: c_uint, p_timeout: i64) gstrtsp.RTSPResult;
    pub const readUsec = gst_rtsp_connection_read_usec;

    /// Attempt to read into `message` from the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be `NULL`, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_receive(p_conn: *RTSPConnection, p_message: *gstrtsp.RTSPMessage, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const receive = gst_rtsp_connection_receive;

    /// Attempt to read into `message` from the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be 0, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_receive_usec(p_conn: *RTSPConnection, p_message: *gstrtsp.RTSPMessage, p_timeout: i64) gstrtsp.RTSPResult;
    pub const receiveUsec = gst_rtsp_connection_receive_usec;

    /// Reset the timeout of `conn`.
    extern fn gst_rtsp_connection_reset_timeout(p_conn: *RTSPConnection) gstrtsp.RTSPResult;
    pub const resetTimeout = gst_rtsp_connection_reset_timeout;

    /// Attempt to send `message` to the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be `NULL`, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_send(p_conn: *RTSPConnection, p_message: *gstrtsp.RTSPMessage, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const send = gst_rtsp_connection_send;

    /// Attempt to send `messages` to the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be `NULL`, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_send_messages(p_conn: *RTSPConnection, p_messages: [*]gstrtsp.RTSPMessage, p_n_messages: c_uint, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const sendMessages = gst_rtsp_connection_send_messages;

    /// Attempt to send `messages` to the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be 0, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_send_messages_usec(p_conn: *RTSPConnection, p_messages: [*]gstrtsp.RTSPMessage, p_n_messages: c_uint, p_timeout: i64) gstrtsp.RTSPResult;
    pub const sendMessagesUsec = gst_rtsp_connection_send_messages_usec;

    /// Attempt to send `message` to the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be 0, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_send_usec(p_conn: *RTSPConnection, p_message: *gstrtsp.RTSPMessage, p_timeout: i64) gstrtsp.RTSPResult;
    pub const sendUsec = gst_rtsp_connection_send_usec;

    /// Sets a custom accept-certificate function for checking certificates for
    /// validity. This will directly map to `gio.TlsConnection` 's "accept-certificate"
    /// signal and be performed after the default checks of `gstrtsp.RTSPConnection`
    /// (checking against the `gio.TlsDatabase` with the given `gio.TlsCertificateFlags`)
    /// have failed. If no `gio.TlsDatabase` is set on this connection, only `func` will
    /// be called.
    extern fn gst_rtsp_connection_set_accept_certificate_func(p_conn: *RTSPConnection, p_func: gstrtsp.RTSPConnectionAcceptCertificateFunc, p_user_data: ?*anyopaque, p_destroy_notify: ?glib.DestroyNotify) void;
    pub const setAcceptCertificateFunc = gst_rtsp_connection_set_accept_certificate_func;

    /// Configure `conn` for authentication mode `method` with `user` and `pass` as the
    /// user and password respectively.
    extern fn gst_rtsp_connection_set_auth(p_conn: *RTSPConnection, p_method: gstrtsp.RTSPAuthMethod, p_user: [*:0]const u8, p_pass: [*:0]const u8) gstrtsp.RTSPResult;
    pub const setAuth = gst_rtsp_connection_set_auth;

    /// Setup `conn` with authentication directives. This is not necessary for
    /// methods `GST_RTSP_AUTH_NONE` and `GST_RTSP_AUTH_BASIC`. For
    /// `GST_RTSP_AUTH_DIGEST`, directives should be taken from the digest challenge
    /// in the WWW-Authenticate response header and can include realm, domain,
    /// nonce, opaque, stale, algorithm, qop as per RFC2617.
    extern fn gst_rtsp_connection_set_auth_param(p_conn: *RTSPConnection, p_param: [*:0]const u8, p_value: [*:0]const u8) void;
    pub const setAuthParam = gst_rtsp_connection_set_auth_param;

    /// Configure `conn` to use the specified Content-Length limit.
    /// Both requests and responses are validated. If content-length is
    /// exceeded, ENOMEM error will be returned.
    extern fn gst_rtsp_connection_set_content_length_limit(p_conn: *RTSPConnection, p_limit: c_uint) void;
    pub const setContentLengthLimit = gst_rtsp_connection_set_content_length_limit;

    /// By setting the HTTP mode to `TRUE` the message parsing will support HTTP
    /// messages in addition to the RTSP messages. It will also disable the
    /// automatic handling of setting up an HTTP tunnel.
    extern fn gst_rtsp_connection_set_http_mode(p_conn: *RTSPConnection, p_enable: c_int) void;
    pub const setHttpMode = gst_rtsp_connection_set_http_mode;

    /// Set whether to ignore the x-server-ip-address header reply or not. If the
    /// header is ignored, the original address will be used instead.
    extern fn gst_rtsp_connection_set_ignore_x_server_reply(p_conn: *RTSPConnection, p_ignore: c_int) void;
    pub const setIgnoreXServerReply = gst_rtsp_connection_set_ignore_x_server_reply;

    /// Set the IP address of the server.
    extern fn gst_rtsp_connection_set_ip(p_conn: *RTSPConnection, p_ip: [*:0]const u8) void;
    pub const setIp = gst_rtsp_connection_set_ip;

    /// Set the proxy host and port.
    extern fn gst_rtsp_connection_set_proxy(p_conn: *RTSPConnection, p_host: [*:0]const u8, p_port: c_uint) gstrtsp.RTSPResult;
    pub const setProxy = gst_rtsp_connection_set_proxy;

    /// Configure `conn` to use the specified DSCP value.
    extern fn gst_rtsp_connection_set_qos_dscp(p_conn: *RTSPConnection, p_qos_dscp: c_uint) gstrtsp.RTSPResult;
    pub const setQosDscp = gst_rtsp_connection_set_qos_dscp;

    /// Sets if the `gstrtsp.RTSPConnection` should remember the session id from the last
    /// response received and force it onto any further requests.
    ///
    /// The default value is `TRUE`
    extern fn gst_rtsp_connection_set_remember_session_id(p_conn: *RTSPConnection, p_remember: c_int) void;
    pub const setRememberSessionId = gst_rtsp_connection_set_remember_session_id;

    /// Sets the anchor certificate authorities database. This certificate
    /// database will be used to verify the server's certificate in case it
    /// can't be verified with the default certificate database first.
    extern fn gst_rtsp_connection_set_tls_database(p_conn: *RTSPConnection, p_database: ?*gio.TlsDatabase) void;
    pub const setTlsDatabase = gst_rtsp_connection_set_tls_database;

    /// Sets a `gio.TlsInteraction` object to be used when the connection or certificate
    /// database need to interact with the user. This will be used to prompt the
    /// user for passwords where necessary.
    extern fn gst_rtsp_connection_set_tls_interaction(p_conn: *RTSPConnection, p_interaction: ?*gio.TlsInteraction) void;
    pub const setTlsInteraction = gst_rtsp_connection_set_tls_interaction;

    /// Sets the TLS validation flags to be used to verify the peer
    /// certificate when a TLS connection is established.
    ///
    /// GLib guarantees that if certificate verification fails, at least one error
    /// will be set, but it does not guarantee that all possible errors will be
    /// set. Accordingly, you may not safely decide to ignore any particular type
    /// of error.
    ///
    /// For example, it would be incorrect to mask `G_TLS_CERTIFICATE_EXPIRED` if
    /// you want to allow expired certificates, because this could potentially be
    /// the only error flag set even if other problems exist with the certificate.
    extern fn gst_rtsp_connection_set_tls_validation_flags(p_conn: *RTSPConnection, p_flags: gio.TlsCertificateFlags) c_int;
    pub const setTlsValidationFlags = gst_rtsp_connection_set_tls_validation_flags;

    /// Set the HTTP tunneling state of the connection. This must be configured before
    /// the `conn` is connected.
    extern fn gst_rtsp_connection_set_tunneled(p_conn: *RTSPConnection, p_tunneled: c_int) void;
    pub const setTunneled = gst_rtsp_connection_set_tunneled;

    /// Attempt to write `size` bytes of `data` to the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be `NULL`, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_write(p_conn: *RTSPConnection, p_data: [*]const u8, p_size: c_uint, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const write = gst_rtsp_connection_write;

    /// Attempt to write `size` bytes of `data` to the connected `conn`, blocking up to
    /// the specified `timeout`. `timeout` can be 0, in which case this function
    /// might block forever.
    ///
    /// This function can be cancelled with `gstrtsp.RTSPConnection.flush`.
    extern fn gst_rtsp_connection_write_usec(p_conn: *RTSPConnection, p_data: [*]const u8, p_size: c_uint, p_timeout: i64) gstrtsp.RTSPResult;
    pub const writeUsec = gst_rtsp_connection_write_usec;

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

/// An interface representing RTSP extensions.
pub const RTSPExtensionInterface = extern struct {
    pub const Instance = gstrtsp.RTSPExtension;

    f_parent: gobject.TypeInterface,
    f_detect_server: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_resp: *gstrtsp.RTSPMessage) callconv(.c) c_int,
    f_before_send: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_req: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult,
    f_after_send: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult,
    f_parse_sdp: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_sdp: *gstsdp.SDPMessage, p_s: *gst.Structure) callconv(.c) gstrtsp.RTSPResult,
    f_setup_media: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_media: *gstsdp.SDPMedia) callconv(.c) gstrtsp.RTSPResult,
    f_configure_stream: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_caps: *gst.Caps) callconv(.c) c_int,
    f_get_transports: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_protocols: gstrtsp.RTSPLowerTrans, p_transport: *[*:0]u8) callconv(.c) gstrtsp.RTSPResult,
    f_stream_select: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_url: *gstrtsp.RTSPUrl) callconv(.c) gstrtsp.RTSPResult,
    f_send: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_req: *gstrtsp.RTSPMessage, p_resp: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult,
    f_receive_request: ?*const fn (p_ext: *gstrtsp.RTSPExtension, p_req: *gstrtsp.RTSPMessage) callconv(.c) gstrtsp.RTSPResult,
    f__gst_reserved: [4]*anyopaque,

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

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

/// Provides methods for creating and parsing request, response and data messages.
pub const RTSPMessage = extern struct {
    /// the message type
    f_type: gstrtsp.RTSPMsgType,
    anon0: extern union {
        anon0: extern struct {
            f_method: gstrtsp.RTSPMethod,
            f_uri: ?[*:0]u8,
            f_version: gstrtsp.RTSPVersion,
        },
        anon1: extern struct {
            f_code: gstrtsp.RTSPStatusCode,
            f_reason: ?[*:0]u8,
            f_version: gstrtsp.RTSPVersion,
        },
        anon2: extern struct {
            f_channel: u8,
        },
    },
    f_hdr_fields: ?*glib.Array,
    f_body: ?*u8,
    f_body_size: c_uint,
    f_body_buffer: ?*gst.Buffer,
    f__gst_reserved: [3]*anyopaque,

    /// Add a header with key `field` and `value` to `msg`. This function takes a copy
    /// of `value`.
    extern fn gst_rtsp_message_add_header(p_msg: *RTSPMessage, p_field: gstrtsp.RTSPHeaderField, p_value: [*:0]const u8) gstrtsp.RTSPResult;
    pub const addHeader = gst_rtsp_message_add_header;

    /// Add a header with key `header` and `value` to `msg`. This function takes a copy
    /// of `value`.
    extern fn gst_rtsp_message_add_header_by_name(p_msg: *RTSPMessage, p_header: [*:0]const u8, p_value: [*:0]const u8) gstrtsp.RTSPResult;
    pub const addHeaderByName = gst_rtsp_message_add_header_by_name;

    /// Append the currently configured headers in `msg` to the `glib.String` `str` suitable
    /// for transmission.
    extern fn gst_rtsp_message_append_headers(p_msg: *const RTSPMessage, p_str: *glib.String) gstrtsp.RTSPResult;
    pub const appendHeaders = gst_rtsp_message_append_headers;

    /// Allocate a new copy of `msg` and store the result in `copy`. The value in
    /// `copy` should be release with gst_rtsp_message_free function.
    extern fn gst_rtsp_message_copy(p_msg: *const RTSPMessage, p_copy: ?**gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const copy = gst_rtsp_message_copy;

    /// Dump the contents of `msg` to stdout.
    extern fn gst_rtsp_message_dump(p_msg: *RTSPMessage) gstrtsp.RTSPResult;
    pub const dump = gst_rtsp_message_dump;

    /// Free the memory used by `msg`.
    extern fn gst_rtsp_message_free(p_msg: *RTSPMessage) gstrtsp.RTSPResult;
    pub const free = gst_rtsp_message_free;

    /// Get the body of `msg`. `data` remains valid for as long as `msg` is valid and
    /// unchanged.
    ///
    /// If the message body was set as a `gst.Buffer` before this will cause the data
    /// to be copied and stored in the message. The `gst.Buffer` will no longer be
    /// kept in the message.
    extern fn gst_rtsp_message_get_body(p_msg: *const RTSPMessage, p_data: *[*]u8, p_size: *c_uint) gstrtsp.RTSPResult;
    pub const getBody = gst_rtsp_message_get_body;

    /// Get the body of `msg`. `buffer` remains valid for as long as `msg` is valid and
    /// unchanged.
    ///
    /// If body data was set from raw memory instead of a `gst.Buffer` this function
    /// will always return `NULL`. The caller can check if there is a body buffer by
    /// calling `gstrtsp.RTSPMessage.hasBodyBuffer`.
    extern fn gst_rtsp_message_get_body_buffer(p_msg: *const RTSPMessage, p_buffer: **gst.Buffer) gstrtsp.RTSPResult;
    pub const getBodyBuffer = gst_rtsp_message_get_body_buffer;

    /// Get the `indx` header value with key `field` from `msg`. The result in `value`
    /// stays valid as long as it remains present in `msg`.
    extern fn gst_rtsp_message_get_header(p_msg: *const RTSPMessage, p_field: gstrtsp.RTSPHeaderField, p_value: ?*[*:0]u8, p_indx: c_int) gstrtsp.RTSPResult;
    pub const getHeader = gst_rtsp_message_get_header;

    /// Get the `index` header value with key `header` from `msg`. The result in `value`
    /// stays valid as long as it remains present in `msg`.
    extern fn gst_rtsp_message_get_header_by_name(p_msg: *RTSPMessage, p_header: [*:0]const u8, p_value: ?*[*:0]u8, p_index: c_int) gstrtsp.RTSPResult;
    pub const getHeaderByName = gst_rtsp_message_get_header_by_name;

    /// Get the message type of `msg`.
    extern fn gst_rtsp_message_get_type(p_msg: *RTSPMessage) gstrtsp.RTSPMsgType;
    pub const getType = gst_rtsp_message_get_type;

    /// Checks if `msg` has a body and the body is stored as `gst.Buffer`.
    extern fn gst_rtsp_message_has_body_buffer(p_msg: *const RTSPMessage) c_int;
    pub const hasBodyBuffer = gst_rtsp_message_has_body_buffer;

    /// Initialize `msg`. This function is mostly used when `msg` is allocated on the
    /// stack. The reverse operation of this is `gstrtsp.RTSPMessage.unset`.
    extern fn gst_rtsp_message_init(p_msg: *RTSPMessage) gstrtsp.RTSPResult;
    pub const init = gst_rtsp_message_init;

    /// Initialize a new data `gstrtsp.RTSPMessage` for `channel`.
    extern fn gst_rtsp_message_init_data(p_msg: *RTSPMessage, p_channel: u8) gstrtsp.RTSPResult;
    pub const initData = gst_rtsp_message_init_data;

    /// Initialize `msg` as a request message with `method` and `uri`. To clear `msg`
    /// again, use `gstrtsp.RTSPMessage.unset`.
    extern fn gst_rtsp_message_init_request(p_msg: *RTSPMessage, p_method: gstrtsp.RTSPMethod, p_uri: [*:0]const u8) gstrtsp.RTSPResult;
    pub const initRequest = gst_rtsp_message_init_request;

    /// Initialize `msg` with `code` and `reason`.
    ///
    /// When `reason` is `NULL`, the default reason for `code` will be used.
    ///
    /// When `request` is not `NULL`, the relevant headers will be copied to the new
    /// response message.
    extern fn gst_rtsp_message_init_response(p_msg: *RTSPMessage, p_code: gstrtsp.RTSPStatusCode, p_reason: ?[*:0]const u8, p_request: ?*const gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
    pub const initResponse = gst_rtsp_message_init_response;

    /// Parses the credentials given in a WWW-Authenticate or Authorization header.
    extern fn gst_rtsp_message_parse_auth_credentials(p_msg: *RTSPMessage, p_field: gstrtsp.RTSPHeaderField) [*]*gstrtsp.RTSPAuthCredential;
    pub const parseAuthCredentials = gst_rtsp_message_parse_auth_credentials;

    /// Parse the data message `msg` and store the channel in `channel`.
    extern fn gst_rtsp_message_parse_data(p_msg: *RTSPMessage, p_channel: ?*u8) gstrtsp.RTSPResult;
    pub const parseData = gst_rtsp_message_parse_data;

    /// Parse the request message `msg` and store the values `method`, `uri` and
    /// `version`. The result locations can be `NULL` if one is not interested in its
    /// value.
    ///
    /// `uri` remains valid for as long as `msg` is valid and unchanged.
    extern fn gst_rtsp_message_parse_request(p_msg: *RTSPMessage, p_method: ?*gstrtsp.RTSPMethod, p_uri: ?*[*:0]const u8, p_version: ?*gstrtsp.RTSPVersion) gstrtsp.RTSPResult;
    pub const parseRequest = gst_rtsp_message_parse_request;

    /// Parse the response message `msg` and store the values `code`, `reason` and
    /// `version`. The result locations can be `NULL` if one is not interested in its
    /// value.
    ///
    /// `reason` remains valid for as long as `msg` is valid and unchanged.
    extern fn gst_rtsp_message_parse_response(p_msg: *RTSPMessage, p_code: ?*gstrtsp.RTSPStatusCode, p_reason: ?*[*:0]const u8, p_version: ?*gstrtsp.RTSPVersion) gstrtsp.RTSPResult;
    pub const parseResponse = gst_rtsp_message_parse_response;

    /// Remove the `indx` header with key `field` from `msg`. If `indx` equals -1, all
    /// headers will be removed.
    extern fn gst_rtsp_message_remove_header(p_msg: *RTSPMessage, p_field: gstrtsp.RTSPHeaderField, p_indx: c_int) gstrtsp.RTSPResult;
    pub const removeHeader = gst_rtsp_message_remove_header;

    /// Remove the `index` header with key `header` from `msg`. If `index` equals -1,
    /// all matching headers will be removed.
    extern fn gst_rtsp_message_remove_header_by_name(p_msg: *RTSPMessage, p_header: [*:0]const u8, p_index: c_int) gstrtsp.RTSPResult;
    pub const removeHeaderByName = gst_rtsp_message_remove_header_by_name;

    /// Set the body of `msg` to a copy of `data`. Any existing body or body buffer
    /// will be replaced by the new body.
    extern fn gst_rtsp_message_set_body(p_msg: *RTSPMessage, p_data: [*]const u8, p_size: c_uint) gstrtsp.RTSPResult;
    pub const setBody = gst_rtsp_message_set_body;

    /// Set the body of `msg` to `buffer`. Any existing body or body buffer
    /// will be replaced by the new body.
    extern fn gst_rtsp_message_set_body_buffer(p_msg: *RTSPMessage, p_buffer: *gst.Buffer) gstrtsp.RTSPResult;
    pub const setBodyBuffer = gst_rtsp_message_set_body_buffer;

    /// Take the body of `msg` and store it in `data` and `size`. After this method,
    /// the body and size of `msg` will be set to `NULL` and 0 respectively.
    extern fn gst_rtsp_message_steal_body(p_msg: *RTSPMessage, p_data: *[*]u8, p_size: *c_uint) gstrtsp.RTSPResult;
    pub const stealBody = gst_rtsp_message_steal_body;

    /// Take the body of `msg` and store it in `buffer`. After this method,
    /// the body and size of `msg` will be set to `NULL` and 0 respectively.
    ///
    /// If body data was set from raw memory instead of a `gst.Buffer` this function
    /// will always return `NULL`. The caller can check if there is a body buffer by
    /// calling `gstrtsp.RTSPMessage.hasBodyBuffer`.
    extern fn gst_rtsp_message_steal_body_buffer(p_msg: *RTSPMessage, p_buffer: **gst.Buffer) gstrtsp.RTSPResult;
    pub const stealBodyBuffer = gst_rtsp_message_steal_body_buffer;

    /// Set the body of `msg` to `data` and `size`. This method takes ownership of
    /// `data`. Any existing body or body buffer will be replaced by the new body.
    extern fn gst_rtsp_message_take_body(p_msg: *RTSPMessage, p_data: [*]u8, p_size: c_uint) gstrtsp.RTSPResult;
    pub const takeBody = gst_rtsp_message_take_body;

    /// Set the body of `msg` to `buffer`. This method takes ownership of `buffer`.
    /// Any existing body or body buffer will be replaced by the new body.
    extern fn gst_rtsp_message_take_body_buffer(p_msg: *RTSPMessage, p_buffer: *gst.Buffer) gstrtsp.RTSPResult;
    pub const takeBodyBuffer = gst_rtsp_message_take_body_buffer;

    /// Add a header with key `field` and `value` to `msg`. This function takes
    /// ownership of `value`.
    extern fn gst_rtsp_message_take_header(p_msg: *RTSPMessage, p_field: gstrtsp.RTSPHeaderField, p_value: [*:0]u8) gstrtsp.RTSPResult;
    pub const takeHeader = gst_rtsp_message_take_header;

    /// Add a header with key `header` and `value` to `msg`. This function takes
    /// ownership of `value`, but not of `header`.
    extern fn gst_rtsp_message_take_header_by_name(p_msg: *RTSPMessage, p_header: [*:0]const u8, p_value: [*:0]u8) gstrtsp.RTSPResult;
    pub const takeHeaderByName = gst_rtsp_message_take_header_by_name;

    /// Unset the contents of `msg` so that it becomes an uninitialized
    /// `gstrtsp.RTSPMessage` again. This function is mostly used in combination with
    /// `gstrtsp.RTSPMessage.initRequest`, `gstrtsp.RTSPMessage.initResponse` and
    /// `gstrtsp.RTSPMessage.initData` on stack allocated `gstrtsp.RTSPMessage` structures.
    extern fn gst_rtsp_message_unset(p_msg: *RTSPMessage) gstrtsp.RTSPResult;
    pub const unset = gst_rtsp_message_unset;

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

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

/// Provides helper functions to deal with time ranges.
pub const RTSPRange = extern struct {
    /// minimum value of the range
    f_min: c_int,
    /// maximum value of the range
    f_max: c_int,

    /// Converts the range in-place between different types of units.
    /// Ranges containing the special value `GST_RTSP_TIME_NOW` can not be
    /// converted as these are only valid for `GST_RTSP_RANGE_NPT`.
    extern fn gst_rtsp_range_convert_units(p_range: *gstrtsp.RTSPTimeRange, p_unit: gstrtsp.RTSPRangeUnit) c_int;
    pub const convertUnits = gst_rtsp_range_convert_units;

    /// Free the memory allocated by `range`.
    extern fn gst_rtsp_range_free(p_range: *gstrtsp.RTSPTimeRange) void;
    pub const free = gst_rtsp_range_free;

    /// Retrieve the minimum and maximum values from `range` converted to
    /// `gst.ClockTime` in `min` and `max`.
    ///
    /// A value of `GST_CLOCK_TIME_NONE` will be used to signal `GST_RTSP_TIME_NOW`
    /// and `GST_RTSP_TIME_END` for `min` and `max` respectively.
    ///
    /// UTC times will be converted to nanoseconds since 1900.
    extern fn gst_rtsp_range_get_times(p_range: *const gstrtsp.RTSPTimeRange, p_min: *gst.ClockTime, p_max: *gst.ClockTime) c_int;
    pub const getTimes = gst_rtsp_range_get_times;

    /// Parse `rangestr` to a `gstrtsp.RTSPTimeRange`.
    extern fn gst_rtsp_range_parse(p_rangestr: [*:0]const u8, p_range: **gstrtsp.RTSPTimeRange) gstrtsp.RTSPResult;
    pub const parse = gst_rtsp_range_parse;

    /// Convert `range` into a string representation.
    extern fn gst_rtsp_range_to_string(p_range: *const gstrtsp.RTSPTimeRange) [*:0]u8;
    pub const toString = gst_rtsp_range_to_string;

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

/// A time indication.
pub const RTSPTime = extern struct {
    /// the time of the time
    f_type: gstrtsp.RTSPTimeType,
    /// seconds when `type` is GST_RTSP_TIME_SECONDS,
    ///           GST_RTSP_TIME_UTC and GST_RTSP_TIME_FRAMES
    f_seconds: f64,

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

/// Extra fields for a time indication.
pub const RTSPTime2 = extern struct {
    /// frames and subframes when type in GstRTSPTime is
    ///          GST_RTSP_TIME_FRAMES
    f_frames: f64,
    /// year when type is GST_RTSP_TIME_UTC
    f_year: c_uint,
    /// month when type is GST_RTSP_TIME_UTC
    f_month: c_uint,
    /// day when type is GST_RTSP_TIME_UTC
    f_day: c_uint,

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

/// A time range.
pub const RTSPTimeRange = extern struct {
    /// the time units used
    f_unit: gstrtsp.RTSPRangeUnit,
    /// the minimum interval
    f_min: gstrtsp.RTSPTime,
    /// the maximum interval
    f_max: gstrtsp.RTSPTime,
    /// extra fields in the minimum interval (Since: 1.2)
    f_min2: gstrtsp.RTSPTime2,
    /// extra fields in the maximum interval (Since: 1.2)
    f_max2: gstrtsp.RTSPTime2,

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

/// Provides helper functions to deal with RTSP transport strings.
pub const RTSPTransport = extern struct {
    /// the transport mode
    f_trans: gstrtsp.RTSPTransMode,
    /// the tansport profile
    f_profile: gstrtsp.RTSPProfile,
    /// the lower transport
    f_lower_transport: gstrtsp.RTSPLowerTrans,
    /// the destination ip/hostname
    f_destination: ?[*:0]u8,
    /// the source ip/hostname
    f_source: ?[*:0]u8,
    /// the number of layers
    f_layers: c_uint,
    /// if play mode was selected
    f_mode_play: c_int,
    /// if record mode was selected
    f_mode_record: c_int,
    /// is append mode was selected
    f_append: c_int,
    /// the interleave range
    f_interleaved: gstrtsp.RTSPRange,
    /// the time to live for multicast UDP
    f_ttl: c_uint,
    /// the port pair for multicast sessions
    f_port: gstrtsp.RTSPRange,
    /// the client port pair for receiving data. For TCP
    ///   based transports, applications can use this field to store the
    ///   sender and receiver ports of the client.
    f_client_port: gstrtsp.RTSPRange,
    /// the server port pair for receiving data. For TCP
    ///   based transports, applications can use this field to store the
    ///   sender and receiver ports of the server.
    f_server_port: gstrtsp.RTSPRange,
    /// the ssrc that the sender/receiver will use
    f_ssrc: c_uint,
    f__gst_reserved: [4]*anyopaque,

    /// Get the `gst.Element` that can handle the buffers transported over `trans`.
    ///
    /// It is possible that there are several managers available, use `option` to
    /// selected one.
    ///
    /// `manager` will contain an element name or `NULL` when no manager is
    /// needed/available for `trans`.
    extern fn gst_rtsp_transport_get_manager(p_trans: gstrtsp.RTSPTransMode, p_manager: ?*[*:0]const u8, p_option: c_uint) gstrtsp.RTSPResult;
    pub const getManager = gst_rtsp_transport_get_manager;

    /// Get the mime type of the transport mode `trans`. This mime type is typically
    /// used to generate `gst.Caps` events.
    extern fn gst_rtsp_transport_get_mime(p_trans: gstrtsp.RTSPTransMode, p_mime: *[*:0]const u8) gstrtsp.RTSPResult;
    pub const getMime = gst_rtsp_transport_get_mime;

    /// Initialize `transport` so that it can be used.
    extern fn gst_rtsp_transport_init(p_transport: *gstrtsp.RTSPTransport) gstrtsp.RTSPResult;
    pub const init = gst_rtsp_transport_init;

    /// Allocate a new initialized `gstrtsp.RTSPTransport`. Use `gstrtsp.RTSPTransport.free`
    /// after usage.
    extern fn gst_rtsp_transport_new(p_transport: **gstrtsp.RTSPTransport) gstrtsp.RTSPResult;
    pub const new = gst_rtsp_transport_new;

    /// Parse the RTSP transport string `str` into `transport`.
    extern fn gst_rtsp_transport_parse(p_str: [*:0]const u8, p_transport: *gstrtsp.RTSPTransport) gstrtsp.RTSPResult;
    pub const parse = gst_rtsp_transport_parse;

    /// Convert `transport` into a string that can be used to signal the transport in
    /// an RTSP SETUP response.
    extern fn gst_rtsp_transport_as_text(p_transport: *RTSPTransport) ?[*:0]u8;
    pub const asText = gst_rtsp_transport_as_text;

    /// Free the memory used by `transport`.
    extern fn gst_rtsp_transport_free(p_transport: *RTSPTransport) gstrtsp.RTSPResult;
    pub const free = gst_rtsp_transport_free;

    /// Get the media type of `transport`. This media type is typically
    /// used to generate `gst.Caps` events.
    extern fn gst_rtsp_transport_get_media_type(p_transport: *RTSPTransport, p_media_type: *[*:0]const u8) gstrtsp.RTSPResult;
    pub const getMediaType = gst_rtsp_transport_get_media_type;

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

/// Provides helper functions to handle RTSP urls.
pub const RTSPUrl = extern struct {
    /// the transports allowed
    f_transports: gstrtsp.RTSPLowerTrans,
    /// the family
    f_family: gstrtsp.RTSPFamily,
    /// the user
    f_user: ?[*:0]u8,
    /// the password
    f_passwd: ?[*:0]u8,
    /// the host
    f_host: ?[*:0]u8,
    /// the port
    f_port: u16,
    /// the absolute path
    f_abspath: ?[*:0]u8,
    /// additional query parameters
    f_query: ?[*:0]u8,

    /// Parse the RTSP `urlstr` into a newly allocated `gstrtsp.RTSPUrl`. Free after usage
    /// with `gstrtsp.RTSPUrl.free`.
    extern fn gst_rtsp_url_parse(p_urlstr: [*:0]const u8, p_url: ?**gstrtsp.RTSPUrl) gstrtsp.RTSPResult;
    pub const parse = gst_rtsp_url_parse;

    /// Make a copy of `url`.
    extern fn gst_rtsp_url_copy(p_url: *const RTSPUrl) *gstrtsp.RTSPUrl;
    pub const copy = gst_rtsp_url_copy;

    /// Splits the path of `url` on '/' boundaries, decoding the resulting components,
    ///
    /// The decoding performed by this routine is "URI decoding", as defined in RFC
    /// 3986, commonly known as percent-decoding. For example, a string "foo\%2fbar"
    /// will decode to "foo/bar" -- the \%2f being replaced by the corresponding byte
    /// with hex value 0x2f. Note that there is no guarantee that the resulting byte
    /// sequence is valid in any given encoding. As a special case, \%00 is not
    /// unescaped to NUL, as that would prematurely terminate the string.
    ///
    /// Also note that since paths usually start with a slash, the first component
    /// will usually be the empty string.
    extern fn gst_rtsp_url_decode_path_components(p_url: *const RTSPUrl) [*][*:0]u8;
    pub const decodePathComponents = gst_rtsp_url_decode_path_components;

    /// Free the memory used by `url`.
    extern fn gst_rtsp_url_free(p_url: *RTSPUrl) void;
    pub const free = gst_rtsp_url_free;

    /// Get the port number of `url`.
    extern fn gst_rtsp_url_get_port(p_url: *const RTSPUrl, p_port: *u16) gstrtsp.RTSPResult;
    pub const getPort = gst_rtsp_url_get_port;

    /// Get a newly allocated string describing the request URI for `url`.
    extern fn gst_rtsp_url_get_request_uri(p_url: *const RTSPUrl) [*:0]u8;
    pub const getRequestUri = gst_rtsp_url_get_request_uri;

    /// Get a newly allocated string describing the request URI for `url`
    /// combined with the control path for `control_path`
    extern fn gst_rtsp_url_get_request_uri_with_control(p_url: *const RTSPUrl, p_control_path: [*:0]const u8) [*:0]u8;
    pub const getRequestUriWithControl = gst_rtsp_url_get_request_uri_with_control;

    /// Set the port number in `url` to `port`.
    extern fn gst_rtsp_url_set_port(p_url: *RTSPUrl, p_port: u16) gstrtsp.RTSPResult;
    pub const setPort = gst_rtsp_url_set_port;

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

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

/// Opaque RTSP watch object that can be used for asynchronous RTSP
/// operations.
pub const RTSPWatch = opaque {
    /// Create a watch object for `conn`. The functions provided in `funcs` will be
    /// called with `user_data` when activity happened on the watch.
    ///
    /// The new watch is usually created so that it can be attached to a
    /// maincontext with `gstrtsp.RTSPWatch.attach`.
    ///
    /// `conn` must exist for the entire lifetime of the watch.
    extern fn gst_rtsp_watch_new(p_conn: *gstrtsp.RTSPConnection, p_funcs: *gstrtsp.RTSPWatchFuncs, p_user_data: ?*anyopaque, p_notify: glib.DestroyNotify) *gstrtsp.RTSPWatch;
    pub const new = gst_rtsp_watch_new;

    /// Adds a `gstrtsp.RTSPWatch` to a context so that it will be executed within that context.
    extern fn gst_rtsp_watch_attach(p_watch: *RTSPWatch, p_context: ?*glib.MainContext) c_uint;
    pub const attach = gst_rtsp_watch_attach;

    /// Get the maximum amount of bytes and messages that will be queued in `watch`.
    /// See `gstrtsp.RTSPWatch.setSendBacklog`.
    extern fn gst_rtsp_watch_get_send_backlog(p_watch: *RTSPWatch, p_bytes: ?*usize, p_messages: ?*c_uint) void;
    pub const getSendBacklog = gst_rtsp_watch_get_send_backlog;

    /// Reset `watch`, this is usually called after `gstrtsp.RTSPConnection.doTunnel`
    /// when the file descriptors of the connection might have changed.
    extern fn gst_rtsp_watch_reset(p_watch: *RTSPWatch) void;
    pub const reset = gst_rtsp_watch_reset;

    /// Send a `message` using the connection of the `watch`. If it cannot be sent
    /// immediately, it will be queued for transmission in `watch`. The contents of
    /// `message` will then be serialized and transmitted when the connection of the
    /// `watch` becomes writable. In case the `message` is queued, the ID returned in
    /// `id` will be non-zero and used as the ID argument in the message_sent
    /// callback.
    extern fn gst_rtsp_watch_send_message(p_watch: *RTSPWatch, p_message: *gstrtsp.RTSPMessage, p_id: ?*c_uint) gstrtsp.RTSPResult;
    pub const sendMessage = gst_rtsp_watch_send_message;

    /// Sends `messages` using the connection of the `watch`. If they cannot be sent
    /// immediately, they will be queued for transmission in `watch`. The contents of
    /// `messages` will then be serialized and transmitted when the connection of the
    /// `watch` becomes writable. In case the `messages` are queued, the ID returned in
    /// `id` will be non-zero and used as the ID argument in the message_sent
    /// callback once the last message is sent. The callback will only be called
    /// once for the last message.
    extern fn gst_rtsp_watch_send_messages(p_watch: *RTSPWatch, p_messages: [*]gstrtsp.RTSPMessage, p_n_messages: c_uint, p_id: ?*c_uint) gstrtsp.RTSPResult;
    pub const sendMessages = gst_rtsp_watch_send_messages;

    /// When `flushing` is `TRUE`, abort a call to `gstrtsp.RTSPWatch.waitBacklog`
    /// and make sure `gstrtsp.RTSPWatch.writeData` returns immediately with
    /// `GST_RTSP_EINTR`. And empty the queue.
    extern fn gst_rtsp_watch_set_flushing(p_watch: *RTSPWatch, p_flushing: c_int) void;
    pub const setFlushing = gst_rtsp_watch_set_flushing;

    /// Set the maximum amount of bytes and messages that will be queued in `watch`.
    /// When the maximum amounts are exceeded, `gstrtsp.RTSPWatch.writeData` and
    /// `gstrtsp.RTSPWatch.sendMessage` will return `GST_RTSP_ENOMEM`.
    ///
    /// A value of 0 for `bytes` or `messages` means no limits.
    extern fn gst_rtsp_watch_set_send_backlog(p_watch: *RTSPWatch, p_bytes: usize, p_messages: c_uint) void;
    pub const setSendBacklog = gst_rtsp_watch_set_send_backlog;

    /// Decreases the reference count of `watch` by one. If the resulting reference
    /// count is zero the watch and associated memory will be destroyed.
    extern fn gst_rtsp_watch_unref(p_watch: *RTSPWatch) void;
    pub const unref = gst_rtsp_watch_unref;

    /// Wait until there is place in the backlog queue, `timeout` is reached
    /// or `watch` is set to flushing.
    ///
    /// If `timeout` is `NULL` this function can block forever. If `timeout`
    /// contains a valid timeout, this function will return `GST_RTSP_ETIMEOUT`
    /// after the timeout expired.
    ///
    /// The typically use of this function is when gst_rtsp_watch_write_data
    /// returns `GST_RTSP_ENOMEM`. The caller then calls this function to wait for
    /// free space in the backlog queue and try again.
    extern fn gst_rtsp_watch_wait_backlog(p_watch: *RTSPWatch, p_timeout: *glib.TimeVal) gstrtsp.RTSPResult;
    pub const waitBacklog = gst_rtsp_watch_wait_backlog;

    /// Wait until there is place in the backlog queue, `timeout` is reached
    /// or `watch` is set to flushing.
    ///
    /// If `timeout` is 0 this function can block forever. If `timeout`
    /// contains a valid timeout, this function will return `GST_RTSP_ETIMEOUT`
    /// after the timeout expired.
    ///
    /// The typically use of this function is when gst_rtsp_watch_write_data
    /// returns `GST_RTSP_ENOMEM`. The caller then calls this function to wait for
    /// free space in the backlog queue and try again.
    extern fn gst_rtsp_watch_wait_backlog_usec(p_watch: *RTSPWatch, p_timeout: i64) gstrtsp.RTSPResult;
    pub const waitBacklogUsec = gst_rtsp_watch_wait_backlog_usec;

    /// Write `data` using the connection of the `watch`. If it cannot be sent
    /// immediately, it will be queued for transmission in `watch`. The contents of
    /// `message` will then be serialized and transmitted when the connection of the
    /// `watch` becomes writable. In case the `message` is queued, the ID returned in
    /// `id` will be non-zero and used as the ID argument in the message_sent
    /// callback.
    ///
    /// This function will take ownership of `data` and `glib.free` it after use.
    ///
    /// If the amount of queued data exceeds the limits set with
    /// `gstrtsp.RTSPWatch.setSendBacklog`, this function will return
    /// `GST_RTSP_ENOMEM`.
    extern fn gst_rtsp_watch_write_data(p_watch: *RTSPWatch, p_data: [*]const u8, p_size: c_uint, p_id: ?*c_uint) gstrtsp.RTSPResult;
    pub const writeData = gst_rtsp_watch_write_data;

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

/// Callback functions from a `gstrtsp.RTSPWatch`.
pub const RTSPWatchFuncs = extern struct {
    /// callback when a message was received
    f_message_received: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_message: *gstrtsp.RTSPMessage, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    /// callback when a message was sent
    f_message_sent: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_id: c_uint, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    /// callback when the connection is closed
    f_closed: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    /// callback when an error occurred
    f_error: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_result: gstrtsp.RTSPResult, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    /// a client started a tunneled connection. The tunnelid of the
    ///   connection must be saved.
    f_tunnel_start: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPStatusCode,
    /// a client finished a tunneled connection. In this callback
    ///   you usually pair the tunnelid of this connection with the saved one using
    ///   `gstrtsp.RTSPConnection.doTunnel`.
    f_tunnel_complete: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    /// callback when an error occurred with more information than
    ///   the `error` callback.
    f_error_full: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_result: gstrtsp.RTSPResult, p_message: *gstrtsp.RTSPMessage, p_id: c_uint, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    /// callback when the post connection of a tunnel is closed.
    f_tunnel_lost: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    /// callback when an HTTP response to the GET request
    ///   is about to be sent for a tunneled connection. The response can be
    ///   modified in the callback. Since: 1.4.
    f_tunnel_http_response: ?*const fn (p_watch: *gstrtsp.RTSPWatch, p_request: *gstrtsp.RTSPMessage, p_response: *gstrtsp.RTSPMessage, p_user_data: ?*anyopaque) callconv(.c) gstrtsp.RTSPResult,
    f__gst_reserved: [3]*anyopaque,

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

/// Authentication methods, ordered by strength
pub const RTSPAuthMethod = enum(c_int) {
    none = 0,
    basic = 1,
    digest = 2,
    _,

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

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

/// The possible network families.
pub const RTSPFamily = enum(c_int) {
    none = 0,
    inet = 1,
    inet6 = 2,
    _,

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

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

/// Enumeration of rtsp header fields
pub const RTSPHeaderField = enum(c_int) {
    invalid = 0,
    accept = 1,
    accept_encoding = 2,
    accept_language = 3,
    allow = 4,
    authorization = 5,
    bandwidth = 6,
    blocksize = 7,
    cache_control = 8,
    conference = 9,
    connection = 10,
    content_base = 11,
    content_encoding = 12,
    content_language = 13,
    content_length = 14,
    content_location = 15,
    content_type = 16,
    cseq = 17,
    date = 18,
    expires = 19,
    from = 20,
    if_modified_since = 21,
    last_modified = 22,
    proxy_authenticate = 23,
    proxy_require = 24,
    public = 25,
    range = 26,
    referer = 27,
    require = 28,
    retry_after = 29,
    rtp_info = 30,
    scale = 31,
    session = 32,
    server = 33,
    speed = 34,
    transport = 35,
    unsupported = 36,
    user_agent = 37,
    via = 38,
    www_authenticate = 39,
    client_challenge = 40,
    real_challenge1 = 41,
    real_challenge2 = 42,
    real_challenge3 = 43,
    subscribe = 44,
    alert = 45,
    client_id = 46,
    company_id = 47,
    guid = 48,
    region_data = 49,
    max_asm_width = 50,
    language = 51,
    player_start_time = 52,
    location = 53,
    etag = 54,
    if_match = 55,
    accept_charset = 56,
    supported = 57,
    vary = 58,
    x_accelerate_streaming = 59,
    x_accept_authent = 60,
    x_accept_proxy_authent = 61,
    x_broadcast_id = 62,
    x_burst_streaming = 63,
    x_notice = 64,
    x_player_lag_time = 65,
    x_playlist = 66,
    x_playlist_change_notice = 67,
    x_playlist_gen_id = 68,
    x_playlist_seek_id = 69,
    x_proxy_client_agent = 70,
    x_proxy_client_verb = 71,
    x_receding_playlistchange = 72,
    x_rtp_info = 73,
    x_startupprofile = 74,
    timestamp = 75,
    authentication_info = 76,
    host = 77,
    pragma = 78,
    x_server_ip_address = 79,
    x_sessioncookie = 80,
    rtcp_interval = 81,
    keymgmt = 82,
    pipelined_requests = 83,
    media_properties = 84,
    seek_style = 85,
    accept_ranges = 86,
    frames = 87,
    rate_control = 88,
    last = 89,
    _,

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

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

/// The type of a message.
pub const RTSPMsgType = enum(c_int) {
    invalid = 0,
    request = 1,
    response = 2,
    http_request = 3,
    http_response = 4,
    data = 5,
    _,

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

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

/// Different possible time range units.
pub const RTSPRangeUnit = enum(c_int) {
    smpte = 0,
    smpte_30_drop = 1,
    smpte_25 = 2,
    npt = 3,
    clock = 4,
    _,

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

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

/// Result codes from the RTSP functions.
pub const RTSPResult = enum(c_int) {
    ok = 0,
    ok_redirect = 1,
    @"error" = -1,
    einval = -2,
    eintr = -3,
    enomem = -4,
    eresolv = -5,
    enotimpl = -6,
    esys = -7,
    eparse = -8,
    ewsastart = -9,
    ewsaversion = -10,
    eeof = -11,
    enet = -12,
    enotip = -13,
    etimeout = -14,
    etget = -15,
    etpost = -16,
    elast = -17,
    _,

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

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

/// The different RTSP states.
pub const RTSPState = enum(c_int) {
    invalid = 0,
    init = 1,
    ready = 2,
    seeking = 3,
    playing = 4,
    recording = 5,
    _,

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

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

/// Enumeration of rtsp status codes
pub const RTSPStatusCode = enum(c_int) {
    invalid = 0,
    @"continue" = 100,
    ok = 200,
    created = 201,
    low_on_storage = 250,
    multiple_choices = 300,
    moved_permanently = 301,
    move_temporarily = 302,
    see_other = 303,
    not_modified = 304,
    use_proxy = 305,
    redirect_temporarily = 307,
    redirect_permanently = 308,
    bad_request = 400,
    unauthorized = 401,
    payment_required = 402,
    forbidden = 403,
    not_found = 404,
    method_not_allowed = 405,
    not_acceptable = 406,
    proxy_auth_required = 407,
    request_timeout = 408,
    gone = 410,
    length_required = 411,
    precondition_failed = 412,
    request_entity_too_large = 413,
    request_uri_too_large = 414,
    unsupported_media_type = 415,
    parameter_not_understood = 451,
    conference_not_found = 452,
    not_enough_bandwidth = 453,
    session_not_found = 454,
    method_not_valid_in_this_state = 455,
    header_field_not_valid_for_resource = 456,
    invalid_range = 457,
    parameter_is_readonly = 458,
    aggregate_operation_not_allowed = 459,
    only_aggregate_operation_allowed = 460,
    unsupported_transport = 461,
    destination_unreachable = 462,
    key_management_failure = 463,
    internal_server_error = 500,
    not_implemented = 501,
    bad_gateway = 502,
    service_unavailable = 503,
    gateway_timeout = 504,
    rtsp_version_not_supported = 505,
    option_not_supported = 551,
    _,

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

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

/// Possible time types.
pub const RTSPTimeType = enum(c_int) {
    seconds = 0,
    now = 1,
    end = 2,
    frames = 3,
    utc = 4,
    _,

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

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

/// The supported RTSP versions.
pub const RTSPVersion = enum(c_int) {
    invalid = 0,
    @"1_0" = 16,
    @"1_1" = 17,
    @"2_0" = 32,
    _,

    /// Convert `version` to a string.
    extern fn gst_rtsp_version_as_text(p_version: gstrtsp.RTSPVersion) [*:0]const u8;
    pub const asText = gst_rtsp_version_as_text;

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

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

/// The possible events for the connection.
pub const RTSPEvent = packed struct(c_uint) {
    read: bool = false,
    write: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_read: RTSPEvent = @bitCast(@as(c_uint, 1));
    pub const flags_write: RTSPEvent = @bitCast(@as(c_uint, 2));
    extern fn gst_rtsp_event_get_type() usize;
    pub const getGObjectType = gst_rtsp_event_get_type;

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

/// The different transport methods.
pub const RTSPLowerTrans = packed struct(c_uint) {
    udp: bool = false,
    udp_mcast: bool = false,
    tcp: bool = false,
    _padding3: bool = false,
    http: bool = false,
    tls: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_unknown: RTSPLowerTrans = @bitCast(@as(c_uint, 0));
    pub const flags_udp: RTSPLowerTrans = @bitCast(@as(c_uint, 1));
    pub const flags_udp_mcast: RTSPLowerTrans = @bitCast(@as(c_uint, 2));
    pub const flags_tcp: RTSPLowerTrans = @bitCast(@as(c_uint, 4));
    pub const flags_http: RTSPLowerTrans = @bitCast(@as(c_uint, 16));
    pub const flags_tls: RTSPLowerTrans = @bitCast(@as(c_uint, 32));
    extern fn gst_rtsp_lower_trans_get_type() usize;
    pub const getGObjectType = gst_rtsp_lower_trans_get_type;

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

/// The different supported RTSP methods.
pub const RTSPMethod = packed struct(c_uint) {
    describe: bool = false,
    announce: bool = false,
    get_parameter: bool = false,
    options: bool = false,
    pause: bool = false,
    play: bool = false,
    record: bool = false,
    redirect: bool = false,
    setup: bool = false,
    set_parameter: bool = false,
    teardown: bool = false,
    get: bool = false,
    post: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_invalid: RTSPMethod = @bitCast(@as(c_uint, 0));
    pub const flags_describe: RTSPMethod = @bitCast(@as(c_uint, 1));
    pub const flags_announce: RTSPMethod = @bitCast(@as(c_uint, 2));
    pub const flags_get_parameter: RTSPMethod = @bitCast(@as(c_uint, 4));
    pub const flags_options: RTSPMethod = @bitCast(@as(c_uint, 8));
    pub const flags_pause: RTSPMethod = @bitCast(@as(c_uint, 16));
    pub const flags_play: RTSPMethod = @bitCast(@as(c_uint, 32));
    pub const flags_record: RTSPMethod = @bitCast(@as(c_uint, 64));
    pub const flags_redirect: RTSPMethod = @bitCast(@as(c_uint, 128));
    pub const flags_setup: RTSPMethod = @bitCast(@as(c_uint, 256));
    pub const flags_set_parameter: RTSPMethod = @bitCast(@as(c_uint, 512));
    pub const flags_teardown: RTSPMethod = @bitCast(@as(c_uint, 1024));
    pub const flags_get: RTSPMethod = @bitCast(@as(c_uint, 2048));
    pub const flags_post: RTSPMethod = @bitCast(@as(c_uint, 4096));
    /// Convert `method` to a string.
    extern fn gst_rtsp_method_as_text(p_method: gstrtsp.RTSPMethod) ?[*:0]const u8;
    pub const asText = gst_rtsp_method_as_text;

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

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

/// The transfer profile to use.
pub const RTSPProfile = packed struct(c_uint) {
    avp: bool = false,
    savp: bool = false,
    avpf: bool = false,
    savpf: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_unknown: RTSPProfile = @bitCast(@as(c_uint, 0));
    pub const flags_avp: RTSPProfile = @bitCast(@as(c_uint, 1));
    pub const flags_savp: RTSPProfile = @bitCast(@as(c_uint, 2));
    pub const flags_avpf: RTSPProfile = @bitCast(@as(c_uint, 4));
    pub const flags_savpf: RTSPProfile = @bitCast(@as(c_uint, 8));
    extern fn gst_rtsp_profile_get_type() usize;
    pub const getGObjectType = gst_rtsp_profile_get_type;

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

/// The transfer mode to use.
pub const RTSPTransMode = packed struct(c_uint) {
    rtp: bool = false,
    rdt: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_unknown: RTSPTransMode = @bitCast(@as(c_uint, 0));
    pub const flags_rtp: RTSPTransMode = @bitCast(@as(c_uint, 1));
    pub const flags_rdt: RTSPTransMode = @bitCast(@as(c_uint, 2));
    extern fn gst_rtsp_trans_mode_get_type() usize;
    pub const getGObjectType = gst_rtsp_trans_mode_get_type;

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

/// Free a `NULL`-terminated array of credentials returned from
/// `gstrtsp.RTSPMessage.parseAuthCredentials`.
extern fn gst_rtsp_auth_credentials_free(p_credentials: **gstrtsp.RTSPAuthCredential) void;
pub const rtspAuthCredentialsFree = gst_rtsp_auth_credentials_free;

/// Convert `header` to a `gstrtsp.RTSPHeaderField`.
extern fn gst_rtsp_find_header_field(p_header: [*:0]const u8) gstrtsp.RTSPHeaderField;
pub const rtspFindHeaderField = gst_rtsp_find_header_field;

/// Convert `method` to a `gstrtsp.RTSPMethod`.
extern fn gst_rtsp_find_method(p_method: [*:0]const u8) gstrtsp.RTSPMethod;
pub const rtspFindMethod = gst_rtsp_find_method;

/// Calculates the digest auth response from the values given by the server and
/// the username and password. See RFC2069 for details.
///
/// Currently only supported algorithm "md5".
extern fn gst_rtsp_generate_digest_auth_response(p_algorithm: ?[*:0]const u8, p_method: [*:0]const u8, p_realm: [*:0]const u8, p_username: [*:0]const u8, p_password: [*:0]const u8, p_uri: [*:0]const u8, p_nonce: [*:0]const u8) ?[*:0]u8;
pub const rtspGenerateDigestAuthResponse = gst_rtsp_generate_digest_auth_response;

/// Calculates the digest auth response from the values given by the server and
/// the md5sum. See RFC2069 for details.
///
/// This function is useful when the passwords are not stored in clear text,
/// but instead in the same format as the .htdigest file.
///
/// Currently only supported algorithm "md5".
extern fn gst_rtsp_generate_digest_auth_response_from_md5(p_algorithm: ?[*:0]const u8, p_method: [*:0]const u8, p_md5: [*:0]const u8, p_uri: [*:0]const u8, p_nonce: [*:0]const u8) ?[*:0]u8;
pub const rtspGenerateDigestAuthResponseFromMd5 = gst_rtsp_generate_digest_auth_response_from_md5;

/// Check whether `field` may appear multiple times in a message.
extern fn gst_rtsp_header_allow_multiple(p_field: gstrtsp.RTSPHeaderField) c_int;
pub const rtspHeaderAllowMultiple = gst_rtsp_header_allow_multiple;

/// Convert `field` to a string.
extern fn gst_rtsp_header_as_text(p_field: gstrtsp.RTSPHeaderField) ?[*:0]const u8;
pub const rtspHeaderAsText = gst_rtsp_header_as_text;

/// Create a new initialized `gstrtsp.RTSPMessage`. Free with `gstrtsp.RTSPMessage.free`.
extern fn gst_rtsp_message_new(p_msg: **gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
pub const rtspMessageNew = gst_rtsp_message_new;

/// Create a new data `gstrtsp.RTSPMessage` with `channel` and store the
/// result message in `msg`. Free with `gstrtsp.RTSPMessage.free`.
extern fn gst_rtsp_message_new_data(p_msg: **gstrtsp.RTSPMessage, p_channel: u8) gstrtsp.RTSPResult;
pub const rtspMessageNewData = gst_rtsp_message_new_data;

/// Create a new `gstrtsp.RTSPMessage` with `method` and `uri` and store the result
/// request message in `msg`. Free with `gstrtsp.RTSPMessage.free`.
extern fn gst_rtsp_message_new_request(p_msg: **gstrtsp.RTSPMessage, p_method: gstrtsp.RTSPMethod, p_uri: [*:0]const u8) gstrtsp.RTSPResult;
pub const rtspMessageNewRequest = gst_rtsp_message_new_request;

/// Create a new response `gstrtsp.RTSPMessage` with `code` and `reason` and store the
/// result message in `msg`. Free with `gstrtsp.RTSPMessage.free`.
///
/// When `reason` is `NULL`, the default reason for `code` will be used.
///
/// When `request` is not `NULL`, the relevant headers will be copied to the new
/// response message.
extern fn gst_rtsp_message_new_response(p_msg: **gstrtsp.RTSPMessage, p_code: gstrtsp.RTSPStatusCode, p_reason: ?[*:0]const u8, p_request: ?*const gstrtsp.RTSPMessage) gstrtsp.RTSPResult;
pub const rtspMessageNewResponse = gst_rtsp_message_new_response;

/// Convert `options` to a string.
extern fn gst_rtsp_options_as_text(p_options: gstrtsp.RTSPMethod) [*:0]u8;
pub const rtspOptionsAsText = gst_rtsp_options_as_text;

/// Convert the comma separated list `options` to a `gstrtsp.RTSPMethod` bitwise or
/// of methods. This functions is the reverse of `gstrtsp.rtspOptionsAsText`.
extern fn gst_rtsp_options_from_text(p_options: [*:0]const u8) gstrtsp.RTSPMethod;
pub const rtspOptionsFromText = gst_rtsp_options_from_text;

/// Convert `code` to a string.
extern fn gst_rtsp_status_as_text(p_code: gstrtsp.RTSPStatusCode) [*:0]const u8;
pub const rtspStatusAsText = gst_rtsp_status_as_text;

/// Convert `result` in a human readable string.
extern fn gst_rtsp_strresult(p_result: gstrtsp.RTSPResult) [*:0]u8;
pub const rtspStrresult = gst_rtsp_strresult;

pub const RTSPConnectionAcceptCertificateFunc = *const fn (p_conn: *gio.TlsConnection, p_peer_cert: *gio.TlsCertificate, p_errors: gio.TlsCertificateFlags, p_user_data: ?*anyopaque) callconv(.c) c_int;

/// The default RTSP port to connect to.
pub const RTSP_DEFAULT_PORT = 554;

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