diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 1c2bfcef56..0a27c082b6 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1053,7 +1053,8 @@ int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) streamInfo->second.needsReset = false; } - if (mpegRingbuffer.packetsFree == mpegRingbuffer.packets) { + // The audio can end earlier than the video does. + if (mpegRingbuffer.packetsFree == mpegRingbuffer.packets || (ctx->mediaengine->IsAudioEnd() && !ctx->mediaengine->IsVideoEnd())) { DEBUG_LOG(HLE, "PSP_ERROR_MPEG_NO_DATA=sceMpegGetAtracAu(%08x, %08x, %08x, %08x)", mpeg, streamId, auAddr, attrAddr); // TODO: Does this really delay? return hleDelayResult(PSP_ERROR_MPEG_NO_DATA, "mpeg get atrac", mpegDecodeErrorDelayMs); diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 81664d74b6..88e24b2f7e 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -92,6 +92,7 @@ MediaEngine::MediaEngine(): m_streamSize(0), m_readSize(0), m_decodedPos(0), m_p m_demux = 0; m_audioContext = 0; m_isVideoEnd = false; + m_isAudioEnd = false; } MediaEngine::~MediaEngine() { @@ -130,6 +131,7 @@ void MediaEngine::closeMedia() { m_demux = 0; Atrac3plus_Decoder::CloseContext(&m_audioContext); m_isVideoEnd = false; + m_isAudioEnd = false; } int _MpegReadbuffer(void *opaque, uint8_t *buf, int buf_size) @@ -220,6 +222,7 @@ bool MediaEngine::openContext() { m_audioPos = 0; m_audioContext = Atrac3plus_Decoder::OpenContext(); m_isVideoEnd = false; + m_isAudioEnd = false; m_decodedPos = mpegoffset; #endif // USE_FFMPEG return true; @@ -561,6 +564,7 @@ int MediaEngine::getAudioSamples(u8* buffer) { int audioSize = m_demux->getaudioStream(&audioStream); if (m_audioPos >= audioSize || !isHeader(audioStream, m_audioPos)) { + m_isAudioEnd = m_demux->getFilePosition() >= m_streamSize; return 0; } u8 headerCode1 = audioStream[2]; @@ -588,6 +592,7 @@ int MediaEngine::getAudioSamples(u8* buffer) { } else m_audioPos = audioSize; m_audiopts += 4180; + m_decodedPos += frameSize; return outbytes; } diff --git a/Core/HW/MediaEngine.h b/Core/HW/MediaEngine.h index f9ac3304ff..d060ca9a40 100644 --- a/Core/HW/MediaEngine.h +++ b/Core/HW/MediaEngine.h @@ -61,7 +61,8 @@ public: s64 getAudioTimeStamp(); s64 getLastTimeStamp(); - bool IsVideoEnd() { return m_isVideoEnd;} + bool IsVideoEnd() { return m_isVideoEnd; } + bool IsAudioEnd() { return m_isAudioEnd; } void DoState(PointerWrap &p) { p.Do(m_streamSize); @@ -101,4 +102,5 @@ public: s64 m_audiopts; bool m_isVideoEnd; + bool m_isAudioEnd; }; diff --git a/Core/HW/MpegDemux.h b/Core/HW/MpegDemux.h index 5d760a6ae6..7eb6374d16 100644 --- a/Core/HW/MpegDemux.h +++ b/Core/HW/MpegDemux.h @@ -15,8 +15,9 @@ public: void demux(); - // return it's size + // return its size int getaudioStream(u8 **audioStream); + int getFilePosition() { return m_index; } private: struct PesHeader { long pts;