Timothy B. Terriberry tterribe at email.unc.edu
Sat Mar 13 13:21:26 PST 2010

Id Kong wrote:
> I'm using TH_ENCCTL_SET_DUP_COUNT for the purpose I believe it was
> intended for: simulating variable frame rate video.  It turns out that

Right, but again, this depends on _how_ you're simulating VFR. A base
frame rate of 1000 fps is, in practice, very different from, say, 120
fps. There are two problems with the old-style "inter frame with no
coded blocks" as a substitute for dropped/duplicate frames.

1) They are 9 bytes instead of 0 (which, when adding Ogg container
overhead, translates into 10 bytes instead of 1). At 1000 fps, that
increases the VFR overhead from 8 kbps (which is not great, but maybe
acceptable) to 80 kbps (which is bad).

2) The decoder application has no way of distinguishing them from
regular frames, and so must do color conversion, display, etc., on every
one. I suspect many of the applications that _do_ handle this correctly
(e.g., which could actually display a 1000 fps file with 24-30 _real_
frames per second without choking) are simply looking for 0-byte packets
and special casing them.

I hacked up your program to actually work on a platform other than
Windows (and removed the dependency on CxImage, which appears to be
hopelessly Windows-only, and converted it from C++ to C). However, I was
not able to reproduce your problem with ffmpeg (I tested on Linux, and
thus did not have ffdshow; it may be specific to the DirectShow
filters). VLC, however, was quite clearly broken (it probably discards
0-byte packets and _then_ adds timestamps to the packets that are
missing them, and so plays along quickly until it hits a packet with an
explicit timestamp, and then stalls until that time passes). 0-byte
packet handling was broken in mplayer until this week, as well.

Thus I changed the encoder to emit the old-style 9-byte packets in VP3
compatibility mode. Because of 1), this makes this mode unsuitable for
1000 fps VFR content; it may still work okay for more reasonable base
frame rates. To address 2), I modified the decoder to return TH_DUPFRAME
from th_decode_packetin() for _any_ frame with no coded blocks (before
it, too, would only return this for 0-byte packets). However, I doubt
much, if any, software other than our player_example is actually
checking this return code. It gives the hope that once these changes are
release and disseminated some future application _could_ be written
which would handle these files efficiently, but for the immediate
future, you can expect 2) will still be a problem. In the mean time,
however, VLC now plays the resulting output of your test program without
problems, though the resulting file is somewhat larger.

You can get the changes from r16966 of the current development branch:

More information about the theora-dev mailing list