GNOME Bugzilla – Bug 669164
oggdemux generates invalid granpos which causes asserts in theoraparse
Last modified: 2012-02-02 20:56:56 UTC
This got fixed a while back, but it is here again. Happens on the sintel trailer, which I think I got as ogg from the Durian site originally.
gst-launch-0.10 filesrc location=/home/v/Samples/sintel_trailer-480p-new.ogv ! oggdemux ! theoraparse ! fakesink
Filing so I don't forget as I've found several issues.
It looks like the culprit is oggdemux, not theoraparse.
I *think* what's happening is that oggdemux places "interpolated" granpos values on outgoing packets, and syncs when it sees an actual granpos. When a page contains several packets, with one of these packets being a keyframe, and where the number of frames comes close to the max keyframe distance (in this file, a granshift of 5 means only 32 frames), the interpolated granpos may violate that max distance (and wrap the "distance since last keyframe" part of the granpos).
See dump from oggz validate showing this. Last known granpos is 398|23, max granpos without needing an intervening keyframe would be 398|31. 422|8 is the true granpos, but simple interpolation makes it an invalid 398|32, which is equivalent to 398|0.
I guess the right fix is to detect keyframes, and bump/reset granpos accordingly when interpolating.
00:00:17.458: serialno 1602069339, granulepos 398|21, packetno 421: 20.003 kB
00:00:17.500: serialno 1602069339, granulepos 398|22, packetno 422: 17.324 kB
00:00:17.541: serialno 1602069339, calc. gpos 398|23, packetno 423: 21.417 kB
00:00:17.583: serialno 1602069339, calc. gpos 422|0, packetno 424: 95 bytes
00:00:17.625: serialno 1602069339, calc. gpos 422|1, packetno 425: 0 bytes
00:00:17.666: serialno 1602069339, calc. gpos 422|2, packetno 426: 0 bytes
00:00:17.708: serialno 1602069339, calc. gpos 422|3, packetno 427: 0 bytes
00:00:17.750: serialno 1602069339, calc. gpos 422|4, packetno 428: 0 bytes
00:00:17.791: serialno 1602069339, calc. gpos 422|5, packetno 429: 0 bytes
00:00:17.833: serialno 1602069339, calc. gpos 422|6, packetno 430: 0 bytes
00:00:17.875: serialno 1602069339, calc. gpos 422|7, packetno 431: 0 bytes
00:00:17.916: serialno 1602069339, calc. gpos 422|8, packetno 432: 0 bytes
00:00:17.958: serialno 1602069339, calc. gpos 422|9, packetno 433: 0 bytes
00:00:18.000: serialno 1602069339, calc. gpos 422|10, packetno 434: 0 bytes
00:00:18.041: serialno 1602069339, calc. gpos 422|11, packetno 435: 0 bytes
00:00:18.083: serialno 1602069339, calc. gpos 422|12, packetno 436: 0 bytes
00:00:18.125: serialno 1602069339, calc. gpos 422|13, packetno 437: 0 bytes
00:00:18.166: serialno 1602069339, granulepos 422|14, packetno 438: 1.042 kB
Created attachment 206577 [details] [review]
oggdemux: fix granpos interpolation violating max keyframe distance
In case many packets fit on a page, we may not see a granpos for
a while, and granpos interpolation can wrap the 'frames since last
keyframe' part of the granpos, generating a granpos which is smaller
than what it should be.
This is fixed by detecting keyframe packets (at least for Theora),
and updating the last keyframe granpos from this.
This may still be generating potentially wrong granpos for streams
which have a Theora like granpos (keyframes, a max keyframe distance
and a count of frames since last keyframe), and which allow implicit
granules on packets. For these streams, a custom keyframe detection
routine should be plugged into their GstOggStream mapper.
This fixes the issue for Theora/theoraparse.
A similar issue may exist for VP8. I think Dirac's OK since it has one packet per page so should not hit the granpos interpolation code. I think other codecs are not affected by this, though not 100% certain.
cherry-picked this into the release branch, so -> 0.10.36