GNOME Bugzilla – Bug 731982
hlsdemux: Don't use approximate duration for fragment buffer pts
Last modified: 2015-01-08 13:11:35 UTC
The HLS demuxer currently uses the duration supplied by the playlist file and uses this information to set the PTS of the first buffer of each fragment. These values are approximate only, and even worse on playlist versions 1 and 2 these are only rounded integer values (in seconds). The result is that there are continuously playback skips between the fragments. The duration information is only really helpful for seeking purposes.
Created attachment 278860 [details] Example playlist This is an example. Each fragment is roughly 10 seconds (rounded integer value in #EXTINF), but if you look at #EXT-X-PROGRAM-DATE-TIME tags you can see that the actual duration of the fragments is slightly different.
Created attachment 278861 [details] [review] Patch Patch to fix this issue: Only set the very first buffer's PTS, do not set it for the first buffer of every subsequent fragment.
This is probably the same as bug #731824
Also seems to be a duplicate of bug #724983
I guess that's the best we can do here, and not try to be too clever. Thanks for the patch.
Comment on attachment 278861 [details] [review] Patch This will break seeking though. After a seek we're supposed to send a buffer downstream with a new timestamp (corresponding to the beginning of the buffer, not the seek position) again.
(In reply to comment #6) > (From update of attachment 278861 [details] [review]) > This will break seeking though. After a seek we're supposed to send a buffer > downstream with a new timestamp (corresponding to the beginning of the buffer, > not the seek position) again. Hm, do you have any idea how this could be fixed?
HLS is just an ill-defined format :) I think for seeking we should use the approximation that was used before, and that is still used in the seek handler to find the corresponding fragment.
Created attachment 279042 [details] [review] Updated patch This patch unconditionally sets demux->reset_pts to TRUE when processing a seek event.
Comment on attachment 279042 [details] [review] Updated patch This breaks playback of http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8 After the first fragment it will switch from the default playlist to the 4th for me... that's at 10 seconds. But it will immediately jump from 10 seconds to 20 seconds.
Any update?
I would really appreciate some help with this. I don't seem to have the jumping issue, but at the same time I don't think mine is switching from the default playlist? Sebastian, is this still happening, or is this that may have been fixed in the meanwhile?
*** Bug 740461 has been marked as a duplicate of this bug. ***
Patch updated to the latest codebase and fixed the issue with resyncing when changing the playlist. commit cd6069f5af03b35fd0182ac9dfac3b4c0eccbe4d Author: Thomas Bluemel <tbluemel@control4.com> Date: Fri Jun 20 12:38:59 2014 -0600 hlsdemux: Don't use approximate duration for fragment buffer pts The duration values in playlists are approximate only, and for playlist versions 2 and older they are only rounded integer values. They cannot be used to timestamp buffers. This resulted in playback gaps and skips because the actual duration of fragments is slightly different. The solution is to only set the pts of the very first buffer processed, not for each fragment.
Thiago, how does this work with seeking though? If we can't use the durations to timestamp buffers then we also can't use them for seeking for the same reason
We still keep track of the timestamps of the segments but we only provide a timestamp when it is the first segment pushed after a seek, when starting or when we switch bitrates. For seeking it uses rough approximation that the playlist provides. So seeking should be just like before but we get more accurate timestamps during playback and we only resync with the playlist's timestamps when needed.
That would mean that seeking near the current playback position could take you somewhere completely different though :)
There's not much that can be done regarding that in HLS. I assumed continuous/smooth playback was more important than seeking accuracy. One other option would be to always push a new segment with every fragment to resync timestamps with HLS without disrupting playback, but that would likely mean that the position would jump a bit every segment. I'm hoping people will move to newer HLS specs that allow using floats to express time related values instead of integers, so this will likely be easier for us.
Yes, smooth playback is more important. I was just curious if you found a better solution :)