Skip to content

Commit 5a98bae

Browse files
roamicfpiesche
authored andcommitted
ajm mp3: fix resampling (shadps4-emu#1500)
1 parent c07322a commit 5a98bae

File tree

2 files changed

+24
-18
lines changed

2 files changed

+24
-18
lines changed

src/core/libraries/ajm/ajm_mp3.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ static constexpr std::array<std::array<s32, 15>, 2> BitrateTable = {{
2828

2929
static constexpr std::array<s32, 2> UnkTable = {0x48, 0x90};
3030

31-
SwrContext* swr_context{};
32-
3331
static AVSampleFormat AjmToAVSampleFormat(AjmFormatEncoding format) {
3432
switch (format) {
3533
case AjmFormatEncoding::S16:
@@ -49,26 +47,28 @@ AVFrame* AjmMp3Decoder::ConvertAudioFrame(AVFrame* frame) {
4947
return frame;
5048
}
5149

52-
auto pcm16_frame = av_frame_clone(frame);
53-
pcm16_frame->format = format;
50+
AVFrame* new_frame = av_frame_alloc();
51+
new_frame->pts = frame->pts;
52+
new_frame->pkt_dts = frame->pkt_dts < 0 ? 0 : frame->pkt_dts;
53+
new_frame->format = format;
54+
new_frame->ch_layout = frame->ch_layout;
55+
new_frame->sample_rate = frame->sample_rate;
5456

55-
if (swr_context) {
56-
swr_free(&swr_context);
57-
swr_context = nullptr;
58-
}
5957
AVChannelLayout in_ch_layout = frame->ch_layout;
60-
AVChannelLayout out_ch_layout = pcm16_frame->ch_layout;
61-
swr_alloc_set_opts2(&swr_context, &out_ch_layout, AVSampleFormat(pcm16_frame->format),
58+
AVChannelLayout out_ch_layout = new_frame->ch_layout;
59+
swr_alloc_set_opts2(&m_swr_context, &out_ch_layout, AVSampleFormat(new_frame->format),
6260
frame->sample_rate, &in_ch_layout, AVSampleFormat(frame->format),
6361
frame->sample_rate, 0, nullptr);
64-
swr_init(swr_context);
65-
const auto res = swr_convert_frame(swr_context, pcm16_frame, frame);
62+
swr_init(m_swr_context);
63+
const auto res = swr_convert_frame(m_swr_context, new_frame, frame);
6664
if (res < 0) {
6765
LOG_ERROR(Lib_AvPlayer, "Could not convert to S16: {}", av_err2str(res));
66+
av_frame_free(&new_frame);
67+
av_frame_free(&frame);
6868
return nullptr;
6969
}
7070
av_frame_free(&frame);
71-
return pcm16_frame;
71+
return new_frame;
7272
}
7373

7474
AjmMp3Decoder::AjmMp3Decoder(AjmFormatEncoding format)
@@ -78,6 +78,7 @@ AjmMp3Decoder::AjmMp3Decoder(AjmFormatEncoding format)
7878
}
7979

8080
AjmMp3Decoder::~AjmMp3Decoder() {
81+
swr_free(&m_swr_context);
8182
avcodec_free_context(&m_codec_context);
8283
}
8384

@@ -108,6 +109,11 @@ std::tuple<u32, u32> AjmMp3Decoder::ProcessData(std::span<u8>& in_buf, SparseOut
108109
u32 frames_decoded = 0;
109110
u32 samples_decoded = 0;
110111

112+
auto max_samples =
113+
max_samples_per_channel.has_value()
114+
? max_samples_per_channel.value() * m_codec_context->ch_layout.nb_channels
115+
: std::numeric_limits<u32>::max();
116+
111117
if (pkt->size) {
112118
// Send the packet with the compressed data to the decoder
113119
pkt->pts = m_parser->pts;
@@ -121,6 +127,7 @@ std::tuple<u32, u32> AjmMp3Decoder::ProcessData(std::span<u8>& in_buf, SparseOut
121127
AVFrame* frame = av_frame_alloc();
122128
ret = avcodec_receive_frame(m_codec_context, frame);
123129
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
130+
av_frame_free(&frame);
124131
break;
125132
} else if (ret < 0) {
126133
UNREACHABLE_MSG("Error during decoding");
@@ -135,11 +142,6 @@ std::tuple<u32, u32> AjmMp3Decoder::ProcessData(std::span<u8>& in_buf, SparseOut
135142
gapless.skipped_samples += skipped_samples;
136143
}
137144

138-
const auto max_samples =
139-
max_samples_per_channel.has_value()
140-
? max_samples_per_channel.value() * frame->ch_layout.nb_channels
141-
: std::numeric_limits<u32>::max();
142-
143145
switch (m_format) {
144146
case AjmFormatEncoding::S16:
145147
samples_decoded +=
@@ -157,6 +159,8 @@ std::tuple<u32, u32> AjmMp3Decoder::ProcessData(std::span<u8>& in_buf, SparseOut
157159
UNREACHABLE();
158160
}
159161

162+
max_samples -= samples_decoded;
163+
160164
av_frame_free(&frame);
161165
}
162166
}

src/core/libraries/ajm/ajm_mp3.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
extern "C" {
1010
#include <libavcodec/avcodec.h>
11+
struct SwrContext;
1112
}
1213

1314
namespace Libraries::Ajm {
@@ -82,6 +83,7 @@ class AjmMp3Decoder : public AjmCodec {
8283
const AVCodec* m_codec = nullptr;
8384
AVCodecContext* m_codec_context = nullptr;
8485
AVCodecParserContext* m_parser = nullptr;
86+
SwrContext* m_swr_context = nullptr;
8587
};
8688

8789
} // namespace Libraries::Ajm

0 commit comments

Comments
 (0)