Index: webrtc/examples/objc/AppRTCMobile/ARDAppClient.m |
diff --git a/webrtc/examples/objc/AppRTCMobile/ARDAppClient.m b/webrtc/examples/objc/AppRTCMobile/ARDAppClient.m |
index ef38138319ac56b2e9655eaec5cedef932cbd2f7..623fad4f285ed35d312b103c456248fc8783c958 100644 |
--- a/webrtc/examples/objc/AppRTCMobile/ARDAppClient.m |
+++ b/webrtc/examples/objc/AppRTCMobile/ARDAppClient.m |
@@ -12,6 +12,7 @@ |
#import "WebRTC/RTCAVFoundationVideoSource.h" |
#import "WebRTC/RTCAudioTrack.h" |
+#import "WebRTC/RTCCameraVideoCapturer.h" |
#import "WebRTC/RTCConfiguration.h" |
#import "WebRTC/RTCFileLogger.h" |
#import "WebRTC/RTCIceServer.h" |
@@ -21,6 +22,7 @@ |
#import "WebRTC/RTCPeerConnectionFactory.h" |
#import "WebRTC/RTCRtpSender.h" |
#import "WebRTC/RTCTracing.h" |
+#import "WebRTC/RTCVideoTrack.h" |
#import "ARDAppEngineClient.h" |
#import "ARDJoinResponse.h" |
@@ -100,6 +102,9 @@ static int const kKbpsMultiplier = 1000; |
RTCFileLogger *_fileLogger; |
ARDTimerProxy *_statsTimer; |
ARDSettingsModel *_settings; |
+ RTCCameraVideoCapturer *_capturer; |
+ RTCVideoTrack *_localVideoTrack; |
+ BOOL _usingFrontCamera; |
} |
@synthesize shouldGetStats = _shouldGetStats; |
@@ -300,11 +305,16 @@ static int const kKbpsMultiplier = 1000; |
// Disconnect from collider. |
_channel = nil; |
} |
+ if (_capturer) { |
+ [_capturer stopCapture]; |
+ _capturer = nil; |
+ } |
_clientId = nil; |
_roomId = nil; |
_isInitiator = NO; |
_hasReceivedSdp = NO; |
_messageQueue = [NSMutableArray array]; |
+ _localVideoTrack = nil; |
#if defined(WEBRTC_IOS) |
[_factory stopAecDump]; |
[_peerConnection stopRtcEventLog]; |
@@ -318,6 +328,11 @@ static int const kKbpsMultiplier = 1000; |
#endif |
} |
+- (void)switchCamera { |
+ _usingFrontCamera = !_usingFrontCamera; |
+ [self startCapture]; |
+} |
+ |
#pragma mark - ARDSignalingChannelDelegate |
- (void)channel:(id<ARDSignalingChannel>)channel |
@@ -666,11 +681,12 @@ static int const kKbpsMultiplier = 1000; |
RTCRtpSender *sender = |
[_peerConnection senderWithKind:kRTCMediaStreamTrackKindVideo |
streamId:kARDMediaStreamId]; |
- RTCVideoTrack *track = [self createLocalVideoTrack]; |
- if (track) { |
- sender.track = track; |
- [_delegate appClient:self didReceiveLocalVideoTrack:track]; |
+ _localVideoTrack = [self createLocalVideoTrack]; |
+ if (_localVideoTrack) { |
+ sender.track = _localVideoTrack; |
+ [_delegate appClient:self didReceiveLocalVideoTrack:_localVideoTrack]; |
} |
+ [_delegate appClient:self didReceiveLocalVideoTrack:_localVideoTrack]; |
daniela-webrtc
2017/04/03 10:16:50
Not sure if we should invoke the delegate with nil
sakal
2017/04/04 09:18:23
Oops, this was added by accident.
|
return sender; |
} |
@@ -709,6 +725,55 @@ static int const kKbpsMultiplier = 1000; |
return sender; |
} |
+- (void)startCapture { |
daniela-webrtc
2017/04/03 10:16:50
This should be exposed in the interface. Also, it
sakal
2017/04/04 09:18:23
Moved to CaptureController as discussed.
|
+ AVCaptureDevicePosition position = |
+ _usingFrontCamera ? AVCaptureDevicePositionFront : AVCaptureDevicePositionBack; |
+ AVCaptureDevice *device = [self findDeviceForPosition:position]; |
+ AVCaptureDeviceFormat *format = [self selectFormatForDevice:device]; |
+ int fps = [self selectFpsForFormat:format]; |
+ |
+ [_capturer startCaptureWithDevice:device format:format fps:fps]; |
+} |
+ |
+- (AVCaptureDevice *)findDeviceForPosition:(AVCaptureDevicePosition)position { |
+ NSArray<AVCaptureDevice *> *captureDevices = [RTCCameraVideoCapturer captureDevices]; |
+ for (AVCaptureDevice *device in captureDevices) { |
+ if (device.position == position) { |
+ return device; |
+ } |
+ } |
+ return captureDevices[0]; |
+} |
+ |
+- (AVCaptureDeviceFormat *)selectFormatForDevice:(AVCaptureDevice *)device { |
+ NSArray<AVCaptureDeviceFormat *> *formats = |
+ [RTCCameraVideoCapturer supportedFormatsForDevice:device]; |
+ int targetWidth = [_settings currentVideoResolutionWidthFromStore]; |
+ int targetHeight = [_settings currentVideoResolutionHeightFromStore]; |
+ AVCaptureDeviceFormat *selectedFormat; |
daniela-webrtc
2017/04/03 10:16:50
Preferably explicitly set pointers to nil.
sakal
2017/04/04 09:18:23
Done.
|
+ int currentDiff = INT_MAX; |
+ |
+ for (AVCaptureDeviceFormat *format in formats) { |
+ CMVideoDimensions dimension = CMVideoFormatDescriptionGetDimensions(format.formatDescription); |
+ int diff = abs(targetWidth - dimension.width) + abs(targetHeight - dimension.height); |
+ if (diff < currentDiff) { |
+ selectedFormat = format; |
+ currentDiff = diff; |
+ } |
+ } |
+ |
+ NSAssert(selectedFormat != nil, @"No suitable capture format found."); |
+ return selectedFormat; |
+} |
+ |
+- (int)selectFpsForFormat:(AVCaptureDeviceFormat *)format { |
+ Float64 maxFramerate = 0; |
+ for (AVFrameRateRange *fpsRange in format.videoSupportedFrameRateRanges) { |
+ maxFramerate = fmax(maxFramerate, fpsRange.maxFrameRate); |
+ } |
+ return maxFramerate; |
+} |
+ |
- (RTCVideoTrack *)createLocalVideoTrack { |
RTCVideoTrack* localVideoTrack = nil; |
// The iOS simulator doesn't provide any sort of camera capture |
@@ -716,10 +781,11 @@ static int const kKbpsMultiplier = 1000; |
// trying to open a local stream. |
#if !TARGET_IPHONE_SIMULATOR |
if (!_isAudioOnly) { |
- RTCMediaConstraints *cameraConstraints = |
- [self cameraConstraints]; |
- RTCAVFoundationVideoSource *source = |
- [_factory avFoundationVideoSourceWithConstraints:cameraConstraints]; |
+ RTCVideoSource *source = [_factory videoSource]; |
+ _capturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:source]; |
+ [_delegate appClient:self didCreateLocalCapturer:_capturer]; |
+ _usingFrontCamera = true; |
+ [self startCapture]; |
daniela-webrtc
2017/04/03 10:16:50
[startCapture] should not be here but rather expos
sakal
2017/04/04 09:18:23
Done.
|
localVideoTrack = |
[_factory videoTrackWithSource:source |
trackId:kARDVideoTrackId]; |
@@ -764,13 +830,6 @@ static int const kKbpsMultiplier = 1000; |
return constraints; |
} |
-- (RTCMediaConstraints *)cameraConstraints { |
- RTCMediaConstraints *cameraConstraints = [[RTCMediaConstraints alloc] |
- initWithMandatoryConstraints:nil |
- optionalConstraints:[_settings currentMediaConstraintFromStoreAsRTCDictionary]]; |
- return cameraConstraints; |
-} |
- |
- (RTCMediaConstraints *)defaultAnswerConstraints { |
return [self defaultOfferConstraints]; |
} |