# HG changeset patch # User drewp@bigasterisk.com # Date 2010-06-08 06:52:59 # Node ID e20419d637d5b9aa38942f7c357dbe5860c00bea # Parent fd4f06a93c95bbbdc6da661877198b8e96c1e56c initial vidref tests Ignore-this: f3ca12ad8071d889ed71689be0716827 diff --git a/bin/vidref b/bin/vidref new file mode 100644 --- /dev/null +++ b/bin/vidref @@ -0,0 +1,8 @@ +#!/usr/bin/python +import gtk +from light9.vidref.main import Main + + +start=Main() +gtk.main() + diff --git a/light9/vidref/__init__.py b/light9/vidref/__init__.py new file mode 100644 diff --git a/light9/vidref/main.py b/light9/vidref/main.py new file mode 100644 --- /dev/null +++ b/light9/vidref/main.py @@ -0,0 +1,126 @@ +#!/usr/bin/python +import pygst +pygst.require("0.10") +import gst, gobject +import pygtk +import gtk +from twisted.python.util import sibpath +import Image + +otherPic = None + + +import StringIO +# gtk.gdk.pixbuf_new_from_data(img.tostring() seems like it would be better +# http://www.daa.com.au/pipermail/pygtk/2003-June/005268.html +def Image_to_GdkPixbuf (image): + file = StringIO.StringIO () + image.save (file, 'ppm') + contents = file.getvalue() + file.close () + loader = gtk.gdk.PixbufLoader ('pnm') + loader.write (contents, len (contents)) + pixbuf = loader.get_pixbuf () + loader.close () + return pixbuf + +class MySink(gst.Element): + _sinkpadtemplate = gst.PadTemplate ("sinkpadtemplate", + gst.PAD_SINK, + gst.PAD_ALWAYS, + gst.caps_new_any()) + + def __init__(self): + gst.Element.__init__(self) + self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink") + self.add_pad(self.sinkpad) + self.sinkpad.set_chain_function(self.chainfunc) + + def chainfunc(self, pad, buffer): + global nextImageCb + self.info("%s timestamp(buffer):%d" % (pad, buffer.timestamp)) + + if 1: + try: + cap = buffer.caps[0] + img = Image.fromstring('RGB', (cap['width'], cap['height']), + buffer.data) + except: + import traceback + traceback.print_exc() + raise + + print "got image to save" + #pixbuf = Image_to_GdkPixbuf(img) + #otherPic.set_from_pixbuf(pixbuf) + + return gst.FLOW_OK +gobject.type_register(MySink) + +class Main(object): + def __init__(self): + global otherPic + wtree = gtk.Builder() + wtree.add_from_file(sibpath(__file__, "vidref.glade")) + mainwin = wtree.get_object("MainWindow") + otherPic = wtree.get_object("liveVideo") + mainwin.connect("destroy", gtk.main_quit) + wtree.connect_signals({ + "foo" : self.OnPlay, + }) + + pipeline = gst.Pipeline("player") + + def makeElem(t, n=None): + e = gst.element_factory_make(t, n) + pipeline.add(e) + return e + + if 0: + source = makeElem("videotestsrc", "video") + else: + source = makeElem("v4l2src", "vsource") + source.set_property("device", "/dev/video0") + + csp = makeElem("ffmpegcolorspace") + + caps = makeElem("capsfilter") + caps.set_property('caps', gst.caps_from_string('video/x-raw-rgb')) + + sink = makeElem("xvimagesink", "sink") + + recSink = MySink() + pipeline.add(recSink) + + # using this adds 5% cpu; not sure the advantage + scaler = makeElem("videoscale", "vscale") + + tee = makeElem("tee") + + source.link(csp) + csp.link(caps) + caps.link(tee) + tee.link(sink) + + tee.link(recSink) +# tee.link(sink2) + + mainwin.show_all() + +# sink2.set_xwindow_id(wtree.get_object("liveVideo").window.xid) + sink.set_xwindow_id(wtree.get_object("vid3").window.xid) + + pipeline.set_state(gst.STATE_PLAYING) + + def OnPlay(self, widget): + print "play" + # Tell the video sink to display the output in our DrawingArea + self.sinkx.set_xwindow_id(self.da.window.xid) + self.pipeline.set_state(gst.STATE_PLAYING) + + def OnStop(self, widget): + print "stop" + self.pipeline.set_state(gst.STATE_READY) + + def OnQuit(self, widget): + gtk.main_quit() diff --git a/light9/vidref/qt_test.py b/light9/vidref/qt_test.py new file mode 100644 --- /dev/null +++ b/light9/vidref/qt_test.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python + +from PyQt4 import QtCore, QtGui, uic +import gst +import gobject + +class Vid(object): + def __init__(self, windowId): + self.player = gst.Pipeline("player") + self.source = gst.element_factory_make("v4l2src", "vsource") + self.sink = gst.element_factory_make("autovideosink", "outsink") + self.source.set_property("device", "/dev/video0") + self.scaler = gst.element_factory_make("videoscale", "vscale") + self.window_id = None + self.windowId = windowId + + self.fvidscale_cap = gst.element_factory_make("capsfilter", "fvidscale_cap") + self.fvidscale_cap.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=320, height=240')) + + self.player.add(self.source, self.scaler, self.fvidscale_cap, self.sink) + gst.element_link_many(self.source,self.scaler, self.fvidscale_cap, self.sink) + + self.s = MySink() + self.player.add(self.s) +# self.scaler.link(self.s) + + bus = self.player.get_bus() + bus.add_signal_watch() +# bus.enable_sync_message_emission() # with this we segv +# bus.connect("message", self.on_message) # with this we segv + bus.connect("sync-message::element", self.on_sync_message) + + def on_message(self, bus, message): + print "msg", bus, message + t = message.type + if t == gst.MESSAGE_EOS: + self.player.set_state(gst.STATE_NULL) + elif t == gst.MESSAGE_ERROR: + err, debug = message.parse_error() + print "Error: %s" % err, debug + self.player.set_state(gst.STATE_NULL) + + def on_sync_message(self, bus, message): + print "syncmsg", bus, message + if message.structure is None: + return + message_name = message.structure.get_name() + if message_name == "prepare-xwindow-id": + print "pxi" + win_id = self.windowId + assert win_id + imagesink = message.src + imagesink.set_property("force-aspect-ratio", True) + print "set_xwindow_id" + imagesink.set_xwindow_id(win_id) + print "dnoe msg" + + def startPrev(self): + self.player.set_state(gst.STATE_PLAYING) + print "should be playing" + + +class MainWin(QtGui.QMainWindow): + def __init__(self, *args): + super(MainWin, self).__init__(*args) + + uic.loadUi('light9/vidref/vidref.ui', self) + v = Vid(self.liveView.winId()) + v.startPrev() + + @QtCore.pyqtSlot() + def startLiveView(self): + print "slv" + + diff --git a/light9/vidref/vidref.glade b/light9/vidref/vidref.glade new file mode 100644 --- /dev/null +++ b/light9/vidref/vidref.glade @@ -0,0 +1,71 @@ + + + + + + 500 + 500 + + + True + + + 85 + 20 + True + 0.47999998927116394 + Live view + + + 5 + 16 + + + + + 320 + 240 + True + + + 6 + 40 + + + + + 338 + 269 + True + 0 + out + + + True + 12 + + + 100 + 80 + True + + + + + + + True + <b>Live view</b> + True + + + + + 332 + 28 + + + + + + diff --git a/light9/vidref/vidref.ui b/light9/vidref/vidref.ui new file mode 100644 --- /dev/null +++ b/light9/vidref/vidref.ui @@ -0,0 +1,234 @@ + + + MainWindow + + + + 0 + 0 + 863 + 728 + + + + MainWindow + + + + + + 20 + 260 + 251 + 16 + + + + Live view + + + + + + 20 + 10 + 320 + 240 + + + + + + + 50 + 280 + 121 + 19 + + + + enabled + + + true + + + + + + 50 + 470 + 171 + 121 + + + + + song + + + + + time + + + + + value + + + + + whatever + + + + + + + 40 + 340 + 52 + 13 + + + + Song + + + + + + 40 + 360 + 52 + 13 + + + + Time + + + + + + 90 + 330 + 113 + 23 + + + + + + + 90 + 360 + 113 + 23 + + + + + + + 570 + 330 + 191 + 191 + + + + true + + + + + 0 + 0 + 189 + 189 + + + + + + + + 270 + 310 + 411 + 331 + + + + Replay from 16:10 + + + + + 20 + 30 + 311 + 231 + + + + + + + 60 + 270 + 191 + 19 + + + + follow current time + + + graphicsView_2 + graphicsView_2 + checkBox_2 + + + + + + 0 + 0 + 863 + 21 + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + toolBar_2 + + + TopToolBarArea + + + false + + + + + + + startLiveView() + +