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