Opened 13 years ago
#1910 new defect
MPlayer incorrecty determines frame-duration for 0-length Theora video packets
Reported by: | Owned by: | reimar | |
---|---|---|---|
Priority: | normal | Component: | demuxer |
Version: | HEAD | Severity: | normal |
Keywords: | Cc: | ||
Blocked By: | Blocking: | ||
Reproduced by developer: | no | Analyzed by developer: | no |
Description
The Theora codec uses 0-length packets to denote frames where the picture does not change at all. These frames just return NULL (drop frame) in vd_theora.c.
video_read_frame() wrongly computes frame duration for these frames as 0.
The cause of this bug is ds_get_next_pts() which returns the *current* pts when the packet read last has zero length. This is due to the check for 'ds->buffer_pos' to see whether data has already been read from the
*current* packet. Of course, ds->buffer_pos won't change when a
zero-length packet was read, so that fails.
A demonstration video can be accessed here: (it contains a 3 FPS video that was transcoded to 24 FPS, so 5 constant 0-packet frames per non-constant frame.)
http://mosquito.dyndns.tv/david/nanonote/theora-0packets.ogv
The problem is especially obvious with -demuxer ogg, although also ffmpeg's demuxer shows problems.
I already reported that bug to the mailinglist, where a simple theora-specific workaround patch was so far declined. After discussion with Reimar Döffinger, it looks like at least these solutions might be applicable:
a) in video_read_frame(), just don't compute frametime as pts1-pts0 for Ogg/Theora videos. In ogg/theora frametime is a constant anyways. This was my first patch and at least Reimar didn't like it. Won't fix the problem for other codecs or Theora in other containers
b) Make the ogg demuxer just drop empty video packets. That might cause trouble with video codecs that use empty packets differently. Also doesn't fix the problem with other containers used for Theora.
c) Make the ogg demuxer just drop empty video packets only for Theora. That also only partially fixes the problem.
d) The proper solution would be to fix ds_get_next_pts() for 0-length packets. But so far I have no idea how such a fix would look like.