Skip to content

Commit

Permalink
#835:
Browse files Browse the repository at this point in the history
* auto-tune the av-sync latency based on the sound codec
* expose the values via xpra info

git-svn-id: https://xpra.org/svn/Xpra/trunk@9381 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed May 15, 2015
1 parent 77744dd commit daaced2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
28 changes: 23 additions & 5 deletions src/xpra/server/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
self.sound_sink = None
self.av_sync = av_sync
self.av_sync_delay = 0
self.av_sync_delay_total = 0

self.server_core_encodings = core_encodings
self.server_encodings = encodings
Expand Down Expand Up @@ -614,7 +615,7 @@ def parse_batch_int(value, varname):
self.set_av_sync_delay(int(self.av_sync and av_sync) * c.intget("av-sync.delay.default", 150))
soundlog("pulseaudio id=%s, server=%s, sound decoders=%s, sound encoders=%s, receive=%s, send=%s",
self.pulseaudio_id, self.pulseaudio_server, self.sound_decoders, self.sound_encoders, self.sound_receive, self.sound_send)
avsynclog("av-sync: server=%s, client=%s, delay=%s", self.av_sync, av_sync, self.av_sync_delay)
avsynclog("av-sync: server=%s, client=%s, total=%s", self.av_sync, av_sync, self.av_sync_delay_total)

log("cursors=%s, bell=%s, notifications=%s", self.send_cursors, self.send_bell, self.send_notifications)
log("client uuid %s", self.uuid)
Expand Down Expand Up @@ -820,6 +821,7 @@ def new_stream(self, sound_source, codec):
{"start-of-stream" : True,
"codec" : sound_source.codec,
"sequence" : sound_source.sequence})
self.update_av_sync_delay_total()

def new_sound_buffer(self, sound_source, data, metadata):
soundlog("new_sound_buffer(%s, %s, %s) suspended=%s",
Expand Down Expand Up @@ -955,10 +957,24 @@ def sink_clean():
def set_av_sync_delay(self, v):
#update all window sources with the given delay
assert self.av_sync, "av-sync is not enabled"
self.av_sync_delay = min(1000, max(0, int(v) + AV_SYNC_DELTA))
avsynclog("av-sync set to %ims (from value=%s and delta=%s)", self.av_sync_delay, v, AV_SYNC_DELTA)
self.av_sync_delay = v
self.update_av_sync_delay_total()

def update_av_sync_delay_total(self):
encoder_latency = 0
ss = self.sound_source
if ss:
try:
from xpra.sound.gstreamer_util import ENCODER_LATENCY
encoder_latency = ENCODER_LATENCY.get(ss.codec, 0)
avsynclog("encoder_latency(%s)=%s", ss.codec, encoder_latency)
except Exception as e:
encoder_latency = 0
avsynclog("failed to get encoder latency for %s: %s", ss.codec, e)
self.av_sync_delay_total = min(1000, max(0, int(self.av_sync_delay) + AV_SYNC_DELTA + encoder_latency))
avsynclog("av-sync set to %ims (from client queue latency=%s, encoder latency=%s, env delta=%s)", self.av_sync_delay_total, self.av_sync_delay, encoder_latency, AV_SYNC_DELTA)
for ws in self.window_sources.values():
ws.av_sync_delay = v
ws.av_sync_delay = self.av_sync_delay_total


def set_screen_sizes(self, screen_sizes):
Expand Down Expand Up @@ -1187,7 +1203,9 @@ def up(prefix, d):
up("encoding", self.default_encoding_options)
up("encoding", self.encoding_options)
up("connection", self.protocol.get_info())
up("av-sync", {"delay" :self.av_sync_delay})
up("av-sync", {"client.delay" : self.av_sync_delay,
"total" : self.av_sync_delay_total,
"delta" : AV_SYNC_DELTA})
info.update(self.get_sound_info())
info.update(self.get_features_info())
info.update(self.get_screen_info())
Expand Down
22 changes: 20 additions & 2 deletions src/xpra/sound/gstreamer_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,27 @@ def get_queue_time(default_value=450, prefix=""):
]
CODECS = {}

#these encoders require an "audioconvert" element:
ENCODER_NEEDS_AUDIOCONVERT = ("flacenc", )

CODEC_ORDER = [MP3, WAVPACK, WAV, FLAC, SPEEX, OPUS]
#options we use to tune for low latency:
ENCODER_DEFAULT_OPTIONS = {
"lamemp3enc" : {"encoding-engine-quality": 0}, #"fast"
"wavpackenc" : {"mode" : 1}, #"fast" (0 aka "very fast" is not supported)
"flacenc" : {"quality" : 0}, #"fast"
"opusenc" : {"cbr" : 0,
"complexity" : 0},
}
#based on the encoder options above:
ENCODER_LATENCY = {
MP3 : 250,
FLAC : 150,
WAV : 0,
WAVPACK : 600,
OPUS : 500,
SPEEX : 500,
}

CODEC_ORDER = [FLAC, MP3, WAVPACK, WAV] #, SPEEX, OPUS, VORBIS, AAC]
#CODEC_ORDER = [MP3, FLAC, SPEEX]


Expand Down

0 comments on commit daaced2

Please sign in to comment.