pitivi r1240 - in branches/SOC_2008_BLEWIS: . pitivi/elements
- From: edwardrv svn gnome org
- To: svn-commits-list gnome org
- Subject: pitivi r1240 - in branches/SOC_2008_BLEWIS: . pitivi/elements
- Date: Mon, 25 Aug 2008 16:41:03 +0000 (UTC)
Author: edwardrv
Date: Mon Aug 25 16:41:03 2008
New Revision: 1240
URL: http://svn.gnome.org/viewvc/pitivi?rev=1240&view=rev
Log:
* pitivi/elements/imagefreeze.py:
Rewrite imagefreeze seeking/output.
Now uses a gst.Task for outputting and proper seeking handling.
Modified:
branches/SOC_2008_BLEWIS/ChangeLog
branches/SOC_2008_BLEWIS/pitivi/elements/imagefreeze.py
Modified: branches/SOC_2008_BLEWIS/pitivi/elements/imagefreeze.py
==============================================================================
--- branches/SOC_2008_BLEWIS/pitivi/elements/imagefreeze.py (original)
+++ branches/SOC_2008_BLEWIS/pitivi/elements/imagefreeze.py Mon Aug 25 16:41:03 2008
@@ -85,6 +85,10 @@
self._segment.init(gst.FORMAT_TIME)
self._needsegment = True
self._bufferduration = 0
+ # this is the buffer we store and repeatedly output
+ self._buffer = None
+ # this will be set by our task
+ self.last_return = gst.FLOW_OK
def _sink_setcaps(self, pad, caps):
gst.debug("caps %s" % caps.to_string())
@@ -130,15 +134,26 @@
if event.type == gst.EVENT_SEEK:
rate,fmt,flags,startt,start,stopt,stop = event.parse_seek()
gst.debug("Handling seek event %r" % flags)
+ if flags & gst.SEEK_FLAG_FLUSH:
+ gst.debug("sending flush_start event")
+ self.srcpad.push_event(gst.event_new_flush_start())
self._segment.set_seek(*event.parse_seek())
gst.debug("_segment start:%s stop:%s" % (gst.TIME_ARGS(self._segment.start),
gst.TIME_ARGS(self._segment.stop)))
# create a new initial seek
- self._needsegment = True
+ gst.debug("pausing task")
+ self.srcpad.pause_task()
+ gst.debug("task paused")
seek = gst.event_new_seek(1.0, gst.FORMAT_TIME, flags,
gst.SEEK_TYPE_NONE, 0,
gst.SEEK_TYPE_NONE, 0)
- return self.sinkpad.push_event(seek)
+ #return self.sinkpad.push_event(seek)
+ self._needsegment = True
+ if flags & gst.SEEK_FLAG_FLUSH:
+ self.srcpad.push_event(gst.event_new_flush_stop())
+ self.srcpad.start_task(self.our_task)
+ return True
+
return self.sinkpad.push_event(event)
def _sink_event(self, pad, event):
@@ -153,53 +168,63 @@
def _sink_chain(self, pad, buffer):
gst.debug("buffer %s %s" % (gst.TIME_ARGS(buffer.timestamp),
gst.TIME_ARGS(buffer.duration)))
- res = gst.FLOW_OK
-
- # and now we go in a glorious loop :)
- while res == gst.FLOW_OK:
- gst.debug("needsegment: %r" % self._needsegment)
-
- if self._needsegment:
- gst.debug("Need to output a new segment")
- segment = gst.event_new_new_segment(False,
- self._segment.rate,
- self._segment.format,
- self._segment.start,
- self._segment.stop,
- self._segment.start)
- self.srcpad.push_event(segment)
- # calculate offset
- # offset is int(segment.start / outputrate)
- self._offset = int(self._segment.start * self._outputrate.num / self._outputrate.denom / gst.SECOND)
- self._needsegment = False
-
- # new position
- position = self._offset * gst.SECOND * self._outputrate.denom / self._outputrate.num
- if self._segment.stop != -1 and position > self._segment.stop:
- gst.debug("end of configured segment (position:%s / segment_stop:%s)" % (gst.TIME_ARGS(position),
- gst.TIME_ARGS(self._segment.stop)))
- # end of stream/segment handling
- if self._segment.flags & gst.SEEK_FLAG_SEGMENT:
- # emit a gst.MESSAGE_SEGMENT_DONE
- self.post_message(gst.message_new_segment_done(self, gst.FORMAT_TIME, self._segment.stop))
- else:
- self.srcpad.push_event(gst.event_new_eos())
- res = gst.FLOW_WRONG_STATE
- break
-
- # we need to update the caps here !
- obuf = buffer.make_metadata_writable()
- ok, nstart, nstop = self._segment.clip(gst.FORMAT_TIME,
- position, position + self._bufferduration)
- if ok:
- obuf.timestamp = nstart
- obuf.duration = nstop - nstart
- obuf.caps = self._srccaps
- gst.debug("Pushing out buffer %s" % gst.TIME_ARGS(obuf.timestamp))
- res = self.srcpad.push(obuf)
- self._offset += 1
-
- return res
+ if self._buffer != None:
+ gst.debug("already have a buffer ! Returning GST_FLOW_WRONG_STATE")
+ return gst.FLOW_WRONG_STATE
+
+ self._buffer = buffer
+ self.srcpad.start_task(self.our_task)
+ return gst.FLOW_WRONG_STATE
+
+ def our_task(self, something):
+ #this is where we repeatedly output our buffer
+ gst.debug("self:%r, something:%r" % (self, something))
+
+ gst.debug("needsegment: %r" % self._needsegment)
+ if self._needsegment:
+ gst.debug("Need to output a new segment")
+ segment = gst.event_new_new_segment(False,
+ self._segment.rate,
+ self._segment.format,
+ self._segment.start,
+ self._segment.stop,
+ self._segment.start)
+ self.srcpad.push_event(segment)
+ # calculate offset
+ # offset is int(segment.start / outputrate)
+ self._offset = int(self._segment.start * self._outputrate.num / self._outputrate.denom / gst.SECOND)
+ self._needsegment = False
+ gst.debug("Newsegment event pushed")
+
+ # new position
+ position = self._offset * gst.SECOND * self._outputrate.denom / self._outputrate.num
+ if self._segment.stop != -1 and position > self._segment.stop:
+ gst.debug("end of configured segment (position:%s / segment_stop:%s)" % (gst.TIME_ARGS(position),
+ gst.TIME_ARGS(self._segment.stop)))
+ # end of stream/segment handling
+ if self._segment.flags & gst.SEEK_FLAG_SEGMENT:
+ # emit a gst.MESSAGE_SEGMENT_DONE
+ self.post_message(gst.message_new_segment_done(self, gst.FORMAT_TIME, self._segment.stop))
+ else:
+ self.srcpad.push_event(gst.event_new_eos())
+ self.last_return = gst.FLOW_WRONG_STATE
+ self.srcpad.pause_task()
+
+ # we need to update the caps here !
+ obuf = self._buffer.make_metadata_writable()
+ ok, nstart, nstop = self._segment.clip(gst.FORMAT_TIME,
+ position, position + self._bufferduration)
+ if ok:
+ obuf.timestamp = nstart
+ obuf.duration = nstop - nstart
+ obuf.caps = self._srccaps
+ gst.debug("Pushing out buffer %s" % gst.TIME_ARGS(obuf.timestamp))
+ self.last_return = self.srcpad.push(obuf)
+ self._offset += 1
+
+ if self.last_return != gst.FLOW_OK:
+ gst.debug("Pausing ourself, last_return : %s" % gst.flow_get_name(self.last_return))
+ self.srcpad.pause_task()
def do_change_state(self, transition):
if transition in [gst.STATE_CHANGE_READY_TO_PAUSED, gst.STATE_CHANGE_PAUSED_TO_READY]:
@@ -207,3 +232,67 @@
return gst.Element.do_change_state(self, transition)
gobject.type_register(ImageFreeze)
+
+def dataprobe(pad, data):
+ if isinstance(data, gst.Buffer):
+ print "Buffer", gst.TIME_ARGS(data.timestamp), gst.TIME_ARGS(data.duration), data.caps.to_string()
+ else:
+ print "Event", data.type
+ if data.type == gst.EVENT_NEWSEGMENT:
+ print data.parse_new_segment()
+ return True
+
+def make_image_video_bin(location):
+ b = gst.Bin("image-video-bin-"+location)
+ src = gst.element_factory_make("filesrc")
+ src.props.location = location
+ src.props.blocksize = 1024 * 1024
+ dec = gst.element_factory_make("jpegdec")
+ vscale = gst.element_factory_make("videoscale")
+ freeze = ImageFreeze()
+ cfil = gst.element_factory_make("capsfilter")
+ cfil.props.caps = gst.Caps("video/x-raw-yuv,framerate=25/1")
+ p.add(src, dec, vscale, freeze, cfil)
+ gst.element_link_many(src, dec, vscale)
+ vscale.link(freeze, gst.Caps("video/x-raw-yuv,width=640,height=480"))
+ gst.element_link_many(freeze, cfil)
+
+ b.add_pad(gst.GhostPad("src", cfil.get_pad("src")))
+
+ return b
+
+def post_link(gnls, pad, q):
+ gnls.link(q)
+
+# filesrc ! jpegdec ! imagefreeze ! xvimagesink
+if __name__ == "__main__":
+ import sys
+ p = gst.Pipeline()
+
+ b = make_image_video_bin(sys.argv[1])
+ gnls = gst.element_factory_make("gnlsource")
+ gnls.add(b)
+
+ gnls.props.media_start = 5 * gst.SECOND
+ gnls.props.media_duration = 5 * gst.SECOND
+ gnls.props.duration = 5 * gst.SECOND
+
+ toverl = gst.element_factory_make("timeoverlay")
+ sink = gst.element_factory_make("xvimagesink")
+ sink.get_pad("sink").add_data_probe(dataprobe)
+
+ q = gst.element_factory_make("queue")
+
+ p.add(gnls, toverl, q, sink)
+
+ gst.element_link_many(q, toverl, sink)
+ #q.link(sink)
+
+ gnls.connect("pad-added", post_link, q)
+
+ ml = gobject.MainLoop()
+
+ p.set_state(gst.STATE_PLAYING)
+
+ ml.run()
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]