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

Rich Felker dalias at aerifal.cx
Sat Dec 31 23:07:46 CET 2005


On Sat, Dec 31, 2005 at 10:43:51PM +0200, Oded Shimon wrote:
>      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;

Hmm, is this chunk for the best? Michael probably had reasons for the
original way he did it..

> +    for(i=0; i<stream_count; i++) {
> +        j = 0;
> +        while (j < syncpoints) {
> +            repeat                      s
> +            type = (repeat > 0)
> +            repeat = abs(repeat)

Is there a reason you don't just use the low bit...

> +            b = repeat & 1;
> +            repeat = (repeat >> 1)+1;

...like this, for the type? The hack with signed field seems
unnecessarily confusing.

> -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 such that one
> +    keyframe for this stream lies between it and the current syncpoint.
> +
> +    Note: back_ptr can be zero, when the frame immediately following is
> +    a keyframe of this stream, or EOR has been set for this stream.
> +    back_ptr of a stream where EOR is set should only be zero if no other
> +    back_ptr of a non-EOR stream in this syncpoint points to before the
> +    EOR.

Cut these last three lines. The semantics of seeking are:

* Find the latest point such that all relevant streams have a keyframe
  after the resulting point but before the requested pts.

Any streams with EOR are not relevant at this point. Those last three
lines will just tend to make seeking give an earlier resulting point
than the latest possible point before pts.

It's true that when you start decoding without the frame from the EOR
stream, you'll see some (e.g.) video frames without (e.g.) their
subtitle. However there should not (and cannot) be any expectation
that all streams will be active and available until the demuxer
reaches the pts. Otherwise you get in nasty recursive situations
trying to satisfy such a ridiculous requirement when all streams have
interframes and don't have their keyframes at the same points.

> +    Syncpoints MUST be placed immediately before a real (non-EOR) keyframe if
> +    more than max_distance passed since the previous keyframe of the same
> +    stream. The exception to this is if the back_ptr of this stream in the
> +    last syncpoint is zero.
> +

Rewrite as:

-------------------------------------------------------------------------------
Syncpoints MUST be placed immediately before any non-EOR keyframe where both:
  * the distance to the stream's previous keyframe is greater than max_distance
  * the back_ptr for this stream in the previous syncpoint is nonzero
-------------------------------------------------------------------------------

> +    global_timestamp MUST be equal to the mts of the frame immediately
> +    following the syncpoint, in a common timebase.

MTS still needs discussion.. :(

> +    All streams SHOULD end with EOR.

..where the pts of the EOR indicates the end presentation time of the
final 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.

Apparently this is still controversial.. :(
Actually I have another new proposal.. :)) I'll send as a separate
message.

> +    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.

IMO the "MN rule" here should be stated separately from mts since it's
not related specifically to mts.

Thanks for doing all this work. It's been rough but I really think
we're almost there. Having you implementing this stuff has been
invaluable to figuring out the difficulties and deficiencies in the
spec.

Rich




More information about the MPlayer-dev-eng mailing list