Make CreateSendChannel and CreateReceiveChannel methods pure virtual
These methods previously had a default implementation that triggered a crash. All implementations must now return a valid object, which simplifies the code that calls them. Bug: webrtc:13931 Change-Id: I877fbc929b58c6b83767c6ac5a81c8aa942e3fef Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/369021 Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43453}
This commit is contained in:
parent
d171832b6c
commit
98b3588974
@ -534,7 +534,7 @@ bool FakeVideoMediaReceiveChannel::GetStats(VideoMediaReceiveInfo* /* info */) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FakeVoiceEngine::FakeVoiceEngine() : fail_create_channel_(false) {
|
FakeVoiceEngine::FakeVoiceEngine() {
|
||||||
// Add a fake audio codec. Note that the name must not be "" as there are
|
// Add a fake audio codec. Note that the name must not be "" as there are
|
||||||
// sanity checks against that.
|
// sanity checks against that.
|
||||||
SetCodecs({cricket::CreateAudioCodec(101, "fake_audio_codec", 8000, 1)});
|
SetCodecs({cricket::CreateAudioCodec(101, "fake_audio_codec", 8000, 1)});
|
||||||
@ -606,8 +606,7 @@ void FakeVoiceEngine::SetRtpHeaderExtensions(
|
|||||||
header_extensions_ = std::move(header_extensions);
|
header_extensions_ = std::move(header_extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
FakeVideoEngine::FakeVideoEngine()
|
FakeVideoEngine::FakeVideoEngine() : capture_(false) {
|
||||||
: capture_(false), fail_create_channel_(false) {
|
|
||||||
// Add a fake video codec. Note that the name must not be "" as there are
|
// Add a fake video codec. Note that the name must not be "" as there are
|
||||||
// sanity checks against that.
|
// sanity checks against that.
|
||||||
send_codecs_.push_back(cricket::CreateVideoCodec(111, "fake_video_codec"));
|
send_codecs_.push_back(cricket::CreateVideoCodec(111, "fake_video_codec"));
|
||||||
@ -625,10 +624,6 @@ FakeVideoEngine::CreateSendChannel(
|
|||||||
const webrtc::CryptoOptions& /* crypto_options */,
|
const webrtc::CryptoOptions& /* crypto_options */,
|
||||||
webrtc::
|
webrtc::
|
||||||
VideoBitrateAllocatorFactory* /* video_bitrate_allocator_factory */) {
|
VideoBitrateAllocatorFactory* /* video_bitrate_allocator_factory */) {
|
||||||
if (fail_create_channel_) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<FakeVideoMediaSendChannel> ch =
|
std::unique_ptr<FakeVideoMediaSendChannel> ch =
|
||||||
std::make_unique<FakeVideoMediaSendChannel>(options,
|
std::make_unique<FakeVideoMediaSendChannel>(options,
|
||||||
call->network_thread());
|
call->network_thread());
|
||||||
@ -640,10 +635,6 @@ FakeVideoEngine::CreateReceiveChannel(
|
|||||||
const MediaConfig& /* config */,
|
const MediaConfig& /* config */,
|
||||||
const VideoOptions& options,
|
const VideoOptions& options,
|
||||||
const webrtc::CryptoOptions& /* crypto_options */) {
|
const webrtc::CryptoOptions& /* crypto_options */) {
|
||||||
if (fail_create_channel_) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<FakeVideoMediaReceiveChannel> ch =
|
std::unique_ptr<FakeVideoMediaReceiveChannel> ch =
|
||||||
std::make_unique<FakeVideoMediaReceiveChannel>(options,
|
std::make_unique<FakeVideoMediaReceiveChannel>(options,
|
||||||
call->network_thread());
|
call->network_thread());
|
||||||
@ -697,9 +688,5 @@ void FakeMediaEngine::SetVideoCodecs(const std::vector<Codec>& codecs) {
|
|||||||
video_->SetSendCodecs(codecs);
|
video_->SetSendCodecs(codecs);
|
||||||
video_->SetRecvCodecs(codecs);
|
video_->SetRecvCodecs(codecs);
|
||||||
}
|
}
|
||||||
void FakeMediaEngine::set_fail_create_channel(bool fail) {
|
|
||||||
voice_->fail_create_channel_ = fail;
|
|
||||||
video_->fail_create_channel_ = fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace cricket
|
} // namespace cricket
|
||||||
|
|||||||
@ -805,7 +805,6 @@ class FakeVoiceEngine : public VoiceEngineInterface {
|
|||||||
private:
|
private:
|
||||||
std::vector<Codec> recv_codecs_;
|
std::vector<Codec> recv_codecs_;
|
||||||
std::vector<Codec> send_codecs_;
|
std::vector<Codec> send_codecs_;
|
||||||
bool fail_create_channel_;
|
|
||||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions_;
|
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions_;
|
||||||
|
|
||||||
friend class FakeMediaEngine;
|
friend class FakeMediaEngine;
|
||||||
@ -847,7 +846,6 @@ class FakeVideoEngine : public VideoEngineInterface {
|
|||||||
std::vector<Codec> recv_codecs_;
|
std::vector<Codec> recv_codecs_;
|
||||||
bool capture_;
|
bool capture_;
|
||||||
VideoOptions options_;
|
VideoOptions options_;
|
||||||
bool fail_create_channel_;
|
|
||||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions_;
|
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions_;
|
||||||
|
|
||||||
friend class FakeMediaEngine;
|
friend class FakeMediaEngine;
|
||||||
@ -864,8 +862,6 @@ class FakeMediaEngine : public CompositeMediaEngine {
|
|||||||
void SetAudioSendCodecs(const std::vector<Codec>& codecs);
|
void SetAudioSendCodecs(const std::vector<Codec>& codecs);
|
||||||
void SetVideoCodecs(const std::vector<Codec>& codecs);
|
void SetVideoCodecs(const std::vector<Codec>& codecs);
|
||||||
|
|
||||||
void set_fail_create_channel(bool fail);
|
|
||||||
|
|
||||||
FakeVoiceEngine* fake_voice_engine() { return voice_; }
|
FakeVoiceEngine* fake_voice_engine() { return voice_; }
|
||||||
FakeVideoEngine* fake_video_engine() { return video_; }
|
FakeVideoEngine* fake_video_engine() { return video_; }
|
||||||
|
|
||||||
|
|||||||
@ -109,22 +109,14 @@ class VoiceEngineInterface : public RtpHeaderExtensionQueryInterface {
|
|||||||
const MediaConfig& /* config */,
|
const MediaConfig& /* config */,
|
||||||
const AudioOptions& /* options */,
|
const AudioOptions& /* options */,
|
||||||
const webrtc::CryptoOptions& /* crypto_options */,
|
const webrtc::CryptoOptions& /* crypto_options */,
|
||||||
webrtc::AudioCodecPairId /* codec_pair_id */) {
|
webrtc::AudioCodecPairId /* codec_pair_id */) = 0;
|
||||||
// TODO(hta): Make pure virtual when all downstream has updated
|
|
||||||
RTC_CHECK_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::unique_ptr<VoiceMediaReceiveChannelInterface>
|
virtual std::unique_ptr<VoiceMediaReceiveChannelInterface>
|
||||||
CreateReceiveChannel(webrtc::Call* /* call */,
|
CreateReceiveChannel(webrtc::Call* /* call */,
|
||||||
const MediaConfig& /* config */,
|
const MediaConfig& /* config */,
|
||||||
const AudioOptions& /* options */,
|
const AudioOptions& /* options */,
|
||||||
const webrtc::CryptoOptions& /* crypto_options */,
|
const webrtc::CryptoOptions& /* crypto_options */,
|
||||||
webrtc::AudioCodecPairId /* codec_pair_id */) {
|
webrtc::AudioCodecPairId /* codec_pair_id */) = 0;
|
||||||
// TODO(hta): Make pure virtual when all downstream has updated
|
|
||||||
RTC_CHECK_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy: Retrieve list of supported codecs.
|
// Legacy: Retrieve list of supported codecs.
|
||||||
// + protection codecs, and assigns PT numbers that may have to be
|
// + protection codecs, and assigns PT numbers that may have to be
|
||||||
@ -159,22 +151,14 @@ class VideoEngineInterface : public RtpHeaderExtensionQueryInterface {
|
|||||||
const MediaConfig& /* config */,
|
const MediaConfig& /* config */,
|
||||||
const VideoOptions& /* options */,
|
const VideoOptions& /* options */,
|
||||||
const webrtc::CryptoOptions& /* crypto_options */,
|
const webrtc::CryptoOptions& /* crypto_options */,
|
||||||
webrtc::
|
webrtc::VideoBitrateAllocatorFactory*
|
||||||
VideoBitrateAllocatorFactory* /* video_bitrate_allocator_factory */) {
|
/* video_bitrate_allocator_factory */) = 0;
|
||||||
// Default implementation, delete when all is updated
|
|
||||||
RTC_CHECK_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::unique_ptr<VideoMediaReceiveChannelInterface>
|
virtual std::unique_ptr<VideoMediaReceiveChannelInterface>
|
||||||
CreateReceiveChannel(webrtc::Call* /* call */,
|
CreateReceiveChannel(webrtc::Call* /* call */,
|
||||||
const MediaConfig& /* config */,
|
const MediaConfig& /* config */,
|
||||||
const VideoOptions& /* options */,
|
const VideoOptions& /* options */,
|
||||||
const webrtc::CryptoOptions& /* crypto_options */) {
|
const webrtc::CryptoOptions& /* crypto_options */) = 0;
|
||||||
// Default implementation, delete when all is updated
|
|
||||||
RTC_CHECK_NOTREACHED();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy: Retrieve list of supported codecs.
|
// Legacy: Retrieve list of supported codecs.
|
||||||
// + protection codecs, and assigns PT numbers that may have to be
|
// + protection codecs, and assigns PT numbers that may have to be
|
||||||
|
|||||||
@ -278,29 +278,6 @@ class PeerConnectionMediaTestPlanB : public PeerConnectionMediaBaseTest {
|
|||||||
: PeerConnectionMediaBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
|
: PeerConnectionMediaBaseTest(SdpSemantics::kPlanB_DEPRECATED) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(PeerConnectionMediaTest,
|
|
||||||
FailToSetRemoteDescriptionIfCreateMediaChannelFails) {
|
|
||||||
auto caller = CreatePeerConnectionWithAudioVideo();
|
|
||||||
auto callee = CreatePeerConnectionWithAudioVideo();
|
|
||||||
callee->media_engine()->set_fail_create_channel(true);
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
ASSERT_FALSE(callee->SetRemoteDescription(caller->CreateOffer(), &error));
|
|
||||||
EXPECT_THAT(error,
|
|
||||||
HasSubstr("Failed to set remote offer sdp: Failed to create"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(PeerConnectionMediaTest,
|
|
||||||
FailToSetLocalDescriptionIfCreateMediaChannelFails) {
|
|
||||||
auto caller = CreatePeerConnectionWithAudioVideo();
|
|
||||||
caller->media_engine()->set_fail_create_channel(true);
|
|
||||||
|
|
||||||
std::string error;
|
|
||||||
ASSERT_FALSE(caller->SetLocalDescription(caller->CreateOffer(), &error));
|
|
||||||
EXPECT_THAT(error,
|
|
||||||
HasSubstr("Failed to set local offer sdp: Failed to create"));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> GetIds(
|
std::vector<std::string> GetIds(
|
||||||
const std::vector<cricket::StreamParams>& streams) {
|
const std::vector<cricket::StreamParams>& streams) {
|
||||||
std::vector<std::string> ids;
|
std::vector<std::string> ids;
|
||||||
|
|||||||
@ -135,6 +135,7 @@ RtpTransceiver::RtpTransceiver(cricket::MediaType media_type,
|
|||||||
context_(context) {
|
context_(context) {
|
||||||
RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO ||
|
RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO ||
|
||||||
media_type == cricket::MEDIA_TYPE_VIDEO);
|
media_type == cricket::MEDIA_TYPE_VIDEO);
|
||||||
|
RTC_DCHECK(context_);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpTransceiver::RtpTransceiver(
|
RtpTransceiver::RtpTransceiver(
|
||||||
@ -151,6 +152,7 @@ RtpTransceiver::RtpTransceiver(
|
|||||||
header_extensions_to_negotiate_(
|
header_extensions_to_negotiate_(
|
||||||
std::move(header_extensions_to_negotiate)),
|
std::move(header_extensions_to_negotiate)),
|
||||||
on_negotiation_needed_(std::move(on_negotiation_needed)) {
|
on_negotiation_needed_(std::move(on_negotiation_needed)) {
|
||||||
|
RTC_DCHECK(context_);
|
||||||
RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO ||
|
RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO ||
|
||||||
media_type_ == cricket::MEDIA_TYPE_VIDEO);
|
media_type_ == cricket::MEDIA_TYPE_VIDEO);
|
||||||
RTC_DCHECK_EQ(sender->media_type(), receiver->media_type());
|
RTC_DCHECK_EQ(sender->media_type(), receiver->media_type());
|
||||||
@ -214,18 +216,20 @@ RTCError RtpTransceiver::CreateChannel(
|
|||||||
VideoBitrateAllocatorFactory* video_bitrate_allocator_factory,
|
VideoBitrateAllocatorFactory* video_bitrate_allocator_factory,
|
||||||
std::function<RtpTransportInternal*(absl::string_view)> transport_lookup) {
|
std::function<RtpTransportInternal*(absl::string_view)> transport_lookup) {
|
||||||
RTC_DCHECK_RUN_ON(thread_);
|
RTC_DCHECK_RUN_ON(thread_);
|
||||||
|
RTC_DCHECK(!channel());
|
||||||
|
|
||||||
if (!media_engine()) {
|
if (!media_engine()) {
|
||||||
// TODO(hta): Must be a better way
|
// TODO(hta): Must be a better way
|
||||||
return RTCError(RTCErrorType::INTERNAL_ERROR,
|
return RTCError(RTCErrorType::INTERNAL_ERROR,
|
||||||
"No media engine for mid=" + std::string(mid));
|
"No media engine for mid=" + std::string(mid));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<cricket::ChannelInterface> new_channel;
|
std::unique_ptr<cricket::ChannelInterface> new_channel;
|
||||||
if (media_type() == cricket::MEDIA_TYPE_AUDIO) {
|
if (media_type() == cricket::MEDIA_TYPE_AUDIO) {
|
||||||
// TODO(bugs.webrtc.org/11992): CreateVideoChannel internally switches to
|
// TODO(bugs.webrtc.org/11992): CreateVideoChannel internally switches to
|
||||||
// the worker thread. We shouldn't be using the `call_ptr_` hack here but
|
// the worker thread. We shouldn't be using the `call_ptr_` hack here but
|
||||||
// simply be on the worker thread and use `call_` (update upstream code).
|
// simply be on the worker thread and use `call_` (update upstream code).
|
||||||
RTC_DCHECK(call_ptr);
|
RTC_DCHECK(call_ptr);
|
||||||
RTC_DCHECK(media_engine());
|
|
||||||
// TODO(bugs.webrtc.org/11992): Remove this workaround after updates in
|
// TODO(bugs.webrtc.org/11992): Remove this workaround after updates in
|
||||||
// PeerConnection and add the expectation that we're already on the right
|
// PeerConnection and add the expectation that we're already on the right
|
||||||
// thread.
|
// thread.
|
||||||
@ -238,17 +242,10 @@ RTCError RtpTransceiver::CreateChannel(
|
|||||||
media_send_channel = media_engine()->voice().CreateSendChannel(
|
media_send_channel = media_engine()->voice().CreateSendChannel(
|
||||||
call_ptr, media_config, audio_options, crypto_options,
|
call_ptr, media_config, audio_options, crypto_options,
|
||||||
codec_pair_id);
|
codec_pair_id);
|
||||||
if (!media_send_channel) {
|
|
||||||
// TODO(bugs.webrtc.org/14912): Consider CHECK or reporting failure
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::unique_ptr<cricket::VoiceMediaReceiveChannelInterface>
|
std::unique_ptr<cricket::VoiceMediaReceiveChannelInterface>
|
||||||
media_receive_channel = media_engine()->voice().CreateReceiveChannel(
|
media_receive_channel = media_engine()->voice().CreateReceiveChannel(
|
||||||
call_ptr, media_config, audio_options, crypto_options,
|
call_ptr, media_config, audio_options, crypto_options,
|
||||||
codec_pair_id);
|
codec_pair_id);
|
||||||
if (!media_receive_channel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Note that this is safe because both sending and
|
// Note that this is safe because both sending and
|
||||||
// receiving channels will be deleted at the same time.
|
// receiving channels will be deleted at the same time.
|
||||||
media_send_channel->SetSsrcListChangedCallback(
|
media_send_channel->SetSsrcListChangedCallback(
|
||||||
@ -276,16 +273,9 @@ RTCError RtpTransceiver::CreateChannel(
|
|||||||
media_send_channel = media_engine()->video().CreateSendChannel(
|
media_send_channel = media_engine()->video().CreateSendChannel(
|
||||||
call_ptr, media_config, video_options, crypto_options,
|
call_ptr, media_config, video_options, crypto_options,
|
||||||
video_bitrate_allocator_factory);
|
video_bitrate_allocator_factory);
|
||||||
if (!media_send_channel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<cricket::VideoMediaReceiveChannelInterface>
|
std::unique_ptr<cricket::VideoMediaReceiveChannelInterface>
|
||||||
media_receive_channel = media_engine()->video().CreateReceiveChannel(
|
media_receive_channel = media_engine()->video().CreateReceiveChannel(
|
||||||
call_ptr, media_config, video_options, crypto_options);
|
call_ptr, media_config, video_options, crypto_options);
|
||||||
if (!media_receive_channel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Note that this is safe because both sending and
|
// Note that this is safe because both sending and
|
||||||
// receiving channels will be deleted at the same time.
|
// receiving channels will be deleted at the same time.
|
||||||
media_send_channel->SetSsrcListChangedCallback(
|
media_send_channel->SetSsrcListChangedCallback(
|
||||||
@ -301,11 +291,6 @@ RTCError RtpTransceiver::CreateChannel(
|
|||||||
context()->ssrc_generator());
|
context()->ssrc_generator());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!new_channel) {
|
|
||||||
// TODO(hta): Must be a better way
|
|
||||||
return RTCError(RTCErrorType::INTERNAL_ERROR,
|
|
||||||
"Failed to create channel for mid=" + std::string(mid));
|
|
||||||
}
|
|
||||||
SetChannel(std::move(new_channel), transport_lookup);
|
SetChannel(std::move(new_channel), transport_lookup);
|
||||||
return RTCError::OK();
|
return RTCError::OK();
|
||||||
}
|
}
|
||||||
@ -339,6 +324,8 @@ void RtpTransceiver::SetChannel(
|
|||||||
// helps with keeping the channel implementation requirements being met and
|
// helps with keeping the channel implementation requirements being met and
|
||||||
// avoids synchronization for accessing the pointer or network related state.
|
// avoids synchronization for accessing the pointer or network related state.
|
||||||
context()->network_thread()->BlockingCall([&]() {
|
context()->network_thread()->BlockingCall([&]() {
|
||||||
|
// TODO(tommi): Isn't `channel_` guaranteed to be nullptr here? (i.e.
|
||||||
|
// remove this block).
|
||||||
if (channel_) {
|
if (channel_) {
|
||||||
channel_->SetFirstPacketReceivedCallback(nullptr);
|
channel_->SetFirstPacketReceivedCallback(nullptr);
|
||||||
channel_->SetFirstPacketSentCallback(nullptr);
|
channel_->SetFirstPacketSentCallback(nullptr);
|
||||||
|
|||||||
@ -99,6 +99,7 @@ TEST_F(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
|
|||||||
// Clear the current channel - required to allow SetChannel()
|
// Clear the current channel - required to allow SetChannel()
|
||||||
EXPECT_CALL(*channel1_ptr, SetFirstPacketReceivedCallback(_));
|
EXPECT_CALL(*channel1_ptr, SetFirstPacketReceivedCallback(_));
|
||||||
transceiver->ClearChannel();
|
transceiver->ClearChannel();
|
||||||
|
ASSERT_EQ(nullptr, transceiver->channel());
|
||||||
// Channel can no longer be set, so this call should be a no-op.
|
// Channel can no longer be set, so this call should be a no-op.
|
||||||
transceiver->SetChannel(std::move(channel2),
|
transceiver->SetChannel(std::move(channel2),
|
||||||
[](const std::string&) { return nullptr; });
|
[](const std::string&) { return nullptr; });
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user