After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 619778 - oggdemux: fails on zero-length pages with Patent_Absurdity_HD_3540kbit.ogv
oggdemux: fails on zero-length pages with Patent_Absurdity_HD_3540kbit.ogv
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
0.10.29
Other Linux
: Normal blocker
: 0.10.33
Assigned To: David Schleef
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2010-05-27 04:19 UTC by bens
Modified: 2011-04-09 21:13 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch (1.65 KB, patch)
2011-01-06 00:03 UTC, David Schleef
none Details | Review

Description bens 2010-05-27 04:19:14 UTC
gstreamer fails to demux the following file correctly:

http://ia331209.us.archive.org/0/items/Patent_Absurdity/Patent_Absurdity_HD_3540kbit.ogv

I discovered this when trying to execute the following pipeline:

gst-launch-0.10 filesrc location= /tmp/Patent_Absurdity_HD_3540kbit.ogv ! oggdemux name=demux ! theoradec ! queue ! videoscale method=2 ! video/x-raw-yuv,width=720,height=480 ! queue ! mpeg2enc format=8 aspect=3 ! mpegpsmux name=mux ! filesink location=/tmp/patents_out.mpg . demux. ! vorbisdec ! audioconvert ! queue ! twolame bitrate=320 ! mux.

This pipeline will hang after about a minute.  I believe it stops because oggdemux is dropping zero-length pages (i.e. pages containing only zero-length packets), leading to audio and video drifting apart.  I confirmed this suspicion by running

gst-launch-0.10 filesrc location= /tmp/Patent_Absurdity_HD_3540kbit.ogv ! oggdemux name=demux ! theoradec ! queue ! videoscale method=2 ! video/x-raw-yuv,width=720,height=480 ! queue ! mpeg2enc format=9 bitrate=7000 ! mpegpsmux name=mux ! filesink location=/tmp/patents_out.m2v

i.e. re-encoding just the video.  The resulting m2v file is mostly complete, but long perfectly still scenes in the ogv are greatly shortened in the m2v.

I suspect that this bug has not been observed previously because (1) real-time decode happens to work anyway because the dropped frames don't affect display, and (2) old versions of libogg were less likely to produce zero-length pages.
Comment 1 Sebastian Dröge (slomo) 2010-05-27 05:00:03 UTC
Which version of gstreamer and gst-plugins-base are you using? Playing this file via HTTP with latest releases and GIT works fine here.
Comment 2 bens 2010-05-27 20:54:46 UTC
0.10.29.

To be clear, the file will appear to play fine.  You need to run one of the above pipelines to see that there's a problem.  This is consistent with oggdemux not forwarding some empty packets, because not forwarding them causes the preceding frame to continue being displayed, which is the same thing that happens if they _are_ forwarded.

This behavior doesn't work correctly for re-encode, because those duplicate frames still need to reach the encoder in order to maintain a constant framerate stream of the correct length.
Comment 3 David Schleef 2010-05-27 22:55:31 UTC
Your analysis about oggdemux/theoradec is incorrect:

$ gst-launch filesrc location=green.ogg ! oggdemux ! fakesink -v

...

/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (   42 bytes, timestamp: none, duration: none, offset: 0, offset_end: -1, flags: 32) 0x83e6508"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (   61 bytes, timestamp: none, duration: none, offset: 0, offset_end: -1, flags: 0) 0x83e6558"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < ( 3196 bytes, timestamp: none, duration: none, offset: 0, offset_end: -1, flags: 0) 0x83e65a8"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (74880 bytes, timestamp: 0:00:00.000000000, duration: 0:00:00.041666666, offset: 41666666, offset_end: 1, flags: 0) 0x83e6240"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:00:00.041666666, duration: 0:00:00.041666667, offset: 83333333, offset_end: 2, flags: 0) 0x83e61f0"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:00:00.083333333, duration: 0:00:00.041666667, offset: 125000000, offset_end: 3, flags: 0) 0x83e61a0"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:00:00.125000000, duration: 0:00:00.041666666, offset: 166666666, offset_end: 4, flags: 0) 0x83e6150"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:00:00.166666666, duration: 0:00:00.041666667, offset: 208333333, offset_end: 5, flags: 0) 0x83e6100"

$ gst-launch filesrc location=green.ogg ! oggdemux ! theoradec ! fakesink -v

...

/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (279720 bytes, timestamp: 0:00:00.000000000, duration: 0:00:00.041666666, offset: -1, offset_end: -1, flags: 32) 0x8c265f0"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (279720 bytes, timestamp: 0:00:00.041666666, duration: 0:00:00.041666667, offset: -1, offset_end: -1, flags: 0) 0x8c26550"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (279720 bytes, timestamp: 0:00:00.083333333, duration: 0:00:00.041666667, offset: -1, offset_end: -1, flags: 0) 0x8c264b0"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (279720 bytes, timestamp: 0:00:00.125000000, duration: 0:00:00.041666666, offset: -1, offset_end: -1, flags: 0) 0x8c26410"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (279720 bytes, timestamp: 0:00:00.166666666, duration: 0:00:00.041666667, offset: -1, offset_end: -1, flags: 0) 0x8c264b0"
Comment 4 bens 2010-05-28 00:52:17 UTC
ds: I agree.  I did a test with a file constructed to have a few zero-length pages and all packets were decoded successfully.  However, fakesink did provide some surprising output:

/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:04:08.000000000, duration: 0:00:01.0000000
00, offset: 249000000000, offset_end: 249, flags: 0) 0x92c5468"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:04:09.000000000, duration: 0:00:01.0000000
00, offset: 250000000000, offset_end: 250, flags: 0) 0x92c5418"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:04:10.000000000, duration: 0:00:01.0000000
00, offset: 251000000000, offset_end: 1274, flags: 0) 0x92c5468"
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = "chain   ******* < (    0 bytes, timestamp: 0:04:11.000000000, duration: 0:00:01.0000000
00, offset: 252000000000, offset_end: 1275, flags: 0) 0x92c54b8"


Packet 250 is the last packet on the first page.  1274 is 250+1024, and 1024 is 2^granuleshift.  (This has also matched when I tried with different granuleshifts.)  I don't know if this is a problem, because I don't know what offset_end means.

On Patent_Absurdity_HD_3540kbit.ogv, running theoradec into fakesink and counting packets shows the right number of packets coming out, so the problem must not be what I thought.
Comment 5 David Schleef 2010-05-28 02:19:35 UTC
That's a known bug that only affects ogg remuxing.
Comment 6 David Schleef 2011-01-06 00:03:23 UTC
Created attachment 177627 [details] [review]
patch

This patch fixes the case for the start of a normal file, as described in #638276.

Mental note: I'm guessing there are still cases where granulepos is not reconstructed correctly, since the code is needlessly cumbersome.
Comment 7 David Schleef 2011-01-06 00:19:50 UTC
Oh frack, that got merged with oggkoggk's patch from the other bug.  You get the idea.
Comment 8 Vincent Penquerc'h 2011-01-06 10:33:53 UTC
Maybe check for 0 for non sparse streams only ?
I'm not sure if there's a good way to know whether a 0 granpos page is a header page or not since there might be another page before that with an unknown number of packets ending on it.
Comment 9 Tim-Philipp Müller 2011-01-06 22:34:06 UTC
Can this be closed, or shall we keep it open for now? (re. comment #8)


 commit 3c4466b816eca8becc69ded9cf011eb45d6dfcdb
 Author: David Schleef <ds@schleef.org>
 Date:   Wed Jan 5 15:54:15 2011 -0800

    oggdemux: ignore header pages when looking for keyframe
    
    This was causing keyframe_granule to be set to 0 for all streams
    when seeking to the beginning of the stream, i.e., at the
    beginning of playback.  Fixes #619778.
Comment 10 Sebastian Dröge (slomo) 2011-04-08 12:45:34 UTC
Ping?
Comment 11 David Schleef 2011-04-09 21:13:28 UTC
This was supposed to be closed.