Skip to content

Commit

Permalink
Improvements to RTCFrameCryptor (#123)
Browse files Browse the repository at this point in the history
### Improvements

* nil checks
* Thread safety 
* Fix typo for `RTCCryptorAlgorithm`

### Breaking changes

* `RTCCyrptorAlgorithm` renamed to `RTCCryptorAlgorithm`
* Initialization of RTCFrameCryptor could return nil.
  • Loading branch information
hiroshihorie authored Jun 5, 2024
1 parent 66fd81b commit dac8015
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 66 deletions.
28 changes: 14 additions & 14 deletions sdk/objc/api/peerconnection/RTCFrameCryptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ NS_ASSUME_NONNULL_BEGIN
@class RTC_OBJC_TYPE(RTCFrameCryptor);
@class RTC_OBJC_TYPE(RTCPeerConnectionFactory);

typedef NS_ENUM(NSUInteger, RTCCyrptorAlgorithm) {
RTCCyrptorAlgorithmAesGcm = 0,
RTCCyrptorAlgorithmAesCbc,
typedef NS_ENUM(NSUInteger, RTCCryptorAlgorithm) {
RTCCryptorAlgorithmAesGcm = 0,
RTCCryptorAlgorithmAesCbc,
};

typedef NS_ENUM(NSInteger, FrameCryptionState) {
Expand Down Expand Up @@ -61,17 +61,17 @@ RTC_OBJC_EXPORT

@property(nonatomic, weak, nullable) id<RTC_OBJC_TYPE(RTCFrameCryptorDelegate)> delegate;

- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpSender:(RTC_OBJC_TYPE(RTCRtpSender) *)sender
participantId:(NSString *)participantId
algorithm:(RTCCyrptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider;

- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver
participantId:(NSString *)participantId
algorithm:(RTCCyrptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider;
- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpSender:(RTC_OBJC_TYPE(RTCRtpSender) *)sender
participantId:(NSString *)participantId
algorithm:(RTCCryptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider;

- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver
participantId:(NSString *)participantId
algorithm:(RTCCryptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider;

@end

Expand Down
141 changes: 89 additions & 52 deletions sdk/objc/api/peerconnection/RTCFrameCryptor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@

#import "RTCFrameCryptor+Private.h"
#import "RTCFrameCryptorKeyProvider+Private.h"
#import "RTCPeerConnectionFactory+Private.h"
#import "RTCRtpReceiver+Private.h"
#import "RTCRtpSender+Private.h"
#import "RTCPeerConnectionFactory+Private.h"

#import <os/lock.h>
#include <memory>

#import "base/RTCLogging.h"
Expand Down Expand Up @@ -93,95 +94,131 @@
@implementation RTC_OBJC_TYPE (RTCFrameCryptor) {
const webrtc::RtpSenderInterface *_sender;
const webrtc::RtpReceiverInterface *_receiver;
NSString *_participantId;
rtc::scoped_refptr<webrtc::FrameCryptorTransformer> frame_crypto_transformer_;
rtc::scoped_refptr<webrtc::FrameCryptorTransformer> _frame_crypto_transformer;
rtc::scoped_refptr<webrtc::RTCFrameCryptorDelegateAdapter> _observer;
os_unfair_lock _lock;
}

@synthesize participantId = _participantId;
@synthesize delegate = _delegate;

- (webrtc::FrameCryptorTransformer::Algorithm)algorithmFromEnum:(RTCCyrptorAlgorithm)algorithm {
- (webrtc::FrameCryptorTransformer::Algorithm)algorithmFromEnum:(RTCCryptorAlgorithm)algorithm {
switch (algorithm) {
case RTCCyrptorAlgorithmAesGcm:
case RTCCryptorAlgorithmAesGcm:
return webrtc::FrameCryptorTransformer::Algorithm::kAesGcm;
case RTCCyrptorAlgorithmAesCbc:
case RTCCryptorAlgorithmAesCbc:
return webrtc::FrameCryptorTransformer::Algorithm::kAesCbc;
default:
return webrtc::FrameCryptorTransformer::Algorithm::kAesGcm;
}
}

- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpSender:(RTC_OBJC_TYPE(RTCRtpSender) *)sender
participantId:(NSString *)participantId
algorithm:(RTCCyrptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider {
- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpSender:(RTC_OBJC_TYPE(RTCRtpSender) *)sender
participantId:(NSString *)participantId
algorithm:(RTCCryptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider {
if (self = [super init]) {
_lock = OS_UNFAIR_LOCK_INIT;

rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeRtpSender = sender.nativeRtpSender;
if (nativeRtpSender == nullptr) return nil;

rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack = nativeRtpSender->track();
if (nativeTrack == nullptr) return nil;

_observer = rtc::make_ref_counted<webrtc::RTCFrameCryptorDelegateAdapter>(self);
_participantId = participantId;
auto rtpSender = sender.nativeRtpSender;
auto mediaType = rtpSender->track()->kind() == "audio" ?
webrtc::FrameCryptorTransformer::MediaType::kAudioFrame :
webrtc::FrameCryptorTransformer::MediaType::kVideoFrame;
frame_crypto_transformer_ = rtc::scoped_refptr<webrtc::FrameCryptorTransformer>(
new webrtc::FrameCryptorTransformer(factory.signalingThread,
[participantId stdString],
mediaType,
[self algorithmFromEnum:algorithm],
keyProvider.nativeKeyProvider));

rtpSender->SetEncoderToPacketizerFrameTransformer(frame_crypto_transformer_);
frame_crypto_transformer_->SetEnabled(false);
frame_crypto_transformer_->RegisterFrameCryptorTransformerObserver(_observer);

webrtc::FrameCryptorTransformer::MediaType mediaType =
nativeTrack->kind() == "audio" ? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame
: webrtc::FrameCryptorTransformer::MediaType::kVideoFrame;

_frame_crypto_transformer =
rtc::scoped_refptr<webrtc::FrameCryptorTransformer>(new webrtc::FrameCryptorTransformer(
factory.signalingThread, [participantId stdString], mediaType,
[self algorithmFromEnum:algorithm], keyProvider.nativeKeyProvider));

nativeRtpSender->SetEncoderToPacketizerFrameTransformer(_frame_crypto_transformer);
_frame_crypto_transformer->SetEnabled(false);
_frame_crypto_transformer->RegisterFrameCryptorTransformerObserver(_observer);
}

return self;
}

- (instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver
participantId:(NSString *)participantId
algorithm:(RTCCyrptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider {
- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
rtpReceiver:(RTC_OBJC_TYPE(RTCRtpReceiver) *)receiver
participantId:(NSString *)participantId
algorithm:(RTCCryptorAlgorithm)algorithm
keyProvider:(RTC_OBJC_TYPE(RTCFrameCryptorKeyProvider) *)keyProvider {
if (self = [super init]) {
_lock = OS_UNFAIR_LOCK_INIT;

rtc::scoped_refptr<webrtc::RtpReceiverInterface> nativeRtpReceiver = receiver.nativeRtpReceiver;
if (nativeRtpReceiver == nullptr) return nil;

rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> nativeTrack = nativeRtpReceiver->track();
if (nativeTrack == nullptr) return nil;

_observer = rtc::make_ref_counted<webrtc::RTCFrameCryptorDelegateAdapter>(self);
_participantId = participantId;
auto rtpReceiver = receiver.nativeRtpReceiver;
auto mediaType = rtpReceiver->track()->kind() == "audio" ?
webrtc::FrameCryptorTransformer::MediaType::kAudioFrame :
webrtc::FrameCryptorTransformer::MediaType::kVideoFrame;
frame_crypto_transformer_ = rtc::scoped_refptr<webrtc::FrameCryptorTransformer>(
new webrtc::FrameCryptorTransformer(factory.signalingThread,
[participantId stdString],
mediaType,
[self algorithmFromEnum:algorithm],
keyProvider.nativeKeyProvider));

rtpReceiver->SetDepacketizerToDecoderFrameTransformer(frame_crypto_transformer_);
frame_crypto_transformer_->SetEnabled(false);
frame_crypto_transformer_->RegisterFrameCryptorTransformerObserver(_observer);

webrtc::FrameCryptorTransformer::MediaType mediaType =
nativeTrack->kind() == "audio" ? webrtc::FrameCryptorTransformer::MediaType::kAudioFrame
: webrtc::FrameCryptorTransformer::MediaType::kVideoFrame;

_frame_crypto_transformer =
rtc::scoped_refptr<webrtc::FrameCryptorTransformer>(new webrtc::FrameCryptorTransformer(
factory.signalingThread, [participantId stdString], mediaType,
[self algorithmFromEnum:algorithm], keyProvider.nativeKeyProvider));

nativeRtpReceiver->SetDepacketizerToDecoderFrameTransformer(_frame_crypto_transformer);
_frame_crypto_transformer->SetEnabled(false);
_frame_crypto_transformer->RegisterFrameCryptorTransformerObserver(_observer);
}

return self;
}

- (void)dealloc {
os_unfair_lock_lock(&_lock);
if (_frame_crypto_transformer != nullptr) {
_frame_crypto_transformer->UnRegisterFrameCryptorTransformerObserver();
_frame_crypto_transformer = nullptr;
}
_observer = nullptr;
os_unfair_lock_unlock(&_lock);
}

- (BOOL)enabled {
return frame_crypto_transformer_->enabled();
os_unfair_lock_lock(&_lock);
BOOL result = _frame_crypto_transformer != nullptr ? _frame_crypto_transformer->enabled() : NO;
os_unfair_lock_unlock(&_lock);
return result;
}

- (void)setEnabled:(BOOL)enabled {
frame_crypto_transformer_->SetEnabled(enabled);
os_unfair_lock_lock(&_lock);
if (_frame_crypto_transformer != nullptr) {
_frame_crypto_transformer->SetEnabled(enabled);
}
os_unfair_lock_unlock(&_lock);
}

- (int)keyIndex {
return frame_crypto_transformer_->key_index();
os_unfair_lock_lock(&_lock);
int result = _frame_crypto_transformer != nullptr ? _frame_crypto_transformer->key_index() : 0;
os_unfair_lock_unlock(&_lock);
return result;
}

- (void)setKeyIndex:(int)keyIndex {
frame_crypto_transformer_->SetKeyIndex(keyIndex);
}

- (void)dealloc {
frame_crypto_transformer_->UnRegisterFrameCryptorTransformerObserver();
os_unfair_lock_lock(&_lock);
if (_frame_crypto_transformer != nullptr) {
_frame_crypto_transformer->SetKeyIndex(keyIndex);
}
os_unfair_lock_unlock(&_lock);
}

@end

0 comments on commit dac8015

Please sign in to comment.