diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 1206159def..d67875e8f1 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -740,7 +740,6 @@ bool InitPmp(MpegContext * ctx){ InitFFmpeg(); auto mediaengine = ctx->mediaengine; mediaengine->m_isVideoEnd = false; - mediaengine->m_noAudioData = false; mediaengine->m_firstTimeStamp = 0; mediaengine->m_lastTimeStamp = 0; ctx->mpegFirstTimestamp = 0; diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index 4592dbc9d9..10557dc7eb 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -148,7 +148,6 @@ MediaEngine::MediaEngine(): m_pdata(0) { m_firstTimeStamp = 0; m_lastTimeStamp = 0; m_isVideoEnd = false; - m_noAudioData = false; m_ringbuffersize = 0; m_mpegheaderReadPos = 0; @@ -171,7 +170,6 @@ void MediaEngine::closeMedia() { m_demux = 0; AudioClose(&m_audioContext); m_isVideoEnd = false; - m_noAudioData = false; } void MediaEngine::DoState(PointerWrap &p){ @@ -212,11 +210,11 @@ void MediaEngine::DoState(PointerWrap &p){ } p.Do(m_isVideoEnd); - p.Do(m_noAudioData); - if (s >= 3){ + bool noAudioDataRemoved; + p.Do(noAudioDataRemoved); + if (s >= 3) { p.Do(m_audioType); - } - else{ + } else { m_audioType = PSP_CODEC_AT3PLUS; } } @@ -288,7 +286,6 @@ bool MediaEngine::openContext() { setVideoDim(); m_audioContext = new SimpleAudio(m_audioType); m_isVideoEnd = false; - m_noAudioData = false; m_mpegheaderReadPos++; av_seek_frame(m_pFormatCtx, m_videoStream, 0, 0); #endif // USE_FFMPEG @@ -343,7 +340,6 @@ int MediaEngine::addStreamData(u8* buffer, int addSize) { if (!m_pdata->push(buffer, size)) size = 0; if (m_demux) { - m_noAudioData = false; m_demux->addStreamData(buffer, addSize); } #ifdef USE_FFMPEG @@ -729,7 +725,7 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) { return 0; } - // When m_demux , increment pts + // When getting a frame, increment pts m_audiopts += 4180; // Demux now (rather than on add data) so that we select the right stream. @@ -737,9 +733,8 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) { u8 *audioFrame = 0; int headerCode1, headerCode2; - int frameSize = m_demux->getNextaudioFrame(&audioFrame, &headerCode1, &headerCode2); + int frameSize = m_demux->getNextAudioFrame(&audioFrame, &headerCode1, &headerCode2); if (frameSize == 0) { - m_noAudioData = true; return 0; } int outbytes = 0; @@ -761,10 +756,20 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) { } } - m_noAudioData = false; return 0x2000; } +bool MediaEngine::IsNoAudioData() { + if (!m_demux) { + return true; + } + + // Let's double check. Here should be a safe enough place to demux. + m_demux->demux(m_audioStream); + return !m_demux->hasNextAudioFrame(NULL, NULL, NULL, NULL); + +} + s64 MediaEngine::getVideoTimeStamp() { return m_videopts; } diff --git a/Core/HW/MediaEngine.h b/Core/HW/MediaEngine.h index aae6a528a0..378ba18537 100644 --- a/Core/HW/MediaEngine.h +++ b/Core/HW/MediaEngine.h @@ -87,7 +87,7 @@ public: s64 getLastTimeStamp(); bool IsVideoEnd() { return m_isVideoEnd; } - bool IsNoAudioData() { return m_noAudioData; } + bool IsNoAudioData(); void DoState(PointerWrap &p); @@ -128,7 +128,6 @@ public: // TODO: Very little of this below should be public. s64 m_lastTimeStamp; bool m_isVideoEnd; - bool m_noAudioData; int m_ringbuffersize; u8 m_mpegheader[0x10000]; // TODO: Allocate separately diff --git a/Core/HW/MpegDemux.cpp b/Core/HW/MpegDemux.cpp index 1dd1fc8ed5..02b39ba142 100644 --- a/Core/HW/MpegDemux.cpp +++ b/Core/HW/MpegDemux.cpp @@ -45,7 +45,7 @@ void MpegDemux::DoState(PointerWrap &p) { p.DoClass(m_audioStream); } -bool MpegDemux::addStreamData(u8* buf, int addSize) { +bool MpegDemux::addStreamData(const u8 *buf, int addSize) { if (m_readSize + addSize > m_len) return false; memcpy(m_buf + m_readSize, buf, addSize); @@ -234,25 +234,43 @@ static int getNextHeaderPosition(u8* audioStream, int curpos, int limit, int fra return -1; } -int MpegDemux::getNextaudioFrame(u8** buf, int *headerCode1, int *headerCode2) +int MpegDemux::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2) { - int gotsize = m_audioStream.get_front(m_audioFrame, 0x2000); - if (gotsize == 0 || !isHeader(m_audioFrame, 0)) - return 0; - u8 Code1 = m_audioFrame[2]; - u8 Code2 = m_audioFrame[3]; - int frameSize = (((Code1 & 0x03) << 8) | ((Code2 & 0xFF) * 8)) + 0x10; - if (frameSize > gotsize) + int gotsize; + int frameSize; + if (!hasNextAudioFrame(&gotsize, &frameSize, headerCode1, headerCode2)) return 0; int audioPos = 8; int nextHeader = getNextHeaderPosition(m_audioFrame, audioPos, gotsize, frameSize); if (nextHeader >= 0) { audioPos = nextHeader; - } else + } else { audioPos = gotsize; + } m_audioStream.pop_front(0, audioPos); *buf = m_audioFrame + 8; - if (headerCode1) *headerCode1 = Code1; - if (headerCode2) *headerCode2 = Code2; return frameSize - 8; } + +bool MpegDemux::hasNextAudioFrame(int *gotsizeOut, int *frameSizeOut, int *headerCode1, int *headerCode2) +{ + int gotsize = m_audioStream.get_front(m_audioFrame, 0x2000); + if (gotsize == 0 || !isHeader(m_audioFrame, 0)) + return false; + u8 code1 = m_audioFrame[2]; + u8 code2 = m_audioFrame[3]; + int frameSize = (((code1 & 0x03) << 8) | ((code2 & 0xFF) * 8)) + 0x10; + if (frameSize > gotsize) + return false; + + if (gotsizeOut) + *gotsizeOut = gotsize; + if (frameSizeOut) + *frameSizeOut = frameSize; + if (headerCode1) + *headerCode1 = code1; + if (headerCode2) + *headerCode2 = code2; + + return true; +} diff --git a/Core/HW/MpegDemux.h b/Core/HW/MpegDemux.h index 0a973e9c5c..11f2bccf82 100644 --- a/Core/HW/MpegDemux.h +++ b/Core/HW/MpegDemux.h @@ -14,11 +14,12 @@ public: MpegDemux(int size, int offset); ~MpegDemux(); - bool addStreamData(u8* buf, int addSize); + bool addStreamData(const u8 *buf, int addSize); void demux(int audioChannel); // return its framesize - int getNextaudioFrame(u8** buf, int *headerCode1, int *headerCode2); + int getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2); + bool hasNextAudioFrame(int *gotsizeOut, int *frameSizeOut, int *headerCode1, int *headerCode2); inline int getRemainSize() { return m_len - m_readSize;