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

const std = @import("std");
const compat = @import("compat");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
pub const MIKEYDecryptInfo = opaque {
    test {
        @setEvalBranchQuota(100_000);
        std.testing.refAllDecls(@This());
    }
};

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

/// The Security policy Map item for SRTP
pub const MIKEYMapSRTP = extern struct {
    /// The security policy applied for the stream with `ssrc`
    f_policy: u8,
    /// the SSRC that must be used for the stream
    f_ssrc: u32,
    /// current rollover counter
    f_roc: u32,

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

/// Structure holding the information of the MIKEY message
pub const MIKEYMessage = extern struct {
    f_mini_object: gst.MiniObject,
    /// the version
    f_version: u8,
    /// the `gstsdp.MIKEYType` message type
    f_type: gstsdp.MIKEYType,
    /// verify flag
    f_V: c_int,
    /// a `gstsdp.MIKEYPRFFunc`
    f_prf_func: gstsdp.MIKEYPRFFunc,
    /// Identifies the Crypto Session Bundle
    f_CSB_id: u32,
    /// a `gstsdp.MIKEYMapType`
    f_map_type: gstsdp.MIKEYMapType,
    /// map info array of type depending on `map_type`
    f_map_info: ?*glib.Array,
    /// the payload array of `gstsdp.MIKEYPayload`
    f_payloads: ?*glib.Array,

    /// Make a new MIKEY message.
    extern fn gst_mikey_message_new() *gstsdp.MIKEYMessage;
    pub const new = gst_mikey_message_new;

    /// Make a new `gstsdp.MIKEYMessage` from `bytes`.
    extern fn gst_mikey_message_new_from_bytes(p_bytes: *glib.Bytes, p_info: *gstsdp.MIKEYDecryptInfo, p_error: ?*?*glib.Error) ?*gstsdp.MIKEYMessage;
    pub const newFromBytes = gst_mikey_message_new_from_bytes;

    /// Makes mikey message including:
    ///  - Security Policy Payload
    ///  - Key Data Transport Payload
    ///  - Key Data Sub-Payload
    extern fn gst_mikey_message_new_from_caps(p_caps: *gst.Caps) ?*gstsdp.MIKEYMessage;
    pub const newFromCaps = gst_mikey_message_new_from_caps;

    /// Parse `size` bytes from `data` into a `gstsdp.MIKEYMessage`. `info` contains the
    /// parameters to decrypt and verify the data.
    extern fn gst_mikey_message_new_from_data(p_data: [*]const u8, p_size: usize, p_info: *gstsdp.MIKEYDecryptInfo, p_error: ?*?*glib.Error) ?*gstsdp.MIKEYMessage;
    pub const newFromData = gst_mikey_message_new_from_data;

    /// Add a Crypto policy for SRTP to `msg`.
    extern fn gst_mikey_message_add_cs_srtp(p_msg: *MIKEYMessage, p_policy: u8, p_ssrc: u32, p_roc: u32) c_int;
    pub const addCsSrtp = gst_mikey_message_add_cs_srtp;

    /// Add a new payload to `msg`.
    extern fn gst_mikey_message_add_payload(p_msg: *MIKEYMessage, p_payload: *gstsdp.MIKEYPayload) c_int;
    pub const addPayload = gst_mikey_message_add_payload;

    /// Add a new PKE payload to `msg` with the given parameters.
    extern fn gst_mikey_message_add_pke(p_msg: *MIKEYMessage, p_C: gstsdp.MIKEYCacheType, p_data_len: u16, p_data: [*]const u8) c_int;
    pub const addPke = gst_mikey_message_add_pke;

    /// Add a new RAND payload to `msg` with the given parameters.
    extern fn gst_mikey_message_add_rand(p_msg: *MIKEYMessage, p_len: u8, p_rand: [*]const u8) c_int;
    pub const addRand = gst_mikey_message_add_rand;

    /// Add a new RAND payload to `msg` with `len` random bytes.
    extern fn gst_mikey_message_add_rand_len(p_msg: *MIKEYMessage, p_len: u8) c_int;
    pub const addRandLen = gst_mikey_message_add_rand_len;

    /// Add a new T payload to `msg` with the given parameters.
    extern fn gst_mikey_message_add_t(p_msg: *MIKEYMessage, p_type: gstsdp.MIKEYTSType, p_ts_value: [*]const u8) c_int;
    pub const addT = gst_mikey_message_add_t;

    /// Add a new T payload to `msg` that contains the current time
    /// in NTP-UTC format.
    extern fn gst_mikey_message_add_t_now_ntp_utc(p_msg: *MIKEYMessage) c_int;
    pub const addTNowNtpUtc = gst_mikey_message_add_t_now_ntp_utc;

    extern fn gst_mikey_message_base64_encode(p_msg: *MIKEYMessage) [*:0]u8;
    pub const base64Encode = gst_mikey_message_base64_encode;

    /// Find the `nth` occurrence of the payload with `type` in `msg`.
    extern fn gst_mikey_message_find_payload(p_msg: *const MIKEYMessage, p_type: gstsdp.MIKEYPayloadType, p_nth: c_uint) ?*const gstsdp.MIKEYPayload;
    pub const findPayload = gst_mikey_message_find_payload;

    /// Get the policy information of `msg` at `idx`.
    extern fn gst_mikey_message_get_cs_srtp(p_msg: *const MIKEYMessage, p_idx: c_uint) ?*const gstsdp.MIKEYMapSRTP;
    pub const getCsSrtp = gst_mikey_message_get_cs_srtp;

    /// Get the number of crypto sessions in `msg`.
    extern fn gst_mikey_message_get_n_cs(p_msg: *const MIKEYMessage) c_uint;
    pub const getNCs = gst_mikey_message_get_n_cs;

    /// Get the number of payloads in `msg`.
    extern fn gst_mikey_message_get_n_payloads(p_msg: *const MIKEYMessage) c_uint;
    pub const getNPayloads = gst_mikey_message_get_n_payloads;

    /// Get the `gstsdp.MIKEYPayload` at `idx` in `msg`
    extern fn gst_mikey_message_get_payload(p_msg: *const MIKEYMessage, p_idx: c_uint) ?*const gstsdp.MIKEYPayload;
    pub const getPayload = gst_mikey_message_get_payload;

    /// Insert a Crypto Session map for SRTP in `msg` at `idx`
    ///
    /// When `idx` is -1, the policy will be appended.
    extern fn gst_mikey_message_insert_cs_srtp(p_msg: *MIKEYMessage, p_idx: c_int, p_map: *const gstsdp.MIKEYMapSRTP) c_int;
    pub const insertCsSrtp = gst_mikey_message_insert_cs_srtp;

    /// Insert the `payload` at index `idx` in `msg`. If `idx` is -1, the payload
    /// will be appended to `msg`.
    extern fn gst_mikey_message_insert_payload(p_msg: *MIKEYMessage, p_idx: c_uint, p_payload: *gstsdp.MIKEYPayload) c_int;
    pub const insertPayload = gst_mikey_message_insert_payload;

    /// Remove the SRTP policy at `idx`.
    extern fn gst_mikey_message_remove_cs_srtp(p_msg: *MIKEYMessage, p_idx: c_int) c_int;
    pub const removeCsSrtp = gst_mikey_message_remove_cs_srtp;

    /// Remove the payload in `msg` at `idx`
    extern fn gst_mikey_message_remove_payload(p_msg: *MIKEYMessage, p_idx: c_uint) c_int;
    pub const removePayload = gst_mikey_message_remove_payload;

    /// Replace a Crypto Session map for SRTP in `msg` at `idx` with `map`.
    extern fn gst_mikey_message_replace_cs_srtp(p_msg: *MIKEYMessage, p_idx: c_int, p_map: *const gstsdp.MIKEYMapSRTP) c_int;
    pub const replaceCsSrtp = gst_mikey_message_replace_cs_srtp;

    /// Replace the payload at `idx` in `msg` with `payload`.
    extern fn gst_mikey_message_replace_payload(p_msg: *MIKEYMessage, p_idx: c_uint, p_payload: *gstsdp.MIKEYPayload) c_int;
    pub const replacePayload = gst_mikey_message_replace_payload;

    /// Set the information in `msg`.
    extern fn gst_mikey_message_set_info(p_msg: *MIKEYMessage, p_version: u8, p_type: gstsdp.MIKEYType, p_V: c_int, p_prf_func: gstsdp.MIKEYPRFFunc, p_CSB_id: u32, p_map_type: gstsdp.MIKEYMapType) c_int;
    pub const setInfo = gst_mikey_message_set_info;

    /// Convert `msg` to a `glib.Bytes`.
    extern fn gst_mikey_message_to_bytes(p_msg: *MIKEYMessage, p_info: *gstsdp.MIKEYEncryptInfo, p_error: ?*?*glib.Error) ?*glib.Bytes;
    pub const toBytes = gst_mikey_message_to_bytes;

    extern fn gst_mikey_message_to_caps(p_msg: *const MIKEYMessage, p_caps: *gst.Caps) c_int;
    pub const toCaps = gst_mikey_message_to_caps;

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

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

/// Hold the common fields for all payloads
pub const MIKEYPayload = extern struct {
    f_mini_object: gst.MiniObject,
    /// the payload type
    f_type: gstsdp.MIKEYPayloadType,
    /// length of the payload
    f_len: c_uint,

    /// Make a new `gstsdp.MIKEYPayload` with `type`.
    extern fn gst_mikey_payload_new(p_type: gstsdp.MIKEYPayloadType) ?*gstsdp.MIKEYPayload;
    pub const new = gst_mikey_payload_new;

    /// Add a new sub payload to `payload`.
    extern fn gst_mikey_payload_kemac_add_sub(p_payload: *MIKEYPayload, p_newpay: *gstsdp.MIKEYPayload) c_int;
    pub const kemacAddSub = gst_mikey_payload_kemac_add_sub;

    /// Get the number of sub payloads of `payload`. `payload` should be of type
    /// `GST_MIKEY_PT_KEMAC`.
    extern fn gst_mikey_payload_kemac_get_n_sub(p_payload: *const MIKEYPayload) c_uint;
    pub const kemacGetNSub = gst_mikey_payload_kemac_get_n_sub;

    /// Get the sub payload of `payload` at `idx`. `payload` should be of type
    /// `GST_MIKEY_PT_KEMAC`.
    extern fn gst_mikey_payload_kemac_get_sub(p_payload: *const MIKEYPayload, p_idx: c_uint) ?*const gstsdp.MIKEYPayload;
    pub const kemacGetSub = gst_mikey_payload_kemac_get_sub;

    /// Remove the sub payload at `idx` in `payload`.
    extern fn gst_mikey_payload_kemac_remove_sub(p_payload: *MIKEYPayload, p_idx: c_uint) c_int;
    pub const kemacRemoveSub = gst_mikey_payload_kemac_remove_sub;

    /// Set the KEMAC parameters. `payload` should point to a `GST_MIKEY_PT_KEMAC`
    /// payload.
    extern fn gst_mikey_payload_kemac_set(p_payload: *MIKEYPayload, p_enc_alg: gstsdp.MIKEYEncAlg, p_mac_alg: gstsdp.MIKEYMacAlg) c_int;
    pub const kemacSet = gst_mikey_payload_kemac_set;

    /// Set the key validity period in the `GST_MIKEY_PT_KEY_DATA` `payload`.
    extern fn gst_mikey_payload_key_data_set_interval(p_payload: *MIKEYPayload, p_vf_len: u8, p_vf_data: [*]const u8, p_vt_len: u8, p_vt_data: [*]const u8) c_int;
    pub const keyDataSetInterval = gst_mikey_payload_key_data_set_interval;

    /// Set `key_len` bytes of `key_data` of type `key_type` as the key for the
    /// `GST_MIKEY_PT_KEY_DATA` `payload`.
    extern fn gst_mikey_payload_key_data_set_key(p_payload: *MIKEYPayload, p_key_type: gstsdp.MIKEYKeyDataType, p_key_len: u16, p_key_data: [*]const u8) c_int;
    pub const keyDataSetKey = gst_mikey_payload_key_data_set_key;

    /// Set the salt key data. If `salt_len` is 0 and `salt_data` is `NULL`, the
    /// salt data will be removed.
    extern fn gst_mikey_payload_key_data_set_salt(p_payload: *MIKEYPayload, p_salt_len: u16, p_salt_data: ?[*]const u8) c_int;
    pub const keyDataSetSalt = gst_mikey_payload_key_data_set_salt;

    /// Set the SPI/MKI validity in the `GST_MIKEY_PT_KEY_DATA` `payload`.
    extern fn gst_mikey_payload_key_data_set_spi(p_payload: *MIKEYPayload, p_spi_len: u8, p_spi_data: [*]const u8) c_int;
    pub const keyDataSetSpi = gst_mikey_payload_key_data_set_spi;

    /// Set the PKE values in `payload`. `payload` must be of type
    /// `GST_MIKEY_PT_PKE`.
    extern fn gst_mikey_payload_pke_set(p_payload: *MIKEYPayload, p_C: gstsdp.MIKEYCacheType, p_data_len: u16, p_data: [*]const u8) c_int;
    pub const pkeSet = gst_mikey_payload_pke_set;

    /// Set the random values in a `GST_MIKEY_PT_RAND` `payload`.
    extern fn gst_mikey_payload_rand_set(p_payload: *MIKEYPayload, p_len: u8, p_rand: [*]const u8) c_int;
    pub const randSet = gst_mikey_payload_rand_set;

    /// Add a new parameter to the `GST_MIKEY_PT_SP` `payload` with `type`, `len`
    /// and `val`.
    extern fn gst_mikey_payload_sp_add_param(p_payload: *MIKEYPayload, p_type: u8, p_len: u8, p_val: [*]const u8) c_int;
    pub const spAddParam = gst_mikey_payload_sp_add_param;

    /// Get the number of security policy parameters in a `GST_MIKEY_PT_SP`
    /// `payload`.
    extern fn gst_mikey_payload_sp_get_n_params(p_payload: *const MIKEYPayload) c_uint;
    pub const spGetNParams = gst_mikey_payload_sp_get_n_params;

    /// Get the Security Policy parameter in a `GST_MIKEY_PT_SP` `payload`
    /// at `idx`.
    extern fn gst_mikey_payload_sp_get_param(p_payload: *const MIKEYPayload, p_idx: c_uint) ?*const gstsdp.MIKEYPayloadSPParam;
    pub const spGetParam = gst_mikey_payload_sp_get_param;

    /// Remove the Security Policy parameters from a `GST_MIKEY_PT_SP`
    /// `payload` at `idx`.
    extern fn gst_mikey_payload_sp_remove_param(p_payload: *MIKEYPayload, p_idx: c_uint) c_int;
    pub const spRemoveParam = gst_mikey_payload_sp_remove_param;

    /// Set the Security Policy parameters for `payload`.
    extern fn gst_mikey_payload_sp_set(p_payload: *MIKEYPayload, p_policy: c_uint, p_proto: gstsdp.MIKEYSecProto) c_int;
    pub const spSet = gst_mikey_payload_sp_set;

    /// Set the timestamp in a `GST_MIKEY_PT_T` `payload`.
    extern fn gst_mikey_payload_t_set(p_payload: *MIKEYPayload, p_type: gstsdp.MIKEYTSType, p_ts_value: [*]const u8) c_int;
    pub const tSet = gst_mikey_payload_t_set;

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

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

/// A structure holding the KEMAC payload
pub const MIKEYPayloadKEMAC = extern struct {
    /// the common `gstsdp.MIKEYPayload`
    f_pt: gstsdp.MIKEYPayload,
    /// the `gstsdp.MIKEYEncAlg`
    f_enc_alg: gstsdp.MIKEYEncAlg,
    /// the `gstsdp.MIKEYMacAlg`
    f_mac_alg: gstsdp.MIKEYMacAlg,
    /// the subpayloads
    f_subpayloads: ?*glib.Array,

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

/// The Key data payload contains key material. It should be added as sub
/// payload to the KEMAC.
pub const MIKEYPayloadKeyData = extern struct {
    /// the payload header
    f_pt: gstsdp.MIKEYPayload,
    /// the `gstsdp.MIKEYKeyDataType` of `key_data`
    f_key_type: gstsdp.MIKEYKeyDataType,
    /// length of `key_data`
    f_key_len: u16,
    /// the key data
    f_key_data: ?*u8,
    /// the length of `salt_data`, can be 0
    f_salt_len: u16,
    /// salt data
    f_salt_data: ?*u8,
    /// the Key Validity type
    f_kv_type: gstsdp.MIKEYKVType,
    /// length of `kv_data`
    f_kv_len: [2]u8,
    /// key validity data
    f_kv_data: [2]*u8,

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

/// The Envelope data payload contains the encrypted envelope key that is
/// used in the public-key transport to protect the data in the Key data
/// transport payload.  The encryption algorithm used is implicit from
/// the certificate/public key used.
pub const MIKEYPayloadPKE = extern struct {
    /// the common `gstsdp.MIKEYPayload`
    f_pt: gstsdp.MIKEYPayload,
    /// envelope key cache indicator
    f_C: gstsdp.MIKEYCacheType,
    /// length of `data`
    f_data_len: u16,
    /// the encrypted envelope key
    f_data: ?*u8,

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

/// The RAND payload consists of a (pseudo-)random bit-string
pub const MIKEYPayloadRAND = extern struct {
    /// the payload header
    f_pt: gstsdp.MIKEYPayload,
    /// the length of `rand`
    f_len: u8,
    /// random values
    f_rand: ?*u8,

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

/// The Security Policy payload defines a set of policies that apply to a
/// specific security protocol
pub const MIKEYPayloadSP = extern struct {
    /// the payload header
    f_pt: gstsdp.MIKEYPayload,
    /// the policy number
    f_policy: c_uint,
    /// the security protocol
    f_proto: gstsdp.MIKEYSecProto,
    /// array of `gstsdp.MIKEYPayloadSPParam`
    f_params: ?*glib.Array,

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

/// A Type/Length/Value field for security parameters
pub const MIKEYPayloadSPParam = extern struct {
    /// specifies the type of the parameter
    f_type: u8,
    /// specifies the length of `val`
    f_len: u8,
    /// specifies the value of the parameter
    f_val: ?*u8,

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

/// The timestamp payload carries the timestamp information
pub const MIKEYPayloadT = extern struct {
    /// the payload header
    f_pt: gstsdp.MIKEYPayload,
    /// a `gstsdp.MIKEYTSType`
    f_type: gstsdp.MIKEYTSType,
    /// the timestamp value
    f_ts_value: ?*u8,

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

/// The contents of the SDP "a=" field which contains a key/value pair.
pub const SDPAttribute = extern struct {
    /// the attribute key
    f_key: ?[*:0]u8,
    /// the attribute value or NULL when it was a property attribute
    f_value: ?[*:0]u8,

    /// Clear the attribute.
    extern fn gst_sdp_attribute_clear(p_attr: *SDPAttribute) gstsdp.SDPResult;
    pub const clear = gst_sdp_attribute_clear;

    /// Set the attribute with `key` and `value`.
    extern fn gst_sdp_attribute_set(p_attr: *SDPAttribute, p_key: [*:0]const u8, p_value: ?[*:0]const u8) gstsdp.SDPResult;
    pub const set = gst_sdp_attribute_set;

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

/// The contents of the SDP "b=" field which specifies the proposed bandwidth to
/// be used by the session or media.
pub const SDPBandwidth = extern struct {
    /// the bandwidth modifier type
    f_bwtype: ?[*:0]u8,
    /// the bandwidth in kilobits per second
    f_bandwidth: c_uint,

    /// Reset the bandwidth information in `bw`.
    extern fn gst_sdp_bandwidth_clear(p_bw: *SDPBandwidth) gstsdp.SDPResult;
    pub const clear = gst_sdp_bandwidth_clear;

    /// Set bandwidth information in `bw`.
    extern fn gst_sdp_bandwidth_set(p_bw: *SDPBandwidth, p_bwtype: [*:0]const u8, p_bandwidth: c_uint) gstsdp.SDPResult;
    pub const set = gst_sdp_bandwidth_set;

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

/// The contents of the SDP "c=" field which contains connection data.
pub const SDPConnection = extern struct {
    /// the type of network. "IN" is defined to have the meaning
    ///    "Internet".
    f_nettype: ?[*:0]u8,
    /// the type of `address`.
    f_addrtype: ?[*:0]u8,
    /// the address
    f_address: ?[*:0]u8,
    /// the time to live of the address
    f_ttl: c_uint,
    /// the number of layers
    f_addr_number: c_uint,

    /// Clear the connection.
    extern fn gst_sdp_connection_clear(p_conn: *SDPConnection) gstsdp.SDPResult;
    pub const clear = gst_sdp_connection_clear;

    /// Set the connection with the given parameters.
    extern fn gst_sdp_connection_set(p_conn: *SDPConnection, p_nettype: [*:0]const u8, p_addrtype: [*:0]const u8, p_address: [*:0]const u8, p_ttl: c_uint, p_addr_number: c_uint) gstsdp.SDPResult;
    pub const set = gst_sdp_connection_set;

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

/// The contents of the SDP "k=" field which is used to convey encryption
/// keys.
pub const SDPKey = extern struct {
    /// the encryption type
    f_type: ?[*:0]u8,
    /// the encryption data
    f_data: ?[*:0]u8,

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

/// The contents of the SDP "m=" field with all related fields.
pub const SDPMedia = extern struct {
    /// the media type
    f_media: ?[*:0]u8,
    /// the transport port to which the media stream will be sent
    f_port: c_uint,
    /// the number of ports or -1 if only one port was specified
    f_num_ports: c_uint,
    /// the transport protocol
    f_proto: ?[*:0]u8,
    /// an array of `gchar` formats
    f_fmts: ?*glib.Array,
    /// the media title
    f_information: ?[*:0]u8,
    /// array of `gstsdp.SDPConnection` with media connection information
    f_connections: ?*glib.Array,
    /// array of `gstsdp.SDPBandwidth` with media bandwidth information
    f_bandwidths: ?*glib.Array,
    /// the encryption key
    f_key: gstsdp.SDPKey,
    /// array of `gstsdp.SDPAttribute` with the additional media attributes
    f_attributes: ?*glib.Array,

    /// Initialize `media` so that its contents are as if it was freshly allocated
    /// with `gstsdp.sdpMediaNew`. This function is mostly used to initialize a media
    /// allocated on the stack. `gstsdp.SDPMedia.uninit` undoes this operation.
    ///
    /// When this function is invoked on newly allocated data (with malloc or on the
    /// stack), its contents should be set to 0 before calling this function.
    extern fn gst_sdp_media_init(p_media: *gstsdp.SDPMedia) gstsdp.SDPResult;
    pub const init = gst_sdp_media_init;

    /// Allocate a new GstSDPMedia and store the result in `media`.
    extern fn gst_sdp_media_new(p_media: **gstsdp.SDPMedia) gstsdp.SDPResult;
    pub const new = gst_sdp_media_new;

    /// Mapping of caps to SDP fields:
    ///
    /// a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
    ///
    /// a=framesize:(payload) (width)-(height)
    ///
    /// a=fmtp:(payload) (param)[=(value)];...
    ///
    /// a=rtcp-fb:(payload) (param1) [param2]...
    ///
    /// a=extmap:(id)[/direction] (extensionname) (extensionattributes)
    extern fn gst_sdp_media_set_media_from_caps(p_caps: *const gst.Caps, p_media: *gstsdp.SDPMedia) gstsdp.SDPResult;
    pub const setMediaFromCaps = gst_sdp_media_set_media_from_caps;

    /// Add the attribute with `key` and `value` to `media`.
    extern fn gst_sdp_media_add_attribute(p_media: *SDPMedia, p_key: [*:0]const u8, p_value: ?[*:0]const u8) gstsdp.SDPResult;
    pub const addAttribute = gst_sdp_media_add_attribute;

    /// Add the bandwidth information with `bwtype` and `bandwidth` to `media`.
    extern fn gst_sdp_media_add_bandwidth(p_media: *SDPMedia, p_bwtype: [*:0]const u8, p_bandwidth: c_uint) gstsdp.SDPResult;
    pub const addBandwidth = gst_sdp_media_add_bandwidth;

    /// Add the given connection parameters to `media`.
    extern fn gst_sdp_media_add_connection(p_media: *SDPMedia, p_nettype: [*:0]const u8, p_addrtype: [*:0]const u8, p_address: [*:0]const u8, p_ttl: c_uint, p_addr_number: c_uint) gstsdp.SDPResult;
    pub const addConnection = gst_sdp_media_add_connection;

    /// Add the format information to `media`.
    extern fn gst_sdp_media_add_format(p_media: *SDPMedia, p_format: [*:0]const u8) gstsdp.SDPResult;
    pub const addFormat = gst_sdp_media_add_format;

    /// Convert the contents of `media` to a text string.
    extern fn gst_sdp_media_as_text(p_media: *const SDPMedia) [*:0]u8;
    pub const asText = gst_sdp_media_as_text;

    /// Get the number of attribute fields in `media`.
    extern fn gst_sdp_media_attributes_len(p_media: *const SDPMedia) c_uint;
    pub const attributesLen = gst_sdp_media_attributes_len;

    /// Mapping of attributes of `gstsdp.SDPMedia` to `gst.Caps`
    extern fn gst_sdp_media_attributes_to_caps(p_media: *const SDPMedia, p_caps: *gst.Caps) gstsdp.SDPResult;
    pub const attributesToCaps = gst_sdp_media_attributes_to_caps;

    /// Get the number of bandwidth fields in `media`.
    extern fn gst_sdp_media_bandwidths_len(p_media: *const SDPMedia) c_uint;
    pub const bandwidthsLen = gst_sdp_media_bandwidths_len;

    /// Get the number of connection fields in `media`.
    extern fn gst_sdp_media_connections_len(p_media: *const SDPMedia) c_uint;
    pub const connectionsLen = gst_sdp_media_connections_len;

    /// Allocate a new copy of `media` and store the result in `copy`. The value in
    /// `copy` should be release with gst_sdp_media_free function.
    extern fn gst_sdp_media_copy(p_media: *const SDPMedia, p_copy: **gstsdp.SDPMedia) gstsdp.SDPResult;
    pub const copy = gst_sdp_media_copy;

    /// Get the number of formats in `media`.
    extern fn gst_sdp_media_formats_len(p_media: *const SDPMedia) c_uint;
    pub const formatsLen = gst_sdp_media_formats_len;

    /// Free all resources allocated by `media`. `media` should not be used anymore after
    /// this function. This function should be used when `media` was dynamically
    /// allocated with `gstsdp.sdpMediaNew`.
    extern fn gst_sdp_media_free(p_media: *SDPMedia) gstsdp.SDPResult;
    pub const free = gst_sdp_media_free;

    /// Get the attribute at position `idx` in `media`.
    extern fn gst_sdp_media_get_attribute(p_media: *const SDPMedia, p_idx: c_uint) *const gstsdp.SDPAttribute;
    pub const getAttribute = gst_sdp_media_get_attribute;

    /// Get the first attribute value for `key` in `media`.
    extern fn gst_sdp_media_get_attribute_val(p_media: *const SDPMedia, p_key: [*:0]const u8) ?[*:0]const u8;
    pub const getAttributeVal = gst_sdp_media_get_attribute_val;

    /// Get the `nth` attribute value for `key` in `media`.
    extern fn gst_sdp_media_get_attribute_val_n(p_media: *const SDPMedia, p_key: [*:0]const u8, p_nth: c_uint) ?[*:0]const u8;
    pub const getAttributeValN = gst_sdp_media_get_attribute_val_n;

    /// Get the bandwidth at position `idx` in `media`.
    extern fn gst_sdp_media_get_bandwidth(p_media: *const SDPMedia, p_idx: c_uint) *const gstsdp.SDPBandwidth;
    pub const getBandwidth = gst_sdp_media_get_bandwidth;

    /// Mapping of caps from SDP fields:
    ///
    /// a=rtpmap:(payload) (encoding_name)/(clock_rate)[/(encoding_params)]
    ///
    /// a=framesize:(payload) (width)-(height)
    ///
    /// a=fmtp:(payload) (param)[=(value)];...
    ///
    /// Note that the extmap, ssrc and rid attributes are set only by `gstsdp.SDPMedia.attributesToCaps`.
    extern fn gst_sdp_media_get_caps_from_media(p_media: *const SDPMedia, p_pt: c_int) ?*gst.Caps;
    pub const getCapsFromMedia = gst_sdp_media_get_caps_from_media;

    /// Get the connection at position `idx` in `media`.
    extern fn gst_sdp_media_get_connection(p_media: *const SDPMedia, p_idx: c_uint) *const gstsdp.SDPConnection;
    pub const getConnection = gst_sdp_media_get_connection;

    /// Get the format information at position `idx` in `media`.
    extern fn gst_sdp_media_get_format(p_media: *const SDPMedia, p_idx: c_uint) [*:0]const u8;
    pub const getFormat = gst_sdp_media_get_format;

    /// Get the information of `media`
    extern fn gst_sdp_media_get_information(p_media: *const SDPMedia) [*:0]const u8;
    pub const getInformation = gst_sdp_media_get_information;

    /// Get the encryption information from `media`.
    extern fn gst_sdp_media_get_key(p_media: *const SDPMedia) *const gstsdp.SDPKey;
    pub const getKey = gst_sdp_media_get_key;

    /// Get the media description of `media`.
    extern fn gst_sdp_media_get_media(p_media: *const SDPMedia) [*:0]const u8;
    pub const getMedia = gst_sdp_media_get_media;

    /// Get the number of ports for `media`.
    extern fn gst_sdp_media_get_num_ports(p_media: *const SDPMedia) c_uint;
    pub const getNumPorts = gst_sdp_media_get_num_ports;

    /// Get the port number for `media`.
    extern fn gst_sdp_media_get_port(p_media: *const SDPMedia) c_uint;
    pub const getPort = gst_sdp_media_get_port;

    /// Get the transport protocol of `media`
    extern fn gst_sdp_media_get_proto(p_media: *const SDPMedia) [*:0]const u8;
    pub const getProto = gst_sdp_media_get_proto;

    /// Insert the attribute to `media` at `idx`. When `idx` is -1,
    /// the attribute is appended.
    extern fn gst_sdp_media_insert_attribute(p_media: *SDPMedia, p_idx: c_int, p_attr: *gstsdp.SDPAttribute) gstsdp.SDPResult;
    pub const insertAttribute = gst_sdp_media_insert_attribute;

    /// Insert the bandwidth information to `media` at `idx`. When `idx` is -1,
    /// the bandwidth is appended.
    extern fn gst_sdp_media_insert_bandwidth(p_media: *SDPMedia, p_idx: c_int, p_bw: *gstsdp.SDPBandwidth) gstsdp.SDPResult;
    pub const insertBandwidth = gst_sdp_media_insert_bandwidth;

    /// Insert the connection information to `media` at `idx`. When `idx` is -1,
    /// the connection is appended.
    extern fn gst_sdp_media_insert_connection(p_media: *SDPMedia, p_idx: c_int, p_conn: *gstsdp.SDPConnection) gstsdp.SDPResult;
    pub const insertConnection = gst_sdp_media_insert_connection;

    /// Insert the format information to `media` at `idx`. When `idx` is -1,
    /// the format is appended.
    extern fn gst_sdp_media_insert_format(p_media: *SDPMedia, p_idx: c_int, p_format: [*:0]const u8) gstsdp.SDPResult;
    pub const insertFormat = gst_sdp_media_insert_format;

    /// Creates a new `gstsdp.MIKEYMessage` after parsing the key-mgmt attribute
    /// from a `gstsdp.SDPMedia`.
    extern fn gst_sdp_media_parse_keymgmt(p_media: *const SDPMedia, p_mikey: **gstsdp.MIKEYMessage) gstsdp.SDPResult;
    pub const parseKeymgmt = gst_sdp_media_parse_keymgmt;

    /// Remove the attribute in `media` at `idx`.
    extern fn gst_sdp_media_remove_attribute(p_media: *SDPMedia, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeAttribute = gst_sdp_media_remove_attribute;

    /// Remove the bandwidth information in `media` at `idx`.
    extern fn gst_sdp_media_remove_bandwidth(p_media: *SDPMedia, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeBandwidth = gst_sdp_media_remove_bandwidth;

    /// Remove the connection information in `media` at `idx`.
    extern fn gst_sdp_media_remove_connection(p_media: *SDPMedia, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeConnection = gst_sdp_media_remove_connection;

    /// Remove the format information in `media` at `idx`.
    extern fn gst_sdp_media_remove_format(p_media: *SDPMedia, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeFormat = gst_sdp_media_remove_format;

    /// Replace the attribute in `media` at `idx` with `attr`.
    extern fn gst_sdp_media_replace_attribute(p_media: *SDPMedia, p_idx: c_uint, p_attr: *gstsdp.SDPAttribute) gstsdp.SDPResult;
    pub const replaceAttribute = gst_sdp_media_replace_attribute;

    /// Replace the bandwidth information in `media` at `idx` with `bw`.
    extern fn gst_sdp_media_replace_bandwidth(p_media: *SDPMedia, p_idx: c_uint, p_bw: *gstsdp.SDPBandwidth) gstsdp.SDPResult;
    pub const replaceBandwidth = gst_sdp_media_replace_bandwidth;

    /// Replace the connection information in `media` at `idx` with `conn`.
    extern fn gst_sdp_media_replace_connection(p_media: *SDPMedia, p_idx: c_uint, p_conn: *gstsdp.SDPConnection) gstsdp.SDPResult;
    pub const replaceConnection = gst_sdp_media_replace_connection;

    /// Replace the format information in `media` at `idx` with `format`.
    extern fn gst_sdp_media_replace_format(p_media: *SDPMedia, p_idx: c_uint, p_format: [*:0]const u8) gstsdp.SDPResult;
    pub const replaceFormat = gst_sdp_media_replace_format;

    /// Set the media information of `media` to `information`.
    extern fn gst_sdp_media_set_information(p_media: *SDPMedia, p_information: [*:0]const u8) gstsdp.SDPResult;
    pub const setInformation = gst_sdp_media_set_information;

    /// Adds the encryption information to `media`.
    extern fn gst_sdp_media_set_key(p_media: *SDPMedia, p_type: [*:0]const u8, p_data: [*:0]const u8) gstsdp.SDPResult;
    pub const setKey = gst_sdp_media_set_key;

    /// Set the media description of `media` to `med`.
    extern fn gst_sdp_media_set_media(p_media: *SDPMedia, p_med: [*:0]const u8) gstsdp.SDPResult;
    pub const setMedia = gst_sdp_media_set_media;

    /// Set the port information in `media`.
    extern fn gst_sdp_media_set_port_info(p_media: *SDPMedia, p_port: c_uint, p_num_ports: c_uint) gstsdp.SDPResult;
    pub const setPortInfo = gst_sdp_media_set_port_info;

    /// Set the media transport protocol of `media` to `proto`.
    extern fn gst_sdp_media_set_proto(p_media: *SDPMedia, p_proto: [*:0]const u8) gstsdp.SDPResult;
    pub const setProto = gst_sdp_media_set_proto;

    /// Free all resources allocated in `media`. `media` should not be used anymore after
    /// this function. This function should be used when `media` was allocated on the
    /// stack and initialized with `gstsdp.sdpMediaInit`.
    extern fn gst_sdp_media_uninit(p_media: *SDPMedia) gstsdp.SDPResult;
    pub const uninit = gst_sdp_media_uninit;

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

/// The GstSDPMessage helper functions makes it easy to parse and create SDP
/// messages.
pub const SDPMessage = extern struct {
    /// the protocol version
    f_version: ?[*:0]u8,
    /// owner/creator and session identifier
    f_origin: gstsdp.SDPOrigin,
    /// session name
    f_session_name: ?[*:0]u8,
    /// session information
    f_information: ?[*:0]u8,
    /// URI of description
    f_uri: ?[*:0]u8,
    /// array of `gchar` with email addresses
    f_emails: ?*glib.Array,
    /// array of `gchar` with phone numbers
    f_phones: ?*glib.Array,
    /// connection information for the session
    f_connection: gstsdp.SDPConnection,
    /// array of `gstsdp.SDPBandwidth` with bandwidth information
    f_bandwidths: ?*glib.Array,
    /// array of `gstsdp.SDPTime` with time descriptions
    f_times: ?*glib.Array,
    /// array of `gstsdp.SDPZone` with time zone adjustments
    f_zones: ?*glib.Array,
    /// encryption key
    f_key: gstsdp.SDPKey,
    /// array of `gstsdp.SDPAttribute` with session attributes
    f_attributes: ?*glib.Array,
    /// array of `gstsdp.SDPMedia` with media descriptions
    f_medias: ?*glib.Array,

    /// Creates a uri from `msg` with the given `scheme`. The uri has the format:
    ///
    ///  \@scheme:///[`@"type"`=value *[&type=value]]
    ///
    ///  Where each value is url encoded.
    extern fn gst_sdp_message_as_uri(p_scheme: [*:0]const u8, p_msg: *const gstsdp.SDPMessage) [*:0]u8;
    pub const asUri = gst_sdp_message_as_uri;

    /// Initialize `msg` so that its contents are as if it was freshly allocated
    /// with `gstsdp.sdpMessageNew`. This function is mostly used to initialize a message
    /// allocated on the stack. `gstsdp.SDPMessage.uninit` undoes this operation.
    ///
    /// When this function is invoked on newly allocated data (with malloc or on the
    /// stack), its contents should be set to 0 before calling this function.
    extern fn gst_sdp_message_init(p_msg: *gstsdp.SDPMessage) gstsdp.SDPResult;
    pub const init = gst_sdp_message_init;

    /// Allocate a new GstSDPMessage and store the result in `msg`.
    extern fn gst_sdp_message_new(p_msg: **gstsdp.SDPMessage) gstsdp.SDPResult;
    pub const new = gst_sdp_message_new;

    /// Parse `text` and create a new SDPMessage from these.
    extern fn gst_sdp_message_new_from_text(p_text: [*:0]const u8, p_msg: **gstsdp.SDPMessage) gstsdp.SDPResult;
    pub const newFromText = gst_sdp_message_new_from_text;

    /// Parse the contents of `size` bytes pointed to by `data` and store the result in
    /// `msg`.
    extern fn gst_sdp_message_parse_buffer(p_data: [*]const u8, p_size: c_uint, p_msg: *gstsdp.SDPMessage) gstsdp.SDPResult;
    pub const parseBuffer = gst_sdp_message_parse_buffer;

    /// Parse the null-terminated `uri` and store the result in `msg`.
    ///
    /// The uri should be of the form:
    ///
    ///  scheme://[address[:ttl=ttl][:noa=noa]]/[sessionname]
    ///               [`@"type"`=value *[&type=value]]
    ///
    ///  where value is url encoded. This looslely resembles
    ///  http://tools.ietf.org/html/draft-fujikawa-sdp-url-01
    extern fn gst_sdp_message_parse_uri(p_uri: [*:0]const u8, p_msg: *gstsdp.SDPMessage) gstsdp.SDPResult;
    pub const parseUri = gst_sdp_message_parse_uri;

    /// Add the attribute with `key` and `value` to `msg`.
    extern fn gst_sdp_message_add_attribute(p_msg: *SDPMessage, p_key: [*:0]const u8, p_value: ?[*:0]const u8) gstsdp.SDPResult;
    pub const addAttribute = gst_sdp_message_add_attribute;

    /// Add the specified bandwidth information to `msg`.
    extern fn gst_sdp_message_add_bandwidth(p_msg: *SDPMessage, p_bwtype: [*:0]const u8, p_bandwidth: c_uint) gstsdp.SDPResult;
    pub const addBandwidth = gst_sdp_message_add_bandwidth;

    /// Add `email` to the list of emails in `msg`.
    extern fn gst_sdp_message_add_email(p_msg: *SDPMessage, p_email: [*:0]const u8) gstsdp.SDPResult;
    pub const addEmail = gst_sdp_message_add_email;

    /// Adds `media` to the array of medias in `msg`. This function takes ownership of
    /// the contents of `media` so that `media` will have to be reinitialized with
    /// `gstsdp.sdpMediaInit` before it can be used again.
    extern fn gst_sdp_message_add_media(p_msg: *SDPMessage, p_media: *gstsdp.SDPMedia) gstsdp.SDPResult;
    pub const addMedia = gst_sdp_message_add_media;

    /// Add `phone` to the list of phones in `msg`.
    extern fn gst_sdp_message_add_phone(p_msg: *SDPMessage, p_phone: [*:0]const u8) gstsdp.SDPResult;
    pub const addPhone = gst_sdp_message_add_phone;

    /// Add time information `start` and `stop` to `msg`.
    extern fn gst_sdp_message_add_time(p_msg: *SDPMessage, p_start: [*:0]const u8, p_stop: [*:0]const u8, p_repeat: [*][*:0]const u8) gstsdp.SDPResult;
    pub const addTime = gst_sdp_message_add_time;

    /// Add time zone information to `msg`.
    extern fn gst_sdp_message_add_zone(p_msg: *SDPMessage, p_adj_time: [*:0]const u8, p_typed_time: [*:0]const u8) gstsdp.SDPResult;
    pub const addZone = gst_sdp_message_add_zone;

    /// Convert the contents of `msg` to a text string.
    extern fn gst_sdp_message_as_text(p_msg: *const SDPMessage) [*:0]u8;
    pub const asText = gst_sdp_message_as_text;

    /// Get the number of attributes in `msg`.
    extern fn gst_sdp_message_attributes_len(p_msg: *const SDPMessage) c_uint;
    pub const attributesLen = gst_sdp_message_attributes_len;

    /// Mapping of attributes of `gstsdp.SDPMessage` to `gst.Caps`
    extern fn gst_sdp_message_attributes_to_caps(p_msg: *const SDPMessage, p_caps: *gst.Caps) gstsdp.SDPResult;
    pub const attributesToCaps = gst_sdp_message_attributes_to_caps;

    /// Get the number of bandwidth information in `msg`.
    extern fn gst_sdp_message_bandwidths_len(p_msg: *const SDPMessage) c_uint;
    pub const bandwidthsLen = gst_sdp_message_bandwidths_len;

    /// Allocate a new copy of `msg` and store the result in `copy`. The value in
    /// `copy` should be release with gst_sdp_message_free function.
    extern fn gst_sdp_message_copy(p_msg: *const SDPMessage, p_copy: **gstsdp.SDPMessage) gstsdp.SDPResult;
    pub const copy = gst_sdp_message_copy;

    /// Dump the parsed contents of `msg` to stdout.
    extern fn gst_sdp_message_dump(p_msg: *const SDPMessage) gstsdp.SDPResult;
    pub const dump = gst_sdp_message_dump;

    /// Get the number of emails in `msg`.
    extern fn gst_sdp_message_emails_len(p_msg: *const SDPMessage) c_uint;
    pub const emailsLen = gst_sdp_message_emails_len;

    /// Free all resources allocated by `msg`. `msg` should not be used anymore after
    /// this function. This function should be used when `msg` was dynamically
    /// allocated with `gstsdp.sdpMessageNew`.
    extern fn gst_sdp_message_free(p_msg: *SDPMessage) gstsdp.SDPResult;
    pub const free = gst_sdp_message_free;

    /// Get the attribute at position `idx` in `msg`.
    extern fn gst_sdp_message_get_attribute(p_msg: *const SDPMessage, p_idx: c_uint) *const gstsdp.SDPAttribute;
    pub const getAttribute = gst_sdp_message_get_attribute;

    /// Get the first attribute with key `key` in `msg`.
    extern fn gst_sdp_message_get_attribute_val(p_msg: *const SDPMessage, p_key: [*:0]const u8) ?[*:0]const u8;
    pub const getAttributeVal = gst_sdp_message_get_attribute_val;

    /// Get the `nth` attribute with key `key` in `msg`.
    extern fn gst_sdp_message_get_attribute_val_n(p_msg: *const SDPMessage, p_key: [*:0]const u8, p_nth: c_uint) ?[*:0]const u8;
    pub const getAttributeValN = gst_sdp_message_get_attribute_val_n;

    /// Get the bandwidth at index `idx` from `msg`.
    extern fn gst_sdp_message_get_bandwidth(p_msg: *const SDPMessage, p_idx: c_uint) *const gstsdp.SDPBandwidth;
    pub const getBandwidth = gst_sdp_message_get_bandwidth;

    /// Get the connection of `msg`.
    extern fn gst_sdp_message_get_connection(p_msg: *const SDPMessage) *const gstsdp.SDPConnection;
    pub const getConnection = gst_sdp_message_get_connection;

    /// Get the email with number `idx` from `msg`.
    extern fn gst_sdp_message_get_email(p_msg: *const SDPMessage, p_idx: c_uint) [*:0]const u8;
    pub const getEmail = gst_sdp_message_get_email;

    /// Get the information in `msg`.
    extern fn gst_sdp_message_get_information(p_msg: *const SDPMessage) [*:0]const u8;
    pub const getInformation = gst_sdp_message_get_information;

    /// Get the encryption information from `msg`.
    extern fn gst_sdp_message_get_key(p_msg: *const SDPMessage) *const gstsdp.SDPKey;
    pub const getKey = gst_sdp_message_get_key;

    /// Get the media description at index `idx` in `msg`.
    extern fn gst_sdp_message_get_media(p_msg: *const SDPMessage, p_idx: c_uint) *const gstsdp.SDPMedia;
    pub const getMedia = gst_sdp_message_get_media;

    /// Get the origin of `msg`.
    extern fn gst_sdp_message_get_origin(p_msg: *const SDPMessage) *const gstsdp.SDPOrigin;
    pub const getOrigin = gst_sdp_message_get_origin;

    /// Get the phone with number `idx` from `msg`.
    extern fn gst_sdp_message_get_phone(p_msg: *const SDPMessage, p_idx: c_uint) [*:0]const u8;
    pub const getPhone = gst_sdp_message_get_phone;

    /// Get the session name in `msg`.
    extern fn gst_sdp_message_get_session_name(p_msg: *const SDPMessage) [*:0]const u8;
    pub const getSessionName = gst_sdp_message_get_session_name;

    /// Get time information with index `idx` from `msg`.
    extern fn gst_sdp_message_get_time(p_msg: *const SDPMessage, p_idx: c_uint) *const gstsdp.SDPTime;
    pub const getTime = gst_sdp_message_get_time;

    /// Get the URI in `msg`.
    extern fn gst_sdp_message_get_uri(p_msg: *const SDPMessage) [*:0]const u8;
    pub const getUri = gst_sdp_message_get_uri;

    /// Get the version in `msg`.
    extern fn gst_sdp_message_get_version(p_msg: *const SDPMessage) [*:0]const u8;
    pub const getVersion = gst_sdp_message_get_version;

    /// Get time zone information with index `idx` from `msg`.
    extern fn gst_sdp_message_get_zone(p_msg: *const SDPMessage, p_idx: c_uint) *const gstsdp.SDPZone;
    pub const getZone = gst_sdp_message_get_zone;

    /// Insert attribute into the array of attributes in `msg`
    /// at index `idx`.
    /// When -1 is given as `idx`, the attribute is inserted at the end.
    extern fn gst_sdp_message_insert_attribute(p_msg: *SDPMessage, p_idx: c_int, p_attr: *gstsdp.SDPAttribute) gstsdp.SDPResult;
    pub const insertAttribute = gst_sdp_message_insert_attribute;

    /// Insert bandwidth parameters into the array of bandwidths in `msg`
    /// at index `idx`.
    /// When -1 is given as `idx`, the bandwidth is inserted at the end.
    extern fn gst_sdp_message_insert_bandwidth(p_msg: *SDPMessage, p_idx: c_int, p_bw: *gstsdp.SDPBandwidth) gstsdp.SDPResult;
    pub const insertBandwidth = gst_sdp_message_insert_bandwidth;

    /// Insert `email` into the array of emails in `msg` at index `idx`.
    /// When -1 is given as `idx`, the email is inserted at the end.
    extern fn gst_sdp_message_insert_email(p_msg: *SDPMessage, p_idx: c_int, p_email: [*:0]const u8) gstsdp.SDPResult;
    pub const insertEmail = gst_sdp_message_insert_email;

    /// Insert `phone` into the array of phone numbers in `msg` at index `idx`.
    /// When -1 is given as `idx`, the phone is inserted at the end.
    extern fn gst_sdp_message_insert_phone(p_msg: *SDPMessage, p_idx: c_int, p_phone: [*:0]const u8) gstsdp.SDPResult;
    pub const insertPhone = gst_sdp_message_insert_phone;

    /// Insert time parameters into the array of times in `msg`
    /// at index `idx`.
    /// When -1 is given as `idx`, the times are inserted at the end.
    extern fn gst_sdp_message_insert_time(p_msg: *SDPMessage, p_idx: c_int, p_t: *gstsdp.SDPTime) gstsdp.SDPResult;
    pub const insertTime = gst_sdp_message_insert_time;

    /// Insert zone parameters into the array of zones in `msg`
    /// at index `idx`.
    /// When -1 is given as `idx`, the zone is inserted at the end.
    extern fn gst_sdp_message_insert_zone(p_msg: *SDPMessage, p_idx: c_int, p_zone: *gstsdp.SDPZone) gstsdp.SDPResult;
    pub const insertZone = gst_sdp_message_insert_zone;

    /// Get the number of media descriptions in `msg`.
    extern fn gst_sdp_message_medias_len(p_msg: *const SDPMessage) c_uint;
    pub const mediasLen = gst_sdp_message_medias_len;

    /// Creates a new `gstsdp.MIKEYMessage` after parsing the key-mgmt attribute
    /// from a `gstsdp.SDPMessage`.
    extern fn gst_sdp_message_parse_keymgmt(p_msg: *const SDPMessage, p_mikey: **gstsdp.MIKEYMessage) gstsdp.SDPResult;
    pub const parseKeymgmt = gst_sdp_message_parse_keymgmt;

    /// Get the number of phones in `msg`.
    extern fn gst_sdp_message_phones_len(p_msg: *const SDPMessage) c_uint;
    pub const phonesLen = gst_sdp_message_phones_len;

    /// Remove the attribute in `msg` at index `idx`.
    extern fn gst_sdp_message_remove_attribute(p_msg: *SDPMessage, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeAttribute = gst_sdp_message_remove_attribute;

    /// Remove the bandwidth information in `msg` at index `idx`.
    extern fn gst_sdp_message_remove_bandwidth(p_msg: *SDPMessage, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeBandwidth = gst_sdp_message_remove_bandwidth;

    /// Remove the email in `msg` at index `idx`.
    extern fn gst_sdp_message_remove_email(p_msg: *SDPMessage, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeEmail = gst_sdp_message_remove_email;

    /// Remove the media at `idx` from the array of medias in `msg` if found.
    extern fn gst_sdp_message_remove_media(p_msg: *SDPMessage, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeMedia = gst_sdp_message_remove_media;

    /// Remove the phone number in `msg` at index `idx`.
    extern fn gst_sdp_message_remove_phone(p_msg: *SDPMessage, p_idx: c_uint) gstsdp.SDPResult;
    pub const removePhone = gst_sdp_message_remove_phone;

    /// Remove the time information in `msg` at index `idx`.
    extern fn gst_sdp_message_remove_time(p_msg: *SDPMessage, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeTime = gst_sdp_message_remove_time;

    /// Remove the zone information in `msg` at index `idx`.
    extern fn gst_sdp_message_remove_zone(p_msg: *SDPMessage, p_idx: c_uint) gstsdp.SDPResult;
    pub const removeZone = gst_sdp_message_remove_zone;

    /// Replace the attribute in `msg` at index `idx` with `attr`.
    extern fn gst_sdp_message_replace_attribute(p_msg: *SDPMessage, p_idx: c_uint, p_attr: *gstsdp.SDPAttribute) gstsdp.SDPResult;
    pub const replaceAttribute = gst_sdp_message_replace_attribute;

    /// Replace the bandwidth information in `msg` at index `idx` with `bw`.
    extern fn gst_sdp_message_replace_bandwidth(p_msg: *SDPMessage, p_idx: c_uint, p_bw: *gstsdp.SDPBandwidth) gstsdp.SDPResult;
    pub const replaceBandwidth = gst_sdp_message_replace_bandwidth;

    /// Replace the email in `msg` at index `idx` with `email`.
    extern fn gst_sdp_message_replace_email(p_msg: *SDPMessage, p_idx: c_uint, p_email: [*:0]const u8) gstsdp.SDPResult;
    pub const replaceEmail = gst_sdp_message_replace_email;

    /// Replace the phone number in `msg` at index `idx` with `phone`.
    extern fn gst_sdp_message_replace_phone(p_msg: *SDPMessage, p_idx: c_uint, p_phone: [*:0]const u8) gstsdp.SDPResult;
    pub const replacePhone = gst_sdp_message_replace_phone;

    /// Replace the time information in `msg` at index `idx` with `t`.
    extern fn gst_sdp_message_replace_time(p_msg: *SDPMessage, p_idx: c_uint, p_t: *gstsdp.SDPTime) gstsdp.SDPResult;
    pub const replaceTime = gst_sdp_message_replace_time;

    /// Replace the zone information in `msg` at index `idx` with `zone`.
    extern fn gst_sdp_message_replace_zone(p_msg: *SDPMessage, p_idx: c_uint, p_zone: *gstsdp.SDPZone) gstsdp.SDPResult;
    pub const replaceZone = gst_sdp_message_replace_zone;

    /// Configure the SDP connection in `msg` with the given parameters.
    extern fn gst_sdp_message_set_connection(p_msg: *SDPMessage, p_nettype: [*:0]const u8, p_addrtype: [*:0]const u8, p_address: [*:0]const u8, p_ttl: c_uint, p_addr_number: c_uint) gstsdp.SDPResult;
    pub const setConnection = gst_sdp_message_set_connection;

    /// Set the information in `msg`.
    extern fn gst_sdp_message_set_information(p_msg: *SDPMessage, p_information: [*:0]const u8) gstsdp.SDPResult;
    pub const setInformation = gst_sdp_message_set_information;

    /// Adds the encryption information to `msg`.
    extern fn gst_sdp_message_set_key(p_msg: *SDPMessage, p_type: [*:0]const u8, p_data: [*:0]const u8) gstsdp.SDPResult;
    pub const setKey = gst_sdp_message_set_key;

    /// Configure the SDP origin in `msg` with the given parameters.
    extern fn gst_sdp_message_set_origin(p_msg: *SDPMessage, p_username: [*:0]const u8, p_sess_id: [*:0]const u8, p_sess_version: [*:0]const u8, p_nettype: [*:0]const u8, p_addrtype: [*:0]const u8, p_addr: [*:0]const u8) gstsdp.SDPResult;
    pub const setOrigin = gst_sdp_message_set_origin;

    /// Set the session name in `msg`.
    extern fn gst_sdp_message_set_session_name(p_msg: *SDPMessage, p_session_name: [*:0]const u8) gstsdp.SDPResult;
    pub const setSessionName = gst_sdp_message_set_session_name;

    /// Set the URI in `msg`.
    extern fn gst_sdp_message_set_uri(p_msg: *SDPMessage, p_uri: [*:0]const u8) gstsdp.SDPResult;
    pub const setUri = gst_sdp_message_set_uri;

    /// Set the version in `msg`.
    extern fn gst_sdp_message_set_version(p_msg: *SDPMessage, p_version: [*:0]const u8) gstsdp.SDPResult;
    pub const setVersion = gst_sdp_message_set_version;

    /// Get the number of time information entries in `msg`.
    extern fn gst_sdp_message_times_len(p_msg: *const SDPMessage) c_uint;
    pub const timesLen = gst_sdp_message_times_len;

    /// Free all resources allocated in `msg`. `msg` should not be used anymore after
    /// this function. This function should be used when `msg` was allocated on the
    /// stack and initialized with `gstsdp.sdpMessageInit`.
    extern fn gst_sdp_message_uninit(p_msg: *SDPMessage) gstsdp.SDPResult;
    pub const uninit = gst_sdp_message_uninit;

    /// Get the number of time zone information entries in `msg`.
    extern fn gst_sdp_message_zones_len(p_msg: *const SDPMessage) c_uint;
    pub const zonesLen = gst_sdp_message_zones_len;

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

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

/// The contents of the SDP "o=" field which gives the originator of the session
/// (their username and the address of the user's host) plus a session id and
/// session version number.
pub const SDPOrigin = extern struct {
    /// the user's login on the originating host, or it is "-"
    ///    if the originating host does not support the concept of user ids.
    f_username: ?[*:0]u8,
    /// is a numeric string such that the tuple of `username`, `sess_id`,
    ///    `nettype`, `addrtype` and `addr` form a globally unique identifier for the
    ///    session.
    f_sess_id: ?[*:0]u8,
    /// a version number for this announcement
    f_sess_version: ?[*:0]u8,
    /// the type of network. "IN" is defined to have the meaning
    ///    "Internet".
    f_nettype: ?[*:0]u8,
    /// the type of `addr`.
    f_addrtype: ?[*:0]u8,
    /// the globally unique address of the machine from which the session was
    ///     created.
    f_addr: ?[*:0]u8,

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

/// The contents of the SDP "t=" field which specify the start and stop times for
/// a conference session.
pub const SDPTime = extern struct {
    /// start time for the conference. The value is the decimal
    ///     representation of Network Time Protocol (NTP) time values in seconds
    f_start: ?[*:0]u8,
    /// stop time for the conference. The value is the decimal
    ///     representation of Network Time Protocol (NTP) time values in seconds
    f_stop: ?[*:0]u8,
    /// repeat times for a session
    f_repeat: ?*glib.Array,

    /// Reset the time information in `t`.
    extern fn gst_sdp_time_clear(p_t: *SDPTime) gstsdp.SDPResult;
    pub const clear = gst_sdp_time_clear;

    /// Set time information `start`, `stop` and `repeat` in `t`.
    extern fn gst_sdp_time_set(p_t: *SDPTime, p_start: [*:0]const u8, p_stop: [*:0]const u8, p_repeat: [*][*:0]const u8) gstsdp.SDPResult;
    pub const set = gst_sdp_time_set;

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

/// The contents of the SDP "z=" field which allows the sender to
/// specify a list of time zone adjustments and offsets from the base
/// time.
pub const SDPZone = extern struct {
    /// the NTP time that a time zone adjustment happens
    f_time: ?[*:0]u8,
    /// the offset from the time when the session was first scheduled
    f_typed_time: ?[*:0]u8,

    /// Reset the zone information in `zone`.
    extern fn gst_sdp_zone_clear(p_zone: *SDPZone) gstsdp.SDPResult;
    pub const clear = gst_sdp_zone_clear;

    /// Set zone information in `zone`.
    extern fn gst_sdp_zone_set(p_zone: *SDPZone, p_adj_time: [*:0]const u8, p_typed_time: [*:0]const u8) gstsdp.SDPResult;
    pub const set = gst_sdp_zone_set;

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

/// The different cache types
pub const MIKEYCacheType = enum(c_int) {
    none = 0,
    always = 1,
    for_csb = 2,
    _,

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

/// The encryption algorithm used to encrypt the Encr data field
pub const MIKEYEncAlg = enum(c_int) {
    null = 0,
    aes_cm_128 = 1,
    aes_kw_128 = 2,
    aes_gcm_128 = 6,
    _,

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

/// The key validity type
pub const MIKEYKVType = enum(c_int) {
    null = 0,
    spi = 1,
    interval = 2,
    _,

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

/// The type of key.
pub const MIKEYKeyDataType = enum(c_int) {
    tgk = 0,
    tek = 2,
    _,

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

/// Specifies the authentication algorithm used
pub const MIKEYMacAlg = enum(c_int) {
    null = 0,
    hmac_sha_1_160 = 1,
    _,

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

/// Specifies the method of uniquely mapping Crypto Sessions to the security
/// protocol sessions.
pub const MIKEYMapType = enum(c_int) {
    mikey_map_type_srtp = 0,
    _,

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

/// The PRF function that has been/will be used for key derivation
pub const MIKEYPRFFunc = enum(c_int) {
    mikey_prf_mikey_1 = 0,
    _,

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

/// Different MIKEY Payload types.
pub const MIKEYPayloadType = enum(c_int) {
    last = 0,
    kemac = 1,
    pke = 2,
    dh = 3,
    sign = 4,
    t = 5,
    id = 6,
    cert = 7,
    chash = 8,
    v = 9,
    sp = 10,
    rand = 11,
    err = 12,
    key_data = 20,
    gen_ext = 21,
    _,

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

/// Specifies the security protocol
pub const MIKEYSecProto = enum(c_int) {
    mikey_sec_proto_srtp = 0,
    _,

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

/// This policy specifies the parameters for SRTP and SRTCP
pub const MIKEYSecSRTP = enum(c_int) {
    enc_alg = 0,
    enc_key_len = 1,
    auth_alg = 2,
    auth_key_len = 3,
    salt_key_len = 4,
    prf = 5,
    key_deriv_rate = 6,
    srtp_enc = 7,
    srtcp_enc = 8,
    fec_order = 9,
    srtp_auth = 10,
    auth_tag_len = 11,
    srtp_prefix_len = 12,
    aead_auth_tag_len = 20,
    _,

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

/// Specifies the timestamp type.
pub const MIKEYTSType = enum(c_int) {
    ntp_utc = 0,
    ntp = 1,
    counter = 2,
    _,

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

/// Different MIKEY data types.
pub const MIKEYType = enum(c_int) {
    invalid = -1,
    psk_init = 0,
    psk_verify = 1,
    pk_init = 2,
    pk_verify = 3,
    dh_init = 4,
    dh_resp = 5,
    @"error" = 6,
    _,

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

/// Return values for the SDP functions.
pub const SDPResult = enum(c_int) {
    ok = 0,
    einval = -1,
    _,

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

/// Check if the given `addr` is a multicast address.
extern fn gst_sdp_address_is_multicast(p_nettype: [*:0]const u8, p_addrtype: [*:0]const u8, p_addr: [*:0]const u8) c_int;
pub const sdpAddressIsMulticast = gst_sdp_address_is_multicast;

/// Makes key management data
extern fn gst_sdp_make_keymgmt(p_uri: [*:0]const u8, p_base64: [*:0]const u8) [*:0]u8;
pub const sdpMakeKeymgmt = gst_sdp_make_keymgmt;

/// The supported MIKEY version 1.
pub const MIKEY_VERSION = 1;
/// The Application-Specific Maximum bandwidth modifier.
pub const SDP_BWTYPE_AS = "AS";
/// The Conference Total bandwidth modifier.
pub const SDP_BWTYPE_CT = "CT";
/// The extension prefix bandwidth modifier.
pub const SDP_BWTYPE_EXT_PREFIX = "X-";
/// RTCP bandwidth allocated to data receivers (RFC 3556).
pub const SDP_BWTYPE_RR = "RR";
/// RTCP bandwidth allocated to active data senders (RFC 3556).
pub const SDP_BWTYPE_RS = "RS";
/// Transport Independent Application Specific Maximum bandwidth (RFC 3890).
pub const SDP_BWTYPE_TIAS = "TIAS";

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