| /* |
| * 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 for the "both" case. |
| if (send_impl_ && receive_impl_) { |
| RTC_CHECK_NOTREACHED(); |
| } |
| send_impl()->SetSendCodecChangedCallback(std::move(callback)); |
| } |
| |
| // 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_ |