Opened 8 years ago

#1910 new defect

MPlayer incorrecty determines frame-duration for 0-length Theora video packets

Reported by: dvdkhlng@… Owned by: reimar
Priority: normal Component: demuxer
Version: HEAD Severity: normal
Keywords: Cc:
Blocked By: Blocking:
Reproduced by developer: Analyzed by developer:

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.

Change History (0)

Note: See TracTickets for help on using tickets.