Hi John,
Thanks for your detailed reply! I appreciate the explanations about the fundamental Gaffer design choices, this will surely help us make more informed decisions going forward.
As for `libav`, you are correct in assuming that decoders store some internal state for retrieving images. Also, there are some additional parameters beyond `video_stream_index`, e.g. "filter graphs" and such. I'm thinking that a reasonable approach is to create a `DecoderCache` that stores opened decoders, which are essentially then a file handle together with metadata about the streams in the file.
However, I think it will also be necessary to have a `FrameCache` (similar to `OpenImageIOReader`) since decoding frames can be quite expensive, especially given that we are not necessarily decoding them in consecutive order, but rather support random access via "seeking". We will need to be careful when populating the `FrameCache` so that we don't end up with multiple threads requesting frames from the same decoder concurrently. As a first attempt we could always lock while decoding a frame, although this might not be the most efficient solution. A better solution might be to associate each decoder with its own mutex, so that we can lock each decoder separately.
I have been studying `ImageReader`/`OpenImageIOReader` in some detail to try to understand the inner workings, I've got a few questions related to that. I've created a [Miro board](
https://miro.com/app/board/uXjVNKEP_90=/) (can you access this?) to map things out visually. This is still a work in progress.
[ImageReader::affects](
https://github.com/GafferHQ/gaffer/blob/main/src/GafferImage/ImageReader.cpp#L390-L393)
Here I'm not sure what "parent" means, is it the node that owns the plug or is it the output plug that the input is connected to (or something else entirely)?
[ImageReader::compute](
https://github.com/GafferHQ/gaffer/blob/main/src/GafferImage/ImageReader.cpp#L449-L453)
For `availableFrames` the corresponding output plug on `OpenImageIOReader` is simply [forwarded](
https://github.com/GafferHQ/gaffer/blob/main/src/GafferImage/ImageReader.cpp#L177), which makes sense since the low-level reader must be able to determine the valid frame range(s). I'm guessing that `fileValid` is a bit different since it must also take the "frame masking" into account, which is a concept that the low-level reader doesn't know about.
I'll be doing some implementing and will post more when I run into more interesting cases!
Best,
T