something breaks if video width/height is not multiple of 4

This commit is contained in:
j 2010-08-25 17:38:08 +02:00
parent 9d7e6ecdac
commit 3c73ffe9e0
2 changed files with 33 additions and 15 deletions

View file

@ -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,

View file

@ -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