Skip to content

Commit e5d2897

Browse files
committed
Fix playback of mono Atrac3+ tracks in videos
This is rare, but does occur: #19782 I missed that setChannels could happen late in my refactor (#19033)
1 parent 3c16932 commit e5d2897

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

Core/HW/Atrac3Standalone.cpp

+36-15
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,13 @@ class Atrac3Audio : public AudioDecoder {
1818
Atrac3Audio(PSPAudioType audioType, int channels, size_t blockAlign, const uint8_t *extraData, size_t extraDataSize)
1919
: audioType_(audioType), channels_(channels) {
2020
blockAlign_ = (int)blockAlign;
21-
if (audioType == PSP_CODEC_AT3PLUS) {
22-
at3pCtx_ = atrac3p_alloc(channels, &blockAlign_);
23-
if (at3pCtx_) {
24-
codecOpen_ = true;
25-
} else {
26-
ERROR_LOG(Log::ME, "Failed to open atrac3+ context! (channels=%d blockAlign=%d ed=%d)", channels, (int)blockAlign, (int)extraDataSize);
27-
}
28-
} else if (audioType_ == PSP_CODEC_AT3) {
21+
if (audioType_ == PSP_CODEC_AT3) {
2922
at3Ctx_ = atrac3_alloc(channels, &blockAlign_, extraData, (int)extraDataSize);
3023
if (at3Ctx_) {
3124
codecOpen_ = true;
3225
} else {
3326
ERROR_LOG(Log::ME, "Failed to open atrac3 context! !channels=%d blockAlign=%d ed=%d)", channels, (int)blockAlign, (int)extraDataSize);
27+
codecFailed_ = true;
3428
}
3529
}
3630
for (int i = 0; i < 2; i++) {
@@ -63,17 +57,34 @@ class Atrac3Audio : public AudioDecoder {
6357
}
6458

6559
bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) override {
60+
if (outSamples)
61+
*outSamples = 0;
62+
if (inbytesConsumed)
63+
*inbytesConsumed = 0;
6664
if (!codecOpen_) {
67-
WARN_LOG_N_TIMES(codecNotOpen, 5, Log::ME, "Atrac3Audio:Decode: Codec not open, not decoding");
68-
if (outSamples)
69-
*outSamples = 0;
70-
if (inbytesConsumed)
71-
*inbytesConsumed = 0;
72-
return false;
65+
// We delay the codecOpen until the first decode, so the setChannels call from MediaEngine::getAudioSamples
66+
// can take effect. Note, we don't do this with Atrac3, just Atrac3+.
67+
if (codecFailed_) {
68+
return false;
69+
}
70+
if (audioType_ == PSP_CODEC_AT3PLUS) {
71+
at3pCtx_ = atrac3p_alloc(channels_, &blockAlign_);
72+
if (at3pCtx_) {
73+
codecOpen_ = true;
74+
} else {
75+
ERROR_LOG(Log::ME, "Failed to open atrac3+ context! (channels=%d blockAlign=%d)", channels_, (int)blockAlign_);
76+
codecFailed_ = true;
77+
}
78+
}
79+
if (!codecOpen_) {
80+
WARN_LOG_N_TIMES(codecNotOpen, 5, Log::ME, "Atrac3Audio:Decode: Codec not open, not decoding");
81+
return false;
82+
}
7383
}
7484
if (inbytes != blockAlign_ && blockAlign_ != 0) {
7585
WARN_LOG(Log::ME, "Atrac3Audio::Decode: Unexpected block align %d (expected %d). %s", inbytes, blockAlign_, at3pCtx_ ? "Atrac3+" : "Atrac3");
7686
}
87+
7788
blockAlign_ = inbytes;
7889
// We just call the decode function directly without going through the whole packet machinery.
7990
int result;
@@ -125,7 +136,16 @@ class Atrac3Audio : public AudioDecoder {
125136
}
126137

127138
void SetChannels(int channels) override {
128-
// Hmm. ignore for now.
139+
_dbg_assert_(audioType_ == PSPAudioType::PSP_CODEC_AT3PLUS);
140+
if (audioType_ == PSPAudioType::PSP_CODEC_AT3PLUS) {
141+
if (!at3pCtx_) {
142+
// Codec shouldn't be open yet.
143+
_dbg_assert_(!codecOpen_);
144+
channels_ = 1;
145+
} else {
146+
// This will come every packet, just ignore it.
147+
}
148+
}
129149
}
130150

131151
PSPAudioType GetAudioType() const override { return audioType_; }
@@ -141,6 +161,7 @@ class Atrac3Audio : public AudioDecoder {
141161
float *buffers_[2]{};
142162

143163
bool codecOpen_ = false;
164+
bool codecFailed_ = false;
144165

145166
PSPAudioType audioType_;
146167
};

Core/HW/SimpleAudioDec.h

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class AudioDecoder {
4343
virtual bool Decode(const uint8_t *inbuf, int inbytes, int *inbytesConsumed, int outputChannels, int16_t *outbuf, int *outSamples) = 0;
4444
virtual bool IsOK() const = 0;
4545

46+
// NOTE: This can come late (MediaEngine::getAudioSample)! But it will come before the first Decode.
4647
virtual void SetChannels(int channels) = 0;
4748
virtual void FlushBuffers() {}
4849

0 commit comments

Comments
 (0)