mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-19 17:29:06 +02:00
Improve the AudioDecoder API to avoid having to call a function to get the bytes consumed
This commit is contained in:
1 parent
45936e8826
commit
5ed77b58ca
8 files changed
+34
-43
No files matched your search
@@ -118,7 +118,8 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) {
|
||||
// Use SimpleAudioDec to decode audio
|
||||
auto ctx = PSPPointer<AudioCodecContext>::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;
|
||||
|
||||
+3
-2
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
+19
-28
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// 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
|
||||
|
||||
Reference in new issue
Block a user