aboutsummaryrefslogtreecommitdiff
path: root/voctocore
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2017-02-28 15:10:39 +0100
committerJonas Smedegaard <dr@jones.dk>2017-02-28 15:10:39 +0100
commitcb42a9ad193179c527b44eccd3ca3ac59d573386 (patch)
tree8967af004209c8d7f159e45e5807979c7ca5953f /voctocore
parent6ce57b47f050c39fbf28f4af639ef19608a74cfa (diff)
Add composition Matrix Two-by-two.
Diffstat (limited to 'voctocore')
-rw-r--r--voctocore/default-config.ini11
-rw-r--r--voctocore/lib/videomix.py81
2 files changed, 91 insertions, 1 deletions
diff --git a/voctocore/default-config.ini b/voctocore/default-config.ini
index d5f69e9..3341b80 100644
--- a/voctocore/default-config.ini
+++ b/voctocore/default-config.ini
@@ -60,6 +60,17 @@ mix_out=10000
;default-a=grabber
;default-b=cam1
+[matrix-two-by-two]
+; defaults to 1% of the video width
+;gutter=12
+
+; if configured, switching to the matrix-2x2 mode will automatically select these
+; sources. if not configured, it will not change the last set sources
+;default-a=cam1
+;default-b=cam2
+;default-c=cam3
+;default-d=cam4
+
[previews]
; disable if ui & server run on the same computer and can exchange uncompressed video frames
enabled=false
diff --git a/voctocore/lib/videomix.py b/voctocore/lib/videomix.py
index 38432e8..e7c0233 100644
--- a/voctocore/lib/videomix.py
+++ b/voctocore/lib/videomix.py
@@ -12,6 +12,7 @@ class CompositeModes(Enum):
side_by_side_equal = 1
side_by_side_preview = 2
picture_in_picture = 3
+ matrix_two_by_two = 4
class PadState(object):
@@ -98,6 +99,8 @@ class VideoMix(object):
self.compositeMode = CompositeModes.fullscreen
self.sourceA = 0
self.sourceB = 1
+ self.sourceC = 2
+ self.sourceD = 3
self.recalculateMixerState()
self.applyMixerState()
@@ -129,6 +132,9 @@ class VideoMix(object):
elif self.compositeMode == CompositeModes.picture_in_picture:
self.recalculateMixerStatePictureInPicture()
+ elif self.compositeMode == CompositeModes.matrix_two_by_two:
+ self.recalculateMixerStateMatrixTwoByTwo()
+
self.log.debug('Marking Pad-State as Dirty')
self.padStateDirty = True
@@ -322,6 +328,62 @@ class VideoMix(object):
else:
pad.alpha = 0
+ def recalculateMixerStateMatrixTwoByTwo(self):
+ self.log.info('Updating Mixer-State for '
+ 'Matrix-Two-by-two-Composition')
+
+ width, height = self.getInputVideoSize()
+ self.log.debug('Video-Size parsed as %ux%u', width, height)
+
+ try:
+ gutter = Config.getint('matrix-two-by-two', 'gutter')
+ self.log.debug('Gutter configured to %u', gutter)
+ except:
+ gutter = int(width / 100)
+ self.log.debug('Gutter calculated to %u', gutter)
+
+ targetWidth = int((width - gutter) / 2)
+ #targetHeight = int(targetWidth / width * height)
+ targetHeight = int((height - gutter) / 2)
+
+ self.log.debug('Video-Size calculated to %ux%u',
+ targetWidth, targetHeight)
+
+ xa = 0
+ xb = width - targetWidth
+ y1 = 0
+ y2 = height - targetHeight
+
+ for idx, name in enumerate(self.names):
+ pad = self.padState[idx]
+ pad.reset()
+
+ pad.width = targetWidth
+ pad.height = targetHeight
+
+ if idx == self.sourceA:
+ pad.xpos = xa
+ pad.ypos = y1
+ pad.zorder = 1
+
+ elif idx == self.sourceB:
+ pad.xpos = xb
+ pad.ypos = y1
+ pad.zorder = 2
+
+ elif idx == self.sourceC:
+ pad.xpos = xa
+ pad.ypos = y2
+ pad.zorder = 3
+
+ elif idx == self.sourceD:
+ pad.xpos = xb
+ pad.ypos = y2
+ pad.zorder = 4
+
+ else:
+ pad.alpha = 0
+
def applyMixerState(self):
for idx, state in enumerate(self.padState):
# mixerpad 0 = background
@@ -346,7 +408,8 @@ class VideoMix(object):
CompositeModes.fullscreen: 'fullscreen',
CompositeModes.side_by_side_equal: 'side-by-side-equal',
CompositeModes.side_by_side_preview: 'side-by-side-preview',
- CompositeModes.picture_in_picture: 'picture-in-picture'
+ CompositeModes.picture_in_picture: 'picture-in-picture',
+ CompositeModes.matrix_two_by_two: 'matrix-two-by-two'
}
compositeModeName = self.compositeMode.name
@@ -368,6 +431,22 @@ class VideoMix(object):
except Exception as e:
pass
+ try:
+ defSource = Config.get(sectionName, 'default-c')
+ self.setVideoSourceC(self.names.index(defSource))
+ self.log.info('Changing sourceC to default of Mode %s: %s',
+ compositeModeName, defSource)
+ except Exception as e:
+ pass
+
+ try:
+ defSource = Config.get(sectionName, 'default-d')
+ self.setVideoSourceD(self.names.index(defSource))
+ self.log.info('Changing sourceD to default of Mode %s: %s',
+ compositeModeName, defSource)
+ except Exception as e:
+ pass
+
def on_handoff(self, object, buffer):
if self.padStateDirty:
self.padStateDirty = False