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:
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user