VLC knows the timestamp of the current frame. From that information it can seek to a frame that is before the current frame, possibly by just subtracting the inverse of frame rate from the current frame's timestamp and if seeking to that time results in seeking to the same frame, try again a bit older.
I'm relatively sure this can be implemented in terms of timestamp-based seeking. Quite possibly the metadata of the frames is already in the memory, further simplifying the process.
> just subtracting the inverse of frame rate from the current frame's timestamp
Variable frame rate (VFR) videos break this approach. It might seem like an esoteric edge case, TV and movies aren't VFR after all, but VFR is extremely common in videos from smartphones.
There are TV shows that have telecined film segments and also interlaced VFX sections. While this wasn't broadcast as VFR the best way (as in highest quality result) to convert to a fully progressive frame sequence for display on modern displays would end up recombining the two fields for telecined segments (keeping the framerate) while doubling the framerate during deinterlacing for the VFX segments.
But VFR is also irrelevant to the problem at hand since it doesn't make it harder to find the next keyframe before the current frame - you need an index for that anyway.
This is why I also suggested a fallback in case it lands up in the same frame, but yes, it also needs checking that the next frame is indeed the original frame.
I expect it to work unless the frame rate is wildly varying, e.g. 60 fps and 60 spf in the same video. I guess one reasonable use case would be video that's triggered by motion, though. It would still work for almost every video.