diff options
Diffstat (limited to 'voctocore')
-rw-r--r-- | voctocore/default-config.ini | 11 | ||||
-rw-r--r-- | voctocore/lib/videomix.py | 81 |
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 |