changeset 17711:8aa18d8e5eb6

add forward_ptr to syncpoint (+0.006% overhead) give syncpoint and frameheader their own checksums (worst case overhead increase <0.006%) fix filestructure so that extendability is restored move index_ptr to the fileend so that index packets arent a special case with their reserved_bytes position -> all packets follow the same structure now remove "optional" word from info packets, they are not more optional then index packets split index packets note, this is entirely optional and a muxer which has difficulty with it can always output a single index packet remove the index MUST be at the file end if anywher rule, its not needed anymore as index_ptr will always be at the end info frames must be keyframes last info frame is the most correct comments, flames?
author michael
date Wed, 01 Mar 2006 14:19:37 +0000
parents 9a976f1550f1
children a320248c2450
files DOCS/tech/mpcf.txt
diffstat 1 files changed, 84 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/tech/mpcf.txt	Wed Mar 01 13:37:09 2006 +0000
+++ b/DOCS/tech/mpcf.txt	Wed Mar 01 14:19:37 2006 +0000
@@ -122,8 +122,6 @@
         Headers:
 
 main header:
-    main_startcode                      f(64)
-    forward_ptr                         v
     version                             v
     stream_count                        v
     max_distance                        v
@@ -162,12 +160,8 @@
             reserved_count[i]= tmp_res;
         }
     }
-    reserved_bytes
-    checksum                            u(32)
 
 stream_header:
-    stream_startcode                    f(64)
-    forward_ptr                         v
     stream_id                           v
     stream_class                        v
     fourcc                              vb
@@ -190,8 +184,6 @@
         samplerate_denom                v
         channel_count                   v
     }
-    reserved_bytes
-    checksum                            u(32)
 
         Basic Packets:
 
@@ -211,22 +203,21 @@
     }
     for(i=0; i<reserved_count[frame_code]; i++)
         reserved                        v
-    if (after_syncpoint){
-        syncpoint_checksum              u(32)
+    if(stream_flags&4){
+        checksum                        u(32)
     }
     data
 
 index:
-    index_startcode                     f(64)
-    forward_ptr                         v
     max_pts                             v
+    syncpoint_start                     v
     syncpoints                          v
-    for(i=0; i<syncpoints; i++){
+    for(i=syncpoint_start; i<syncpoints; i++){
         syncpoint_pos_div8              v
     }
     for(i=0; i<stream_count; i++){
         last_pts= -1
-        for(j=0; j<syncpoints; ){
+        for(j=syncpoint_start; j<syncpoints; ){
             x                           v
             type= x & 1
             x>>=1
@@ -257,11 +248,8 @@
             }
         }
     }
-    reserved_bytes
-    index_ptr                           u(64)
-    checksum                            u(32)
 
-info_frame: (optional)
+info_packet:
     stream_id_plus1                     v
     chapter_id                          v
     chapter_start                       v
@@ -287,16 +275,12 @@
             type= "v"
         }
     }
-    reserved_bytes
-    checksum                            u(32)
 
-info_packet: (optional)
-    info_startcode                      f(64)
-    forward_ptr                         v
-    info_frame
+info_frame:
+    info_packet
+    packet_footer
 
 syncpoint:
-    syncpoint_startcode                 f(64)
     coded_pts                           v
     stream = coded_pts % stream_count
     global_key_pts = coded_pts/stream_count
@@ -306,23 +290,73 @@
 
 file:
     file_id_string
-    while(!eof){
-        main_header
+    while(bytes_left > 8){
+        if(next_byte == 'N'){
+            startcode                           f(64)
+            forward_ptr                         v
+            switch(startcode){
+                case      main_startcode:  main_header; break;
+                case    stream_startcode:stream_header; break;
+                case      info_startcode:  info_packet; break;
+                case     index_startcode:        index; break;
+                case syncpoint_startcode:    syncpoint; break;
+            }
+            reserved_bytes
+            checksum                    u(32)
+        }else
+            frame
+    }
+    index_ptr                           u(64)
+
+the structure of a undamaged file should look like the following, but
+demuxers should be flexible and be able to deal with damaged headers so the
+above is a better loop in practice (not to mention its simpler)
+note, demuxers MUST be able to deal with new and unknown headers
+
+packet_header
+        startcode                               f(64)
+        forward_ptr                             v
+
+packet_footer
+        reserved_bytes
+        checksum                                u(32)
+
+reserved_headers
+    while(next_byte == 'N' && next_code !=      main_startcode
+                           && next_code !=    stream_startcode
+                           && next_code !=      info_startcode
+                           && next_code !=     index_startcode
+                           && next_code != syncpoint_startcode){
+        packet_header
+        packet_footer
+    }
+
+file:
+    file_id_string
+    while(bytes_left > 8){
+        packet_header, main_header, packet_footer
+        reserved_headers
         for(i=0; i<stream_count; i++){
-            stream_header
+            packet_header, stream_header, packet_footer
+            reserved_headers
         }
         while(next_code == info_startcode){
-            info_packet
+            packet_header, info_packet, packet_footer
+            reserved_headers
         }
-        if(next_code == index_startcode){
-            index
+        while(next_code == index_startcode){
+            packet_header, index_packet, packet_footer
+            reserved_headers
         }
-        if (!eof) while(next_code != main_startcode){
-            if(next_code == syncpoint_startcode)
-                syncpoint
+        if (bytes_left > 8) while(next_code != main_startcode){
+            if(next_code == syncpoint_startcode){
+                packet_header, syncpoint, packet_footer
+            }
             frame
+            reserved_headers
         }
     }
+    index_ptr                           u(64)
 
 
 Tag description:
@@ -372,8 +406,8 @@
 
 max_pts_distance
     max absoloute difference of pts of new frame from last_pts in the
-    timebase of the stream, without a syncpoint immediately before the
-    frame. Note that last_pts is not necessarily the pts of the last frame
+    timebase of the stream, without a checksum after the frameheader
+    Note that last_pts is not necessarily the pts of the last frame
     on the same stream, as it is altered by syncpoint timestamps.
 
 stream_id
@@ -474,12 +508,15 @@
       1  is_key             if set, frame is keyframe
       2  end_of_relevance   if set, stream has no relevance on
                             presentation. (EOR)
+      4  has_checksum       if set then the frame header contains a checksum
 
     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.
     EOR can only be unset in streams with zero decode_delay .
+    has_checksum must be set if the frame is larger then 2*max_distance or its
+    pts differs by more then max_pts_distance from the last frame
 
 stream_id_plus1[frame_code]
     must be <250
@@ -560,16 +597,12 @@
     checksum is calculated for the area pointed to by forward_ptr not
     including the checksum itself (from first byte after the
     forward_ptr until last byte before the checksum).
-    In the case of info frames, covers area from begginning of frame.
+    for frame headers the checksum contains the framecode byte and all
+    following bytes upto the checksum itself
 
 Syncpoint tags:
 ---------------
 
-syncpoint_checksum
-    crc32 checksum
-    checksum covers from first byte after syncpoint startcode until last
-    byte before the syncpoint_checksum.
-
 back_ptr_div8
     back_ptr = back_ptr_div8 * 8 + 7
     back_ptr must point to a position within 8 bytes of a syncpoint
@@ -612,11 +645,8 @@
     that EOR. EOR is unset by the first keyframe after it.
 
 index_ptr
-    Length in bytes of the entire index, from the first byte of the
-    startcode until the last byte of the checksum.
-    Note: A demuxer can use this to find the index when it is written at
-    EOF, as index_ptr will always be 12 bytes before the end of file if
-    there is an index at all.
+    absolute location in the file of the first byte of the startcode of the 
+    first index packet, or 0 if there is no index
 
 Info tags:
 ----------
@@ -630,6 +660,8 @@
     file. Positive chapter_id's are real chapters and MUST NOT overlap.
     Negative chapter_id indicate a sub region of file and not a real
     chapter. chapter_id MUST be unique to the region it represents.
+    chapter_id n MUST not be used unless there are at least n chapters in the
+    file
 
 chapter_start
     s= chapter_start % stream_count
@@ -724,8 +756,6 @@
 
 Note: with realtime streaming, there is no end, so no index there either
 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:
@@ -742,6 +772,11 @@
 Info SHOULD be stored in global packets instead of info streams/frames if
 possible, and the amount of data is not large.
 
+If 2 info frames have the same chapter_id and stream_id then the earlier
+MUST be ignored (the last info frame is the most correct, this allows
+updating or correcting info)
+
+Info frames MUST be keyframes
 
 demuxer (non-normative):
 ------------------------