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

Oded Shimon ods15 at ods15.dyndns.org
Sat Dec 31 15:27:59 CET 2005


OK, patch ready.

On Fri, Dec 30, 2005 at 09:10:02PM +0200, Oded Shimon wrote:
> To sum up a rather long discussion between me and Rich today:
> 
> 1. EOS

EOR now, in the patch.

> 2. syncpoints must be max(dts) (min(pts)?)

It is now MTS of following frame, in the patch.

> 3. strict interleaving method

MTS, in the patch.

> 4. my keyframe rule (keyframes further than max distance)

with the change for preventing excessive syncpoints, in the patch.

> 5. index can also have zero back ptr

repeat is almost get_s() style, as it has a repeat++ to prevent redudnancy.
in the patch.
Entire index style is explained in code, no words.

> 6. seperate control and stream flags in frame code

Apperantely I've gone completely mad, and even changed the main header 
fields. IMHO this structure makes more sense. We've already lost all 
compatiblity with old nut files, we really don't need to worry about that.
Is anyone with me with this new main header format? Against me?

> 7. real back ptr is back ptr / (10 + number of streams)

dumped, we're keeping /8

> 8. syncpoints too big?

I added per stream back_ptr...
Like I said, my keyframe rule with updated "no pts change" rule.

9. renaming deprecated "frame_startcode"
10. changing goals section (sorry, index is nowhere near <10kb per hour :/ )
11. fix small oddity in info packets, apperantely we support "s" according 
    to info table, but not according to code.


Patch attached.. Please review, if I get a nod from Rich and Micheal I'll 
commit.
Documenters - spelling fixes? grammar fixes? better suggestions for 
explanations?

Come on! Just a little more, and we can lock NUT. :)

- 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 14:23:49 -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,37 @@
 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++){
+        type                            v
+        j=0
+        if (type) while (j<syncpoints){
+            repeat                      v
+            b=repeat&1
+            repeat=(repeat>>1)+1
+            for(k=0; k<repeat; k++){
+                syncpoint[j+k].stream[i].back_ptr= syncpoint[j-b].pos_div8
+            }
+            j+= repeat
+        } else while (j<syncpoints) {
+            repeat                      v
+            repeat++
+            b=repeat&1
+            repeat=repeat>>1
+            for(k=0; k<repeat; k++){
+                syncpoint[j+k].stream[i].back_ptr= syncpoint[j+k-b].pos_div8
+            }
+            if (!repeat) {
+                syncpoint[j].stream[i].back_ptr= syncpoint[j-1].stream[i].back_ptr
+                j++
+            }
+            j+= repeat
+        }
     }
     reserved_bytes
     checksum                            u(32)
@@ -243,6 +276,8 @@
             name                        vb
         if(type=="v")
             value                       v
+        else if(type=="s")
+            value                       s
         else
             value                       vb
     }
@@ -254,10 +289,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 +314,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 +332,14 @@
     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 so a syncpoint startcode begins
+    within the next 8 bytes, and such that this syncpoint is the closest
+    syncpoint so one keyframe for this stream lies between that syncpoint
+    and the current syncpoint.
+    Note back_ptr can be zero, when the frame immdiately following is a
+    keyframe of this stream, or EOR has been set for this stream.
 
 file_id_string
     "nut/multimedia container\0"
@@ -316,13 +353,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 +366,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 only 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 previous keyframe of the same stream,
+    unless the timestamp to be set for this syncpoint is identical to the
+    last syncpoints's timestamp. In which case, 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 +421,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 +433,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 muxer timestamp of the frame
+    immediately following 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 +458,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_relavence if set, stream has no relavence 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_ptr's for this stream are set to zero.
+    All streams SHOULD end with EOR.
 
 stream_id_plus1[frame_code]
     must be <250
@@ -479,9 +524,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 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 +561,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 reffered 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
+    reffered 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