Skip to content

Commit

Permalink
#669:
Browse files Browse the repository at this point in the history
* logging tweaks
* log restart delay (and simplify delay calculation)
* always include a sound sequence: start at 0 (so we can distinguish when one is not present)
* discard sound buffers on the server side if the sequence has been bumped
* associate the sequence number with a sound_source (that's the point)

git-svn-id: https://xpra.org/svn/Xpra/trunk@8966 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Apr 8, 2015
1 parent 1fd46bf commit d58dbaf
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 26 deletions.
36 changes: 19 additions & 17 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1606,16 +1606,18 @@ def sink_ready(*args):

def stop_receiving_sound(self, tell_server=True):
""" ask the server to stop sending sound, toggle flag so we ignore further packets and emit client signal """
soundlog("stop_receiving_sound() sound sink=%s", self.sound_sink)
soundlog("stop_receiving_sound(%s) sound sink=%s", tell_server, self.sound_sink)
ss = self.sound_sink
self.speaker_enabled = False
if tell_server:
self.send("sound-control", "stop")
if ss is None:
return
self.sound_sink = None
soundlog("stop_receiving_sound(%s) calling %s", tell_server, ss.cleanup)
ss.cleanup()
self.emit("speaker-changed")
soundlog("stop_receiving_sound(%s) done", tell_server)

def bump_sound_sequence(self):
if self.server_sound_sequence:
Expand Down Expand Up @@ -1660,16 +1662,14 @@ def sound_sink_overrun(self, sound_sink, *args):
self.min_sound_sequence += 1
self.stop_receiving_sound()
def restart():
soundlog("sound_sink=%s, codec=%s, server_sound_sequence=%s", self.sound_sink, codec, self.server_sound_sequence)
soundlog("restarting sound sound_sink=%s, codec=%s, server_sound_sequence=%s", self.sound_sink, codec, self.server_sound_sequence)
if self.server_sound_sequence:
self.send_new_sound_sequence()
self.start_receiving_sound()
#by default for older servers,
#wait before restarting so we can process the "end-of-stream" message:
delay = 500
if self.server_sound_eos_sequence:
#no need to wait, we won't mistakenly stop() the wrong sink:
delay = 0
delay = 500 * int(not self.server_sound_eos_sequence)
soundlog("sound_sink_overrun() will restart in %ims (server supports eos sequence: %s)", delay, self.server_sound_eos_sequence)
self.timeout_add(delay, restart)

def start_sound_sink(self, codec):
Expand Down Expand Up @@ -1707,6 +1707,12 @@ def _process_sound_data(self, packet):
metadata = typedict(metadata)
if data:
self.sound_in_bytecount += len(data)
#verify sequence number if present:
seq = metadata.intget("sequence", -1)
if self.min_sound_sequence>0 and seq>=0 and seq<self.min_sound_sequence:
soundlog("ignoring sound data with old sequence number %s", seq)
return

if not self.speaker_enabled:
if metadata.boolget("start-of-stream"):
#server is asking us to start playing sound
Expand All @@ -1723,23 +1729,19 @@ def _process_sound_data(self, packet):
else:
soundlog("speaker is now disabled - dropping packet")
return
seq = metadata.intget("sequence", -1)
if self.min_sound_sequence>0 and seq>=0 and seq<self.min_sound_sequence:
soundlog("ignoring sound data with old sequence number %s", seq)
return
ss = self.sound_sink
if metadata.boolget("end-of-stream"):
if self.sound_sink:
soundlog("server sent end-of-stream, closing sound pipeline")
if ss:
soundlog("server sent end-of-stream for sequence %s, closing sound pipeline", seq)
self.stop_receiving_sound(False)
return
ss = self.sound_sink
if ss is not None and codec!=self.sound_sink.codec:
log.error("sound codec change not supported! (from %s to %s)", ss.codec, codec)
ss.stop()
return
if ss is None:
soundlog("no sound sink to process sound data, dropping it")
return
if codec!=ss.codec:
log.error("sound codec change not supported! (from %s to %s)", ss.codec, codec)
ss.stop()
return
elif ss.get_state()=="stopped":
soundlog("sound data received, sound sink is stopped - starting it")
ss.start()
Expand Down
21 changes: 12 additions & 9 deletions src/xpra/server/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
self.speaker_codecs = speaker_codecs
self.supports_microphone = supports_microphone
self.microphone_codecs = microphone_codecs
self.sound_source_sequence = -1
self.sound_source_sequence = 0
self.sound_source = None
self.sound_sink = None

Expand Down Expand Up @@ -777,6 +777,7 @@ def start_sending_sound(self, codec, volume=1.0):
self.sound_source = start_sending_sound(self.sound_source_plugin, codec, volume, self.sound_decoders, self.pulseaudio_server, self.pulseaudio_id)
soundlog("start_sending_sound() sound source=%s", self.sound_source)
if self.sound_source:
self.sound_source.sequence = self.sound_source_sequence
self.sound_source.connect("new-buffer", self.new_sound_buffer)
self.sound_source.connect("new-stream", self.new_stream)
self.sound_source.start()
Expand All @@ -791,7 +792,7 @@ def stop_sending_sound(self):
if self.server_driven:
#tell the client this is the end:
self.send("sound-data", ss.codec, "", {"end-of-stream" : True,
"sequence" : self.sound_source_sequence})
"sequence" : ss.sequence})
ss.cleanup()

def new_stream(self, sound_source, codec):
Expand All @@ -805,15 +806,17 @@ def new_stream(self, sound_source, codec):
self.send("sound-data", self.sound_source.codec, "",
{"start-of-stream" : True,
"codec" : self.sound_source.codec,
"sequence" : self.sound_source_sequence})
"sequence" : self.sound_source.sequence})

def new_sound_buffer(self, sound_source, data, metadata):
soundlog("new_sound_buffer(%s, %s, %s) suspended=%s, sequence=%s",
sound_source, len(data or []), metadata, self.suspended, self.sound_source_sequence)
if self.sound_source is None or self.is_closed():
soundlog("new_sound_buffer(%s, %s, %s) suspended=%s",
sound_source, len(data or []), metadata, self.suspended)
if self.sound_source!=sound_source or self.is_closed():
return
if self.sound_source_sequence>0:
metadata["sequence"] = self.sound_source_sequence
if sound_source.sequence<self.sound_source_sequence:
return
if self.sound_source.sequence>=0:
metadata["sequence"] = self.sound_source.sequence
self.send("sound-data", self.sound_source.codec, Compressed(self.sound_source.codec, data), metadata)

def stop_receiving_sound(self):
Expand Down Expand Up @@ -876,7 +879,7 @@ def fadeout():
return False
self.timeout_add(100, fadeout)
elif action=="new-sequence":
self.sound_source_sequence = args[0]
self.sound_source_sequence = int(args[0])
return "new sequence is %s" % self.sound_source_sequence
#elif action=="quality":
# assert self.sound_source
Expand Down

0 comments on commit d58dbaf

Please sign in to comment.