diff --git a/StreamingKit/StreamingKit/STKBufferingDataSource.m b/StreamingKit/StreamingKit/STKBufferingDataSource.m index 77f88c0..5a4a06d 100644 --- a/StreamingKit/StreamingKit/STKBufferingDataSource.m +++ b/StreamingKit/StreamingKit/STKBufferingDataSource.m @@ -37,6 +37,7 @@ @interface STKBufferingDataSource() { @private + NSRunLoop* runLoop; int bufferStartIndex; int bufferStartFileOffset; int bufferBytesUsed; @@ -47,8 +48,64 @@ } @end +@interface STKBufferingDataSourceThread : NSThread +{ +@private + NSRunLoop* runLoop; + NSConditionLock* threadStartedLock; +} +@end + +@implementation STKBufferingDataSourceThread + +-(id) init +{ + if (self = [super init]) + { + threadStartedLock = [[NSConditionLock alloc] initWithCondition:0]; + } + + return self; +} + +-(NSRunLoop*) runLoop +{ + [threadStartedLock lockWhenCondition:1]; + [threadStartedLock unlockWithCondition:0]; + + return self->runLoop; +} + +-(void) main +{ + runLoop = [NSRunLoop currentRunLoop]; + + [threadStartedLock lockWhenCondition:0]; + [threadStartedLock unlockWithCondition:1]; + + [runLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode]; + + while (true) + { + NSDate* date = [[NSDate alloc] initWithTimeIntervalSinceNow:10]; + + [runLoop runMode:NSDefaultRunLoopMode beforeDate:date]; + } +} + +@end + +static STKBufferingDataSourceThread* thread; + @implementation STKBufferingDataSource ++(void) initialize +{ + thread = [[STKBufferingDataSourceThread alloc] init]; + + [thread start]; +} + -(id) initWithDataSource:(STKDataSource*)dataSourceIn withMaxSize:(int)maxSizeIn { if (self = [super init]) @@ -57,6 +114,8 @@ self->bufferBytesTotal = maxSizeIn; self->dataSource.delegate = self.delegate; + + [self->dataSource registerForEvents:[thread runLoop]]; } return self; @@ -89,6 +148,55 @@ { } +-(BOOL) hasBytesAvailable +{ + return bufferBytesUsed > 0; +} + +-(int) readIntoBuffer:(UInt8*)bufferIn withSize:(int)size +{ + SInt64 bytesAlreadyReadInBuffer = (position - bufferStartFileOffset); + SInt64 bytesAvailable = bufferBytesUsed - bytesAlreadyReadInBuffer; + + if (bytesAvailable < 0) + { + return 0; + } + + int start = (bufferStartIndex + bytesAlreadyReadInBuffer) % bufferBytesTotal; + int end = (start + bufferBytesUsed) % bufferBytesTotal; + int bytesToRead = MIN(end - start, size); + + memcpy(self->buffer, bufferIn, bytesToRead); + + self->bufferBytesUsed -= bytesToRead; + self->bufferStartFileOffset += bytesToRead; + + return bytesToRead; +} + +-(BOOL) registerForEvents:(NSRunLoop*)runLoopIn +{ + runLoop = runLoopIn; + + [dataSource registerForEvents:[thread runLoop]]; + + return YES; +} + +-(void) unregisterForEvents +{ + runLoop = nil; + + [dataSource unregisterForEvents]; +} + +-(void) close +{ + [dataSource unregisterForEvents]; + [dataSource close]; +} + -(void) dataSourceDataAvailable:(STKDataSource*)dataSourceIn { if (self->buffer == nil) @@ -102,6 +210,7 @@ if (start >= end) { int bytesRead; + int bufferStartFileOffsetDelta = 0; int bytesToRead = bufferBytesTotal - start; if (bytesToRead > 0) @@ -110,9 +219,11 @@ } else { - bytesToRead = start; + bytesToRead = end; bytesRead = [dataSource readIntoBuffer:self->buffer withSize:bytesToRead]; + + bufferStartFileOffsetDelta = bytesRead - bufferStartIndex; } if (bytesRead < 0) @@ -120,8 +231,8 @@ return; } - bufferStartIndex += bytesRead; bufferBytesUsed += bytesRead; + bufferStartFileOffset += bufferStartFileOffsetDelta; } else { @@ -134,8 +245,11 @@ return; } + int bufferStartFileOffsetDelta = (bytesRead + start) - bufferStartIndex; + bufferStartIndex += bytesRead; bufferBytesUsed += bytesRead; + bufferStartFileOffset += bufferStartFileOffsetDelta; } } diff --git a/StreamingKit/StreamingKit/STKHTTPDataSource.h b/StreamingKit/StreamingKit/STKHTTPDataSource.h index dda2924..628a62f 100644 --- a/StreamingKit/StreamingKit/STKHTTPDataSource.h +++ b/StreamingKit/StreamingKit/STKHTTPDataSource.h @@ -43,7 +43,7 @@ typedef void(^STKAsyncURLProvider)(STKHTTPDataSource* dataSource, BOOL forSeek, @interface STKHTTPDataSource : STKCoreFoundationDataSource @property (readonly, retain) NSURL* url; -@property (readwrite) UInt32 httpStatusCode; +@property (readonly) UInt32 httpStatusCode; +(AudioFileTypeID) audioFileTypeHintFromMimeType:(NSString*)fileExtension; -(id) initWithURL:(NSURL*)url; diff --git a/StreamingKit/StreamingKit/STKHTTPDataSource.m b/StreamingKit/StreamingKit/STKHTTPDataSource.m index 2046b44..e98a5d6 100644 --- a/StreamingKit/StreamingKit/STKHTTPDataSource.m +++ b/StreamingKit/StreamingKit/STKHTTPDataSource.m @@ -38,6 +38,7 @@ @interface STKHTTPDataSource() { @private + UInt32 httpStatusCode; SInt64 seekStart; SInt64 relativePosition; SInt64 fileLength; @@ -152,7 +153,7 @@ { httpHeaders = (__bridge_transfer NSDictionary*)CFHTTPMessageCopyAllHeaderFields((CFHTTPMessageRef)response); - self.httpStatusCode = CFHTTPMessageGetResponseStatusCode((CFHTTPMessageRef)response); + self->httpStatusCode = CFHTTPMessageGetResponseStatusCode((CFHTTPMessageRef)response); CFRelease(response); } @@ -342,7 +343,7 @@ [self reregisterForEvents]; - self.httpStatusCode = 0; + self->httpStatusCode = 0; // Open @@ -364,6 +365,11 @@ }); } +-(UInt32) httpStatusCode +{ + return self->httpStatusCode; +} + -(NSRunLoop*) eventsRunLoop { return self->eventsRunLoop;