From 6ee2f6fa042f4ee8ed34c8515abfb25fb642986e Mon Sep 17 00:00:00 2001 From: Mark Calderbank Date: Sat, 29 Apr 2006 15:38:08 +0000 Subject: [PATCH] Sync changes in demuxer --- demuxer.cc | 76 +++++++++++++++++++++++++++++++++++++++++------------- demuxer.h | 8 ++++-- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/demuxer.cc b/demuxer.cc index 1911f44..b529e41 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -1,5 +1,5 @@ /* - Copyright 2005 Mark Calderbank + Copyright 2005-2006 Mark Calderbank This file is part of VOMP. @@ -101,7 +101,8 @@ void Demuxer::flushAudio() void Demuxer::seek() { - seeking = 1; + vid_seeking = aud_seeking = 1; + video_pts = audio_pts = 0; } void Demuxer::setAudioStream(int id) @@ -327,7 +328,7 @@ int Demuxer::parse_video_frame(int len, int* full) 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. @@ -395,15 +396,19 @@ int Demuxer::parse_audio_frame(int len, int* full) 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; @@ -446,6 +451,25 @@ int Demuxer::parse_private1_frame(int len, int* full) } } +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 @@ -479,7 +503,7 @@ void Demuxer::parse_video_details(UCHAR* buf, int len) byte = *(buf++); --len; switch (byte) { - case 0x00: // Picture header +/* case 0x00: // Picture header // 10 bits: temporal reference // 3 bits: coding type (I/P/B) // ... @@ -489,6 +513,7 @@ void Demuxer::parse_video_details(UCHAR* buf, int len) buf += 4; // Minimum length of picture header len -= 4; break; +*/ case 0xb3: // Sequence header // 12 bits: Horizontal size // 12 bits: Vertical size @@ -508,16 +533,26 @@ void Demuxer::parse_video_details(UCHAR* buf, int len) 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; +*/ } } } @@ -532,20 +567,25 @@ int Demuxer::findVideoPTS(UCHAR* buf, int len, ULLONG* dest) 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. diff --git a/demuxer.h b/demuxer.h index 604b3cd..ff7e90b 100644 --- a/demuxer.h +++ b/demuxer.h @@ -1,5 +1,5 @@ /* - Copyright 2005 Mark Calderbank + Copyright 2005-2006 Mark Calderbank This file is part of VOMP. @@ -86,7 +86,8 @@ class Demuxer Stream audiostream; int shutdown(); int initted; - int seeking; + int vid_seeking; + int aud_seeking; UCHAR* inbuf; void setAspectRatio(enum AspectRatio); @@ -101,6 +102,7 @@ class Demuxer int parse_audio_frame(int len, int* full); int parse_private1_frame(int len, int* full); void parse_video_details(UCHAR* buf, int len); + void parse_audio_details(UCHAR* buf, int len); UCHAR* local_frame; static const int demuxMemoryV = 2097152; @@ -171,6 +173,8 @@ class Demuxer int frame_rate; int bit_rate; ULLONG video_pts; + ULLONG video_pts_seek; + ULLONG audio_pts; }; #endif -- 2.39.5