split out RunDecode function

This commit is contained in:
Glenn Maynard
2004-04-02 23:00:29 +00:00
parent 7bdb2d5a6b
commit c8f626cf8c
2 changed files with 121 additions and 99 deletions
@@ -420,6 +420,8 @@ try {
m_ImageWaiting = false; m_ImageWaiting = false;
m_Rate = 1; m_Rate = 1;
m_bWantRewind = false; m_bWantRewind = false;
m_Clock = 0;
m_FrameSkipMode = false;
m_BufferFinished = SDL_CreateSemaphore(0); m_BufferFinished = SDL_CreateSemaphore(0);
@@ -711,49 +713,28 @@ void MovieTexture_FFMpeg::CreateTexture()
m_uTexHandle = DISPLAY->CreateTexture( pixfmt, m_img, false ); m_uTexHandle = DISPLAY->CreateTexture( pixfmt, m_img, false );
} }
/* Handle decoding for a frame. Return true if a frame was decoded and is waiting
* to be handled. */
void MovieTexture_FFMpeg::DecoderThread() bool MovieTexture_FFMpeg::RunDecode()
{ {
RageTimer Timer;
float Clock = 0;
bool FrameSkipMode = false;
#if defined(_WINDOWS)
/* Movie decoding is bursty. We burst decode a frame, then we sleep, then we burst
* to YUV->RGB convert, then we wait for the frame to move, and we repeat. */
// if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL))
// LOG->Warn(werr_ssprintf(GetLastError(), "Failed to set sound thread priority"));
/* Windows likes to boost priority when processes come out of a wait state. We don't
* want that, since it'll result in us having a small priority boost after each movie
* frame, resulting in skips in the gameplay thread. */
if( !SetThreadPriorityBoost(GetCurrentThread(), TRUE) && GetLastError() != ERROR_NOT_SUPPORTED )
LOG->Warn( werr_ssprintf(GetLastError(), "SetThreadPriorityBoost failed") );
#endif
CHECKPOINT;
while( m_State != DECODER_QUIT )
{
if( m_State == PAUSE_DECODER ) if( m_State == PAUSE_DECODER )
{ {
SDL_Delay( 10 );
/* The video isn't running; skip time. */ /* The video isn't running; skip time. */
Timer.GetDeltaTime(); m_Timer.GetDeltaTime();
continue; return false;
} }
if( m_State != PLAYING )
return false;
CHECKPOINT; CHECKPOINT;
/* We're playing. Update the clock. */ /* We're playing. Update the clock. */
Clock += Timer.GetDeltaTime() * m_Rate; m_Clock += m_Timer.GetDeltaTime() * m_Rate;
/* Read a frame. */ /* Read a frame. */
int ret = decoder->GetFrame(); int ret = decoder->GetFrame();
if( ret == -1 ) if( ret == -1 )
return; return false;
if( m_bWantRewind && decoder->GetTimestamp() == 0 ) if( m_bWantRewind && decoder->GetTimestamp() == 0 )
m_bWantRewind = false; /* ignore */ m_bWantRewind = false; /* ignore */
@@ -762,7 +743,7 @@ void MovieTexture_FFMpeg::DecoderThread()
{ {
/* EOF. */ /* EOF. */
if( !m_bLoop ) if( !m_bLoop )
return; return false;
LOG->Trace( "File \"%s\" looping", GetID().filename.c_str() ); LOG->Trace( "File \"%s\" looping", GetID().filename.c_str() );
m_bWantRewind = true; m_bWantRewind = true;
@@ -777,22 +758,22 @@ void MovieTexture_FFMpeg::DecoderThread()
CreateDecoder(); CreateDecoder();
decoder->Init(); decoder->Init();
Clock = 0; m_Clock = 0;
continue; return false;
} }
/* We got a frame. */ /* We got a frame. */
const float Offset = decoder->GetTimestamp() - Clock; const float Offset = decoder->GetTimestamp() - m_Clock;
/* If we're ahead, we're decoding too fast; delay. */ /* If we're ahead, we're decoding too fast; delay. */
if( Offset > 0 ) if( Offset > 0 )
{ {
SDL_Delay( int(1000*Offset) ); SDL_Delay( int(1000*Offset) );
if( FrameSkipMode ) if( m_FrameSkipMode )
{ {
/* We're caught up; stop skipping frames. */ /* We're caught up; stop skipping frames. */
LOG->Trace( "stopped skipping frames" ); LOG->Trace( "stopped skipping frames" );
FrameSkipMode = false; m_FrameSkipMode = false;
} }
} else { } else {
/* We're behind by -Offset seconds. /* We're behind by -Offset seconds.
@@ -822,16 +803,16 @@ void MovieTexture_FFMpeg::DecoderThread()
*/ */
const float FrameSkipThreshold = 0.5f; const float FrameSkipThreshold = 0.5f;
if( -Offset >= FrameSkipThreshold && !FrameSkipMode ) if( -Offset >= FrameSkipThreshold && !m_FrameSkipMode )
{ {
LOG->Trace( "(%s) Time is %f, and the movie is at %f. Entering frame skip mode.", LOG->Trace( "(%s) Time is %f, and the movie is at %f. Entering frame skip mode.",
GetID().filename.c_str(), Clock, decoder->GetTimestamp()); GetID().filename.c_str(), m_Clock, decoder->GetTimestamp());
FrameSkipMode = true; m_FrameSkipMode = true;
} }
} }
if( FrameSkipMode && decoder->m_stream->codec.frame_number % 2 ) if( m_FrameSkipMode && decoder->m_stream->codec.frame_number % 2 )
continue; /* skip */ return false; /* skip */
/* Convert it. */ /* Convert it. */
ConvertFrame(); ConvertFrame();
@@ -839,7 +820,42 @@ void MovieTexture_FFMpeg::DecoderThread()
/* Signal the main thread to update the image on the next Update. */ /* Signal the main thread to update the image on the next Update. */
m_ImageWaiting=true; m_ImageWaiting=true;
return true;
}
void MovieTexture_FFMpeg::DecoderThread()
{
#if defined(_WINDOWS)
/* Movie decoding is bursty. We burst decode a frame, then we sleep, then we burst
* to YUV->RGB convert, then we wait for the frame to move, and we repeat. */
// if(!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL))
// LOG->Warn(werr_ssprintf(GetLastError(), "Failed to set sound thread priority"));
/* Windows likes to boost priority when processes come out of a wait state. We don't
* want that, since it'll result in us having a small priority boost after each movie
* frame, resulting in skips in the gameplay thread. */
if( !SetThreadPriorityBoost(GetCurrentThread(), TRUE) && GetLastError() != ERROR_NOT_SUPPORTED )
LOG->Warn( werr_ssprintf(GetLastError(), "SetThreadPriorityBoost failed") );
#endif
CHECKPOINT;
while( m_State != DECODER_QUIT )
{
bool bGotFrame = RunDecode();
if( m_State == PAUSE_DECODER )
{
/* We aren't feeding frames, so we aren't waiting; don't chew CPU. */
SDL_Delay( 10 );
continue;
}
if( !bGotFrame )
continue;
/* SDL_SemWait does not properly retry sem_wait in Linux on EINTR. */ /* SDL_SemWait does not properly retry sem_wait in Linux on EINTR. */
int ret;
do do
{ {
CHECKPOINT; CHECKPOINT;
@@ -6,6 +6,7 @@
#include "RageDisplay.h" #include "RageDisplay.h"
#include "RageTexture.h" #include "RageTexture.h"
#include "RageThreads.h" #include "RageThreads.h"
#include "RageTimer.h"
#include "SDL_mutex.h" #include "SDL_mutex.h"
@@ -64,6 +65,10 @@ private:
SDL_sem *m_BufferFinished; SDL_sem *m_BufferFinished;
RageTimer m_Timer;
float m_Clock;
bool m_FrameSkipMode;
static int DecoderThread_start(void *p) { ((MovieTexture_FFMpeg *)(p))->DecoderThread(); return 0; } static int DecoderThread_start(void *p) { ((MovieTexture_FFMpeg *)(p))->DecoderThread(); return 0; }
void DecoderThread(); void DecoderThread();
RageThread m_DecoderThread; RageThread m_DecoderThread;
@@ -77,6 +82,7 @@ private:
void DestroyTexture(); void DestroyTexture();
void StartThread(); void StartThread();
void StopThread(); void StopThread();
bool RunDecode();
}; };
/* /*