[FFmpeg-devel] matroska encoder option -- force new Cluster on keyframe
bernt at wulfram.com
Sat Jul 20 02:11:54 CEST 2013
I'm working on implementing a video player that would benefit from a tiny optional change to the matroska encoder in ffmpeg. I propose to add a command line option that generates a valid matroska file with the added constraint that each keyframe gets a new cluster. I'm writing to ask if folks think that adding this option to ffmpeg is acceptable before I submit such a patch.
Currently, even when we use CueRelativePosition (which is a new EBML tag I am preparing another ffmpeg patch for), we first have to seek to the Cluster heading first, get the timecode, and then possibly seek many bytes ahead -- possibly close to 5 MB of data to get to the block for the cuepoint in question.
There are two purposes to have this option in ffmpeg:
a) Should one wish to implement a specialized video player that wants to rely on the above constraint, then the implementation for a fast seek is easier (just seek to the Cluster and start pulling blocks, and you have the right data), and it's also faster because it avoids a second seek. We know that the first block of a Cluster must be the block we wanted to seek to. Clearly any video player that relies on this behavior has to be used in an environment that guarantees the video files it is asked to play are prepared in this manner. I happened to be in such an environment where I can make such a guarantee.
b) The above option would still be of use even to video players that do not wish to rely on the additional constraint that each CuePoint starts a new Cluster. Even in an implementation that makes use of CueRelativePosition for seeking (ie: does a second seek after reading the timecode from the cluster), there would still be performance benefits because the second seek ought to be more efficient given that the data would only be a few hundred bytes away from the Cluster offset. So even if the code went for the second seek, it ought to be faster.
For my use case, I would combine the above option with a rather large value for the -g (GOP size), but then make use of -force_key_frames that states explicitly where I wish the keyframes to be placed, and in turn, where the cuepoints are made, and should the above option be available, force new clusters at those key frames.
Proposed option name: -force_new_cluster_on_key_frame
or perhaps: -new_cluster_on_key_frame
Though I'd be happy to have it be something different (assuming people are OK with the idea).
It might be better to think about it in terms of CuePoints. Nothing says that you have to have a CuePoint for each keyframe in the stream. Perhaps another way to describe the above is via CuePoints. So instead of saying that for each keyframe we create a new cluster, you'd say you create a new cluster for each CuePoint. I believe currently each keyframe gets an entry in the Cues index.
Lastly, I can certainly create my own private version of this option, but would feel much better if it became part of the public ffmpeg tool.
More information about the ffmpeg-devel