[MPlayer-dev-eng] Nut proposal [Re: Cleaning your nuts]

D Richard Felker III dalias at aerifal.cx
Thu Apr 22 06:14:20 CEST 2004


On Wed, Apr 21, 2004 at 10:11:16PM -0400, D Richard Felker III wrote:
> OK, there's been some discussion/complaints/objections regarding some
> decisions in nut spec, and imo we need to figure out what the issues
> are and fix them so we can move on and finish it.
> [...]
> Finally, I have some proposals of my own. I'm not sure if they're good
> as-is, but I want to discuss them anyway.
> [...]
> 2. Get rid of framecode and replace it with something non-obfuscated. 
> [...]
> 3. Store size (forward pointer) with bias.
> [...]
> Of course, it might be more efficient to just use several bits of the
> flags/bitfield byte for lsb of the size. For example 2 bits for stream
> id, 2 bits for pts predictor, and 3 or 4 bits for size lsb. That would
> allow packets up to 1024 bytes (or 2048) with just one byte spent for
> size.
> 
> At the very least, we should make the size coding a little more
> efficient if we don't want to use predictors. For example, 0-byte
> packet is never possible, and neither is 1-byte. So we could always
> add 2 to the size. To allow a range of 2-1025 instead of 0-1023.
> 
> 4. Use bitstreams rather than bytestreams for the packet headers.

OK, time for a proposal based on these points. Here's my proposed nut
frame structure:

header_field    v
size_msb        v
(stream_id)     v
(pts)           v
data

(stream_id and pts are only optionally coded as vlc depending on the
contents of header_field)

Now for an explanation of header_field:

bits 0-1: lsb of frame size
bits 2-3: stream code
  00 - stream_id coded with vlc
  01 - same stream as previous frame, +1
  10 - same stream as previous frame
  11 - same stream as previous frame, -1
bits 4-5: pts code
  00 - pts coded with vlc
  01,10,11 - use predicted deltas
bit 7: keyframe flag

Since header_field is vlc coded, we can add extra flags if we ever
need to. Note that all dependent/predictive codes are ruled out if a
startcode is present (aka type2 frame).

With this structure, any packet under 512 bytes and sane pts behavior
can be coded with just a 2-byte header. And for packets above 512
bytes, an additional header header byte is at worst 0.2% overhead.

First some points about stream code. In a simple 2-stream file, you'll
never need to vlc code stream_id. Coding as -1/same/+1 always works.
Figuring out that this should work well in the case with more than 2
streams is left for the reader. :)

Now about pts coding...relative or absolute? Rather than wasting space
in the header_field to store this, we store the flag in the pts vlc
code. The pts vlc actually stores (pts<<1)|relative_pts_flag.

Optional changes: Forget about vlc for the header_field and use 3 bits
for size_lsb. This way we can encode sizes up to 1024 with just a
2byte header.

Optional changes, part 2: Make header_field 16-bit and allow more
values for stream_code and several more bits for size_lsb. This hurts
our best-case overhead quite a bit, but might improve worst-case
enough to be worth it...?

TODO: Avoid conflicting with start codes. If we keep vlc for the
header_field, one way to do this is to change startcodes to have bit 8
of their first byte set, and then just make a rule that any extended
flags we add in the future won't conflict with the startcode.

Comments? Michael? Ivan?

Rich





More information about the MPlayer-dev-eng mailing list