Add FrameHolder struct and logic around finding totalFrames of movies.

This commit is contained in:
Brandon W
2024-07-25 11:42:16 -07:00
committed by teejusb
parent 75531a67a0
commit 23f7ebd476
7 changed files with 40 additions and 7 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -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;