Make a shim object implementing the VideoMediaChannel interface

The intent is that this object can be used instead of VideoMediaChannel,
clearing the way for decomposing VideoMediaChannel into send and
receive classes.

This CL uses it for the "both" role of WebRtcVideoEngine::CreateMediaChannel; a later CL will use it for all roles on all engines.

Bug: webrtc:13931
Change-Id: Ibd0ca2c3c45b5e3bfcced8f7e30a1edd63cf7654
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/306720
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40173}
This commit is contained in:
Harald Alvestrand 2023-05-30 04:04:07 +00:00 committed by WebRTC LUCI CQ
parent 4c1e9598a3
commit 97c9623839
8 changed files with 510 additions and 53 deletions

View File

@ -141,6 +141,40 @@ rtc_library("rtc_media_base") {
]
}
rtc_library("media_channel_shim") {
sources = [
"base/media_channel_shim.cc",
"base/media_channel_shim.h",
]
deps = [
":codec",
":media_channel",
":media_channel_impl",
":stream_params",
"../api:frame_transformer_interface",
"../api:rtc_error",
"../api:rtp_headers",
"../api:rtp_parameters",
"../api:rtp_sender_interface",
"../api:scoped_refptr",
"../api/crypto:frame_decryptor_interface",
"../api/crypto:frame_encryptor_interface",
"../api/transport/rtp:rtp_source",
"../api/video:recordable_encoded_frame",
"../api/video:video_frame",
"../api/video_codecs:video_codecs_api",
"../modules/rtp_rtcp:rtp_rtcp_format",
"../rtc_base:checks",
"../rtc_base:network_route",
"../rtc_base/network:sent_packet",
]
absl_deps = [
"//third_party/abseil-cpp/absl/functional:any_invocable",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("media_channel_impl") {
sources = [
"base/media_channel_impl.cc",
@ -205,8 +239,10 @@ rtc_source_set("media_channel") {
"../api:frame_transformer_interface",
"../api:media_stream_interface",
"../api:rtc_error",
"../api:rtp_headers",
"../api:rtp_parameters",
"../api:rtp_sender_interface",
"../api:scoped_refptr",
"../api/audio_codecs:audio_codecs_api",
"../api/crypto:frame_decryptor_interface",
"../api/crypto:frame_encryptor_interface",
@ -214,6 +250,7 @@ rtc_source_set("media_channel") {
"../api/transport:datagram_transport_interface",
"../api/transport/rtp:rtp_source",
"../api/units:time_delta",
"../api/video:recordable_encoded_frame",
"../api/video:video_frame",
"../api/video:video_rtp_headers",
"../api/video_codecs:scalability_mode",
@ -224,15 +261,21 @@ rtc_source_set("media_channel") {
"../modules/rtp_rtcp:rtp_rtcp_format",
"../rtc_base:async_packet_socket",
"../rtc_base:buffer",
"../rtc_base:checks",
"../rtc_base:copy_on_write_buffer",
"../rtc_base:dscp",
"../rtc_base:logging",
"../rtc_base:network_route",
"../rtc_base:socket",
"../rtc_base:stringutils",
"../rtc_base/network:sent_packet",
"../video/config:encoder_config",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
absl_deps = [
"//third_party/abseil-cpp/absl/functional:any_invocable",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_source_set("delayable") {
@ -429,6 +472,7 @@ rtc_library("rtc_audio_video") {
":codec",
":media_channel",
":media_channel_impl",
":media_channel_shim",
":media_constants",
":rid_description",
":rtc_media_base",

View File

@ -954,6 +954,9 @@ class VideoMediaSendChannelInterface : public MediaSendChannelInterface {
virtual bool SendCodecHasLntf() const = 0;
virtual bool SendCodecHasNack() const = 0;
virtual absl::optional<int> SendCodecRtxTime() const = 0;
// TODO(bugs.webrtc.org/13931): Remove when configuration is more sensible
virtual void SetSendCodecChangedCallback(
absl::AnyInvocable<void()> callback) = 0;
};
class VideoMediaReceiveChannelInterface : public MediaReceiveChannelInterface {

View File

@ -244,6 +244,9 @@ class VideoMediaChannel : public MediaChannel,
0;
bool AddRecvStream(const StreamParams& sp) override = 0;
void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override = 0;
void SetEncoderSelector(uint32_t ssrc,
webrtc::VideoEncoderFactory::EncoderSelectorInterface*
encoder_selector) override {}
// This fills the "bitrate parts" (rtx, video bitrate) of the
// BandwidthEstimationInfo, since that part that isn't possible to get
@ -257,27 +260,25 @@ class VideoMediaChannel : public MediaChannel,
// Gets quality stats for the channel.
virtual bool GetSendStats(VideoMediaSendInfo* info) = 0;
virtual bool GetReceiveStats(VideoMediaReceiveInfo* info) = 0;
bool GetStats(VideoMediaSendInfo* info) override {
return GetSendStats(info);
}
bool GetStats(VideoMediaReceiveInfo* info) override {
return GetReceiveStats(info);
}
// TODO(bugs.webrtc.org/13931): Remove when configuration is more sensible
virtual void SetSendCodecChangedCallback(
absl::AnyInvocable<void()> callback) = 0;
void SetSendCodecChangedCallback(
absl::AnyInvocable<void()> callback) override = 0;
// Enable network condition based codec switching.
// Note: should have been pure virtual.
void SetVideoCodecSwitchingEnabled(bool enabled) override;
private:
// Functions not implemented on this interface
bool GetStats(VideoMediaSendInfo* info) override {
RTC_CHECK_NOTREACHED();
return false;
}
bool GetStats(VideoMediaReceiveInfo* info) override {
RTC_CHECK_NOTREACHED();
return false;
}
bool HasNetworkInterface() const override {
return MediaChannel::HasNetworkInterface();
}
// Enable network condition based codec switching.
void SetVideoCodecSwitchingEnabled(bool enabled) override;
MediaChannel* ImplForTesting() override {
// This class and its subclasses are not interface classes.
RTC_CHECK_NOTREACHED();
@ -666,6 +667,10 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface {
absl::AnyInvocable<void(const std::set<uint32_t>&)> callback) override {
impl()->SetSsrcListChangedCallback(std::move(callback));
}
void SetSendCodecChangedCallback(
absl::AnyInvocable<void()> callback) override {
impl()->SetSendCodecChangedCallback(std::move(callback));
}
MediaChannel* ImplForTesting() override { return impl_; }

View File

@ -0,0 +1,38 @@
/*
* Copyright 2023 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "media/base/media_channel_shim.h"
namespace cricket {
// Note: The VideoMediaChannel default implementations are not used here, and
// should be removed from that interface.
// TODO(bugs.webrtc.org/13931): Remove them.
VideoMediaShimChannel::VideoMediaShimChannel(
std::unique_ptr<VideoMediaSendChannelInterface> send_impl,
std::unique_ptr<VideoMediaReceiveChannelInterface> receive_impl)
: VideoMediaChannel(MediaChannel::Role::kBoth, nullptr, false),
send_impl_(std::move(send_impl)),
receive_impl_(std::move(receive_impl)) {
if (send_impl_ && receive_impl_) {
send_impl_->SetSendCodecChangedCallback([this]() {
// Adjust receive streams based on send codec.
receive_impl_->SetReceiverFeedbackParameters(
send_impl_->SendCodecHasLntf(), send_impl_->SendCodecHasNack(),
send_impl_->SendCodecRtcpMode(), send_impl_->SendCodecRtxTime());
});
send_impl_->SetSsrcListChangedCallback(
[this](const std::set<uint32_t>& choices) {
receive_impl_->ChooseReceiverReportSsrc(choices);
});
}
}
} // namespace cricket

View File

@ -0,0 +1,333 @@
/*
* Copyright 2023 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MEDIA_BASE_MEDIA_CHANNEL_SHIM_H_
#define MEDIA_BASE_MEDIA_CHANNEL_SHIM_H_
#include <stdint.h>
#include <functional>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/crypto/frame_decryptor_interface.h"
#include "api/crypto/frame_encryptor_interface.h"
#include "api/frame_transformer_interface.h"
#include "api/media_types.h"
#include "api/rtc_error.h"
#include "api/rtp_headers.h"
#include "api/rtp_parameters.h"
#include "api/rtp_sender_interface.h"
#include "api/scoped_refptr.h"
#include "api/transport/rtp/rtp_source.h"
#include "api/video/recordable_encoded_frame.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "api/video/video_source_interface.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "media/base/codec.h"
#include "media/base/media_channel.h"
#include "media/base/media_channel_impl.h"
#include "media/base/stream_params.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "rtc_base/checks.h"
#include "rtc_base/network/sent_packet.h"
#include "rtc_base/network_route.h"
// The VideoMediaShimChannel is replacing the VideoMediaChannel
// interface.
// If called with both send_impl and receive_impl, it operates in kBoth
// mode; if called with only one, it will shim that one and DCHECK if one
// tries to do functions belonging to the other.
namespace cricket {
class VideoMediaShimChannel : public VideoMediaChannel {
public:
VideoMediaShimChannel(
std::unique_ptr<VideoMediaSendChannelInterface> send_impl,
std::unique_ptr<VideoMediaReceiveChannelInterface> receive_impl);
VideoMediaSendChannelInterface* AsVideoSendChannel() override { return this; }
VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override {
return this;
}
VoiceMediaSendChannelInterface* AsVoiceSendChannel() override {
RTC_CHECK_NOTREACHED();
return nullptr;
}
VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() override {
RTC_CHECK_NOTREACHED();
return nullptr;
}
// SetInterface needs to run on both send and receive channels.
void SetInterface(MediaChannelNetworkInterface* iface) override {
if (send_impl_) {
send_impl()->SetInterface(iface);
}
if (receive_impl_) {
receive_impl()->SetInterface(iface);
}
}
// Not really valid for this mode
MediaChannel* ImplForTesting() override {
RTC_CHECK_NOTREACHED();
return nullptr;
}
// Implementation of MediaBaseChannelInterface
cricket::MediaType media_type() const override { return MEDIA_TYPE_VIDEO; }
// Implementation of MediaSendChannelInterface
void OnPacketSent(const rtc::SentPacket& sent_packet) override {
send_impl()->OnPacketSent(sent_packet);
}
void OnReadyToSend(bool ready) override { send_impl()->OnReadyToSend(ready); }
void OnNetworkRouteChanged(absl::string_view transport_name,
const rtc::NetworkRoute& network_route) override {
send_impl()->OnNetworkRouteChanged(transport_name, network_route);
}
void SetExtmapAllowMixed(bool extmap_allow_mixed) override {
send_impl()->SetExtmapAllowMixed(extmap_allow_mixed);
}
bool HasNetworkInterface() const override {
return send_impl()->HasNetworkInterface();
}
bool ExtmapAllowMixed() const override {
return send_impl()->ExtmapAllowMixed();
}
bool AddSendStream(const StreamParams& sp) override {
return send_impl()->AddSendStream(sp);
}
bool RemoveSendStream(uint32_t ssrc) override {
return send_impl()->RemoveSendStream(ssrc);
}
void SetFrameEncryptor(uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameEncryptorInterface>
frame_encryptor) override {
send_impl()->SetFrameEncryptor(ssrc, frame_encryptor);
}
webrtc::RTCError SetRtpSendParameters(
uint32_t ssrc,
const webrtc::RtpParameters& parameters,
webrtc::SetParametersCallback callback = nullptr) override {
return send_impl()->SetRtpSendParameters(ssrc, parameters,
std::move(callback));
}
void SetEncoderToPacketizerFrameTransformer(
uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
override {
return send_impl()->SetEncoderToPacketizerFrameTransformer(
ssrc, frame_transformer);
}
void SetEncoderSelector(uint32_t ssrc,
webrtc::VideoEncoderFactory::EncoderSelectorInterface*
encoder_selector) override {
send_impl()->SetEncoderSelector(ssrc, encoder_selector);
}
webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override {
return send_impl()->GetRtpSendParameters(ssrc);
}
// Send_Implementation of VideoMediaSendChannelInterface
bool SetSendParameters(const VideoSendParameters& params) override {
return send_impl()->SetSendParameters(params);
}
bool GetSendCodec(VideoCodec* send_codec) override {
return send_impl()->GetSendCodec(send_codec);
}
bool SetSend(bool send) override { return send_impl()->SetSend(send); }
bool SetVideoSend(
uint32_t ssrc,
const VideoOptions* options,
rtc::VideoSourceInterface<webrtc::VideoFrame>* source) override {
return send_impl()->SetVideoSend(ssrc, options, source);
}
void GenerateSendKeyFrame(uint32_t ssrc,
const std::vector<std::string>& rids) override {
return send_impl()->GenerateSendKeyFrame(ssrc, rids);
}
void SetVideoCodecSwitchingEnabled(bool enabled) override {
return send_impl()->SetVideoCodecSwitchingEnabled(enabled);
}
bool GetStats(VideoMediaSendInfo* info) override {
return send_impl_->GetStats(info);
}
bool GetSendStats(VideoMediaSendInfo* info) override {
return send_impl_->GetStats(info);
}
void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override {
return send_impl_->FillBitrateInfo(bwe_info);
}
// Information queries to support SetReceiverFeedbackParameters
webrtc::RtcpMode SendCodecRtcpMode() const override {
return send_impl()->SendCodecRtcpMode();
}
bool SendCodecHasLntf() const override {
return send_impl()->SendCodecHasLntf();
}
bool SendCodecHasNack() const override {
return send_impl()->SendCodecHasNack();
}
absl::optional<int> SendCodecRtxTime() const override {
return send_impl()->SendCodecRtxTime();
}
void SetSsrcListChangedCallback(
absl::AnyInvocable<void(const std::set<uint32_t>&)> callback) override {
send_impl()->SetSsrcListChangedCallback(std::move(callback));
}
void SetSendCodecChangedCallback(
absl::AnyInvocable<void()> callback) override {
// This callback is used internally by the shim, so should not be called by
// users.
RTC_CHECK_NOTREACHED();
}
// Implementation of Delayable
bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override {
return receive_impl()->SetBaseMinimumPlayoutDelayMs(ssrc, delay_ms);
}
absl::optional<int> GetBaseMinimumPlayoutDelayMs(
uint32_t ssrc) const override {
return receive_impl()->GetBaseMinimumPlayoutDelayMs(ssrc);
}
// Implementation of MediaReceiveChannelInterface
void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override {
receive_impl()->OnPacketReceived(packet);
}
bool AddRecvStream(const StreamParams& sp) override {
return receive_impl()->AddRecvStream(sp);
}
bool RemoveRecvStream(uint32_t ssrc) override {
return receive_impl()->RemoveRecvStream(ssrc);
}
void ResetUnsignaledRecvStream() override {
return receive_impl()->ResetUnsignaledRecvStream();
}
absl::optional<uint32_t> GetUnsignaledSsrc() const override {
return receive_impl()->GetUnsignaledSsrc();
}
void ChooseReceiverReportSsrc(const std::set<uint32_t>& choices) override {
return receive_impl()->ChooseReceiverReportSsrc(choices);
}
void OnDemuxerCriteriaUpdatePending() override {
receive_impl()->OnDemuxerCriteriaUpdatePending();
}
void OnDemuxerCriteriaUpdateComplete() override {
receive_impl()->OnDemuxerCriteriaUpdateComplete();
}
void SetFrameDecryptor(uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameDecryptorInterface>
frame_decryptor) override {
receive_impl()->SetFrameDecryptor(ssrc, frame_decryptor);
}
void SetDepacketizerToDecoderFrameTransformer(
uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
override {
receive_impl()->SetDepacketizerToDecoderFrameTransformer(ssrc,
frame_transformer);
}
// Implementation of VideoMediaReceiveChannelInterface
bool SetRecvParameters(const VideoRecvParameters& params) override {
return receive_impl()->SetRecvParameters(params);
}
webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const override {
return receive_impl()->GetRtpReceiveParameters(ssrc);
}
webrtc::RtpParameters GetDefaultRtpReceiveParameters() const override {
return receive_impl()->GetDefaultRtpReceiveParameters();
}
bool SetSink(uint32_t ssrc,
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override {
return receive_impl()->SetSink(ssrc, sink);
}
void SetDefaultSink(
rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override {
return receive_impl()->SetDefaultSink(sink);
}
void RequestRecvKeyFrame(uint32_t ssrc) override {
return receive_impl()->RequestRecvKeyFrame(ssrc);
}
std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const override {
return receive_impl()->GetSources(ssrc);
}
// Set recordable encoded frame callback for `ssrc`
void SetRecordableEncodedFrameCallback(
uint32_t ssrc,
std::function<void(const webrtc::RecordableEncodedFrame&)> callback)
override {
return receive_impl()->SetRecordableEncodedFrameCallback(
ssrc, std::move(callback));
}
// Clear recordable encoded frame callback for `ssrc`
void ClearRecordableEncodedFrameCallback(uint32_t ssrc) override {
receive_impl()->ClearRecordableEncodedFrameCallback(ssrc);
}
bool GetStats(VideoMediaReceiveInfo* info) override {
return receive_impl()->GetStats(info);
}
bool GetReceiveStats(VideoMediaReceiveInfo* info) override {
return receive_impl()->GetStats(info);
}
void SetReceiverFeedbackParameters(bool lntf_enabled,
bool nack_enabled,
webrtc::RtcpMode rtcp_mode,
absl::optional<int> rtx_time) override {
receive_impl()->SetReceiverFeedbackParameters(lntf_enabled, nack_enabled,
rtcp_mode, rtx_time);
}
void SetReceive(bool receive) override {
receive_impl()->SetReceive(receive);
}
bool AddDefaultRecvStreamForTesting(const StreamParams& sp) override {
return receive_impl()->AddDefaultRecvStreamForTesting(sp);
}
// Only for testing of implementations - these will be used to static_cast the
// pointers to the implementations, so can only be safely used in conjunction
// with the corresponding create functions.
VideoMediaSendChannelInterface* SendImplForTesting() {
return send_impl_.get();
}
VideoMediaReceiveChannelInterface* ReceiveImplForTesting() {
return receive_impl_.get();
}
private:
VideoMediaSendChannelInterface* send_impl() { return send_impl_.get(); }
VideoMediaReceiveChannelInterface* receive_impl() {
RTC_DCHECK(receive_impl_);
return receive_impl_.get();
}
const VideoMediaSendChannelInterface* send_impl() const {
RTC_DCHECK(send_impl_);
return send_impl_.get();
}
const VideoMediaReceiveChannelInterface* receive_impl() const {
return receive_impl_.get();
}
std::unique_ptr<VideoMediaSendChannelInterface> send_impl_;
std::unique_ptr<VideoMediaReceiveChannelInterface> receive_impl_;
};
} // namespace cricket
#endif // MEDIA_BASE_MEDIA_CHANNEL_SHIM_H_

View File

@ -627,6 +627,18 @@ VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel(
const webrtc::CryptoOptions& crypto_options,
webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) {
RTC_LOG(LS_INFO) << "CreateMediaChannel. Options: " << options.ToString();
if (role == MediaChannel::Role::kBoth) {
auto send_channel = std::make_unique<WebRtcVideoChannel>(
MediaChannel::Role::kSend, call, config, options, crypto_options,
encoder_factory_.get(), decoder_factory_.get(),
video_bitrate_allocator_factory);
auto receive_channel = std::make_unique<WebRtcVideoChannel>(
MediaChannel::Role::kReceive, call, config, options, crypto_options,
encoder_factory_.get(), decoder_factory_.get(),
video_bitrate_allocator_factory);
return new VideoMediaShimChannel(std::move(send_channel),
std::move(receive_channel));
}
return new WebRtcVideoChannel(role, call, config, options, crypto_options,
encoder_factory_.get(), decoder_factory_.get(),
video_bitrate_allocator_factory);
@ -1014,7 +1026,9 @@ bool WebRtcVideoChannel::ApplyChangedParams(
}
} else {
if (changed_params.send_codec || changed_params.rtcp_mode) {
send_codec_changed_callback_();
if (send_codec_changed_callback_) {
send_codec_changed_callback_();
}
}
}
return true;

View File

@ -59,6 +59,7 @@
#include "media/base/codec.h"
#include "media/base/media_channel.h"
#include "media/base/media_channel_impl.h"
#include "media/base/media_channel_shim.h"
#include "media/base/media_config.h"
#include "media/base/media_engine.h"
#include "media/base/stream_params.h"

View File

@ -1797,11 +1797,10 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test {
// needs to be disabled, otherwise, tests which check the size of received
// frames become flaky.
media_config.video.enable_cpu_adaptation = false;
channel_.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), media_config,
cricket::VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
channel_.reset(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), media_config,
cricket::VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
send_channel_ = std::make_unique<VideoMediaSendChannel>(channel_.get());
receive_channel_ =
std::make_unique<VideoMediaReceiveChannel>(channel_.get());
@ -1820,6 +1819,15 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test {
EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
}
// Returns pointer to implementation of the send channel.
WebRtcVideoChannel* SendImpl() {
// Note that this function requires intimate knowledge of how the channel
// was created.
return static_cast<cricket::WebRtcVideoChannel*>(
static_cast<VideoMediaShimChannel*>(channel_.get())
->SendImplForTesting());
}
// Utility method to setup an additional stream to send and receive video.
// Used to test send and recv between two streams.
void SetUpSecondStream() {
@ -1866,7 +1874,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test {
frame_source_ = std::make_unique<cricket::FakeFrameSource>(
kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);
bool sending = channel_->sending();
bool sending = SendImpl()->sending();
bool success = SetSend(false);
if (success) {
cricket::VideoSendParameters parameters;
@ -1992,7 +2000,7 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test {
std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;
std::unique_ptr<WebRtcVideoChannel> channel_;
std::unique_ptr<VideoMediaChannel> channel_;
std::unique_ptr<VideoMediaSendChannel> send_channel_;
std::unique_ptr<VideoMediaReceiveChannel> receive_channel_;
cricket::FakeNetworkInterface network_interface_;
@ -2004,23 +2012,23 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test {
// Test that SetSend works.
TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
EXPECT_FALSE(channel_->sending());
EXPECT_FALSE(SendImpl()->sending());
EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
EXPECT_TRUE(SetOneCodec(DefaultCodec()));
EXPECT_FALSE(channel_->sending());
EXPECT_FALSE(SendImpl()->sending());
EXPECT_TRUE(SetSend(true));
EXPECT_TRUE(channel_->sending());
EXPECT_TRUE(SendImpl()->sending());
SendFrame();
EXPECT_GT(NumRtpPackets(), 0);
EXPECT_TRUE(SetSend(false));
EXPECT_FALSE(channel_->sending());
EXPECT_FALSE(SendImpl()->sending());
}
// Test that SetSend fails without codecs being set.
TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
EXPECT_FALSE(channel_->sending());
EXPECT_FALSE(SendImpl()->sending());
EXPECT_FALSE(SetSend(true));
EXPECT_FALSE(channel_->sending());
EXPECT_FALSE(SendImpl()->sending());
}
// Test that we properly set the send and recv buffer sizes by the time
@ -2544,13 +2552,13 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) {
// RequestEncoderFallback will post a task to the worker thread (which is also
// the current thread), hence the ProcessMessages call.
channel_->RequestEncoderFallback();
SendImpl()->RequestEncoderFallback();
time_controller_.AdvanceTime(kFrameDuration);
ASSERT_TRUE(channel_->GetSendCodec(&codec));
EXPECT_EQ("VP8", codec.name);
// No other codec to fall back to, keep using VP8.
channel_->RequestEncoderFallback();
SendImpl()->RequestEncoderFallback();
time_controller_.AdvanceTime(kFrameDuration);
ASSERT_TRUE(channel_->GetSendCodec(&codec));
EXPECT_EQ("VP8", codec.name);
@ -2568,8 +2576,8 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchDefaultFallback) {
// RequestEncoderSwitch will post a task to the worker thread (which is also
// the current thread), hence the ProcessMessages call.
channel_->RequestEncoderSwitch(webrtc::SdpVideoFormat("UnavailableCodec"),
/*allow_default_fallback=*/true);
SendImpl()->RequestEncoderSwitch(webrtc::SdpVideoFormat("UnavailableCodec"),
/*allow_default_fallback=*/true);
time_controller_.AdvanceTime(kFrameDuration);
// Requested encoder is not available. Default fallback is allowed. Switch to
@ -2591,7 +2599,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) {
ASSERT_TRUE(channel_->GetSendCodec(&codec));
EXPECT_EQ("VP8", codec.name);
channel_->RequestEncoderSwitch(
SendImpl()->RequestEncoderSwitch(
webrtc::SdpVideoFormat("VP9", {{"profile-id", "1"}}),
/*allow_default_fallback=*/false);
time_controller_.AdvanceTime(kFrameDuration);
@ -2601,7 +2609,7 @@ TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) {
ASSERT_TRUE(channel_->GetSendCodec(&codec));
EXPECT_EQ("VP8", codec.name);
channel_->RequestEncoderSwitch(
SendImpl()->RequestEncoderSwitch(
webrtc::SdpVideoFormat("VP9", {{"profile-id", "0"}}),
/*allow_default_fallback=*/false);
time_controller_.AdvanceTime(kFrameDuration);
@ -2624,7 +2632,7 @@ TEST_F(WebRtcVideoChannelBaseTest, SendCodecIsMovedToFrontInRtpParameters) {
// RequestEncoderFallback will post a task to the worker thread (which is also
// the current thread), hence the ProcessMessages call.
channel_->RequestEncoderFallback();
SendImpl()->RequestEncoderFallback();
time_controller_.AdvanceTime(kFrameDuration);
send_codecs = send_channel_->GetRtpSendParameters(kSsrc).codecs;
@ -2676,6 +2684,23 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
SetUp();
}
// Returns pointer to implementation of the send channel.
WebRtcVideoChannel* SendImpl() {
// Note that this function requires intimate knowledge of how the channel
// was created.
return static_cast<cricket::WebRtcVideoChannel*>(
static_cast<VideoMediaShimChannel*>(channel_.get())
->SendImplForTesting());
}
// Casts a shim channel to a webrtc::Transport. Used once.
webrtc::Transport* ChannelImplAsTransport(VideoMediaChannel* channel) {
return static_cast<webrtc::Transport*>(
static_cast<cricket::WebRtcVideoChannel*>(
static_cast<VideoMediaShimChannel*>(channel)
->SendImplForTesting()));
}
cricket::VideoCodec GetEngineCodec(const std::string& name) {
for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) {
if (absl::EqualsIgnoreCase(name, engine_codec.name))
@ -5511,15 +5536,13 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
new cricket::FakeNetworkInterface);
MediaConfig config;
std::unique_ptr<cricket::WebRtcVideoChannel> channel;
std::unique_ptr<cricket::VideoMediaChannel> channel;
std::unique_ptr<cricket::VideoMediaSendChannel> send_channel;
webrtc::RtpParameters parameters;
channel.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
channel.reset(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), config, VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
send_channel.reset(new VideoMediaSendChannel(channel_.get()));
channel->SetInterface(network_interface.get());
@ -5530,11 +5553,9 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
// Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
// through rtp parameters.
config.enable_dscp = true;
channel.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
channel.reset(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), config, VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
send_channel.reset(new VideoMediaSendChannel(channel.get()));
channel->SetInterface(network_interface.get());
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
@ -5556,19 +5577,17 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
// Packets should also self-identify their dscp in PacketOptions.
const uint8_t kData[10] = {0};
EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
->SendRtcp(kData, sizeof(kData)));
EXPECT_TRUE(
ChannelImplAsTransport(channel.get())->SendRtcp(kData, sizeof(kData)));
EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
channel->SetInterface(nullptr);
// Verify that setting the option to false resets the
// DiffServCodePoint.
config.enable_dscp = false;
channel.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
channel.reset(engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, call_.get(), config, VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
channel->SetInterface(network_interface.get());
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
channel->SetInterface(nullptr);