summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/audio/hwopus.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/audio/hwopus.cpp')
-rw-r--r--src/core/hle/service/audio/hwopus.cpp46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 763e619a4..a850cadc8 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -46,10 +46,13 @@ public:
private:
void DecodeInterleaved(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Audio, "called");
+
u32 consumed = 0;
u32 sample_count = 0;
std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples)) {
+ LOG_ERROR(Audio, "Failed to decode opus data");
IPC::ResponseBuilder rb{ctx, 2};
// TODO(ogniK): Use correct error code
rb.Push(ResultCode(-1));
@@ -63,12 +66,15 @@ private:
}
void DecodeInterleavedWithPerformance(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Audio, "called");
+
u32 consumed = 0;
u32 sample_count = 0;
u64 performance = 0;
std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16));
if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples,
performance)) {
+ LOG_ERROR(Audio, "Failed to decode opus data");
IPC::ResponseBuilder rb{ctx, 2};
// TODO(ogniK): Use correct error code
rb.Push(ResultCode(-1));
@@ -88,24 +94,39 @@ private:
std::optional<std::reference_wrapper<u64>> performance_time = std::nullopt) {
const auto start_time = std::chrono::high_resolution_clock::now();
std::size_t raw_output_sz = output.size() * sizeof(opus_int16);
- if (sizeof(OpusHeader) > input.size())
+ if (sizeof(OpusHeader) > input.size()) {
+ LOG_ERROR(Audio, "Input is smaller than the header size, header_sz={}, input_sz={}",
+ sizeof(OpusHeader), input.size());
return false;
+ }
OpusHeader hdr{};
std::memcpy(&hdr, input.data(), sizeof(OpusHeader));
if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) {
+ LOG_ERROR(Audio, "Input does not fit in the opus header size. data_sz={}, input_sz={}",
+ sizeof(OpusHeader) + static_cast<u32>(hdr.sz), input.size());
return false;
}
auto frame = input.data() + sizeof(OpusHeader);
auto decoded_sample_count = opus_packet_get_nb_samples(
frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)),
static_cast<opus_int32>(sample_rate));
- if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz)
+ if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) {
+ LOG_ERROR(
+ Audio,
+ "Decoded data does not fit into the output data, decoded_sz={}, raw_output_sz={}",
+ decoded_sample_count * channel_count * sizeof(u16), raw_output_sz);
return false;
+ }
+ const int frame_size = (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count));
auto out_sample_count =
- opus_decode(decoder.get(), frame, hdr.sz, output.data(),
- (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count)), 0);
- if (out_sample_count < 0)
+ opus_decode(decoder.get(), frame, hdr.sz, output.data(), frame_size, 0);
+ if (out_sample_count < 0) {
+ LOG_ERROR(Audio,
+ "Incorrect sample count received from opus_decode, "
+ "output_sample_count={}, frame_size={}, data_sz_from_hdr={}",
+ out_sample_count, frame_size, static_cast<u32>(hdr.sz));
return false;
+ }
const auto end_time = std::chrono::high_resolution_clock::now() - start_time;
sample_count = out_sample_count;
consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz);
@@ -134,14 +155,17 @@ static std::size_t WorkerBufferSize(u32 channel_count) {
void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- auto sample_rate = rp.Pop<u32>();
- auto channel_count = rp.Pop<u32>();
+ const auto sample_rate = rp.Pop<u32>();
+ const auto channel_count = rp.Pop<u32>();
+ LOG_DEBUG(Audio, "called with sample_rate={}, channel_count={}", sample_rate, channel_count);
+
ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
sample_rate == 12000 || sample_rate == 8000,
"Invalid sample rate");
ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
- u32 worker_buffer_sz = static_cast<u32>(WorkerBufferSize(channel_count));
- LOG_DEBUG(Audio, "called worker_buffer_sz={}", worker_buffer_sz);
+
+ const u32 worker_buffer_sz = static_cast<u32>(WorkerBufferSize(channel_count));
+ LOG_DEBUG(Audio, "worker_buffer_sz={}", worker_buffer_sz);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
@@ -155,6 +179,7 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
auto buffer_sz = rp.Pop<u32>();
LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate,
channel_count, buffer_sz);
+
ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 ||
sample_rate == 12000 || sample_rate == 8000,
"Invalid sample rate");
@@ -164,7 +189,8 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
ASSERT_MSG(buffer_sz >= worker_sz, "Worker buffer too large");
std::unique_ptr<OpusDecoder, OpusDeleter> decoder{
static_cast<OpusDecoder*>(operator new(worker_sz))};
- if (opus_decoder_init(decoder.get(), sample_rate, channel_count)) {
+ if (const int err = opus_decoder_init(decoder.get(), sample_rate, channel_count)) {
+ LOG_ERROR(Audio, "Failed to init opus decoder with error={}", err);
IPC::ResponseBuilder rb{ctx, 2};
// TODO(ogniK): Use correct error code
rb.Push(ResultCode(-1));