mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
disable breaking the loop in multi-frame if storage is insufficient
This commit is contained in:
parent
5f63f46204
commit
4d4d9d5e2c
@ -123,14 +123,16 @@ AjmSidebandFormat AjmAt9Decoder::GetFormat() const {
|
||||
.channel_mask = GetChannelMask(u32(m_codec_info.channels)),
|
||||
.sampl_freq = u32(m_codec_info.samplingRate),
|
||||
.sample_encoding = m_format,
|
||||
.bitrate = u32(m_codec_info.samplingRate * GetPCMSize(m_format) * 8),
|
||||
.bitrate = u32((m_codec_info.samplingRate * m_codec_info.superframeSize * 8) /
|
||||
(m_codec_info.framesInSuperframe * m_codec_info.frameSamples)),
|
||||
.reserved = 0,
|
||||
};
|
||||
}
|
||||
|
||||
u32 AjmAt9Decoder::GetNextFrameSize(u32 max_samples) const {
|
||||
return std::min(u32(m_codec_info.frameSamples), max_samples) * m_codec_info.channels *
|
||||
GetPCMSize(m_format);
|
||||
u32 AjmAt9Decoder::GetNextFrameSize(u32 skip_samples, u32 max_samples) const {
|
||||
skip_samples = std::min({skip_samples, u32(m_codec_info.frameSamples), max_samples});
|
||||
return (std::min(u32(m_codec_info.frameSamples), max_samples) - skip_samples) *
|
||||
m_codec_info.channels * GetPCMSize(m_format);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Ajm
|
||||
|
@ -35,7 +35,7 @@ struct AjmAt9Decoder final : AjmCodec {
|
||||
void Initialize(const void* buffer, u32 buffer_size) override;
|
||||
void GetInfo(void* out_info) const override;
|
||||
AjmSidebandFormat GetFormat() const override;
|
||||
u32 GetNextFrameSize(u32 max_samples) const override;
|
||||
u32 GetNextFrameSize(u32 skip_samples, u32 max_samples) const override;
|
||||
std::tuple<u32, u32> ProcessData(std::span<u8>& input, SparseOutputBuffer& output,
|
||||
AjmSidebandGaplessDecode& gapless,
|
||||
std::optional<u32> max_samples) override;
|
||||
|
@ -135,7 +135,10 @@ AjmJob AjmJobFromBatchBuffer(u32 instance_id, AjmBatchBuffer batch_buffer) {
|
||||
case Identifier::AjmIdentInputControlBuf: {
|
||||
ASSERT_MSG(!input_control_buffer.has_value(),
|
||||
"Only one instance of input control buffer is allowed per job");
|
||||
input_control_buffer = batch_buffer.Consume<AjmChunkBuffer>();
|
||||
const auto& buffer = batch_buffer.Consume<AjmChunkBuffer>();
|
||||
if (buffer.p_address != nullptr && buffer.size != 0) {
|
||||
input_control_buffer = buffer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Identifier::AjmIdentControlFlags:
|
||||
@ -155,19 +158,27 @@ AjmJob AjmJobFromBatchBuffer(u32 instance_id, AjmBatchBuffer batch_buffer) {
|
||||
case Identifier::AjmIdentInlineBuf: {
|
||||
ASSERT_MSG(!output_control_buffer.has_value(),
|
||||
"Only one instance of inline buffer is allowed per job");
|
||||
inline_buffer = batch_buffer.Consume<AjmChunkBuffer>();
|
||||
const auto& buffer = batch_buffer.Consume<AjmChunkBuffer>();
|
||||
if (buffer.p_address != nullptr && buffer.size != 0) {
|
||||
inline_buffer = buffer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Identifier::AjmIdentOutputRunBuf: {
|
||||
auto& buffer = batch_buffer.Consume<AjmChunkBuffer>();
|
||||
u8* p_begin = reinterpret_cast<u8*>(buffer.p_address);
|
||||
job.output.buffers.emplace_back(std::span<u8>(p_begin, p_begin + buffer.size));
|
||||
if (p_begin != nullptr && buffer.size != 0) {
|
||||
job.output.buffers.emplace_back(std::span<u8>(p_begin, p_begin + buffer.size));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Identifier::AjmIdentOutputControlBuf: {
|
||||
ASSERT_MSG(!output_control_buffer.has_value(),
|
||||
"Only one instance of output control buffer is allowed per job");
|
||||
output_control_buffer = batch_buffer.Consume<AjmChunkBuffer>();
|
||||
const auto& buffer = batch_buffer.Consume<AjmChunkBuffer>();
|
||||
if (buffer.p_address != nullptr && buffer.size != 0) {
|
||||
output_control_buffer = buffer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -78,8 +78,12 @@ void AjmInstance::ExecuteJob(AjmJob& job) {
|
||||
}
|
||||
if (job.input.gapless_decode.has_value()) {
|
||||
auto& params = job.input.gapless_decode.value();
|
||||
m_gapless.total_samples = params.total_samples;
|
||||
m_gapless.skip_samples = params.skip_samples;
|
||||
if (params.total_samples != 0) {
|
||||
m_gapless.total_samples = std::max(params.total_samples, m_gapless.total_samples);
|
||||
}
|
||||
if (params.skip_samples != 0) {
|
||||
m_gapless.skip_samples = std::max(params.skip_samples, m_gapless.skip_samples);
|
||||
}
|
||||
}
|
||||
|
||||
if (!job.input.buffer.empty() && !job.output.buffers.empty()) {
|
||||
@ -90,16 +94,14 @@ void AjmInstance::ExecuteJob(AjmJob& job) {
|
||||
auto in_size = in_buf.size();
|
||||
auto out_size = out_buf.Size();
|
||||
while (!in_buf.empty() && !out_buf.IsEmpty() && !IsGaplessEnd()) {
|
||||
const auto samples_remain = GetNumRemainingSamples();
|
||||
if (!HasEnoughSpace(out_buf, samples_remain)) {
|
||||
if (job.output.p_mframe == nullptr) {
|
||||
LOG_ERROR(Lib_Ajm, "Single-frame job buffer too small.");
|
||||
if (!HasEnoughSpace(out_buf)) {
|
||||
if (job.output.p_mframe == nullptr || frames_decoded == 0) {
|
||||
job.output.p_result->result = ORBIS_AJM_RESULT_NOT_ENOUGH_ROOM;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
const auto [nframes, nsamples] =
|
||||
m_codec->ProcessData(in_buf, out_buf, m_gapless, samples_remain);
|
||||
m_codec->ProcessData(in_buf, out_buf, m_gapless, GetNumRemainingSamples());
|
||||
frames_decoded += nframes;
|
||||
m_total_samples += nsamples;
|
||||
m_gapless_samples += nsamples;
|
||||
@ -138,10 +140,11 @@ bool AjmInstance::IsGaplessEnd() const {
|
||||
return m_gapless.total_samples != 0 && m_gapless_samples >= m_gapless.total_samples;
|
||||
}
|
||||
|
||||
bool AjmInstance::HasEnoughSpace(const SparseOutputBuffer& output,
|
||||
std::optional<u32> opt_samples_remain) const {
|
||||
const auto remain = opt_samples_remain.value_or(std::numeric_limits<u32>::max());
|
||||
return output.Size() >= m_codec->GetNextFrameSize(remain);
|
||||
bool AjmInstance::HasEnoughSpace(const SparseOutputBuffer& output) const {
|
||||
const auto skip =
|
||||
m_gapless.skip_samples - std::min(m_gapless.skip_samples, m_gapless.skipped_samples);
|
||||
const auto remain = GetNumRemainingSamples().value_or(std::numeric_limits<u32>::max());
|
||||
return output.Size() >= m_codec->GetNextFrameSize(skip, remain);
|
||||
}
|
||||
|
||||
std::optional<u32> AjmInstance::GetNumRemainingSamples() const {
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
virtual void Reset() = 0;
|
||||
virtual void GetInfo(void* out_info) const = 0;
|
||||
virtual AjmSidebandFormat GetFormat() const = 0;
|
||||
virtual u32 GetNextFrameSize(u32 max_samples) const = 0;
|
||||
virtual u32 GetNextFrameSize(u32 skip_samples, u32 max_samples) const = 0;
|
||||
virtual std::tuple<u32, u32> ProcessData(std::span<u8>& input, SparseOutputBuffer& output,
|
||||
AjmSidebandGaplessDecode& gapless,
|
||||
std::optional<u32> max_samples_per_channel) = 0;
|
||||
@ -80,7 +80,7 @@ public:
|
||||
|
||||
private:
|
||||
bool IsGaplessEnd() const;
|
||||
bool HasEnoughSpace(const SparseOutputBuffer& output, std::optional<u32> samples_remain) const;
|
||||
bool HasEnoughSpace(const SparseOutputBuffer& output) const;
|
||||
std::optional<u32> GetNumRemainingSamples() const;
|
||||
|
||||
AjmInstanceFlags m_flags{};
|
||||
|
@ -219,9 +219,10 @@ std::tuple<u32, u32> AjmMp3Decoder::ProcessData(std::span<u8>& in_buf, SparseOut
|
||||
return {frames_decoded, samples_decoded / m_codec_context->ch_layout.nb_channels};
|
||||
}
|
||||
|
||||
u32 AjmMp3Decoder::GetNextFrameSize(u32 max_samples) const {
|
||||
return std::min(m_frame_samples, max_samples) * m_codec_context->ch_layout.nb_channels *
|
||||
GetPCMSize(m_format);
|
||||
u32 AjmMp3Decoder::GetNextFrameSize(u32 skip_samples, u32 max_samples) const {
|
||||
skip_samples = std::min({skip_samples, m_frame_samples, max_samples});
|
||||
return (std::min(m_frame_samples, max_samples) - skip_samples) *
|
||||
m_codec_context->ch_layout.nb_channels * GetPCMSize(m_format);
|
||||
}
|
||||
|
||||
class BitReader {
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
void Initialize(const void* buffer, u32 buffer_size) override {}
|
||||
void GetInfo(void* out_info) const override;
|
||||
AjmSidebandFormat GetFormat() const override;
|
||||
u32 GetNextFrameSize(u32 max_samples) const override;
|
||||
u32 GetNextFrameSize(u32 skip_samples, u32 max_samples) const override;
|
||||
std::tuple<u32, u32> ProcessData(std::span<u8>& input, SparseOutputBuffer& output,
|
||||
AjmSidebandGaplessDecode& gapless,
|
||||
std::optional<u32> max_samples_per_channel) override;
|
||||
|
Loading…
Reference in New Issue
Block a user