Last active
September 25, 2018 17:33
-
-
Save JohnDMcMaster/44b19eb9c36f86341062c31f52714cfc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
''' | |
gst-launch-0.10 videotestsrc ! ffmpegcolorspace ! videoscale ! ximagesink | |
''' | |
from PyQt4 import Qt | |
from PyQt4.QtGui import * | |
from PyQt4.QtCore import * | |
from PyQt4.QtGui import QWidget, QLabel | |
import sys | |
import traceback | |
import os | |
import signal | |
import gobject, pygst | |
pygst.require('0.10') | |
import gst | |
import StringIO | |
from PIL import Image | |
class MainWindow(QMainWindow): | |
def __init__(self): | |
QMainWindow.__init__(self) | |
#self.showMaximized() | |
self.initUI() | |
self.gstWindowId = None | |
self.source = gst.element_factory_make("videotestsrc", "video-source") | |
self.setupGst() | |
assert self.gstWindowId | |
def init_x1_unreliable(): | |
''' | |
X1: 5 / 10 worked | |
On failure: white background | |
T61: 0 / 10 worked | |
On failure: white background | |
''' | |
self.start_gstreamer() | |
self.show() | |
def init_x1_reliable1(): | |
''' | |
X1: 10 / 10 worked | |
T61: 0 / 10 worked | |
On failure: uninitialized / old window memory background | |
''' | |
self.timer = QTimer() | |
self.timer.setSingleShot(True) | |
self.timer.timeout.connect(self.start_gstreamer) | |
self.timer.start(100) | |
self.show() | |
def init_x1_reliable2(): | |
''' | |
X1: 10 / 10 worked | |
T61: 0 / 10 worked | |
On failure: briefly shows uninitialized memory, then goes white | |
''' | |
self.show() | |
self.start_gstreamer() | |
#init_x1_unreliable() | |
init_x1_reliable1() | |
#init_x1_reliable2() | |
def start_gstreamer(self): | |
print("Starting gstreamer pipeline") | |
self.player.set_state(gst.STATE_PLAYING) | |
def get_video_layout(self): | |
# Overview | |
def low_res_layout(): | |
layout = QVBoxLayout() | |
layout.addWidget(QLabel("Overview")) | |
# Raw X-windows canvas | |
self.video_container = QWidget() | |
w, h = 3264/4, 2448/4 | |
self.video_container.setMinimumSize(w, h) | |
self.video_container.resize(w, h) | |
policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) | |
self.video_container.setSizePolicy(policy) | |
layout.addWidget(self.video_container) | |
return layout | |
layout = QHBoxLayout() | |
layout.addLayout(low_res_layout()) | |
return layout | |
def setupGst(self): | |
self.gstWindowId = self.video_container.winId() | |
print "Setting up gstreamer pipeline, win id %s" % (self.gstWindowId,) | |
self.player = gst.Pipeline("player") | |
sinkx = gst.element_factory_make("ximagesink", 'sinkx_overview') | |
fcs = gst.element_factory_make('ffmpegcolorspace') | |
self.capture_enc = gst.element_factory_make("jpegenc") | |
self.resizer = gst.element_factory_make("videoscale") | |
self.player.add(self.source, fcs, self.resizer, sinkx) | |
gst.element_link_many(self.source, fcs, self.resizer, sinkx) | |
bus = self.player.get_bus() | |
bus.add_signal_watch() | |
bus.enable_sync_message_emission() | |
bus.connect("message", self.on_message) | |
bus.connect("sync-message::element", self.on_sync_message) | |
def on_message(self, bus, message): | |
t = message.type | |
#print('\n'.join(dir(gst))) | |
print('MSG: %s' % (t,)) | |
if t == gst.MESSAGE_EOS: | |
self.player.set_state(gst.STATE_NULL) | |
print(" End of stream") | |
elif t == gst.MESSAGE_STREAM_STATUS: | |
print(' status') | |
elif t == gst.MESSAGE_STATE_CHANGED: | |
state = self.player.get_state() | |
s1, s2, s3 = state | |
print(' %s, %s' % (gst.element_state_get_name(s2), gst.element_state_get_name(s3))) | |
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('sync, %s' % (message,)) | |
if message.structure is None: | |
return | |
message_name = message.structure.get_name() | |
if message_name == "prepare-xwindow-id": | |
assert message.src.get_name() == 'sinkx_overview' | |
print 'sinkx_overview win_id: %s (%s)' % (self.gstWindowId, self.video_container.winId()) | |
win_id = self.gstWindowId | |
assert win_id | |
imagesink = message.src | |
imagesink.set_xwindow_id(win_id) | |
def initUI(self): | |
self.setGeometry(300, 300, 250, 150) | |
self.setWindowTitle('pyv4l test') | |
# top layout | |
layout = QHBoxLayout() | |
layout.addLayout(self.get_video_layout()) | |
w = QWidget() | |
w.setLayout(layout) | |
self.setCentralWidget(w) | |
def excepthook(excType, excValue, tracebackobj): | |
print '%s: %s' % (excType, excValue) | |
traceback.print_tb(tracebackobj) | |
os._exit(1) | |
if __name__ == '__main__': | |
if 1: | |
sys.excepthook = excepthook | |
# Exit on ^C instead of ignoring | |
signal.signal(signal.SIGINT, signal.SIG_DFL) | |
gobject.threads_init() | |
app = QApplication(sys.argv) | |
qApp.connect(qApp, SIGNAL('lastWindowClosed()'), qApp, SLOT('quit()')) | |
_gui = MainWindow() | |
sys.exit(app.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment