mirror of
https://github.com/jech/galene.git
synced 2024-12-22 07:15:47 +01:00
Move MediaPipe initialisation to filter init.
We used to initialise MediaPipe at worker start, which prevented us from handling errors. We now do it at filter init, and stop the stream with an error message if initialisation fails.
This commit is contained in:
parent
3fbe274785
commit
0a14b78d67
2 changed files with 46 additions and 29 deletions
|
@ -2,17 +2,15 @@
|
||||||
|
|
||||||
let imageSegmenter;
|
let imageSegmenter;
|
||||||
|
|
||||||
async function loadImageSegmenter() {
|
async function loadImageSegmenter(model) {
|
||||||
let module = await import('/third-party/tasks-vision/vision_bundle.mjs');
|
let module = await import('/third-party/tasks-vision/vision_bundle.mjs');
|
||||||
|
|
||||||
let vision = await module.FilesetResolver.forVisionTasks(
|
let vision = await module.FilesetResolver.forVisionTasks(
|
||||||
"/third-party/tasks-vision/wasm"
|
"/third-party/tasks-vision/wasm"
|
||||||
);
|
);
|
||||||
|
|
||||||
imageSegmenter =
|
return await module.ImageSegmenter.createFromOptions(vision, {
|
||||||
await module.ImageSegmenter.createFromOptions(vision, {
|
|
||||||
baseOptions: {
|
baseOptions: {
|
||||||
modelAssetPath: '/third-party/tasks-vision/models/selfie_segmenter.tflite',
|
modelAssetPath: model,
|
||||||
},
|
},
|
||||||
outputCategoryMask: true,
|
outputCategoryMask: true,
|
||||||
outputConfidenceMasks: false,
|
outputConfidenceMasks: false,
|
||||||
|
@ -20,19 +18,24 @@ async function loadImageSegmenter() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadImageSegmenter();
|
onmessage = async e => {
|
||||||
|
let data = e.data;
|
||||||
onmessage = e => {
|
if(imageSegmenter == null) {
|
||||||
let bitmap = e.data.bitmap;
|
try {
|
||||||
if(!(bitmap instanceof ImageBitmap)) {
|
imageSegmenter = await loadImageSegmenter(data.model);
|
||||||
postMessage(new Error('Bad type for worker data'));
|
if(imageSegmenter == null)
|
||||||
|
throw new Error("loadImageSegmenter returned null");
|
||||||
|
} catch(e) {
|
||||||
|
postMessage(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
postMessage(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!imageSegmenter) {
|
let bitmap = e.data.bitmap;
|
||||||
// not ready yet
|
if(!(bitmap instanceof ImageBitmap)) {
|
||||||
bitmap.close();
|
postMessage(new Error('Bad type for worker data'));
|
||||||
postMessage(null);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1188,6 +1188,30 @@ async function setFilter(c) {
|
||||||
c.userdata.filter = filter;
|
c.userdata.filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to a worker, then waits for a reply.
|
||||||
|
*
|
||||||
|
* @param {Worker} worker
|
||||||
|
* @param {any} message
|
||||||
|
* @param {any[]} [transfer]
|
||||||
|
*/
|
||||||
|
async function workerSendReceive(worker, message, transfer) {
|
||||||
|
let p = new Promise((resolve, reject) => {
|
||||||
|
worker.onmessage = e => {
|
||||||
|
if(e && e.data) {
|
||||||
|
if(e.data instanceof Error)
|
||||||
|
reject(e.data);
|
||||||
|
else
|
||||||
|
resolve(e.data);
|
||||||
|
} else {
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
worker.postMessage(message, transfer);
|
||||||
|
return await p
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object.<string,filterDefinition>}
|
* @type {Object.<string,filterDefinition>}
|
||||||
*/
|
*/
|
||||||
|
@ -1242,6 +1266,9 @@ let filters = {
|
||||||
if(this.userdata.worker)
|
if(this.userdata.worker)
|
||||||
throw new Error("Worker already running (this shouldn't happen)")
|
throw new Error("Worker already running (this shouldn't happen)")
|
||||||
this.userdata.worker = new Worker('/background-blur-worker.js');
|
this.userdata.worker = new Worker('/background-blur-worker.js');
|
||||||
|
await workerSendReceive(this.userdata.worker, {
|
||||||
|
model: '/third-party/tasks-vision/models/selfie_segmenter.tflite',
|
||||||
|
});
|
||||||
},
|
},
|
||||||
cleanup: async function() {
|
cleanup: async function() {
|
||||||
if(this.userdata.worker.onmessage) {
|
if(this.userdata.worker.onmessage) {
|
||||||
|
@ -1253,23 +1280,10 @@ let filters = {
|
||||||
draw: async function(src, ctx) {
|
draw: async function(src, ctx) {
|
||||||
let bitmap = await createImageBitmap(src);
|
let bitmap = await createImageBitmap(src);
|
||||||
try {
|
try {
|
||||||
let p = new Promise((resolve, reject) => {
|
let result = await workerSendReceive(this.userdata.worker, {
|
||||||
this.userdata.worker.onmessage = e => {
|
|
||||||
if(e && e.data) {
|
|
||||||
if(e.data instanceof Error)
|
|
||||||
reject(e.data);
|
|
||||||
else
|
|
||||||
resolve(e.data);
|
|
||||||
} else {
|
|
||||||
resolve(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
this.userdata.worker.postMessage({
|
|
||||||
bitmap: bitmap,
|
bitmap: bitmap,
|
||||||
timestamp: performance.now(),
|
timestamp: performance.now(),
|
||||||
}, [bitmap]);
|
}, [bitmap]);
|
||||||
let result = await p;
|
|
||||||
|
|
||||||
if(!result)
|
if(!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in a new issue