summaryrefslogtreecommitdiff
path: root/voctocore
diff options
context:
space:
mode:
authorMaZderMind <github@mazdermind.de>2015-05-23 13:40:51 +0200
committerMaZderMind <github@mazdermind.de>2015-05-23 13:40:51 +0200
commit1353c75413f7b660939a48d09f17a18f75015e0d (patch)
treec05aa495113cb90daf0b6c8cb966f840f991460f /voctocore
parentc7755226facb125af1fc154dd0a4ee5e6659d428 (diff)
Picture-in-Picture composition mode
Diffstat (limited to 'voctocore')
-rw-r--r--voctocore/default-config.ini4
-rw-r--r--voctocore/lib/videomix.py66
-rwxr-xr-xvoctocore/scripts/demo-cycle-modes.sh6
-rwxr-xr-xvoctocore/scripts/set-composite-picture-in-picture.sh2
4 files changed, 77 insertions, 1 deletions
diff --git a/voctocore/default-config.ini b/voctocore/default-config.ini
index eb2de84..df361b1 100644
--- a/voctocore/default-config.ini
+++ b/voctocore/default-config.ini
@@ -15,6 +15,10 @@ sources=cam1,cam2,grabber
;bsize=320x180
;bpos=948/528
+[picture-in-picture]
+;pipsize=320x180
+;pippos=948/528
+
[previews]
; disable if ui & server run on the same computer and exchange uncompressed video frames
enabled=true
diff --git a/voctocore/lib/videomix.py b/voctocore/lib/videomix.py
index 53e1d03..6508346 100644
--- a/voctocore/lib/videomix.py
+++ b/voctocore/lib/videomix.py
@@ -9,6 +9,7 @@ class CompositeModes(Enum):
fullscreen = 0
side_by_side_equal = 1
side_by_side_preview = 2
+ picture_in_picture = 3
class VideoMix(object):
log = logging.getLogger('VideoMix')
@@ -83,6 +84,9 @@ class VideoMix(object):
elif self.compositeMode == CompositeModes.side_by_side_preview:
self.updateMixerStateSideBySidePreview()
+ elif self.compositeMode == CompositeModes.picture_in_picture:
+ self.updateMixerStatePictureInPicture()
+
def updateMixerStateFullscreen(self):
self.log.info('Updating Mixer-State for Fullscreen-Composition')
@@ -238,6 +242,68 @@ class VideoMix(object):
self.log.debug('Setting Mixerpad %u to x/y=%u/%u and alpha=%0.2f', idx, 0, 0, 0)
self.log.debug('Resetting Scaler %u to non-scaling', idx)
+ def updateMixerStatePictureInPicture(self):
+ self.log.info('Updating Mixer-State for Picture-in-Picture-Composition')
+
+ width, height = self.getInputVideoSize()
+ self.log.debug('Video-Size parsed as %ux%u', width, height)
+
+ try:
+ pipsize = [int(i) for i in Config.get('picture-in-picture', 'pipsize').split('x', 1)]
+ self.log.debug('PIP-Size configured to %ux%u', pipsize[0], pipsize[1])
+ except:
+ pipsize = [
+ int(width / 4), # 25%
+ int(height / 4) # 25%
+ ]
+ self.log.debug('PIP-Size calculated to %ux%u', pipsize[0], pipsize[1])
+
+ try:
+ pippos = [int(i) for i in Config.get('picture-in-picture', 'pippos').split('/', 1)]
+ self.log.debug('PIP-Position configured to %u/%u', pippos[0], pippos[1])
+ except:
+ pippos = [
+ width - pipsize[0] - int(width / 100), # 1%
+ height - pipsize[1] -int(width / 100) # 1%
+ ]
+ self.log.debug('PIP-Position calculated to %u/%u', pippos[0], pippos[1])
+
+ scaleCaps = Gst.Caps.from_string('video/x-raw,width=%u,height=%u' % tuple(pipsize))
+ noScaleCaps = Gst.Caps.from_string('video/x-raw')
+
+ for idx, name in enumerate(self.names):
+ mixerpad = self.mixingPipeline.get_by_name('mix').get_static_pad('sink_%u' % idx)
+ capsfilter = self.mixingPipeline.get_by_name('caps_%u' % idx)
+
+ if idx == self.sourceA:
+ mixerpad.set_property('alpha', 1)
+ mixerpad.set_property('xpos', 0)
+ mixerpad.set_property('ypos', 0)
+ mixerpad.set_property('zorder', 0)
+ capsfilter.set_property('caps', noScaleCaps)
+
+ self.log.debug('Setting Mixerpad %u to x/y=%u/%u and alpha=%0.2f, zorder=%u', idx, 0, 0, 1, 0)
+ self.log.debug('Resetting Scaler %u to non-scaling', idx)
+
+ elif idx == self.sourceB:
+ mixerpad.set_property('alpha', 1)
+ mixerpad.set_property('xpos', pippos[0])
+ mixerpad.set_property('ypos', pippos[1])
+ mixerpad.set_property('zorder', 1)
+ capsfilter.set_property('caps', scaleCaps)
+
+ self.log.debug('Setting Mixerpad %u to x/y=%u/%u, alpha=%0.2f, zorder=%u', idx, pippos[0], pippos[1], 1, 1)
+ self.log.debug('Setting Scaler %u to %u/%u', idx, pipsize[0], pipsize[1])
+
+ else:
+ mixerpad.set_property('alpha', 0)
+ mixerpad.set_property('xpos', 0)
+ mixerpad.set_property('ypos', 0)
+ capsfilter.set_property('caps', noScaleCaps)
+
+ self.log.debug('Setting Mixerpad %u to x/y=%u/%u and alpha=%0.2f', idx, 0, 0, 0)
+ self.log.debug('Resetting Scaler %u to non-scaling', idx)
+
def setVideoSourceA(self, source):
# swap if required
if self.sourceB == source:
diff --git a/voctocore/scripts/demo-cycle-modes.sh b/voctocore/scripts/demo-cycle-modes.sh
index 264bdfa..da5fdb8 100755
--- a/voctocore/scripts/demo-cycle-modes.sh
+++ b/voctocore/scripts/demo-cycle-modes.sh
@@ -1,8 +1,12 @@
while true; do
- ./set-composite-side-by-side-preview.sh
+ ./set-composite-picture-in-picture.sh
sleep 10
./set-video-cam2.sh
sleep 10
+ ./set-composite-side-by-side-preview.sh
+ sleep 10
+ ./set-video-cam1.sh
+ sleep 10
./set-composite-side-by-side-equal.sh
sleep 10
./set-audio-cam2.sh
diff --git a/voctocore/scripts/set-composite-picture-in-picture.sh b/voctocore/scripts/set-composite-picture-in-picture.sh
new file mode 100755
index 0000000..eae3bea
--- /dev/null
+++ b/voctocore/scripts/set-composite-picture-in-picture.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo set_composite_mode picture_in_picture | nc -q0 localhost 9999