Update demux_mpg.c

The MPEG4 Part 2 spec defines frame type using AN EXTRA BYTE.  It seems that neither MPEG2 nor H264 ( MPEG Part 10? ) do this.

The first part 0x1B6 specifies only that the frame is a VOP (Video Object Plane). It could be differential compression frame (B) or predicted frame (P) or a actual full picture (IDR, Immediate Decoder Refresh, keyframe).

The next byte specifies which kind of frame. During seeking we only want IDR(keyframes), otherwise distortion will be large until the next keyframe.

Ok... The code to check for this is in there, but it doesn't seem to work.

Specifically, this appears quite wrong and broken.

if((videobuffer[pos+4] & 0x3F) == 0)

The spec says that the higher 2 bits from this byte determine the frame type.

VOP_CODING_TYPE (binary)  Coding method
                      00  intra-coded (I)
                      01  predictive-coded (P)
                      10  bidirectionally-predictive-coded (B)
                      11  sprite (S)

So to find out if this definitely is an IDR(keyframe) we must:

videobuffer[pos+4] & 0xC0

00xxxxxx & 00111111 (x3F) Doesnt tell us anything

00xxxxxx & 11000000 (xC0) Will be 00000000 (==0) if and only if it's an IDR(keyframe). 

On to the next.

Since the other encoding methods (MPEG2 and H264) don't use this extra byte we have to go and get it special.

Specifically, this seems designed to do this.   An extra read inside of the main read loop.

//if(!read_video_packet(d_video)) break; // EOF

But if you look at the code for read_video_packet, it seems to only 'copy the startcode' for the first bytes.

  // COPY STARTCODE:
  packet_start=videobuf_len;
  videobuffer[videobuf_len+0]=0;
  videobuffer[videobuf_len+1]=0;
  videobuffer[videobuf_len+2]=1;
  videobuffer[videobuf_len+3]=next_nal;
videobuf_len+=4;

SOOOO, not only is x3F the wrong bit-mask, the data won't be there anyway. And, to compound the problem, this extra read_video_packet PROBABLY does something funky to the state of the stream.  Not sure. Anyway.

My solution/hack.

Super Global variable "peek_nal_descriptor"
Set this whenever getting data, but don't mess up the state of the stream..use "demux_peekc".

next_nal = demux_getc(ds);
    peek_nal_descriptor = demux_peekc(ds);

Use super global variable in seek code.

    if(i==0x1B6) {
          if ( (peek_nal_descriptor & 0xc0)  == 0)
        break;