@@ -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
18211804void SFB::AudioPlayer::HandleAudioEngineConfigurationChange (AVAudioEngine *engine, NSDictionary *userInfo) noexcept
0 commit comments