[MPlayer-dev-eng] Nut & framecode...
D Richard Felker III
dalias at aerifal.cx
Fri Apr 23 08:09:52 CEST 2004
I think Michael's convinced me that framecode is a good thing, for
extensibility reasons. For now it can be used like my bitfields, and
more specialized muxers could choose an optimal framecode table if
they like. But I'd like to propose some minor changes and suggest a
sane default framecode table that muxers could use. First, the
changes:
1. XOR framecode byte with 'N' or 'N'^0xff.
Right now 'N' is the forbidden framecode, and that makes things
particularly annoying for muxers that want to use the framecode as a
sort of bitfield. You might say the muxer could just do the XOR
itself, but then it has to write the framecode table in the global
header this way, and Michael's compression tricks for it no longer
work because it's shuffled out of order.
If XOR is made part of the spec, then 0x00 or 0xff becomes the
forbidden framecode, and nothing special is needed to exclude it.
(Just have a table of 255 framecodes instead of 256).
2. Remove predictive coding for data_size.
It's bad for error recovery and unlikely to help except for CBR which
wastes 30% or more space anyway.
3. Clean up flags table (flags[framecode]). It's very confusing.
4. Perhaps replace all timestamp_lsb stuff with timestamp_delta.
5. Remove the buffer overflow from the main header framecode table. :)
All of these except #5 are open to discussion. I'm also pretty
determined about #2 tho. Maybe #1 is stupid and you could just add/sub
instead of xor...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now, the default framecodes:
data_size_msb is always coded
data_size_mul is always 16
usage of the bits in framecode:
bits 0-1: stream id
00,01,10 = the 3 most overhead-critical streams (audio, then video)
11 = vlc follows (or stream 4 if only 4 total)
bits 2-5: low 4 bits of data_size
bits 6-7: pts code:
00=delta1
01=delta2
10=delta3
11=vlc follows
Note that keyframe flag is NOT present. For intra-only streams
(including most audio) it's pointless. For such streams, all
framecodes will have their keyframe flag set.
In intra/inter streams (most video), keyframes are rare. Therefore all
framecodes will have the keyframe flag cleared, except for one
reserved combination for which all fields are vlc-coded (stream id,
pts) and data_size_mul=1, data_size_lsb=0.
Some optional variants:
- use 3 bits for stream id and 3 for data_size_lsb if there are more
than 3 audio/video streams and more than 4 total streams.
- likewise only use 1 bit for stream id if there are just 2 streams,
and exclude stream id entirely if there is just one.
- remove pts code if the stream is fixed_fps (pts is always +1) and
use the extra bits for something useful. (but what about b frames?)
- try to put the reserved frame codes (the one that conflicts with
startcode and the one used for keyframes) with a less size-critical
stream id. first choice is subtitle, then video.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A few notes:
Headers on packets < 2048 bytes should only need 2 bytes. This means
that you don't have to worry about bad overhead increases from large
packets. The only trouble case is very small packets, and even then,
overhead is only 1% for 200-byte packets. Average packet size for
low-bitrate vorbis could easily be as low as 75 bytes, but that only
gives 2.66% overhead. It's really not possible to do much better.
Michael had one-byte-per-packet headers before, but that was with data
size prediction which only works for CBR. Keep in mind these figures
don't count frames with startcodes ("type2").
Rich
More information about the MPlayer-dev-eng
mailing list