diff --git a/oxgst/imagesink.py b/oxgst/imagesink.py index 5040725..0a676d7 100644 --- a/oxgst/imagesink.py +++ b/oxgst/imagesink.py @@ -10,11 +10,13 @@ import gst import Image class ImageSink(gst.BaseSink): + #def log(self, msg): + # print msg __gsignals__ = { "frame" : (gobject.SIGNAL_RUN_LAST, - gobject.TYPE_NONE, - ( gobject.TYPE_PYOBJECT, gobject.TYPE_UINT64 )) + gobject.TYPE_NONE, + ( gobject.TYPE_PYOBJECT, gobject.TYPE_UINT64 )) } __gsttemplates__ = ( diff --git a/oxgst/video.py b/oxgst/video.py index cc8b753..86e2575 100644 --- a/oxgst/video.py +++ b/oxgst/video.py @@ -16,12 +16,15 @@ from singledecodebin import SingleDecodeBin from imagesink import ImageSink class Video(gst.Pipeline): + #def log(self, msg): + # print msg def __init__(self, uri, framerate='25/1'): gst.Pipeline.__init__(self) + self.framerate = framerate self.duration = -1 # queue of timestamps - self.queue = [] + self._queue = [] # queue callbacks self.callback = {} # extracted frames @@ -29,6 +32,7 @@ class Video(gst.Pipeline): # true only if we are prerolled self._ready = False + uri = 'file://' + uri self.log("uri : %s" % uri) @@ -37,19 +41,17 @@ class Video(gst.Pipeline): self.sbin = SingleDecodeBin(caps=gst.Caps("video/x-raw-rgb;video/x-raw-yuv"), uri=self.uri) self.csp = gst.element_factory_make("ffmpegcolorspace") + self.scale = gst.element_factory_make("videoscale") self.rate = gst.element_factory_make("videorate") self.queue = gst.element_factory_make("queue") self.sink = ImageSink() self.sink.connect('frame', self._frameCb) - self.add(self.sbin, self.csp, self.queue, self.rate, self.sink) - - self.queue.link(self.rate) - self.rate.link(self.csp, gst.Caps("video/x-raw-yuv,framerate=%s"%framerate)) - self.csp.link(self.sink) + self.add(self.sbin, self.csp, self.queue, self.scale, self.rate, self.sink) self.sbin.connect('pad-added', self._sbinPadAddedCb) + self.set_state(gst.STATE_PAUSED) self.get_state() self.width = self.sink.width @@ -61,6 +63,20 @@ class Video(gst.Pipeline): def _sbinPadAddedCb(self, unused_sbin, pad): self.log("pad : %s" % pad) pad.link(self.queue.get_pad("sink")) + caps = pad.get_caps() + width = caps[0]["width"] + height = caps[0]["height"] + + if width % 4: + width += 4 - width % 4 + if height % 4: + height += 4 - height % 4 + + self.queue.link(self.scale) + self.scale.link(self.rate) + self.rate.link(self.csp, gst.Caps("video/x-raw-rgb;video/x-raw-yuv,framerate=%s,width=%s,height=%s" % (self.framerate, width, height))) + self.csp.link(self.sink) + def _frameCb(self, unused_thsink, frame, timestamp): self.log("image:%s, timestamp:%s" % (frame, gst.TIME_ARGS(timestamp))) @@ -72,12 +88,12 @@ class Video(gst.Pipeline): self.callback[timestamp](frame, timestamp) del self.callback[timestamp] - if timestamp in self.queue: - self.queue.remove(timestamp) + if timestamp in self._queue: + self._queue.remove(timestamp) - if self.queue: + if self._queue: # still some more thumbnails to process - gobject.idle_add(self._getFrame, self.queue.pop(0)) + gobject.idle_add(self._getFrame, self._queue.pop(0)) def getDuration(self): if self.duration < 0: @@ -105,12 +121,12 @@ class Video(gst.Pipeline): self.callback[timestamp] = callback - if self.queue or not self._ready: + if self._queue or not self._ready: self.log('ready') - self.queue.append(timestamp) + self._queue.append(timestamp) else: - self.queue.append(timestamp) + self._queue.append(timestamp) self._getFrame(timestamp) return True