diff options
author | MaZderMind <github@mazdermind.de> | 2015-05-10 16:28:38 +0200 |
---|---|---|
committer | MaZderMind <github@mazdermind.de> | 2015-05-10 16:28:38 +0200 |
commit | b9ec27da68ddce2afc94454e92a78fe262812a0e (patch) | |
tree | eb917f731b6d199c6a76b1cf541d6f6af29ca6fd /voctocore/lib/quadmix.py | |
parent | f8a0b46028b9c902da7ce67590f9ce952ea44544 (diff) |
Implementing a Video-Switching-Server is easy … if you know what your're doing
Diffstat (limited to 'voctocore/lib/quadmix.py')
-rw-r--r-- | voctocore/lib/quadmix.py | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/voctocore/lib/quadmix.py b/voctocore/lib/quadmix.py deleted file mode 100644 index 8d69304..0000000 --- a/voctocore/lib/quadmix.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/python3 -import math, logging -from gi.repository import GLib, Gst - -from lib.helper import iteratorHelper -from lib.config import Config - -class QuadMix(Gst.Bin): - log = logging.getLogger('QuadMix') - previewbins = [] - mixerpads = [] - - def __init__(self): - super().__init__() - - caps = Gst.Caps.from_string(Config.get('mix', 'monitorcaps')) - self.log.debug('parsing monitorcaps from config: %s', caps.to_string()) - struct = caps.get_structure(0) - - self.monitorSize = [struct.get_int('width')[1], struct.get_int('height')[1]] - - self.bgsrc = Gst.ElementFactory.make('videotestsrc', 'bgsrc') - self.mixer = Gst.ElementFactory.make('videomixer', 'mixer') - self.scale = Gst.ElementFactory.make('videoscale', 'scale') - - self.add(self.bgsrc) - self.add(self.mixer) - self.add(self.scale) - - self.bgsrc.link_filtered(self.mixer, caps) - self.mixer.link_filtered(self.scale, caps) - - self.bgsrc.set_property('pattern', 'solid-color') - self.bgsrc.set_property('foreground-color', 0x808080) - - self.add_pad( - Gst.GhostPad.new('src', self.scale.get_static_pad('src')) - ) - - def request_mixer_pad(self): - previewbin = QuadMixPreview() - self.add(previewbin) - self.previewbins.append(previewbin) - - srcpad = previewbin.get_static_pad('src') - sinkpad = previewbin.get_static_pad('sink') - - mixerpad = self.mixer.get_request_pad('sink_%u') - self.mixerpads.append(mixerpad) - srcpad.link(mixerpad) - - self.log.info('requested mixerpad %u (named %s)', len(self.mixerpads) - 1, mixerpad.get_name()) - ghostpad = Gst.GhostPad.new(mixerpad.get_name(), sinkpad) - self.add_pad(ghostpad) - return ghostpad - - def finalize(self): - self.log.debug('all sources linked, calculating layout') - - # number of placed sources - count = len(self.previewbins) - - # coordinate of the cell where we place the next video - place = [0, 0] - - # number of cells in the quadmix-monitor - grid = [0, 0] - grid[0] = math.ceil(math.sqrt(count)) - grid[1] = math.ceil(count / grid[0]) - - # size of each cell in the quadmix-monitor - cellSize = ( - self.monitorSize[0] / grid[0], - self.monitorSize[1] / grid[1] - ) - - # report calculation results - self.log.info('showing %u videosources in a %u×%u grid in a %u×%u px window, which gives cells of %u×%u px per videosource', - count, grid[0], grid[1], self.monitorSize[0], self.monitorSize[1], cellSize[0], cellSize[1]) - - # iterate over all previewbins - for idx, previewbin in enumerate(self.previewbins): - # request srcpad to query videosize and aspect from it - srcpad = previewbin.get_static_pad('src') - - # select the mixerpad responsible for this previewbin from the videomixer - mixerpad = self.mixerpads[idx] - - # query the video-source caps and extract its size - caps = srcpad.query_caps(None) - capsstruct = caps.get_structure(0) - srcSize = ( - capsstruct.get_int('width')[1], - capsstruct.get_int('height')[1], - ) - - # calculate the ideal scale factor and scale the sizes - f = max(srcSize[0] / cellSize[0], srcSize[1] / cellSize[1]) - scaleSize = ( - srcSize[0] / f, - srcSize[1] / f, - ) - - # calculate the top/left coordinate - coord = ( - place[0] * cellSize[0] + (cellSize[0] - scaleSize[0]) / 2, - place[1] * cellSize[1] + (cellSize[1] - scaleSize[1]) / 2, - ) - - self.log.info('placing mixerpad %u of size %u×%u scaled by %u to %u×%u in a cell %u×%u px cell (%u/%u) at position (%u/%u)', - idx, srcSize[0], srcSize[1], f, scaleSize[0], scaleSize[1], cellSize[0], cellSize[1], place[0], place[1], coord[0], coord[1]) - - # request a pad from the quadmixer and configure x/y position - mixerpad.set_property('xpos', round(coord[0])) - mixerpad.set_property('ypos', round(coord[1])) - - previewbin.set_size(scaleSize) - previewbin.set_idx(idx) - - # increment grid position - place[0] += 1 - if place[0] >= grid[0]: - place[1] += 1 - place[0] = 0 - - def set_active(self, target): - self.log.info('setting videosource %u active, disabling other', target) - for idx, previewbin in enumerate(self.previewbins): - previewbin.set_active(target == idx) - -class QuadMixPreview(Gst.Bin): - log = logging.getLogger('QuadMixPreview') - strokeWidth = 5 - - def __init__(self): - super().__init__() - - self.scale = Gst.ElementFactory.make('videoscale', 'scale') - self.caps = Gst.ElementFactory.make('capsfilter', 'caps') - self.cropbox = Gst.ElementFactory.make('videobox', 'cropbox') - self.strokebox = Gst.ElementFactory.make('videobox', 'strokebox') - self.textoverlay = Gst.ElementFactory.make('textoverlay', 'textoverlay') - - self.add(self.scale) - self.add(self.caps) - self.add(self.cropbox) - self.add(self.strokebox) - self.add(self.textoverlay) - - self.strokebox.set_property('fill', 'green') - - self.textoverlay.set_property('color', 0xFFFFFFFF) - self.textoverlay.set_property('halignment', 'left') - self.textoverlay.set_property('valignment', 'top') - self.textoverlay.set_property('xpad', 10) - self.textoverlay.set_property('ypad', 5) - self.textoverlay.set_property('font-desc', 'sans 35') - - self.scale.link(self.caps) - self.caps.link(self.cropbox) - self.cropbox.link(self.strokebox) - self.strokebox.link(self.textoverlay) - - self.set_active(False) - - # Add Ghost Pads - self.add_pad( - Gst.GhostPad.new('sink', self.scale.get_static_pad('sink')) - ) - self.add_pad( - Gst.GhostPad.new('src', self.textoverlay.get_static_pad('src')) - ) - - def set_size(self, scaleSize): - caps = Gst.Caps.new_empty_simple('video/x-raw') - caps.set_value('width', round(scaleSize[0])) - caps.set_value('height', round(scaleSize[1])) - self.caps.set_property('caps', caps) - - def set_idx(self, idx): - self.textoverlay.set_property('text', str(idx)) - - def set_active(self, active): - self.log.info("switching active-state to %u", active) - for side in ('top', 'left', 'right', 'bottom'): - self.cropbox.set_property(side, self.strokeWidth if active else 0) - self.strokebox.set_property(side, -self.strokeWidth if active else 0) - - def set_color(self, color): - self.strokebox.set_property('fill', color) |