From 5a8068b859f1bccbd55e77df77ec658f5ffff00d Mon Sep 17 00:00:00 2001 From: Thong Nguyen Date: Sun, 16 Feb 2014 11:57:23 +0000 Subject: [PATCH] STKAutoRecoveringHTTPDataSource shouldn't retry if inner data source no longer is registered --- StreamingKit/StreamingKit/STKAudioPlayer.h | 2 + StreamingKit/StreamingKit/STKAudioPlayer.m | 41 ++++++++++++------- .../STKAutoRecoveringHTTPDataSource.m | 5 ++- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.h b/StreamingKit/StreamingKit/STKAudioPlayer.h index 8cd3a52..0ce6d53 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.h +++ b/StreamingKit/StreamingKit/STKAudioPlayer.h @@ -94,6 +94,8 @@ typedef struct UInt32 bufferSizeInSeconds; /// Number of seconds of decompressed audio is required before playback first starts for each item (Default is 0.5 seconds. Must be larger than bufferSizeInSeconds) Float32 secondsRequiredToStartPlaying; + /// Seconds after a seek is performed before data needs to come in (after which the state will change to playing/buffering) + Float32 gracePeriodAfterSeekInSeconds; /// Number of seconds of decompressed audio required before playback resumes after a buffer underrun (Default is 5 seconds. Must be larger than bufferSizeinSeconds) Float32 secondsRequiredToStartPlayingAfterBufferUnderun; } diff --git a/StreamingKit/StreamingKit/STKAudioPlayer.m b/StreamingKit/StreamingKit/STKAudioPlayer.m index 659d53c..a3f1661 100644 --- a/StreamingKit/StreamingKit/STKAudioPlayer.m +++ b/StreamingKit/StreamingKit/STKAudioPlayer.m @@ -57,7 +57,7 @@ #define STK_MAX_COMPRESSED_PACKETS_FOR_BITRATE_CALCULATION (4096) #define STK_DEFAULT_READ_BUFFER_SIZE (64 * 1024) #define STK_DEFAULT_PACKET_BUFFER_SIZE (2048) -#define STK_CYCLES_REQUIRED_BEFORE_SEEK_BECOMES_PLAYING (6) +#define STK_DEFAULT_GRACE_PERIOD_AFTER_SEEK_SECONDS (0.5) #define LOGINFO(x) [self logInfo:[NSString stringWithFormat:@"%s %@", sel_getName(_cmd), x]]; @@ -82,6 +82,11 @@ static void PopulateOptionsWithDefault(STKAudioPlayerOptions* options) { options->secondsRequiredToStartPlayingAfterBufferUnderun = MIN(STK_DEFAULT_SECONDS_REQUIRED_TO_START_PLAYING_AFTER_BUFFER_UNDERRUN, options->bufferSizeInSeconds); } + + if (options->gracePeriodAfterSeekInSeconds == 0) + { + options->gracePeriodAfterSeekInSeconds = MIN(STK_DEFAULT_GRACE_PERIOD_AFTER_SEEK_SECONDS, options->bufferSizeInSeconds); + } } #define CHECK_STATUS_AND_REPORT(call) \ @@ -199,10 +204,11 @@ static AudioStreamBasicDescription canonicalAudioStreamBasicDescription; AudioComponentInstance outputUnit; UInt32 eqBandCount; - int32_t waitingForDataAfterSeekCycleCount; + int32_t waitingForDataAfterSeekFrameCount; UInt32 framesRequiredToStartPlaying; UInt32 framesRequiredToPlayAfterRebuffering; + UInt32 framesRequiredBeforeWaitingForDataAfterSeekBecomesPlaying; STKQueueEntry* volatile currentlyPlayingEntry; STKQueueEntry* volatile currentlyReadingEntry; @@ -384,11 +390,8 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn OSSpinLockLock(&internalStateLock); - if (internalState != STKAudioPlayerInternalStateWaitingForDataAfterSeek) - { - waitingForDataAfterSeekCycleCount = 0; - } - + waitingForDataAfterSeekFrameCount = 0; + if (value == internalState) { OSSpinLockUnlock(&internalStateLock); @@ -468,6 +471,7 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn framesRequiredToStartPlaying = canonicalAudioStreamBasicDescription.mSampleRate * options.secondsRequiredToStartPlaying; framesRequiredToPlayAfterRebuffering = canonicalAudioStreamBasicDescription.mSampleRate * options.secondsRequiredToStartPlayingAfterBufferUnderun; + framesRequiredBeforeWaitingForDataAfterSeekBecomesPlaying = canonicalAudioStreamBasicDescription.mSampleRate * options.gracePeriodAfterSeekInSeconds; pcmAudioBuffer = &pcmAudioBufferList.mBuffers[0]; @@ -1459,6 +1463,8 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn [currentEntry reset]; [currentEntry.dataSource seekToOffset:seekByteOffset]; + self->waitingForDataAfterSeekFrameCount = 0; + self.internalState = STKAudioPlayerInternalStateWaitingForDataAfterSeek; if (audioGraph) @@ -2562,7 +2568,7 @@ static OSStatus OutputRenderCallback(void* inRefCon, AudioUnitRenderActionFlags* } else if (state == STKAudioPlayerInternalStateWaitingForDataAfterSeek) { - int64_t framesRequiredToStartPlaying = inNumberFrames; + int64_t framesRequiredToStartPlaying = 1024; if (entry->lastFrameQueued >= 0) { @@ -2681,14 +2687,21 @@ static OSStatus OutputRenderCallback(void* inRefCon, AudioUnitRenderActionFlags* } else if (state == STKAudioPlayerInternalStateWaitingForDataAfterSeek) { - OSAtomicIncrement32(&audioPlayer->waitingForDataAfterSeekCycleCount); - - if (audioPlayer->waitingForDataAfterSeekCycleCount > STK_CYCLES_REQUIRED_BEFORE_SEEK_BECOMES_PLAYING) + if (totalFramesCopied == 0) { - [audioPlayer setInternalState:STKAudioPlayerInternalStatePlaying ifInState:^BOOL(STKAudioPlayerInternalState state) + OSAtomicAdd32(inNumberFrames - totalFramesCopied, &audioPlayer->waitingForDataAfterSeekFrameCount); + + if (audioPlayer->waitingForDataAfterSeekFrameCount > audioPlayer->framesRequiredBeforeWaitingForDataAfterSeekBecomesPlaying) { - return (state & STKAudioPlayerInternalStateRunning) && state != STKAudioPlayerInternalStatePaused; - }]; + [audioPlayer setInternalState:STKAudioPlayerInternalStatePlaying ifInState:^BOOL(STKAudioPlayerInternalState state) + { + return (state & STKAudioPlayerInternalStateRunning) && state != STKAudioPlayerInternalStatePaused; + }]; + } + } + else + { + audioPlayer->waitingForDataAfterSeekFrameCount = 0; } } } diff --git a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m index fc65774..cdee441 100644 --- a/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m +++ b/StreamingKit/StreamingKit/STKAutoRecoveringHTTPDataSource.m @@ -308,7 +308,10 @@ static void PopulateOptionsWithDefault(STKAutoRecoveringHTTPDataSourceOptions* o NSLog(@"attemptReconnect %lld/%lld", self.position, self.length); - [self.innerDataSource reconnect]; + if (self.innerDataSource.eventsRunLoop) + { + [self.innerDataSource reconnect]; + } } -(void) attemptReconnectWithTimer:(NSTimer*)timer