Advertisement
mantielero

Untitled

Jan 9th, 2022
2,156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Nim 7.45 KB | None | 0 0
  1. import gintro/[gst,gobject,glib], os, strformat
  2.  
  3. # Structure to contain all our information, so we can pass it to callbacks
  4. type
  5.   CustomData = object
  6.     pipeline, source, convert, resample, sink: gst.Element
  7.  
  8. #[
  9. typedef struct _CustomData {
  10.   GstElement *pipeline;
  11.   GstElement *source;
  12.   GstElement *convert;
  13.   GstElement *resample;
  14.   GstElement *sink;
  15. } CustomData;
  16. ]#
  17.  
  18. #[
  19. /* Handler for the pad-added signal */
  20. static void pad_added_handler (GstElement *src, GstPad *pad, CustomData *data);
  21. ]#
  22.  
  23.  
  24. #[ proc sourceName*(self: Message): string =
  25.   let resul0 = gst_object_get_name(cast[ptr Object00](self.impl.src))
  26.   if resul0.isNil:
  27.     return
  28.   result = $resul0
  29.   cogfree(resul0) ]#
  30.  
  31.  
  32. # This function will be called by the pad-added signal NOTA: cast[ptr Pad00](pad.impl)
  33. proc padAddedHandler(src:ptr Element00; newPad:ptr Pad00; dataPtr:pointer) {.cdecl.} =
  34.   var data = cast[CustomData](dataPtr)
  35.   #var sinkPad:gst.Pad = gst_element_get_static_pad(data.convert, "sink")
  36.   var sinkPad:gst.Pad = getRequestPad(data.convert, "sink")
  37.   #GstPadLinkReturn ret;
  38.   #GstCaps *new_pad_caps = NULL;
  39.   #GstStructure *new_pad_struct = NULL;
  40.   #const gchar *new_pad_type = NULL;
  41.   echo "New pad"
  42.   #echo("Received new pad '%s' from '%s':\n",  newPad.name,  src.name )  # GST_PAD_NAME, GST_ELEMENT_NAME
  43.  
  44.   #[ /* If our converter is already linked, we have nothing to do here */
  45.   if (gst_pad_is_linked (sink_pad)) {
  46.     g_print ("We are already linked. Ignoring.\n");
  47.     goto exit;
  48.   } ]#
  49.  
  50.  #[  /* Check the new pad's type */
  51.   new_pad_caps = gst_pad_get_current_caps (new_pad);
  52.   new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
  53.   new_pad_type = gst_structure_get_name (new_pad_struct);
  54.   if (!g_str_has_prefix (new_pad_type, "audio/x-raw")) {
  55.     g_print ("It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);
  56.     goto exit;
  57.   } ]#
  58.  
  59.  #[  /* Attempt the link */
  60.   ret = gst_pad_link (new_pad, sink_pad);
  61.   if (GST_PAD_LINK_FAILED (ret)) {
  62.     g_print ("Type is '%s' but link failed.\n", new_pad_type);
  63.   } else {
  64.     g_print ("Link succeeded (type '%s').\n", new_pad_type);
  65.   }
  66.  ]#
  67. #[ exit:
  68.   /* Unreference the new pad's caps, if we got them */
  69.   if (new_pad_caps != NULL)
  70.     gst_caps_unref (new_pad_caps);
  71.  
  72.   /* Unreference the sink pad */
  73.   gst_object_unref (sink_pad); ]#
  74.  
  75.  
  76.  
  77.  
  78. proc toBoolVal(b: bool): Value =
  79.   let gtype = typeFromName("gboolean")
  80.   discard init(result, gtype)
  81.   setBoolean(result, b)
  82.  
  83. proc toUIntVal(i: int): Value =
  84.   let gtype = typeFromName("guint")
  85.   discard init(result, gtype)
  86.   setUint(result, i)
  87.  
  88. proc toStringVal(i: string): Value =
  89.   let gtype = typeFromName("gchararray")
  90.   discard init(result, gtype)
  91.   setString(result, i)
  92.   echo repr result
  93.  
  94. converter toBin*(elem:gst.Element):gst.Bin =
  95.   cast[gst.Bin](elem)
  96.  
  97. proc main =
  98.   var data:CustomData
  99.   #GstBus *bus;
  100.   #GstMessage *msg;
  101.   #GstStateChangeReturn ret;
  102.   #gboolean terminate = FALSE;
  103.  
  104.   ##  Initialize GStreamer
  105.   gst.init()
  106.  
  107.   # Create the elements
  108.   data.source   = make("uridecodebin", "source")
  109.   data.convert  = make("audioconvert", "convert")
  110.   data.resample = make("audioresample", "resample")
  111.   data.sink     = make("autoaudiosink", "sink")
  112.  
  113.   # Create the empty pipeline
  114.   data.pipeline = newPipeline("test-pipeline")
  115.  
  116.   # Check if the elements are empty
  117.   if data.source.isNil or data.pipeline.isNil or data.convert.isNil or data.resample.isNil or data.sink.isNil:
  118.     quit("Not all elements could be created.\n") # QuitFailure,
  119.  
  120.   # Build the pipeline
  121.   # 1. Add the elements
  122.   discard data.pipeline.add(data.source)
  123.   discard data.pipeline.add(data.convert)
  124.   discard data.pipeline.add(data.resample)
  125.   discard data.pipeline.add(data.sink)
  126.  
  127.   # 2. Linking
  128.   discard data.source.link(data.convert)  
  129.   discard data.convert.link(data.resample)
  130.   discard data.resample.link(data.sink)
  131.  
  132.   #[
  133.   /* Build the pipeline. Note that we are NOT linking the source at this
  134.    * point. We will do it later. */
  135.   gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.convert, data.resample, data.sink, NULL);
  136.   if (!gst_element_link_many (data.convert, data.resample, data.sink, NULL)) {
  137.     g_printerr ("Elements could not be linked.\n");
  138.     gst_object_unref (data.pipeline);
  139.     return -1;
  140.   }
  141.   ]#
  142.  
  143.   # Set the URI to play
  144.   var uri = toStringVal("https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm")
  145.   data.source.setProperty("uri", uri)
  146.  
  147.   # Connect to the pad-added signal
  148.   #g_signal_connect (data.source, "pad-added", G_CALLBACK (pad_added_handler), &data);
  149.   #var flag:ConnectFlag = 0
  150.   #discard scPadAdded( data.source, padAddedHandler, cast[pointer](data.unsafeAddr), {0.ConnectFlag})
  151.  
  152.  
  153.   # Start playing
  154.   discard gst.setState(data.pipeline, gst.State.playing)
  155.  
  156.  
  157.   ##  Wait until error or EOS
  158.   var bus:gst.Bus     = gst.getBus(data.pipeline)
  159.   var msg:gst.Message = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
  160.   var tmp = msg.getType
  161.   discard gst.setState(data.pipeline, gst.State.null) # is this necessary?
  162.  
  163.   #var msgFlag:MessageFlag = msg.getType
  164.   var msgType = msg.getType
  165.   #echo msg.impl.src.getName
  166.   echo msg.getStructure.getName
  167.  
  168.   if gst.MessageFlag.error in msgType:
  169.     var err:ptr glib.Error
  170.     var debugInfo:string
  171.     msg.parseError(err, debugInfo)
  172.  
  173.     #echo typeof(msg.src)
  174.     echo &"Error received from element {gst_object_get_name(msg.impl.src)}: {err.message}"
  175.     #echo cast[ptr gst.Object00](msg.impl).name
  176.     if debugInfo == "":
  177.       debugInfo = "none"
  178.     echo &"Debugging information: {debugInfo}\n"
  179.     #echo "Error received from element %s: %s", msg.src.name, err.message
  180.  
  181. #[
  182.  
  183.  
  184.   /* Listen to the bus */
  185.   bus = gst_element_get_bus (data.pipeline);
  186.   do {
  187.     msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
  188.         GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
  189.  
  190.     /* Parse message */
  191.     if (msg != NULL) {
  192.       GError *err;
  193.       gchar *debug_info;
  194.  
  195.       switch (GST_MESSAGE_TYPE (msg)) {
  196.         case GST_MESSAGE_ERROR:
  197.           gst_message_parse_error (msg, &err, &debug_info);
  198.           g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
  199.           g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
  200.           g_clear_error (&err);
  201.           g_free (debug_info);
  202.           terminate = TRUE;
  203.           break;
  204.         case GST_MESSAGE_EOS:
  205.           g_print ("End-Of-Stream reached.\n");
  206.           terminate = TRUE;
  207.           break;
  208.         case GST_MESSAGE_STATE_CHANGED:
  209.           /* We are only interested in state-changed messages from the pipeline */
  210.           if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data.pipeline)) {
  211.             GstState old_state, new_state, pending_state;
  212.             gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
  213.             g_print ("Pipeline state changed from %s to %s:\n",
  214.                 gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
  215.           }
  216.           break;
  217.         default:
  218.           /* We should not reach here */
  219.           g_printerr ("Unexpected message received.\n");
  220.           break;
  221.       }
  222.       gst_message_unref (msg);
  223.     }
  224.   } while (!terminate);
  225.  
  226.   /* Free resources */
  227.   gst_object_unref (bus);
  228.   gst_element_set_state (data.pipeline, GST_STATE_NULL);
  229.   gst_object_unref (data.pipeline);
  230.   return 0;
  231. }
  232.  
  233.  
  234. ]#
  235. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement