Skip to content

Commit

Permalink
#669:
Browse files Browse the repository at this point in the history
* make it more OO-style: move common code and attributes to utility superclasses
* add docstrings
* cleanup, etc

git-svn-id: https://xpra.org/svn/Xpra/trunk@8820 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Mar 23, 2015
1 parent 07dea50 commit 3792775
Showing 1 changed file with 53 additions and 29 deletions.
82 changes: 53 additions & 29 deletions src/xpra/sound/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@
# The input can be a regular xpra packet, those are converted into method calls

class sound_subprocess(subprocess_callee):
""" Utility superclass for sound subprocess wrappers
(see sound_record and sound_play below)
"""
def __init__(self, wrapped_object, method_whitelist, exports_list):
#add bits common to both record and play:
methods = method_whitelist+["set_volume", "stop"]
exports = ["state-changed", "bitrate-changed", "error"] + exports_list
subprocess_callee.__init__(self, wrapped_object=wrapped_object, method_whitelist=methods)
for x in exports:
self.connect_export(x)

def start(self):
if EXPORT_INFO_TIME>0:
Expand All @@ -55,33 +65,40 @@ def stop(self):
self.wrapped_object = None
subprocess_callee.stop(self)

def export_info(self):
self.send("info", self.wrapped_object.get_info())


class sound_record(sound_subprocess):
""" wraps SoundSource as a subprocess """
def __init__(self, *pipeline_args):
from xpra.sound.src import SoundSource
sound_pipeline = SoundSource(*pipeline_args)
sound_subprocess.__init__(self, sound_pipeline, [], ["new-stream", "new-buffer"])

def make_protocol(self):
#overriden so we can tell that "new-buffer" is a large packet:
p = subprocess_callee.make_protocol(self)
p.large_packets = ["new-buffer"]
return p

def export_info(self):
self.send("info", self.wrapped_object.get_info())
class sound_play(sound_subprocess):
""" wraps SoundSink as a subprocess """
def __init__(self, *pipeline_args):
from xpra.sound.sink import SoundSink
sound_pipeline = SoundSink(*pipeline_args)
sound_subprocess.__init__(self, sound_pipeline, ["add_data"], ["underrun", "overrun"])


def run_sound(mode, error_cb, options, args):
""" this function just parses command line arguments to feed into the sound subprocess class,
which in turn just feeds them into the sound pipeline class (sink.py or src.py)
"""
assert len(args)>=6, "not enough arguments"
#common to both sink and src:
exports = ["state-changed", "bitrate-changed",
"error"]
methods = ["set_volume", "stop"]
if mode=="_sound_record":
from xpra.sound.src import SoundSource
gst_wrapper = SoundSource
exports += ["new-stream", "new-buffer"]
subproc = sound_record
elif mode=="_sound_play":
from xpra.sound.sink import SoundSink
gst_wrapper = SoundSink
#def eos(*args):
# gobject.idle_add(mainloop.quit)
#signal_handlers["eos"] = eos
methods += ["add_data"]
exports += ["underrun", "overrun"]
subproc = sound_play
else:
raise Exception("unknown mode: %s" % mode)

Expand All @@ -100,22 +117,26 @@ def run_sound(mode, error_cb, options, args):
except:
volume = 1.0

ss = None
try:
pipeline = gst_wrapper(plugin, options, codecs, codec_options, volume)
ss = sound_subprocess(wrapped_object=pipeline, method_whitelist=methods)
for x in exports:
ss.connect_export(x)
ss = subproc(plugin, options, codecs, codec_options, volume)
ss.start()
return 0
except Exception:
log.error("run_sound%s error", (mode, error_cb, options, args), exc_info=True)
return 1
finally:
ss.stop()
if ss:
ss.stop()


class sound_subprocess_wrapper(subprocess_caller):

""" This utility superclass deals with the caller side of the sound subprocess wrapper:
* starting the wrapper subprocess
* handling state-changed signal so we have a local copy of the current value ready
* handle "info" packets so we have a cached copy
* forward get/set volume calls (get_volume uses the value found in "info")
"""
def __init__(self):
subprocess_caller.__init__(self, description="sound")
self.state = "stopped"
Expand Down Expand Up @@ -150,13 +171,6 @@ def get_volume(self):
return self.last_info.get("volume", 100)/100.0


def make_protocol(self):
""" add some 'large packets' to the list """
protocol = subprocess_caller.make_protocol(self)
protocol.large_packets = ["new-buffer", "add_data"]
return protocol


def _add_debug_args(self):
from xpra.log import debug_enabled_categories
debug = SUBPROCESS_DEBUG[:]
Expand All @@ -173,6 +187,11 @@ def __init__(self, plugin, options, codecs, volume, element_options):
self.command = [get_sound_executable(), "_sound_record", "-", "-", plugin or "", "", ",".join(codecs), "", str(volume)]
self._add_debug_args()

def make_protocol(self):
protocol = subprocess_caller.make_protocol(self)
protocol.large_packets = ["new-buffer"]
return protocol

def __repr__(self):
return "source_subprocess_wrapper(%s)" % self.process

Expand All @@ -185,6 +204,11 @@ def __init__(self, plugin, options, codec, volume, element_options):
self.command = [get_sound_executable(), "_sound_play", "-", "-", plugin or "", "", codec, "", str(volume)]
self._add_debug_args()

def make_protocol(self):
protocol = subprocess_caller.make_protocol(self)
protocol.large_packets = ["add_data"]
return protocol

def add_data(self, data, metadata):
if DEBUG_SOUND:
log("add_data(%s bytes, %s) forwarding to %s", len(data), metadata, self.protocol)
Expand Down

0 comments on commit 3792775

Please sign in to comment.