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();
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
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 bool IsAMovie() const { return false; }
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(!bSkipThisMovieUpdate && m_DecodeMovie)
m_pTexture->DecodeSeconds( std::max(0.0f, fTimePassed) );
m_pTexture->UpdateMovie( std::max(0.0f, fTimePassed) );
// update scrolling
if( m_fTexCoordVelocityX != 0 || m_fTexCoordVelocityY != 0 )
+12 -2
View File
@@ -156,6 +156,7 @@ void MovieDecoder_FFMpeg::Init()
m_fTimestamp = 0;
m_fLastFrameDelay = 0;
m_iFrameNumber = -1; /* decode one frame and you're on the 0th */
m_totalFrames = 0;
m_fTimestampOffset = 0;
m_fLastFrame = 0;
m_swsctx = nullptr;
@@ -453,8 +454,17 @@ RString MovieDecoder_FFMpeg::Open( RString sFile )
if( !sError.empty() )
return ssprintf( "AVCodec (%s): %s", sFile.c_str(), sError.c_str() );
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("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));
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();
}
@@ -6,6 +6,7 @@
#include "MovieTexture_Generic.h"
#include <cstdint>
#include <mutex>
struct RageSurface;
@@ -23,6 +24,27 @@ namespace avcodec
#define STEPMANIA_FFMPEG_BUFFER_SIZE 4096
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
{
public:
@@ -76,6 +98,7 @@ private:
float m_fTimestampOffset;
float m_fLastFrameDelay;
int m_iFrameNumber;
int m_totalFrames; // Total number of frames in the movie.
unsigned char *m_buffer;
avcodec::AVIOContext *m_avioContext;
@@ -413,7 +413,7 @@ float MovieTexture_Generic::CheckFrameTime()
}
/* Decode data. */
void MovieTexture_Generic::DecodeSeconds( float fSeconds )
void MovieTexture_Generic::UpdateMovie( float fSeconds )
{
m_fClock += fSeconds * m_fRate;
+1 -1
View File
@@ -92,7 +92,7 @@ public:
virtual void Reload();
virtual void SetPosition( float fSeconds );
virtual void DecodeSeconds( float fSeconds );
virtual void UpdateMovie( float fSeconds );
virtual void SetPlaybackRate( float fRate ) { m_fRate = fRate; }
void SetLooping( bool bLooping=true ) { m_bLoop = bLooping; }
std::uintptr_t GetTexHandle() const;