Skip to content

Commit

Permalink
split code into more readable functions
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed Aug 18, 2021
1 parent abfccbd commit 592da90
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 151 deletions.
2 changes: 1 addition & 1 deletion html5/js/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
const XPRA_CLIENT_FORCE_NO_WORKER = false;
const CLIPBOARD_IMAGES = true;
const CLIPBOARD_EVENT_DELAY = 100;
const DECODE_WORKER = !Utilities.isMobile();
const DECODE_WORKER = true;
const rencode_ok = rencode && rencode_selftest();

function XpraClient(container) {
Expand Down
306 changes: 156 additions & 150 deletions html5/js/DecodeWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,171 +96,177 @@ function close_broadway(wid) {

const on_hold = new Map();

onmessage = function(e) {
var data = e.data;
switch (data.cmd) {
case 'check':
self.postMessage({'result': true});
break;
case 'eos':
close_broadway(data.wid);
if (data.wid in on_hold) {
on_hold.remove(data.wid);
}
//console.log("decode worker eos for wid", wid);
break;
case 'decode':
const packet = data.packet,
wid = packet[1],
width = packet[4],
height = packet[5],
coding = packet[6],
packet_sequence = packet[8];
let wid_hold = on_hold.get(wid);
//console.log("packet to decode:", data.packet);
function send_back(raw_buffers) {
//console.log("send_back: wid_hold=", wid_hold);
if (wid_hold) {
//find the highest sequence number which is still lower than this packet
let seq_holding = 0;
for (let seq of wid_hold.keys()) {
if (seq>seq_holding && seq<packet_sequence) {
seq_holding = seq;
}
function decode_eos(wid) {
close_broadway(wid);
if (wid in on_hold) {
on_hold.remove(wid);
}
}

function decode_draw_packet(packet) {
const wid = packet[1],
width = packet[4],
height = packet[5],
coding = packet[6],
packet_sequence = packet[8];
let wid_hold = on_hold.get(wid);
//console.log("packet to decode:", data.packet);
function send_back(raw_buffers) {
//console.log("send_back: wid_hold=", wid_hold);
if (wid_hold) {
//find the highest sequence number which is still lower than this packet
let seq_holding = 0;
for (let seq of wid_hold.keys()) {
if (seq>seq_holding && seq<packet_sequence) {
seq_holding = seq;
}
if (seq_holding) {
const held = wid_hold.get(seq_holding);
if (held) {
held.push([packet, raw_buffers]);
return;
}
}
if (seq_holding) {
const held = wid_hold.get(seq_holding);
if (held) {
held.push([packet, raw_buffers]);
return;
}
}
self.postMessage({'draw': packet}, raw_buffers);
}
function do_send_back(p, raw_buffers) {
self.postMessage({'draw': p}, raw_buffers);
}
function decode_error(msg) {
self.postMessage({'error': msg, 'packet' : packet});
}
self.postMessage({'draw': packet}, raw_buffers);
}
function do_send_back(p, raw_buffers) {
self.postMessage({'draw': p}, raw_buffers);
}
function decode_error(msg) {
self.postMessage({'error': msg, 'packet' : packet});
}

function send_rgb32_back(data, width, height, options) {
const img = new ImageData(new Uint8ClampedArray(data.buffer), width, height);
createImageBitmap(img, 0, 0, width, height, options).then(function(bitmap) {
packet[6] = "bitmap:rgb32";
packet[7] = bitmap;
send_back([bitmap]);
}, decode_error);
}
function send_rgb32_back(data, width, height, options) {
const img = new ImageData(new Uint8ClampedArray(data.buffer), width, height);
createImageBitmap(img, 0, 0, width, height, options).then(function(bitmap) {
packet[6] = "bitmap:rgb32";
packet[7] = bitmap;
send_back([bitmap]);
}, decode_error);
}

try {
if (coding=="rgb24" || coding=="rgb32") {
const data = decode_rgb(packet);
send_rgb32_back(data, width, height, {
"premultiplyAlpha" : "none",
});
try {
if (coding=="rgb24" || coding=="rgb32") {
const data = decode_rgb(packet);
send_rgb32_back(data, width, height, {
"premultiplyAlpha" : "none",
});
}
else if (coding=="png" || coding=="jpeg" || coding=="webp") {
const data = packet[7];
const blob = new Blob([data.buffer]);
//we're loading asynchronously
//so ensure that any packet sequence arriving after this one will be put on hold
//until we have finished decoding this one:
if (!wid_hold) {
wid_hold = new Map();
on_hold.set(wid, wid_hold);
}
else if (coding=="png" || coding=="jpeg" || coding=="webp") {
const data = packet[7];
const blob = new Blob([data.buffer]);
//we're loading asynchronously
//so ensure that any packet sequence arriving after this one will be put on hold
//until we have finished decoding this one:
if (!wid_hold) {
wid_hold = new Map();
on_hold.set(wid, wid_hold);
}
//console.log("holding=", packet_sequence);
wid_hold[packet_sequence] = [];
function release() {
//release any packets held back by this image:
const held = wid_hold[packet_sequence];
//console.log("release held=", held);
if (held) {
let i;
for (i=0; i<held.length; i++) {
const held_packet = held[i][0];
const held_raw_buffers = held[i][1];
do_send_back(held_packet, held_raw_buffers);
}
wid_hold.delete(packet_sequence);
//console.log("wid_hold=", wid_hold, "on_hold=", on_hold);
if (wid_hold.size==0 && on_hold.has(wid)) {
on_hold.delete(wid);
}
//console.log("holding=", packet_sequence);
wid_hold[packet_sequence] = [];
function release() {
//release any packets held back by this image:
const held = wid_hold[packet_sequence];
//console.log("release held=", held);
if (held) {
let i;
for (i=0; i<held.length; i++) {
const held_packet = held[i][0];
const held_raw_buffers = held[i][1];
do_send_back(held_packet, held_raw_buffers);
}
wid_hold.delete(packet_sequence);
//console.log("wid_hold=", wid_hold, "on_hold=", on_hold);
if (wid_hold.size==0 && on_hold.has(wid)) {
on_hold.delete(wid);
}
}
createImageBitmap(blob).then(function(bitmap) {
packet[6] = "bitmap:"+coding;
packet[7] = bitmap;
send_back([bitmap]);
release();
}, function(e) {
decode_error(e);
release();
}
createImageBitmap(blob).then(function(bitmap) {
packet[6] = "bitmap:"+coding;
packet[7] = bitmap;
send_back([bitmap]);
release();
}, function(e) {
decode_error(e);
release();
});
}
else if (coding=="h264") {
let options = {};
if (packet.length>10)
options = packet[10];
const data = packet[7];
let enc_width = width;
let enc_height = height;
const scaled_size = options["scaled_size"];
if (scaled_size) {
enc_width = scaled_size[0];
enc_height = scaled_size[1];
delete options["scaled-size"];
}
const frame = options["frame"] || 0;
if (frame==0) {
close_broadway();
}
let decoder = broadway_decoders[wid];
if (decoder && (decoder._enc_size[0]!=enc_width || decoder._enc_size[1]!=enc_height)) {
close_broadway();
decoder = null;
}
//console.log("decoder=", decoder);
if (!decoder) {
decoder = new Decoder({
"rgb": true,
"size": { "width" : enc_width, "height" : enc_height },
});
decoder._enc_size = [enc_width, enc_height];
broadway_decoders[wid] = decoder;
}
else if (coding=="h264") {
let options = {};
if (packet.length>10)
options = packet[10];
const data = packet[7];
let enc_width = width;
let enc_height = height;
const scaled_size = options["scaled_size"];
if (scaled_size) {
enc_width = scaled_size[0];
enc_height = scaled_size[1];
delete options["scaled-size"];
}
const frame = options["frame"] || 0;
if (frame==0) {
close_broadway();
}
let decoder = broadway_decoders[wid];
if (decoder && (decoder._enc_size[0]!=enc_width || decoder._enc_size[1]!=enc_height)) {
close_broadway();
decoder = null;
}
//console.log("decoder=", decoder);
if (!decoder) {
decoder = new Decoder({
"rgb": true,
"size": { "width" : enc_width, "height" : enc_height },
let count = 0;
decoder.onPictureDecoded = function(buffer, p_width, p_height, infos) {
//console.log("broadway frame: enc size=", enc_width, enc_height, ", decode size=", p_width, p_height);
count++;
//forward it as rgb32:
send_rgb32_back(buffer, p_width, p_height, {
"premultiplyAlpha" : "none",
"resizeWidth" : width,
"resizeHeight" : height,
"resizeQuality" : "medium",
});
decoder._enc_size = [enc_width, enc_height];
broadway_decoders[wid] = decoder;
}
let count = 0;
decoder.onPictureDecoded = function(buffer, p_width, p_height, infos) {
//console.log("broadway frame: enc size=", enc_width, enc_height, ", decode size=", p_width, p_height);
count++;
//forward it as rgb32:
send_rgb32_back(buffer, p_width, p_height, {
"premultiplyAlpha" : "none",
"resizeWidth" : width,
"resizeHeight" : height,
"resizeQuality" : "medium",
});
};
// we can pass a buffer full of NALs to decode() directly
// as long as they are framed properly with the NAL header
decoder.decode(data);
// broadway decoding is actually synchronous
// and onPictureDecoded is called from decode(data) above.
if (count==0) {
decode_error("no "+coding+" picture decoded");
}
}
else {
//pass-through:
send_back([]);
};
// we can pass a buffer full of NALs to decode() directly
// as long as they are framed properly with the NAL header
decoder.decode(data);
// broadway decoding is actually synchronous
// and onPictureDecoded is called from decode(data) above.
if (count==0) {
decode_error("no "+coding+" picture decoded");
}
}
catch (e) {
decode_error(e);
else {
//pass-through:
send_back([]);
}
}
catch (e) {
decode_error(e);
}
}

onmessage = function(e) {
const data = e.data;
switch (data.cmd) {
case 'check':
self.postMessage({'result': true});
break;
case 'eos':
decode_eos(data.wid);
break;
case 'decode':
decode_draw_packet(data.packet);
break
default:
console.error("decode worker got unknown message: "+data.cmd);
Expand Down

0 comments on commit 592da90

Please sign in to comment.