diff --git a/playback.js b/playback.js index 1d89719435ef01c1fa9338251931a2d2171d5881..f10a07144df7e887d966d46d9399f4d141db8270 100644 --- a/playback.js +++ b/playback.js @@ -89,15 +89,6 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg) { var data = new SpiceMsgPlaybackData(msg.data); - // If this packet has the same time as the last, just bump up by one. - if (this.last_data_time && data.time <= this.last_data_time) - { - // FIXME - this is arguably wrong. But delaying the transmission was worse, - // in initial testing. Could use more research. - PLAYBACK_DEBUG > 1 && console.log("Hacking time of " + data.time + " to " + this.last_data_time + 1); - data.time = this.last_data_time + 1; - } - if (! this.source_buffer) return true; @@ -110,8 +101,35 @@ SpicePlaybackConn.prototype.process_channel_message = function(msg) this.audio.currentTime = this.audio.buffered.start(this.audio.buffered.length - 1); } - this.last_data_time = data.time; + /* Around version 45, Firefox started being very particular about the + time stamps put into the Opus stream. The time stamps from the Spice server are + somewhat irregular. They mostly arrive every 10 ms, but sometimes it is 11, or sometimes + with two time stamps the same in a row. The previous logic resulted in fuzzy and/or + distorted audio streams in Firefox in a row. + + In theory, the sequence mode should be appropriate for us, but as of 09/27/2016, + I was unable to make sequence mode work with Firefox. + Thus, we end up with an inelegant hack. Essentially, we force every packet to have + a 10ms time delta, unless there is an obvious gap in time stream, in which case we + will resync. + */ + + if (this.start_time != 0 && data.time != (this.last_data_time + EXPECTED_PACKET_DURATION)) + { + if (Math.abs(data.time - (EXPECTED_PACKET_DURATION + this.last_data_time)) < MAX_CLUSTER_TIME) + { + PLAYBACK_DEBUG > 1 && console.log("Hacking time of " + data.time + " to " + + (this.last_data_time + EXPECTED_PACKET_DURATION)); + data.time = this.last_data_time + EXPECTED_PACKET_DURATION; + } + else + { + PLAYBACK_DEBUG > 1 && console.log("Apparent gap in audio time; now is " + data.time + " last was " + this.last_data_time); + } + } + + this.last_data_time = data.time; PLAYBACK_DEBUG > 1 && console.log("PlaybackData; time " + data.time + "; length " + data.data.byteLength); diff --git a/webm.js b/webm.js index 8faa8e7edc5e77c3b7bfbde28784d16d7ae803d0..789da1441647a7c40aedbf1c32b83b9e503d5391 100644 --- a/webm.js +++ b/webm.js @@ -84,6 +84,7 @@ var OPUS_CHANNELS = 2; var SPICE_PLAYBACK_CODEC = 'audio/webm; codecs="opus"'; var MAX_CLUSTER_TIME = 1000; +var EXPECTED_PACKET_DURATION = 10; var GAP_DETECTION_THRESHOLD = 50; var SPICE_VP8_CODEC = 'video/webm; codecs="vp8"';