1 /* 2 * libjingle 3 * Copyright 2004 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_MEDIA_WEBRTCVIDEOENGINE_H_ 29 #define TALK_MEDIA_WEBRTCVIDEOENGINE_H_ 30 31 #include <map> 32 #include <vector> 33 34 #include "talk/base/scoped_ptr.h" 35 #include "talk/media/base/codec.h" 36 #include "talk/media/base/videocommon.h" 37 #include "talk/media/webrtc/webrtccommon.h" 38 #include "talk/media/webrtc/webrtcexport.h" 39 #include "talk/media/webrtc/webrtcvideoencoderfactory.h" 40 #include "talk/session/media/channel.h" 41 #include "webrtc/video_engine/include/vie_base.h" 42 43 #if !defined(LIBPEERCONNECTION_LIB) && \ 44 !defined(LIBPEERCONNECTION_IMPLEMENTATION) 45 #error "Bogus include." 46 #endif 47 48 49 namespace webrtc { 50 class VideoCaptureModule; 51 class VideoDecoder; 52 class VideoEncoder; 53 class VideoRender; 54 class ViEExternalCapture; 55 class ViERTP_RTCP; 56 } 57 58 namespace talk_base { 59 class CpuMonitor; 60 } // namespace talk_base 61 62 namespace cricket { 63 64 class CoordinatedVideoAdapter; 65 class ViETraceWrapper; 66 class ViEWrapper; 67 class VideoCapturer; 68 class VideoFrame; 69 class VideoProcessor; 70 class VideoRenderer; 71 class VoiceMediaChannel; 72 class WebRtcDecoderObserver; 73 class WebRtcEncoderObserver; 74 class WebRtcLocalStreamInfo; 75 class WebRtcRenderAdapter; 76 class WebRtcVideoChannelRecvInfo; 77 class WebRtcVideoChannelSendInfo; 78 class WebRtcVideoDecoderFactory; 79 class WebRtcVideoEncoderFactory; 80 class WebRtcVideoMediaChannel; 81 class WebRtcVoiceEngine; 82 83 struct CapturedFrame; 84 struct Device; 85 86 class WebRtcVideoEngine : public sigslot::has_slots<>, 87 public webrtc::TraceCallback, 88 public WebRtcVideoEncoderFactory::Observer { 89 public: 90 // Creates the WebRtcVideoEngine with internal VideoCaptureModule. 91 WebRtcVideoEngine(); 92 // For testing purposes. Allows the WebRtcVoiceEngine, 93 // ViEWrapper and CpuMonitor to be mocks. 94 // TODO(juberti): Remove the 3-arg ctor once fake tracing is implemented. 95 WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine, 96 ViEWrapper* vie_wrapper, 97 talk_base::CpuMonitor* cpu_monitor); 98 WebRtcVideoEngine(WebRtcVoiceEngine* voice_engine, 99 ViEWrapper* vie_wrapper, 100 ViETraceWrapper* tracing, 101 talk_base::CpuMonitor* cpu_monitor); 102 ~WebRtcVideoEngine(); 103 104 // Basic video engine implementation. 105 bool Init(talk_base::Thread* worker_thread); 106 void Terminate(); 107 108 int GetCapabilities(); 109 bool SetOptions(const VideoOptions &options); 110 bool SetDefaultEncoderConfig(const VideoEncoderConfig& config); 111 VideoEncoderConfig GetDefaultEncoderConfig() const; 112 113 WebRtcVideoMediaChannel* CreateChannel(VoiceMediaChannel* voice_channel); 114 115 const std::vector<VideoCodec>& codecs() const; 116 const std::vector<RtpHeaderExtension>& rtp_header_extensions() const; 117 void SetLogging(int min_sev, const char* filter); 118 119 bool SetLocalRenderer(VideoRenderer* renderer); 120 sigslot::repeater2<VideoCapturer*, CaptureState> SignalCaptureStateChange; 121 122 // Set the VoiceEngine for A/V sync. This can only be called before Init. 123 bool SetVoiceEngine(WebRtcVoiceEngine* voice_engine); 124 // Set a WebRtcVideoDecoderFactory for external decoding. Video engine does 125 // not take the ownership of |decoder_factory|. The caller needs to make sure 126 // that |decoder_factory| outlives the video engine. 127 void SetExternalDecoderFactory(WebRtcVideoDecoderFactory* decoder_factory); 128 // Set a WebRtcVideoEncoderFactory for external encoding. Video engine does 129 // not take the ownership of |encoder_factory|. The caller needs to make sure 130 // that |encoder_factory| outlives the video engine. 131 void SetExternalEncoderFactory(WebRtcVideoEncoderFactory* encoder_factory); 132 // Enable the render module with timing control. 133 bool EnableTimedRender(); 134 135 // Returns an external decoder for the given codec type. The return value 136 // can be NULL if decoder factory is not given or it does not support the 137 // codec type. The caller takes the ownership of the returned object. 138 webrtc::VideoDecoder* CreateExternalDecoder(webrtc::VideoCodecType type); 139 // Releases the decoder instance created by CreateExternalDecoder(). 140 void DestroyExternalDecoder(webrtc::VideoDecoder* decoder); 141 142 // Returns an external encoder for the given codec type. The return value 143 // can be NULL if encoder factory is not given or it does not support the 144 // codec type. The caller takes the ownership of the returned object. 145 webrtc::VideoEncoder* CreateExternalEncoder(webrtc::VideoCodecType type); 146 // Releases the encoder instance created by CreateExternalEncoder(). 147 void DestroyExternalEncoder(webrtc::VideoEncoder* encoder); 148 149 // Returns true if the codec type is supported by the external encoder. 150 bool IsExternalEncoderCodecType(webrtc::VideoCodecType type) const; 151 152 // Functions called by WebRtcVideoMediaChannel. 153 talk_base::Thread* worker_thread() { return worker_thread_; } 154 ViEWrapper* vie() { return vie_wrapper_.get(); } 155 const VideoFormat& default_codec_format() const { 156 return default_codec_format_; 157 } 158 int GetLastEngineError(); 159 bool FindCodec(const VideoCodec& in); 160 bool CanSendCodec(const VideoCodec& in, const VideoCodec& current, 161 VideoCodec* out); 162 void RegisterChannel(WebRtcVideoMediaChannel* channel); 163 void UnregisterChannel(WebRtcVideoMediaChannel* channel); 164 bool ConvertFromCricketVideoCodec(const VideoCodec& in_codec, 165 webrtc::VideoCodec* out_codec); 166 // Check whether the supplied trace should be ignored. 167 bool ShouldIgnoreTrace(const std::string& trace); 168 int GetNumOfChannels(); 169 170 VideoFormat GetStartCaptureFormat() const { return default_codec_format_; } 171 172 talk_base::CpuMonitor* cpu_monitor() { return cpu_monitor_.get(); } 173 174 protected: 175 // When a video processor registers with the engine. 176 // SignalMediaFrame will be invoked for every video frame. 177 // See videoprocessor.h for param reference. 178 sigslot::signal3<uint32, VideoFrame*, bool*> SignalMediaFrame; 179 180 private: 181 typedef std::vector<WebRtcVideoMediaChannel*> VideoChannels; 182 struct VideoCodecPref { 183 const char* name; 184 int payload_type; 185 // For RTX, this field is the payload-type that RTX applies to. 186 // For other codecs, it should be set to -1. 187 int associated_payload_type; 188 int pref; 189 }; 190 191 static const VideoCodecPref kVideoCodecPrefs[]; 192 static const VideoFormatPod kVideoFormats[]; 193 static const VideoFormatPod kDefaultVideoFormat; 194 195 void Construct(ViEWrapper* vie_wrapper, 196 ViETraceWrapper* tracing, 197 WebRtcVoiceEngine* voice_engine, 198 talk_base::CpuMonitor* cpu_monitor); 199 bool SetDefaultCodec(const VideoCodec& codec); 200 bool RebuildCodecList(const VideoCodec& max_codec); 201 void SetTraceFilter(int filter); 202 void SetTraceOptions(const std::string& options); 203 bool InitVideoEngine(); 204 bool VerifyApt(const VideoCodec& in, int expected_apt) const; 205 206 // webrtc::TraceCallback implementation. 207 virtual void Print(webrtc::TraceLevel level, const char* trace, int length); 208 209 // WebRtcVideoEncoderFactory::Observer implementation. 210 virtual void OnCodecsAvailable(); 211 212 talk_base::Thread* worker_thread_; 213 talk_base::scoped_ptr<ViEWrapper> vie_wrapper_; 214 bool vie_wrapper_base_initialized_; 215 talk_base::scoped_ptr<ViETraceWrapper> tracing_; 216 WebRtcVoiceEngine* voice_engine_; 217 talk_base::scoped_ptr<webrtc::VideoRender> render_module_; 218 WebRtcVideoEncoderFactory* encoder_factory_; 219 WebRtcVideoDecoderFactory* decoder_factory_; 220 std::vector<VideoCodec> video_codecs_; 221 std::vector<RtpHeaderExtension> rtp_header_extensions_; 222 VideoFormat default_codec_format_; 223 224 bool initialized_; 225 talk_base::CriticalSection channels_crit_; 226 VideoChannels channels_; 227 228 bool capture_started_; 229 int local_renderer_w_; 230 int local_renderer_h_; 231 VideoRenderer* local_renderer_; 232 233 talk_base::scoped_ptr<talk_base::CpuMonitor> cpu_monitor_; 234 }; 235 236 class WebRtcVideoMediaChannel : public talk_base::MessageHandler, 237 public VideoMediaChannel, 238 public webrtc::Transport { 239 public: 240 WebRtcVideoMediaChannel(WebRtcVideoEngine* engine, 241 VoiceMediaChannel* voice_channel); 242 ~WebRtcVideoMediaChannel(); 243 bool Init(); 244 245 WebRtcVideoEngine* engine() { return engine_; } 246 VoiceMediaChannel* voice_channel() { return voice_channel_; } 247 int video_channel() const { return vie_channel_; } 248 bool sending() const { return sending_; } 249 250 // Public for testing purpose. 251 uint32 GetDefaultChannelSsrc(); 252 253 // VideoMediaChannel implementation 254 virtual bool SetRecvCodecs(const std::vector<VideoCodec> &codecs); 255 virtual bool SetSendCodecs(const std::vector<VideoCodec> &codecs); 256 virtual bool GetSendCodec(VideoCodec* send_codec); 257 virtual bool SetSendStreamFormat(uint32 ssrc, const VideoFormat& format); 258 virtual bool SetRender(bool render); 259 virtual bool SetSend(bool send); 260 261 virtual bool AddSendStream(const StreamParams& sp); 262 virtual bool RemoveSendStream(uint32 ssrc); 263 virtual bool AddRecvStream(const StreamParams& sp); 264 virtual bool RemoveRecvStream(uint32 ssrc); 265 virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer); 266 virtual bool GetStats(const StatsOptions& options, VideoMediaInfo* info); 267 virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer); 268 virtual bool SendIntraFrame(); 269 virtual bool RequestIntraFrame(); 270 271 virtual void OnPacketReceived(talk_base::Buffer* packet, 272 const talk_base::PacketTime& packet_time); 273 virtual void OnRtcpReceived(talk_base::Buffer* packet, 274 const talk_base::PacketTime& packet_time); 275 virtual void OnReadyToSend(bool ready); 276 virtual bool MuteStream(uint32 ssrc, bool on); 277 virtual bool SetRecvRtpHeaderExtensions( 278 const std::vector<RtpHeaderExtension>& extensions); 279 virtual bool SetSendRtpHeaderExtensions( 280 const std::vector<RtpHeaderExtension>& extensions); 281 virtual int GetRtpSendTimeExtnId() const; 282 virtual bool SetStartSendBandwidth(int bps); 283 virtual bool SetMaxSendBandwidth(int bps); 284 virtual bool SetOptions(const VideoOptions &options); 285 virtual bool GetOptions(VideoOptions *options) const { 286 *options = options_; 287 return true; 288 } 289 virtual void SetInterface(NetworkInterface* iface); 290 virtual void UpdateAspectRatio(int ratio_w, int ratio_h); 291 292 // Public functions for use by tests and other specialized code. 293 uint32 send_ssrc() const { return 0; } 294 bool GetRenderer(uint32 ssrc, VideoRenderer** renderer); 295 bool GetVideoAdapter(uint32 ssrc, CoordinatedVideoAdapter** video_adapter); 296 void SendFrame(VideoCapturer* capturer, const VideoFrame* frame); 297 bool SendFrame(WebRtcVideoChannelSendInfo* channel_info, 298 const VideoFrame* frame, bool is_screencast); 299 300 // Thunk functions for use with HybridVideoEngine 301 void OnLocalFrame(VideoCapturer* capturer, const VideoFrame* frame) { 302 SendFrame(0u, frame, capturer->IsScreencast()); 303 } 304 void OnLocalFrameFormat(VideoCapturer* capturer, const VideoFormat* format) { 305 } 306 307 virtual void OnMessage(talk_base::Message* msg); 308 309 protected: 310 int GetLastEngineError() { return engine()->GetLastEngineError(); } 311 virtual int SendPacket(int channel, const void* data, int len); 312 virtual int SendRTCPPacket(int channel, const void* data, int len); 313 314 private: 315 typedef std::map<uint32, WebRtcVideoChannelRecvInfo*> RecvChannelMap; 316 typedef std::map<uint32, WebRtcVideoChannelSendInfo*> SendChannelMap; 317 typedef std::map<uint32, uint32> SsrcMap; 318 typedef int (webrtc::ViERTP_RTCP::* ExtensionSetterFunction)(int, bool, int); 319 320 enum MediaDirection { MD_RECV, MD_SEND, MD_SENDRECV }; 321 322 // Creates and initializes a ViE channel. When successful |channel_id| will 323 // contain the new channel's ID. If |receiving| is true |ssrc| is the 324 // remote ssrc. If |sending| is true the ssrc is local ssrc. If both 325 // |receiving| and |sending| is true the ssrc must be 0 and the channel will 326 // be created as a default channel. The ssrc must be different for receive 327 // channels and it must be different for send channels. If the same SSRC is 328 // being used for creating channel more than once, this function will fail 329 // returning false. 330 bool CreateChannel(uint32 ssrc_key, MediaDirection direction, 331 int* channel_id); 332 bool CreateUnsignalledRecvChannel(uint32 ssrc_key, int* channel_id); 333 bool ConfigureChannel(int channel_id, MediaDirection direction, 334 uint32 ssrc_key); 335 bool ConfigureReceiving(int channel_id, uint32 remote_ssrc_key); 336 bool ConfigureSending(int channel_id, uint32 local_ssrc_key); 337 bool SetNackFec(int channel_id, int red_payload_type, int fec_payload_type, 338 bool nack_enabled); 339 bool SetSendCodec(const webrtc::VideoCodec& codec); 340 bool SetSendCodec(WebRtcVideoChannelSendInfo* send_channel, 341 const webrtc::VideoCodec& codec); 342 void LogSendCodecChange(const std::string& reason); 343 // Prepares the channel with channel id |info->channel_id()| to receive all 344 // codecs in |receive_codecs_| and start receive packets. 345 bool SetReceiveCodecs(WebRtcVideoChannelRecvInfo* info); 346 // Returns the channel number that receives the stream with SSRC |ssrc|. 347 int GetRecvChannelNum(uint32 ssrc); 348 bool MaybeSetRtxSsrc(const StreamParams& sp, int channel_id); 349 // Given captured video frame size, checks if we need to reset vie send codec. 350 // |reset| is set to whether resetting has happened on vie or not. 351 // Returns false on error. 352 bool MaybeResetVieSendCodec(WebRtcVideoChannelSendInfo* send_channel, 353 int new_width, int new_height, bool is_screencast, 354 bool* reset); 355 // Checks the current bitrate estimate and modifies the bitrates 356 // accordingly, including converting kAutoBandwidth to the correct defaults. 357 void MaybeChangeBitrates(int channel_id, webrtc::VideoCodec* video_codec); 358 // Helper function for starting the sending of media on all channels or 359 // |channel_id|. Note that these two function do not change |sending_|. 360 bool StartSend(); 361 bool StartSend(WebRtcVideoChannelSendInfo* send_channel); 362 // Helper function for stop the sending of media on all channels or 363 // |channel_id|. Note that these two function do not change |sending_|. 364 bool StopSend(); 365 bool StopSend(WebRtcVideoChannelSendInfo* send_channel); 366 bool SendIntraFrame(int channel_id); 367 368 bool HasReadySendChannels(); 369 370 // Send channel key returns the key corresponding to the provided local SSRC 371 // in |key|. The return value is true upon success. 372 // If the local ssrc correspond to that of the default channel the key is 0. 373 // For all other channels the returned key will be the same as the local ssrc. 374 bool GetSendChannelKey(uint32 local_ssrc, uint32* key); 375 WebRtcVideoChannelSendInfo* GetSendChannel(uint32 local_ssrc); 376 // Creates a new unique key that can be used for inserting a new send channel 377 // into |send_channels_| 378 bool CreateSendChannelKey(uint32 local_ssrc, uint32* key); 379 // Get the number of the send channels |capturer| registered with. 380 int GetSendChannelNum(VideoCapturer* capturer); 381 382 bool IsDefaultChannel(int channel_id) const { 383 return channel_id == vie_channel_; 384 } 385 386 bool DeleteSendChannel(uint32 ssrc_key); 387 388 bool InConferenceMode() const { 389 return options_.conference_mode.GetWithDefaultIfUnset(false); 390 } 391 bool RemoveCapturer(uint32 ssrc); 392 393 394 talk_base::MessageQueue* worker_thread() { return engine_->worker_thread(); } 395 void QueueBlackFrame(uint32 ssrc, int64 timestamp, int framerate); 396 void FlushBlackFrame(uint32 ssrc, int64 timestamp); 397 398 void SetNetworkTransmissionState(bool is_transmitting); 399 400 bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id, 401 const RtpHeaderExtension* extension); 402 bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id, 403 const std::vector<RtpHeaderExtension>& extensions, 404 const char header_extension_uri[]); 405 406 // Signal when cpu adaptation has no further scope to adapt. 407 void OnCpuAdaptationUnable(); 408 409 // Set the local (send-side) RTX SSRC corresponding to primary_ssrc. 410 bool SetLocalRtxSsrc(int channel_id, const StreamParams& send_params, 411 uint32 primary_ssrc, int stream_idx); 412 413 // Connect |capturer| to WebRtcVideoMediaChannel if it is only registered 414 // to one send channel, i.e. the first send channel. 415 void MaybeConnectCapturer(VideoCapturer* capturer); 416 // Disconnect |capturer| from WebRtcVideoMediaChannel if it is only registered 417 // to one send channel, i.e. the last send channel. 418 void MaybeDisconnectCapturer(VideoCapturer* capturer); 419 420 bool RemoveRecvStreamInternal(uint32 ssrc); 421 422 // Global state. 423 WebRtcVideoEngine* engine_; 424 VoiceMediaChannel* voice_channel_; 425 int vie_channel_; 426 bool nack_enabled_; 427 // Receiver Estimated Max Bitrate 428 bool remb_enabled_; 429 VideoOptions options_; 430 431 // Global recv side state. 432 // Note the default channel (vie_channel_), i.e. the send channel 433 // corresponding to all the receive channels (this must be done for REMB to 434 // work properly), resides in both recv_channels_ and send_channels_ with the 435 // ssrc key 0. 436 RecvChannelMap recv_channels_; // Contains all receive channels. 437 // A map from the SSRCs on which RTX packets are received to the media SSRCs 438 // the RTX packets are associated with. RTX packets will be delivered to the 439 // streams matching the primary SSRC. 440 SsrcMap rtx_to_primary_ssrc_; 441 std::vector<webrtc::VideoCodec> receive_codecs_; 442 // A map from codec payload types to their associated payload types, if any. 443 // TODO(holmer): This is a temporary solution until webrtc::VideoCodec has 444 // an associated payload type member, when it does we can rely on 445 // receive_codecs_. 446 std::map<int, int> associated_payload_types_; 447 bool render_started_; 448 uint32 first_receive_ssrc_; 449 std::vector<RtpHeaderExtension> receive_extensions_; 450 int num_unsignalled_recv_channels_; 451 452 // Global send side state. 453 SendChannelMap send_channels_; 454 talk_base::scoped_ptr<webrtc::VideoCodec> send_codec_; 455 int send_rtx_type_; 456 int send_red_type_; 457 int send_fec_type_; 458 bool sending_; 459 std::vector<RtpHeaderExtension> send_extensions_; 460 461 // The aspect ratio that the channel desires. 0 means there is no desired 462 // aspect ratio 463 int ratio_w_; 464 int ratio_h_; 465 }; 466 467 } // namespace cricket 468 469 #endif // TALK_MEDIA_WEBRTCVIDEOENGINE_H_ 470