[MPlayer-dev-eng] Patches for NUT
Oded Shimon
ods15 at ods15.dyndns.org
Sat Feb 4 09:49:15 CET 2006
On Fri, Feb 03, 2006 at 02:21:18PM -0500, Rich Felker wrote:
> On Fri, Feb 03, 2006 at 01:05:36PM +0100, Michael Niedermayer wrote:
> > > >
> > > > accurate compare_ts, 02-compare_ts.patch
> >
> > there is something i dont like ...
> > we should not force a specific implementation here which this more or less
> > does, instead we should specify things more like:
> > compare_ts
> > Compares timestamps from 2 different timebases,
> > if a is before b then compare_ts(a, b) = -1
> > if a is after b then compare_ts(a, b) = 1
> > else compare_ts(a, b) = 0
> > care must be taken that this is done exactly with no rounding errors, simply
> > casting to float or double and doing the obvious a*timebase >/<= b*timebase
> > is not compliant or correct, neither is the same with integers, and
> > a*a.ts.num*b.ts.den >/<= b*b.ts.num*a.ts.den will overflow
> > one possible implementation which shouldnt overflow within the range of
> > legal timestamps and timebases is:
> > comare_ts(a, b){
> > if (convert_ts(a, a_timebase, b_timebase) < b) return -1;
> > if (convert_ts(b, b_timebase, a_timebase) < a) return 1;
> > return 0;
> > }
>
> I agree totally, this is basically what I said on irc.
fixed
> > > > remove 2^n header restriction, 03-header-repeat.patch .
> >
> > ok
>
> IMO the wording is slightly confusing and makes it sound like the
> headers must be repeated at EACH 2^n position.
well, it says SHOULD, not MUST, I haven't got any better ideas.. We can
polish it later.
> > > > Regarding error recovery michael suggested, checksum for frame header etc.
> > > > I dislike it, it complicates binary search when looking for startcodes.
> > > > Rich already proposed a solution to prevent loosing the entire file - if
> > > > you see a frame with abnormally high size immediately after a syncpoint,
> > > > while reading the frame (which you have to anyway), linear search entire
> > > > area for possible syncpoint. The worst that will happen is that you'll skip
> > > > the entire damaged area in that single frame, and that's actually a good
> > > > thing...
> >
> > ok, but that still leaves the issue with abnormally high pts and damaged pts
> > during binary search
I'm now inclined back to checksum, because checking checksum in binary
search is much easier than varifying timestamp or any other hack.
As for damaged pts, there is no good fix for that except optional
max_pts_diff in header... The player should just not be that
dumb...
> Hmm..
> I'm ok with having checksums but I'd like to hear other ideas too.
We considered adding checksums and shortening startcodes to 4 bytes, but it
makes the startcodes very silly: 0x7A56U + ((('N'<<8) + 'M')<<16)
I also considered 16 bit checksum, as adler32 is kind of a waste on 10-20
bytes, but 16 bits is too weak. :/
Maybe we can make only syncpoint startcode 32 bits? It's not ideal, but it
does somehow make sense as this startcode is the only one with checksum
immediately following it, making the checksum practically part of the
startcode.
- ods15
-------------- next part --------------
--- mpcf.txt 2006-02-03 08:22:53.000000000 +0200
+++ mpcf.1.txt 2006-02-03 08:50:02.000000000 +0200
@@ -1,5 +1,5 @@
========================================
-NUT Open Container Format DRAFT 20060120
+NUT Open Container Format DRAFT 20060203
========================================
@@ -249,8 +249,14 @@
for(; j<n && j<syncpoints; j++){
if (!has_keyframe[j][i]) continue
A v
- last_pts += A
- keyframe_pts[j][i] = last_pts
+ if(!A){
+ A v
+ B v
+ eor_pts[j][i] = last_pts + A + B
+ }else
+ B=0
+ keyframe_pts[j][i] = last_pts + A
+ last_pts += A + B
}
}
}
@@ -557,7 +563,11 @@
keyframe_pts
The pts of the first keyframe for this stream in the region between the
- 2 syncpoints, in the stream's timebase.
+ 2 syncpoints, in the stream's timebase. (EOR frames are also keyframes)
+
+eor_pts
+ Coded only if EOR is set at the position of the syncpoint. The pts of
+ that EOR. EOR is unset by the first keyframe after it.
index_ptr
Length in bytes from the first byte of the index startcode to the first
-------------- next part --------------
--- mpcf.1.txt 2006-02-03 08:50:02.000000000 +0200
+++ mpcf.2.txt 2006-02-04 10:14:38.000000000 +0200
@@ -413,6 +413,24 @@
Note: this calculation MUST be done with unsigned 64 bit integers, and
is equivalent to (ln*sn)/(d1*d2) but this would require a 96bit integer
+compare_ts
+ Compares timestamps from 2 different timebases,
+ if a is before b then compare_ts(a, b) = -1
+ if a is after b then compare_ts(a, b) = 1
+ else compare_ts(a, b) = 0
+
+ Care must be taken that this is done exactly with no rounding errors,
+ simply casting to float or double and doing the obvious
+ a*timebase > b*timebase is not compliant or correct, neither is the
+ same with integers, and
+ a*a_timebase.num*b_timebase.den > b*b_timebase.num*a_timebase.den
+ will overflow. One possible implementation which shouldn't overflow
+ within the range of legal timestamps and timebases is:
+
+ if (convert_ts(a, a_timebase, b_timebase) < b) return -1;
+ if (convert_ts(b, b_timebase, a_timebase) < a) return 1;
+ return 0;
+
msb_pts_shift
amount of bits in lsb_pts
MUST be <16
-------------- next part --------------
--- mpcf.2.txt 2006-02-04 10:14:38.000000000 +0200
+++ mpcf.3.txt 2006-02-04 10:14:08.000000000 +0200
@@ -677,7 +677,7 @@
headers may be repeated, but if they are, then they MUST all be repeated
together and repeated headers MUST be identical
-headers MAY only repeat at the closest possible positions after 2^x where x is
+headers SHOULD repeat at the closest possible positions after 2^x where x is
an integer and the file end, so the headers may be repeated at 4102 if that is
the closest position after 2^12=4096 at which the headers can be placed
-------------- next part --------------
--- mpcf.3.txt 2006-02-04 10:14:08.000000000 +0200
+++ mpcf.4.txt 2006-02-04 10:14:23.000000000 +0200
@@ -299,7 +299,7 @@
file:
file_id_string
- while(!eof && next_code != index_startcode){
+ while(!eof){
main_header
for(i=0; i<stream_count; i++){
if(next_packet==video_stream_header)
@@ -312,14 +312,16 @@
while(next_code == info_startcode){
info_packet
}
- while(next_code != main_startcode){
+ if(next_code == index_startcode){
+ index
+ }
+ if (!eof) while(next_code != main_startcode){
if(next_code == syncpoint_startcode)
syncpoint
frame
}
}
- if (next_code == index_startcode){
- index
+ if (has_index){
index_ptr u(64)
}
@@ -590,7 +592,8 @@
index_ptr
Length in bytes from the first byte of the index startcode to the first
byte of the index_ptr. If there is no index, index_ptr MUST NOT be
- written.
+ written. If there are several indexes, index_ptr MUST point to the last
+ index.
id
the ID of the type/name pair, so it is more compact
@@ -692,8 +695,9 @@
------
Note: with realtime streaming, there is no end, so no index there either
-An index SHOULD be written for every stream. Indices MUST be placed at end
-of file. Indices MAY be repeated for a stream.
+Index MAY only be repeated after main headers.
+If an index is written anywhere in the file, it MUST be written at end of
+file as well.
Info frames:
-------------- next part --------------
--- mpcf.4.txt 2006-02-04 10:14:23.000000000 +0200
+++ mpcf.5.txt 2006-02-04 10:31:46.000000000 +0200
@@ -290,6 +290,7 @@
syncpoint:
syncpoint_startcode f(64)
+ syncpoint_checksum u(32)
coded_pts v
stream = coded_pts % stream_count
global_key_pts = coded_pts/stream_count
@@ -551,6 +552,11 @@
including the checksum itself (from first byte after the
forward_ptr until last byte before the checksum).
+syncpoint_checksum
+ adler32 checksum
+ checksum covers from syncpoint timestamp until the end of the frame
+ header immediately following the syncpoint.
+
back_ptr_div8
back_ptr = back_ptr_div8 * 8 + 7
back_ptr must point to a position within 8 bytes of a syncpoint
More information about the MPlayer-dev-eng
mailing list