-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gopro-telemetry - performance question #196
Comments
Try reading the LRV files instead; they do have the same data but a smaller video resolution (basically a thumbnail). It should lead much faster... |
Thanks. Unfortunately that is not a viable option |
Hi. I don't use the library on a browser, so I don't know if that's slow or not. We can leave this open in case someone else has insights. I wouldn't expect the LRV files to make a difference, as the data stream is the same size, so that should not affect gopro-telemetry, just gpmf-extract |
Ok, thanks. Apart from this minor issue the library works well, great job! |
Same issue here. I have MP4 files that are around 4GB in size, and gpmfExtract works quite fast, but goproTelemetry takes ages and eats unholy amounts of memory, so much so that I cannot run it on my local device. I did telemetry extraction myself with a Python implementation and that was basically instant, so I am convinced that there must be some bug/misallocation here - though not sure where. |
Streaming might be the solution for memory footprint. It would also grant user feedback about progress... For how long it takes... who knows why Python is so fast. The original C code is only about 20% faster; thus, it would not be real to try to fix this... |
I cannot follow the code really, there are so many nested loops and components that without properly profiling, I doubt we can say anything about it. I don't think I will have time for it, but if I do, will let you know. Overall I highly suspect that this is a bug, since it simply cannot take so long to parse a couple megabytes of data that does not require backtracking. @Akxe are you sure that the original C code is only 20% faster? Are there any benchmarks in the repo? |
@meakbiyik I am not; a friend of mine who tested my implementation of GoPro telemetry vs original C and he said that the telemetry itself is not that much slower... But given you are testing 4GB file, the extraction might be a lot slower... Also, for me, the GMPF-Extract takes about 70% while the telemetry takes only about 30%... |
I think there is a misunderstanding about the file size. |
I don't think so. It just might be dependent on the file... For me, the extraction is the long process, not the telemetry processing... |
Hi @forna . Are you able to share the raw data file for analysis? |
Here is the file, you have to extract it: gpmfExtract.zip |
Thanks for sharing that. Extracting your data to geojson is taking about 1 second on my end, on a very modest mac. Are you able to share a minimal repo to reproduce your exact conditions? |
OK sure. Do you have any favorite bundler? I am using Svelte that is integrated with Rollup, so I was thinking to use that. |
Anything that we can test by just running npm install and npm run start |
I can reproduce the issue with the goproTelemetry chained to the gpmfExtract (so the whole end-to-end process starting with the video file). This is how I do it in my application. How have you loaded the binary gpmfExtract file I provided above into goproTelemetry? |
I run this node script:
|
Somehow I am not able to load into goproTelemetry the gpmfextract binary file I have provided. Assuming your projects folder is /projects and this new project's name is performance-test: In /projects run the following command from the terminal (svelte scaffolding)
In src/routes replace the +page.svelte file content with the one I've provided below Start the dev server: The application URL will be: Select any GoPro video with the size around 1 GB and click Upload to see the goproTelemetry slowness. +page.svelte:
|
Hi @forna, Thank you for providing this example. On my end, it sometimes runs fast, sometimes really slow. I haven't really used the library on a browser environment (or used Svelte at all) so I don't know if this is normal. I don't see anything evidently wrong with your implementation, and the same files are parsed almost instantly in a Node environment. |
That makes sense... The library is heavily using nodeJS APIs that need to be polyfilled for browser... Could you try the older version? The one that was fully supporting of browsers or of the box? |
The version with full browser support is still the published one. I'm not sure we should keep it that way, but for now, only the Dev branch has been reverted (just the @gmod/binary-parser bits) |
It may be something related to the Buffer lib polyfill. |
To my knowledge, |
The
The current version of the library does not require any nodeJS polyfill. The compiler might yell, that it wants them, but they are optional. Rollup will not say anything; Webpack v5 will make a warning, Webpack v4 will bundle polyfills. I don't know the rest |
If you are polyfilling and suspect Buffer is problematic, try using the dev branch:
|
As Akxe mentioned there is no polyfilling required. |
I'm wondering what latest info is on this. I'm trying to shift server work to the client to make is as offline-friendly as possible, and finding that for large files, the processing.. we'll let's say I've been unable to tell if it's crashed or just taking a long time. for example: 5.67GB video (1:12:30 @ 1920 * 1080 * 29.97fps) times are obviously only so accurate as it's running in browser. my code, running in web worker in browser: import gpmfExtract from 'gpmf-extract';
import { goProTelemetry } from 'gopro-telemetry';
type FileSendType = { type: 'file'; file: File; videoId: string };
type FileCancelType = { type: 'cancel' };
const cancellationToken = { cancelled: false };
addEventListener(
'message',
(event: MessageEvent<FileSendType | FileCancelType>) => {
switch (event.data.type) {
case 'file': {
// browser has sent message with video file as payload, as well as a video ID so that any info back to the browser is labelled to the right video
const videoId = event.data.videoId;
gpmfExtract(event.data.file, {
browserMode: true,
progress: (extractionProgress) => {
return postMessage({ videoId, extractionProgress });
},
cancellationToken,
})
.then((res) => {
postMessage({ videoId, extractComplete: res });
goProTelemetry(res, {
stream: ['GPS'],
debug: true, // tried playing with this...
raw: true, // this...
tolerant: true, // this...
preset: 'geojson', // ...and this, and didn't notice anything different
progress: (processingProgress) =>
// update user of progress
postMessage({ videoId, processingProgress }),
})
.then((res) => {
postMessage({ videoId, processComplete: res });
})
.catch((e) => {
postMessage({ videoId, error: e.message });
});
if (!res) return;
})
.catch((e) => {
postMessage({ videoId, error: e.message });
});
break;
}
case 'cancel': {
// "cancel" button clicked by user
cancellationToken.cancelled = true;
break;
}
}
}
); I'm also not getting any kind of errors thrown in browser console. When I view performance I see a long brown line, which zoomed in, turns out to be a whole lot of garbage collection, not sure that to make of that: Sorry that's all I really have to help, let me know what else I can do |
The thing is when running in Node, the extraction and processing combined for the same 5.67GB video takes 30 seconds, while browser side sits idle for at least 20 mins, so something in the browser version is definitely ending prematurely or getting stuck in a loop. By comparison, the 406MB video which takes about 50s in browser is done in less than 2 seconds in Node. Forgot to point out, this is with:
I also tried with and without I also just tried the svelte example above (I'm using react/next in my example) and still seeing same results as described by @forna , in his version as with my own. |
@forna FWIW, I'm noticing a huge speed difference in your svelte example between Firefox vs Chrome/Edge, FF being way slower just to extract, let alone process the telemetry. Are you seeing this and do you think it proved any clues? |
Hi, unfortunately I am not using goproTelemetry anymore since I was not able to make it work properly in the browser. |
I am testing the conversion of a 2 Gb GoPro video using both gpmfExtract and gopro-telemetry in the browser.
The gpmfExtract part takes about 2.5 seconds (with the worker disabled since it's crashing the browser).
The gopro-telemetry needs about 30 seconds.
I have also analyzed the gpmfExtract file by saving it to the disk as Blob, it's 2.68 Mb, so not a large amount of data.
I am using the latest [v1.2.0] version of the code.
Is it normal for gopro-telemetry to be taking so long or am I doing something wrong?
I have also tested with different presets like "gpx" but I don't see any performance gain.
Here is the relevant part of the code:
Here is an extract of the browser's console log:
The text was updated successfully, but these errors were encountered: