[MPlayer-dev-eng] NUT (informal) proposal, based on discussions

Oded Shimon ods15 at ods15.dyndns.org
Fri Jan 20 17:48:02 CET 2006


On Fri, Jan 20, 2006 at 06:12:07PM +0200, Oded Shimon wrote:
> Index results:
> 
> high quality 700mb  0 subtitle streams: 81031
> high quality 700mb 10 subtitle streams: 102475
> low  quality 620mb  0 subtitle streams: 65790
> low  quality 620mb 10 subtitle streams: 109409
> 
> BTW, my repeat stuff is apperantely quite unhelpful, it can be removed at 
> the cost of 3kb or so for the sake of simplicity.

high quality 700mb  0 subtitle streams: 83609
high quality 700mb 10 subtitle streams: 104683
low  quality 620mb  0 subtitle streams: 65225
low  quality 620mb 10 subtitle streams: 142253

The high change is thanks to the subtitle streams being very "idealistic", 
giving exactly 1 frame every 100 frames, with pts 100 more than last 
frame... So I still think it is a good idea to remove the repeat stuff.

> I'm sending a new patch soon and asking for immediatte aproval for 
> commit...

Again:

step-4:
  add EOR
  add coded stream flags
  just add sflags to header and give intial values to tmp_*

step-5:
  change goals slightly..
  max_index_distance removed
  index changed to combination of syncpoint index and pts for keyframes,
  using ideas by michael
  syncpoint still single back_ptr and pts, however back_ptr is changed -
  points to most correct keyframe, not most recent.
  syncpoint timestamp is max(last_dts)

cosmetic:
  move things around to IMO more logical positions.

whats left:
  info streams, how do they deal with EOR, back_ptr, etc.
  index repetition (atleast the option for it)
  I'd like to define function like convert_ts: "compare_ts", for comparing 
  timestamps of different timebases, mostly because I don't know how to do 
  it myself. :) Function should return less than, equal to, or greater than 
  zero as needed...


Well, review please, I'd like to commit these things as long as the date 
change in the patches hold. :)

- ods15
-------------- next part --------------
--- mpcf.3.txt	2006-01-20 09:26:15.000000000 +0200
+++ mpcf.4.txt	2006-01-20 18:42:17.000000000 +0200
@@ -1,5 +1,5 @@
 ========================================
-NUT Open Container Format DRAFT 20060105
+NUT Open Container Format DRAFT 20060120
 ========================================
 
 
@@ -131,23 +131,29 @@
     stream_count                        v
     max_distance                        v
     max_index_distance                  v
+    tmp_pts=0
+    tmp_mul=1
+    tmp_stream=0
     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_sflag      v
+        else tmp_sflag=0
+        if(tmp_fields>1) tmp_pts        s
+        if(tmp_fields>2) tmp_mul        v
+        if(tmp_fields>3) tmp_stream     v
+        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;
@@ -208,6 +214,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
@@ -302,6 +311,8 @@
     one keyframe for each stream lies between the syncpoint to which
     real_back_ptr points, and the current syncpoint.
 
+    A stream where EOR is set is to be ignored for back_ptr.
+
 global_key_pts
     After a syncpoint, last_pts of each stream is to be set to:
     last_pts[i] = convert_ts(global_key_pts, timebase[stream], timebase[i])
@@ -417,17 +428,27 @@
     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. (EOR)
+
+    EOR frames MUST be zero-length and must be set keyframe.
+    All streams SHOULD end with EOR, where the pts of the EOR indicates the
+    end presentation time of the final frame.
+    An EOR set stream is unset by the first content frames.
+    When an EOR is unset, dts_cache of the stream is reset to -1.
 
 stream_id_plus1[frame_code]
     must be <250
@@ -476,7 +497,8 @@
     this buffer is initalized with decode_delay -1 elements
 
     Pts of all frames in all streams MUST be bigger or equal to dts of all
-    previous frames in all streams, compared in common timebase.
+    previous frames in all streams, compared in common timebase. (EOR
+    frames are NOT exempt from this rule)
 
 width/height
     MUST be set to the coded width/height
-------------- next part --------------
--- mpcf.4.txt	2006-01-20 18:42:17.000000000 +0200
+++ mpcf.5.txt	2006-01-20 18:27:18.000000000 +0200
@@ -21,7 +21,7 @@
 
 Compact
     ~0.2% overhead, for normal bitrates
-    index is <10kb per hour (1 keyframe every 3sec)
+    index is <100kb per hour
     a usual header for a file is about 100 bytes (audio + video headers together)
     a packet header is about ~1-5 bytes
 
@@ -130,7 +130,6 @@
     version                             v
     stream_count                        v
     max_distance                        v
-    max_index_distance                  v
     tmp_pts=0
     tmp_mul=1
     tmp_stream=0
@@ -224,12 +223,35 @@
 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_pos_div8              v
+    }
+    for(i=0; i<stream_count; i++){
+        for(j=0; j<syncpoint_count; ){
+            x                           v
+            type= x & 1
+            x>>=1
+            if(type){
+                flag= x & 1
+                x>>=1
+                while(x--)
+                    has_keyframe[j++][i]=flag
+                has_keyframe[j++][i]=!flag;
+            }else{
+                while(x != 1){
+                    has_keyframe[j++][i]=x&1;
+                    x>>=1;
+                }
+            }
+        }
+        for(j=0; j<syncpoint_count; j++){
+            if (!has_keyframe[j++][i]) continue
+            A                           v
+            last_pts += A
+            keyframe_pts[j][i] = last_pts
+        }
     }
     reserved_bytes
     checksum                            u(32)
@@ -264,7 +286,7 @@
     coded_pts                           v
     stream = coded_pts % stream_count
     global_key_pts = coded_pts/stream_count
-    back_ptr                            v
+    back_ptr_div8                       v
 
             Complete definition:
 
@@ -290,9 +312,7 @@
         }
     }
     if (next_code == index_startcode){
-        while(!eof){
-            index
-        }
+        index
         index_ptr                       u(64)
     }
 
@@ -304,12 +324,12 @@
     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
-    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.
+back_ptr_div8
+    back_ptr = back_ptr_div8 * 8 + 7
+    back_ptr must point to a position within 8 bytes of a syncpoint
+    startcode. This syncpoint MUST be the closest syncpoint such that at
+    least one keyframe with a pts lower or equal to the original syncpoint's
+    global_key_pts for all streams lies between it and the current syncpoint.
 
     A stream where EOR is set is to be ignored for back_ptr.
 
@@ -317,6 +337,9 @@
     After a syncpoint, last_pts of each stream is to be set to:
     last_pts[i] = convert_ts(global_key_pts, timebase[stream], timebase[i])
 
+    global_key_pts MUST be the highest dts across all streams for all
+    frames before the syncpoint.
+
 file_id_string
     "nut/multimedia container\0"
 
@@ -355,13 +378,6 @@
     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
@@ -525,23 +541,27 @@
     forward_ptr until last byte before the checksum).
 
 max_pts
-    The highest pts in the stream.
-
-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
+    s = max_pts % stream_count
+    pts = max_pts / stream_count
+    The highest pts in the entire file in the timebase of stream 's' .
+
+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.
+
+has_keyframe
+    indicates whether this stream has a keyframe between this syncpoint and
+    the last syncpoint.
+
+keyframe_pts
+    The pts of the first keyframe for this stream in the region between the
+    2 syncpoints, in the stream's timebase.
 
 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
-------------- next part --------------
--- mpcf.5.txt	2006-01-20 18:27:18.000000000 +0200
+++ mpcf.cosmetic.txt	2006-01-20 18:30:01.000000000 +0200
@@ -320,26 +320,6 @@
 Tag description:
 ----------------
 
-forward_ptr
-    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_div8
-    back_ptr = back_ptr_div8 * 8 + 7
-    back_ptr must point to a position within 8 bytes of a syncpoint
-    startcode. This syncpoint MUST be the closest syncpoint such that at
-    least one keyframe with a pts lower or equal to the original syncpoint's
-    global_key_pts for all streams lies between it and the current syncpoint.
-
-    A stream where EOR is set is to be ignored for back_ptr.
-
-global_key_pts
-    After a syncpoint, last_pts of each stream is to be set to:
-    last_pts[i] = convert_ts(global_key_pts, timebase[stream], timebase[i])
-
-    global_key_pts MUST be the highest dts across all streams for all
-    frames before the syncpoint.
-
 file_id_string
     "nut/multimedia container\0"
 
@@ -355,10 +335,6 @@
 syncpoint_startcode
     0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48)
 
-    syncpoint_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)
 
@@ -368,12 +344,20 @@
 version
     NUT version. The current value is 2.
 
+forward_ptr
+    size of the packet data (exactly the distance from the first byte
+    after the forward_ptr to the first byte of the next packet)
+
 max_distance
     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 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
+
     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
@@ -540,6 +524,22 @@
     including the checksum itself (from first byte after the
     forward_ptr until last byte before the checksum).
 
+back_ptr_div8
+    back_ptr = back_ptr_div8 * 8 + 7
+    back_ptr must point to a position within 8 bytes of a syncpoint
+    startcode. This syncpoint MUST be the closest syncpoint such that at
+    least one keyframe with a pts lower or equal to the original syncpoint's
+    global_key_pts for all streams lies between it and the current syncpoint.
+
+    A stream where EOR is set is to be ignored for back_ptr.
+
+global_key_pts
+    After a syncpoint, last_pts of each stream is to be set to:
+    last_pts[i] = convert_ts(global_key_pts, timebase[stream], timebase[i])
+
+    global_key_pts MUST be the highest dts across all streams for all
+    frames before the syncpoint.
+
 max_pts
     s = max_pts % stream_count
     pts = max_pts / stream_count


More information about the MPlayer-dev-eng mailing list