How to implement custom frame encryptor in Android?

129 views
Skip to first unread message

Ivan Hutomo

unread,
Jul 29, 2022, 2:14:21 AM7/29/22
to discuss-webrtc
Hi, I tried to implement FakeFrameEncryptor in webrtc android based on the example from rtp_sender_receiver_unittest.cc? I tried to implement it in peer_connection.cc as shown below:

RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
PeerConnection::AddTransceiver(
cricket::MediaType media_type,
rtc::scoped_refptr<MediaStreamTrackInterface> track,
const RtpTransceiverInit& init,
bool update_negotiation_needed) {
RTC_DCHECK_RUN_ON(signaling_thread());
RTC_DCHECK((media_type == cricket::MEDIA_TYPE_AUDIO ||
media_type == cricket::MEDIA_TYPE_VIDEO));
if (track) {
RTC_DCHECK_EQ(media_type,
(track->kind() == MediaStreamTrackInterface::kAudioKind
? cricket::MEDIA_TYPE_AUDIO
: cricket::MEDIA_TYPE_VIDEO));
}

RTC_HISTOGRAM_COUNTS_LINEAR(kSimulcastNumberOfEncodings,
init.send_encodings.size(), 0, 7, 8);

size_t num_rids = absl::c_count_if(init.send_encodings,
[](const RtpEncodingParameters& encoding) {
return !encoding.rid.empty();
});
if (num_rids > 0 && num_rids != init.send_encodings.size()) {
LOG_AND_RETURN_ERROR(
RTCErrorType::INVALID_PARAMETER,
"RIDs must be provided for either all or none of the send encodings.");
}

if (num_rids > 0 && absl::c_any_of(init.send_encodings,
[](const RtpEncodingParameters& encoding) {
return !IsLegalRsidName(encoding.rid);
})) {
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
"Invalid RID value provided.");
}

if (absl::c_any_of(init.send_encodings,
[](const RtpEncodingParameters& encoding) {
return encoding.ssrc.has_value();
})) {
LOG_AND_RETURN_ERROR(
RTCErrorType::UNSUPPORTED_PARAMETER,
"Attempted to set an unimplemented parameter of RtpParameters.");
}

RtpParameters parameters;
parameters.encodings = init.send_encodings;

// Encodings are dropped from the tail if too many are provided.
size_t max_simulcast_streams =
media_type == cricket::MEDIA_TYPE_VIDEO ? kMaxSimulcastStreams : 1u;
if (parameters.encodings.size() > max_simulcast_streams) {
parameters.encodings.erase(
parameters.encodings.begin() + max_simulcast_streams,
parameters.encodings.end());
}

// Single RID should be removed.
if (parameters.encodings.size() == 1 &&
!parameters.encodings[0].rid.empty()) {
RTC_LOG(LS_INFO) << "Removing RID: " << parameters.encodings[0].rid << ".";
parameters.encodings[0].rid.clear();
}

// If RIDs were not provided, they are generated for simulcast scenario.
if (parameters.encodings.size() > 1 && num_rids == 0) {
rtc::UniqueStringGenerator rid_generator;
for (RtpEncodingParameters& encoding : parameters.encodings) {
encoding.rid = rid_generator();
}
}

if (UnimplementedRtpParameterHasValue(parameters)) {
LOG_AND_RETURN_ERROR(
RTCErrorType::UNSUPPORTED_PARAMETER,
"Attempted to set an unimplemented parameter of RtpParameters.");
}

auto result = cricket::CheckRtpParametersValues(parameters);
if (!result.ok()) {
LOG_AND_RETURN_ERROR(result.type(), result.message());
}

RTC_LOG(LS_INFO) << "Adding " << cricket::MediaTypeToString(media_type)
<< " transceiver in response to a call to AddTransceiver.";
// Set the sender ID equal to the track ID if the track is specified unless
// that sender ID is already in use.

// Add by Ivan to new frame encryptor interface
rtc::scoped_refptr<FrameEncryptorInterface> fake_frame_encryptor(
new FakeFrameEncryptor());

std::string sender_id = (track && !rtp_manager()->FindSenderById(track->id())
? track->id()
: rtc::CreateRandomUuid());
auto sender = rtp_manager()->CreateSender(
media_type, sender_id, track, init.stream_ids, parameters.encodings);

// Add by Ivan: add a fake frame encryptor to the sender.
sender->SetFrameEncryptor(fake_frame_encryptor);

auto receiver =
rtp_manager()->CreateReceiver(media_type, rtc::CreateRandomUuid());
auto transceiver = rtp_manager()->CreateAndAddTransceiver(sender, receiver);
transceiver->internal()->set_direction(init.direction);

if (update_negotiation_needed) {
sdp_handler_->UpdateNegotiationNeeded();
}

return rtc::scoped_refptr<RtpTransceiverInterface>(transceiver);
}

I already put
#include "api/test/fake_frame_decryptor.h"
#include "api/test/fake_frame_encryptor.h"

and

#include "api/crypto/frame_decryptor_interface.h"
#include "api/crypto/frame_encryptor_interface.h"

Actually, I am new to C++ so I am not really familiar with it, Maybe anyone who already implements a custom frame encryptor in webrtc android could give me some clue or help.

Really appreciate any help

Best Regards,
Ivan

Ivan Hutomo

unread,
Jul 31, 2022, 3:43:19 AM7/31/22
to discuss-webrtc
Hello everyone just wants to follow up on this question again. How is the correct way to use this frame encryptor in Android, does my approach still wrong? Do I need to implement this in Java directly? Thanks in advance
Reply all
Reply to author
Forward
0 new messages