Skip to content

Commit 1c8f1b1

Browse files
authored
Merge pull request #11 from Kitware/fixes-vue-2-and-3
Fixes for vue 2 and 3
2 parents f3d6e64 + 12857b8 commit 1c8f1b1

File tree

6 files changed

+123
-70
lines changed

6 files changed

+123
-70
lines changed

vue-components/src/components/ImageDisplayArea.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export default {
4545
displayURL: '',
4646
};
4747
},
48+
expose: ['resetContent', 'updatePoolSize'],
4849
methods: {
4950
resetContent() {
5051
this.hasContent = false;
@@ -57,6 +58,17 @@ export default {
5758
this.frames.pop();
5859
}
5960
},
61+
cleanup() {
62+
if (this.wslinkSubscription) {
63+
if (this.trame) {
64+
this.trame.client
65+
.getConnection()
66+
.getSession()
67+
.unsubscribe(this.wslinkSubscription);
68+
this.wslinkSubscription = null;
69+
}
70+
}
71+
},
6072
},
6173
created() {
6274
// Image decoding
@@ -84,16 +96,12 @@ export default {
8496
.subscribe('trame.rca.topic.stream', this.onImage);
8597
}
8698
},
99+
// support both vue2 and vue3 cleanup functions
100+
beforeDestroy() {
101+
this.cleanup();
102+
},
87103
beforeUnmount() {
88-
if (this.wslinkSubscription) {
89-
if (this.trame) {
90-
this.trame.client
91-
.getConnection()
92-
.getSession()
93-
.unsubscribe(this.wslinkSubscription);
94-
this.wslinkSubscription = null;
95-
}
96-
}
104+
this.cleanup();
97105
},
98106
inject: ['trame'],
99107
template: `<img :src="displayURL" v-show="hasContent" />`,

vue-components/src/components/MediaSourceDisplayArea.js

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,27 @@ export default {
8080
received: 0,
8181
};
8282
},
83+
expose: ['requestInitializationSegment'],
8384
methods: {
8485
requestInitializationSegment() {
8586
if (this.rcaPushSize) {
8687
this.rcaPushSize({ videoHeader: 1 });
8788
}
8889
},
90+
cleanup() {
91+
// unsub trame.rca.topic.stream
92+
if (this.wslinkSubscription) {
93+
if (this.trame) {
94+
this.trame.client
95+
.getConnection()
96+
.getSession()
97+
.unsubscribe(this.wslinkSubscription);
98+
this.wslinkSubscription = null;
99+
// shutdown decoder
100+
this.decoder.exit();
101+
}
102+
}
103+
},
89104
},
90105
created() {
91106
this.pushChunk = (bytes, mime) => {
@@ -111,14 +126,17 @@ export default {
111126
};
112127
},
113128
mounted() {
114-
this.onChunkAvailable = ([{ name, meta, content }]) => {
129+
this.onChunkAvailable = async ([{ name, meta, content }]) => {
115130
if (!meta.type.includes('video/')) {
116131
this.hasContent = false;
117132
return;
118133
}
119134
if (this.name === name) {
120135
this.received += 1;
121-
content.arrayBuffer().then((v) => this.pushChunk(v, meta.type));
136+
const v = content.buffer
137+
? content
138+
: new Uint8Array(await content.arrayBuffer());
139+
this.pushChunk(v, meta.type);
122140
this.hasContent = true;
123141
}
124142
};
@@ -131,18 +149,10 @@ export default {
131149
}
132150
},
133151
beforeUnmount() {
134-
// unsub trame.rca.topic.stream
135-
if (this.wslinkSubscription) {
136-
if (this.trame) {
137-
this.trame.client
138-
.getConnection()
139-
.getSession()
140-
.unsubscribe(this.wslinkSubscription);
141-
this.wslinkSubscription = null;
142-
// shutdown decoder
143-
this.decoder.exit();
144-
}
145-
}
152+
this.cleanup();
153+
},
154+
beforeDestroy() {
155+
this.cleanup();
146156
},
147157
inject: ['trame', 'rcaPushSize'],
148158
template: `

vue-components/src/components/RawImageDisplayArea.js

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,30 @@ export default {
1414
hasContent: false,
1515
};
1616
},
17+
methods: {
18+
cleanup() {
19+
// unsub trame.rca.topic.stream
20+
if (this.wslinkSubscription) {
21+
if (this.trame) {
22+
this.trame.client
23+
.getConnection()
24+
.getSession()
25+
.unsubscribe(this.wslinkSubscription);
26+
this.wslinkSubscription = null;
27+
}
28+
}
29+
},
30+
},
1731
mounted() {
1832
this.wslinkSubscription = null;
1933
const canvas = this.$el;
2034
const ctx = canvas.getContext('2d');
2135
this.onImage = async ([{ name, meta, content }]) => {
2236
if (this.name === name) {
2337
if (meta.type.includes('image/rgb24')) {
24-
const data = content.buffer ? content : new Uint8Array(await content.arrayBuffer());
38+
const data = content.buffer
39+
? content
40+
: new Uint8Array(await content.arrayBuffer());
2541
canvas.width = meta.w;
2642
canvas.height = meta.h;
2743
const imageData = ctx.createImageData(meta.w, meta.h);
@@ -37,7 +53,9 @@ export default {
3753
ctx.putImageData(imageData, 0, 0);
3854
this.hasContent = true;
3955
} else if (meta.type.includes('image/rgba32')) {
40-
const data = content.buffer ? content : new Uint8Array(await content.arrayBuffer());
56+
const data = new Uint8ClampedArray(
57+
content.buffer ? content : await content.arrayBuffer()
58+
);
4159
canvas.width = meta.w;
4260
canvas.height = meta.h;
4361
const imageData = new ImageData(data, meta.w, meta.h);
@@ -55,17 +73,12 @@ export default {
5573
.subscribe('trame.rca.topic.stream', this.onImage);
5674
}
5775
},
76+
// support both vue2 and vue3 unmount callbacks
77+
beforeDestroy() {
78+
this.cleanup();
79+
},
5880
beforeUnmount() {
59-
// unsub trame.rca.topic.stream
60-
if (this.wslinkSubscription) {
61-
if (this.trame) {
62-
this.trame.client
63-
.getConnection()
64-
.getSession()
65-
.unsubscribe(this.wslinkSubscription);
66-
this.wslinkSubscription = null;
67-
}
68-
}
81+
this.cleanup();
6982
},
7083
inject: ['trame'],
7184
template: '<canvas class="js-canvas" v-show="hasContent"></canvas>',

vue-components/src/components/StatisticsDisplay.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export default {
143143
this.monitor.newInteractionThreshold = v;
144144
},
145145
},
146+
expose: ['sizeUnit'],
146147
methods: {
147148
sizeUnit(v) {
148149
let value = v;
@@ -153,6 +154,18 @@ export default {
153154
value /= 1000;
154155
}
155156
},
157+
cleanup() {
158+
this.observer.unobserve(this.$el);
159+
if (this.wslinkSubscription) {
160+
if (this.trame) {
161+
this.trame.client
162+
.getConnection()
163+
.getSession()
164+
.unsubscribe(this.wslinkSubscription);
165+
this.wslinkSubscription = null;
166+
}
167+
}
168+
},
156169
draw(client, server, clientColor = '#1DE9B688', serverColor = '#EF9A9A') {
157170
if (!this.$el) {
158171
return;
@@ -243,17 +256,12 @@ export default {
243256
mounted() {
244257
this.observer.observe(this.$el);
245258
},
259+
// support both vue2 and vue3 unmount callbacks
260+
beforeDestroy() {
261+
this.cleanup();
262+
},
246263
beforeUnmount() {
247-
this.observer.unobserve(this.$el);
248-
if (this.wslinkSubscription) {
249-
if (this.trame) {
250-
this.trame.client
251-
.getConnection()
252-
.getSession()
253-
.unsubscribe(this.wslinkSubscription);
254-
this.wslinkSubscription = null;
255-
}
256-
}
264+
this.cleanup();
257265
},
258266
inject: ['trame'],
259267
template: `

vue-components/src/components/VideoDecoderDisplayArea.js

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,32 @@ export default {
1616
isSupported: 'VideoFrame' in window,
1717
};
1818
},
19-
created() {
20-
this.worker = new DecoderWorker();
19+
expose: [''],
20+
methods: {
21+
cleanup() {
22+
if (this.worker) {
23+
this.worker.terminate();
24+
}
25+
26+
// unsub trame.rca.topic.stream
27+
if (this.wslinkSubscription) {
28+
if (this.trame) {
29+
this.trame.client
30+
.getConnection()
31+
.getSession()
32+
.unsubscribe(this.wslinkSubscription);
33+
this.wslinkSubscription = null;
34+
}
35+
}
36+
},
2137
},
2238
mounted() {
39+
this.worker = new DecoderWorker();
2340
if (this.isSupported) {
2441
const canvas = this.$el.querySelector('.js-canvas');
2542
this.worker.bindCanvas(canvas);
2643

27-
this.onChunkAvailable = ([{ name, meta, content }]) => {
44+
this.onChunkAvailable = async ([{ name, meta, content }]) => {
2845
// when we do not get octet-stream or valid codec, terminate worker.
2946
if (
3047
!meta.type.includes('application/octet-stream') ||
@@ -36,9 +53,10 @@ export default {
3653

3754
if (this.name === name && meta.codec.length) {
3855
this.worker.setContentType(meta.codec, meta.w, meta.h);
39-
content.arrayBuffer().then((data) => {
40-
this.worker.pushChunk(meta.st, meta.key, data);
41-
});
56+
const data = content.buffer
57+
? content
58+
: new Uint8Array(await content.arrayBuffer());
59+
this.worker.pushChunk(meta.st, meta.key, data);
4260
}
4361
};
4462

@@ -50,23 +68,12 @@ export default {
5068
}
5169
}
5270
},
71+
// support both vue2 and vue3 unmount callbacks
5372
beforeUnmount() {
54-
if (this.worker) {
55-
this.worker.terminate();
56-
this.worker = null;
57-
}
58-
59-
// unsub trame.rca.topic.stream
60-
if (this.wslinkSubscription) {
61-
if (this.trame) {
62-
this.trame.client
63-
.getConnection()
64-
.getSession()
65-
.unsubscribe(this.wslinkSubscription);
66-
this.wslinkSubscription = null;
67-
}
68-
this.destroyDecoder();
69-
}
73+
this.cleanup();
74+
},
75+
beforeDestroy() {
76+
this.cleanup();
7077
},
7178
inject: ['trame', 'rcaPushSize'],
7279
template: `

vue-components/src/utils/decoder.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ onmessage = async function({ data: msg }) {
7070
this.decoder.reset();
7171
break;
7272
case 6: // close
73+
// flush before close() to avoid currepoted state.
74+
// calling postMessage(flush)
75+
// postMessage(close) is not enough since the second
76+
// abort the first before it finishes.
77+
await this.decoder.flush();
7378
this.decoder.close();
7479
break;
7580
}
@@ -121,7 +126,7 @@ export class DecoderWorker {
121126

122127
pushChunk(timestamp, type, data) {
123128
const action = CHUNK;
124-
this.worker.postMessage({ action, timestamp, type, data }, [data]);
129+
this.worker.postMessage({ action, timestamp, type, data }, [data.buffer]);
125130
}
126131

127132
flush() {
@@ -134,7 +139,9 @@ export class DecoderWorker {
134139

135140
terminate() {
136141
this.worker.postMessage({ action: CLOSE });
137-
this.worker.terminate();
138-
this.worker = null;
142+
// don't terminate immediately we need to wail for the video encoder to finish flushing
143+
// not sure how to achieve this ...
144+
//this.worker.terminate();
145+
//this.worker = null;
139146
}
140147
}

0 commit comments

Comments
 (0)