[MPlayer-dev-eng] Flaming NUT

Ivan Kalvachev ivan at cacad.com
Fri May 7 02:48:02 CEST 2004


Ok, here is resume of all my flames.

1. startcodes are good for recovering after error. They are not good for check
(sums) and confirming validity of any data.
2. type0 frames would cause disaster if they are not heavy limited by
design!
3. Extendability are more important than overhead.
4. Error resistance could be better.
5. Seeking should not be done by searching startcodes. (without index)
6. Buffering is actually needed for streaming. Find out why vbv_buffer
exist in MPEG.

> On Tue, May 04, 2004 at 01:25:19AM +0300, Ivan Kalvachev wrote:
> >
> > Hello,
> > Maybe you have noticed that I am not including myself in nut discussions
anymore.
> > Why?
> > I looked at older (20030906) version on nut and I found that I like it
> > more, as it is nearly what I have proposed. From this fact I think that
> > nut is heading in a wrong direction. Michael is great optimizer,
> > but I will repeat again (and again) that reducing overhead is not our
> > primary goal!
>
> This is not about overhead, altho the old design SUCKED and had
> considerably worse overhead than most other containers, unless you
> used subpackets. But subpackets preclude live streaming, and live
> low-bitrate streaming is where overhead matters most!!

Hmm, as usual you use the word "suck" without any reason.
I just love the way you use word "overhead",
proving yourself wrong in the very same sentence.

Let me repeat it.
"This is not about _overhead_, altho the old design SUCKED and had
considerably worse _overhead_ ..."

I don't think I could convince you about anything as long as
your primary target and compartment criteria is overhead.

In future I will ignore all your arguments that contain the
word overhead.

> If you notice, all the design changes we have made recently in NUT
> fulfill MULTIPLE goals, which include:
>
> - allowing zero-latency muxing (streaming)

This is pointless. Completely useless.
I'm sure we could discuss on it farther.

> - reducing overhead

OVERHEAD, OVEARHEAD, go over my head...

> - improving error resilience


So far, I haven't sow anything that improve error resistance.
All changes improve overhead and decrease error resistance.
Short synccodes are not part of the drafts yet. (atm of writing
original flame)

>
> > I found something interesting too. The old draft have more
> > requirements for error resistance! Cheaters.)
>
> Yes, it had one more requirement: the ability to identify damaged
> frame _contents_ in order to re-download. We decided this is stupid
> because it belongs at the protocol level (ed2k, bittorrent, rtsp, tcp,
> whatever).

Do you know the SEP syndrome? It is very popular in (post) socialist
countries with heavy bureaucracy. It mean "Somebody Else Problem".
You simple try to move the problem, not to solve it. The fun comes when
the one that you have moved the problem to, comes with SEP in turn...

OGG people did that. They throw away all problems. I see that Michael
is very happy because of this :P

The checksum are to make checks. I am bashing you for at least one byte
or optional checksum that guarantee that the packet_header is not damaged.
But this break your HIGHEST TOP NUMBER 1 priority.


> > So, I will try to explain one more time my point of view.
> >
> > 1. The format is not extendible.
> > "allow adding more fields at the end of headers".
> > This also include frame headers!
>
> Not to us. The frame headers are designed not to need more fields. We
                                   ========WTF=========
> will not make further additions (which would prevent old players from
> supporting new NUT files) after the spec is final and in-use!

The very same argument could be used for all extensions!
Here you remove the requirement for extendibility.
What was the right term of that - demagogy?

>
> > After all, the main function of container is to keep the frame data
> > and all other meta data that is required for it.
> >
> > Just turn back and see what beautiful hack you have done for DTS support.
>
> Actually the dts "hack" is only there so we can formally specify what
> proper interleaving means in the spec. In practice, a demuxer/decoder
> never needs to know dts. Instead it just uses "delay" as the decoding
> latency, and thus demuxes "delay" packets ahead at all times, which
> will give the same effect.
>
> So, our "beautiful hack" is really just a clever way of (formally)
> writing down what everyone has known for years.

Saying that decoder never need to know decode timestamp is somehow ...
flowed ;)
DTS could be just frame number. Why it should be in the same timebase
as the presentation time? Just to serve a rule without real value?
Also, the current scheme "may" lead to problems with variable
framerate formats.


> > Oh I am sure that you will may extend frame_code to add additional bits
> > that will indicate additional fields. Maybe frame_codes won't be
> > enough?
> > I guess that escape_frame_code (e.g. 0xFF) could be used, so you will
> > still have about 250 normal codes. Of course escaped code will grow to
> > minimum 2 bytes  :( Not to mention main and stream header changes...
>
> Maybe you have some points about the current structure not being
> extensible enough. I'll check and recommend any necessary changes. IMO
> there should be a number before the framecode table, which tells how
> many vlc-coded fields will follow for each framecode. That way we can
> add new fields that can be ignored by old players.

Nice. Something had penetrated.

>
> > 2. I wanted more checksums (in frame headers too). Rich explained me
> > that they are not necessary as backward/forward pointers are the
> > biggest part of the header and breaking one of them is easy to be
> > found. Few days later Michael removed the backward pointers.
> > Of course nobody want to spend  precious bytes for checksums.
>
> Checksums ARE NOT NECESSARY to identify damage. Startcode checking
> does a much better job of the same thing, with less computational

That's the most stupid thing I've heard from skilled developer.
Startcodes prove ONLY that THEY are not damaged. Nothing else.
Even one simple XOR of all bytes is better than nothing. Or lower
meaning part of the bytes. Both ways were used at Apple II times,
so they ARE fast.(XOR was faster, but it may be slower on crappy P4)

> overhead (I sure as hell don't want to be wasting cpu cycles on
> checksums when I'm trying to get my k6 to decode 720x480 video with
> he-aac audio.....).

try to avoid EMMS, it is slow as hell (about 300 cycles).
> > 3. Seeking ATM is something horrible. The place of index is not
> > determined by any way. It may come to the confusing situation to read
> > the half (or whole) file until index is found:O
>
> There is no good spec for the index right now, so your complaint is
> about the incompleteness of NUT, not a flaw in NUT. Rest assured we
> WILL specify the index properly, but not necessarily before the "1.0"
> NUT spec. Seeking in NUT is very efficient without an index.
>
> > Seeking without index is very similar to the mpeg stream seeking.
>
> Nope. Correct seeking in mpeg is O(n) because timestamps are entirely
> random.

LOL. I hope you can prove that. Otherwise it is very stupid flame.

> In practice mpeg players implement incorrect bitrate-based
> seeking, which usually seeks by the wrong amount (thus everyone
> complaining about -ss with mpeg files...).

This bitrate base seeking is actually attempt for O(1). If MPlayer
want correct seeking then it need to do "binary search".

Seeking (without index) IS THE SAME!!

>
> Seeking in NUT with no index is O(log n). You always seek to the exact
> time you want.

I'm already sick of this O(log n). IT IS FALSE. IT IS NOT CORRECT.
It is larger.
Why? Because you need to find frame_header first. You jump in a middle
of the frame data. Then you need to start reading forward until you find
startcode. This takes time. So it depends on data_size and type0 max size.

> > With the tiny detail that nothing guarantee that these startcodes are
> > unique, just very improbable.
>
> Guess what? Nothing guarantees that a "packet" with the right checksum
> is valid either. It's just incredibly improbable to get a bad packet
> with a good checksum. The probability of a false positive for your 32
> bit checksum is 1/2^32. The probability of false positive for NUT
> startcodes is 1/2^64.

You miss something. Startcodes are always one and same. What would you do
if M$ try to sabotage the NUT, by making the very same startcodes
part of their next codec? Sue them? Change nut?

> > Do you remember the nut it nut scenario.
>
> Nut is not allowed to contain other containers (including itself),
> only raw codec frames.
>
> > It could make nut demuxer
> > completely nuts on seeking, dumping errors that don't really exist.
> > Ya,ya even ogg don't do it anymore.
>
> You can come up with pathologies that break any system of sync/error
> recovery.

But I am not talking about breaking error recovery. I talk of
breaking the _NORMAL_ seeking.

> > 4. I am serious about NUT in MPEG-TS. Really.
> > You are trying to reduce the overhead of NUT, with words that it is
> > good for very low bitrate streams. But these streams are good only for
> > streaming. And NUT is not suited for streaming. No packet priority
> > no retransmition etc...
>
> This belongs in the PROTOCOL, not the file format. They are two
> entirely separate layers.

SEP

>
> > 5. The current level of error resistance ability is somehow lower
> > than MPEG-(P)ES. Why? If there is broken frame_header of type0 frame
> > then we will loose all frames until next type2. This may mean up to
> > 0.5 seconds (15 frames) or even more (>16kb) data.
>
> Nonsense. See below for explanations.
>
> > Just for compartment with mpeg elementary stream you may resync on next
> > slice in the same picture!
>
> You can do this just fine with nut. If the damage is only inside the
> frame (and not in the nut headers), then the codec does its own

I SAID FRAME_HEADER!!! I'm going to use Ascii Art next time, if you
miss the point (again;)

In your scenario frame_header of type0 is ONE (1) byte. If it is broken
you loose all frames until next synccode.
According to the standard (now) synccode should be used at least every
0.5 seconds or max_type0_size (16kb) data. As max_type_0_size is now
optional it WILL lead to disaster.


> resyncing with error concealment, and you'll never notice any problem.
> Also, if you know your nut file contains (for example) only mp3 audio
> and mpeg-4 video, you can use mpeg headers to resync. BUT THIS IS
> CODEC-SPECIFIC, and so is the resyncing you're talking about in
> MPEG-ES. It does not work in general.

Isn't that what I am saying?
Then why I need nut? It don't even have total time with it:(


> > If some player need error recovery it is better to completely ignore NUT
> > demuxer and search mpeg startcodes in the data.
>
> You're free to do this for MPEG files if you like...
>
> > 6. There is no way to find error in the frame headers or frame data,
> > unless something really bad happens (hit impossible value). Even then
> > the damaged region could not be exactly determined :(
>
> Yes it can. That's what recovery points (aka type1 startcodes) are

Such thing exist only in your imagination at the time of writing
(my) flame.
Relaying of startcodes is stupid. If they were so good they would have
been used in every possible file. Don't forget that they are called
sync codes. They are good only to recover after error. Nothing else.


> for. If the chain of packet lengths does not lead to a recovery point
> within the coded max_distance, then the header is invalid. Otherwise
> it's assumed valid (probability of it being invalid is very very low).

I'm talking for the scenario when INVALID CODE is taken AS BEEN VALID.
See bellow.

> Recovery points are sufficiently small (only 3 bytes!) that you can
> have the interval between them be very small (e.g. 4k), and then it's
> easy for the demuxer to check them in its buffers. If the interval is
> too large for the demuxer, it can instead remember the last known
> "good" point, and then go back and check (via seeking) if it goes too
> long without finding any startcodes. OR, a basic demuxer can simply
> wait until the next sync point to begin demuxing again, which is NOT A
> BIG LOSS!!

Oh, yee. But at the time you have found that something is wrong your
whole image would be full of flashing blocks and lavc would print
2 tome encyclopedia of errors.


> > Do you remember the scenario I was trying to convince you while I was
> > studding NUT? It was not possible because of backwards pointers. But now
> > it is:
> > If there is one broken byte in frame_code of type0, it is very probable
> > that demuxer won't detect it and will return data_frames. It may
> > calculate wrong size of frame and will read wrong frame_code for next
> > frame. Same will repeat until summary size grows beyond the limit. But
> > as the size is variable now, it could become quite big mess.
>
> Look Ivan. Error resilience is UP TO THE PERSON CREATING THE FILE. If
> you want to avoid losing anything when there's an error, you're
> perfectly free to put a startcode before each and every frame. Nothing
> is stopping you. And this may be useful for archival material.

Guess what? Next thing you will do when (if) nut become popular is for
these idiots that set too big max_type0_sizes and break the last
chance of recovery. Not to mention that they have to actually hack the
muxer source to tweak it as I like it.

As you said it is trade off. And you value overhead too much.

>
> On the other hand, if you're copying a DVD to share on P2P ;), or
> streaming video (where the PROTOCOL ALREADY HAS ERROR DETECTION AND
> RETRANSMISSION), then you and use very few startcodes, since you have
> other ways of repairing the data if it's damaged.

Looks like you haver had dealed with floppy disk, or cd-roms, or dvd
burners. What would you do if this is the only copy that exist?
Relaying on pirate networks is not something I would do.


> > 7. The size test are done in best conditions. We don't have real test
> > stream that could be used for comparing results. Every test is unique
> > and unrepeatable. Of course nut will beat every container in CBR mp3, except
> > mp3, as it have monotone timestamp
> > s, (nearly) constant
> > framesize and only one stream. So what?
> > > We need an real stress test, for worst scenario.
>
> Stress test is 8kbit/sec vorbis. I demonstrated that the base overhead
> for this case is 1 byte-per-packet. You can't get lower than that. Add
> whatever level of error resilience you like on top, but IMO 8kbit/sec
> is normally for streaming where the PROTOCOL ALREADY RECOVERS ERRORS!

Oh yee. That's what I mean. All test scenarios I see so far show nut
in superior view. All test are made to demonstrate how frame_header==1 byte
performs so great. There is no real tests with real movie. How about
storing DVD into NUT? With multiangel, multiple langueges, probably with
5.1 vorbis? Something that would actually make nut spend bytes. Don't forget
that nut don't have size limitations. The largest the file the bigger overhead.

BTW I know that there are speech compressions that work well with
1-2kbits, but I don't know an general audio compression algorithm
that could produce something acceptable at that bitrate.


> > Non of these problems are fatal. Most of the time nut will work.
>
> It will always work for what it's intended for, by the person making
> the file. Forcing people who have no use for extensive error
> resilience to waste tons of kabbebytes on it is idiotic. What's even
> worse is forcing people to waste tons of kabbebytes on USELESS
> overhead that doesn't even help with error recovery (MKV and OGG).
> >
> Making container better than avi is not big deal.
>
> Tell that to the OGG people... :)) They still can't seem to do it.
Microsoft DID. ASF/WMV is the superior of avi.


> Don't forget that OGG is quite good container and only one
>
> ROTFL!!!
>
> > small (design) error banned it from broad usage. Now there is OGG2 in
> > development and if there is even single problem in NUT it may be doomed.
> > > (Not to mention matroska;)
>
> FUD.
OGG people had their priority and they have fulfilled their goals.
The small design error may not be so obvious from their point of view.
Can you see something else than overhead?

>
[...]
You know that a chain is as strong as it weakest link
[...]

> > Yes, it is possible to create container with even lower overhead, that
> > is more simple and error resistant. But it looks like all current nut's
> > are against any kind of buffering.(
>
> > Feel free to explain how. IMO it can't be done even with buffering.
It is simple, you should use LESS than byte:)
:))
No, you won't take that idea for free. I already contacted M$ and Real.
I will see who will give best offer.)


Best Regards
   Ivan Kalvachev
  iive




More information about the MPlayer-dev-eng mailing list