mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
Refactor: Change *outBytes to *outSamples in AudioDecoder::Decode.
This commit is contained in:
parent
fa8d8d1121
commit
1b366afa35
@ -949,16 +949,17 @@ u32 Atrac::DecodeData(u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u32 *finish, i
|
||||
if (off < first_.size) {
|
||||
uint8_t *indata = BufferStart() + off;
|
||||
int bytesConsumed = 0;
|
||||
int outBytes = 0;
|
||||
if (!decoder_->Decode(indata, track_.bytesPerFrame, &bytesConsumed, outputChannels_, outbuf, &outBytes)) {
|
||||
int outSamples = 0;
|
||||
if (!decoder_->Decode(indata, track_.bytesPerFrame, &bytesConsumed, outputChannels_, (int16_t *)outbuf, &outSamples)) {
|
||||
// Decode failed.
|
||||
*SamplesNum = 0;
|
||||
*finish = 1;
|
||||
return ATRAC_ERROR_ALL_DATA_DECODED;
|
||||
}
|
||||
int outBytes = outSamples * outputChannels_ * sizeof(int16_t);
|
||||
gotFrame = true;
|
||||
|
||||
numSamples = outBytes / 4;
|
||||
numSamples = outSamples;
|
||||
uint32_t packetAddr = CurBufferAddress(-skipSamples);
|
||||
// got a frame
|
||||
int skipped = std::min((u32)skipSamples, numSamples);
|
||||
|
@ -944,7 +944,7 @@ static int sceAtracLowLevelInitDecoder(int atracID, u32 paramsAddr) {
|
||||
static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesConsumedAddr, u32 samplesAddr, u32 sampleBytesAddr) {
|
||||
auto srcp = PSPPointer<u8>::Create(sourceAddr);
|
||||
auto srcConsumed = PSPPointer<u32_le>::Create(sourceBytesConsumedAddr);
|
||||
auto outp = PSPPointer<u8>::Create(samplesAddr);
|
||||
auto outp = PSPPointer<s16>::Create(samplesAddr);
|
||||
auto outWritten = PSPPointer<u32_le>::Create(sampleBytesAddr);
|
||||
|
||||
AtracBase *atrac = getAtrac(atracID);
|
||||
@ -958,8 +958,9 @@ static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesCo
|
||||
}
|
||||
|
||||
int bytesConsumed = 0;
|
||||
int bytesWritten = 0;
|
||||
atrac->Decoder()->Decode(srcp, atrac->GetTrack().BytesPerFrame(), &bytesConsumed, 2, outp, &bytesWritten);
|
||||
int outSamples = 0;
|
||||
atrac->Decoder()->Decode(srcp, atrac->GetTrack().BytesPerFrame(), &bytesConsumed, 2, outp, &outSamples);
|
||||
int bytesWritten = outSamples * 2 * sizeof(int16_t);
|
||||
*srcConsumed = bytesConsumed;
|
||||
*outWritten = bytesWritten;
|
||||
|
||||
|
@ -102,7 +102,6 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) {
|
||||
}
|
||||
|
||||
if (IsValidCodec(audioType)){
|
||||
int outbytes = 0;
|
||||
// find a decoder in audioList
|
||||
auto decoder = findDecoder(ctxPtr);
|
||||
|
||||
@ -119,7 +118,8 @@ static int sceAudiocodecDecode(u32 ctxPtr, int codec) {
|
||||
auto ctx = PSPPointer<AudioCodecContext>::Create(ctxPtr); // On stack, no need to allocate.
|
||||
// Decode audio
|
||||
int inDataConsumed = 0;
|
||||
decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, &inDataConsumed, 2, Memory::GetPointerWrite(ctx->outDataPtr), &outbytes);
|
||||
int outSamples = 0;
|
||||
decoder->Decode(Memory::GetPointer(ctx->inDataPtr), ctx->inDataSize, &inDataConsumed, 2, (int16_t *)Memory::GetPointerWrite(ctx->outDataPtr), &outSamples);
|
||||
}
|
||||
DEBUG_LOG(ME, "sceAudiocodecDec(%08x, %i (%s))", ctxPtr, codec, GetCodecName(codec));
|
||||
return 0;
|
||||
|
@ -739,16 +739,17 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto inbuff = Memory::GetPointerWriteUnchecked(sourceAddr);
|
||||
auto outbuff = Memory::GetPointerWriteUnchecked(samplesAddr);
|
||||
const u8 *inbuff = Memory::GetPointerWriteUnchecked(sourceAddr);
|
||||
int16_t *outbuf = (int16_t *)Memory::GetPointerWriteUnchecked(samplesAddr);
|
||||
|
||||
int outpcmbytes = 0;
|
||||
int outSamples = 0;
|
||||
int inbytesConsumed = 0;
|
||||
ctx->decoder->Decode(inbuff, 4096, &inbytesConsumed, 2, outbuff, &outpcmbytes);
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outpcmbytes, "Mp3LowLevelDecode");
|
||||
ctx->decoder->Decode(inbuff, 4096, &inbytesConsumed, 2, outbuf, &outSamples);
|
||||
int outBytes = outSamples * sizeof(int16_t) * 2;
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outBytes, "Mp3LowLevelDecode");
|
||||
|
||||
Memory::Write_U32(inbytesConsumed, sourceBytesConsumedAddr);
|
||||
Memory::Write_U32(outpcmbytes, sampleBytesAddr);
|
||||
Memory::Write_U32(outBytes, sampleBytesAddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) override {
|
||||
bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) override {
|
||||
if (!codecOpen_) {
|
||||
_dbg_assert_(false);
|
||||
}
|
||||
@ -73,45 +73,42 @@ public:
|
||||
result = atrac3_decode_frame(at3Ctx_, buffers_, &nb_samples, inbuf, inbytes);
|
||||
}
|
||||
if (result < 0) {
|
||||
*outbytes = 0;
|
||||
if (outSamples) {
|
||||
*outSamples = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (inbytesConsumed) {
|
||||
*inbytesConsumed = result;
|
||||
}
|
||||
outSamples_ = nb_samples;
|
||||
if (outSamples) {
|
||||
*outSamples = nb_samples;
|
||||
}
|
||||
if (nb_samples > 0) {
|
||||
if (outbytes) {
|
||||
*outbytes = nb_samples * 2 * 2;
|
||||
if (outSamples) {
|
||||
*outSamples = nb_samples;
|
||||
}
|
||||
if (outbuf) {
|
||||
_dbg_assert_(outputChannels == 1 || outputChannels == 2);
|
||||
int16_t *output = (int16_t *)outbuf;
|
||||
const float *left = buffers_[0];
|
||||
if (outputChannels == 2) {
|
||||
// Stereo output, standard.
|
||||
const float *right = channels_ == 2 ? buffers_[1] : buffers_[0];
|
||||
for (int i = 0; i < nb_samples; i++) {
|
||||
output[i * 2] = clamp16(left[i]);
|
||||
output[i * 2 + 1] = clamp16(right[i]);
|
||||
outbuf[i * 2] = clamp16(left[i]);
|
||||
outbuf[i * 2 + 1] = clamp16(right[i]);
|
||||
}
|
||||
} else {
|
||||
// Mono output, just take the left channel.
|
||||
for (int i = 0; i < nb_samples; i++) {
|
||||
output[i] = clamp16(left[i]);
|
||||
outbuf[i] = clamp16(left[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (outbytes) {
|
||||
*outbytes = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int GetOutSamples() const override {
|
||||
return outSamples_;
|
||||
}
|
||||
|
||||
void SetChannels(int channels) override {
|
||||
// Hmm. ignore for now.
|
||||
}
|
||||
@ -125,7 +122,6 @@ private:
|
||||
int channels_ = 0;
|
||||
int blockAlign_ = 0;
|
||||
|
||||
int outSamples_ = 0;
|
||||
int srcPos_ = 0;
|
||||
float *buffers_[2]{};
|
||||
|
||||
|
@ -1054,7 +1054,7 @@ int MediaEngine::getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2)
|
||||
}
|
||||
|
||||
int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
||||
u8 *buffer = Memory::GetPointerWriteRange(bufferPtr, 8192);
|
||||
int16_t *buffer = (int16_t *)Memory::GetPointerWriteRange(bufferPtr, 8192);
|
||||
if (buffer == nullptr) {
|
||||
ERROR_LOG_REPORT(ME, "Ignoring bad audio decode address %08x during video playback", bufferPtr);
|
||||
}
|
||||
@ -1068,7 +1068,7 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
||||
if (frameSize == 0) {
|
||||
return 0;
|
||||
}
|
||||
int outbytes = 0;
|
||||
int outSamples = 0;
|
||||
|
||||
if (m_audioContext != nullptr) {
|
||||
if (headerCode1 == 0x24) {
|
||||
@ -1078,11 +1078,12 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) {
|
||||
}
|
||||
|
||||
int inbytesConsumed = 0;
|
||||
if (!m_audioContext->Decode(audioFrame, frameSize, &inbytesConsumed, 2, buffer, &outbytes)) {
|
||||
if (!m_audioContext->Decode(audioFrame, frameSize, &inbytesConsumed, 2, buffer, &outSamples)) {
|
||||
ERROR_LOG(ME, "Audio (%s) decode failed during video playback", GetCodecName(m_audioType));
|
||||
}
|
||||
int outBytes = outSamples * sizeof(int16_t) * 2;
|
||||
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, bufferPtr, outbytes, "VideoDecodeAudio");
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, bufferPtr, outBytes, "VideoDecodeAudio");
|
||||
}
|
||||
|
||||
return 0x2000;
|
||||
|
@ -67,22 +67,17 @@ public:
|
||||
}
|
||||
~MiniMp3Audio() {}
|
||||
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) override {
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) override {
|
||||
_dbg_assert_(outputChannels == 2);
|
||||
|
||||
mp3dec_frame_info_t info{};
|
||||
int samplesWritten = mp3dec_decode_frame(&mp3_, inbuf, inbytes, (mp3d_sample_t *)outbuf, &info);
|
||||
*inbytesConsumed = info.frame_bytes;
|
||||
*outbytes = samplesWritten * sizeof(mp3d_sample_t) * info.channels;
|
||||
outSamples_ = samplesWritten * info.channels;
|
||||
*outSamples = samplesWritten;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsOK() const override { return true; }
|
||||
int GetOutSamples() const override {
|
||||
return outSamples_;
|
||||
}
|
||||
|
||||
void SetChannels(int channels) override {
|
||||
// Hmm. ignore for now.
|
||||
}
|
||||
@ -92,8 +87,6 @@ public:
|
||||
private:
|
||||
// We use the lowest-level API.
|
||||
mp3dec_t mp3_{};
|
||||
int outSamples_ = 0;
|
||||
int srcPos_ = 0;
|
||||
};
|
||||
|
||||
// FFMPEG-based decoder. TODO: Replace with individual codecs.
|
||||
@ -103,7 +96,7 @@ public:
|
||||
FFmpegAudioDecoder(PSPAudioType audioType, int sampleRateHz = 44100, int channels = 2);
|
||||
~FFmpegAudioDecoder();
|
||||
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) override;
|
||||
bool Decode(const uint8_t* inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) override;
|
||||
bool IsOK() const override {
|
||||
#ifdef USE_FFMPEG
|
||||
return codec_ != 0;
|
||||
@ -112,10 +105,6 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
int GetOutSamples() const override {
|
||||
return outSamples_;
|
||||
}
|
||||
|
||||
void SetChannels(int channels) override;
|
||||
|
||||
// These two are only here because of save states.
|
||||
@ -127,7 +116,6 @@ private:
|
||||
PSPAudioType audioType;
|
||||
int sample_rate_;
|
||||
int channels_;
|
||||
int outSamples_ = 0; // output samples per frame
|
||||
|
||||
AVFrame *frame_ = nullptr;
|
||||
AVCodec *codec_ = nullptr;
|
||||
@ -266,7 +254,7 @@ FFmpegAudioDecoder::~FFmpegAudioDecoder() {
|
||||
}
|
||||
|
||||
// Decodes a single input frame.
|
||||
bool FFmpegAudioDecoder::Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) {
|
||||
bool FFmpegAudioDecoder::Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) {
|
||||
#ifdef USE_FFMPEG
|
||||
if (!codecOpen_) {
|
||||
OpenCodec(inbytes);
|
||||
@ -280,8 +268,12 @@ bool FFmpegAudioDecoder::Decode(const uint8_t *inbuf, int inbytes, int *inbytesC
|
||||
int got_frame = 0;
|
||||
av_frame_unref(frame_);
|
||||
|
||||
*outbytes = 0;
|
||||
*inbytesConsumed = 0;
|
||||
if (outSamples) {
|
||||
*outSamples = 0;
|
||||
}
|
||||
if (inbytesConsumed) {
|
||||
*inbytesConsumed = 0;
|
||||
}
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
|
||||
if (inbytes != 0) {
|
||||
int err = avcodec_send_packet(codecCtx_, &packet);
|
||||
@ -344,17 +336,14 @@ bool FFmpegAudioDecoder::Decode(const uint8_t *inbuf, int inbytes, int *inbytesC
|
||||
// convert audio to AV_SAMPLE_FMT_S16
|
||||
int swrRet = 0;
|
||||
if (outbuf != nullptr) {
|
||||
swrRet = swr_convert(swrCtx_, &outbuf, frame_->nb_samples, (const u8 **)frame_->extended_data, frame_->nb_samples);
|
||||
swrRet = swr_convert(swrCtx_, (uint8_t **)&outbuf, frame_->nb_samples, (const u8 **)frame_->extended_data, frame_->nb_samples);
|
||||
}
|
||||
if (swrRet < 0) {
|
||||
ERROR_LOG(ME, "swr_convert: Error while converting: %d", swrRet);
|
||||
return false;
|
||||
}
|
||||
// output samples per frame, we should *2 since we have two channels
|
||||
outSamples_ = swrRet * 2;
|
||||
|
||||
// each sample occupies 2 bytes
|
||||
*outbytes = outSamples_ * 2;
|
||||
// output stereo samples per frame
|
||||
*outSamples = swrRet;
|
||||
|
||||
// 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);
|
||||
@ -439,7 +428,9 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
|
||||
nextSync = (int)FindNextMp3Sync();
|
||||
}
|
||||
int inbytesConsumed = 0;
|
||||
decoder->Decode(&sourcebuff[nextSync], (int)sourcebuff.size() - nextSync, &inbytesConsumed, 2, outbuf, &outpcmbufsize);
|
||||
int outSamples = 0;
|
||||
decoder->Decode(&sourcebuff[nextSync], (int)sourcebuff.size() - nextSync, &inbytesConsumed, 2, (int16_t *)outbuf, &outSamples);
|
||||
outpcmbufsize = outSamples * 2 * sizeof(int16_t);
|
||||
|
||||
if (outpcmbufsize == 0) {
|
||||
// Nothing was output, hopefully we're at the end of the stream.
|
||||
@ -447,7 +438,7 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
|
||||
sourcebuff.clear();
|
||||
} else {
|
||||
// Update our total decoded samples, but don't count stereo.
|
||||
SumDecodedSamples += decoder->GetOutSamples() / 2;
|
||||
SumDecodedSamples += outSamples;
|
||||
// get consumed source length
|
||||
int srcPos = inbytesConsumed + nextSync;
|
||||
// remove the consumed source
|
||||
|
@ -37,14 +37,11 @@ public:
|
||||
virtual PSPAudioType GetAudioType() const = 0;
|
||||
|
||||
// inbytesConsumed can include skipping metadata.
|
||||
virtual bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, uint8_t *outbuf, int *outbytes) = 0;
|
||||
// outSamples is in stereo samples. So you have to multiply by 4 for 16-bit stereo audio to get bytes.
|
||||
virtual bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) = 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 void SetChannels(int channels) = 0;
|
||||
|
||||
virtual void FlushBuffers() {}
|
||||
|
||||
// Just metadata.
|
||||
|
@ -217,11 +217,12 @@ public:
|
||||
return false;
|
||||
|
||||
while (bgQueue.size() < (size_t)(len * 2)) {
|
||||
int outBytes = 0;
|
||||
int outSamples = 0;
|
||||
int inbytesConsumed = 0;
|
||||
decoder_->Decode(wave_.raw_data + raw_offset_, wave_.raw_bytes_per_frame, &inbytesConsumed, 2, (uint8_t *)buffer_, &outBytes);
|
||||
if (!outBytes)
|
||||
bool result = decoder_->Decode(wave_.raw_data + raw_offset_, wave_.raw_bytes_per_frame, &inbytesConsumed, 2, (int16_t *)buffer_, &outSamples);
|
||||
if (!result || !outSamples)
|
||||
return false;
|
||||
int outBytes = outSamples * 2 * sizeof(int16_t);
|
||||
|
||||
if (wave_.raw_offset_loop_end != 0 && raw_offset_ == wave_.raw_offset_loop_end) {
|
||||
// Only take the remaining bytes, but convert to stereo s16.
|
||||
|
Loading…
Reference in New Issue
Block a user