Skip to content

Commit cabd738

Browse files
committed
Refactor decoder suspension loop
1 parent ec2e3d0 commit cabd738

File tree

2 files changed

+19
-39
lines changed

2 files changed

+19
-39
lines changed

Sources/CSFBAudioEngine/Player/AudioPlayer.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,6 @@ class AudioPlayer final {
366366
/// Returns the decoder state in `activeDecoders_` with the smallest sequence number that has not been canceled
367367
DecoderState * const _Nullable FirstActiveDecoderState() const noexcept;
368368

369-
/// Returns the decoder state in `activeDecoders_` with the smallest sequence number greater than `sequenceNumber` that has not been canceled
370-
DecoderState * const _Nullable FirstActiveDecoderStateFollowingSequenceNumber(const uint64_t sequenceNumber) const noexcept;
371-
372369
public:
373370
// MARK: - AVAudioEngine Notification Handling
374371

Sources/CSFBAudioEngine/Player/AudioPlayer.mm

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -995,31 +995,31 @@ bool PerformSeek() noexcept
995995
decoderState->flags_.fetch_and(~static_cast<unsigned int>(DecoderState::Flags::decodingComplete), std::memory_order_acq_rel);
996996
decoderState->flags_.fetch_or(static_cast<unsigned int>(DecoderState::Flags::decodingResumed), std::memory_order_acq_rel);
997997

998-
DecoderState *nextDecoderState = nullptr;
999998
{
1000999
std::lock_guard lock{activeDecodersLock_};
1001-
nextDecoderState = FirstActiveDecoderStateFollowingSequenceNumber(decoderState->sequenceNumber_);
1002-
}
10031000

1004-
// Rewind ensuing decoder states if possible to avoid discarding frames
1005-
while(nextDecoderState) {
1006-
if(nextDecoderState->flags_.load(std::memory_order_acquire) & static_cast<unsigned int>(DecoderState::Flags::decodingStarted)) {
1007-
os_log_debug(log_, "Suspending decoding for %{public}@", nextDecoderState->decoder_);
1001+
// Rewind ensuing decoder states if possible to avoid discarding frames
1002+
for(auto& nextDecoderState : activeDecoders_) {
1003+
if(nextDecoderState->sequenceNumber_ <= decoderState->sequenceNumber_)
1004+
continue;
10081005

1009-
// TODO: Investigate a per-state buffer to mitigate frame loss
1010-
if(nextDecoderState->decoder_.supportsSeeking) {
1011-
nextDecoderState->RequestSeekToFrame(0);
1012-
nextDecoderState->PerformSeek();
1013-
} else
1014-
os_log_error(log_, "Discarding %lld frames from %{public}@", nextDecoderState->framesDecoded_.load(std::memory_order_acquire), nextDecoderState->decoder_);
1006+
const auto flags = nextDecoderState->flags_.load(std::memory_order_acquire);
1007+
if(flags & (static_cast<unsigned int>(DecoderState::Flags::isCanceled)))
1008+
continue;
10151009

1016-
nextDecoderState->flags_.fetch_and(~static_cast<unsigned int>(DecoderState::Flags::decodingStarted), std::memory_order_acq_rel);
1017-
nextDecoderState->flags_.fetch_or(static_cast<unsigned int>(DecoderState::Flags::decodingSuspended), std::memory_order_acq_rel);
1018-
}
1010+
if(flags & static_cast<unsigned int>(DecoderState::Flags::decodingStarted)) {
1011+
os_log_debug(log_, "Suspending decoding for %{public}@", nextDecoderState->decoder_);
1012+
1013+
// TODO: Investigate a per-state buffer to mitigate frame loss
1014+
if(nextDecoderState->decoder_.supportsSeeking) {
1015+
nextDecoderState->RequestSeekToFrame(0);
1016+
nextDecoderState->PerformSeek();
1017+
} else
1018+
os_log_error(log_, "Discarding %lld frames from %{public}@", nextDecoderState->framesDecoded_.load(std::memory_order_acquire), nextDecoderState->decoder_);
10191019

1020-
{
1021-
std::lock_guard lock{activeDecodersLock_};
1022-
nextDecoderState = FirstActiveDecoderStateFollowingSequenceNumber(nextDecoderState->sequenceNumber_);
1020+
nextDecoderState->flags_.fetch_and(~static_cast<unsigned int>(DecoderState::Flags::decodingStarted), std::memory_order_acq_rel);
1021+
nextDecoderState->flags_.fetch_or(static_cast<unsigned int>(DecoderState::Flags::decodingSuspended), std::memory_order_acq_rel);
1022+
}
10231023
}
10241024
}
10251025
}
@@ -1799,23 +1799,6 @@ bool PerformSeek() noexcept
17991799
return iter->get();
18001800
}
18011801

1802-
SFB::AudioPlayer::DecoderState * const SFB::AudioPlayer::FirstActiveDecoderStateFollowingSequenceNumber(const uint64_t sequenceNumber) const noexcept
1803-
{
1804-
#if DEBUG
1805-
activeDecodersLock_.assert_owner();
1806-
#endif /* DEBUG */
1807-
1808-
const auto iter = std::ranges::find_if(activeDecoders_, [sequenceNumber](const auto& decoderState) {
1809-
if(decoderState->sequenceNumber_ <= sequenceNumber)
1810-
return false;
1811-
const auto flags = decoderState->flags_.load(std::memory_order_acquire);
1812-
return !(flags & static_cast<unsigned int>(DecoderState::Flags::isCanceled));
1813-
});
1814-
if(iter == activeDecoders_.cend())
1815-
return nullptr;
1816-
return iter->get();
1817-
}
1818-
18191802
// MARK: - AVAudioEngine Notification Handling
18201803

18211804
void SFB::AudioPlayer::HandleAudioEngineConfigurationChange(AVAudioEngine *engine, NSDictionary *userInfo) noexcept

0 commit comments

Comments
 (0)