From 13bfcced454a1f93f96250cf4086620e31bd5fa9 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Sun, 14 Jun 2015 02:43:29 +0200 Subject: [PATCH] Output to for operator works Output to network works in theory --- ini/base.ini | 2 +- python/camerafeed.py | 46 +++++++++------------------------ python/config.py | 12 +++++++++ python/feed.py | 35 ++++++++++++++++++++++++++ python/outputfeed.py | 60 ++++++++++++++++++++++++++++++++++++++++++++ python/runfeeds.py | 3 +++ scripts/outputtest | 9 +++++++ scripts/stopmixer.sh | 3 ++- 8 files changed, 134 insertions(+), 36 deletions(-) create mode 100644 python/feed.py create mode 100644 python/outputfeed.py create mode 100644 scripts/outputtest diff --git a/ini/base.ini b/ini/base.ini index c6060b0..10419a5 100644 --- a/ini/base.ini +++ b/ini/base.ini @@ -124,4 +124,4 @@ command end overlay finish ShowAll -monitor on +#monitor on diff --git a/python/camerafeed.py b/python/camerafeed.py index 7ef5676..8029dcf 100644 --- a/python/camerafeed.py +++ b/python/camerafeed.py @@ -7,57 +7,35 @@ import pygst pygst.require('0.10') import gst +from feed import Feed + from config import * -WIDTH = 1280 -HEIGHT = 720 -FRAMERATE = 25 -SHM_SIZE = 10000000 - -class CameraFeed(object): +class CameraFeed(Feed): def __init__(self, feed_pipe, camera_ip): + super(CameraFeed, self).__init__(feed_pipe) + self._feed_pipe = feed_pipe self._camera_ip = camera_ip - self._running = False - self._pipeline = None - self._thead = None def start(self): - if self._running: + if self.is_running(): return if not os.path.exists(MIXER_PIPE): - print '[%s] not starting because mixer is not running (pipe is missing)' % self._feed_pipe + print '[%s] not starting because mixer is not running (pipe is missing)' % self._name return if os.path.exists(self._feed_pipe): - print '[%s] not starting because feed pipe already exists' % self._feed_pipe + print '[%s] not starting because feed pipe already exists' % self._name return - print '[%s] is starting' % self._feed_pipe + print '[%s] is starting' % self._name self._running = True self._thread = threading.Thread(target=self._run) self._thread.start() - def is_running(self): - return self._running - - - def stop(self): - - if not self._running: - return - - if self._pipeline <> None: - print "[%s] pipeline stopped" % self._feed_pipe - self._pipeline.set_state(gst.STATE_NULL) - - if self._thread <> None: - print "[%s] waiting for thread to terminate" % self._feed_pipe - self._thread.join(2.0) - - def _run(self): src = FEED_SOURCE % {'ip': self._camera_ip} mixer_format = MIXER_FORMAT % {'width' : MIXER_WIDTH, 'height' : MIXER_HEIGHT, 'framerate' : MIXER_FRAMERATE} @@ -66,14 +44,14 @@ class CameraFeed(object): self._pipeline = gst.parse_launch('%s ! %s ! %s ! %s' % (src, SCALE, mixer_format, sink)) self._pipeline.set_state(gst.STATE_PLAYING) - print "[%s] is playing" % self._feed_pipe + print "[%s] is playing" % self._name bus = self._pipeline.get_bus() msg = bus.timed_pop_filtered(gst.CLOCK_TIME_NONE, gst.MESSAGE_ERROR | gst.MESSAGE_EOS) - print "[%s] %s" % (self._feed_pipe, msg.parse_error()[1]) + print "[%s] %s" % (self._name, msg.parse_error()[1]) self._pipeline.set_state(gst.STATE_NULL) self._running = False - print "[%s] has stopped" % self._feed_pipe + print "[%s] has stopped" % self._name diff --git a/python/config.py b/python/config.py index c51d386..16613fb 100644 --- a/python/config.py +++ b/python/config.py @@ -13,6 +13,11 @@ MIXER_HEIGHT = 720 MIXER_FRAMERATE = 25 SHM_SIZE = 10000000 +SCREEN_WIDTH = 640 +SCREEN_HEIGHT = 360 + + + FEED_SOURCE = 'rtspsrc location=rtsp://%(ip)s ! rtph264depay ! h264parse ! ffdec_h264' MIXER_FORMAT = 'video/x-raw-rgb, bpp=(int)32, endianness=(int)4321, format=(fourcc)BGRA,'\ + ' red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216,'\ @@ -21,3 +26,10 @@ MIXER_FORMAT = 'video/x-raw-rgb, bpp=(int)32, endianness=(int)4321, format=(four SCALE = 'ffmpegcolorspace ! videorate ! videoscale ! ffmpegcolorspace' FEED_SINK = 'shmsink socket-path=%(feed_pipe)s shm-size=%(shm_size)d wait-for-connection=0' +OUTPUT_SOURCE = 'shmsrc socket-path=%(mixer_pipe)s do-timestamp=true is-live=true' +SCREEN_OUTPUT = 'videoscale ! video/x-raw-rgb, width=%(screen_width)d, height=%(screen_height)d !'\ + + ' timeoverlay ! ximagesink' +NETWORK_OUTPUT = 'fakesink' + + + diff --git a/python/feed.py b/python/feed.py new file mode 100644 index 0000000..1071662 --- /dev/null +++ b/python/feed.py @@ -0,0 +1,35 @@ +#!/bin/env python2 + +import pygst +pygst.require('0.10') +import gst + + +class Feed(object): + + def __init__(self, name): + self._running = False + self._thead = None + self._pipeline = None + self._name = name + + + def is_running(self): + return self._running + + + def stop(self): + if not self._running: + return + + if self._pipeline <> None: + print "[%s] pipeline stopped" % self._name + self._pipeline.set_state(gst.STATE_NULL) + + if self._thread <> None: + print "[%s] waiting for thread to terminate" % self._name + self._thread.join(2.0) + + + + diff --git a/python/outputfeed.py b/python/outputfeed.py new file mode 100644 index 0000000..31d1e41 --- /dev/null +++ b/python/outputfeed.py @@ -0,0 +1,60 @@ +#!/bin/env python2 +import os +import threading +from time import sleep + +import pygst +pygst.require('0.10') +import gst + +from feed import Feed + +from config import * + + +class OutputFeed(Feed): + def __init__(self): + super(OutputFeed, self).__init__(MIXER_PIPE) + + + def start(self): + if self.is_running(): + return + + if not os.path.exists(MIXER_PIPE): + print '[%s] not starting because mixer is not running (pipe is missing)' % self._name + return + + + print '[%s] is starting' % self._name + self._running = True + self._thread = threading.Thread(target=self._run) + self._thread.start() + + + def _run(self): + src = OUTPUT_SOURCE % {'mixer_pipe' : MIXER_PIPE} + mixer_format = MIXER_FORMAT % {'width' : MIXER_WIDTH, 'height' : MIXER_HEIGHT, 'framerate' : MIXER_FRAMERATE} + screen_output = SCREEN_OUTPUT % {'screen_width': SCREEN_WIDTH, 'screen_height': SCREEN_HEIGHT} + + pipeline = '%s ! %s ! queue leaky=2 ! tee name=split ! queue ! %s split. ! queue ! %s' % (src, + mixer_format, + screen_output, + NETWORK_OUTPUT) + print pipeline + self._pipeline = gst.parse_launch(pipeline) + + + + self._pipeline.set_state(gst.STATE_PLAYING) + print "[%s] is playing" % self._name + + bus = self._pipeline.get_bus() + msg = bus.timed_pop_filtered(gst.CLOCK_TIME_NONE, gst.MESSAGE_ERROR | gst.MESSAGE_EOS) + print "[%s] %s" % (self._name, msg.parse_error()[1]) + + self._pipeline.set_state(gst.STATE_NULL) + + self._running = False + + print "[%s] has stopped" % self._name diff --git a/python/runfeeds.py b/python/runfeeds.py index 057f6e9..b6ab55e 100644 --- a/python/runfeeds.py +++ b/python/runfeeds.py @@ -6,6 +6,7 @@ import time import gobject from camerafeed import CameraFeed +from outputfeed import OutputFeed from config import * @@ -28,6 +29,8 @@ signal.signal(signal.SIGINT, handle_sigint) for pipe, ip in CAMERA_FEEDS.items(): feeds.append(CameraFeed(pipe, ip)) +feeds.append(OutputFeed()) + while os.path.exists(MIXER_PIPE): for feed in feeds: if not feed.is_running(): diff --git a/scripts/outputtest b/scripts/outputtest new file mode 100644 index 0000000..36446b3 --- /dev/null +++ b/scripts/outputtest @@ -0,0 +1,9 @@ +#!/bin/bash + +FORMAT="video/x-raw-rgb, bpp=(int)32, endianness=(int)4321, format=(fourcc)BGRA, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)1280, height=(int)720, framerate=(fraction)25/1, pixel-aspect-ratio=(fraction)1/1, interlaced=(boolean)false" + +SCREEN_FORMAT="video/x-raw-rgb, width=(int)640, height=(int)360" + +gst-launch-0.10 -v shmsrc socket-path=/tmp/mixer1 do-timestamp=true is-live=true ! $FORMAT ! queue leaky=2 ! tee name=split ! queue ! videoscale ! $SCREEN_FORMAT ! timeoverlay ! ximagesink split. ! queue ! ffmpegcolorspace ! x264enc tune="zerolatency" ! mpegtsmux ! tcpserversink port=8042 + +#gst-launch-0.10 tcpclientsrc port=8042 host=localhost ! tsdemux ! h264parse ! ffdec_h264 ! xvimagesink diff --git a/scripts/stopmixer.sh b/scripts/stopmixer.sh index 38faa89..af9b464 100755 --- a/scripts/stopmixer.sh +++ b/scripts/stopmixer.sh @@ -1,2 +1,3 @@ #!/bin/bash -echo quit | nc localhost 9999 \ No newline at end of file +echo quit | nc localhost 9999 +rm /tmp/mixer1