Add FrameHolder struct and logic around finding totalFrames of movies.
This commit is contained in:
@@ -611,7 +611,7 @@ void ActorMultiVertex::Update(float fDelta)
|
|||||||
UpdateAnimationState();
|
UpdateAnimationState();
|
||||||
if(!skip_this_movie_update && _decode_movie)
|
if(!skip_this_movie_update && _decode_movie)
|
||||||
{
|
{
|
||||||
_Texture->DecodeSeconds(std::max(0.0f, time_passed));
|
_Texture->UpdateMovie(std::max(0.0f, time_passed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ public:
|
|||||||
|
|
||||||
// movie texture/animated texture stuff
|
// movie texture/animated texture stuff
|
||||||
virtual void SetPosition( float /* fSeconds */ ) {} // seek
|
virtual void SetPosition( float /* fSeconds */ ) {} // seek
|
||||||
virtual void DecodeSeconds( float /* fSeconds */ ) {} // decode
|
virtual void UpdateMovie( float /* fSeconds */ ) {} // decode and update
|
||||||
virtual void SetPlaybackRate( float ) {}
|
virtual void SetPlaybackRate( float ) {}
|
||||||
virtual bool IsAMovie() const { return false; }
|
virtual bool IsAMovie() const { return false; }
|
||||||
virtual void SetLooping(bool) { }
|
virtual void SetLooping(bool) { }
|
||||||
|
|||||||
+1
-1
@@ -474,7 +474,7 @@ void Sprite::Update( float fDelta )
|
|||||||
|
|
||||||
// If the texture is a movie, decode frames.
|
// If the texture is a movie, decode frames.
|
||||||
if(!bSkipThisMovieUpdate && m_DecodeMovie)
|
if(!bSkipThisMovieUpdate && m_DecodeMovie)
|
||||||
m_pTexture->DecodeSeconds( std::max(0.0f, fTimePassed) );
|
m_pTexture->UpdateMovie( std::max(0.0f, fTimePassed) );
|
||||||
|
|
||||||
// update scrolling
|
// update scrolling
|
||||||
if( m_fTexCoordVelocityX != 0 || m_fTexCoordVelocityY != 0 )
|
if( m_fTexCoordVelocityX != 0 || m_fTexCoordVelocityY != 0 )
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ void MovieDecoder_FFMpeg::Init()
|
|||||||
m_fTimestamp = 0;
|
m_fTimestamp = 0;
|
||||||
m_fLastFrameDelay = 0;
|
m_fLastFrameDelay = 0;
|
||||||
m_iFrameNumber = -1; /* decode one frame and you're on the 0th */
|
m_iFrameNumber = -1; /* decode one frame and you're on the 0th */
|
||||||
|
m_totalFrames = 0;
|
||||||
m_fTimestampOffset = 0;
|
m_fTimestampOffset = 0;
|
||||||
m_fLastFrame = 0;
|
m_fLastFrame = 0;
|
||||||
m_swsctx = nullptr;
|
m_swsctx = nullptr;
|
||||||
@@ -455,6 +456,15 @@ RString MovieDecoder_FFMpeg::Open( RString sFile )
|
|||||||
|
|
||||||
LOG->Trace("Bitrate: %i", static_cast<int>(m_pStreamCodec->bit_rate));
|
LOG->Trace("Bitrate: %i", static_cast<int>(m_pStreamCodec->bit_rate));
|
||||||
LOG->Trace("Codec pixel format: %s", avcodec::av_get_pix_fmt_name(m_pStreamCodec->pix_fmt));
|
LOG->Trace("Codec pixel format: %s", avcodec::av_get_pix_fmt_name(m_pStreamCodec->pix_fmt));
|
||||||
|
m_totalFrames = m_pStream->nb_frames;
|
||||||
|
if (m_totalFrames <= 0) {
|
||||||
|
// Sometimes we might not get a correct frame count.
|
||||||
|
// In that case, approximate and fix it later.
|
||||||
|
m_totalFrames = m_fctx->duration // microseconds
|
||||||
|
* (m_pStream->avg_frame_rate.num) / (m_pStream->avg_frame_rate.den) / (1000000);
|
||||||
|
LOG->Trace("Number of frames provided is inaccurate, estimating.");
|
||||||
|
}
|
||||||
|
LOG->Trace("Number of frames detected: %i", m_totalFrames);
|
||||||
|
|
||||||
return RString();
|
return RString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "MovieTexture_Generic.h"
|
#include "MovieTexture_Generic.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
struct RageSurface;
|
struct RageSurface;
|
||||||
|
|
||||||
@@ -23,6 +24,27 @@ namespace avcodec
|
|||||||
#define STEPMANIA_FFMPEG_BUFFER_SIZE 4096
|
#define STEPMANIA_FFMPEG_BUFFER_SIZE 4096
|
||||||
static const int sws_flags = SWS_BICUBIC; // XXX: Reasonable default?
|
static const int sws_flags = SWS_BICUBIC; // XXX: Reasonable default?
|
||||||
|
|
||||||
|
struct FrameHolder {
|
||||||
|
avcodec::AVFrame frame;
|
||||||
|
avcodec::AVPacket packet;
|
||||||
|
float frameTimestamp;
|
||||||
|
float frameDelay;
|
||||||
|
bool decoded = false;
|
||||||
|
std::mutex lock; // Protects the frame as it's being initialized.
|
||||||
|
|
||||||
|
FrameHolder() = default;
|
||||||
|
|
||||||
|
// Copy constructor, unused but we need to make the compiler not copy
|
||||||
|
// the mutex.
|
||||||
|
FrameHolder(const FrameHolder& fh) {
|
||||||
|
frame = fh.frame;
|
||||||
|
packet = fh.packet;
|
||||||
|
frameTimestamp = fh.frameTimestamp;
|
||||||
|
frameDelay = fh.frameDelay;
|
||||||
|
decoded = fh.decoded;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class MovieTexture_FFMpeg: public MovieTexture_Generic
|
class MovieTexture_FFMpeg: public MovieTexture_Generic
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -76,6 +98,7 @@ private:
|
|||||||
float m_fTimestampOffset;
|
float m_fTimestampOffset;
|
||||||
float m_fLastFrameDelay;
|
float m_fLastFrameDelay;
|
||||||
int m_iFrameNumber;
|
int m_iFrameNumber;
|
||||||
|
int m_totalFrames; // Total number of frames in the movie.
|
||||||
|
|
||||||
unsigned char *m_buffer;
|
unsigned char *m_buffer;
|
||||||
avcodec::AVIOContext *m_avioContext;
|
avcodec::AVIOContext *m_avioContext;
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ float MovieTexture_Generic::CheckFrameTime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Decode data. */
|
/* Decode data. */
|
||||||
void MovieTexture_Generic::DecodeSeconds( float fSeconds )
|
void MovieTexture_Generic::UpdateMovie( float fSeconds )
|
||||||
{
|
{
|
||||||
m_fClock += fSeconds * m_fRate;
|
m_fClock += fSeconds * m_fRate;
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
virtual void Reload();
|
virtual void Reload();
|
||||||
|
|
||||||
virtual void SetPosition( float fSeconds );
|
virtual void SetPosition( float fSeconds );
|
||||||
virtual void DecodeSeconds( float fSeconds );
|
virtual void UpdateMovie( float fSeconds );
|
||||||
virtual void SetPlaybackRate( float fRate ) { m_fRate = fRate; }
|
virtual void SetPlaybackRate( float fRate ) { m_fRate = fRate; }
|
||||||
void SetLooping( bool bLooping=true ) { m_bLoop = bLooping; }
|
void SetLooping( bool bLooping=true ) { m_bLoop = bLooping; }
|
||||||
std::uintptr_t GetTexHandle() const;
|
std::uintptr_t GetTexHandle() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user