diff --git a/Core/HLE/sceAudiocodec.cpp b/Core/HLE/sceAudiocodec.cpp index 0da9ede65d..9934aa1d56 100644 --- a/Core/HLE/sceAudiocodec.cpp +++ b/Core/HLE/sceAudiocodec.cpp @@ -118,7 +118,8 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) { // Use SimpleAudioDec to decode audio auto ctx = PSPPointer::Create(ctxPtr); // On stack, no need to allocate. // Decode audio - decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, Memory::GetPointerWrite(ctx->outDataPtr), &outbytes); + int inDataConsumed = 0; + decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, &inDataConsumed, Memory::GetPointerWrite(ctx->outDataPtr), &outbytes); } DEBUG_LOG(ME, "sceAudiocodecDec(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec)); return 0; diff --git a/Core/HLE/sceMp3.cpp b/Core/HLE/sceMp3.cpp index f73ea438aa..cdd8f09964 100644 --- a/Core/HLE/sceMp3.cpp +++ b/Core/HLE/sceMp3.cpp @@ -743,10 +743,11 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed auto outbuff = Memory::GetPointerWriteUnchecked(samplesAddr); int outpcmbytes = 0; - ctx->decoder->Decode(inbuff, 4096, outbuff, &outpcmbytes); + int inbytesConsumed = 0; + ctx->decoder->Decode(inbuff, 4096, &inbytesConsumed, outbuff, &outpcmbytes); NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outpcmbytes, "Mp3LowLevelDecode"); - Memory::Write_U32(ctx->decoder->GetSourcePos(), sourceBytesConsumedAddr); + Memory::Write_U32(inbytesConsumed, sourceBytesConsumedAddr); Memory::Write_U32(outpcmbytes, sampleBytesAddr); return 0; } diff --git a/Core/HW/Atrac3Standalone.cpp b/Core/HW/Atrac3Standalone.cpp index 4aa506a183..da1ccdcd21 100644 --- a/Core/HW/Atrac3Standalone.cpp +++ b/Core/HW/Atrac3Standalone.cpp @@ -55,7 +55,7 @@ public: } } - bool Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override { + bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) override { if (!codecOpen_) { _dbg_assert_(false); } @@ -70,19 +70,18 @@ public: if (audioType_ == PSP_CODEC_AT3PLUS) { result = atrac3p_decode_frame(at3pCtx_, buffers_, &nb_samples, &got_frame, inbuf, inbytes); } else { - result = atrac3_decode_frame(at3Ctx_, buffers_, &nb_samples, &got_frame, inbuf, inbytes); } if (result < 0) { *outbytes = 0; return false; } - srcPos_ = result; + *inbytesConsumed = result; outSamples_ = nb_samples; if (nb_samples > 0) { *outbytes = nb_samples * 2 * 2; - // Convert frame to outbuf. + // Convert frame to outbuf. TODO: Very SIMDable, though hardly hot. for (int channel = 0; channel < 2; channel++) { int16_t *output = (int16_t *)outbuf; for (int i = 0; i < nb_samples; i++) { @@ -99,9 +98,6 @@ public: int GetOutSamples() const override { return outSamples_; } - int GetSourcePos() const override { - return srcPos_; - } void SetChannels(int channels) override { // Hmm. ignore for now. diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index c1e23612ab..cd5d1b9b1e 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -1077,7 +1077,8 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) { m_audioContext->SetChannels(1); } - if (!m_audioContext->Decode(audioFrame, frameSize, buffer, &outbytes)) { + int inbytesConsumed = 0; + if (!m_audioContext->Decode(audioFrame, frameSize, &inbytesConsumed, buffer, &outbytes)) { ERROR_LOG(ME, "Audio (%s) decode failed during video playback", GetCodecName(m_audioType)); } diff --git a/Core/HW/SimpleAudioDec.cpp b/Core/HW/SimpleAudioDec.cpp index 83b79ec975..c1e57ffdaa 100644 --- a/Core/HW/SimpleAudioDec.cpp +++ b/Core/HW/SimpleAudioDec.cpp @@ -65,10 +65,10 @@ public: } ~MiniMp3Audio() {} - bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override { + bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) override { mp3dec_frame_info_t info{}; int samplesWritten = mp3dec_decode_frame(&mp3_, inbuf, inbytes, (mp3d_sample_t *)outbuf, &info); - srcPos_ = info.frame_bytes; + *inbytesConsumed = info.frame_bytes; *outbytes = samplesWritten * sizeof(mp3d_sample_t) * info.channels; outSamples_ = samplesWritten * info.channels; return true; @@ -78,9 +78,6 @@ public: int GetOutSamples() const override { return outSamples_; } - int GetSourcePos() const override { - return srcPos_; - } void SetChannels(int channels) override { // Hmm. ignore for now. @@ -101,7 +98,7 @@ public: SimpleAudio(PSPAudioType audioType, int sampleRateHz = 44100, int channels = 2); ~SimpleAudio(); - bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) override; + bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) override; bool IsOK() const override { #ifdef USE_FFMPEG return codec_ != 0; @@ -111,10 +108,7 @@ public: } int GetOutSamples() const override { - return outSamples; - } - int GetSourcePos() const override { - return srcPos; + return outSamples_; } void SetChannels(int channels) override; @@ -128,18 +122,17 @@ private: PSPAudioType audioType; int sample_rate_; int channels_; - int outSamples; // output samples per frame - int srcPos; // bytes consumed in source during the last decoding + int outSamples_ = 0; // output samples per frame - AVFrame *frame_; + AVFrame *frame_ = nullptr; #if HAVE_LIBAVCODEC_CONST_AVCODEC // USE_FFMPEG is implied const #endif - AVCodec *codec_; - AVCodecContext *codecCtx_; - SwrContext *swrCtx_; + AVCodec *codec_ = nullptr; + AVCodecContext *codecCtx_ = nullptr; + SwrContext *swrCtx_ = nullptr; - bool codecOpen_; + bool codecOpen_ = false; }; AudioDecoder *CreateAudioDecoder(PSPAudioType audioType, int sampleRateHz, int channels, size_t blockAlign, const uint8_t *extraData, size_t extraDataSize) { @@ -176,10 +169,7 @@ static int GetAudioCodecID(int audioType) { } SimpleAudio::SimpleAudio(PSPAudioType audioType, int sampleRateHz, int channels) - : audioType(audioType), sample_rate_(sampleRateHz), channels_(channels), - outSamples(0), srcPos(0), - frame_(0), codec_(0), codecCtx_(0), swrCtx_(0), - codecOpen_(false) { + : audioType(audioType), sample_rate_(sampleRateHz), channels_(channels) { #ifdef USE_FFMPEG #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 18, 100) @@ -274,7 +264,7 @@ SimpleAudio::~SimpleAudio() { } // Decodes a single input frame. -bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int *outbytes) { +bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) { #ifdef USE_FFMPEG if (!codecOpen_) { OpenCodec(inbytes); @@ -289,7 +279,7 @@ bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int av_frame_unref(frame_); *outbytes = 0; - srcPos = 0; + *inbytesConsumed = 0; #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101) if (inbytes != 0) { int err = avcodec_send_packet(codecCtx_, &packet); @@ -321,7 +311,7 @@ bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int } // get bytes consumed in source - srcPos = len; + *inbytesConsumed = len; if (got_frame) { // Initializing the sample rate convert. We will use it to convert float output into int. @@ -358,10 +348,10 @@ bool SimpleAudio::Decode(const uint8_t *inbuf, int inbytes, uint8_t *outbuf, int return false; } // output samples per frame, we should *2 since we have two channels - outSamples = swrRet * 2; + outSamples_ = swrRet * 2; // each sample occupies 2 bytes - *outbytes = outSamples * 2; + *outbytes = outSamples_ * 2; // Save outbuf into pcm audio, you can uncomment this line to save and check the decoded audio into pcm file. // SaveAudio("dump.pcm", outbuf, *outbytes); @@ -446,7 +436,8 @@ u32 AuCtx::AuDecode(u32 pcmAddr) { if (!sourcebuff.empty()) { // FFmpeg doesn't seem to search for a sync for us, so let's do that. int nextSync = (int)FindNextMp3Sync(); - decoder->Decode(&sourcebuff[nextSync], (int)sourcebuff.size() - nextSync, outbuf, &outpcmbufsize); + int inbytesConsumed = 0; + decoder->Decode(&sourcebuff[nextSync], (int)sourcebuff.size() - nextSync, &inbytesConsumed, outbuf, &outpcmbufsize); if (outpcmbufsize == 0) { // Nothing was output, hopefully we're at the end of the stream. @@ -456,7 +447,7 @@ u32 AuCtx::AuDecode(u32 pcmAddr) { // Update our total decoded samples, but don't count stereo. SumDecodedSamples += decoder->GetOutSamples() / 2; // get consumed source length - int srcPos = decoder->GetSourcePos() + nextSync; + int srcPos = inbytesConsumed + nextSync; // remove the consumed source if (srcPos > 0) sourcebuff.erase(sourcebuff.begin(), sourcebuff.begin() + srcPos); diff --git a/Core/HW/SimpleAudioDec.h b/Core/HW/SimpleAudioDec.h index b227b3889a..d000850133 100644 --- a/Core/HW/SimpleAudioDec.h +++ b/Core/HW/SimpleAudioDec.h @@ -39,12 +39,12 @@ public: virtual PSPAudioType GetAudioType() const = 0; - virtual bool Decode(const uint8_t* inbuf, int inbytes, uint8_t *outbuf, int *outbytes) = 0; + // inbytesConsumed can include skipping metadata. + virtual bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, uint8_t *outbuf, int *outbytes) = 0; virtual bool IsOK() const = 0; // These two are only ever called after Decode, so can initialize on first. virtual int GetOutSamples() const = 0; - virtual int GetSourcePos() const = 0; virtual void SetChannels(int channels) = 0; diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index fc528274fa..0231c77edc 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -218,7 +218,8 @@ public: while (bgQueue.size() < (size_t)(len * 2)) { int outBytes = 0; - decoder_->Decode(wave_.raw_data + raw_offset_, wave_.raw_bytes_per_frame, (uint8_t *)buffer_, &outBytes); + int inbytesConsumed = 0; + decoder_->Decode(wave_.raw_data + raw_offset_, wave_.raw_bytes_per_frame, &inbytesConsumed, (uint8_t *)buffer_, &outBytes); if (!outBytes) return false; diff --git a/ext/at3_standalone/compat.h b/ext/at3_standalone/compat.h index 7e236bb9cb..4eac214f2e 100644 --- a/ext/at3_standalone/compat.h +++ b/ext/at3_standalone/compat.h @@ -2,7 +2,7 @@ #include -// Compat hacks +// Compat hacks to make an FFMPEG-like environment, so we can keep the core code mostly unchanged. #if defined(__GNUC__) #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v