text: import sys
  import cv2
  import gi
  
  gi.require_version("Gst", "1.0")
  from gi.repository import Gst
  
  
  def cb_newpad(decodebin, decoder_src_pad, data):
      print("In cb_newpad\n")
      caps = decoder_src_pad.get_current_caps()
      gststruct = caps.get_structure(0)
      gstname = gststruct.get_name()
      source_bin = data
      features = caps.get_features(0)
  
      # Need to check if the pad created by the decodebin is for video and not
      # audio.
      print("gstname=", gstname)
      if gstname.find("video") != -1:
          # Link the decodebin pad only if decodebin has picked nvidia
          # decoder plugin nvdec_*. We do this by checking if the pad caps contain
          # NVMM memory features.
          print("features=", features)
          if features.contains("memory:NVMM"):
              # Get the source bin ghost pad
              bin_ghost_pad = source_bin.get_static_pad("src")
              if not bin_ghost_pad.set_target(decoder_src_pad):
                  sys.stderr.write(
                      "Failed to link decoder src pad to source bin ghost pad\n"
                  )
          else:
              sys.stderr.write(" Error: Decodebin did not pick nvidia decoder plugin.\n")
  
  
  def decodebin_child_added(child_proxy, Object, name, user_data):
      print("Decodebin child added:", name, "\n")
      if name.find("decodebin") != -1:
          Object.connect("child-added", decodebin_child_added, user_data)
  
  
  def create_source_bin(index, uri):
      print("Creating source bin")
  
      # Create a source GstBin to abstract this bin's content from the rest of the
      # pipeline
      bin_name = "source-bin-%02d" % index
      print(bin_name)
      nbin = Gst.Bin.new(bin_name)
      if not nbin:
          sys.stderr.write(" Unable to create source bin \n")
  
      # Source element for reading from the uri.
      # We will use decodebin and let it figure out the container format of the
      # stream and the codec and plug the appropriate demux and decode plugins.
      uri_decode_bin = Gst.ElementFactory.make("uridecodebin", "uri-decode-bin")
      if not uri_decode_bin:
          sys.stderr.write(" Unable to create uri decode bin \n")
      # We set the input uri to the source element
      uri_decode_bin.set_property("uri", uri)
      # Connect to the "pad-added" signal of the decodebin which generates a
      # callback once a new pad for raw data has beed created by the decodebin
      uri_decode_bin.connect("pad-added", cb_newpad, nbin)
      uri_decode_bin.connect("child-added", decodebin_child_added, nbin)
  
      # We need to create a ghost pad for the source bin which will act as a proxy
      # for the video decoder src pad. The ghost pad will not have a target right
      # now. Once the decode bin creates the video decoder and generates the
      # cb_newpad callback, we will set the ghost pad target to the video decoder
      # src pad.
      Gst.Bin.add(nbin, uri_decode_bin)
      bin_pad = nbin.add_pad(Gst.GhostPad.new_no_target("src", Gst.PadDirection.SRC))
      if not bin_pad:
          sys.stderr.write(" Failed to add ghost pad in source bin \n")
          return None
      return nbin
  
  
  def get_video_info(video_path):
  
      cap = cv2.VideoCapture(video_path)
      frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
      width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
      height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
      fps = int(cap.get(cv2.CAP_PROP_FPS))
      cap.release()
  
      return {"frame_count": frame_count, "width": width, "height": height, "fps": fps}