Allow frames that didn't decode to skip.
This commit is contained in:
@@ -223,8 +223,12 @@ bool MovieDecoder_FFMpeg::IsCurrentFrameReady() {
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex>(m_FrameBuffer[m_iFrameNumber].lock);
|
||||
if (m_FrameBuffer[m_iFrameNumber].skip) {
|
||||
LOG->Info("Frame %i not decoded, skipping...", m_iFrameNumber);
|
||||
return true;
|
||||
}
|
||||
if (!m_FrameBuffer[m_iFrameNumber].decoded) {
|
||||
LOG->Info("Frame %i not decoded, total frames: %i", m_iFrameNumber, m_totalFrames);
|
||||
LOG->Info("Frame %i not decoded and was not skipped, total frames: %i", m_iFrameNumber, m_totalFrames);
|
||||
}
|
||||
return m_FrameBuffer[m_iFrameNumber].decoded;
|
||||
}
|
||||
@@ -344,19 +348,22 @@ int MovieDecoder_FFMpeg::DecodePacketInBuffer() {
|
||||
m_FrameBuffer.back().packet.data = m_FrameBuffer.back().packet.size ? m_FrameBuffer.back().packet.data : nullptr;
|
||||
int len = m_FrameBuffer.back().packet.size;
|
||||
avcodec::avcodec_send_packet(m_pStreamCodec, &m_FrameBuffer.back().packet);
|
||||
int iGotFrame = !avcodec::avcodec_receive_frame(m_pStreamCodec, &m_FrameBuffer.back().frame);
|
||||
int avcodec_return = avcodec::avcodec_receive_frame(m_pStreamCodec, &m_FrameBuffer.back().frame);
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
LOG->Warn("avcodec_decode_video2: %i", len);
|
||||
LOG->Warn("avcodec_decode_video2 fatal error, packet size negative: %i", len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_iCurrentPacketOffset += len;
|
||||
|
||||
if (!iGotFrame)
|
||||
if (avcodec_return != 0)
|
||||
{
|
||||
LOG->Warn("Frame number %i not successfully decoded into buffer.", static_cast<int>(m_FrameBuffer.size() - 1));
|
||||
LOG->Warn(
|
||||
"Frame number %i not successfully decoded into buffer. avcodec_receive_frame status: %i",
|
||||
static_cast<int>(m_FrameBuffer.size() - 1),
|
||||
avcodec_return);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -385,6 +392,13 @@ int MovieDecoder_FFMpeg::DecodePacketInBuffer() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This if statement means the packet did not decode correctly. This is not
|
||||
// necessarily fatal for video playback, but out of caution the frame should
|
||||
// be skipped.
|
||||
if (!m_FrameBuffer.back().decoded) {
|
||||
m_FrameBuffer.back().skip = true;
|
||||
}
|
||||
|
||||
return 0; /* packet done */
|
||||
}
|
||||
|
||||
@@ -510,6 +524,17 @@ int MovieDecoder_FFMpeg::DecodePacket( float fTargetTime )
|
||||
return 0; /* packet done */
|
||||
}
|
||||
|
||||
bool MovieDecoder_FFMpeg::SkipNextFrame() {
|
||||
if (m_iFrameNumber > (m_totalFrames - 1)) {
|
||||
return true;
|
||||
}
|
||||
if (m_FrameBuffer[m_iFrameNumber].skip) {
|
||||
m_iFrameNumber++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MovieDecoder_FFMpeg::GetFrame(RageSurface* pSurface)
|
||||
{
|
||||
avcodec::AVFrame pict;
|
||||
|
||||
@@ -30,6 +30,7 @@ struct FrameHolder {
|
||||
float frameTimestamp;
|
||||
float frameDelay;
|
||||
bool decoded = false;
|
||||
bool skip = false;
|
||||
std::mutex lock; // Protects the frame as it's being initialized.
|
||||
|
||||
FrameHolder() = default;
|
||||
@@ -42,6 +43,7 @@ struct FrameHolder {
|
||||
frameTimestamp = fh.frameTimestamp;
|
||||
frameDelay = fh.frameDelay;
|
||||
decoded = fh.decoded;
|
||||
skip = fh.skip;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -102,6 +104,9 @@ public:
|
||||
|
||||
void Cancel() { cancel = true; };
|
||||
|
||||
// If the next frame to display had an issue decoding, skip it.
|
||||
bool SkipNextFrame();
|
||||
|
||||
private:
|
||||
void Init();
|
||||
RString OpenCodec();
|
||||
|
||||
@@ -407,6 +407,10 @@ void MovieTexture_Generic::UpdateFrame()
|
||||
/* Just in case we were invalidated: */
|
||||
CreateTexture();
|
||||
|
||||
if (m_pDecoder->SkipNextFrame()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pTextureLock != nullptr)
|
||||
{
|
||||
std::uintptr_t iHandle = m_pTextureIntermediate != nullptr ? m_pTextureIntermediate->GetTexHandle(): this->GetTexHandle();
|
||||
|
||||
@@ -54,6 +54,9 @@ public:
|
||||
*/
|
||||
virtual bool GetFrame( RageSurface *pOut ) = 0;
|
||||
|
||||
// Returns true if the frame should be skipped.
|
||||
virtual bool SkipNextFrame() = 0;
|
||||
|
||||
/* Return the dimensions of the image, in pixels (before aspect ratio
|
||||
* adjustments). */
|
||||
virtual int GetWidth() const = 0;
|
||||
|
||||
Reference in New Issue
Block a user