Fixed crash when PCF is destroyed before MediaSource/Track in ObjC

Bug: webrtc:9231
Change-Id: I31b86aa560f4ad230c9a94fedebebf320e0370a4
Reviewed-on: https://webrtc-review.googlesource.com/88221
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23981}
This commit is contained in:
Yura Yaroshevich
2018-07-11 15:35:40 +03:00
committed by Commit Bot
parent 5a3d87d122
commit 01cee079dc
15 changed files with 180 additions and 76 deletions

View File

@ -21,12 +21,12 @@
@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::AudioSourceInterface> nativeAudioSource;
/** Initialize an RTCAudioSource from a native AudioSourceInterface. */
- (instancetype)initWithNativeAudioSource:
(rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource
- (instancetype)initWithFactory:(RTCPeerConnectionFactory*)factory
nativeAudioSource:(rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource
NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithNativeMediaSource:
(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type NS_UNAVAILABLE;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory*)factory
nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type NS_UNAVAILABLE;
@end

View File

@ -18,19 +18,23 @@
@synthesize volume = _volume;
@synthesize nativeAudioSource = _nativeAudioSource;
- (instancetype)initWithNativeAudioSource:
(rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeAudioSource:
(rtc::scoped_refptr<webrtc::AudioSourceInterface>)nativeAudioSource {
RTC_DCHECK(factory);
RTC_DCHECK(nativeAudioSource);
if (self = [super initWithNativeMediaSource:nativeAudioSource
type:RTCMediaSourceTypeAudio]) {
if (self = [super initWithFactory:factory
nativeMediaSource:nativeAudioSource
type:RTCMediaSourceTypeAudio]) {
_nativeAudioSource = nativeAudioSource;
}
return self;
}
- (instancetype)initWithNativeMediaSource:
(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type {
RTC_NOTREACHED();
return nil;
}

View File

@ -31,18 +31,19 @@
std::string nativeId = [NSString stdStringForString:trackId];
rtc::scoped_refptr<webrtc::AudioTrackInterface> track =
factory.nativeFactory->CreateAudioTrack(nativeId, source.nativeAudioSource);
if (self = [self initWithNativeTrack:track type:RTCMediaStreamTrackTypeAudio]) {
if (self = [self initWithFactory:factory nativeTrack:track type:RTCMediaStreamTrackTypeAudio]) {
_source = source;
}
return self;
}
- (instancetype)initWithNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
type:(RTCMediaStreamTrackType)type {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
type:(RTCMediaStreamTrackType)type {
NSParameterAssert(factory);
NSParameterAssert(nativeTrack);
NSParameterAssert(type == RTCMediaStreamTrackTypeAudio);
return [super initWithNativeTrack:nativeTrack type:type];
return [super initWithFactory:factory nativeTrack:nativeTrack type:type];
}
@ -51,7 +52,8 @@
rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
self.nativeAudioTrack->GetSource();
if (source) {
_source = [[RTCAudioSource alloc] initWithNativeAudioSource:source.get()];
_source =
[[RTCAudioSource alloc] initWithFactory:self.factory nativeAudioSource:source.get()];
}
}
return _source;

View File

@ -14,6 +14,8 @@
NS_ASSUME_NONNULL_BEGIN
@class RTCPeerConnectionFactory;
typedef NS_ENUM(NSInteger, RTCMediaSourceType) {
RTCMediaSourceTypeAudio,
RTCMediaSourceTypeVideo,
@ -23,9 +25,9 @@ typedef NS_ENUM(NSInteger, RTCMediaSourceType) {
@property(nonatomic, readonly) rtc::scoped_refptr<webrtc::MediaSourceInterface> nativeMediaSource;
- (instancetype)initWithNativeMediaSource:
(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type NS_DESIGNATED_INITIALIZER;
+ (webrtc::MediaSourceInterface::SourceState)nativeSourceStateForState:(RTCSourceState)state;

View File

@ -13,16 +13,19 @@
#include "rtc_base/checks.h"
@implementation RTCMediaSource {
RTCPeerConnectionFactory *_factory;
RTCMediaSourceType _type;
}
@synthesize nativeMediaSource = _nativeMediaSource;
- (instancetype)initWithNativeMediaSource:
(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type {
RTC_DCHECK(factory);
RTC_DCHECK(nativeMediaSource);
if (self = [super init]) {
_factory = factory;
_nativeMediaSource = nativeMediaSource;
_type = type;
}

View File

@ -109,14 +109,14 @@
for (auto &track : audioTracks) {
RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeAudio;
RTCAudioTrack *audioTrack =
[[RTCAudioTrack alloc] initWithNativeTrack:track type:type];
[[RTCAudioTrack alloc] initWithFactory:_factory nativeTrack:track type:type];
[_audioTracks addObject:audioTrack];
}
for (auto &track : videoTracks) {
RTCMediaStreamTrackType type = RTCMediaStreamTrackTypeVideo;
RTCVideoTrack *videoTrack =
[[RTCVideoTrack alloc] initWithNativeTrack:track type:type];
[[RTCVideoTrack alloc] initWithFactory:_factory nativeTrack:track type:type];
[_videoTracks addObject:videoTrack];
}
}

View File

@ -19,8 +19,12 @@ typedef NS_ENUM(NSInteger, RTCMediaStreamTrackType) {
NS_ASSUME_NONNULL_BEGIN
@class RTCPeerConnectionFactory;
@interface RTCMediaStreamTrack ()
@property(nonatomic, readonly) RTCPeerConnectionFactory *factory;
/**
* The native MediaStreamTrackInterface passed in or created during
* construction.
@ -30,12 +34,12 @@ NS_ASSUME_NONNULL_BEGIN
/**
* Initialize an RTCMediaStreamTrack from a native MediaStreamTrackInterface.
*/
- (instancetype)initWithNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
type:(RTCMediaStreamTrackType)type NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
type:(RTCMediaStreamTrackType)type NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack;
- (BOOL)isEqualToTrack:(RTCMediaStreamTrack *)track;
@ -48,7 +52,8 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSString *)stringForState:(RTCMediaStreamTrackState)state;
+ (RTCMediaStreamTrack *)mediaTrackForNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack;
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
factory:(RTCPeerConnectionFactory *)factory;
@end

View File

@ -20,6 +20,7 @@ NSString * const kRTCMediaStreamTrackKindVideo =
@(webrtc::MediaStreamTrackInterface::kVideoKind);
@implementation RTCMediaStreamTrack {
RTCPeerConnectionFactory *_factory;
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> _nativeTrack;
RTCMediaStreamTrackType _type;
}
@ -73,29 +74,31 @@ NSString * const kRTCMediaStreamTrackKindVideo =
return _nativeTrack;
}
- (instancetype)initWithNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
type:(RTCMediaStreamTrackType)type {
@synthesize factory = _factory;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
type:(RTCMediaStreamTrackType)type {
NSParameterAssert(nativeTrack);
NSParameterAssert(factory);
if (self = [super init]) {
_factory = factory;
_nativeTrack = nativeTrack;
_type = type;
}
return self;
}
- (instancetype)initWithNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeTrack:(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack {
NSParameterAssert(nativeTrack);
if (nativeTrack->kind() ==
std::string(webrtc::MediaStreamTrackInterface::kAudioKind)) {
return [self initWithNativeTrack:nativeTrack
type:RTCMediaStreamTrackTypeAudio];
return [self initWithFactory:factory nativeTrack:nativeTrack type:RTCMediaStreamTrackTypeAudio];
}
if (nativeTrack->kind() ==
std::string(webrtc::MediaStreamTrackInterface::kVideoKind)) {
return [self initWithNativeTrack:nativeTrack
type:RTCMediaStreamTrackTypeVideo];
return [self initWithFactory:factory nativeTrack:nativeTrack type:RTCMediaStreamTrackTypeVideo];
}
return nil;
}
@ -137,16 +140,20 @@ NSString * const kRTCMediaStreamTrackKindVideo =
}
+ (RTCMediaStreamTrack *)mediaTrackForNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack {
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeTrack
factory:(RTCPeerConnectionFactory *)factory {
NSParameterAssert(nativeTrack);
NSParameterAssert(factory);
if (nativeTrack->kind() == webrtc::MediaStreamTrackInterface::kAudioKind) {
return
[[RTCAudioTrack alloc] initWithNativeTrack:nativeTrack type:RTCMediaStreamTrackTypeAudio];
return [[RTCAudioTrack alloc] initWithFactory:factory
nativeTrack:nativeTrack
type:RTCMediaStreamTrackTypeAudio];
} else if (nativeTrack->kind() == webrtc::MediaStreamTrackInterface::kVideoKind) {
return
[[RTCVideoTrack alloc] initWithNativeTrack:nativeTrack type:RTCMediaStreamTrackTypeVideo];
return [[RTCVideoTrack alloc] initWithFactory:factory
nativeTrack:nativeTrack
type:RTCMediaStreamTrackTypeVideo];
} else {
return [[RTCMediaStreamTrack alloc] initWithNativeTrack:nativeTrack];
return [[RTCMediaStreamTrack alloc] initWithFactory:factory nativeTrack:nativeTrack];
}
}

View File

@ -180,7 +180,7 @@
rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
_nativeFactory->CreateAudioSource(options);
return [[RTCAudioSource alloc] initWithNativeAudioSource:source];
return [[RTCAudioSource alloc] initWithFactory:self nativeAudioSource:source];
}
- (RTCAudioTrack *)audioTrackWithTrackId:(NSString *)trackId {
@ -196,8 +196,9 @@
}
- (RTCVideoSource *)videoSource {
return [[RTCVideoSource alloc] initWithSignalingThread:_signalingThread.get()
workerThread:_workerThread.get()];
return [[RTCVideoSource alloc] initWithFactory:self
signalingThread:_signalingThread.get()
workerThread:_workerThread.get()];
}
- (RTCVideoTrack *)videoTrackWithSource:(RTCVideoSource *)source

View File

@ -63,7 +63,7 @@ void RtpReceiverDelegateAdapter::OnFirstPacketReceived(
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack(
_nativeRtpReceiver->track());
if (nativeTrack) {
return [RTCMediaStreamTrack mediaTrackForNativeTrack:nativeTrack];
return [RTCMediaStreamTrack mediaTrackForNativeTrack:nativeTrack factory:_factory];
}
return nil;
}

View File

@ -45,7 +45,7 @@
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack(
_nativeRtpSender->track());
if (nativeTrack) {
return [RTCMediaStreamTrack mediaTrackForNativeTrack:nativeTrack];
return [RTCMediaStreamTrack mediaTrackForNativeTrack:nativeTrack factory:_factory];
}
return nil;
}

View File

@ -26,16 +26,18 @@ NS_ASSUME_NONNULL_BEGIN
nativeVideoSource;
/** Initialize an RTCVideoSource from a native VideoTrackSourceInterface. */
- (instancetype)initWithNativeVideoSource:
(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeVideoSource:
(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource
NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithNativeMediaSource:
(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type NS_UNAVAILABLE;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type NS_UNAVAILABLE;
- (instancetype)initWithSignalingThread:(rtc::Thread *)signalingThread
workerThread:(rtc::Thread *)workerThread;
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
signalingThread:(rtc::Thread *)signalingThread
workerThread:(rtc::Thread *)workerThread;
@end

View File

@ -28,30 +28,35 @@ static webrtc::ObjCVideoTrackSource *getObjCVideoSource(
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> _nativeVideoSource;
}
- (instancetype)initWithNativeVideoSource:
(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeVideoSource:
(rtc::scoped_refptr<webrtc::VideoTrackSourceInterface>)nativeVideoSource {
RTC_DCHECK(factory);
RTC_DCHECK(nativeVideoSource);
if (self = [super initWithNativeMediaSource:nativeVideoSource
type:RTCMediaSourceTypeVideo]) {
if (self = [super initWithFactory:factory
nativeMediaSource:nativeVideoSource
type:RTCMediaSourceTypeVideo]) {
_nativeVideoSource = nativeVideoSource;
}
return self;
}
- (instancetype)initWithNativeMediaSource:
(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeMediaSource:(rtc::scoped_refptr<webrtc::MediaSourceInterface>)nativeMediaSource
type:(RTCMediaSourceType)type {
RTC_NOTREACHED();
return nil;
}
- (instancetype)initWithSignalingThread:(rtc::Thread *)signalingThread
workerThread:(rtc::Thread *)workerThread {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
signalingThread:(rtc::Thread *)signalingThread
workerThread:(rtc::Thread *)workerThread {
rtc::scoped_refptr<webrtc::ObjCVideoTrackSource> objCVideoTrackSource(
new rtc::RefCountedObject<webrtc::ObjCVideoTrackSource>());
return [self initWithNativeVideoSource:webrtc::VideoTrackSourceProxy::Create(
signalingThread, workerThread, objCVideoTrackSource)];
return [self initWithFactory:factory
nativeVideoSource:webrtc::VideoTrackSourceProxy::Create(
signalingThread, workerThread, objCVideoTrackSource)];
}
- (NSString *)description {

View File

@ -32,18 +32,20 @@
rtc::scoped_refptr<webrtc::VideoTrackInterface> track =
factory.nativeFactory->CreateVideoTrack(nativeId,
source.nativeVideoSource);
if (self = [self initWithNativeTrack:track type:RTCMediaStreamTrackTypeVideo]) {
if (self = [self initWithFactory:factory nativeTrack:track type:RTCMediaStreamTrackTypeVideo]) {
_source = source;
}
return self;
}
- (instancetype)initWithNativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeMediaTrack
type:(RTCMediaStreamTrackType)type {
- (instancetype)initWithFactory:(RTCPeerConnectionFactory *)factory
nativeTrack:
(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)nativeMediaTrack
type:(RTCMediaStreamTrackType)type {
NSParameterAssert(factory);
NSParameterAssert(nativeMediaTrack);
NSParameterAssert(type == RTCMediaStreamTrackTypeVideo);
if (self = [super initWithNativeTrack:nativeMediaTrack type:type]) {
if (self = [super initWithFactory:factory nativeTrack:nativeMediaTrack type:type]) {
_adapters = [NSMutableArray array];
}
return self;
@ -60,7 +62,8 @@
rtc::scoped_refptr<webrtc::VideoTrackSourceInterface> source =
self.nativeVideoTrack->GetSource();
if (source) {
_source = [[RTCVideoSource alloc] initWithNativeVideoSource:source.get()];
_source =
[[RTCVideoSource alloc] initWithFactory:self.factory nativeVideoSource:source.get()];
}
}
return _source;

View File

@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#import <WebRTC/RTCAudioSource.h>
#import <WebRTC/RTCConfiguration.h>
#import <WebRTC/RTCDataChannel.h>
#import <WebRTC/RTCDataChannelConfiguration.h>
@ -18,6 +19,7 @@
#import <WebRTC/RTCRtpReceiver.h>
#import <WebRTC/RTCRtpSender.h>
#import <WebRTC/RTCRtpTransceiver.h>
#import <WebRTC/RTCVideoSource.h>
#import <XCTest/XCTest.h>
@ -193,6 +195,74 @@
XCTAssertTrue(true, "Expect test does not crash");
}
- (void)testAudioSourceLifetime {
@autoreleasepool {
RTCPeerConnectionFactory *factory;
RTCAudioSource *audioSource;
@autoreleasepool {
factory = [[RTCPeerConnectionFactory alloc] init];
audioSource = [factory audioSourceWithConstraints:nil];
XCTAssertNotNil(audioSource);
factory = nil;
}
audioSource = nil;
}
XCTAssertTrue(true, "Expect test does not crash");
}
- (void)testVideoSourceLifetime {
@autoreleasepool {
RTCPeerConnectionFactory *factory;
RTCVideoSource *videoSource;
@autoreleasepool {
factory = [[RTCPeerConnectionFactory alloc] init];
videoSource = [factory videoSource];
XCTAssertNotNil(videoSource);
factory = nil;
}
videoSource = nil;
}
XCTAssertTrue(true, "Expect test does not crash");
}
- (void)testAudioTrackLifetime {
@autoreleasepool {
RTCPeerConnectionFactory *factory;
RTCAudioTrack *audioTrack;
@autoreleasepool {
factory = [[RTCPeerConnectionFactory alloc] init];
audioTrack = [factory audioTrackWithTrackId:@"audioTrack"];
XCTAssertNotNil(audioTrack);
factory = nil;
}
audioTrack = nil;
}
XCTAssertTrue(true, "Expect test does not crash");
}
- (void)testVideoTrackLifetime {
@autoreleasepool {
RTCPeerConnectionFactory *factory;
RTCVideoTrack *videoTrack;
@autoreleasepool {
factory = [[RTCPeerConnectionFactory alloc] init];
videoTrack = [factory videoTrackWithSource:[factory videoSource] trackId:@"videoTrack"];
XCTAssertNotNil(videoTrack);
factory = nil;
}
videoTrack = nil;
}
XCTAssertTrue(true, "Expect test does not crash");
}
- (bool)negotiatePeerConnection:(RTCPeerConnection *)pc1
withPeerConnection:(RTCPeerConnection *)pc2
negotiationTimeout:(NSTimeInterval)timeout {