/*
- Copyright 2005 Mark Calderbank
+ Copyright 2005-2006 Mark Calderbank
This file is part of VOMP.
void Demuxer::seek()
{
- seeking = 1;
+ vid_seeking = aud_seeking = 1;
+ video_pts = audio_pts = 0;
}
void Demuxer::setAudioStream(int id)
parse_video_details(local_frame+6, frame_length);
}
- if (!seeking)
+ if (!vid_seeking)
{
// We have the whole frame in local_frame. Send it to the stream.
// We still support streams that might not consume all the data.
inbuf += len; ret += len; state_framepos += len;
if (len < bytes_remaining) // Not all arrived yet
return ret;
+ parse_audio_details(local_frame+6, frame_length);
}
- // We have the whole frame in local_frame. Send it to the stream.
- // We still support streams that might not consume all the data.
- state_stream_fill += audiostream.put(local_frame,
- 6 + frame_length - state_stream_fill);
- if (state_stream_fill < frame_length + 6) // stream is full!
+ if (!aud_seeking)
{
- *full = 1; return ret;
+ // We have the whole frame in local_frame. Send it to the stream.
+ // We still support streams that might not consume all the data.
+ state_stream_fill += audiostream.put(local_frame,
+ 6 + frame_length - state_stream_fill);
+ if (state_stream_fill < frame_length + 6) // stream is full!
+ {
+ *full = 1; return ret;
+ }
}
state_frametype = state_framepos = 0;
return ret;
}
}
+void Demuxer::parse_audio_details(UCHAR* buf, int len)
+{
+ // Extract audio PTS if it exists
+ if ( buf[1] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
+ {
+ audio_pts = ( (ULLONG)(buf[3] & 0x0E) << 29 ) |
+ ( (ULLONG)(buf[4]) << 22 ) |
+ ( (ULLONG)(buf[5] & 0xFE) << 14 ) |
+ ( (ULLONG)(buf[6]) << 7 ) |
+ ( (ULLONG)(buf[7] & 0xFE) >> 1 );
+ if (aud_seeking && !vid_seeking && audio_pts >= video_pts_seek)
+ {
+ aud_seeking = 0;
+ Log::getInstance()->log("Demuxer", Log::DEBUG,
+ "Leaving audio seek: Audio PTS = %llu", audio_pts);
+ }
+ }
+}
+
void Demuxer::parse_video_details(UCHAR* buf, int len)
{
// Extract video PTS if it exists
byte = *(buf++); --len;
switch (byte)
{
- case 0x00: // Picture header
+/* case 0x00: // Picture header
// 10 bits: temporal reference
// 3 bits: coding type (I/P/B)
// ...
buf += 4; // Minimum length of picture header
len -= 4;
break;
+*/
case 0xb3: // Sequence header
// 12 bits: Horizontal size
// 12 bits: Vertical size
bit_rate = ((int)buf[4] << 10) |
((int)buf[5] << 2) |
((int)buf[6] >> 6);
- seeking = 0;
+ if (vid_seeking)
+ {
+ vid_seeking = 0;
+ video_pts_seek = video_pts;
+ Log::getInstance()->log("Demuxer", Log::DEBUG,
+ "Entering video seek: Video PTS = %llu", video_pts);
+ Log::getInstance()->log("Demuxer", Log::DEBUG,
+ "Entering video seek: Audio PTS = %llu", audio_pts);
+ }
buf += 8; // Minimum length of sequence header
len -= 8;
break;
+/*
case 0xb8: // Group header
// We're not going to bother parsing anything.
seeking = 0;
buf += 4; // Minimum length of group header
len -= 4;
break;
+*/
}
}
}
UINT pattern = *(UINT*)buf;
buf++; len--;
if (pattern < LoPattern || pattern > HiPattern) continue;
+ if ((buf[5] & 0xC0) != 0x80) continue;
UINT framelength = ((UINT)buf[3] << 8) | buf[4];
- buf += 5; len -= 5;
- if ( buf[1] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
+ if ( buf[6] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
{
- *dest = ( (ULLONG)(buf[3] & 0x0E) << 29 ) |
- ( (ULLONG)(buf[4]) << 22 ) |
- ( (ULLONG)(buf[5] & 0xFE) << 14 ) |
- ( (ULLONG)(buf[6]) << 7 ) |
- ( (ULLONG)(buf[7] & 0xFE) >> 1 );
+ if ( (buf[8] & 0x01) != 0x01 ||
+ (buf[10] & 0x01) != 0x01 ||
+ (buf[12] & 0x01) != 0x01) continue;
+
+ *dest = ( (ULLONG)(buf[8] & 0x0E) << 29 ) |
+ ( (ULLONG)(buf[9]) << 22 ) |
+ ( (ULLONG)(buf[10] & 0xFE) << 14 ) |
+ ( (ULLONG)(buf[11]) << 7 ) |
+ ( (ULLONG)(buf[12] & 0xFE) >> 1 );
return 1;
}
+ buf += 5; len -= 5;
buf += framelength; len -= framelength;
}
// No PTS found.