Optimised seekToTime to avoid using the player thread mutex to allow smoother scrubbing

This commit is contained in:
Thong Nguyen 2014-01-27 02:00:01 +00:00
parent 804aa9dd6e
commit ca80243083
2 changed files with 3101 additions and 17 deletions

File diff suppressed because it is too large Load Diff

View File

@ -326,6 +326,8 @@ AudioQueueBufferRefLookupEntry;
AudioPlayerErrorCode errorCode;
AudioPlayerStopReason stopReason;
int seekLock;
int32_t seekVersion;
int currentEntryReferencesLock;
pthread_mutex_t playerMutex;
pthread_mutex_t queueBuffersMutex;
@ -1927,22 +1929,30 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
-(void) seekToTime:(double)value
{
pthread_mutex_lock(&playerMutex);
if (currentlyPlayingEntry == nil)
{
if (currentlyPlayingEntry != nil)
{
BOOL seekAlreadyRequested = seekToTimeWasRequested;
seekToTimeWasRequested = YES;
requestedSeekTime = value;
if (!seekAlreadyRequested)
{
[self wakeupPlaybackThread];
}
}
return;
}
pthread_mutex_unlock(&playerMutex);
OSSpinLockLock(&seekLock);
BOOL seekAlreadyRequested = seekToTimeWasRequested;
seekToTimeWasRequested = YES;
requestedSeekTime = value;
if (!seekAlreadyRequested)
{
OSAtomicIncrement32(&seekVersion);
OSSpinLockUnlock(&seekLock);
[self wakeupPlaybackThread];
return;
}
OSSpinLockUnlock(&seekLock);
}
-(void) createOrWakeupPlaybackThread
@ -2055,7 +2065,9 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
{
next.seekTime = 0;
OSSpinLockLock(&seekLock);
seekToTimeWasRequested = NO;
OSSpinLockUnlock(&seekLock);
}
OSSpinLockLock(&currentEntryReferencesLock);
@ -2216,7 +2228,7 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
currentlyReadingEntry = nil;
seekToTimeWasRequested = NO;
OSSpinLockUnlock(&currentEntryReferencesLock);
}
}
else if (self.internalState == AudioPlayerInternalStateStopped && stopReason == AudioPlayerStopReasonUserActionFlushStop)
{
currentlyReadingEntry.dataSource.delegate = nil;
@ -2293,10 +2305,24 @@ static void AudioQueueIsRunningCallbackProc(void* userData, AudioQueueRef audioQ
if (currentlyPlayingEntry && currentlyPlayingEntry->parsedHeader)
{
if (seekToTimeWasRequested && currentlyReadingEntry == currentlyPlayingEntry)
int32_t originalSeekVersion;
BOOL originalSeekToTimeRequested;
OSSpinLockLock(&seekLock);
originalSeekVersion = seekVersion;
originalSeekToTimeRequested = seekToTimeWasRequested;
OSSpinLockUnlock(&seekLock);
if (originalSeekToTimeRequested && currentlyReadingEntry == currentlyPlayingEntry)
{
[self processSeekToTime];
seekToTimeWasRequested = NO;
OSSpinLockLock(&seekLock);
if (originalSeekVersion == seekVersion)
{
seekToTimeWasRequested = NO;
}
OSSpinLockUnlock(&seekLock);
}
}
else if (currentlyPlayingEntry == nil && seekToTimeWasRequested)