sync fixes

This commit is contained in:
Glenn Maynard
2003-09-21 07:49:36 +00:00
parent 60264048d0
commit d2b3919987
@@ -270,10 +270,6 @@ int FFMpeg_Helper::DecodePacket()
GetNextTimestamp = true; GetNextTimestamp = true;
/* Length of this frame: */
LastFrameDelay = (float)m_stream->codec.frame_rate_base / m_stream->codec.frame_rate;
LastFrameDelay += frame.repeat_pict * (LastFrameDelay * 0.5f);
if ( m_stream->codec.has_b_frames && if ( m_stream->codec.has_b_frames &&
frame.pict_type != FF_B_TYPE ) frame.pict_type != FF_B_TYPE )
{ {
@@ -291,6 +287,10 @@ int FFMpeg_Helper::DecodePacket()
CurrentTimestamp += LastFrameDelay; CurrentTimestamp += LastFrameDelay;
} }
/* Length of this frame: */
LastFrameDelay = (float)m_stream->codec.frame_rate_base / m_stream->codec.frame_rate;
LastFrameDelay += frame.repeat_pict * (LastFrameDelay * 0.5f);
return 1; return 1;
} }
@@ -539,6 +539,7 @@ void MovieTexture_FFMpeg::DecoderThread()
{ {
RageTimer Timer; RageTimer Timer;
float Clock = 0; float Clock = 0;
float ClockOffset = 0;
bool FrameSkipMode = false; bool FrameSkipMode = false;
/* Movie decoding is bursty. We burst decode a frame, then we sleep, then we burst /* Movie decoding is bursty. We burst decode a frame, then we sleep, then we burst
@@ -553,6 +554,7 @@ void MovieTexture_FFMpeg::DecoderThread()
// LOG->Warn(werr_ssprintf(GetLastError(), "SetThreadPriorityBoost failed")); // LOG->Warn(werr_ssprintf(GetLastError(), "SetThreadPriorityBoost failed"));
CHECKPOINT; CHECKPOINT;
bool FirstDecodedFrame = true;
while( m_State != DECODER_QUIT ) while( m_State != DECODER_QUIT )
{ {
@@ -575,6 +577,28 @@ void MovieTexture_FFMpeg::DecoderThread()
if( ret == -1 ) if( ret == -1 )
return; return;
if( FirstDecodedFrame )
{
/* Some videos start with a timestamp other than 0. I think this is used
* when audio starts before the video. We don't want to honor that, since
* the DShow renderer doesn't and we don't want to break sync compatibility.
*
* Subtlety: this isn't actually the first frame (unless it's a rewind)--we
* did that when we loaded. That's important: if we have B-frames, the first
* frame will be an I-frame with the timestamp of the next P-frame, not its
* own timestamp, and we want to ignore that and look at the next B-frame.
*/
const float expect = decoder->LastFrameDelay;
const float actual = decoder->CurrentTimestamp;
if( actual - expect > 0 )
{
LOG->Trace("Expect %f, got %f -> %f", expect, actual, actual - expect );
ClockOffset = actual - expect;
Clock += ClockOffset;
}
FirstDecodedFrame = false;
}
if( m_bWantRewind && decoder->CurrentTimestamp == 0 ) if( m_bWantRewind && decoder->CurrentTimestamp == 0 )
m_bWantRewind = false; /* ignore */ m_bWantRewind = false; /* ignore */
@@ -597,7 +621,7 @@ void MovieTexture_FFMpeg::DecoderThread()
CreateDecoder(); CreateDecoder();
decoder->Init(); decoder->Init();
Clock = 0; Clock = ClockOffset;
continue; continue;
} }