Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import gintro/[gst,gobject,glib], os, strformat
- # Structure to contain all our information, so we can pass it to callbacks
- type
- CustomData = object
- pipeline, source, convert, resample, sink: gst.Element
- #[
- typedef struct _CustomData {
- GstElement *pipeline;
- GstElement *source;
- GstElement *convert;
- GstElement *resample;
- GstElement *sink;
- } CustomData;
- ]#
- #[
- /* Handler for the pad-added signal */
- static void pad_added_handler (GstElement *src, GstPad *pad, CustomData *data);
- ]#
- #[ proc sourceName*(self: Message): string =
- let resul0 = gst_object_get_name(cast[ptr Object00](self.impl.src))
- if resul0.isNil:
- return
- result = $resul0
- cogfree(resul0) ]#
- # This function will be called by the pad-added signal NOTA: cast[ptr Pad00](pad.impl)
- proc padAddedHandler(src:ptr Element00; newPad:ptr Pad00; dataPtr:pointer) {.cdecl.} =
- var data = cast[CustomData](dataPtr)
- #var sinkPad:gst.Pad = gst_element_get_static_pad(data.convert, "sink")
- var sinkPad:gst.Pad = getRequestPad(data.convert, "sink")
- #GstPadLinkReturn ret;
- #GstCaps *new_pad_caps = NULL;
- #GstStructure *new_pad_struct = NULL;
- #const gchar *new_pad_type = NULL;
- echo "New pad"
- #echo("Received new pad '%s' from '%s':\n", newPad.name, src.name ) # GST_PAD_NAME, GST_ELEMENT_NAME
- #[ /* If our converter is already linked, we have nothing to do here */
- if (gst_pad_is_linked (sink_pad)) {
- g_print ("We are already linked. Ignoring.\n");
- goto exit;
- } ]#
- #[ /* Check the new pad's type */
- new_pad_caps = gst_pad_get_current_caps (new_pad);
- new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
- new_pad_type = gst_structure_get_name (new_pad_struct);
- if (!g_str_has_prefix (new_pad_type, "audio/x-raw")) {
- g_print ("It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);
- goto exit;
- } ]#
- #[ /* Attempt the link */
- ret = gst_pad_link (new_pad, sink_pad);
- if (GST_PAD_LINK_FAILED (ret)) {
- g_print ("Type is '%s' but link failed.\n", new_pad_type);
- } else {
- g_print ("Link succeeded (type '%s').\n", new_pad_type);
- }
- ]#
- #[ exit:
- /* Unreference the new pad's caps, if we got them */
- if (new_pad_caps != NULL)
- gst_caps_unref (new_pad_caps);
- /* Unreference the sink pad */
- gst_object_unref (sink_pad); ]#
- proc toBoolVal(b: bool): Value =
- let gtype = typeFromName("gboolean")
- discard init(result, gtype)
- setBoolean(result, b)
- proc toUIntVal(i: int): Value =
- let gtype = typeFromName("guint")
- discard init(result, gtype)
- setUint(result, i)
- proc toStringVal(i: string): Value =
- let gtype = typeFromName("gchararray")
- discard init(result, gtype)
- setString(result, i)
- echo repr result
- converter toBin*(elem:gst.Element):gst.Bin =
- cast[gst.Bin](elem)
- proc main =
- var data:CustomData
- #GstBus *bus;
- #GstMessage *msg;
- #GstStateChangeReturn ret;
- #gboolean terminate = FALSE;
- ## Initialize GStreamer
- gst.init()
- # Create the elements
- data.source = make("uridecodebin", "source")
- data.convert = make("audioconvert", "convert")
- data.resample = make("audioresample", "resample")
- data.sink = make("autoaudiosink", "sink")
- # Create the empty pipeline
- data.pipeline = newPipeline("test-pipeline")
- # Check if the elements are empty
- if data.source.isNil or data.pipeline.isNil or data.convert.isNil or data.resample.isNil or data.sink.isNil:
- quit("Not all elements could be created.\n") # QuitFailure,
- # Build the pipeline
- # 1. Add the elements
- discard data.pipeline.add(data.source)
- discard data.pipeline.add(data.convert)
- discard data.pipeline.add(data.resample)
- discard data.pipeline.add(data.sink)
- # 2. Linking
- discard data.source.link(data.convert)
- discard data.convert.link(data.resample)
- discard data.resample.link(data.sink)
- #[
- /* Build the pipeline. Note that we are NOT linking the source at this
- * point. We will do it later. */
- gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.convert, data.resample, data.sink, NULL);
- if (!gst_element_link_many (data.convert, data.resample, data.sink, NULL)) {
- g_printerr ("Elements could not be linked.\n");
- gst_object_unref (data.pipeline);
- return -1;
- }
- ]#
- # Set the URI to play
- var uri = toStringVal("https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm")
- data.source.setProperty("uri", uri)
- # Connect to the pad-added signal
- #g_signal_connect (data.source, "pad-added", G_CALLBACK (pad_added_handler), &data);
- #var flag:ConnectFlag = 0
- #discard scPadAdded( data.source, padAddedHandler, cast[pointer](data.unsafeAddr), {0.ConnectFlag})
- # Start playing
- discard gst.setState(data.pipeline, gst.State.playing)
- ## Wait until error or EOS
- var bus:gst.Bus = gst.getBus(data.pipeline)
- var msg:gst.Message = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
- var tmp = msg.getType
- discard gst.setState(data.pipeline, gst.State.null) # is this necessary?
- #var msgFlag:MessageFlag = msg.getType
- var msgType = msg.getType
- #echo msg.impl.src.getName
- echo msg.getStructure.getName
- if gst.MessageFlag.error in msgType:
- var err:ptr glib.Error
- var debugInfo:string
- msg.parseError(err, debugInfo)
- #echo typeof(msg.src)
- echo &"Error received from element {gst_object_get_name(msg.impl.src)}: {err.message}"
- #echo cast[ptr gst.Object00](msg.impl).name
- if debugInfo == "":
- debugInfo = "none"
- echo &"Debugging information: {debugInfo}\n"
- #echo "Error received from element %s: %s", msg.src.name, err.message
- #[
- /* Listen to the bus */
- bus = gst_element_get_bus (data.pipeline);
- do {
- msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
- GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
- /* Parse message */
- if (msg != NULL) {
- GError *err;
- gchar *debug_info;
- switch (GST_MESSAGE_TYPE (msg)) {
- case GST_MESSAGE_ERROR:
- gst_message_parse_error (msg, &err, &debug_info);
- g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
- g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
- g_clear_error (&err);
- g_free (debug_info);
- terminate = TRUE;
- break;
- case GST_MESSAGE_EOS:
- g_print ("End-Of-Stream reached.\n");
- terminate = TRUE;
- break;
- case GST_MESSAGE_STATE_CHANGED:
- /* We are only interested in state-changed messages from the pipeline */
- if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data.pipeline)) {
- GstState old_state, new_state, pending_state;
- gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
- g_print ("Pipeline state changed from %s to %s:\n",
- gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
- }
- break;
- default:
- /* We should not reach here */
- g_printerr ("Unexpected message received.\n");
- break;
- }
- gst_message_unref (msg);
- }
- } while (!terminate);
- /* Free resources */
- gst_object_unref (bus);
- gst_element_set_state (data.pipeline, GST_STATE_NULL);
- gst_object_unref (data.pipeline);
- return 0;
- }
- ]#
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement