Adding AecDump functionality to AppRTCDemo for iOS

BUG=webrtc:6229

Review-Url: https://codereview.webrtc.org/2253013006
Cr-Commit-Position: refs/heads/master@{#13927}
This commit is contained in:
peah
2016-08-25 22:15:14 -07:00
committed by Commit bot
parent bad33bf73b
commit 5085b0ca94
12 changed files with 98 additions and 14 deletions

View File

@ -43,6 +43,8 @@
@property(nonatomic, strong) NSURL *webSocketRestURL; @property(nonatomic, strong) NSURL *webSocketRestURL;
@property(nonatomic, readonly) BOOL isLoopback; @property(nonatomic, readonly) BOOL isLoopback;
@property(nonatomic, readonly) BOOL isAudioOnly; @property(nonatomic, readonly) BOOL isAudioOnly;
@property(nonatomic, readonly) BOOL shouldMakeAecDump;
@property(nonatomic, assign) BOOL isAecDumpActive;
@property(nonatomic, strong) @property(nonatomic, strong)
RTCMediaConstraints *defaultPeerConnectionConstraints; RTCMediaConstraints *defaultPeerConnectionConstraints;

View File

@ -64,9 +64,11 @@ typedef NS_ENUM(NSInteger, ARDAppClientState) {
// Establishes a connection with the AppRTC servers for the given room id. // Establishes a connection with the AppRTC servers for the given room id.
// If |isLoopback| is true, the call will connect to itself. // If |isLoopback| is true, the call will connect to itself.
// If |isAudioOnly| is true, video will be disabled for the call. // If |isAudioOnly| is true, video will be disabled for the call.
// If |shouldMakeAecDump| is true, an aecdump will be created for the call.
- (void)connectToRoomWithId:(NSString *)roomId - (void)connectToRoomWithId:(NSString *)roomId
isLoopback:(BOOL)isLoopback isLoopback:(BOOL)isLoopback
isAudioOnly:(BOOL)isAudioOnly; isAudioOnly:(BOOL)isAudioOnly
shouldMakeAecDump:(BOOL)shouldMakeAecDump;
// Disconnects from the AppRTC servers and any connected clients. // Disconnects from the AppRTC servers and any connected clients.
- (void)disconnect; - (void)disconnect;

View File

@ -129,6 +129,8 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
_defaultPeerConnectionConstraints; _defaultPeerConnectionConstraints;
@synthesize isLoopback = _isLoopback; @synthesize isLoopback = _isLoopback;
@synthesize isAudioOnly = _isAudioOnly; @synthesize isAudioOnly = _isAudioOnly;
@synthesize shouldMakeAecDump = _shouldMakeAecDump;
@synthesize isAecDumpActive = _isAecDumpActive;
- (instancetype)init { - (instancetype)init {
if (self = [super init]) { if (self = [super init]) {
@ -220,11 +222,13 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
- (void)connectToRoomWithId:(NSString *)roomId - (void)connectToRoomWithId:(NSString *)roomId
isLoopback:(BOOL)isLoopback isLoopback:(BOOL)isLoopback
isAudioOnly:(BOOL)isAudioOnly { isAudioOnly:(BOOL)isAudioOnly
shouldMakeAecDump:(BOOL)shouldMakeAecDump {
NSParameterAssert(roomId.length); NSParameterAssert(roomId.length);
NSParameterAssert(_state == kARDAppClientStateDisconnected); NSParameterAssert(_state == kARDAppClientStateDisconnected);
_isLoopback = isLoopback; _isLoopback = isLoopback;
_isAudioOnly = isAudioOnly; _isAudioOnly = isAudioOnly;
_shouldMakeAecDump = shouldMakeAecDump;
self.state = kARDAppClientStateConnecting; self.state = kARDAppClientStateConnecting;
#if defined(WEBRTC_IOS) #if defined(WEBRTC_IOS)
@ -309,6 +313,10 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
_hasReceivedSdp = NO; _hasReceivedSdp = NO;
_messageQueue = [NSMutableArray array]; _messageQueue = [NSMutableArray array];
#if defined(WEBRTC_IOS) #if defined(WEBRTC_IOS)
if (_isAecDumpActive) {
[_factory stopAecDump];
_isAecDumpActive = NO;
}
[_peerConnection stopRtcEventLog]; [_peerConnection stopRtcEventLog];
#endif #endif
_peerConnection = nil; _peerConnection = nil;
@ -562,6 +570,22 @@ static int64_t const kARDAppClientRtcEventLogMaxSizeInBytes = 5e6; // 5 MB.
RTCLogError(@"Failed to start event logging."); RTCLogError(@"Failed to start event logging.");
} }
} }
// Start aecdump diagnostic recording.
if (_shouldMakeAecDump) {
_isAecDumpActive = YES;
NSString *filePath = [self documentsFilePathForFileName:@"audio.aecdump"];
int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
if (fd < 0) {
RTCLogError(@"Failed to create the aecdump file!");
_isAecDumpActive = NO;
} else {
if (![_factory startAecDumpWithFileDescriptor:fd maxFileSizeInBytes:-1]) {
RTCLogError(@"Failed to create aecdump.");
_isAecDumpActive = NO;
}
}
}
#endif #endif
} }

View File

@ -15,10 +15,11 @@
@protocol ARDMainViewDelegate <NSObject> @protocol ARDMainViewDelegate <NSObject>
- (void)mainView:(ARDMainView *)mainView - (void)mainView:(ARDMainView *)mainView
didInputRoom:(NSString *)room didInputRoom:(NSString *)room
isLoopback:(BOOL)isLoopback isLoopback:(BOOL)isLoopback
isAudioOnly:(BOOL)isAudioOnly isAudioOnly:(BOOL)isAudioOnly
useManualAudio:(BOOL)useManualAudio; shouldMakeAecDump:(BOOL)shouldMakeAecDump
useManualAudio:(BOOL)useManualAudio;
- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView; - (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView;

View File

@ -119,6 +119,8 @@ static CGFloat const kCallControlMargin = 8;
UILabel *_callOptionsLabel; UILabel *_callOptionsLabel;
UISwitch *_audioOnlySwitch; UISwitch *_audioOnlySwitch;
UILabel *_audioOnlyLabel; UILabel *_audioOnlyLabel;
UISwitch *_aecdumpSwitch;
UILabel *_aecdumpLabel;
UISwitch *_loopbackSwitch; UISwitch *_loopbackSwitch;
UILabel *_loopbackLabel; UILabel *_loopbackLabel;
UISwitch *_useManualAudioSwitch; UISwitch *_useManualAudioSwitch;
@ -174,6 +176,17 @@ static CGFloat const kCallControlMargin = 8;
[_loopbackLabel sizeToFit]; [_loopbackLabel sizeToFit];
[self addSubview:_loopbackLabel]; [self addSubview:_loopbackLabel];
_aecdumpSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
[_aecdumpSwitch sizeToFit];
[self addSubview:_aecdumpSwitch];
_aecdumpLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_aecdumpLabel.text = @"Create AecDump";
_aecdumpLabel.font = controlFont;
_aecdumpLabel.textColor = controlFontColor;
[_aecdumpLabel sizeToFit];
[self addSubview:_aecdumpLabel];
_useManualAudioSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; _useManualAudioSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
[_useManualAudioSwitch sizeToFit]; [_useManualAudioSwitch sizeToFit];
_useManualAudioSwitch.on = YES; _useManualAudioSwitch.on = YES;
@ -274,8 +287,21 @@ static CGFloat const kCallControlMargin = 8;
_loopbackLabel.center = CGPointMake(loopbackModeLabelCenterX, _loopbackLabel.center = CGPointMake(loopbackModeLabelCenterX,
CGRectGetMidY(loopbackModeRect)); CGRectGetMidY(loopbackModeRect));
CGFloat useManualAudioTop = CGFloat aecdumpModeTop =
CGRectGetMaxY(_loopbackSwitch.frame) + kCallControlMargin; CGRectGetMaxY(_loopbackSwitch.frame) + kCallControlMargin;
CGRect aecdumpModeRect = CGRectMake(kCallControlMargin * 3,
aecdumpModeTop,
_aecdumpSwitch.frame.size.width,
_aecdumpSwitch.frame.size.height);
_aecdumpSwitch.frame = aecdumpModeRect;
CGFloat aecdumpModeLabelCenterX = CGRectGetMaxX(aecdumpModeRect) +
kCallControlMargin + _aecdumpLabel.frame.size.width / 2;
_aecdumpLabel.center = CGPointMake(aecdumpModeLabelCenterX,
CGRectGetMidY(aecdumpModeRect));
CGFloat useManualAudioTop =
CGRectGetMaxY(_aecdumpSwitch.frame) + kCallControlMargin;
CGRect useManualAudioRect = CGRect useManualAudioRect =
CGRectMake(kCallControlMargin * 3, CGRectMake(kCallControlMargin * 3,
useManualAudioTop, useManualAudioTop,
@ -334,6 +360,7 @@ static CGFloat const kCallControlMargin = 8;
didInputRoom:room didInputRoom:room
isLoopback:_loopbackSwitch.isOn isLoopback:_loopbackSwitch.isOn
isAudioOnly:_audioOnlySwitch.isOn isAudioOnly:_audioOnlySwitch.isOn
shouldMakeAecDump:_aecdumpSwitch.isOn
useManualAudio:_useManualAudioSwitch.isOn]; useManualAudio:_useManualAudioSwitch.isOn];
} }

View File

@ -54,9 +54,10 @@
#pragma mark - ARDMainViewDelegate #pragma mark - ARDMainViewDelegate
- (void)mainView:(ARDMainView *)mainView - (void)mainView:(ARDMainView *)mainView
didInputRoom:(NSString *)room didInputRoom:(NSString *)room
isLoopback:(BOOL)isLoopback isLoopback:(BOOL)isLoopback
isAudioOnly:(BOOL)isAudioOnly isAudioOnly:(BOOL)isAudioOnly
shouldMakeAecDump:(BOOL)shouldMakeAecDump
useManualAudio:(BOOL)useManualAudio { useManualAudio:(BOOL)useManualAudio {
if (!room.length) { if (!room.length) {
[self showAlertWithMessage:@"Missing room name."]; [self showAlertWithMessage:@"Missing room name."];
@ -96,6 +97,7 @@
[[ARDVideoCallViewController alloc] initForRoom:trimmedRoom [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
isLoopback:isLoopback isLoopback:isLoopback
isAudioOnly:isAudioOnly isAudioOnly:isAudioOnly
shouldMakeAecDump:shouldMakeAecDump
delegate:self]; delegate:self];
videoCallViewController.modalTransitionStyle = videoCallViewController.modalTransitionStyle =
UIModalTransitionStyleCrossDissolve; UIModalTransitionStyleCrossDissolve;

View File

@ -24,6 +24,7 @@
- (instancetype)initForRoom:(NSString *)room - (instancetype)initForRoom:(NSString *)room
isLoopback:(BOOL)isLoopback isLoopback:(BOOL)isLoopback
isAudioOnly:(BOOL)isAudioOnly isAudioOnly:(BOOL)isAudioOnly
shouldMakeAecDump:(BOOL)shouldMakeAecDump
delegate:(id<ARDVideoCallViewControllerDelegate>)delegate; delegate:(id<ARDVideoCallViewControllerDelegate>)delegate;
@end @end

View File

@ -39,13 +39,15 @@
- (instancetype)initForRoom:(NSString *)room - (instancetype)initForRoom:(NSString *)room
isLoopback:(BOOL)isLoopback isLoopback:(BOOL)isLoopback
isAudioOnly:(BOOL)isAudioOnly isAudioOnly:(BOOL)isAudioOnly
shouldMakeAecDump:(BOOL)shouldMakeAecDump
delegate:(id<ARDVideoCallViewControllerDelegate>)delegate { delegate:(id<ARDVideoCallViewControllerDelegate>)delegate {
if (self = [super init]) { if (self = [super init]) {
_delegate = delegate; _delegate = delegate;
_client = [[ARDAppClient alloc] initWithDelegate:self]; _client = [[ARDAppClient alloc] initWithDelegate:self];
[_client connectToRoomWithId:room [_client connectToRoomWithId:room
isLoopback:isLoopback isLoopback:isLoopback
isAudioOnly:isAudioOnly]; isAudioOnly:isAudioOnly
shouldMakeAecDump:shouldMakeAecDump];
} }
return self; return self;
} }

View File

@ -284,7 +284,7 @@ static NSUInteger const kLogViewHeight = 280;
didEnterRoomId:(NSString*)roomId { didEnterRoomId:(NSString*)roomId {
[_client disconnect]; [_client disconnect];
ARDAppClient *client = [[ARDAppClient alloc] initWithDelegate:self]; ARDAppClient *client = [[ARDAppClient alloc] initWithDelegate:self];
[client connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; [client connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO shouldMakeAecDump:NO];
_client = client; _client = client;
} }

View File

@ -283,8 +283,8 @@
weakAnswerer = answerer; weakAnswerer = answerer;
// Kick off connection. // Kick off connection.
[caller connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; [caller connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO shouldMakeAecDump:NO];
[answerer connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO]; [answerer connectToRoomWithId:roomId isLoopback:NO isAudioOnly:NO shouldMakeAecDump:NO];
[self waitForExpectationsWithTimeout:20 handler:^(NSError *error) { [self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
if (error) { if (error) {
NSLog(@"Expectations error: %@", error); NSLog(@"Expectations error: %@", error);

View File

@ -48,6 +48,19 @@
return self; return self;
} }
- (BOOL)startAecDumpWithFileDescriptor:(int)fileDescriptor
maxFileSizeInBytes:(int)maxFileSizeInBytes {
// Pass the file to the recorder. The file ownership
// is passed to the recorder, and the recorder
// closes the file when needed.
return _nativeFactory->StartAecDump(fileDescriptor, maxFileSizeInBytes);
}
- (void)stopAecDump {
// The file is closed by the call below.
_nativeFactory->StopAecDump();
}
- (RTCAVFoundationVideoSource *)avFoundationVideoSourceWithConstraints: - (RTCAVFoundationVideoSource *)avFoundationVideoSourceWithConstraints:
(nullable RTCMediaConstraints *)constraints { (nullable RTCMediaConstraints *)constraints {
return [[RTCAVFoundationVideoSource alloc] initWithFactory:self return [[RTCAVFoundationVideoSource alloc] initWithFactory:self

View File

@ -53,6 +53,16 @@ RTC_EXPORT
delegate: delegate:
(nullable id<RTCPeerConnectionDelegate>)delegate; (nullable id<RTCPeerConnectionDelegate>)delegate;
/** Start an aecdump recording with a file descriptor and
a specified maximum size limit (-1 specifies that no
limit should be used).
This API call will likely change in the future */
- (BOOL)startAecDumpWithFileDescriptor:(int)fileDescriptor
maxFileSizeInBytes:(int)maxFileSizeInBytes;
/* Stop an active aecdump recording */
- (void)stopAecDump;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END