[MPlayer-dev-eng] Lots of stuff for NUT

Oded Shimon ods15 at ods15.dyndns.org
Sat Dec 31 20:10:08 CET 2005


On Sat, Dec 31, 2005 at 05:47:45PM +0100, Diego Biurrun wrote:
> On Sat, Dec 31, 2005 at 05:21:32PM +0200, Oded Shimon wrote:
> > On Sat, Dec 31, 2005 at 03:53:11PM +0100, Diego Biurrun wrote:
> > > On Sat, Dec 31, 2005 at 04:27:59PM +0200, Oded Shimon wrote:
> > > > 
> > > > +    When EOR is set, all back_ptr's for this stream are set to zero.
> > > 
> > > back_ptrs
> > 
> > Is this rule set in stone? I've seen it many times used in either way.
> 
> Yes, it's a matter of grammar.  Plural is constructed with "s".  "'s" is
> used for the possessive case, i.e. to indicate what belong's to who
> (that's a *very* basic explanation, but it should work for you).
> 
> Example:
> 
> one girl - two girls
> 
> Oded's NUT implementation - the NUT implementation made by Oded

Actually, I was well aware of all this, the problem I was having is that 
back_ptr is "almost" and acronym. I totally agree with "back_pointers", no 
apostraphee. But with acronyms I think there is a debate. Is it "ATM's" or 
"ATMs"...
But I guess back_ptr isn't really an acronym (I say it in my head back-P-T-R),
so I'll use back_ptrs.

BTW, I think I'm pretty damn good when it comes to English grammar. I suck 
at spelling though. :/

> > -    max distance of frame_startcodes, the distance may only be larger if
> > -    there is only a single frame between the two frame_startcodes this can
> > +    max distance of syncpoints, the distance may only be larger if
> > +    there is only a single frame between the two syncpoints. This can
> 
> s/only/no more/

no more.. than ?

> > +    syncpoints MUST be placed immediately before a keyframe if more
> > +    than max_distance passed since the previous keyframe of the same stream.
> > +    The exception to this is if the timestamp to be set for this syncpoint
> > +    is identical to the timestamp of the last syncpoint. Instead, the syncpoint
> > +    is to be put immediately BEFORE the timestamp will change (So it will
> > +    still have the same timestamp).
> 
> This still sounds a bit awkward, but let's fix that once the draft is
> approaching its final stages.

It is!! :)

> > +    Bit  Name             Description
> > +      1  is_key           if set, frame is keyframe
> > +      2  end_of_relavence if set, stream has no relevance on
> 
> relEvAnce

I was blinking for 2 minutes till I realized that relevance is written 
twice in this line :)

Attached patch has all these fixes and my new index method.

- ods15
-------------- next part --------------
Index: DOCS/tech/mpcf.txt
===================================================================
RCS file: /cvsroot/mplayer/main/DOCS/tech/mpcf.txt,v
retrieving revision 1.86
diff -u -r1.86 mpcf.txt
--- DOCS/tech/mpcf.txt	22 Dec 2005 05:48:04 -0000	1.86
+++ DOCS/tech/mpcf.txt	31 Dec 2005 19:07:07 -0000
@@ -1,5 +1,5 @@
 ========================================
-NUT Open Container Format DRAFT 20051118
+NUT Open Container Format DRAFT 20051231
 ========================================
 
 
@@ -21,13 +21,13 @@
 
 Compact
     ~0.2% overhead, for normal bitrates
-    index is <10kb per hour (1 keyframe every 3sec)
+    index is <100kb per hour (1 keyframe every 3sec)
     a usual header for a file is about 100 bytes (audio + video headers together)
-    a packet header is about ~1-8 bytes
+    a packet header is about ~1-5 bytes
 
 Error resistant
     seeking / playback without an index
-    headers & index can be repeated
+    headers can be repeated
     damaged files can be played back with minimal data loss and fast
     resync times
 
@@ -134,26 +134,31 @@
     version                             v
     stream_count                        v
     max_distance                        v
-    max_index_distance                  v
     global_time_base_nom                v
     global_time_base_denom              v
     for(i=0; i<256; ){
         tmp_flag                        v
         tmp_fields                      v
-        if(tmp_fields>0) tmp_pts        s
-        if(tmp_fields>1) tmp_mul        v
-        if(tmp_fields>2) tmp_stream     v
-        if(tmp_fields>3) tmp_size       v
+        if(tmp_fields>0) tmp_mul        v
+        else tmp_mul=1
+        if(tmp_fields>1) tmp_sflag      v
+        else tmp_sflag=0
+        if(tmp_fields>2) tmp_pts        s
+        else tmp_pts=0
+        if(tmp_fields>3) tmp_stream     v
+        else tmp_stream=0
+        if(tmp_fields>4) tmp_size       v
         else tmp_size=0
-        if(tmp_fields>4) tmp_res        v
+        if(tmp_fields>5) tmp_res        v
         else tmp_res=0
-        if(tmp_fields>5) count          v
+        if(tmp_fields>6) count          v
         else count= tmp_mul - tmp_size
-        for(j=6; j<tmp_fields; j++){
+        for(j=7; j<tmp_fields; j++){
             tmp_reserved[i]             v
         }
         for(j=0; j<count && i<256; j++, i++){
             flags[i]= tmp_flag;
+            stream_flags[i]= tmp_sflag;
             stream_id_plus1[i]= tmp_stream;
             data_size_mul[i]= tmp_mul;
             data_size_lsb[i]= tmp_size + j;
@@ -214,6 +219,9 @@
     if(flags[frame_code]&1){
         data_size_msb                   v
     }
+    if(flags[frame_code]&2){
+        coded_stream_flags              v
+    }
     for(i=0; i<reserved_count[frame_code]; i++)
         reserved                        v
     data
@@ -221,12 +229,29 @@
 index:
     index_startcode                     f(64)
     packet header
-    stream_id                           v
     max_pts                             v
-    index_length                        v
-    for(i=0; i<index_length; i++){
-        index_pts                       v
-        index_position                  v
+    syncpoints                          v
+    for(i=0; i<syncpoints; i++){
+        syncpoint_pts                   v
+        syncpoint_pos_div8              v
+    }
+    for(i=0; i<stream_count; i++) {
+        j = 0;
+        while (j < syncpoints) {
+            repeat                      s
+            type = (repeat > 0)
+            repeat = abs(repeat)
+            b = repeat & 1;
+            repeat = (repeat >> 1)+1;
+            if (type) {
+                for(k=0; k<repeat; k++)
+                    syncpoint[j+k].stream[i].back_ptr = syncpoint[j-b].pos_div8
+            } else {
+                for(k=0; k<repeat; k++)
+                    syncpoint[j+k].stream[i].back_ptr = syncpoint[j+k-b].pos_div8
+            }
+            j += repeat
+        }
     }
     reserved_bytes
     checksum                            u(32)
@@ -243,6 +268,8 @@
             name                        vb
         if(type=="v")
             value                       v
+        else if(type=="s")
+            value                       s
         else
             value                       vb
     }
@@ -254,10 +281,12 @@
     packet header
     info_frame
 
-sync_point:
-    frame_startcode                     f(64)
+syncpoint:
+    syncpoint_startcode                 f(64)
     global_timestamp                    v
-    back_ptr                            v
+    for(i=0; i<stream_count; i++){
+        back_ptr[i]                     v
+    }
 
             Complete definition:
 
@@ -277,15 +306,13 @@
             info_packet
         }
         while(next_code != main_startcode){
-            if(next_code == frame_startcode)
-                sync_point
+            if(next_code == syncpoint_startcode)
+                syncpoint
             frame
         }
     }
     if (next_code == index_startcode){
-        while(!eof){
-            index
-        }
+        index
         index_ptr                       u(64)
     }
 
@@ -297,12 +324,13 @@
     size of the packet data (exactly the distance from the first byte
     after the forward_ptr to the first byte of the next packet)
 
-back_ptr
+back_ptr[stream]
     real_back_ptr = back_ptr * 8 + 7
-    real_back_ptr must point to a position such that a syncpoint
-    startcode begins within the next 8 bytes, and such that at least
-    one keyframe for each stream lies between the syncpoint to which
-    real_back_ptr points, and the current syncpoint.
+    real_back_ptr must point to a position within 8 bytes of a syncpoint
+    startcode. This syncpoint MUST be the closest syncpoint so one keyframe
+    for this stream lies between it and the current syncpoint.
+    Note that back_ptr can be zero, when the frame immediately following is
+    a keyframe of this stream, or EOR has been set for this stream.
 
 file_id_string
     "nut/multimedia container\0"
@@ -316,13 +344,9 @@
 stream_starcode
     0x11405BF2F9DBULL + (((uint64_t)('N'<<8) + 'S')<<48)
 
-frame_startcode
+syncpoint_startcode
     0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48)
 
-    frame_startcodes SHOULD be placed immediately before a keyframe if the
-    previous frame of the same stream was a non-keyframe, unless such
-    non-keyframe - keyframe transitions are very frequent
-
 index_startcode
     0xDD672F23E64EULL + (((uint64_t)('N'<<8) + 'X')<<48)
 
@@ -333,22 +357,22 @@
     NUT version. The current value is 2.
 
 max_distance
-    max distance of frame_startcodes, the distance may only be larger if
-    there is only a single frame between the two frame_startcodes this can
+    max distance of syncpoints, the distance may only be larger if
+    there is no more than a single frame between the two syncpoints. This can
     be used by the demuxer to detect damaged frame headers if the damage
     results in too long of a chain
 
+    syncpoints MUST be placed immediately before a keyframe if more
+    than max_distance passed since the previous keyframe of the same stream.
+    The exception to this is if the timestamp to be set for this syncpoint
+    is identical to the timestamp of the last syncpoint. Instead, the syncpoint
+    is to be put immediately BEFORE the timestamp will change (So it will
+    still have the same timestamp).
+
     SHOULD be set to <=32768 or at least <=65536 unless there is a very
     good reason to set it higher, otherwise reasonable error recovery will
     be impossible
 
-max_index_distance
-    max distance of keyframes which are represented in the index, the
-    distance between consecutive entries A and B may only be larger if
-    there are no keyframes within this stream between A and B
-    SHOULD be set to <=32768 or at least <=65536 unless there is a very
-    good reason to set it higher
-
 stream_id
     Stream identifier
     stream_id MUST be < stream_count
@@ -388,7 +412,7 @@
     global_time_base_denom MUST be < 2^31
 
 global_timestamp
-    timestamp in global_time_base units
+    syncpoint timestamp in global_time_base units
     when a global_timestamp is encountered the last_pts of all
     streams is set to the following:
 
@@ -400,13 +424,16 @@
     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
 
+    global_timestamp MUST be equal to the mts of the frame immediately
+    before the syncpoint, in a common timebase.
+
 msb_pts_shift
     amount of bits in lsb_pts
     MUST be <16
 
 decode_delay
     maximum time between input and output for a codec, used to generate
-    dts from pts
+    dts and mts from pts
     is set to 0 for streams without B-frames, and set to 1 for streams with
     B-frames, may be larger for future codecs
 
@@ -422,17 +449,26 @@
     different from the first byte of any startcode
 
 flags[frame_code]
-    first of the flags from MSB to LSB are called KD
-    if D is 1 then data_size_msb is coded, otherwise data_size_msb is 0
-    K is the keyframe_type
-        0 -> no keyframe,
-        1 -> keyframe,
-    flags=4 can be used to mark illegal frame_code bytes
-    frame_code=78 must have flags=4
-    Note: frames MUST NOT depend(1) upon frames prior to the last
-          frame_startcode
-    Important: depend(1) means dependency on the container level (NUT) not
-    dependency on the codec level
+    Bit  Name             Description
+      1  data_size_msb    if set, data_size_msb is at frame header,
+                          otherwise data_size_msb is 0
+      2  more_flags       if set, stream control flags are at frame header.
+      4  invalid          if set, frame_code is invalid.
+
+    frame_code=78 ('N') MUST have flags=64
+
+stream_flags
+    stream_flags is "stream_flags[frame_code] | coded_stream_flags"
+
+    Bit  Name             Description
+      1  is_key           if set, frame is keyframe
+      2  end_of_relevance if set, stream has no relevance on
+                          presentation until next frame. (EOR)
+
+    EOR frames MUST be zero-length and must be set keyframe. EOR is unset
+    by the first frame following the EOR of the same stream.
+    When EOR is set, all back_ptrs for this stream are set to zero.
+    All streams SHOULD end with EOR.
 
 stream_id_plus1[frame_code]
     must be <250
@@ -479,9 +515,17 @@
     stream, into which the current pts is inserted and the element with
     the smallest value is removed, this is then the current dts
     this buffer is initalized with decode_delay -1 elements
-    all frames must be monotone, that means a frame
-    which occurs later in the stream must have a larger or equal dts
-    than an earlier frame
+
+mts
+    muxer timestamp, mts is defined:
+    MIN(pts of this frame and all subsequent frames on this stream)
+    only decode_delay subsuquent frames need to be checked.
+    All frames of all streams MUST have monotone growing mts, in a common
+    timebase.
+    A demuxer can detect stream corruption if mts is out of order. To detect
+    this, dts can be used. With monotone mts, pts of all frames in all
+    streams must be bigger or equal to dts of all previous frames in all
+    streams.
 
 width/height
     MUST be set to the coded width/height
@@ -508,23 +552,24 @@
     forward_ptr until last byte before the checksum).
 
 max_pts
-    The highest pts in the stream.
+    The highest pts in the entire file in global timebase.
+
+syncpoints
+    amount of syncpoints in the file.
 
-index_pts
-    value of the pts of a keyframe relative to the last keyframe
-    stored in this index
-
-index_position
-    position in bytes of the first byte of a keyframe, relative to the
-    last keyframe stored in this index
-    there MUST be no keyframe with the same stream_id as this index between
-    two consecutive index entries if they are more than max_index_distance
-    apart
+syncpoint_pts
+    global_timestamp of the syncpoint referred to in this index entry.
+    relative to global_timestamp of last syncpoint.
+
+syncpoint_pos_div8
+    offset from begginning of file to up to 7 bytes before the syncpoint
+    referred to in this index entry. Relative to position of last
+    syncpoint.
 
 index_ptr
-    Length in bytes from the first byte of the first index startcode
-    to the first byte of the index_ptr. If there is no index, index_ptr
-    MUST NOT be written.
+    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.
 
 id
     the ID of the type/name pair, so it is more compact


More information about the MPlayer-dev-eng mailing list