[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