Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configs/gstsource/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sample core.ini used to test gstsource.py
35 changes: 35 additions & 0 deletions configs/gstsource/gst_4s.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[mix]
sources = gst1,gst2,gst3,gst4

[source.gst1]
kind=gst
audio_source=audiotestsrc freq=550 ! audio/x-raw,format=S16LE,channels=2
audio_debug=True
video_source=videotestsrc pattern=ball motion=hsweep animation-mode=wall-time flip=true is-live=true
video_debug=True
audio.original=0+1

[source.gst2]
kind=gst
audio_source=audiotestsrc freq=1200
audio_debug=True
video_source=videotestsrc pattern=red ! textoverlay text=hello
video_debug=True

[source.gst3]
kind=gst
audio_debug=True
video_source=videotestsrc pattern=blue ! textoverlay text='good bye'
video_debug=True

[source.gst4]
kind=gst
audio_debug=True
video_source=multifilesrc location=data/images/voc2bg.png caps=image/png,width=1920,height=1080 loop=true ! queue ! pngdec ! videoscale ! videoconvert ! videorate ! queue
video_debug=True

[composites]
FULL.alpha-b = 0

[transitions]
FADE = 750, FULL / FULL
13 changes: 13 additions & 0 deletions configs/gstsource/gst_minimal.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[mix]
# core errors if there is only one source
sources = Gst,Test

[source.Gst]
kind=gst
audio.original=0+1

[composites]
FULL.alpha-b = 0

[transitions]
FADE = 750, FULL / FULL
25 changes: 25 additions & 0 deletions configs/gstsource/gst_vivid.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[mix]
sources = vivid,gsttst

[source.vivid]
kind=gst
audio_debug=True

# modprobe vivid
# v4l2-ctl --device /dev/v4l/by-path/platform-vivid.0-video-index0 --set-ctrl show_square=1
video_source=v4l2src device=/dev/v4l/by-path/platform-vivid.0-video-index0
video_debug=True

audio.original=0+1

[source.gsttst]
kind=gst
audio_debug=True
video_source=videotestsrc pattern=ball motion=hsweep animation-mode=wall-time flip=true is-live=true
video_debug=True

[composites]
FULL.alpha-b = 0

[transitions]
FADE = 750, FULL / FULL
4 changes: 2 additions & 2 deletions vocto/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
os.environ['GST_DEBUG_DUMP_DOT_DIR'] = os.getcwd()

def kind_has_audio(source: str) -> bool:
return source in ["aja", "decklink", "tcp", "test", "pa", "alsa"]
return source in ["aja", "decklink", "tcp", "test", "pa", "alsa", "gst"]

def kind_has_video(source: str) -> bool:
return source in ["aja", "decklink", "tcp", "test", "v4l2", "img", "file", "background", "RPICam"]
return source in ["aja", "decklink", "tcp", "test", "v4l2", "img", "file", "background", "RPICam", "gst"]
23 changes: 22 additions & 1 deletion vocto/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def getDeckLinkVideoMode(self, source) -> str:

def getDeckLinkVideoFormat(self, source) -> str:
return self.get('source.{}'.format(source), 'video_format', fallback='auto')

def getAJADeviceIdentifier(self, source) -> str:
return self.get(f'source.{source}', 'device', fallback='')

Expand Down Expand Up @@ -524,3 +524,24 @@ def source_has_audio(source: str) -> bool:
if internal:
sources.extend(self._getInternalSources())
return list(filter(source_has_audio, sources))

def getGstAudioPipe(self, source) -> str:
return self.get(f'source.{source}',
'audio_source',
fallback='audiotestsrc wave=ticks freq=330')

def getGstAudioDebug(self, source) -> bool:
return self.get(f'source.{source}',
'audio_debug',
fallback=False)

def getGstVideoPipe(self, source) -> str:
return self.get(f'source.{source}',
'video_source',
fallback='videotestsrc pattern=ball motion=hsweep animation-mode=wall-time')

def getGstVideoDebug(self, source) -> bool:
return self.get(f'source.{source}',
'video_debug',
fallback=False)

4 changes: 4 additions & 0 deletions voctocore/lib/sources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def spawn_source(name: str, port: Optional[int], has_audio: bool=True, has_video
from voctocore.lib.sources.pulseaudiosource import PulseAudioSource
from voctocore.lib.sources.alsaaudiosource import AlsaAudioSource

from voctocore.lib.sources.gstsource import GstAVSource

kind = Config.getSourceKind(name)

if kind == 'img':
Expand All @@ -41,6 +43,8 @@ def spawn_source(name: str, port: Optional[int], has_audio: bool=True, has_video
sources[name] = PulseAudioSource(name)
elif kind == 'alsa':
sources[name] = AlsaAudioSource(name)
elif kind == 'gst':
sources[name] = GstAVSource(name)
else:
if kind != 'test':
log.warning(
Expand Down
56 changes: 56 additions & 0 deletions voctocore/lib/sources/gstsource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
import logging

from gi.repository import Gst

from voctocore.lib.config import Config
from voctocore.lib.sources.avsource import AVSource


class GstAVSource(AVSource):
def __init__(self, name, has_audio=True, has_video=True,
force_num_streams=None):
super().__init__('GstAVSource', name, has_audio, has_video,
force_num_streams)

self.name = name
self.audio_source = Config.getGstAudioPipe(name)
self.audio_debug = Config.getGstAudioDebug(name)
self.video_source = Config.getGstVideoPipe(name)
self.video_debug = Config.getGstVideoDebug(name)
self.build_pipeline()

def num_connections(self):
return 1

def port(self):
if self.internal_audio_channels():
audio_hint=self.audio_source.split()[0]
else:
audio_hint="(None)"
if self.has_video:
video_hint=self.video_source.split()[0]
else:
video_hint="(None)"

return f"(AV:{audio_hint}+{video_hint})"

def __str__(self):
return f'GSTSource[{self.name}] ({self.port()})'

def build_audioport(self):
return self.audio_source

def build_videoport(self):
vpipe=self.video_source

texts=[]
if self.audio_debug:
texts.append(self.audio_source)
if self.video_debug:
texts.append(self.video_source)
if texts:
text = "\n".join(texts)
vpipe+=f' ! clockoverlay text="{self.name=}\n{text}\n" halignment=left line-alignment=left'

return vpipe
4 changes: 4 additions & 0 deletions voctocore/lib/sources/v4l2source.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ def build_source(self):
! videoconvert
! videoscale
! videorate
"""
pipe = f'fallbacksrc source="{pipe}"'

pipe += """\
name=vout-{name}
""".format(name=self.name)

Expand Down