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

const std = @import("std");
const compat = @import("compat");
const gstpbutils = @import("gstpbutils1");
const gstvideo = @import("gstvideo1");
const gstbase = @import("gstbase1");
const gst = @import("gst1");
const gobject = @import("gobject2");
const glib = @import("glib2");
const gmodule = @import("gmodule2");
const gstaudio = @import("gstaudio1");
pub const Transcoder = opaque {
    pub const Parent = gst.Object;
    pub const Implements = [_]type{};
    pub const Class = gsttranscoder.TranscoderClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// See `encodebin.properties.avoid`-reencoding
        pub const avoid_reencoding = struct {
            pub const name = "avoid-reencoding";

            pub const Type = c_int;
        };

        pub const dest_uri = struct {
            pub const name = "dest-uri";

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

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

            pub const Type = u64;
        };

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

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

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

            pub const Type = u64;
        };

        pub const position_update_interval = struct {
            pub const name = "position-update-interval";

            pub const Type = c_uint;
        };

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

            pub const Type = ?*gstpbutils.EncodingProfile;
        };

        pub const src_uri = struct {
            pub const name = "src-uri";

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

    pub const signals = struct {};

    extern fn gst_transcoder_is_transcoder_message(p_msg: *gst.Message) c_int;
    pub const isTranscoderMessage = gst_transcoder_is_transcoder_message;

    extern fn gst_transcoder_new(p_source_uri: [*:0]const u8, p_dest_uri: [*:0]const u8, p_encoding_profile: [*:0]const u8) *gsttranscoder.Transcoder;
    pub const new = gst_transcoder_new;

    extern fn gst_transcoder_new_full(p_source_uri: [*:0]const u8, p_dest_uri: [*:0]const u8, p_profile: *gstpbutils.EncodingProfile) *gsttranscoder.Transcoder;
    pub const newFull = gst_transcoder_new_full;

    extern fn gst_transcoder_get_avoid_reencoding(p_self: *Transcoder) c_int;
    pub const getAvoidReencoding = gst_transcoder_get_avoid_reencoding;

    /// Gets the URI of the destination of the transcoded stream.
    extern fn gst_transcoder_get_dest_uri(p_self: *Transcoder) [*:0]u8;
    pub const getDestUri = gst_transcoder_get_dest_uri;

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

    /// GstTranscoder API exposes a `gst.Bus` instance which purpose is to provide data
    /// structures representing transcoder-internal events in form of `gst.Message`-s of
    /// type GST_MESSAGE_APPLICATION.
    ///
    /// Each message carries a "transcoder-message" field of type `gsttranscoder.TranscoderMessage`.
    /// Further fields of the message data are specific to each possible value of
    /// that enumeration.
    ///
    /// Applications can consume the messages asynchronously within their own
    /// event-loop / UI-thread etc. Note that in case the application does not
    /// consume the messages, the bus will accumulate these internally and eventually
    /// fill memory. To avoid that, the bus has to be set "flushing".
    extern fn gst_transcoder_get_message_bus(p_transcoder: *Transcoder) *gst.Bus;
    pub const getMessageBus = gst_transcoder_get_message_bus;

    extern fn gst_transcoder_get_pipeline(p_self: *Transcoder) *gst.Element;
    pub const getPipeline = gst_transcoder_get_pipeline;

    extern fn gst_transcoder_get_position(p_self: *Transcoder) gst.ClockTime;
    pub const getPosition = gst_transcoder_get_position;

    extern fn gst_transcoder_get_position_update_interval(p_self: *Transcoder) c_uint;
    pub const getPositionUpdateInterval = gst_transcoder_get_position_update_interval;

    /// Gets the `gsttranscoder.TranscoderSignalAdapter` attached to `self` if it is attached to
    /// the right `glib.MainContext`. If no `gsttranscoder.TranscoderSignalAdapter` has been created
    /// yet, it will be created and returned, other calls will return that same
    /// adapter until it is destroyed, at which point, a new one can be attached the
    /// same way.
    extern fn gst_transcoder_get_signal_adapter(p_self: *Transcoder, p_context: ?*glib.MainContext) ?*gsttranscoder.TranscoderSignalAdapter;
    pub const getSignalAdapter = gst_transcoder_get_signal_adapter;

    /// Gets the URI of the currently-transcoding stream.
    extern fn gst_transcoder_get_source_uri(p_self: *Transcoder) [*:0]u8;
    pub const getSourceUri = gst_transcoder_get_source_uri;

    /// Gets the `gsttranscoder.TranscoderSignalAdapter` attached to `self` to emit signals from
    /// its thread of emission.
    extern fn gst_transcoder_get_sync_signal_adapter(p_self: *Transcoder) *gsttranscoder.TranscoderSignalAdapter;
    pub const getSyncSignalAdapter = gst_transcoder_get_sync_signal_adapter;

    /// Run the transcoder task synchonously. You can connect
    /// to the 'position' signal to get information about the
    /// progress of the transcoding.
    extern fn gst_transcoder_run(p_self: *Transcoder, p_error: ?*?*glib.Error) c_int;
    pub const run = gst_transcoder_run;

    /// Run the transcoder task asynchronously. You should connect
    /// to the 'done' signal to be notified about when the
    /// transcoding is done, and to the 'error' signal to be
    /// notified about any error.
    extern fn gst_transcoder_run_async(p_self: *Transcoder) void;
    pub const runAsync = gst_transcoder_run_async;

    extern fn gst_transcoder_set_avoid_reencoding(p_self: *Transcoder, p_avoid_reencoding: c_int) void;
    pub const setAvoidReencoding = gst_transcoder_set_avoid_reencoding;

    /// Sets `cpu_usage` as target percentage CPU usage of the process running the
    /// transcoding task. It will modulate the transcoding speed to reach that target
    /// usage.
    extern fn gst_transcoder_set_cpu_usage(p_self: *Transcoder, p_cpu_usage: c_int) void;
    pub const setCpuUsage = gst_transcoder_set_cpu_usage;

    /// Set interval in milliseconds between two position-updated signals.
    /// Pass 0 to stop updating the position.
    extern fn gst_transcoder_set_position_update_interval(p_self: *Transcoder, p_interval: c_uint) void;
    pub const setPositionUpdateInterval = gst_transcoder_set_position_update_interval;

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

    extern fn g_object_ref(p_self: *gsttranscoder.Transcoder) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gsttranscoder.Transcoder) void;
    pub const unref = g_object_unref;

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

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

/// Transforms `gsttranscoder.Transcoder` bus messages to signals from the adapter object.
pub const TranscoderSignalAdapter = opaque {
    pub const Parent = gobject.Object;
    pub const Implements = [_]type{};
    pub const Class = gsttranscoder.TranscoderSignalAdapterClass;
    pub const virtual_methods = struct {};

    pub const properties = struct {
        /// The `gsttranscoder.Transcoder` tracked by the adapter.
        pub const transcoder = struct {
            pub const name = "transcoder";

            pub const Type = ?*gsttranscoder.Transcoder;
        };
    };

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

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

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

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

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

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

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

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

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

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

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

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

    extern fn gst_transcoder_signal_adapter_get_transcoder(p_self: *TranscoderSignalAdapter) ?*gsttranscoder.Transcoder;
    pub const getTranscoder = gst_transcoder_signal_adapter_get_transcoder;

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

    extern fn g_object_ref(p_self: *gsttranscoder.TranscoderSignalAdapter) void;
    pub const ref = g_object_ref;

    extern fn g_object_unref(p_self: *gsttranscoder.TranscoderSignalAdapter) void;
    pub const unref = g_object_unref;

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

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

pub const TranscoderClass = extern struct {
    pub const Instance = gsttranscoder.Transcoder;

    f_parent_class: gst.ObjectClass,

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

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

pub const TranscoderSignalAdapterClass = extern struct {
    pub const Instance = gsttranscoder.TranscoderSignalAdapter;

    f_parent_class: gobject.ObjectClass,

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

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

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

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

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

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

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

/// Types of messages that will be posted on the transcoder API bus.
///
/// See also `gsttranscoder.Transcoder.getMessageBus``gsttranscoder.Transcoder.getMessageBus`
pub const TranscoderMessage = enum(c_int) {
    position_updated = 0,
    duration_changed = 1,
    state_changed = 2,
    done = 3,
    @"error" = 4,
    warning = 5,
    _,

    /// Returns (transfer none): The message name
    extern fn gst_transcoder_message_get_name(p_message: gsttranscoder.TranscoderMessage) [*:0]const u8;
    pub const getName = gst_transcoder_message_get_name;

    /// Parse the given duration `msg` and extract the corresponding `gst.ClockTime`
    extern fn gst_transcoder_message_parse_duration(p_msg: *gst.Message, p_duration: *gst.ClockTime) void;
    pub const parseDuration = gst_transcoder_message_parse_duration;

    /// Parse the given error `msg` and extract the corresponding `glib.Error`
    extern fn gst_transcoder_message_parse_error(p_msg: *gst.Message, p_error: ?*glib.Error, p_details: **gst.Structure) void;
    pub const parseError = gst_transcoder_message_parse_error;

    /// Parse the given position `msg` and extract the corresponding `gst.ClockTime`
    extern fn gst_transcoder_message_parse_position(p_msg: *gst.Message, p_position: *gst.ClockTime) void;
    pub const parsePosition = gst_transcoder_message_parse_position;

    /// Parse the given state `msg` and extract the corresponding `gsttranscoder.TranscoderState`
    extern fn gst_transcoder_message_parse_state(p_msg: *gst.Message, p_state: *gsttranscoder.TranscoderState) void;
    pub const parseState = gst_transcoder_message_parse_state;

    /// Parse the given error `msg` and extract the corresponding `glib.Error` warning
    extern fn gst_transcoder_message_parse_warning(p_msg: *gst.Message, p_error: ?*glib.Error, p_details: **gst.Structure) void;
    pub const parseWarning = gst_transcoder_message_parse_warning;

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

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

/// High level representation of the transcoder pipeline state.
pub const TranscoderState = enum(c_int) {
    stopped = 0,
    paused = 1,
    playing = 2,
    _,

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

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

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

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