Closed Ceylo closed 8 years ago
As audio can no more be late at start (except if the decoder is buggy), this issue should be much less noticeable.
Generally a good container format will provide some information that helps maintain synchronization between audio and video streams. You can use this information (when available) to hold the current video frame until the audio catches up.
Actually, I assumed ffmpeg would handle this particular aspect. Is there a specific scenario that can duplicate this issue so I can get a better idea of what is going on?
Actually the issue is mainly with SFML audio buffering and audio driver delays, data on FFmpeg's side is fine, it usually have good timestamps.
SFML preloads approximatively 3s of audio data, and the initial delay with the audio driver (ie. between data when has finished being sent to SFML and went it starts playing) can go up to 1s. What is being done for now is that when starting playing, sfeMovie waits for OpenAL to indicate that audio playback did start (ie. playing position > 0). This is the best way I've found to at least start playback synchronized: once we know audio is playing, video starts and can catch up audio by playing the first video frames faster.
While playing, if audio gets late at some point, you have two possible solutions: (1) make video wait (2) skip some audio samples
I was rather for the idea (2) in order to keep the playback on time, the main issue being that if you start skipping samples, you can no more rely on the playing offset given by OpenAL, and if you update the offset given to OpenAL, it'll flush preloaded data and will start loading again 3 secs of data (but remember, you're already reading 3 secs in advance on the FFmpeg's audio stream, so you have to seek backward if you don't want to miss data, which isn't supported by sfeMovie yet).
Solution (1) is probably easier but not perfect too: I can't check every video frame update if video should wait for audio to catch up because the playing offset returned by OpenAL (and thus SFML) is not regularly updated enough (it gets updated every 0.2s if I remember well). So sfeMovie may think audio is late just because the playing offset wasn't updated yet.
I'm not familiar with OpenAL much...(I know what it is but have not poked into its internals and API). Does it provide a callback function that you can use to help maintain synchronization perhaps? Something that provides the current positional data and is called only when that data is updated?
I don't know... but even if it does, it would require some support on SFML's side, because sfeMovie doesn't use OpenAL directly, it only uses SFML's API.
I looked at how SFML uses OpenAL: it queries for the AL_SEC_OFFSET property on a OpenAL audio source, and this information is not updated very often. That's what other users seem to have reported too and in some way it look normal because it depends on what the audio hardware sends back.
Closing as it does not appear to be noticed by users, so it means it happens too rarely to be annoying :)
For now, when video is late, images are skipped to re-synchronize. But there's no such method for audio when it gets late.