Playing an MPEG1 file in WMP via HTTP returns the wrong duration

A colleague of mine in Japan recently found this very interesting issue in Windows Media Player (WMP) on Windows XP. From what he found WMP returns the wrong duration value when playing back MPEG1 files via HTTP. This only appears to occur if the file has not been cached locally by the player. This issue can cause WMP to stop playing content before it has reached the end.

For example:

  - Expected duration: 1 min 20 sec
  - Actual duration: 50 sec

On XP when WMP tries to play an MPEG1 file using HTTP and progressive download, it uses the old DirectShow “URL Async File Source” filter. To determine the length of the file WMP queries DShow for the duration. The "MPEG1 Splitter" filter communicates with the “URL Async File Source” filter, requesting the duration. The “URL Async File Source” filter calculates the duration based on the amount of data that it has currently downloaded. As you can imagine the actual amount of file that is downloaded when the source filter is queried could vary widely. The”MPEG1 Splitter” filter recognizes that the duration being returned isn’t quite right. The filter then tries to calculate the duration based on information in the System Pack Header. This calculation will always return a duration that is shorter than the full length of the file.

On Vista we use a totally different way of calculating the duration in this scenario. Since the HTTP source filter on Vista supports “seeking” over HTTP, it is possible to calculate the total duration. The “MPEG1 Splitter” filter sends a command to the source filter to seek to the end of the file. We then read the time stamp information in the last few PES packets at the end of the file. This yields the actual duration of the file.

The main reason for all this strangeness is that MPEG1 and MPEG2 are streaming formats (remember progressive download is not the same as streaming).  They are just not designed to be file archive containers.  That’s why things like Video CD and DVD wrap the MPEG streaming format and add things like indexes to enable seeking.  Of course that doesn’t stop people trying to use them as file formats.  The only way to be sure of getting the proper duration is to pre-scan the entire file before we start playback. Without an index this is a very expensive operation (order “n”). This adds a major delay before we start playing the file. Because of this a design decision was made that we would just have to deal with incorrect duration values.