#ifndef TGCALLS_MEDIA_MANAGER_H #define TGCALLS_MEDIA_MANAGER_H #include "rtc_base/thread.h" #include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/third_party/sigslot/sigslot.h" #include "api/transport/field_trial_based_config.h" #include "pc/rtp_sender.h" #include "Instance.h" #include "Message.h" #include "VideoCaptureInterface.h" #include "Stats.h" #include #include namespace webrtc { class Call; class RtcEventLogNull; class TaskQueueFactory; class VideoBitrateAllocatorFactory; class VideoTrackSourceInterface; class AudioDeviceModule; } // namespace webrtc namespace cricket { class MediaEngineInterface; class VoiceMediaChannel; class VideoMediaChannel; } // namespace cricket namespace tgcalls { class VideoSinkInterfaceProxyImpl; class MediaManager : public sigslot::has_slots<>, public std::enable_shared_from_this { public: static rtc::Thread *getWorkerThread(); MediaManager( rtc::Thread *thread, bool isOutgoing, ProtocolVersion protocolVersion, const MediaDevicesConfig &devicesConfig, std::shared_ptr videoCapture, std::function sendSignalingMessage, std::function sendTransportMessage, std::function signalBarsUpdated, std::function audioLevelsUpdated, std::function(webrtc::TaskQueueFactory*)> createAudioDeviceModule, bool enableHighBitrateVideo, std::vector preferredCodecs, std::shared_ptr platformContext); ~MediaManager(); void start(); void setIsConnected(bool isConnected); void notifyPacketSent(const rtc::SentPacket &sentPacket); void setSendVideo(std::shared_ptr videoCapture); void sendVideoDeviceUpdated(); void setRequestedVideoAspect(float aspect); void setMuteOutgoingAudio(bool mute); void setIncomingVideoOutput(std::weak_ptr> sink); void receiveMessage(DecryptedMessage &&message); void remoteVideoStateUpdated(VideoState videoState); void setNetworkParameters(bool isLowCost, bool isDataSavingActive); void fillCallStats(CallStats &callStats); void setAudioInputDevice(std::string id); void setAudioOutputDevice(std::string id); void setInputVolume(float level); void setOutputVolume(float level); void addExternalAudioSamples(std::vector &&samples); private: struct SSRC { uint32_t incoming = 0; uint32_t outgoing = 0; uint32_t fecIncoming = 0; uint32_t fecOutgoing = 0; }; class NetworkInterfaceImpl : public cricket::MediaChannel::NetworkInterface { public: NetworkInterfaceImpl(MediaManager *mediaManager, bool isVideo); bool SendPacket(rtc::CopyOnWriteBuffer *packet, const rtc::PacketOptions& options) override; bool SendRtcp(rtc::CopyOnWriteBuffer *packet, const rtc::PacketOptions& options) override; int SetOption(SocketType type, rtc::Socket::Option opt, int option) override; private: bool sendTransportMessage(rtc::CopyOnWriteBuffer *packet, const rtc::PacketOptions& options); MediaManager *_mediaManager = nullptr; bool _isVideo = false; }; friend class MediaManager::NetworkInterfaceImpl; void setPeerVideoFormats(VideoFormatsMessage &&peerFormats); bool computeIsSendingVideo() const; void configureSendingVideoIfNeeded(); void checkIsSendingVideoChanged(bool wasSending); bool videoCodecsNegotiated() const; int getMaxVideoBitrate() const; int getMaxAudioBitrate() const; void adjustBitratePreferences(bool resetStartBitrate); bool computeIsReceivingVideo() const; void checkIsReceivingVideoChanged(bool wasReceiving); void setOutgoingVideoState(VideoState state); void setOutgoingAudioState(AudioState state); void sendVideoParametersMessage(); void sendOutgoingMediaStateMessage(); rtc::scoped_refptr createAudioDeviceModule(); void beginStatsTimer(int timeoutMs); void beginLevelsTimer(int timeoutMs); void collectStats(); rtc::Thread *_thread = nullptr; std::unique_ptr _eventLog; std::unique_ptr _taskQueueFactory; std::function _sendSignalingMessage; std::function _sendTransportMessage; std::function _signalBarsUpdated; std::function _audioLevelsUpdated; std::function(webrtc::TaskQueueFactory*)> _createAudioDeviceModule; SSRC _ssrcAudio; SSRC _ssrcVideo; bool _enableFlexfec = true; ProtocolVersion _protocolVersion; bool _isConnected = false; bool _didConnectOnce = false; bool _readyToReceiveVideo = false; bool _didConfigureVideo = false; AudioState _outgoingAudioState = AudioState::Active; VideoState _outgoingVideoState = VideoState::Inactive; VideoFormatsMessage _myVideoFormats; std::vector _videoCodecs; absl::optional _videoCodecOut; std::unique_ptr _mediaEngine; std::unique_ptr _call; webrtc::LocalAudioSinkAdapter _audioSource; rtc::scoped_refptr _audioDeviceModule; std::unique_ptr _audioChannel; std::unique_ptr _videoChannel; std::unique_ptr _videoBitrateAllocatorFactory; std::shared_ptr _videoCapture; std::shared_ptr _videoCaptureGuard; bool _isScreenCapture = false; std::shared_ptr _incomingVideoSinkProxy; float _localPreferredVideoAspectRatio = 0.0f; float _preferredAspectRatio = 0.0f; bool _enableHighBitrateVideo = false; bool _isLowCostNetwork = false; bool _isDataSavingActive = false; float _currentAudioLevel = 0.0f; float _currentMyAudioLevel = 0.0f; std::unique_ptr _audioNetworkInterface; std::unique_ptr _videoNetworkInterface; std::vector _bitrateRecords; std::vector _externalAudioSamples; webrtc::Mutex _externalAudioSamplesMutex; std::shared_ptr _platformContext; }; } // namespace tgcalls #endif