<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 08/05/2012 06:29 AM, Brian Quandt
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAOLkBAmRorHYSWF9TcxDqqoEHhWC6=a6jjGzc736P6+SnkfN3Q@mail.gmail.com"
      type="cite">I'm still a bit new to the concepts of gstreamer from
      a coding perspective, but am trying to learn from within some
      python testing.<br>
      <br>
      My goal is to take the demo script "switch.py" and augment it to
      add a 3rd item to switch to after the pipeline has started (ie via
      interaction with the UI/user).  Think of having a user be able to
      enter a new streaming source to pull from to add to their list of
      items they can switch back and forth.<br>
      <br>
      Things work great when I'm using videotestsrc as my sources (ie if
      I change my attached code to use videotestsrc instead of
      uridecodebin's).   For clarity, if I make my dynmaically added
      uridecodebin a videotestsrc, this works without a problem.<br>
      <br>
      But if I set my user added src to be uridecodebin (as in the
      attached code) which is added to the pipeline after the startup of
      the pipeline, playback get's wonky, ie stuffer playback in 3rd
      uridecode, which also results in stuffer playback on my original
      items.<br>
      <br>
      I think this has something to do with clocking, which I'm still
      trying to comprehend how or what gstreamer wants to be done.<br>
    </blockquote>
    The problem is that the newly added branch does not have any
    context. There are various workarounds that you can find in e.g.
    gst-plugins-base/tests/examples/dynamic. But as you can see, you
    can't really atomically set the base-time. It might work a little
    better by sticking your elements into a bin, then you only need to
    do the { paused, set_base_time, play } on the bin.<br>
    <br>
    Stefan<br>
    <br>
    <br>
    <blockquote
cite="mid:CAOLkBAmRorHYSWF9TcxDqqoEHhWC6=a6jjGzc736P6+SnkfN3Q@mail.gmail.com"
      type="cite"><br>
      Attached below is the modified "switch.py" code<br>
      <br>
      -- Brian<br>
      <br>
      <br>
      <br>
      #!/usr/bin/env python<br>
      # -*- Mode: Python -*-<br>
      # vi:si:et:sw=4:sts=4:ts=4<br>
      <br>
      import pygtk<br>
      pygtk.require('2.0')<br>
      <br>
      import sys<br>
      <br>
      import gobject<br>
      gobject.threads_init()<br>
      <br>
      import pygst<br>
      pygst.require('0.10')<br>
      import gst<br>
      import gst.interfaces<br>
      import gtk<br>
      gtk.gdk.threads_init()<br>
      <br>
      class SwitchTest:<br>
          def __init__(self, videowidget):<br>
              self.playing = False<br>
              pipestr = ('uridecodebin uri=<a moz-do-not-send="true"
        href="http://localhost:8000/p1.ogg">http://localhost:8000/p1.ogg</a>
      ! queue ! s.sink0'<br>
                         ' videotestsrc name=blah ! queue ! s.sink1'<br>
                         ' input-selector sync-streams=true name=s !
      autovideosink ' )<br>
      #theoraenc quality=1 ! oggmux ! shout2send ip=localhost port=8000
      password=hackme mount=mytest.ogg ')<br>
              self.pipeline = gst.parse_launch(pipestr)<br>
              self.videowidget = videowidget<br>
      <br>
              bus = self.pipeline.get_bus()<br>
              bus.enable_sync_message_emission()<br>
              bus.add_signal_watch()<br>
              bus.connect('sync-message::element', self.on_sync_message)<br>
              bus.connect('message', self.on_message)<br>
      <br>
          def on_sync_message(self, bus, message):<br>
              if message.structure is None:<br>
                  return<br>
              if message.structure.get_name() == 'prepare-xwindow-id':<br>
                  # Sync with the X server before giving the X-id to the
      sink<br>
                  gtk.gdk.threads_enter()<br>
                  gtk.gdk.display_get_default().sync()<br>
                  self.videowidget.set_sink(message.src)<br>
                  message.src.set_property('force-aspect-ratio', True)<br>
                  gtk.gdk.threads_leave()<br>
                  <br>
          def on_message(self, bus, message):<br>
              t = message.type<br>
              if t == gst.MESSAGE_ERROR:<br>
                  err, debug = message.parse_error()<br>
                  print "Error: %s" % err, debug<br>
                  if self.on_eos:<br>
                      self.on_eos()<br>
                  self.playing = False<br>
              elif t == gst.MESSAGE_EOS:<br>
                  if self.on_eos:<br>
                      self.on_eos()<br>
                  self.playing = False<br>
      <br>
          def play(self):<br>
              self.playing = True<br>
              <a moz-do-not-send="true" href="http://gst.info">gst.info</a>("playing
      player")<br>
              self.pipeline.set_state(gst.STATE_PLAYING)<br>
              <br>
          def stop(self):<br>
              self.pipeline.set_state(gst.STATE_NULL)<br>
              <a moz-do-not-send="true" href="http://gst.info">gst.info</a>("stopped
      player")<br>
              self.playing = False<br>
      <br>
          def get_state(self, timeout=1):<br>
              return self.pipeline.get_state(timeout=timeout)<br>
      <br>
          def is_playing(self):<br>
              return self.playing<br>
          <br>
          def switch(self, padname):<br>
              switch = self.pipeline.get_by_name('s')<br>
              stop_time = switch.emit('block')<br>
              newpad = switch.get_static_pad(padname)<br>
              start_time = newpad.get_property('running-time')<br>
          <br>
              print stop_time<br>
              print start_time<br>
              <br>
              gst.warning('stop time = %d' % (stop_time,))<br>
              gst.warning('stop time = %s' %
      (gst.TIME_ARGS(stop_time),))<br>
      <br>
              gst.warning('start time = %d' % (start_time,))<br>
              gst.warning('start time = %s' %
      (gst.TIME_ARGS(start_time),))<br>
      <br>
              gst.warning('switching from %r to %r'<br>
                          % (switch.get_property('active-pad'),
      padname))<br>
              switch.emit('switch', newpad, stop_time, start_time)<br>
      <br>
      class VideoWidget(gtk.DrawingArea):<br>
          def __init__(self):<br>
              gtk.DrawingArea.__init__(self)<br>
              self.imagesink = None<br>
              self.unset_flags(gtk.DOUBLE_BUFFERED)<br>
      <br>
          def do_expose_event(self, event):<br>
              if self.imagesink:<br>
                  self.imagesink.expose()<br>
                  return False<br>
              else:<br>
                  return True<br>
      <br>
          def set_sink(self, sink):<br>
              assert self.window.xid<br>
              self.imagesink = sink<br>
              self.imagesink.set_xwindow_id(self.window.xid)<br>
      <br>
      class SwitchWindow(gtk.Window):<br>
          UPDATE_INTERVAL = 500<br>
          def __init__(self):<br>
              gtk.Window.__init__(self)<br>
              self.set_default_size(410, 325)<br>
      <br>
              self.create_ui()<br>
              self.player = SwitchTest(self.videowidget)<br>
              self.populate_combobox()<br>
      <br>
              self.update_id = -1<br>
              self.changed_id = -1<br>
              self.seek_timeout_id = -1<br>
      <br>
              self.p_position = gst.CLOCK_TIME_NONE<br>
              self.p_duration = gst.CLOCK_TIME_NONE<br>
      <br>
              def on_delete_event():<br>
                  self.player.stop()<br>
                  gtk.main_quit()<br>
              self.connect('delete-event', lambda *x: on_delete_event())<br>
      <br>
          def load_file(self, location):<br>
              self.player.set_location(location)<br>
                                        <br>
          def play(self):<br>
              self.player.play()<br>
              <br>
          def populate_combobox(self):<br>
              switch = self.player.pipeline.get_by_name('s')<br>
              for i, pad in enumerate([p for p in switch.pads()<br>
                                       if p.get_direction() ==
      gst.PAD_SINK]):<br>
                  self.combobox.append_text(pad.get_name())<br>
                  if switch.get_property('active-pad') ==
      pad.get_name():<br>
                      self.combobox.set_active(i)<br>
              if self.combobox.get_active() == -1:<br>
                  self.combobox.set_active(0)<br>
      <br>
          def combobox_changed(self):<br>
              model = self.combobox.get_model()<br>
              row = model[self.combobox.get_active()]<br>
              padname, = row<br>
              self.player.switch(padname)<br>
      <br>
          def onPad(self,element, pad,target):<br>
              #sinkpad = target.get_compatible_pad(pad, pad.get_caps())<br>
              #print sinkpad<br>
              #pad.link(sinkpad)<br>
              caps = pad.get_caps()<br>
              name = caps[0].get_name()<br>
              #for now only like the video pad from uridecode<br>
              if name == 'video/x-raw-yuv':<br>
                  tpad = target.get_pad('sink')<br>
                  if not tpad.is_linked():<br>
                      pad.link(tpad)<br>
                      print 'on_pad_added:', name<br>
      <br>
              return True<br>
      <br>
          def enter_callback(self, widget, entry):<br>
      <br>
      <br>
              myuri = gst.element_factory_make("uridecodebin")<br>
              myuri.set_property("uri","<a moz-do-not-send="true"
        href="http://localhost:8000/p2.ogg">http://localhost:8000/p2.ogg</a>")<br>
              myuri.set_property("name","xyz")<br>
      <br>
              myq = gst.element_factory_make("queue")<br>
              #myq.set_property("leaky","upstream")<br>
      <br>
              self.player.pipeline.add(myuri,myq)<br>
      <br>
              #link stuff up<br>
              myuri.connect("pad-added",self.onPad,myq) <br>
      <br>
              # get the element in the bin who's name is 's', ie
      input-selector<br>
              # then get the src pad on the queue element and use the
      below code<br>
              # to connect stuff<br>
              inputselectorelement =
      self.player.pipeline.get_by_name('s')<br>
              myq.link(inputselectorelement)<br>
              self.populate_combobox()<br>
      <br>
              myuri.set_state(gst.STATE_READY)<br>
              myq.set_state(gst.STATE_READY)<br>
              <br>
              #For whatever reason when I hook this thing in, it plays
      weird, and throws<br>
              # off tons of QOS dropped frames<br>
              # guessing something with the element system clocks.   for
      some reason<br>
              # when I add things to an active pipeline, they get their
      base_time set<br>
              # to what the others are, and not when these new ones
      really started<br>
              # so this is an attempt to address that, assuming this is
      the real problem<br>
              print "clock testing"<br>
              myclk = myuri.get_clock()<br>
              print myclk.get_time()<br>
              print myuri.get_base_time()<br>
              print myclk.get_time() - myuri.get_base_time()<br>
              xxx= myclk.get_time()<br>
              myuri.set_base_time(xxx)<br>
              myq.set_base_time(xxx)<br>
      <br>
              myuri.set_state(gst.STATE_PLAYING)<br>
              myq.set_state(gst.STATE_PLAYING)<br>
      <br>
              print "clock checks"<br>
              print 'videotestsrc base time'<br>
              tel = self.player.pipeline.get_by_name('blah')<br>
              print tel.get_base_time()<br>
              print "myuri"<br>
              print myuri.get_base_time()<br>
              print "myq"<br>
              print myq.get_base_time()<br>
      <br>
              #myqpadsrc = myq.get_pad('src')<br>
              #ipadsink = inputselectorelement.get_pad('sink')<br>
             
      #inputselectorelement.link_pads(myqpadsrc,inputselectorelement,ipadsink)<br>
      <br>
      <br>
              entry_text = entry.get_text()<br>
              print "Entry contents: %s\n" % entry_text<br>
      <br>
          def create_ui(self):<br>
              vbox = gtk.VBox()<br>
              self.add(vbox)<br>
      <br>
              self.videowidget = VideoWidget()<br>
              vbox.pack_start(self.videowidget)<br>
              <br>
              hbox = gtk.HBox()<br>
              vbox.pack_start(hbox, fill=False, expand=False)<br>
              <br>
              self.combobox = combobox = gtk.combo_box_new_text()<br>
              combobox.show()<br>
              hbox.pack_start(combobox)<br>
      <br>
              self.combobox.connect('changed',<br>
                                    lambda *x: self.combobox_changed())<br>
      <br>
              self.videowidget.connect_after('realize',<br>
                                             lambda *x: self.play())<br>
              entry = gtk.Entry()<br>
              entry.set_max_length(50)<br>
              entry.connect("activate", self.enter_callback, entry)<br>
              entry.set_text("hello")<br>
              entry.insert_text(" world", len(entry.get_text()))<br>
              entry.select_region(0, len(entry.get_text()))<br>
              hbox.pack_start(entry)<br>
              entry.show()<br>
      <br>
      def main(args):<br>
          def usage():<br>
              sys.stderr.write("usage: %s\n" % args[0])<br>
              return 1<br>
      <br>
          # Need to register our derived widget types for implicit event<br>
          # handlers to get called.<br>
          gobject.type_register(SwitchWindow)<br>
          gobject.type_register(VideoWidget)<br>
      <br>
          if len(args) != 1:<br>
              return usage()<br>
      <br>
          w = SwitchWindow()<br>
          w.show_all()<br>
          gtk.main()<br>
          return 0<br>
      <br>
      if __name__ == '__main__':<br>
          sys.exit(main(sys.argv))<br>
      <br>
      <br>
      <br>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
gstreamer-devel mailing list
<a class="moz-txt-link-abbreviated" href="mailto:gstreamer-devel@lists.freedesktop.org">gstreamer-devel@lists.freedesktop.org</a>
<a class="moz-txt-link-freetext" href="http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel">http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>