[jokosher-devel] Query position on pipelines



I updated my gstreamer CVS the other day and since then the playhead
indicator does not seem to behave itself after doing a seek. Now I think that
it's gst.Element.query_position() that's changed. Can someone else please
check this out in the attached script to prove it's not me or my machine?
You need to change the filename on line 98 to something on your machine and
then run it twice:

 first time: 
   $ ./seek_test.py # uses the standard dapper gst
 and then:
   $ gst-head ./seek_test.py # uses the CVS gst
 
Press <Play> and then <Seek> a few times. <Seek> will seek to 3 secs and
then about a second later will do a query_position() on the pipeline and
prints the output. On my machine the first one always gives about 1 second
(the time since the last seek) which is what Jokosher currently expects.
Since I recompiled gst CVS on friday the second gives about 4secs (the
*actual* position) which throws Jokosher a bit.

If it's not me then we could maybe chase the gst guys a bit and see if
they've cleared a bug or created one.

-- 
John Green
#!/usr/bin/python
import pygst
pygst.require("0.10")
import gst
import pygtk
import gtk
import gtk.glade
import time
import gobject

class Instrument:
	def __init__(self, project, filename, insnum):

		self.project = project

		gst.debug("Adding an instrument gnlcomposition")
		self.comp = gst.element_factory_make("gnlcomposition", "mycomposition" + str(insnum))
		self.comp.connect("pad-added", self.project.OnPad, self)

		self.compconvert = gst.element_factory_make("audioconvert", "compconvert" + str(insnum))
		self.project.pipeline.add(self.compconvert)

		self.silenceaudio = gst.element_factory_make("audiotestsrc")
		self.silenceaudio.set_property("volume", 0.0)
		
		self.silencesource = gst.element_factory_make("gnlsource")
		self.silencesource.set_property("priority", 1000)
		self.silencesource.set_property("start", 0)
		self.silencesource.set_property("duration", 100 * gst.SECOND)
		self.silencesource.set_property("media-start", 0)
		self.silencesource.set_property("media-duration", 100 * gst.SECOND)
		self.silencesource.add(self.silenceaudio)
		self.comp.add(self.silencesource)

		
		gst.debug("Adding first gnlfilesource")
		self.audio1 = gst.element_factory_make("gnlfilesource", "audio" + str(insnum))
		self.audio1.set_property("location", filename)
		self.audio1.set_property("start", 0 * gst.SECOND)
		self.audio1.set_property("duration", 12 * gst.SECOND)
		self.audio1.set_property("media-start", 0)
		self.audio1.set_property("media-duration", 12 * gst.SECOND)

		self.comp.add(self.audio1)


		self.project.pipeline.add(self.comp)

		self.volume = gst.element_factory_make("volume", "volume" + str(insnum))
		self.project.pipeline.add(self.volume)

		self.level = gst.element_factory_make("level", "level" + str(insnum))
		self.project.pipeline.add(self.level)
		gst.debug("Adding an instrument audioconvert")
		self.convert = gst.element_factory_make("audioconvert", "convert" + str(insnum))
		self.project.pipeline.add(self.convert)
		self.resample = gst.element_factory_make("audioresample", "resample" + str(insnum))
		self.project.pipeline.add(self.resample)
			
		self.compconvert.link(self.volume)
		self.volume.link(self.level)
		self.level.link(self.convert)
		self.convert.link(self.resample)
		self.resample.link(self.project.masteradder)

class Project:
	def __init__(self):
		print "Running class"

		instruments = []

		self.pipeline = gst.Pipeline("mixer")

		self.bus = self.pipeline.get_bus()
		self.bus.add_signal_watch()
		self.bus.connect("message::error", self.BusMessage)

		gst.debug("Adding master adder")
		self.masteradder = gst.element_factory_make("adder", "masteradder")
		self.pipeline.add(self.masteradder)

		gst.debug("Adding alsasink")

		self.out = gst.element_factory_make("alsasink", "out")
		self.out.set_property("device", "default")
		self.pipeline.add(self.out)

		gst.debug("Linking masteradder to alsasink")

		# need to restrict the format on adder's output
		caps = gst.caps_from_string ("audio/x-raw-int,"
		    "rate=44100,channels=2,endianness=1234,width=16,depth=16,signed=(boolean)true")

		self.masteradder.link(self.out, caps)

		# change the file names to something on your computer
		
		self.ins1 = Instrument(self, "/home/john/code/jokosher_tests/audio/one.wav", 1)

	def OnPad(self, comp, pad, instrument):
		print "pad added!"
		gst.debug("Pad added")
		convpad = instrument.compconvert.get_compatible_pad(pad, pad.get_caps())
		pad.link(convpad)

	def Play(self):
		self.pipeline.set_state(gst.STATE_PLAYING)
		#print self.pipeline.get_state(0)

	def Stop(self):
		self.pipeline.set_state(gst.STATE_NULL)
		#print self.pipeline.get_state(0)
		
	def Seek(self):
		print "seeking to 3 seconds"
		r=self.pipeline.seek( 1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH,
					gst.SEEK_TYPE_SET, long(3 * gst.SECOND), 
					gst.SEEK_TYPE_NONE, -1)
		if r:
			print "seek success"
		else:
			print ">>> seek failed <<<"
		gobject.timeout_add(1000, self.ReportPos)
		
	def ReportPos(self):
		print "reported position 1 second after seek",float(self.pipeline.query_position(gst.FORMAT_TIME)[0]) / gst.SECOND
		
	def BusMessage(self, bus, message):
		st = message.structure
		error, debug = message.parse_error()
		print "!!!! bus message error: " + str(error)
		print "!!!! bus message debug: " + str(debug)
class Main:
	def __init__(self):
		self.project = Project()

		self.wTree = gtk.glade.XML("gui.glade", "mainwindow")
		
		signals = {
			"on_play_clicked" : self.OnPlay,
			"on_stop_clicked" : self.OnStop,
			"on_quit_clicked" : self.OnQuit,
			"on_seek_clicked" : self.OnSeek,
		}

		self.wTree.signal_autoconnect(signals)

		self.window = self.wTree.get_widget("mainwindow")
		self.window.show_all()

	def OnPlay(self, widget):
		print "play"
		self.project.Play()

	def OnStop(self, widget):
		print "stop"
		self.project.Stop()

	def OnQuit(self, widget):
		gtk.main_quit()
	
	def OnSeek(self, widget):
		print "seek"
		self.project.Seek()

start=Main()
gtk.main()
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>

<glade-interface>

<widget class="GtkWindow" id="mainwindow">
  <property name="visible">True</property>
  <property name="title" translatable="yes">window1</property>
  <property name="type">GTK_WINDOW_TOPLEVEL</property>
  <property name="window_position">GTK_WIN_POS_NONE</property>
  <property name="modal">False</property>
  <property name="resizable">True</property>
  <property name="destroy_with_parent">False</property>
  <property name="decorated">True</property>
  <property name="skip_taskbar_hint">False</property>
  <property name="skip_pager_hint">False</property>
  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
  <property name="focus_on_map">True</property>
  <property name="urgency_hint">False</property>

  <child>
    <widget class="GtkHButtonBox" id="hbuttonbox1">
      <property name="visible">True</property>
      <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
      <property name="spacing">0</property>

      <child>
	<widget class="GtkButton" id="button1">
	  <property name="visible">True</property>
	  <property name="can_default">True</property>
	  <property name="can_focus">True</property>
	  <property name="label">gtk-media-play</property>
	  <property name="use_stock">True</property>
	  <property name="relief">GTK_RELIEF_NORMAL</property>
	  <property name="focus_on_click">True</property>
	  <signal name="clicked" handler="on_play_clicked" last_modification_time="Sat, 20 May 2006 22:35:59 GMT"/>
	</widget>
      </child>

      <child>
	<widget class="GtkButton" id="button2">
	  <property name="visible">True</property>
	  <property name="can_default">True</property>
	  <property name="can_focus">True</property>
	  <property name="label">gtk-media-stop</property>
	  <property name="use_stock">True</property>
	  <property name="relief">GTK_RELIEF_NORMAL</property>
	  <property name="focus_on_click">True</property>
	  <signal name="clicked" handler="on_stop_clicked" last_modification_time="Sat, 20 May 2006 22:36:08 GMT"/>
	</widget>
      </child>

      <child>
	<widget class="GtkButton" id="button3">
	  <property name="visible">True</property>
	  <property name="can_default">True</property>
	  <property name="can_focus">True</property>
	  <property name="label">gtk-quit</property>
	  <property name="use_stock">True</property>
	  <property name="relief">GTK_RELIEF_NORMAL</property>
	  <property name="focus_on_click">True</property>
	  <signal name="clicked" handler="on_quit_clicked" last_modification_time="Sat, 20 May 2006 22:36:21 GMT"/>
	</widget>
      </child>

      <child>
	<widget class="GtkButton" id="button4">
	  <property name="visible">True</property>
	  <property name="can_default">True</property>
	  <property name="can_focus">True</property>
	  <property name="label" translatable="yes">Seek</property>
	  <property name="use_underline">True</property>
	  <property name="relief">GTK_RELIEF_NORMAL</property>
	  <property name="focus_on_click">True</property>
	  <signal name="clicked" handler="on_seek_clicked" last_modification_time="Mon, 18 Sep 2006 00:29:26 GMT"/>
	</widget>
      </child>
    </widget>
  </child>
</widget>

</glade-interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]