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

const std = @import("std");
const compat = @import("compat");
const gstbase = @import("gstbase1");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
/// Provides a base class for audio RTP payloaders for frame or sample based
/// audio codecs (constant bitrate)
///
/// This class derives from GstRTPBasePayload. It can be used for payloading
/// audio codecs. It will only work with constant bitrate codecs. It supports
/// both frame based and sample based codecs. It takes care of packing up the
/// audio data into RTP packets and filling up the headers accordingly. The
/// payloading is done based on the maximum MTU (mtu) and the maximum time per
/// packet (max-ptime). The general idea is to divide large data buffers into
/// smaller RTP packets. The RTP packet size is the minimum of either the MTU,
/// max-ptime (if set) or available data. The RTP packet size is always larger or
/// equal to min-ptime (if set). If min-ptime is not set, any residual data is
/// sent in a last RTP packet. In the case of frame based codecs, the resulting
/// RTP packets always contain full frames.
///
/// ## Usage
///
/// To use this base class, your child element needs to call either
/// `gstrtp.RTPBaseAudioPayload.setFrameBased` or
/// `gstrtp.RTPBaseAudioPayload.setSampleBased`. This is usually done in the
/// element's ``_init`` function. Then, the child element must call either
/// `gstrtp.RTPBaseAudioPayload.setFrameOptions`,
/// `gstrtp.RTPBaseAudioPayload.setSampleOptions` or
/// gst_rtp_base_audio_payload_set_samplebits_options. Since
/// GstRTPBaseAudioPayload derives from GstRTPBasePayload, the child element
/// must set any variables or call/override any functions required by that base
/// class. The child element does not need to override any other functions
/// specific to GstRTPBaseAudioPayload.
pub const RTPBaseAudioPayload = extern struct {
    pub const Parent = gstrtp.RTPBasePayload;
    pub const Implements = [_]type{};
    pub const Class = gstrtp.RTPBaseAudioPayloadClass;
    f_payload: gstrtp.RTPBasePayload,
    f_priv: ?*gstrtp.RTPBaseAudioPayloadPrivate,
    f_base_ts: gst.ClockTime,
    f_frame_size: c_int,
    f_frame_duration: c_int,
    f_sample_size: c_int,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {};

    pub const properties = struct {
        pub const buffer_list = struct {
            pub const name = "buffer-list";

            pub const Type = c_int;
        };
    };

    pub const signals = struct {};

    /// Create an RTP buffer and store `payload_len` bytes of the adapter as the
    /// payload. Set the timestamp on the new buffer to `timestamp` before pushing
    /// the buffer downstream.
    ///
    /// If `payload_len` is -1, all pending bytes will be flushed. If `timestamp` is
    /// -1, the timestamp will be calculated automatically.
    extern fn gst_rtp_base_audio_payload_flush(p_baseaudiopayload: *RTPBaseAudioPayload, p_payload_len: c_uint, p_timestamp: gst.ClockTime) gst.FlowReturn;
    pub const flush = gst_rtp_base_audio_payload_flush;

    /// Gets the internal adapter used by the depayloader.
    extern fn gst_rtp_base_audio_payload_get_adapter(p_rtpbaseaudiopayload: *RTPBaseAudioPayload) *gstbase.Adapter;
    pub const getAdapter = gst_rtp_base_audio_payload_get_adapter;

    /// Create an RTP buffer and store `payload_len` bytes of `data` as the
    /// payload. Set the timestamp on the new buffer to `timestamp` before pushing
    /// the buffer downstream.
    extern fn gst_rtp_base_audio_payload_push(p_baseaudiopayload: *RTPBaseAudioPayload, p_data: [*]const u8, p_payload_len: c_uint, p_timestamp: gst.ClockTime) gst.FlowReturn;
    pub const push = gst_rtp_base_audio_payload_push;

    /// Tells `gstrtp.RTPBaseAudioPayload` that the child element is for a frame based
    /// audio codec
    extern fn gst_rtp_base_audio_payload_set_frame_based(p_rtpbaseaudiopayload: *RTPBaseAudioPayload) void;
    pub const setFrameBased = gst_rtp_base_audio_payload_set_frame_based;

    /// Sets the options for frame based audio codecs.
    extern fn gst_rtp_base_audio_payload_set_frame_options(p_rtpbaseaudiopayload: *RTPBaseAudioPayload, p_frame_duration: c_int, p_frame_size: c_int) void;
    pub const setFrameOptions = gst_rtp_base_audio_payload_set_frame_options;

    /// Tells `gstrtp.RTPBaseAudioPayload` that the child element is for a sample based
    /// audio codec
    extern fn gst_rtp_base_audio_payload_set_sample_based(p_rtpbaseaudiopayload: *RTPBaseAudioPayload) void;
    pub const setSampleBased = gst_rtp_base_audio_payload_set_sample_based;

    /// Sets the options for sample based audio codecs.
    extern fn gst_rtp_base_audio_payload_set_sample_options(p_rtpbaseaudiopayload: *RTPBaseAudioPayload, p_sample_size: c_int) void;
    pub const setSampleOptions = gst_rtp_base_audio_payload_set_sample_options;

    /// Sets the options for sample based audio codecs.
    extern fn gst_rtp_base_audio_payload_set_samplebits_options(p_rtpbaseaudiopayload: *RTPBaseAudioPayload, p_sample_size: c_int) void;
    pub const setSamplebitsOptions = gst_rtp_base_audio_payload_set_samplebits_options;

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

    extern fn g_object_ref(p_self: *gstrtp.RTPBaseAudioPayload) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstrtp.RTPBaseAudioPayload) void;
    pub const unref = g_object_unref;

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

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

/// Provides a base class for RTP depayloaders
///
/// In order to handle RTP header extensions correctly if the
/// depayloader aggregates multiple RTP packet payloads into one output
/// buffer this class provides the function
/// `gstrtp.RTPBaseDepayload.setAggregateHdrextEnabled`. If the
/// aggregation is enabled the virtual functions
/// `GstRTPBaseDepayload`.process or
/// `GstRTPBaseDepayload`.process_rtp_packet must tell the base class
/// what happens to the current RTP packet. By default the base class
/// assumes that the packet payload is used with the next output
/// buffer.
///
/// If the RTP packet will not be used with an output buffer
/// `gstrtp.RTPBaseDepayload.dropped` must be called. A typical
/// situation would be if we are waiting for a keyframe.
///
/// If the RTP packet will be used but not with the current output
/// buffer but with the next one `gstrtp.RTPBaseDepayload.delayed` must
/// be called. This may happen if the current RTP packet signals the
/// start of a new output buffer and the currently processed output
/// buffer will be pushed first. The undelay happens implicitly once
/// the current buffer has been pushed or
/// `gstrtp.RTPBaseDepayload.flush` has been called.
///
/// If `gstrtp.RTPBaseDepayload.flush` is called all RTP packets that
/// have not been dropped since the last output buffer are dropped,
/// e.g. if an output buffer is discarded due to malformed data. This
/// may or may not include the current RTP packet depending on the 2nd
/// parameter `keep_current`.
///
/// Be aware that in case `gstrtp.RTPBaseDepayload.pushList` is used
/// each buffer will see the same list of RTP header extensions.
pub const RTPBaseDepayload = extern struct {
    pub const Parent = gst.Element;
    pub const Implements = [_]type{};
    pub const Class = gstrtp.RTPBaseDepayloadClass;
    f_parent: gst.Element,
    f_sinkpad: ?*gst.Pad,
    f_srcpad: ?*gst.Pad,
    f_clock_rate: c_uint,
    f_segment: gst.Segment,
    f_need_newsegment: c_int,
    f_priv: ?*gstrtp.RTPBaseDepayloadPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// custom event handling
        pub const handle_event = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(RTPBaseDepayload.Class, p_class).f_handle_event.?(gobject.ext.as(RTPBaseDepayload, p_filter), p_event);
            }

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

        /// signal the depayloader about packet loss
        pub const packet_lost = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(RTPBaseDepayload.Class, p_class).f_packet_lost.?(gobject.ext.as(RTPBaseDepayload, p_filter), p_event);
            }

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

        /// process incoming rtp packets. Subclass must implement either
        ///   this method or `process_rtp_packet` to process incoming rtp packets.
        ///   If the child returns a buffer without a valid timestamp, the timestamp
        ///   of the provided buffer will be applied to the result buffer and the
        ///   buffer will be pushed. If this function returns `NULL`, nothing is pushed.
        pub const process = struct {
            pub fn call(p_class: anytype, p_base: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_in: *gst.Buffer) *gst.Buffer {
                return gobject.ext.as(RTPBaseDepayload.Class, p_class).f_process.?(gobject.ext.as(RTPBaseDepayload, p_base), p_in);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_base: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_in: *gst.Buffer) callconv(.c) *gst.Buffer) void {
                gobject.ext.as(RTPBaseDepayload.Class, p_class).f_process = @ptrCast(p_implementation);
            }
        };

        /// Same as the process virtual function, but slightly more
        /// efficient, since it is passed the rtp buffer structure that has already
        /// been mapped (with GST_MAP_READ) by the base class and thus does not have
        /// to be mapped again by the subclass. Can be used by the subclass to process
        /// incoming rtp packets. If the subclass returns a buffer without a valid
        /// timestamp, the timestamp of the input buffer will be applied to the result
        /// buffer and the output buffer will be pushed out. If this function returns
        /// `NULL`, nothing is pushed out. Since: 1.6.
        pub const process_rtp_packet = struct {
            pub fn call(p_class: anytype, p_base: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_rtp_buffer: *gstrtp.RTPBuffer) *gst.Buffer {
                return gobject.ext.as(RTPBaseDepayload.Class, p_class).f_process_rtp_packet.?(gobject.ext.as(RTPBaseDepayload, p_base), p_rtp_buffer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_base: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_rtp_buffer: *gstrtp.RTPBuffer) callconv(.c) *gst.Buffer) void {
                gobject.ext.as(RTPBaseDepayload.Class, p_class).f_process_rtp_packet = @ptrCast(p_implementation);
            }
        };

        /// configure the depayloader
        pub const set_caps = struct {
            pub fn call(p_class: anytype, p_filter: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps) c_int {
                return gobject.ext.as(RTPBaseDepayload.Class, p_class).f_set_caps.?(gobject.ext.as(RTPBaseDepayload, p_filter), p_caps);
            }

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

    pub const properties = struct {
        /// If enabled, the depayloader will automatically try to enable all the
        /// RTP header extensions provided in the sink caps, saving the application
        /// the need to handle these extensions manually using the
        /// GstRTPBaseDepayload::request-extension: signal.
        pub const auto_header_extension = struct {
            pub const name = "auto-header-extension";

            pub const Type = c_int;
        };

        /// A list of already enabled RTP header extensions. This may be useful for finding
        /// out which extensions are already enabled (with add-extension signal) and picking a non-conflicting
        /// ID for a new extension that needs to be added on top of the existing ones.
        ///
        /// Note that the value returned by reading this property is not dynamically updated when the set of
        /// enabled extensions changes by any of existing action signals. Rather, it represents the current state
        /// at the time the property is read.
        ///
        /// Dynamic updates of this property can be received by subscribing to its corresponding "notify" signal, i.e.
        /// "notify::extensions".
        pub const extensions = struct {
            pub const name = "extensions";

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

        /// Max seqnum reorder before the sender is assumed to have restarted.
        ///
        /// When max-reorder is set to 0 all reordered/duplicate packets are
        /// considered coming from a restarted sender.
        pub const max_reorder = struct {
            pub const name = "max-reorder";

            pub const Type = c_int;
        };

        /// Add RTP source information found in RTP header as meta to output buffer.
        pub const source_info = struct {
            pub const name = "source-info";

            pub const Type = c_int;
        };

        /// Various depayloader statistics retrieved atomically (and are therefore
        /// synchroized with each other). This property return a GstStructure named
        /// application/x-rtp-depayload-stats containing the following fields relating to
        /// the last processed buffer and current state of the stream being depayloaded:
        ///
        ///   * `clock-rate`: `G_TYPE_UINT`, clock-rate of the stream
        ///   * `npt-start`: `G_TYPE_UINT64`, time of playback start
        ///   * `npt-stop`: `G_TYPE_UINT64`, time of playback stop
        ///   * `play-speed`: `G_TYPE_DOUBLE`, the playback speed
        ///   * `play-scale`: `G_TYPE_DOUBLE`, the playback scale
        ///   * `running-time-dts`: `G_TYPE_UINT64`, the last running-time of the
        ///      last DTS
        ///   * `running-time-pts`: `G_TYPE_UINT64`, the last running-time of the
        ///      last PTS
        ///   * `seqnum`: `G_TYPE_UINT`, the last seen seqnum
        ///   * `timestamp`: `G_TYPE_UINT`, the last seen RTP timestamp
        pub const stats = struct {
            pub const name = "stats";

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

    pub const signals = struct {
        /// Add `ext` as an extension for reading part of an RTP header extension from
        /// incoming RTP packets.
        pub const add_extension = struct {
            pub const name = "add-extension";

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

        /// Clear all RTP header extensions used by this depayloader.
        pub const clear_extensions = struct {
            pub const name = "clear-extensions";

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

        /// The returned `ext` must be configured with the correct `ext_id` and with the
        /// necessary attributes as required by the extension implementation.
        pub const request_extension = struct {
            pub const name = "request-extension";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_ext_id: c_uint, p_ext_uri: ?[*:0]u8, P_Data) callconv(.c) ?*gstrtp.RTPHeaderExtension, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(RTPBaseDepayload, p_instance))),
                    gobject.signalLookup("request-extension", RTPBaseDepayload.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Called from `GstRTPBaseDepayload`.process or
    /// `GstRTPBaseDepayload`.process_rtp_packet when the depayloader needs
    /// to keep the current input RTP header for use with the next output
    /// buffer.
    ///
    /// The delayed buffer will remain until the end of processing the
    /// current output buffer and then enqueued for processing with the
    /// next output buffer.
    ///
    /// A typical use-case is when the depayloader implementation will
    /// start a new output buffer for the current input RTP buffer but push
    /// the current output buffer first.
    ///
    /// Must be called with the stream lock held.
    extern fn gst_rtp_base_depayload_delayed(p_depayload: *RTPBaseDepayload) void;
    pub const delayed = gst_rtp_base_depayload_delayed;

    /// Called from `GstRTPBaseDepayload`.process or
    /// `GstRTPBaseDepayload`.process_rtp_packet if the depayloader does not
    /// use the current buffer for the output buffer. This will either drop
    /// the delayed buffer or the last buffer from the header extension
    /// cache.
    ///
    /// A typical use-case is when the depayloader implementation is
    /// dropping an input RTP buffer while waiting for the first keyframe.
    ///
    /// Must be called with the stream lock held.
    extern fn gst_rtp_base_depayload_dropped(p_depayload: *RTPBaseDepayload) void;
    pub const dropped = gst_rtp_base_depayload_dropped;

    /// If `GstRTPBaseDepayload`.process or
    /// `GstRTPBaseDepayload`.process_rtp_packet drop an output buffer this
    /// function tells the base class to flush header extension cache as
    /// well.
    ///
    /// This will not drop an input RTP header marked as delayed from
    /// `gstrtp.RTPBaseDepayload.delayed`.
    ///
    /// If `keep_current` is `TRUE` the current input RTP header will be kept
    /// and enqueued after flushing the previous input RTP headers.
    ///
    /// A typical use-case for `keep_current` is when the depayloader
    /// implementation invalidates the current output buffer and starts a
    /// new one with the current RTP input buffer.
    ///
    /// Must be called with the stream lock held.
    extern fn gst_rtp_base_depayload_flush(p_depayload: *RTPBaseDepayload, p_keep_current: c_int) void;
    pub const flush = gst_rtp_base_depayload_flush;

    /// Queries whether header extensions will be aggregated per depayloaded buffers.
    extern fn gst_rtp_base_depayload_is_aggregate_hdrext_enabled(p_depayload: *RTPBaseDepayload) c_int;
    pub const isAggregateHdrextEnabled = gst_rtp_base_depayload_is_aggregate_hdrext_enabled;

    /// Queries whether `gstrtp.RTPSourceMeta` will be added to depayloaded buffers.
    extern fn gst_rtp_base_depayload_is_source_info_enabled(p_depayload: *RTPBaseDepayload) c_int;
    pub const isSourceInfoEnabled = gst_rtp_base_depayload_is_source_info_enabled;

    /// Push `out_buf` to the peer of `filter`. This function takes ownership of
    /// `out_buf`.
    ///
    /// This function will by default apply the last incoming timestamp on
    /// the outgoing buffer when it didn't have a timestamp already.
    extern fn gst_rtp_base_depayload_push(p_filter: *RTPBaseDepayload, p_out_buf: *gst.Buffer) gst.FlowReturn;
    pub const push = gst_rtp_base_depayload_push;

    /// Push `out_list` to the peer of `filter`. This function takes ownership of
    /// `out_list`.
    extern fn gst_rtp_base_depayload_push_list(p_filter: *RTPBaseDepayload, p_out_list: *gst.BufferList) gst.FlowReturn;
    pub const pushList = gst_rtp_base_depayload_push_list;

    /// Enable or disable aggregating header extensions.
    extern fn gst_rtp_base_depayload_set_aggregate_hdrext_enabled(p_depayload: *RTPBaseDepayload, p_enable: c_int) void;
    pub const setAggregateHdrextEnabled = gst_rtp_base_depayload_set_aggregate_hdrext_enabled;

    /// Enable or disable adding `gstrtp.RTPSourceMeta` to depayloaded buffers.
    extern fn gst_rtp_base_depayload_set_source_info_enabled(p_depayload: *RTPBaseDepayload, p_enable: c_int) void;
    pub const setSourceInfoEnabled = gst_rtp_base_depayload_set_source_info_enabled;

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

    extern fn g_object_ref(p_self: *gstrtp.RTPBaseDepayload) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstrtp.RTPBaseDepayload) void;
    pub const unref = g_object_unref;

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

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

/// Provides a base class for RTP payloaders
pub const RTPBasePayload = extern struct {
    pub const Parent = gst.Element;
    pub const Implements = [_]type{};
    pub const Class = gstrtp.RTPBasePayloadClass;
    f_element: gst.Element,
    f_sinkpad: ?*gst.Pad,
    f_srcpad: ?*gst.Pad,
    f_ts_base: u32,
    f_seqnum_base: u16,
    f_media: ?[*:0]u8,
    f_encoding_name: ?[*:0]u8,
    f_dynamic: c_int,
    f_clock_rate: u32,
    f_ts_offset: i32,
    f_timestamp: u32,
    f_seqnum_offset: i16,
    f_seqnum: u16,
    f_max_ptime: i64,
    f_pt: c_uint,
    f_ssrc: c_uint,
    f_current_ssrc: c_uint,
    f_mtu: c_uint,
    f_segment: gst.Segment,
    f_min_ptime: u64,
    f_ptime: u64,
    f_ptime_multiple: u64,
    f_priv: ?*gstrtp.RTPBasePayloadPrivate,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// get desired caps
        pub const get_caps = struct {
            pub fn call(p_class: anytype, p_payload: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad, p_filter: *gst.Caps) *gst.Caps {
                return gobject.ext.as(RTPBasePayload.Class, p_class).f_get_caps.?(gobject.ext.as(RTPBasePayload, p_payload), p_pad, p_filter);
            }

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

        /// process data
        pub const handle_buffer = struct {
            pub fn call(p_class: anytype, p_payload: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_buffer: *gst.Buffer) gst.FlowReturn {
                return gobject.ext.as(RTPBasePayload.Class, p_class).f_handle_buffer.?(gobject.ext.as(RTPBasePayload, p_payload), p_buffer);
            }

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

        /// custom query handling
        pub const query = struct {
            pub fn call(p_class: anytype, p_payload: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_pad: *gst.Pad, p_query: *gst.Query) c_int {
                return gobject.ext.as(RTPBasePayload.Class, p_class).f_query.?(gobject.ext.as(RTPBasePayload, p_payload), p_pad, p_query);
            }

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

        /// configure the payloader
        pub const set_caps = struct {
            pub fn call(p_class: anytype, p_payload: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *gst.Caps) c_int {
                return gobject.ext.as(RTPBasePayload.Class, p_class).f_set_caps.?(gobject.ext.as(RTPBasePayload, p_payload), p_caps);
            }

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

        /// custom event handling on the sinkpad
        pub const sink_event = struct {
            pub fn call(p_class: anytype, p_payload: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(RTPBasePayload.Class, p_class).f_sink_event.?(gobject.ext.as(RTPBasePayload, p_payload), p_event);
            }

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

        /// custom event handling on the srcpad
        pub const src_event = struct {
            pub fn call(p_class: anytype, p_payload: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_event: *gst.Event) c_int {
                return gobject.ext.as(RTPBasePayload.Class, p_class).f_src_event.?(gobject.ext.as(RTPBasePayload, p_payload), p_event);
            }

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

    pub const properties = struct {
        /// If enabled, the payloader will automatically try to enable all the
        /// RTP header extensions provided in the src caps, saving the application
        /// the need to handle these extensions manually using the
        /// GstRTPBasePayload::request-extension: signal.
        pub const auto_header_extension = struct {
            pub const name = "auto-header-extension";

            pub const Type = c_int;
        };

        /// A list of already enabled RTP header extensions. This may be useful for finding
        /// out which extensions are already enabled (with add-extension signal) and picking a non-conflicting
        /// ID for a new extension that needs to be added on top of the existing ones.
        ///
        /// Note that the value returned by reading this property is not dynamically updated when the set of
        /// enabled extensions changes by any of existing action signals. Rather, it represents the current state
        /// at the time the property is read.
        ///
        /// Dynamic updates of this property can be received by subscribing to its corresponding "notify" signal, i.e.
        /// "notify::extensions".
        pub const extensions = struct {
            pub const name = "extensions";

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

        pub const max_ptime = struct {
            pub const name = "max-ptime";

            pub const Type = i64;
        };

        /// Minimum duration of the packet data in ns (can't go above MTU)
        pub const min_ptime = struct {
            pub const name = "min-ptime";

            pub const Type = i64;
        };

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

            pub const Type = c_uint;
        };

        /// Make the payloader timestamp packets according to the Rate-Control=no
        /// behaviour specified in the ONVIF replay spec.
        pub const onvif_no_rate_control = struct {
            pub const name = "onvif-no-rate-control";

            pub const Type = c_int;
        };

        /// Try to use the offset fields to generate perfect RTP timestamps. When this
        /// option is disabled, RTP timestamps are generated from GST_BUFFER_PTS of
        /// each payloaded buffer. The PTSes of buffers may not necessarily increment
        /// with the amount of data in each input buffer, consider e.g. the case where
        /// the buffer arrives from a network which means that the PTS is unrelated to
        /// the amount of data. Because the RTP timestamps are generated from
        /// GST_BUFFER_PTS this can result in RTP timestamps that also don't increment
        /// with the amount of data in the payloaded packet. To circumvent this it is
        /// possible to set the perfect rtptime option enabled. When this option is
        /// enabled the payloader will increment the RTP timestamps based on
        /// GST_BUFFER_OFFSET which relates to the amount of data in each packet
        /// rather than the GST_BUFFER_PTS of each buffer and therefore the RTP
        /// timestamps will more closely correlate with the amount of data in each
        /// buffer. Currently GstRTPBasePayload is limited to handling perfect RTP
        /// timestamps for audio streams.
        pub const perfect_rtptime = struct {
            pub const name = "perfect-rtptime";

            pub const Type = c_int;
        };

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

            pub const Type = c_uint;
        };

        /// Force buffers to be multiples of this duration in ns (0 disables)
        pub const ptime_multiple = struct {
            pub const name = "ptime-multiple";

            pub const Type = i64;
        };

        /// Make the RTP packets' timestamps be scaled with the segment's rate
        /// (corresponding to RTSP speed parameter). Disabling this property means
        /// the timestamps will not be affected by the set delivery speed (RTSP speed).
        ///
        /// Example: A server wants to allow streaming a recorded video in double
        /// speed but still have the timestamps correspond to the position in the
        /// video. This is achieved by the client setting RTSP Speed to 2 while the
        /// server has this property disabled.
        pub const scale_rtptime = struct {
            pub const name = "scale-rtptime";

            pub const Type = c_int;
        };

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

            pub const Type = c_uint;
        };

        pub const seqnum_offset = struct {
            pub const name = "seqnum-offset";

            pub const Type = c_int;
        };

        /// Enable writing the CSRC field in allocated RTP header based on RTP source
        /// information found in the input buffer's `gstrtp.RTPSourceMeta`.
        pub const source_info = struct {
            pub const name = "source-info";

            pub const Type = c_int;
        };

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

            pub const Type = c_uint;
        };

        /// Various payloader statistics retrieved atomically (and are therefore
        /// synchroized with each other), these can be used e.g. to generate an
        /// RTP-Info header. This property return a GstStructure named
        /// application/x-rtp-payload-stats containing the following fields relating to
        /// the last processed buffer and current state of the stream being payloaded:
        ///
        ///   * `clock-rate` :`G_TYPE_UINT`, clock-rate of the stream
        ///   * `running-time` :`G_TYPE_UINT64`, running time
        ///   * `seqnum` :`G_TYPE_UINT`, sequence number, same as `gstrtp.RTPBasePayload.properties.seqnum`
        ///   * `timestamp` :`G_TYPE_UINT`, RTP timestamp, same as `gstrtp.RTPBasePayload.properties.timestamp`
        ///   * `ssrc` :`G_TYPE_UINT`, The SSRC in use
        ///   * `pt` :`G_TYPE_UINT`, The Payload type in use, same as `gstrtp.RTPBasePayload.properties.pt`
        ///   * `seqnum-offset` :`G_TYPE_UINT`, The current offset added to the seqnum
        ///   * `timestamp-offset` :`G_TYPE_UINT`, The current offset added to the timestamp
        pub const stats = struct {
            pub const name = "stats";

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

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

            pub const Type = c_uint;
        };

        pub const timestamp_offset = struct {
            pub const name = "timestamp-offset";

            pub const Type = c_uint;
        };
    };

    pub const signals = struct {
        /// Add `ext` as an extension for writing part of an RTP header extension onto
        /// outgoing RTP packets.
        pub const add_extension = struct {
            pub const name = "add-extension";

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

        /// Clear all RTP header extensions used by this payloader.
        pub const clear_extensions = struct {
            pub const name = "clear-extensions";

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

        /// The returned `ext` must be configured with the correct `ext_id` and with the
        /// necessary attributes as required by the extension implementation.
        pub const request_extension = struct {
            pub const name = "request-extension";

            pub fn connect(p_instance: anytype, comptime P_Data: type, p_callback: *const fn (@TypeOf(p_instance), p_ext_id: c_uint, p_ext_uri: [*:0]u8, P_Data) callconv(.c) ?*gstrtp.RTPHeaderExtension, p_data: P_Data, p_options: gobject.ext.ConnectSignalOptions(P_Data)) c_ulong {
                return gobject.signalConnectClosureById(
                    @ptrCast(@alignCast(gobject.ext.as(RTPBasePayload, p_instance))),
                    gobject.signalLookup("request-extension", RTPBasePayload.getGObjectType()),
                    glib.quarkFromString(p_options.detail orelse null),
                    gobject.CClosure.new(@ptrCast(p_callback), p_data, @ptrCast(p_options.destroyData)),
                    @intFromBool(p_options.after),
                );
            }
        };
    };

    /// Allocate a new `gst.Buffer` with enough data to hold an RTP packet with
    /// minimum `csrc_count` CSRCs, a payload length of `payload_len` and padding of
    /// `pad_len`. If `payload` has `gstrtp.RTPBasePayload.properties.source`-info `TRUE` additional
    /// CSRCs may be allocated and filled with RTP source information.
    extern fn gst_rtp_base_payload_allocate_output_buffer(p_payload: *RTPBasePayload, p_payload_len: c_uint, p_pad_len: u8, p_csrc_count: u8) *gst.Buffer;
    pub const allocateOutputBuffer = gst_rtp_base_payload_allocate_output_buffer;

    /// Count the total number of RTP sources found in the meta of `buffer`, which
    /// will be automically added by `gstrtp.RTPBasePayload.allocateOutputBuffer`.
    /// If `gstrtp.RTPBasePayload.properties.source`-info is `FALSE` the count will be 0.
    extern fn gst_rtp_base_payload_get_source_count(p_payload: *RTPBasePayload, p_buffer: *gst.Buffer) c_uint;
    pub const getSourceCount = gst_rtp_base_payload_get_source_count;

    /// Check if the packet with `size` and `duration` would exceed the configured
    /// maximum size.
    extern fn gst_rtp_base_payload_is_filled(p_payload: *RTPBasePayload, p_size: c_uint, p_duration: gst.ClockTime) c_int;
    pub const isFilled = gst_rtp_base_payload_is_filled;

    /// Queries whether the payloader will add contributing sources (CSRCs) to the
    /// RTP header from `gstrtp.RTPSourceMeta`.
    extern fn gst_rtp_base_payload_is_source_info_enabled(p_payload: *RTPBasePayload) c_int;
    pub const isSourceInfoEnabled = gst_rtp_base_payload_is_source_info_enabled;

    /// Push `buffer` to the peer element of the payloader. The SSRC, payload type,
    /// seqnum and timestamp of the RTP buffer will be updated first.
    ///
    /// This function takes ownership of `buffer`.
    extern fn gst_rtp_base_payload_push(p_payload: *RTPBasePayload, p_buffer: *gst.Buffer) gst.FlowReturn;
    pub const push = gst_rtp_base_payload_push;

    /// Push `list` to the peer element of the payloader. The SSRC, payload type,
    /// seqnum and timestamp of the RTP buffer will be updated first.
    ///
    /// This function takes ownership of `list`.
    extern fn gst_rtp_base_payload_push_list(p_payload: *RTPBasePayload, p_list: *gst.BufferList) gst.FlowReturn;
    pub const pushList = gst_rtp_base_payload_push_list;

    /// Set the rtp options of the payloader. These options will be set in the caps
    /// of the payloader. Subclasses must call this method before calling
    /// `gstrtp.RTPBasePayload.push` or `gstrtp.RTPBasePayload.setOutcaps`.
    extern fn gst_rtp_base_payload_set_options(p_payload: *RTPBasePayload, p_media: [*:0]const u8, p_dynamic: c_int, p_encoding_name: [*:0]const u8, p_clock_rate: u32) void;
    pub const setOptions = gst_rtp_base_payload_set_options;

    /// Configure the output caps with the optional parameters.
    ///
    /// Variable arguments should be in the form field name, field type
    /// (as a GType), value(s).  The last variable argument should be NULL.
    extern fn gst_rtp_base_payload_set_outcaps(p_payload: *RTPBasePayload, p_fieldname: [*:0]const u8, ...) c_int;
    pub const setOutcaps = gst_rtp_base_payload_set_outcaps;

    /// Configure the output caps with the optional fields.
    extern fn gst_rtp_base_payload_set_outcaps_structure(p_payload: *RTPBasePayload, p_s: ?*gst.Structure) c_int;
    pub const setOutcapsStructure = gst_rtp_base_payload_set_outcaps_structure;

    /// Enable or disable adding contributing sources to RTP packets from
    /// `gstrtp.RTPSourceMeta`.
    extern fn gst_rtp_base_payload_set_source_info_enabled(p_payload: *RTPBasePayload, p_enable: c_int) void;
    pub const setSourceInfoEnabled = gst_rtp_base_payload_set_source_info_enabled;

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

    extern fn g_object_ref(p_self: *gstrtp.RTPBasePayload) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstrtp.RTPBasePayload) void;
    pub const unref = g_object_unref;

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

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

/// Instance struct for a RTP Audio/Video header extension.
pub const RTPHeaderExtension = extern struct {
    pub const Parent = gst.Element;
    pub const Implements = [_]type{};
    pub const Class = gstrtp.RTPHeaderExtensionClass;
    /// the parent `gobject.Object`
    f_parent: gst.Element,
    f__gst_reserved: [4]*anyopaque,

    pub const virtual_methods = struct {
        /// This is used to know how much data a certain header extension will need for
        /// both allocating the resulting data, and deciding how much payload data can
        /// be generated.
        ///
        /// Implementations should return as accurate a value as is possible using the
        /// information given in the input `buffer`.
        pub const get_max_size = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_input_meta: *const gst.Buffer) usize {
                return gobject.ext.as(RTPHeaderExtension.Class, p_class).f_get_max_size.?(gobject.ext.as(RTPHeaderExtension, p_ext), p_input_meta);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_input_meta: *const gst.Buffer) callconv(.c) usize) void {
                gobject.ext.as(RTPHeaderExtension.Class, p_class).f_get_max_size = @ptrCast(p_implementation);
            }
        };

        /// retrieve the supported flags
        pub const get_supported_flags = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) gstrtp.RTPHeaderExtensionFlags {
                return gobject.ext.as(RTPHeaderExtension.Class, p_class).f_get_supported_flags.?(gobject.ext.as(RTPHeaderExtension, p_ext));
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance) callconv(.c) gstrtp.RTPHeaderExtensionFlags) void {
                gobject.ext.as(RTPHeaderExtension.Class, p_class).f_get_supported_flags = @ptrCast(p_implementation);
            }
        };

        /// Read the RTP header extension from `data`.
        pub const read = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_read_flags: gstrtp.RTPHeaderExtensionFlags, p_data: [*]const u8, p_size: usize, p_buffer: *gst.Buffer) c_int {
                return gobject.ext.as(RTPHeaderExtension.Class, p_class).f_read.?(gobject.ext.as(RTPHeaderExtension, p_ext), p_read_flags, p_data, p_size, p_buffer);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_read_flags: gstrtp.RTPHeaderExtensionFlags, p_data: [*]const u8, p_size: usize, p_buffer: *gst.Buffer) callconv(.c) c_int) void {
                gobject.ext.as(RTPHeaderExtension.Class, p_class).f_read = @ptrCast(p_implementation);
            }
        };

        /// set the necessary attributes that may be signaled e.g. with
        ///     an SDP.
        pub const set_attributes = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_direction: gstrtp.RTPHeaderExtensionDirection, p_attributes: [*:0]const u8) c_int {
                return gobject.ext.as(RTPHeaderExtension.Class, p_class).f_set_attributes.?(gobject.ext.as(RTPHeaderExtension, p_ext), p_direction, p_attributes);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_direction: gstrtp.RTPHeaderExtensionDirection, p_attributes: [*:0]const u8) callconv(.c) c_int) void {
                gobject.ext.as(RTPHeaderExtension.Class, p_class).f_set_attributes = @ptrCast(p_implementation);
            }
        };

        /// `gstrtp.RTPHeaderExtension.setId` must have been called with a valid
        /// extension id that is contained in these caps.
        ///
        /// The only current known caps format is based on the SDP standard as produced
        /// by `gst_sdp_media_attributes_to_caps`.
        pub const set_caps_from_attributes = 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(RTPHeaderExtension.Class, p_class).f_set_caps_from_attributes.?(gobject.ext.as(RTPHeaderExtension, 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(RTPHeaderExtension.Class, p_class).f_set_caps_from_attributes = @ptrCast(p_implementation);
            }
        };

        /// Passes RTP payloader's sink (i.e. not payloaded) `caps` to the header
        /// extension.
        pub const set_non_rtp_sink_caps = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_caps: *const gst.Caps) c_int {
                return gobject.ext.as(RTPHeaderExtension.Class, p_class).f_set_non_rtp_sink_caps.?(gobject.ext.as(RTPHeaderExtension, 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: *const gst.Caps) callconv(.c) c_int) void {
                gobject.ext.as(RTPHeaderExtension.Class, p_class).f_set_non_rtp_sink_caps = @ptrCast(p_implementation);
            }
        };

        /// Updates depayloader src caps based on the information received in RTP header.
        /// `caps` must be writable as this function may modify them.
        pub const update_non_rtp_src_caps = 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(RTPHeaderExtension.Class, p_class).f_update_non_rtp_src_caps.?(gobject.ext.as(RTPHeaderExtension, 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(RTPHeaderExtension.Class, p_class).f_update_non_rtp_src_caps = @ptrCast(p_implementation);
            }
        };

        /// Writes the RTP header extension to `data` using information available from
        /// the `input_meta`.  `data` will be sized to be at least the value returned
        /// from `gstrtp.RTPHeaderExtension.getMaxSize`.
        pub const write = struct {
            pub fn call(p_class: anytype, p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_input_meta: *const gst.Buffer, p_write_flags: gstrtp.RTPHeaderExtensionFlags, p_output: *gst.Buffer, p_data: [*]u8, p_size: usize) isize {
                return gobject.ext.as(RTPHeaderExtension.Class, p_class).f_write.?(gobject.ext.as(RTPHeaderExtension, p_ext), p_input_meta, p_write_flags, p_output, p_data, p_size);
            }

            pub fn implement(p_class: anytype, p_implementation: *const fn (p_ext: *@typeInfo(@TypeOf(p_class)).pointer.child.Instance, p_input_meta: *const gst.Buffer, p_write_flags: gstrtp.RTPHeaderExtensionFlags, p_output: *gst.Buffer, p_data: [*]u8, p_size: usize) callconv(.c) isize) void {
                gobject.ext.as(RTPHeaderExtension.Class, p_class).f_write = @ptrCast(p_implementation);
            }
        };
    };

    pub const properties = struct {};

    pub const signals = struct {};

    extern fn gst_rtp_header_extension_create_from_uri(p_uri: [*:0]const u8) ?*gstrtp.RTPHeaderExtension;
    pub const createFromUri = gst_rtp_header_extension_create_from_uri;

    /// Retrieve the direction
    extern fn gst_rtp_header_extension_get_direction(p_ext: *RTPHeaderExtension) gstrtp.RTPHeaderExtensionDirection;
    pub const getDirection = gst_rtp_header_extension_get_direction;

    extern fn gst_rtp_header_extension_get_id(p_ext: *RTPHeaderExtension) c_uint;
    pub const getId = gst_rtp_header_extension_get_id;

    /// This is used to know how much data a certain header extension will need for
    /// both allocating the resulting data, and deciding how much payload data can
    /// be generated.
    ///
    /// Implementations should return as accurate a value as is possible using the
    /// information given in the input `buffer`.
    extern fn gst_rtp_header_extension_get_max_size(p_ext: *RTPHeaderExtension, p_input_meta: *const gst.Buffer) usize;
    pub const getMaxSize = gst_rtp_header_extension_get_max_size;

    extern fn gst_rtp_header_extension_get_sdp_caps_field_name(p_ext: *RTPHeaderExtension) [*:0]u8;
    pub const getSdpCapsFieldName = gst_rtp_header_extension_get_sdp_caps_field_name;

    extern fn gst_rtp_header_extension_get_supported_flags(p_ext: *RTPHeaderExtension) gstrtp.RTPHeaderExtensionFlags;
    pub const getSupportedFlags = gst_rtp_header_extension_get_supported_flags;

    extern fn gst_rtp_header_extension_get_uri(p_ext: *RTPHeaderExtension) ?[*:0]const u8;
    pub const getUri = gst_rtp_header_extension_get_uri;

    /// Read the RTP header extension from `data`.
    extern fn gst_rtp_header_extension_read(p_ext: *RTPHeaderExtension, p_read_flags: gstrtp.RTPHeaderExtensionFlags, p_data: [*]const u8, p_size: usize, p_buffer: *gst.Buffer) c_int;
    pub const read = gst_rtp_header_extension_read;

    /// `gstrtp.RTPHeaderExtension.setId` must have been called with a valid
    /// extension id that is contained in these caps.
    ///
    /// The only current known caps format is based on the SDP standard as produced
    /// by `gst_sdp_media_attributes_to_caps`.
    extern fn gst_rtp_header_extension_set_attributes_from_caps(p_ext: *RTPHeaderExtension, p_caps: *const gst.Caps) c_int;
    pub const setAttributesFromCaps = gst_rtp_header_extension_set_attributes_from_caps;

    /// `gstrtp.RTPHeaderExtension.setId` must have been called with a valid
    /// extension id that is contained in these caps.
    ///
    /// The only current known caps format is based on the SDP standard as produced
    /// by `gst_sdp_media_attributes_to_caps`.
    extern fn gst_rtp_header_extension_set_caps_from_attributes(p_ext: *RTPHeaderExtension, p_caps: *gst.Caps) c_int;
    pub const setCapsFromAttributes = gst_rtp_header_extension_set_caps_from_attributes;

    /// Helper implementation for GstRTPExtensionClass::set_caps_from_attributes
    /// that sets the `ext` uri on caps with the specified extension id as required
    /// for sdp `gst.Caps`.
    ///
    /// Requires that the extension does not have any attributes or direction
    /// advertised in `caps`.
    extern fn gst_rtp_header_extension_set_caps_from_attributes_helper(p_ext: *RTPHeaderExtension, p_caps: *gst.Caps, p_attributes: [*:0]const u8) c_int;
    pub const setCapsFromAttributesHelper = gst_rtp_header_extension_set_caps_from_attributes_helper;

    /// Set the direction that this header extension should be used in.
    /// If `GST_RTP_HEADER_EXTENSION_DIRECTION_INHERITED` is included, the
    /// direction will not be included in the caps (as it shouldn't be in the
    /// extmap line in the SDP).
    extern fn gst_rtp_header_extension_set_direction(p_ext: *RTPHeaderExtension, p_direction: gstrtp.RTPHeaderExtensionDirection) void;
    pub const setDirection = gst_rtp_header_extension_set_direction;

    /// sets the RTP extension id on `ext`
    extern fn gst_rtp_header_extension_set_id(p_ext: *RTPHeaderExtension, p_ext_id: c_uint) void;
    pub const setId = gst_rtp_header_extension_set_id;

    /// Passes RTP payloader's sink (i.e. not payloaded) `caps` to the header
    /// extension.
    extern fn gst_rtp_header_extension_set_non_rtp_sink_caps(p_ext: *RTPHeaderExtension, p_caps: *const gst.Caps) c_int;
    pub const setNonRtpSinkCaps = gst_rtp_header_extension_set_non_rtp_sink_caps;

    /// Call this function in a subclass from `gstrtp.RTPHeaderExtensionClass.signals.read` to
    /// tell the depayloader whether the data just parsed from RTP packet require
    /// updating its src (non-RTP) caps. If `state` is TRUE, `gstrtp.RTPBaseDepayload` will
    /// eventually invoke `gstrtp.RTPHeaderExtension.updateNonRtpSrcCaps` to
    /// have the caps update applied. Applying the update also flips the internal
    /// "wants update" flag back to FALSE.
    extern fn gst_rtp_header_extension_set_wants_update_non_rtp_src_caps(p_ext: *RTPHeaderExtension, p_state: c_int) void;
    pub const setWantsUpdateNonRtpSrcCaps = gst_rtp_header_extension_set_wants_update_non_rtp_src_caps;

    /// Updates depayloader src caps based on the information received in RTP header.
    /// `caps` must be writable as this function may modify them.
    extern fn gst_rtp_header_extension_update_non_rtp_src_caps(p_ext: *RTPHeaderExtension, p_caps: *gst.Caps) c_int;
    pub const updateNonRtpSrcCaps = gst_rtp_header_extension_update_non_rtp_src_caps;

    /// Call this function after `gstrtp.RTPHeaderExtension.read` to check if
    /// the depayloader's src caps need updating with data received in the last RTP
    /// packet.
    extern fn gst_rtp_header_extension_wants_update_non_rtp_src_caps(p_ext: *RTPHeaderExtension) c_int;
    pub const wantsUpdateNonRtpSrcCaps = gst_rtp_header_extension_wants_update_non_rtp_src_caps;

    /// Writes the RTP header extension to `data` using information available from
    /// the `input_meta`.  `data` will be sized to be at least the value returned
    /// from `gstrtp.RTPHeaderExtension.getMaxSize`.
    extern fn gst_rtp_header_extension_write(p_ext: *RTPHeaderExtension, p_input_meta: *const gst.Buffer, p_write_flags: gstrtp.RTPHeaderExtensionFlags, p_output: *gst.Buffer, p_data: [*]u8, p_size: usize) isize;
    pub const write = gst_rtp_header_extension_write;

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

    extern fn g_object_ref(p_self: *gstrtp.RTPHeaderExtension) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gstrtp.RTPHeaderExtension) void;
    pub const unref = g_object_unref;

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

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

/// Note: The API in this module is not yet declared stable.
///
/// The GstRTPCBuffer helper functions makes it easy to parse and create regular
/// `gst.Buffer` objects that contain compound RTCP packets. These buffers are typically
/// of 'application/x-rtcp' `gst.Caps`.
///
/// An RTCP buffer consists of 1 or more `gstrtp.RTCPPacket` structures that you can
/// retrieve with `gstrtp.RTCPBuffer.getFirstPacket`. `gstrtp.RTCPPacket` acts as a pointer
/// into the RTCP buffer; you can move to the next packet with
/// `gstrtp.RTCPPacket.moveToNext`.
pub const RTCPBuffer = extern struct {
    f_buffer: ?*gst.Buffer,
    f_map: gst.MapInfo,

    /// Open `buffer` for reading or writing, depending on `flags`. The resulting RTCP
    /// buffer state is stored in `rtcp`.
    extern fn gst_rtcp_buffer_map(p_buffer: *gst.Buffer, p_flags: gst.MapFlags, p_rtcp: *gstrtp.RTCPBuffer) c_int;
    pub const map = gst_rtcp_buffer_map;

    /// Create a new buffer for constructing RTCP packets. The packet will have a
    /// maximum size of `mtu`.
    extern fn gst_rtcp_buffer_new(p_mtu: c_uint) *gst.Buffer;
    pub const new = gst_rtcp_buffer_new;

    /// Create a new buffer and set the data to a copy of `len`
    /// bytes of `data` and the size to `len`. The data will be freed when the buffer
    /// is freed.
    extern fn gst_rtcp_buffer_new_copy_data(p_data: [*]const u8, p_len: c_uint) *gst.Buffer;
    pub const newCopyData = gst_rtcp_buffer_new_copy_data;

    /// Create a new buffer and set the data and size of the buffer to `data` and `len`
    /// respectively. `data` will be freed when the buffer is unreffed, so this
    /// function transfers ownership of `data` to the new buffer.
    extern fn gst_rtcp_buffer_new_take_data(p_data: [*]u8, p_len: c_uint) *gst.Buffer;
    pub const newTakeData = gst_rtcp_buffer_new_take_data;

    /// Check if the data pointed to by `buffer` is a valid RTCP packet using
    /// `gstrtp.rtcpBufferValidateData`.
    extern fn gst_rtcp_buffer_validate(p_buffer: *gst.Buffer) c_int;
    pub const validate = gst_rtcp_buffer_validate;

    /// Check if the `data` and `size` point to the data of a valid compound,
    /// non-reduced size RTCP packet.
    /// Use this function to validate a packet before using the other functions in
    /// this module.
    extern fn gst_rtcp_buffer_validate_data(p_data: [*]u8, p_len: c_uint) c_int;
    pub const validateData = gst_rtcp_buffer_validate_data;

    /// Check if the `data` and `size` point to the data of a valid RTCP packet.
    /// Use this function to validate a packet before using the other functions in
    /// this module.
    ///
    /// This function is updated to support reduced size rtcp packets according to
    /// RFC 5506 and will validate full compound RTCP packets as well as reduced
    /// size RTCP packets.
    extern fn gst_rtcp_buffer_validate_data_reduced(p_data: [*]u8, p_len: c_uint) c_int;
    pub const validateDataReduced = gst_rtcp_buffer_validate_data_reduced;

    /// Check if the data pointed to by `buffer` is a valid RTCP packet using
    /// `gstrtp.rtcpBufferValidateReduced`.
    extern fn gst_rtcp_buffer_validate_reduced(p_buffer: *gst.Buffer) c_int;
    pub const validateReduced = gst_rtcp_buffer_validate_reduced;

    /// Add a new packet of `type` to `rtcp`. `packet` will point to the newly created
    /// packet.
    extern fn gst_rtcp_buffer_add_packet(p_rtcp: *RTCPBuffer, p_type: gstrtp.RTCPType, p_packet: *gstrtp.RTCPPacket) c_int;
    pub const addPacket = gst_rtcp_buffer_add_packet;

    /// Initialize a new `gstrtp.RTCPPacket` pointer that points to the first packet in
    /// `rtcp`.
    extern fn gst_rtcp_buffer_get_first_packet(p_rtcp: *RTCPBuffer, p_packet: *gstrtp.RTCPPacket) c_int;
    pub const getFirstPacket = gst_rtcp_buffer_get_first_packet;

    /// Get the number of RTCP packets in `rtcp`.
    extern fn gst_rtcp_buffer_get_packet_count(p_rtcp: *RTCPBuffer) c_uint;
    pub const getPacketCount = gst_rtcp_buffer_get_packet_count;

    /// Finish `rtcp` after being constructed. This function is usually called
    /// after `gstrtp.rtcpBufferMap` and after adding the RTCP items to the new buffer.
    ///
    /// The function adjusts the size of `rtcp` with the total length of all the
    /// added packets.
    extern fn gst_rtcp_buffer_unmap(p_rtcp: *RTCPBuffer) c_int;
    pub const unmap = gst_rtcp_buffer_unmap;

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

/// Data structure that points to a packet at `offset` in `buffer`.
/// The size of the structure is made public to allow stack allocations.
pub const RTCPPacket = extern struct {
    /// pointer to RTCP buffer
    f_rtcp: ?*gstrtp.RTCPBuffer,
    /// offset of packet in buffer data
    f_offset: c_uint,
    f_padding: c_int,
    f_count: u8,
    f_type: gstrtp.RTCPType,
    f_length: u16,
    f_item_offset: c_uint,
    f_item_count: c_uint,
    f_entry_offset: c_uint,

    /// Add profile-specific extension `data` to `packet`. If `packet` already
    /// contains profile-specific extension `data` will be appended to the existing
    /// extension.
    extern fn gst_rtcp_packet_add_profile_specific_ext(p_packet: *RTCPPacket, p_data: [*]const u8, p_len: c_uint) c_int;
    pub const addProfileSpecificExt = gst_rtcp_packet_add_profile_specific_ext;

    /// Add a new report block to `packet` with the given values.
    extern fn gst_rtcp_packet_add_rb(p_packet: *RTCPPacket, p_ssrc: u32, p_fractionlost: u8, p_packetslost: i32, p_exthighestseq: u32, p_jitter: u32, p_lsr: u32, p_dlsr: u32) c_int;
    pub const addRb = gst_rtcp_packet_add_rb;

    /// Get the application-dependent data attached to a RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_app_get_data(p_packet: *RTCPPacket) *u8;
    pub const appGetData = gst_rtcp_packet_app_get_data;

    /// Get the length of the application-dependent data attached to an APP
    /// `packet`.
    extern fn gst_rtcp_packet_app_get_data_length(p_packet: *RTCPPacket) u16;
    pub const appGetDataLength = gst_rtcp_packet_app_get_data_length;

    /// Get the name field of the APP `packet`.
    extern fn gst_rtcp_packet_app_get_name(p_packet: *RTCPPacket) [*:0]const u8;
    pub const appGetName = gst_rtcp_packet_app_get_name;

    /// Get the SSRC/CSRC field of the APP `packet`.
    extern fn gst_rtcp_packet_app_get_ssrc(p_packet: *RTCPPacket) u32;
    pub const appGetSsrc = gst_rtcp_packet_app_get_ssrc;

    /// Get the subtype field of the APP `packet`.
    extern fn gst_rtcp_packet_app_get_subtype(p_packet: *RTCPPacket) u8;
    pub const appGetSubtype = gst_rtcp_packet_app_get_subtype;

    /// Set the length of the application-dependent data attached to an APP
    /// `packet`.
    extern fn gst_rtcp_packet_app_set_data_length(p_packet: *RTCPPacket, p_wordlen: u16) c_int;
    pub const appSetDataLength = gst_rtcp_packet_app_set_data_length;

    /// Set the name field of the APP `packet`.
    extern fn gst_rtcp_packet_app_set_name(p_packet: *RTCPPacket, p_name: [*:0]const u8) void;
    pub const appSetName = gst_rtcp_packet_app_set_name;

    /// Set the SSRC/CSRC field of the APP `packet`.
    extern fn gst_rtcp_packet_app_set_ssrc(p_packet: *RTCPPacket, p_ssrc: u32) void;
    pub const appSetSsrc = gst_rtcp_packet_app_set_ssrc;

    /// Set the subtype field of the APP `packet`.
    extern fn gst_rtcp_packet_app_set_subtype(p_packet: *RTCPPacket, p_subtype: u8) void;
    pub const appSetSubtype = gst_rtcp_packet_app_set_subtype;

    /// Add `ssrc` to the BYE `packet`.
    extern fn gst_rtcp_packet_bye_add_ssrc(p_packet: *RTCPPacket, p_ssrc: u32) c_int;
    pub const byeAddSsrc = gst_rtcp_packet_bye_add_ssrc;

    /// Adds `len` SSRCs in `ssrc` to BYE `packet`.
    extern fn gst_rtcp_packet_bye_add_ssrcs(p_packet: *RTCPPacket, p_ssrc: [*]u32, p_len: c_uint) c_int;
    pub const byeAddSsrcs = gst_rtcp_packet_bye_add_ssrcs;

    /// Get the `nth` SSRC of the BYE `packet`.
    extern fn gst_rtcp_packet_bye_get_nth_ssrc(p_packet: *RTCPPacket, p_nth: c_uint) u32;
    pub const byeGetNthSsrc = gst_rtcp_packet_bye_get_nth_ssrc;

    /// Get the reason in `packet`.
    extern fn gst_rtcp_packet_bye_get_reason(p_packet: *RTCPPacket) ?[*:0]u8;
    pub const byeGetReason = gst_rtcp_packet_bye_get_reason;

    /// Get the length of the reason string.
    extern fn gst_rtcp_packet_bye_get_reason_len(p_packet: *RTCPPacket) u8;
    pub const byeGetReasonLen = gst_rtcp_packet_bye_get_reason_len;

    /// Get the number of SSRC fields in `packet`.
    extern fn gst_rtcp_packet_bye_get_ssrc_count(p_packet: *RTCPPacket) c_uint;
    pub const byeGetSsrcCount = gst_rtcp_packet_bye_get_ssrc_count;

    /// Set the reason string to `reason` in `packet`.
    extern fn gst_rtcp_packet_bye_set_reason(p_packet: *RTCPPacket, p_reason: [*:0]const u8) c_int;
    pub const byeSetReason = gst_rtcp_packet_bye_set_reason;

    /// The profile-specific extension data is copied into a new allocated
    /// memory area `data`. This must be freed with `glib.free` after usage.
    extern fn gst_rtcp_packet_copy_profile_specific_ext(p_packet: *RTCPPacket, p_data: *[*]u8, p_len: *c_uint) c_int;
    pub const copyProfileSpecificExt = gst_rtcp_packet_copy_profile_specific_ext;

    /// Get the Feedback Control Information attached to a RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_fb_get_fci(p_packet: *RTCPPacket) *u8;
    pub const fbGetFci = gst_rtcp_packet_fb_get_fci;

    /// Get the length of the Feedback Control Information attached to a
    /// RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_fb_get_fci_length(p_packet: *RTCPPacket) u16;
    pub const fbGetFciLength = gst_rtcp_packet_fb_get_fci_length;

    /// Get the media SSRC field of the RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_fb_get_media_ssrc(p_packet: *RTCPPacket) u32;
    pub const fbGetMediaSsrc = gst_rtcp_packet_fb_get_media_ssrc;

    /// Get the sender SSRC field of the RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_fb_get_sender_ssrc(p_packet: *RTCPPacket) u32;
    pub const fbGetSenderSsrc = gst_rtcp_packet_fb_get_sender_ssrc;

    /// Get the feedback message type of the FB `packet`.
    extern fn gst_rtcp_packet_fb_get_type(p_packet: *RTCPPacket) gstrtp.RTCPFBType;
    pub const fbGetType = gst_rtcp_packet_fb_get_type;

    /// Set the length of the Feedback Control Information attached to a
    /// RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_fb_set_fci_length(p_packet: *RTCPPacket, p_wordlen: u16) c_int;
    pub const fbSetFciLength = gst_rtcp_packet_fb_set_fci_length;

    /// Set the media SSRC field of the RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_fb_set_media_ssrc(p_packet: *RTCPPacket, p_ssrc: u32) void;
    pub const fbSetMediaSsrc = gst_rtcp_packet_fb_set_media_ssrc;

    /// Set the sender SSRC field of the RTPFB or PSFB `packet`.
    extern fn gst_rtcp_packet_fb_set_sender_ssrc(p_packet: *RTCPPacket, p_ssrc: u32) void;
    pub const fbSetSenderSsrc = gst_rtcp_packet_fb_set_sender_ssrc;

    /// Set the feedback message type of the FB `packet`.
    extern fn gst_rtcp_packet_fb_set_type(p_packet: *RTCPPacket, p_type: gstrtp.RTCPFBType) void;
    pub const fbSetType = gst_rtcp_packet_fb_set_type;

    /// Get the count field in `packet`.
    extern fn gst_rtcp_packet_get_count(p_packet: *RTCPPacket) u8;
    pub const getCount = gst_rtcp_packet_get_count;

    /// Get the length field of `packet`. This is the length of the packet in
    /// 32-bit words minus one.
    extern fn gst_rtcp_packet_get_length(p_packet: *RTCPPacket) u16;
    pub const getLength = gst_rtcp_packet_get_length;

    /// Get the packet padding of the packet pointed to by `packet`.
    extern fn gst_rtcp_packet_get_padding(p_packet: *RTCPPacket) c_int;
    pub const getPadding = gst_rtcp_packet_get_padding;

    extern fn gst_rtcp_packet_get_profile_specific_ext(p_packet: *RTCPPacket, p_data: *[*]u8, p_len: *c_uint) c_int;
    pub const getProfileSpecificExt = gst_rtcp_packet_get_profile_specific_ext;

    extern fn gst_rtcp_packet_get_profile_specific_ext_length(p_packet: *RTCPPacket) u16;
    pub const getProfileSpecificExtLength = gst_rtcp_packet_get_profile_specific_ext_length;

    /// Parse the values of the `nth` report block in `packet` and store the result in
    /// the values.
    extern fn gst_rtcp_packet_get_rb(p_packet: *RTCPPacket, p_nth: c_uint, p_ssrc: *u32, p_fractionlost: *u8, p_packetslost: *i32, p_exthighestseq: *u32, p_jitter: *u32, p_lsr: *u32, p_dlsr: *u32) void;
    pub const getRb = gst_rtcp_packet_get_rb;

    /// Get the number of report blocks in `packet`.
    extern fn gst_rtcp_packet_get_rb_count(p_packet: *RTCPPacket) c_uint;
    pub const getRbCount = gst_rtcp_packet_get_rb_count;

    /// Get the packet type of the packet pointed to by `packet`.
    extern fn gst_rtcp_packet_get_type(p_packet: *RTCPPacket) gstrtp.RTCPType;
    pub const getType = gst_rtcp_packet_get_type;

    /// Move the packet pointer `packet` to the next packet in the payload.
    /// Use `gstrtp.RTCPBuffer.getFirstPacket` to initialize `packet`.
    extern fn gst_rtcp_packet_move_to_next(p_packet: *RTCPPacket) c_int;
    pub const moveToNext = gst_rtcp_packet_move_to_next;

    /// Removes the packet pointed to by `packet` and moves pointer to the next one
    extern fn gst_rtcp_packet_remove(p_packet: *RTCPPacket) c_int;
    pub const remove = gst_rtcp_packet_remove;

    /// Get the ssrc field of the RR `packet`.
    extern fn gst_rtcp_packet_rr_get_ssrc(p_packet: *RTCPPacket) u32;
    pub const rrGetSsrc = gst_rtcp_packet_rr_get_ssrc;

    /// Set the ssrc field of the RR `packet`.
    extern fn gst_rtcp_packet_rr_set_ssrc(p_packet: *RTCPPacket, p_ssrc: u32) void;
    pub const rrSetSsrc = gst_rtcp_packet_rr_set_ssrc;

    /// Add a new SDES entry to the current item in `packet`.
    extern fn gst_rtcp_packet_sdes_add_entry(p_packet: *RTCPPacket, p_type: gstrtp.RTCPSDESType, p_len: u8, p_data: [*]const u8) c_int;
    pub const sdesAddEntry = gst_rtcp_packet_sdes_add_entry;

    /// Add a new SDES item for `ssrc` to `packet`.
    extern fn gst_rtcp_packet_sdes_add_item(p_packet: *RTCPPacket, p_ssrc: u32) c_int;
    pub const sdesAddItem = gst_rtcp_packet_sdes_add_item;

    /// This function is like `gstrtp.RTCPPacket.sdesGetEntry` but it returns a
    /// null-terminated copy of the data instead. use `glib.free` after usage.
    extern fn gst_rtcp_packet_sdes_copy_entry(p_packet: *RTCPPacket, p_type: *gstrtp.RTCPSDESType, p_len: *u8, p_data: *[*]u8) c_int;
    pub const sdesCopyEntry = gst_rtcp_packet_sdes_copy_entry;

    /// Move to the first SDES entry in the current item.
    extern fn gst_rtcp_packet_sdes_first_entry(p_packet: *RTCPPacket) c_int;
    pub const sdesFirstEntry = gst_rtcp_packet_sdes_first_entry;

    /// Move to the first SDES item in `packet`.
    extern fn gst_rtcp_packet_sdes_first_item(p_packet: *RTCPPacket) c_int;
    pub const sdesFirstItem = gst_rtcp_packet_sdes_first_item;

    /// Get the data of the current SDES item entry. `type` (when not NULL) will
    /// contain the type of the entry. `data` (when not NULL) will point to `len`
    /// bytes.
    ///
    /// When `type` refers to a text item, `data` will point to a UTF8 string. Note
    /// that this UTF8 string is NOT null-terminated. Use
    /// `gstrtp.RTCPPacket.sdesCopyEntry` to get a null-terminated copy of the entry.
    extern fn gst_rtcp_packet_sdes_get_entry(p_packet: *RTCPPacket, p_type: *gstrtp.RTCPSDESType, p_len: *u8, p_data: *[*]u8) c_int;
    pub const sdesGetEntry = gst_rtcp_packet_sdes_get_entry;

    /// Get the number of items in the SDES packet `packet`.
    extern fn gst_rtcp_packet_sdes_get_item_count(p_packet: *RTCPPacket) c_uint;
    pub const sdesGetItemCount = gst_rtcp_packet_sdes_get_item_count;

    /// Get the SSRC of the current SDES item.
    extern fn gst_rtcp_packet_sdes_get_ssrc(p_packet: *RTCPPacket) u32;
    pub const sdesGetSsrc = gst_rtcp_packet_sdes_get_ssrc;

    /// Move to the next SDES entry in the current item.
    extern fn gst_rtcp_packet_sdes_next_entry(p_packet: *RTCPPacket) c_int;
    pub const sdesNextEntry = gst_rtcp_packet_sdes_next_entry;

    /// Move to the next SDES item in `packet`.
    extern fn gst_rtcp_packet_sdes_next_item(p_packet: *RTCPPacket) c_int;
    pub const sdesNextItem = gst_rtcp_packet_sdes_next_item;

    /// Set the `nth` new report block in `packet` with the given values.
    ///
    /// Note: Not implemented.
    extern fn gst_rtcp_packet_set_rb(p_packet: *RTCPPacket, p_nth: c_uint, p_ssrc: u32, p_fractionlost: u8, p_packetslost: i32, p_exthighestseq: u32, p_jitter: u32, p_lsr: u32, p_dlsr: u32) void;
    pub const setRb = gst_rtcp_packet_set_rb;

    /// Parse the SR sender info and store the values.
    extern fn gst_rtcp_packet_sr_get_sender_info(p_packet: *RTCPPacket, p_ssrc: *u32, p_ntptime: *u64, p_rtptime: *u32, p_packet_count: *u32, p_octet_count: *u32) void;
    pub const srGetSenderInfo = gst_rtcp_packet_sr_get_sender_info;

    /// Set the given values in the SR packet `packet`.
    extern fn gst_rtcp_packet_sr_set_sender_info(p_packet: *RTCPPacket, p_ssrc: u32, p_ntptime: u64, p_rtptime: u32, p_packet_count: u32, p_octet_count: u32) void;
    pub const srSetSenderInfo = gst_rtcp_packet_sr_set_sender_info;

    /// Move to the first extended report block in XR `packet`.
    extern fn gst_rtcp_packet_xr_first_rb(p_packet: *RTCPPacket) c_int;
    pub const xrFirstRb = gst_rtcp_packet_xr_first_rb;

    extern fn gst_rtcp_packet_xr_get_block_length(p_packet: *RTCPPacket) u16;
    pub const xrGetBlockLength = gst_rtcp_packet_xr_get_block_length;

    /// Get the extended report block type of the XR `packet`.
    extern fn gst_rtcp_packet_xr_get_block_type(p_packet: *RTCPPacket) gstrtp.RTCPXRType;
    pub const xrGetBlockType = gst_rtcp_packet_xr_get_block_type;

    /// Parse the extended report block for DLRR report block type.
    extern fn gst_rtcp_packet_xr_get_dlrr_block(p_packet: *RTCPPacket, p_nth: c_uint, p_ssrc: *u32, p_last_rr: *u32, p_delay: *u32) c_int;
    pub const xrGetDlrrBlock = gst_rtcp_packet_xr_get_dlrr_block;

    /// Retrieve the packet receipt time of `seq` which ranges in [begin_seq, end_seq).
    extern fn gst_rtcp_packet_xr_get_prt_by_seq(p_packet: *RTCPPacket, p_seq: u16, p_receipt_time: *u32) c_int;
    pub const xrGetPrtBySeq = gst_rtcp_packet_xr_get_prt_by_seq;

    /// Parse the Packet Recept Times Report Block from a XR `packet`
    extern fn gst_rtcp_packet_xr_get_prt_info(p_packet: *RTCPPacket, p_ssrc: *u32, p_thinning: *u8, p_begin_seq: *u16, p_end_seq: *u16) c_int;
    pub const xrGetPrtInfo = gst_rtcp_packet_xr_get_prt_info;

    /// Parse the extended report block for Loss RLE and Duplicated LRE block type.
    extern fn gst_rtcp_packet_xr_get_rle_info(p_packet: *RTCPPacket, p_ssrc: *u32, p_thinning: *u8, p_begin_seq: *u16, p_end_seq: *u16, p_chunk_count: *u32) c_int;
    pub const xrGetRleInfo = gst_rtcp_packet_xr_get_rle_info;

    /// Retrieve actual chunk data.
    extern fn gst_rtcp_packet_xr_get_rle_nth_chunk(p_packet: *RTCPPacket, p_nth: c_uint, p_chunk: *u16) c_int;
    pub const xrGetRleNthChunk = gst_rtcp_packet_xr_get_rle_nth_chunk;

    extern fn gst_rtcp_packet_xr_get_rrt(p_packet: *RTCPPacket, p_timestamp: *u64) c_int;
    pub const xrGetRrt = gst_rtcp_packet_xr_get_rrt;

    /// Get the ssrc field of the XR `packet`.
    extern fn gst_rtcp_packet_xr_get_ssrc(p_packet: *RTCPPacket) u32;
    pub const xrGetSsrc = gst_rtcp_packet_xr_get_ssrc;

    /// Extract a basic information from static summary report block of XR `packet`.
    extern fn gst_rtcp_packet_xr_get_summary_info(p_packet: *RTCPPacket, p_ssrc: *u32, p_begin_seq: *u16, p_end_seq: *u16) c_int;
    pub const xrGetSummaryInfo = gst_rtcp_packet_xr_get_summary_info;

    /// Extract jitter information from the statistics summary. If the jitter flag in
    /// a block header is set as zero, all of jitters will be zero.
    extern fn gst_rtcp_packet_xr_get_summary_jitter(p_packet: *RTCPPacket, p_min_jitter: *u32, p_max_jitter: *u32, p_mean_jitter: *u32, p_dev_jitter: *u32) c_int;
    pub const xrGetSummaryJitter = gst_rtcp_packet_xr_get_summary_jitter;

    /// Get the number of lost or duplicate packets. If the flag in a block header
    /// is set as zero, `lost_packets` or `dup_packets` will be zero.
    extern fn gst_rtcp_packet_xr_get_summary_pkt(p_packet: *RTCPPacket, p_lost_packets: *u32, p_dup_packets: *u32) c_int;
    pub const xrGetSummaryPkt = gst_rtcp_packet_xr_get_summary_pkt;

    /// Extract the value of ttl for ipv4, or hop limit for ipv6.
    extern fn gst_rtcp_packet_xr_get_summary_ttl(p_packet: *RTCPPacket, p_is_ipv4: *c_int, p_min_ttl: *u8, p_max_ttl: *u8, p_mean_ttl: *u8, p_dev_ttl: *u8) c_int;
    pub const xrGetSummaryTtl = gst_rtcp_packet_xr_get_summary_ttl;

    extern fn gst_rtcp_packet_xr_get_voip_burst_metrics(p_packet: *RTCPPacket, p_burst_density: *u8, p_gap_density: *u8, p_burst_duration: *u16, p_gap_duration: *u16) c_int;
    pub const xrGetVoipBurstMetrics = gst_rtcp_packet_xr_get_voip_burst_metrics;

    extern fn gst_rtcp_packet_xr_get_voip_configuration_params(p_packet: *RTCPPacket, p_gmin: *u8, p_rx_config: *u8) c_int;
    pub const xrGetVoipConfigurationParams = gst_rtcp_packet_xr_get_voip_configuration_params;

    extern fn gst_rtcp_packet_xr_get_voip_delay_metrics(p_packet: *RTCPPacket, p_roundtrip_delay: *u16, p_end_system_delay: *u16) c_int;
    pub const xrGetVoipDelayMetrics = gst_rtcp_packet_xr_get_voip_delay_metrics;

    extern fn gst_rtcp_packet_xr_get_voip_jitter_buffer_params(p_packet: *RTCPPacket, p_jb_nominal: *u16, p_jb_maximum: *u16, p_jb_abs_max: *u16) c_int;
    pub const xrGetVoipJitterBufferParams = gst_rtcp_packet_xr_get_voip_jitter_buffer_params;

    extern fn gst_rtcp_packet_xr_get_voip_metrics_ssrc(p_packet: *RTCPPacket, p_ssrc: *u32) c_int;
    pub const xrGetVoipMetricsSsrc = gst_rtcp_packet_xr_get_voip_metrics_ssrc;

    extern fn gst_rtcp_packet_xr_get_voip_packet_metrics(p_packet: *RTCPPacket, p_loss_rate: *u8, p_discard_rate: *u8) c_int;
    pub const xrGetVoipPacketMetrics = gst_rtcp_packet_xr_get_voip_packet_metrics;

    extern fn gst_rtcp_packet_xr_get_voip_quality_metrics(p_packet: *RTCPPacket, p_r_factor: *u8, p_ext_r_factor: *u8, p_mos_lq: *u8, p_mos_cq: *u8) c_int;
    pub const xrGetVoipQualityMetrics = gst_rtcp_packet_xr_get_voip_quality_metrics;

    extern fn gst_rtcp_packet_xr_get_voip_signal_metrics(p_packet: *RTCPPacket, p_signal_level: *u8, p_noise_level: *u8, p_rerl: *u8, p_gmin: *u8) c_int;
    pub const xrGetVoipSignalMetrics = gst_rtcp_packet_xr_get_voip_signal_metrics;

    /// Move to the next extended report block in XR `packet`.
    extern fn gst_rtcp_packet_xr_next_rb(p_packet: *RTCPPacket) c_int;
    pub const xrNextRb = gst_rtcp_packet_xr_next_rb;

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

/// Base class for audio RTP payloader.
pub const RTPBaseAudioPayloadClass = extern struct {
    pub const Instance = gstrtp.RTPBaseAudioPayload;

    /// the parent class
    f_parent_class: gstrtp.RTPBasePayloadClass,
    f__gst_reserved: [4]*anyopaque,

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

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

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

/// Base class for RTP depayloaders.
pub const RTPBaseDepayloadClass = extern struct {
    pub const Instance = gstrtp.RTPBaseDepayload;

    /// the parent class
    f_parent_class: gst.ElementClass,
    /// configure the depayloader
    f_set_caps: ?*const fn (p_filter: *gstrtp.RTPBaseDepayload, p_caps: *gst.Caps) callconv(.c) c_int,
    /// process incoming rtp packets. Subclass must implement either
    ///   this method or `process_rtp_packet` to process incoming rtp packets.
    ///   If the child returns a buffer without a valid timestamp, the timestamp
    ///   of the provided buffer will be applied to the result buffer and the
    ///   buffer will be pushed. If this function returns `NULL`, nothing is pushed.
    f_process: ?*const fn (p_base: *gstrtp.RTPBaseDepayload, p_in: *gst.Buffer) callconv(.c) *gst.Buffer,
    /// signal the depayloader about packet loss
    f_packet_lost: ?*const fn (p_filter: *gstrtp.RTPBaseDepayload, p_event: *gst.Event) callconv(.c) c_int,
    /// custom event handling
    f_handle_event: ?*const fn (p_filter: *gstrtp.RTPBaseDepayload, p_event: *gst.Event) callconv(.c) c_int,
    /// Same as the process virtual function, but slightly more
    /// efficient, since it is passed the rtp buffer structure that has already
    /// been mapped (with GST_MAP_READ) by the base class and thus does not have
    /// to be mapped again by the subclass. Can be used by the subclass to process
    /// incoming rtp packets. If the subclass returns a buffer without a valid
    /// timestamp, the timestamp of the input buffer will be applied to the result
    /// buffer and the output buffer will be pushed out. If this function returns
    /// `NULL`, nothing is pushed out. Since: 1.6.
    f_process_rtp_packet: ?*const fn (p_base: *gstrtp.RTPBaseDepayload, p_rtp_buffer: *gstrtp.RTPBuffer) callconv(.c) *gst.Buffer,
    f__gst_reserved: [3]*anyopaque,

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

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

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

/// Base class for audio RTP payloader.
pub const RTPBasePayloadClass = extern struct {
    pub const Instance = gstrtp.RTPBasePayload;

    /// the parent class
    f_parent_class: gst.ElementClass,
    /// get desired caps
    f_get_caps: ?*const fn (p_payload: *gstrtp.RTPBasePayload, p_pad: *gst.Pad, p_filter: *gst.Caps) callconv(.c) *gst.Caps,
    /// configure the payloader
    f_set_caps: ?*const fn (p_payload: *gstrtp.RTPBasePayload, p_caps: *gst.Caps) callconv(.c) c_int,
    /// process data
    f_handle_buffer: ?*const fn (p_payload: *gstrtp.RTPBasePayload, p_buffer: *gst.Buffer) callconv(.c) gst.FlowReturn,
    /// custom event handling on the sinkpad
    f_sink_event: ?*const fn (p_payload: *gstrtp.RTPBasePayload, p_event: *gst.Event) callconv(.c) c_int,
    /// custom event handling on the srcpad
    f_src_event: ?*const fn (p_payload: *gstrtp.RTPBasePayload, p_event: *gst.Event) callconv(.c) c_int,
    /// custom query handling
    f_query: ?*const fn (p_payload: *gstrtp.RTPBasePayload, p_pad: *gst.Pad, p_query: *gst.Query) callconv(.c) c_int,
    f__gst_reserved: [4]*anyopaque,

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

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

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

/// The GstRTPBuffer helper functions makes it easy to parse and create regular
/// `gst.Buffer` objects that contain RTP payloads. These buffers are typically of
/// 'application/x-rtp' `gst.Caps`.
pub const RTPBuffer = extern struct {
    /// pointer to RTP buffer
    f_buffer: ?*gst.Buffer,
    /// internal state
    f_state: c_uint,
    /// array of data
    f_data: [4]*anyopaque,
    /// array of size
    f_size: [4]usize,
    /// array of `gst.MapInfo`
    f_map: [4]gst.MapInfo,

    /// Allocate enough data in `buffer` to hold an RTP packet with `csrc_count` CSRCs,
    /// a payload length of `payload_len` and padding of `pad_len`.
    /// `buffer` must be writable and all previous memory in `buffer` will be freed.
    /// If `pad_len` is >0, the padding bit will be set. All other RTP header fields
    /// will be set to 0/FALSE.
    extern fn gst_rtp_buffer_allocate_data(p_buffer: *gst.Buffer, p_payload_len: c_uint, p_pad_len: u8, p_csrc_count: u8) void;
    pub const allocateData = gst_rtp_buffer_allocate_data;

    /// Calculate the header length of an RTP packet with `csrc_count` CSRC entries.
    /// An RTP packet can have at most 15 CSRC entries.
    extern fn gst_rtp_buffer_calc_header_len(p_csrc_count: u8) c_uint;
    pub const calcHeaderLen = gst_rtp_buffer_calc_header_len;

    /// Calculate the total length of an RTP packet with a payload size of `payload_len`,
    /// a padding of `pad_len` and a `csrc_count` CSRC entries.
    extern fn gst_rtp_buffer_calc_packet_len(p_payload_len: c_uint, p_pad_len: u8, p_csrc_count: u8) c_uint;
    pub const calcPacketLen = gst_rtp_buffer_calc_packet_len;

    /// Calculate the length of the payload of an RTP packet with size `packet_len`,
    /// a padding of `pad_len` and a `csrc_count` CSRC entries.
    extern fn gst_rtp_buffer_calc_payload_len(p_packet_len: c_uint, p_pad_len: u8, p_csrc_count: u8) c_uint;
    pub const calcPayloadLen = gst_rtp_buffer_calc_payload_len;

    /// Compare two sequence numbers, taking care of wraparounds. This function
    /// returns the difference between `seqnum1` and `seqnum2`.
    extern fn gst_rtp_buffer_compare_seqnum(p_seqnum1: u16, p_seqnum2: u16) c_int;
    pub const compareSeqnum = gst_rtp_buffer_compare_seqnum;

    /// Get the default clock-rate for the static payload type `payload_type`.
    extern fn gst_rtp_buffer_default_clock_rate(p_payload_type: u8) u32;
    pub const defaultClockRate = gst_rtp_buffer_default_clock_rate;

    /// Update the `exttimestamp` field with the extended timestamp of `timestamp`
    /// For the first call of the method, `exttimestamp` should point to a location
    /// with a value of -1.
    ///
    /// This function is able to handle both forward and backward timestamps taking
    /// into account:
    ///   - timestamp wraparound making sure that the returned value is properly increased.
    ///   - timestamp unwraparound making sure that the returned value is properly decreased.
    extern fn gst_rtp_buffer_ext_timestamp(p_exttimestamp: *u64, p_timestamp: u32) u64;
    pub const extTimestamp = gst_rtp_buffer_ext_timestamp;

    /// Similar to gst_rtp_buffer_get_extension_onebyte_header, but working
    /// on the `glib.Bytes` you get from gst_rtp_buffer_get_extension_bytes.
    /// Parses RFC 5285 style header extensions with a one byte header. It will
    /// return the nth extension with the requested id.
    extern fn gst_rtp_buffer_get_extension_onebyte_header_from_bytes(p_bytes: *glib.Bytes, p_bit_pattern: u16, p_id: u8, p_nth: c_uint, p_data: *[*]u8, p_size: *c_uint) c_int;
    pub const getExtensionOnebyteHeaderFromBytes = gst_rtp_buffer_get_extension_onebyte_header_from_bytes;

    /// Map the contents of `buffer` into `rtp`.
    extern fn gst_rtp_buffer_map(p_buffer: *gst.Buffer, p_flags: gst.MapFlags, p_rtp: *gstrtp.RTPBuffer) c_int;
    pub const map = gst_rtp_buffer_map;

    /// Allocate a new `gst.Buffer` with enough data to hold an RTP packet with
    /// `csrc_count` CSRCs, a payload length of `payload_len` and padding of `pad_len`.
    /// All other RTP header fields will be set to 0/FALSE.
    extern fn gst_rtp_buffer_new_allocate(p_payload_len: c_uint, p_pad_len: u8, p_csrc_count: u8) *gst.Buffer;
    pub const newAllocate = gst_rtp_buffer_new_allocate;

    /// Create a new `gst.Buffer` that can hold an RTP packet that is exactly
    /// `packet_len` long. The length of the payload depends on `pad_len` and
    /// `csrc_count` and can be calculated with `gstrtp.rtpBufferCalcPayloadLen`.
    /// All RTP header fields will be set to 0/FALSE.
    extern fn gst_rtp_buffer_new_allocate_len(p_packet_len: c_uint, p_pad_len: u8, p_csrc_count: u8) *gst.Buffer;
    pub const newAllocateLen = gst_rtp_buffer_new_allocate_len;

    /// Create a new buffer and set the data to a copy of `len`
    /// bytes of `data` and the size to `len`. The data will be freed when the buffer
    /// is freed.
    extern fn gst_rtp_buffer_new_copy_data(p_data: [*]const u8, p_len: usize) *gst.Buffer;
    pub const newCopyData = gst_rtp_buffer_new_copy_data;

    /// Create a new buffer and set the data and size of the buffer to `data` and `len`
    /// respectively. `data` will be freed when the buffer is unreffed, so this
    /// function transfers ownership of `data` to the new buffer.
    extern fn gst_rtp_buffer_new_take_data(p_data: [*]u8, p_len: usize) *gst.Buffer;
    pub const newTakeData = gst_rtp_buffer_new_take_data;

    /// Adds a RFC 5285 header extension with a one byte header to the end of the
    /// RTP header. If there is already a RFC 5285 header extension with a one byte
    /// header, the new extension will be appended.
    /// It will not work if there is already a header extension that does not follow
    /// the mechanism described in RFC 5285 or if there is a header extension with
    /// a two bytes header as described in RFC 5285. In that case, use
    /// `gstrtp.RTPBuffer.addExtensionTwobytesHeader`
    extern fn gst_rtp_buffer_add_extension_onebyte_header(p_rtp: *RTPBuffer, p_id: u8, p_data: [*]const u8, p_size: c_uint) c_int;
    pub const addExtensionOnebyteHeader = gst_rtp_buffer_add_extension_onebyte_header;

    /// Adds a RFC 5285 header extension with a two bytes header to the end of the
    /// RTP header. If there is already a RFC 5285 header extension with a two bytes
    /// header, the new extension will be appended.
    /// It will not work if there is already a header extension that does not follow
    /// the mechanism described in RFC 5285 or if there is a header extension with
    /// a one byte header as described in RFC 5285. In that case, use
    /// `gstrtp.RTPBuffer.addExtensionOnebyteHeader`
    extern fn gst_rtp_buffer_add_extension_twobytes_header(p_rtp: *RTPBuffer, p_appbits: u8, p_id: u8, p_data: [*]const u8, p_size: c_uint) c_int;
    pub const addExtensionTwobytesHeader = gst_rtp_buffer_add_extension_twobytes_header;

    /// Get the CSRC at index `idx` in `buffer`.
    extern fn gst_rtp_buffer_get_csrc(p_rtp: *RTPBuffer, p_idx: u8) u32;
    pub const getCsrc = gst_rtp_buffer_get_csrc;

    /// Get the CSRC count of the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_csrc_count(p_rtp: *RTPBuffer) u8;
    pub const getCsrcCount = gst_rtp_buffer_get_csrc_count;

    /// Check if the extension bit is set on the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_extension(p_rtp: *RTPBuffer) c_int;
    pub const getExtension = gst_rtp_buffer_get_extension;

    /// Similar to gst_rtp_buffer_get_extension_data, but more suitable for language
    /// bindings usage. `bits` will contain the extension 16 bits of custom data and
    /// the extension data (not including the extension header) is placed in a new
    /// `glib.Bytes` structure.
    ///
    /// If `rtp` did not contain an extension, this function will return `NULL`, with
    /// `bits` unchanged. If there is an extension header but no extension data then
    /// an empty `glib.Bytes` will be returned.
    extern fn gst_rtp_buffer_get_extension_bytes(p_rtp: *RTPBuffer, p_bits: *u16) ?*glib.Bytes;
    pub const getExtensionBytes = gst_rtp_buffer_get_extension_bytes;

    /// Get the extension data. `bits` will contain the extension 16 bits of custom
    /// data. `data` will point to the data in the extension and `wordlen` will contain
    /// the length of `data` in 32 bits words.
    ///
    /// If `buffer` did not contain an extension, this function will return `FALSE`
    /// with `bits`, `data` and `wordlen` unchanged.
    extern fn gst_rtp_buffer_get_extension_data(p_rtp: *RTPBuffer, p_bits: ?*u16, p_data: ?*[*]u8, p_wordlen: ?*c_uint) c_int;
    pub const getExtensionData = gst_rtp_buffer_get_extension_data;

    /// Parses RFC 5285 style header extensions with a one byte header. It will
    /// return the nth extension with the requested id.
    extern fn gst_rtp_buffer_get_extension_onebyte_header(p_rtp: *RTPBuffer, p_id: u8, p_nth: c_uint, p_data: ?*[*]u8, p_size: ?*c_uint) c_int;
    pub const getExtensionOnebyteHeader = gst_rtp_buffer_get_extension_onebyte_header;

    /// Parses RFC 5285 style header extensions with a two bytes header. It will
    /// return the nth extension with the requested id.
    extern fn gst_rtp_buffer_get_extension_twobytes_header(p_rtp: *RTPBuffer, p_appbits: ?*u8, p_id: u8, p_nth: c_uint, p_data: ?*[*]u8, p_size: ?*c_uint) c_int;
    pub const getExtensionTwobytesHeader = gst_rtp_buffer_get_extension_twobytes_header;

    /// Return the total length of the header in `buffer`. This include the length of
    /// the fixed header, the CSRC list and the extension header.
    extern fn gst_rtp_buffer_get_header_len(p_rtp: *RTPBuffer) c_uint;
    pub const getHeaderLen = gst_rtp_buffer_get_header_len;

    /// Check if the marker bit is set on the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_marker(p_rtp: *RTPBuffer) c_int;
    pub const getMarker = gst_rtp_buffer_get_marker;

    /// Return the total length of the packet in `buffer`.
    extern fn gst_rtp_buffer_get_packet_len(p_rtp: *RTPBuffer) c_uint;
    pub const getPacketLen = gst_rtp_buffer_get_packet_len;

    /// Check if the padding bit is set on the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_padding(p_rtp: *RTPBuffer) c_int;
    pub const getPadding = gst_rtp_buffer_get_padding;

    /// Get a pointer to the payload data in `buffer`. This pointer is valid as long
    /// as a reference to `buffer` is held.
    extern fn gst_rtp_buffer_get_payload(p_rtp: *RTPBuffer) ?[*]u8;
    pub const getPayload = gst_rtp_buffer_get_payload;

    /// Create a buffer of the payload of the RTP packet in `buffer`. This function
    /// will internally create a subbuffer of `buffer` so that a memcpy can be
    /// avoided.
    extern fn gst_rtp_buffer_get_payload_buffer(p_rtp: *RTPBuffer) *gst.Buffer;
    pub const getPayloadBuffer = gst_rtp_buffer_get_payload_buffer;

    /// Similar to gst_rtp_buffer_get_payload, but more suitable for language
    /// bindings usage. The return value is a pointer to a `glib.Bytes` structure
    /// containing the payload data in `rtp`.
    extern fn gst_rtp_buffer_get_payload_bytes(p_rtp: *RTPBuffer) ?*glib.Bytes;
    pub const getPayloadBytes = gst_rtp_buffer_get_payload_bytes;

    /// Get the length of the payload of the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_payload_len(p_rtp: *RTPBuffer) c_uint;
    pub const getPayloadLen = gst_rtp_buffer_get_payload_len;

    /// Create a subbuffer of the payload of the RTP packet in `buffer`. `offset` bytes
    /// are skipped in the payload and the subbuffer will be of size `len`.
    /// If `len` is -1 the total payload starting from `offset` is subbuffered.
    extern fn gst_rtp_buffer_get_payload_subbuffer(p_rtp: *RTPBuffer, p_offset: c_uint, p_len: c_uint) *gst.Buffer;
    pub const getPayloadSubbuffer = gst_rtp_buffer_get_payload_subbuffer;

    /// Get the payload type of the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_payload_type(p_rtp: *RTPBuffer) u8;
    pub const getPayloadType = gst_rtp_buffer_get_payload_type;

    /// Get the sequence number of the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_seq(p_rtp: *RTPBuffer) u16;
    pub const getSeq = gst_rtp_buffer_get_seq;

    /// Get the SSRC of the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_ssrc(p_rtp: *RTPBuffer) u32;
    pub const getSsrc = gst_rtp_buffer_get_ssrc;

    /// Get the timestamp of the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_timestamp(p_rtp: *RTPBuffer) u32;
    pub const getTimestamp = gst_rtp_buffer_get_timestamp;

    /// Get the version number of the RTP packet in `buffer`.
    extern fn gst_rtp_buffer_get_version(p_rtp: *RTPBuffer) u8;
    pub const getVersion = gst_rtp_buffer_get_version;

    /// Set the amount of padding in the RTP packet in `buffer` to
    /// `len`. If `len` is 0, the padding is removed.
    ///
    /// NOTE: This function does not work correctly.
    extern fn gst_rtp_buffer_pad_to(p_rtp: *RTPBuffer, p_len: c_uint) void;
    pub const padTo = gst_rtp_buffer_pad_to;

    /// Unsets the extension bit of the RTP buffer and removes the extension header
    /// and data.
    ///
    /// If the RTP buffer has no header extension data, the action has no effect.
    /// The RTP buffer must be mapped READWRITE only once and the underlying
    /// GstBuffer must be writable.
    extern fn gst_rtp_buffer_remove_extension_data(p_rtp: *RTPBuffer) void;
    pub const removeExtensionData = gst_rtp_buffer_remove_extension_data;

    /// Modify the CSRC at index `idx` in `buffer` to `csrc`.
    extern fn gst_rtp_buffer_set_csrc(p_rtp: *RTPBuffer, p_idx: u8, p_csrc: u32) void;
    pub const setCsrc = gst_rtp_buffer_set_csrc;

    /// Set the extension bit on the RTP packet in `buffer` to `extension`.
    extern fn gst_rtp_buffer_set_extension(p_rtp: *RTPBuffer, p_extension: c_int) void;
    pub const setExtension = gst_rtp_buffer_set_extension;

    /// Set the extension bit of the rtp buffer and fill in the `bits` and `length` of the
    /// extension header. If the existing extension data is not large enough, it will
    /// be made larger.
    ///
    /// Will also shorten the extension data from 1.20.
    extern fn gst_rtp_buffer_set_extension_data(p_rtp: *RTPBuffer, p_bits: u16, p_length: u16) c_int;
    pub const setExtensionData = gst_rtp_buffer_set_extension_data;

    /// Set the marker bit on the RTP packet in `buffer` to `marker`.
    extern fn gst_rtp_buffer_set_marker(p_rtp: *RTPBuffer, p_marker: c_int) void;
    pub const setMarker = gst_rtp_buffer_set_marker;

    /// Set the total `rtp` size to `len`. The data in the buffer will be made
    /// larger if needed. Any padding will be removed from the packet.
    extern fn gst_rtp_buffer_set_packet_len(p_rtp: *RTPBuffer, p_len: c_uint) void;
    pub const setPacketLen = gst_rtp_buffer_set_packet_len;

    /// Set the padding bit on the RTP packet in `buffer` to `padding`.
    extern fn gst_rtp_buffer_set_padding(p_rtp: *RTPBuffer, p_padding: c_int) void;
    pub const setPadding = gst_rtp_buffer_set_padding;

    /// Set the payload type of the RTP packet in `buffer` to `payload_type`.
    extern fn gst_rtp_buffer_set_payload_type(p_rtp: *RTPBuffer, p_payload_type: u8) void;
    pub const setPayloadType = gst_rtp_buffer_set_payload_type;

    /// Set the sequence number of the RTP packet in `buffer` to `seq`.
    extern fn gst_rtp_buffer_set_seq(p_rtp: *RTPBuffer, p_seq: u16) void;
    pub const setSeq = gst_rtp_buffer_set_seq;

    /// Set the SSRC on the RTP packet in `buffer` to `ssrc`.
    extern fn gst_rtp_buffer_set_ssrc(p_rtp: *RTPBuffer, p_ssrc: u32) void;
    pub const setSsrc = gst_rtp_buffer_set_ssrc;

    /// Set the timestamp of the RTP packet in `buffer` to `timestamp`.
    extern fn gst_rtp_buffer_set_timestamp(p_rtp: *RTPBuffer, p_timestamp: u32) void;
    pub const setTimestamp = gst_rtp_buffer_set_timestamp;

    /// Set the version of the RTP packet in `buffer` to `version`.
    extern fn gst_rtp_buffer_set_version(p_rtp: *RTPBuffer, p_version: u8) void;
    pub const setVersion = gst_rtp_buffer_set_version;

    /// Unmap `rtp` previously mapped with `gstrtp.rtpBufferMap`.
    extern fn gst_rtp_buffer_unmap(p_rtp: *RTPBuffer) void;
    pub const unmap = gst_rtp_buffer_unmap;

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

/// Base class for RTP Header extensions.
pub const RTPHeaderExtensionClass = extern struct {
    pub const Instance = gstrtp.RTPHeaderExtension;

    /// the parent class
    f_parent_class: gst.ElementClass,
    /// retrieve the supported flags
    f_get_supported_flags: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension) callconv(.c) gstrtp.RTPHeaderExtensionFlags,
    /// retrieve the maximum size for this extension based on the
    ///     information available from input_meta.  Implementations should attempt
    ///     to provide as accurate information as possible as the returned value
    ///     will be used to control the amount of possible data in the payload.
    ///     Implementations must return the maximum as the allocated size for
    ///     writing the extension will be at least the size of the returned value.
    ///     Return the amount of data read or <0 on failure.
    f_get_max_size: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension, p_input_meta: *const gst.Buffer) callconv(.c) usize,
    /// write into `data` the information for this extension.  Various
    ///     information is provided to help writing extensions in particular cases.
    f_write: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension, p_input_meta: *const gst.Buffer, p_write_flags: gstrtp.RTPHeaderExtensionFlags, p_output: *gst.Buffer, p_data: [*]u8, p_size: usize) callconv(.c) isize,
    /// read from a rtp payloaded buffer and extract the extension
    ///     information, optionally adding some meta onto the output buffer.
    f_read: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension, p_read_flags: gstrtp.RTPHeaderExtensionFlags, p_data: [*]const u8, p_size: usize, p_buffer: *gst.Buffer) callconv(.c) c_int,
    /// read any information from sink caps that the header
    ///     extension needs for its function.
    f_set_non_rtp_sink_caps: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension, p_caps: *const gst.Caps) callconv(.c) c_int,
    /// update depayloader non-RTP (depayloaded) caps with
    ///     the information parsed from RTP header.
    f_update_non_rtp_src_caps: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension, p_caps: *gst.Caps) callconv(.c) c_int,
    /// set the necessary attributes that may be signaled e.g. with
    ///     an SDP.
    f_set_attributes: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension, p_direction: gstrtp.RTPHeaderExtensionDirection, p_attributes: [*:0]const u8) callconv(.c) c_int,
    /// write the necessary caps field/s for the configured
    ///     attributes e.g. as signalled with SDP.
    f_set_caps_from_attributes: ?*const fn (p_ext: *gstrtp.RTPHeaderExtension, p_caps: *gst.Caps) callconv(.c) c_int,
    f__gst_reserved: [20]*anyopaque,

    /// Set the URI for this RTP header extension implementation.
    extern fn gst_rtp_header_extension_class_set_uri(p_klass: *RTPHeaderExtensionClass, p_uri: [*:0]const u8) void;
    pub const setUri = gst_rtp_header_extension_class_set_uri;

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

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

/// Structure holding default payload type information.
pub const RTPPayloadInfo = extern struct {
    /// payload type, -1 means dynamic
    f_payload_type: u8,
    /// the media type(s), usually "audio", "video", "application", "text",
    /// "message".
    f_media: ?[*:0]const u8,
    /// the encoding name of `pt`
    f_encoding_name: ?[*:0]const u8,
    /// default clock rate, 0 = unknown/variable
    f_clock_rate: c_uint,
    /// encoding parameters. For audio this is the number of
    /// channels. NULL = not applicable.
    f_encoding_parameters: ?[*:0]const u8,
    /// the bitrate of the media. 0 = unknown/variable.
    f_bitrate: c_uint,
    f__gst_reserved: [4]*anyopaque,

    /// Get the `gstrtp.RTPPayloadInfo` for `media` and `encoding_name`. This function is
    /// mostly used to get the default clock-rate and bandwidth for dynamic payload
    /// types specified with `media` and `encoding` name.
    ///
    /// The search for `encoding_name` will be performed in a case insensitive way.
    extern fn gst_rtp_payload_info_for_name(p_media: [*:0]const u8, p_encoding_name: [*:0]const u8) ?*const gstrtp.RTPPayloadInfo;
    pub const forName = gst_rtp_payload_info_for_name;

    /// Get the `gstrtp.RTPPayloadInfo` for `payload_type`. This function is
    /// mostly used to get the default clock-rate and bandwidth for static payload
    /// types specified with `payload_type`.
    extern fn gst_rtp_payload_info_for_pt(p_payload_type: u8) ?*const gstrtp.RTPPayloadInfo;
    pub const forPt = gst_rtp_payload_info_for_pt;

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

/// Meta describing the source(s) of the buffer.
pub const RTPSourceMeta = extern struct {
    /// parent `gst.Meta`
    f_meta: gst.Meta,
    /// the SSRC
    f_ssrc: u32,
    /// whether `ssrc` is set and valid
    f_ssrc_valid: c_int,
    /// pointer to the CSRCs
    f_csrc: [15]u32,
    /// number of elements in `csrc`
    f_csrc_count: c_uint,

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

    /// Appends `csrc` to the list of contributing sources in `meta`.
    extern fn gst_rtp_source_meta_append_csrc(p_meta: *RTPSourceMeta, p_csrc: [*]const u32, p_csrc_count: c_uint) c_int;
    pub const appendCsrc = gst_rtp_source_meta_append_csrc;

    /// Count the total number of RTP sources found in `meta`, both SSRC and CSRC.
    extern fn gst_rtp_source_meta_get_source_count(p_meta: *const RTPSourceMeta) c_uint;
    pub const getSourceCount = gst_rtp_source_meta_get_source_count;

    /// Sets `ssrc` in `meta`. If `ssrc` is `NULL` the ssrc of `meta` will be unset.
    extern fn gst_rtp_source_meta_set_ssrc(p_meta: *RTPSourceMeta, p_ssrc: ?*u32) c_int;
    pub const setSsrc = gst_rtp_source_meta_set_ssrc;

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

/// Different types of feedback messages.
pub const RTCPFBType = enum(c_int) {
    fb_type_invalid = 0,
    rtpfb_type_nack = 1,
    rtpfb_type_tmmbr = 3,
    rtpfb_type_tmmbn = 4,
    rtpfb_type_rtcp_sr_req = 5,
    rtpfb_type_twcc = 15,
    psfb_type_sli = 2,
    psfb_type_tstn = 6,
    psfb_type_vbcn = 7,
    _,

    pub const psfb_type_pli = RTCPFBType.rtpfb_type_nack;
    pub const psfb_type_rpsi = RTCPFBType.rtpfb_type_tmmbr;
    pub const psfb_type_afb = RTCPFBType.rtpfb_type_twcc;
    pub const psfb_type_fir = RTCPFBType.rtpfb_type_tmmbn;
    pub const psfb_type_tstr = RTCPFBType.rtpfb_type_rtcp_sr_req;
    extern fn gst_rtcpfb_type_get_type() usize;
    pub const getGObjectType = gst_rtcpfb_type_get_type;

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

/// Different types of SDES content.
pub const RTCPSDESType = enum(c_int) {
    invalid = -1,
    end = 0,
    cname = 1,
    name = 2,
    email = 3,
    phone = 4,
    loc = 5,
    tool = 6,
    note = 7,
    priv = 8,
    h323_caddr = 9,
    apsi = 10,
    rgrp = 11,
    rtp_stream_id = 12,
    repaired_rtp_stream_id = 13,
    ccid = 14,
    mid = 15,
    _,

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

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

/// Different RTCP packet types.
pub const RTCPType = enum(c_int) {
    invalid = 0,
    sr = 200,
    rr = 201,
    sdes = 202,
    bye = 203,
    app = 204,
    rtpfb = 205,
    psfb = 206,
    xr = 207,
    _,

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

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

/// Types of RTCP Extended Reports, those are defined in RFC 3611 and other RFCs
/// according to the [IANA registry](https://www.iana.org/assignments/rtcp-xr-block-types/rtcp-xr-block-types.xhtml).
pub const RTCPXRType = enum(c_int) {
    invalid = -1,
    lrle = 1,
    drle = 2,
    prt = 3,
    rrt = 4,
    dlrr = 5,
    ssumm = 6,
    voip_metrics = 7,
    _,

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

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

/// Standard predefined fixed payload types.
///
/// The official list is at:
/// http://www.iana.org/assignments/rtp-parameters
///
/// Audio:
/// reserved: 19
/// unassigned: 20-23,
///
/// Video:
/// unassigned: 24, 27, 29, 30, 35-71, 77-95
/// Reserved for RTCP conflict avoidance: 72-76
pub const RTPPayload = enum(c_int) {
    pcmu = 0,
    @"1016" = 1,
    g721 = 2,
    gsm = 3,
    g723 = 4,
    dvi4_8000 = 5,
    dvi4_16000 = 6,
    lpc = 7,
    pcma = 8,
    g722 = 9,
    l16_stereo = 10,
    l16_mono = 11,
    qcelp = 12,
    cn = 13,
    mpa = 14,
    g728 = 15,
    dvi4_11025 = 16,
    dvi4_22050 = 17,
    g729 = 18,
    cellb = 25,
    jpeg = 26,
    nv = 28,
    h261 = 31,
    mpv = 32,
    mp2t = 33,
    h263 = 34,
    _,

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

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

/// The transfer profile to use.
pub const RTPProfile = enum(c_int) {
    unknown = 0,
    avp = 1,
    savp = 2,
    avpf = 3,
    savpf = 4,
    _,

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

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

/// Additional RTP buffer flags. These flags can potentially be used on any
/// buffers carrying RTP packets.
///
/// Note that these are only valid for `gst.Caps` of type: application/x-rtp (x-rtcp).
/// They can conflict with other extended buffer flags.
pub const RTPBufferFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    _padding16: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    retransmission: bool = false,
    redundant: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    _padding24: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    last: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_retransmission: RTPBufferFlags = @bitCast(@as(c_uint, 1048576));
    pub const flags_redundant: RTPBufferFlags = @bitCast(@as(c_uint, 2097152));
    pub const flags_last: RTPBufferFlags = @bitCast(@as(c_uint, 268435456));
    extern fn gst_rtp_buffer_flags_get_type() usize;
    pub const getGObjectType = gst_rtp_buffer_flags_get_type;

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

/// Additional mapping flags for `gstrtp.rtpBufferMap`.
pub const RTPBufferMapFlags = packed struct(c_uint) {
    _padding0: bool = false,
    _padding1: bool = false,
    _padding2: bool = false,
    _padding3: bool = false,
    _padding4: bool = false,
    _padding5: bool = false,
    _padding6: bool = false,
    _padding7: bool = false,
    _padding8: bool = false,
    _padding9: bool = false,
    _padding10: bool = false,
    _padding11: bool = false,
    _padding12: bool = false,
    _padding13: bool = false,
    _padding14: bool = false,
    _padding15: bool = false,
    skip_padding: bool = false,
    _padding17: bool = false,
    _padding18: bool = false,
    _padding19: bool = false,
    _padding20: bool = false,
    _padding21: bool = false,
    _padding22: bool = false,
    _padding23: bool = false,
    last: bool = false,
    _padding25: bool = false,
    _padding26: bool = false,
    _padding27: bool = false,
    _padding28: bool = false,
    _padding29: bool = false,
    _padding30: bool = false,
    _padding31: bool = false,

    pub const flags_skip_padding: RTPBufferMapFlags = @bitCast(@as(c_uint, 65536));
    pub const flags_last: RTPBufferMapFlags = @bitCast(@as(c_uint, 16777216));
    extern fn gst_rtp_buffer_map_flags_get_type() usize;
    pub const getGObjectType = gst_rtp_buffer_map_flags_get_type;

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

/// Direction to which to apply the RTP Header Extension
pub const RTPHeaderExtensionDirection = packed struct(c_uint) {
    sendonly: bool = false,
    recvonly: bool = false,
    inherited: 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_inactive: RTPHeaderExtensionDirection = @bitCast(@as(c_uint, 0));
    pub const flags_sendonly: RTPHeaderExtensionDirection = @bitCast(@as(c_uint, 1));
    pub const flags_recvonly: RTPHeaderExtensionDirection = @bitCast(@as(c_uint, 2));
    pub const flags_sendrecv: RTPHeaderExtensionDirection = @bitCast(@as(c_uint, 3));
    pub const flags_inherited: RTPHeaderExtensionDirection = @bitCast(@as(c_uint, 4));
    extern fn gst_rtp_header_extension_direction_get_type() usize;
    pub const getGObjectType = gst_rtp_header_extension_direction_get_type;

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

/// Flags that apply to a RTP Audio/Video header extension.
pub const RTPHeaderExtensionFlags = packed struct(c_uint) {
    one_byte: bool = false,
    two_byte: 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_one_byte: RTPHeaderExtensionFlags = @bitCast(@as(c_uint, 1));
    pub const flags_two_byte: RTPHeaderExtensionFlags = @bitCast(@as(c_uint, 2));
    extern fn gst_rtp_header_extension_flags_get_type() usize;
    pub const getGObjectType = gst_rtp_header_extension_flags_get_type;

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

/// Attaches RTP source information to `buffer`.
extern fn gst_buffer_add_rtp_source_meta(p_buffer: *gst.Buffer, p_ssrc: ?*const u32, p_csrc: ?[*]const u32, p_csrc_count: c_uint) *gstrtp.RTPSourceMeta;
pub const bufferAddRtpSourceMeta = gst_buffer_add_rtp_source_meta;

/// Find the `gstrtp.RTPSourceMeta` on `buffer`.
extern fn gst_buffer_get_rtp_source_meta(p_buffer: *gst.Buffer) ?*gstrtp.RTPSourceMeta;
pub const bufferGetRtpSourceMeta = gst_buffer_get_rtp_source_meta;

/// Converts an NTP time to UNIX nanoseconds. `ntptime` can typically be
/// the NTP time of an SR RTCP message and contains, in the upper 32 bits, the
/// number of seconds since 1900 and, in the lower 32 bits, the fractional
/// seconds. The resulting value will be the number of nanoseconds since 1970.
extern fn gst_rtcp_ntp_to_unix(p_ntptime: u64) u64;
pub const rtcpNtpToUnix = gst_rtcp_ntp_to_unix;

/// Convert `name` into a `GstRTCPSDESType`. `name` is typically a key in a
/// `gst.Structure` containing SDES items.
extern fn gst_rtcp_sdes_name_to_type(p_name: [*:0]const u8) gstrtp.RTCPSDESType;
pub const rtcpSdesNameToType = gst_rtcp_sdes_name_to_type;

/// Converts `type` to the string equivalent. The string is typically used as a
/// key in a `gst.Structure` containing SDES items.
extern fn gst_rtcp_sdes_type_to_name(p_type: gstrtp.RTCPSDESType) [*:0]const u8;
pub const rtcpSdesTypeToName = gst_rtcp_sdes_type_to_name;

/// Converts a UNIX timestamp in nanoseconds to an NTP time. The caller should
/// pass a value with nanoseconds since 1970. The NTP time will, in the upper
/// 32 bits, contain the number of seconds since 1900 and, in the lower 32
/// bits, the fractional seconds. The resulting value can be used as an ntptime
/// for constructing SR RTCP packets.
extern fn gst_rtcp_unix_to_ntp(p_unixtime: u64) u64;
pub const rtcpUnixToNtp = gst_rtcp_unix_to_ntp;

/// Retrieve all the factories of the currently registered RTP header
/// extensions.  Call `gst.ElementFactory.create` with each factory to create
/// the associated `gstrtp.RTPHeaderExtension`.
extern fn gst_rtp_get_header_extension_list() *glib.List;
pub const rtpGetHeaderExtensionList = gst_rtp_get_header_extension_list;

/// Reads the NTP time from the `size` NTP-56 extension bytes in `data` and store the
/// result in `ntptime`.
extern fn gst_rtp_hdrext_get_ntp_56(p_data: [*]u8, p_size: c_uint, p_ntptime: *u64) c_int;
pub const rtpHdrextGetNtp56 = gst_rtp_hdrext_get_ntp_56;

/// Reads the NTP time from the `size` NTP-64 extension bytes in `data` and store the
/// result in `ntptime`.
extern fn gst_rtp_hdrext_get_ntp_64(p_data: [*]u8, p_size: c_uint, p_ntptime: *u64) c_int;
pub const rtpHdrextGetNtp64 = gst_rtp_hdrext_get_ntp_64;

/// Writes the NTP time in `ntptime` to the format required for the NTP-56 header
/// extension. `data` must hold at least `GST_RTP_HDREXT_NTP_56_SIZE` bytes.
extern fn gst_rtp_hdrext_set_ntp_56(p_data: ?*anyopaque, p_size: c_uint, p_ntptime: u64) c_int;
pub const rtpHdrextSetNtp56 = gst_rtp_hdrext_set_ntp_56;

/// Writes the NTP time in `ntptime` to the format required for the NTP-64 header
/// extension. `data` must hold at least `GST_RTP_HDREXT_NTP_64_SIZE` bytes.
extern fn gst_rtp_hdrext_set_ntp_64(p_data: ?*anyopaque, p_size: c_uint, p_ntptime: u64) c_int;
pub const rtpHdrextSetNtp64 = gst_rtp_hdrext_set_ntp_64;

extern fn gst_rtp_source_meta_api_get_type() usize;
pub const rtpSourceMetaApiGetType = gst_rtp_source_meta_api_get_type;

/// The maximum amount of SSRCs in a BYE packet.
pub const RTCP_MAX_BYE_SSRC_COUNT = 31;
/// The maximum amount of Receiver report blocks in RR and SR messages.
pub const RTCP_MAX_RB_COUNT = 31;
/// The maximum text length for an SDES item.
pub const RTCP_MAX_SDES = 255;
/// The maximum amount of SDES items.
pub const RTCP_MAX_SDES_ITEM_COUNT = 31;
/// Mask for version and packet type pair allowing reduced size
/// packets, basically it accepts other types than RR and SR
pub const RTCP_REDUCED_SIZE_VALID_MASK = 49400;
/// Mask for version, padding bit and packet type pair
pub const RTCP_VALID_MASK = 57598;
/// Valid value for the first two bytes of an RTCP packet after applying
/// `GST_RTCP_VALID_MASK` to them.
pub const RTCP_VALID_VALUE = 32968;
/// The supported RTCP version 2.
pub const RTCP_VERSION = 2;
pub const RTP_HDREXT_BASE = "urn:ietf:params:rtp-hdrext:";
/// Constant string used in element classification to signal that this element
/// is a RTP header extension.
pub const RTP_HDREXT_ELEMENT_CLASS = "Network/Extension/RTPHeader";
pub const RTP_HDREXT_NTP_56 = "ntp-56";
pub const RTP_HDREXT_NTP_56_SIZE = 7;
pub const RTP_HDREXT_NTP_64 = "ntp-64";
pub const RTP_HDREXT_NTP_64_SIZE = 8;
pub const RTP_HEADER_EXTENSION_URI_METADATA_KEY = "RTP-Header-Extension-URI";
pub const RTP_PAYLOAD_1016_STRING = "1";
pub const RTP_PAYLOAD_CELLB_STRING = "25";
pub const RTP_PAYLOAD_CN_STRING = "13";
pub const RTP_PAYLOAD_DVI4_11025_STRING = "16";
pub const RTP_PAYLOAD_DVI4_16000_STRING = "6";
pub const RTP_PAYLOAD_DVI4_22050_STRING = "17";
pub const RTP_PAYLOAD_DVI4_8000_STRING = "5";
pub const RTP_PAYLOAD_DYNAMIC_STRING = "[96, 127]";
pub const RTP_PAYLOAD_G721_STRING = "2";
pub const RTP_PAYLOAD_G722_STRING = "9";
pub const RTP_PAYLOAD_G723_53 = 17;
pub const RTP_PAYLOAD_G723_53_STRING = "17";
pub const RTP_PAYLOAD_G723_63 = 16;
pub const RTP_PAYLOAD_G723_63_STRING = "16";
pub const RTP_PAYLOAD_G723_STRING = "4";
pub const RTP_PAYLOAD_G728_STRING = "15";
pub const RTP_PAYLOAD_G729_STRING = "18";
pub const RTP_PAYLOAD_GSM_STRING = "3";
pub const RTP_PAYLOAD_H261_STRING = "31";
pub const RTP_PAYLOAD_H263_STRING = "34";
pub const RTP_PAYLOAD_JPEG_STRING = "26";
pub const RTP_PAYLOAD_L16_MONO_STRING = "11";
pub const RTP_PAYLOAD_L16_STEREO_STRING = "10";
pub const RTP_PAYLOAD_LPC_STRING = "7";
pub const RTP_PAYLOAD_MP2T_STRING = "33";
pub const RTP_PAYLOAD_MPA_STRING = "14";
pub const RTP_PAYLOAD_MPV_STRING = "32";
pub const RTP_PAYLOAD_NV_STRING = "28";
pub const RTP_PAYLOAD_PCMA_STRING = "8";
pub const RTP_PAYLOAD_PCMU_STRING = "0";
pub const RTP_PAYLOAD_QCELP_STRING = "12";
pub const RTP_PAYLOAD_TS41 = 19;
pub const RTP_PAYLOAD_TS41_STRING = "19";
pub const RTP_PAYLOAD_TS48 = 18;
pub const RTP_PAYLOAD_TS48_STRING = "18";
pub const RTP_SOURCE_META_MAX_CSRC_COUNT = 15;
/// The supported RTP version 2.
pub const RTP_VERSION = 2;

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