Dropping frames when writing SKimage async to ssd

hi all,

I interpolate animation keyframes on export to 25fps and use a filewriter within an async region to write the textures to the drive. In the background I start encoding chunks of images to video with ffmpeg.

Unfortunately I have frame drops, even without the ffmpeg encoding. Seems as if some frames do not get written at all. I send each new SKimage with a new filename into an async task.

Is it possible to get a notification when the filewriter has completed? I want to render the frames as fast as possible, so I don’t want to reload a DIR each few ms and check the directory if the filename exists.

Any tipps appreciated!

First thought, have you tried OpenCV VideoWriter (experimental)?

Secondly, I think Async tries so hard to be fast that it can fail to finish writing the files before it moves on to the next one. Try a ForEach loop (reactive) and schedule the speed of the loops, maybe something like this:

ASyncImageWrite
and set the image’s path name in the loop to match the Input of the loop.
Can’t say if this will work for sure

Judging from your screenshot you are using png, I’d try to avoid that since it is really cpu hungry and slow. If you’ve got sufficient disk space go for tga (or bmp if you don’t need alpha). At 25 FPS write speed shouldn’t be an issue on recent M2/NVME SSDs.

edit:
Didn’t look properly. Thought you were using stride not skia. TGA is not avaible for image writer. Even for stride texturewriter tga is currently not an option, it throws exceptions, guess it is related to this issue:

Could you use the current frame as input for the interpolation? Like so:

ImageWriter.vl (35.4 KB)

Also, AsyncTask isn’t the right choice here since it doesn’t have the concept of a queue, if the tasks take longer than a frame

ToObservable and ToBackground is the right expression. This makes sure that you have a valid data package per frame that gets send to a background task.

Another thing to consider is the lifetime of the image, will the image exist long enough to get potentially written to disk 1-2 frames later? And who has the ownership of the image and will take care of the disposal if it’s not in use anymore, i.e. after it’s written to disk?

1 Like

Thx for your input, guys!

Unbenannt

@bjoern Yes I would prefere bmp for speed, but the skia texture renderer just supports a quite awkward range of formats. I have to stay compatible to ffmpeg for merging and encoding the frames.
@tonfilm a bmp option and a “on completed” output on the imageWriter would be nice to have.

Yes, I could go skia-> stride → texturewriter. The texture conversion might waste less time than the encoding when writing the texture.

I tried to do the rendering in the async thread, but this is really slow so I think this has to stay in the main thread. I am aware that the renderer needs to know if it is allowed to render the next frame. Since both image writers are not able to send a signal when they are done - is it possible to “name” the background threads somehow? Or another method to check if a certain texture got written?

cheers

@bjoern
here you need to “connect” the dynamic part of the file name with the image data by using a tuple or a data type. because the ToBackground will schedule the event somewhen in the future and there is no guarantee that it will be in the same moment as the data you pass into the region with links, filename in that case.

so linking into observable regions and background threads is not recommended unless it is object references or static data. like the file format, or quality setting.

1 Like

And that toupled data could be my identifyer for checking if a certain texture is written, right?