1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,339 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef VIDEO_SESSION_H_ 1.9 +#define VIDEO_SESSION_H_ 1.10 + 1.11 +#include "mozilla/Attributes.h" 1.12 + 1.13 +#include "MediaConduitInterface.h" 1.14 +#include "MediaEngineWrapper.h" 1.15 + 1.16 +// Video Engine Includes 1.17 +#include "webrtc/common_types.h" 1.18 +#ifdef FF 1.19 +#undef FF // Avoid name collision between scoped_ptr.h and nsCRTGlue.h. 1.20 +#endif 1.21 +#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" 1.22 +#include "webrtc/video_engine/include/vie_base.h" 1.23 +#include "webrtc/video_engine/include/vie_capture.h" 1.24 +#include "webrtc/video_engine/include/vie_codec.h" 1.25 +#include "webrtc/video_engine/include/vie_external_codec.h" 1.26 +#include "webrtc/video_engine/include/vie_render.h" 1.27 +#include "webrtc/video_engine/include/vie_network.h" 1.28 +#include "webrtc/video_engine/include/vie_rtp_rtcp.h" 1.29 + 1.30 +/** This file hosts several structures identifying different aspects 1.31 + * of a RTP Session. 1.32 + */ 1.33 + 1.34 + using webrtc::ViEBase; 1.35 + using webrtc::ViENetwork; 1.36 + using webrtc::ViECodec; 1.37 + using webrtc::ViECapture; 1.38 + using webrtc::ViERender; 1.39 + using webrtc::ViEExternalCapture; 1.40 + using webrtc::ViEExternalCodec; 1.41 + 1.42 +namespace mozilla { 1.43 + 1.44 +class WebrtcAudioConduit; 1.45 + 1.46 +// Interface of external video encoder for WebRTC. 1.47 +class WebrtcVideoEncoder:public VideoEncoder 1.48 + ,public webrtc::VideoEncoder 1.49 +{}; 1.50 + 1.51 +// Interface of external video decoder for WebRTC. 1.52 +class WebrtcVideoDecoder:public VideoDecoder 1.53 + ,public webrtc::VideoDecoder 1.54 +{}; 1.55 + 1.56 +/** 1.57 + * Concrete class for Video session. Hooks up 1.58 + * - media-source and target to external transport 1.59 + */ 1.60 +class WebrtcVideoConduit:public VideoSessionConduit 1.61 + ,public webrtc::Transport 1.62 + ,public webrtc::ExternalRenderer 1.63 +{ 1.64 +public: 1.65 + //VoiceEngine defined constant for Payload Name Size. 1.66 + static const unsigned int CODEC_PLNAME_SIZE; 1.67 + 1.68 + /** 1.69 + * Set up A/V sync between this (incoming) VideoConduit and an audio conduit. 1.70 + */ 1.71 + void SyncTo(WebrtcAudioConduit *aConduit); 1.72 + 1.73 + /** 1.74 + * Function to attach Renderer end-point for the Media-Video conduit. 1.75 + * @param aRenderer : Reference to the concrete Video renderer implementation 1.76 + * Note: Multiple invocations of this API shall remove an existing renderer 1.77 + * and attaches the new to the Conduit. 1.78 + */ 1.79 + virtual MediaConduitErrorCode AttachRenderer(mozilla::RefPtr<VideoRenderer> aVideoRenderer); 1.80 + virtual void DetachRenderer(); 1.81 + 1.82 + /** 1.83 + * APIs used by the registered external transport to this Conduit to 1.84 + * feed in received RTP Frames to the VideoEngine for decoding 1.85 + */ 1.86 + virtual MediaConduitErrorCode ReceivedRTPPacket(const void *data, int len); 1.87 + 1.88 + /** 1.89 + * APIs used by the registered external transport to this Conduit to 1.90 + * feed in received RTP Frames to the VideoEngine for decoding 1.91 + */ 1.92 + virtual MediaConduitErrorCode ReceivedRTCPPacket(const void *data, int len); 1.93 + 1.94 + /** 1.95 + * Function to configure send codec for the video session 1.96 + * @param sendSessionConfig: CodecConfiguration 1.97 + * @result: On Success, the video engine is configured with passed in codec for send 1.98 + * On failure, video engine transmit functionality is disabled. 1.99 + * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting 1.100 + * transmission sub-system on the engine. 1.101 + */ 1.102 + virtual MediaConduitErrorCode ConfigureSendMediaCodec(const VideoCodecConfig* codecInfo); 1.103 + 1.104 + /** 1.105 + * Function to configure list of receive codecs for the video session 1.106 + * @param sendSessionConfig: CodecConfiguration 1.107 + * @result: On Success, the video engine is configured with passed in codec for send 1.108 + * Also the playout is enabled. 1.109 + * On failure, video engine transmit functionality is disabled. 1.110 + * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting 1.111 + * transmission sub-system on the engine. 1.112 + */ 1.113 + virtual MediaConduitErrorCode ConfigureRecvMediaCodecs( 1.114 + const std::vector<VideoCodecConfig* >& codecConfigList); 1.115 + 1.116 + /** 1.117 + * Register Transport for this Conduit. RTP and RTCP frames from the VideoEngine 1.118 + * shall be passed to the registered transport for transporting externally. 1.119 + */ 1.120 + virtual MediaConduitErrorCode AttachTransport(mozilla::RefPtr<TransportInterface> aTransport); 1.121 + 1.122 + /** 1.123 + * Function to select and change the encoding resolution based on incoming frame size 1.124 + * and current available bandwidth. 1.125 + * @param width, height: dimensions of the frame 1.126 + */ 1.127 + virtual bool SelectSendResolution(unsigned short width, 1.128 + unsigned short height); 1.129 + 1.130 + /** 1.131 + * Function to deliver a capture video frame for encoding and transport 1.132 + * @param video_frame: pointer to captured video-frame. 1.133 + * @param video_frame_length: size of the frame 1.134 + * @param width, height: dimensions of the frame 1.135 + * @param video_type: Type of the video frame - I420, RAW 1.136 + * @param captured_time: timestamp when the frame was captured. 1.137 + * if 0 timestamp is automatcally generated by the engine. 1.138 + *NOTE: ConfigureSendMediaCodec() SHOULD be called before this function can be invoked 1.139 + * This ensures the inserted video-frames can be transmitted by the conduit 1.140 + */ 1.141 + virtual MediaConduitErrorCode SendVideoFrame(unsigned char* video_frame, 1.142 + unsigned int video_frame_length, 1.143 + unsigned short width, 1.144 + unsigned short height, 1.145 + VideoType video_type, 1.146 + uint64_t capture_time); 1.147 + 1.148 + /** 1.149 + * Set an external encoder object |encoder| to the payload type |pltype| 1.150 + * for sender side codec. 1.151 + */ 1.152 + virtual MediaConduitErrorCode SetExternalSendCodec(int pltype, 1.153 + VideoEncoder* encoder); 1.154 + 1.155 + /** 1.156 + * Set an external decoder object |decoder| to the payload type |pltype| 1.157 + * for receiver side codec. 1.158 + */ 1.159 + virtual MediaConduitErrorCode SetExternalRecvCodec(int pltype, 1.160 + VideoDecoder* decoder); 1.161 + 1.162 + 1.163 + /** 1.164 + * Webrtc transport implementation to send and receive RTP packet. 1.165 + * VideoConduit registers itself as ExternalTransport to the VideoEngine 1.166 + */ 1.167 + virtual int SendPacket(int channel, const void *data, int len) ; 1.168 + 1.169 + /** 1.170 + * Webrtc transport implementation to send and receive RTCP packet. 1.171 + * VideoConduit registers itself as ExternalTransport to the VideoEngine 1.172 + */ 1.173 + virtual int SendRTCPPacket(int channel, const void *data, int len) ; 1.174 + 1.175 + 1.176 + /** 1.177 + * Webrtc External Renderer Implementation APIs. 1.178 + * Raw I420 Frames are delivred to the VideoConduit by the VideoEngine 1.179 + */ 1.180 + virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int); 1.181 + 1.182 + virtual int DeliverFrame(unsigned char*,int, uint32_t , int64_t, 1.183 + void *handle); 1.184 + 1.185 + /** 1.186 + * Does DeliverFrame() support a null buffer and non-null handle 1.187 + * (video texture)? 1.188 + * B2G support it (when using HW video decoder with graphic buffer output). 1.189 + * XXX Investigate! Especially for Android 1.190 + */ 1.191 + virtual bool IsTextureSupported() { 1.192 +#ifdef WEBRTC_GONK 1.193 + return true; 1.194 +#else 1.195 + return false; 1.196 +#endif 1.197 + } 1.198 + 1.199 + unsigned short SendingWidth() { 1.200 + return mSendingWidth; 1.201 + } 1.202 + 1.203 + unsigned short SendingHeight() { 1.204 + return mSendingHeight; 1.205 + } 1.206 + 1.207 + unsigned int SendingMaxFs() { 1.208 + if(mCurSendCodecConfig) { 1.209 + return mCurSendCodecConfig->mMaxFrameSize; 1.210 + } 1.211 + return 0; 1.212 + } 1.213 + 1.214 + unsigned int SendingMaxFr() { 1.215 + if(mCurSendCodecConfig) { 1.216 + return mCurSendCodecConfig->mMaxFrameRate; 1.217 + } 1.218 + return 0; 1.219 + } 1.220 + 1.221 + WebrtcVideoConduit(): 1.222 + mOtherDirection(nullptr), 1.223 + mShutDown(false), 1.224 + mVideoEngine(nullptr), 1.225 + mTransport(nullptr), 1.226 + mRenderer(nullptr), 1.227 + mPtrExtCapture(nullptr), 1.228 + mEngineTransmitting(false), 1.229 + mEngineReceiving(false), 1.230 + mChannel(-1), 1.231 + mCapId(-1), 1.232 + mCurSendCodecConfig(nullptr), 1.233 + mSendingWidth(0), 1.234 + mSendingHeight(0), 1.235 + mReceivingWidth(640), 1.236 + mReceivingHeight(480), 1.237 + mVideoLatencyTestEnable(false), 1.238 + mVideoLatencyAvg(0) 1.239 + { 1.240 + } 1.241 + 1.242 + virtual ~WebrtcVideoConduit() ; 1.243 + 1.244 + MediaConduitErrorCode Init(WebrtcVideoConduit *other); 1.245 + 1.246 + int GetChannel() { return mChannel; } 1.247 + webrtc::VideoEngine* GetVideoEngine() { return mVideoEngine; } 1.248 + bool GetLocalSSRC(unsigned int* ssrc); 1.249 + bool GetRemoteSSRC(unsigned int* ssrc); 1.250 + bool GetAVStats(int32_t* jitterBufferDelayMs, 1.251 + int32_t* playoutBufferDelayMs, 1.252 + int32_t* avSyncOffsetMs); 1.253 + bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost); 1.254 + bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, 1.255 + uint32_t* jitterMs, 1.256 + uint32_t* packetsReceived, 1.257 + uint64_t* bytesReceived, 1.258 + uint32_t* cumulativeLost, 1.259 + int32_t* rttMs); 1.260 + bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, 1.261 + unsigned int* packetsSent, 1.262 + uint64_t* bytesSent); 1.263 + uint64_t MozVideoLatencyAvg(); 1.264 + 1.265 +private: 1.266 + 1.267 + WebrtcVideoConduit(const WebrtcVideoConduit& other) MOZ_DELETE; 1.268 + void operator=(const WebrtcVideoConduit& other) MOZ_DELETE; 1.269 + 1.270 + //Local database of currently applied receive codecs 1.271 + typedef std::vector<VideoCodecConfig* > RecvCodecList; 1.272 + 1.273 + //Function to convert between WebRTC and Conduit codec structures 1.274 + void CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo, 1.275 + webrtc::VideoCodec& cinst); 1.276 + 1.277 + // Function to copy a codec structure to Conduit's database 1.278 + bool CopyCodecToDB(const VideoCodecConfig* codecInfo); 1.279 + 1.280 + // Functions to verify if the codec passed is already in 1.281 + // conduits database 1.282 + bool CheckCodecForMatch(const VideoCodecConfig* codecInfo) const; 1.283 + bool CheckCodecsForMatch(const VideoCodecConfig* curCodecConfig, 1.284 + const VideoCodecConfig* codecInfo) const; 1.285 + 1.286 + //Checks the codec to be applied 1.287 + MediaConduitErrorCode ValidateCodecConfig(const VideoCodecConfig* codecInfo, bool send) const; 1.288 + 1.289 + //Utility function to dump recv codec database 1.290 + void DumpCodecDB() const; 1.291 + 1.292 + // Video Latency Test averaging filter 1.293 + void VideoLatencyUpdate(uint64_t new_sample); 1.294 + 1.295 + // The two sides of a send/receive pair of conduits each keep a pointer to the other. 1.296 + // They also share a single VideoEngine and mChannel. Shutdown must be coordinated 1.297 + // carefully to avoid double-freeing or accessing after one frees. 1.298 + WebrtcVideoConduit* mOtherDirection; 1.299 + // The other side has shut down our mChannel and related items already 1.300 + bool mShutDown; 1.301 + 1.302 + // A few of these are shared by both directions. They're released by the last 1.303 + // conduit to die. 1.304 + webrtc::VideoEngine* mVideoEngine; // shared 1.305 + mozilla::RefPtr<TransportInterface> mTransport; 1.306 + mozilla::RefPtr<VideoRenderer> mRenderer; 1.307 + 1.308 + ScopedCustomReleasePtr<webrtc::ViEBase> mPtrViEBase; 1.309 + ScopedCustomReleasePtr<webrtc::ViECapture> mPtrViECapture; 1.310 + ScopedCustomReleasePtr<webrtc::ViECodec> mPtrViECodec; 1.311 + ScopedCustomReleasePtr<webrtc::ViENetwork> mPtrViENetwork; 1.312 + ScopedCustomReleasePtr<webrtc::ViERender> mPtrViERender; 1.313 + ScopedCustomReleasePtr<webrtc::ViERTP_RTCP> mPtrRTP; 1.314 + ScopedCustomReleasePtr<webrtc::ViEExternalCodec> mPtrExtCodec; 1.315 + 1.316 + webrtc::ViEExternalCapture* mPtrExtCapture; // shared 1.317 + 1.318 + // Engine state we are concerned with. 1.319 + bool mEngineTransmitting; //If true ==> Transmit Sub-system is up and running 1.320 + bool mEngineReceiving; // if true ==> Receive Sus-sysmtem up and running 1.321 + 1.322 + int mChannel; // Video Channel for this conduit 1.323 + int mCapId; // Capturer for this conduit 1.324 + RecvCodecList mRecvCodecList; 1.325 + VideoCodecConfig* mCurSendCodecConfig; 1.326 + unsigned short mSendingWidth; 1.327 + unsigned short mSendingHeight; 1.328 + unsigned short mReceivingWidth; 1.329 + unsigned short mReceivingHeight; 1.330 + bool mVideoLatencyTestEnable; 1.331 + uint64_t mVideoLatencyAvg; 1.332 + 1.333 + static const unsigned int sAlphaNum = 7; 1.334 + static const unsigned int sAlphaDen = 8; 1.335 + static const unsigned int sRoundingPadding = 1024; 1.336 + 1.337 + mozilla::RefPtr<WebrtcAudioConduit> mSyncedTo; 1.338 +}; 1.339 + 1.340 +} // end namespace 1.341 + 1.342 +#endif