Reland "Add file capturer to AppRTCMobile on simulator."
This is a reland of 5adcd198752b651f7b7e9199a91f9b873b7d7237
Original change's description:
> Add file capturer to AppRTCMobile on simulator.
>
> To achieve this, the CL does the following
> - Adds sample mp4 video
> - Refactors the existing RTCFileVideoCapturer to achieve continious
> capture and adds tests.
>
> Bug: webrtc:8406
> Change-Id: Ibc0891176c58ec9053b42e340d2113036e7199ec
> Reviewed-on: https://webrtc-review.googlesource.com/12180
> Reviewed-by: Anders Carlsson <andersc@webrtc.org>
> Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
> Commit-Queue: Daniela Jovanoska Petrenko <denicija@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#20598}
Bug: webrtc:8406
Change-Id: I93be89b86e342a9a8195e19ebaf4aef1410d2c20
Reviewed-on: https://webrtc-review.googlesource.com/23200
Reviewed-by: Daniela Jovanoska Petrenko <denicija@webrtc.org>
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Commit-Queue: Daniela Jovanoska Petrenko <denicija@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20870}
diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCFileVideoCapturer.m b/sdk/objc/Framework/Classes/PeerConnection/RTCFileVideoCapturer.m
index 178a958..07cb2c6 100644
--- a/sdk/objc/Framework/Classes/PeerConnection/RTCFileVideoCapturer.m
+++ b/sdk/objc/Framework/Classes/PeerConnection/RTCFileVideoCapturer.m
@@ -8,60 +8,91 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#import "RTCFileVideoCapturer.h"
+#import "WebRTC/RTCFileVideoCapturer.h"
#import "WebRTC/RTCLogging.h"
#import "WebRTC/RTCVideoFrameBuffer.h"
+NSString *const kRTCFileVideoCapturerErrorDomain = @"org.webrtc.RTCFileVideoCapturer";
+
+typedef NS_ENUM(NSInteger, RTCFileVideoCapturerErrorCode) {
+ RTCFileVideoCapturerErrorCode_CapturerRunning = 2000,
+ RTCFileVideoCapturerErrorCode_FileNotFound
+};
+
+typedef NS_ENUM(NSInteger, RTCFileVideoCapturerStatus) {
+ RTCFileVideoCapturerStatusNotInitialized,
+ RTCFileVideoCapturerStatusStarted,
+ RTCFileVideoCapturerStatusStopped
+};
+
@implementation RTCFileVideoCapturer {
AVAssetReader *_reader;
AVAssetReaderTrackOutput *_outTrack;
- BOOL _capturerStopped;
+ RTCFileVideoCapturerStatus _status;
CMTime _lastPresentationTime;
dispatch_queue_t _frameQueue;
+ NSURL *_fileURL;
}
-- (void)startCapturingFromFileNamed:(NSString *)nameOfFile {
+- (void)startCapturingFromFileNamed:(NSString *)nameOfFile
+ onError:(RTCFileVideoCapturerErrorBlock)errorBlock {
+ if (_status == RTCFileVideoCapturerStatusStarted) {
+ NSError *error =
+ [NSError errorWithDomain:kRTCFileVideoCapturerErrorDomain
+ code:RTCFileVideoCapturerErrorCode_CapturerRunning
+ userInfo:@{NSUnderlyingErrorKey : @"Capturer has been started."}];
+
+ errorBlock(error);
+ return;
+ } else {
+ _status = RTCFileVideoCapturerStatusStarted;
+ }
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- if (_reader && _reader.status == AVAssetReaderStatusReading) {
- RTCLog("Capturer exists and reads another file. Start capture request failed.");
- return;
- }
NSString *pathForFile = [self pathForFileName:nameOfFile];
if (!pathForFile) {
- RTCLog("File %@ not found in bundle", nameOfFile);
+ NSString *errorString =
+ [NSString stringWithFormat:@"File %@ not found in bundle", nameOfFile];
+ NSError *error = [NSError errorWithDomain:kRTCFileVideoCapturerErrorDomain
+ code:RTCFileVideoCapturerErrorCode_FileNotFound
+ userInfo:@{NSUnderlyingErrorKey : errorString}];
+ errorBlock(error);
return;
}
_lastPresentationTime = CMTimeMake(0, 0);
- NSURL *URLForFile = [NSURL fileURLWithPath:pathForFile];
- AVURLAsset *asset = [AVURLAsset URLAssetWithURL:URLForFile options:nil];
-
- NSArray *allTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
- NSError *error = nil;
- _reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
- if (error) {
- RTCLog("File reader failed with error: %@", error);
- return;
- }
-
- NSDictionary *options = @{
- (NSString *)
- kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
- };
- _outTrack = [[AVAssetReaderTrackOutput alloc] initWithTrack:allTracks.firstObject
- outputSettings:options];
- [_reader addOutput:_outTrack];
-
- [_reader startReading];
- RTCLog(@"File capturer started reading");
- [self readNextBuffer];
+ _fileURL = [NSURL fileURLWithPath:pathForFile];
+ [self setupReaderOnError:errorBlock];
});
}
+- (void)setupReaderOnError:(RTCFileVideoCapturerErrorBlock)errorBlock {
+ AVURLAsset *asset = [AVURLAsset URLAssetWithURL:_fileURL options:nil];
+
+ NSArray *allTracks = [asset tracksWithMediaType:AVMediaTypeVideo];
+ NSError *error = nil;
+
+ _reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
+ if (error) {
+ errorBlock(error);
+ return;
+ }
+
+ NSDictionary *options = @{
+ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
+ };
+ _outTrack =
+ [[AVAssetReaderTrackOutput alloc] initWithTrack:allTracks.firstObject outputSettings:options];
+ [_reader addOutput:_outTrack];
+
+ [_reader startReading];
+ RTCLog(@"File capturer started reading");
+ [self readNextBuffer];
+}
- (void)stopCapture {
- _capturerStopped = YES;
+ _status = RTCFileVideoCapturerStatusStopped;
RTCLog(@"File capturer stopped.");
}
@@ -88,12 +119,19 @@
}
- (void)readNextBuffer {
- if (_reader.status != AVAssetReaderStatusReading || _capturerStopped) {
+ if (_status == RTCFileVideoCapturerStatusStopped) {
[_reader cancelReading];
_reader = nil;
return;
}
+ if (_reader.status == AVAssetReaderStatusCompleted) {
+ [_reader cancelReading];
+ _reader = nil;
+ [self setupReaderOnError:nil];
+ return;
+ }
+
CMSampleBufferRef sampleBuffer = [_outTrack copyNextSampleBuffer];
if (!sampleBuffer) {
[self readNextBuffer];