something breaks if video width/height is not multiple of 4
This commit is contained in:
parent
9d7e6ecdac
commit
3c73ffe9e0
2 changed files with 33 additions and 15 deletions
|
@ -10,6 +10,8 @@ import gst
|
||||||
import Image
|
import Image
|
||||||
|
|
||||||
class ImageSink(gst.BaseSink):
|
class ImageSink(gst.BaseSink):
|
||||||
|
#def log(self, msg):
|
||||||
|
# print msg
|
||||||
|
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
"frame" : (gobject.SIGNAL_RUN_LAST,
|
"frame" : (gobject.SIGNAL_RUN_LAST,
|
||||||
|
|
|
@ -16,12 +16,15 @@ from singledecodebin import SingleDecodeBin
|
||||||
from imagesink import ImageSink
|
from imagesink import ImageSink
|
||||||
|
|
||||||
class Video(gst.Pipeline):
|
class Video(gst.Pipeline):
|
||||||
|
#def log(self, msg):
|
||||||
|
# print msg
|
||||||
|
|
||||||
def __init__(self, uri, framerate='25/1'):
|
def __init__(self, uri, framerate='25/1'):
|
||||||
gst.Pipeline.__init__(self)
|
gst.Pipeline.__init__(self)
|
||||||
|
self.framerate = framerate
|
||||||
self.duration = -1
|
self.duration = -1
|
||||||
# queue of timestamps
|
# queue of timestamps
|
||||||
self.queue = []
|
self._queue = []
|
||||||
# queue callbacks
|
# queue callbacks
|
||||||
self.callback = {}
|
self.callback = {}
|
||||||
# extracted frames
|
# extracted frames
|
||||||
|
@ -29,6 +32,7 @@ class Video(gst.Pipeline):
|
||||||
|
|
||||||
# true only if we are prerolled
|
# true only if we are prerolled
|
||||||
self._ready = False
|
self._ready = False
|
||||||
|
|
||||||
uri = 'file://' + uri
|
uri = 'file://' + uri
|
||||||
self.log("uri : %s" % 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"),
|
self.sbin = SingleDecodeBin(caps=gst.Caps("video/x-raw-rgb;video/x-raw-yuv"),
|
||||||
uri=self.uri)
|
uri=self.uri)
|
||||||
self.csp = gst.element_factory_make("ffmpegcolorspace")
|
self.csp = gst.element_factory_make("ffmpegcolorspace")
|
||||||
|
self.scale = gst.element_factory_make("videoscale")
|
||||||
self.rate = gst.element_factory_make("videorate")
|
self.rate = gst.element_factory_make("videorate")
|
||||||
self.queue = gst.element_factory_make("queue")
|
self.queue = gst.element_factory_make("queue")
|
||||||
|
|
||||||
self.sink = ImageSink()
|
self.sink = ImageSink()
|
||||||
self.sink.connect('frame', self._frameCb)
|
self.sink.connect('frame', self._frameCb)
|
||||||
|
|
||||||
self.add(self.sbin, self.csp, self.queue, self.rate, self.sink)
|
self.add(self.sbin, self.csp, self.queue, self.scale, 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.sbin.connect('pad-added', self._sbinPadAddedCb)
|
self.sbin.connect('pad-added', self._sbinPadAddedCb)
|
||||||
|
|
||||||
self.set_state(gst.STATE_PAUSED)
|
self.set_state(gst.STATE_PAUSED)
|
||||||
self.get_state()
|
self.get_state()
|
||||||
self.width = self.sink.width
|
self.width = self.sink.width
|
||||||
|
@ -61,6 +63,20 @@ class Video(gst.Pipeline):
|
||||||
def _sbinPadAddedCb(self, unused_sbin, pad):
|
def _sbinPadAddedCb(self, unused_sbin, pad):
|
||||||
self.log("pad : %s" % pad)
|
self.log("pad : %s" % pad)
|
||||||
pad.link(self.queue.get_pad("sink"))
|
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):
|
def _frameCb(self, unused_thsink, frame, timestamp):
|
||||||
self.log("image:%s, timestamp:%s" % (frame, gst.TIME_ARGS(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)
|
self.callback[timestamp](frame, timestamp)
|
||||||
del self.callback[timestamp]
|
del self.callback[timestamp]
|
||||||
|
|
||||||
if timestamp in self.queue:
|
if timestamp in self._queue:
|
||||||
self.queue.remove(timestamp)
|
self._queue.remove(timestamp)
|
||||||
|
|
||||||
if self.queue:
|
if self._queue:
|
||||||
# still some more thumbnails to process
|
# 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):
|
def getDuration(self):
|
||||||
if self.duration < 0:
|
if self.duration < 0:
|
||||||
|
@ -105,12 +121,12 @@ class Video(gst.Pipeline):
|
||||||
|
|
||||||
self.callback[timestamp] = callback
|
self.callback[timestamp] = callback
|
||||||
|
|
||||||
if self.queue or not self._ready:
|
if self._queue or not self._ready:
|
||||||
self.log('ready')
|
self.log('ready')
|
||||||
self.queue.append(timestamp)
|
self._queue.append(timestamp)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
self.queue.append(timestamp)
|
self._queue.append(timestamp)
|
||||||
self._getFrame(timestamp)
|
self._getFrame(timestamp)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue