michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef VIDEO_SESSION_H_ michael@0: #define VIDEO_SESSION_H_ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: #include "MediaConduitInterface.h" michael@0: #include "MediaEngineWrapper.h" michael@0: michael@0: // Video Engine Includes michael@0: #include "webrtc/common_types.h" michael@0: #ifdef FF michael@0: #undef FF // Avoid name collision between scoped_ptr.h and nsCRTGlue.h. michael@0: #endif michael@0: #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" michael@0: #include "webrtc/video_engine/include/vie_base.h" michael@0: #include "webrtc/video_engine/include/vie_capture.h" michael@0: #include "webrtc/video_engine/include/vie_codec.h" michael@0: #include "webrtc/video_engine/include/vie_external_codec.h" michael@0: #include "webrtc/video_engine/include/vie_render.h" michael@0: #include "webrtc/video_engine/include/vie_network.h" michael@0: #include "webrtc/video_engine/include/vie_rtp_rtcp.h" michael@0: michael@0: /** This file hosts several structures identifying different aspects michael@0: * of a RTP Session. michael@0: */ michael@0: michael@0: using webrtc::ViEBase; michael@0: using webrtc::ViENetwork; michael@0: using webrtc::ViECodec; michael@0: using webrtc::ViECapture; michael@0: using webrtc::ViERender; michael@0: using webrtc::ViEExternalCapture; michael@0: using webrtc::ViEExternalCodec; michael@0: michael@0: namespace mozilla { michael@0: michael@0: class WebrtcAudioConduit; michael@0: michael@0: // Interface of external video encoder for WebRTC. michael@0: class WebrtcVideoEncoder:public VideoEncoder michael@0: ,public webrtc::VideoEncoder michael@0: {}; michael@0: michael@0: // Interface of external video decoder for WebRTC. michael@0: class WebrtcVideoDecoder:public VideoDecoder michael@0: ,public webrtc::VideoDecoder michael@0: {}; michael@0: michael@0: /** michael@0: * Concrete class for Video session. Hooks up michael@0: * - media-source and target to external transport michael@0: */ michael@0: class WebrtcVideoConduit:public VideoSessionConduit michael@0: ,public webrtc::Transport michael@0: ,public webrtc::ExternalRenderer michael@0: { michael@0: public: michael@0: //VoiceEngine defined constant for Payload Name Size. michael@0: static const unsigned int CODEC_PLNAME_SIZE; michael@0: michael@0: /** michael@0: * Set up A/V sync between this (incoming) VideoConduit and an audio conduit. michael@0: */ michael@0: void SyncTo(WebrtcAudioConduit *aConduit); michael@0: michael@0: /** michael@0: * Function to attach Renderer end-point for the Media-Video conduit. michael@0: * @param aRenderer : Reference to the concrete Video renderer implementation michael@0: * Note: Multiple invocations of this API shall remove an existing renderer michael@0: * and attaches the new to the Conduit. michael@0: */ michael@0: virtual MediaConduitErrorCode AttachRenderer(mozilla::RefPtr aVideoRenderer); michael@0: virtual void DetachRenderer(); michael@0: michael@0: /** michael@0: * APIs used by the registered external transport to this Conduit to michael@0: * feed in received RTP Frames to the VideoEngine for decoding michael@0: */ michael@0: virtual MediaConduitErrorCode ReceivedRTPPacket(const void *data, int len); michael@0: michael@0: /** michael@0: * APIs used by the registered external transport to this Conduit to michael@0: * feed in received RTP Frames to the VideoEngine for decoding michael@0: */ michael@0: virtual MediaConduitErrorCode ReceivedRTCPPacket(const void *data, int len); michael@0: michael@0: /** michael@0: * Function to configure send codec for the video session michael@0: * @param sendSessionConfig: CodecConfiguration michael@0: * @result: On Success, the video engine is configured with passed in codec for send michael@0: * On failure, video engine transmit functionality is disabled. michael@0: * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting michael@0: * transmission sub-system on the engine. michael@0: */ michael@0: virtual MediaConduitErrorCode ConfigureSendMediaCodec(const VideoCodecConfig* codecInfo); michael@0: michael@0: /** michael@0: * Function to configure list of receive codecs for the video session michael@0: * @param sendSessionConfig: CodecConfiguration michael@0: * @result: On Success, the video engine is configured with passed in codec for send michael@0: * Also the playout is enabled. michael@0: * On failure, video engine transmit functionality is disabled. michael@0: * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting michael@0: * transmission sub-system on the engine. michael@0: */ michael@0: virtual MediaConduitErrorCode ConfigureRecvMediaCodecs( michael@0: const std::vector& codecConfigList); michael@0: michael@0: /** michael@0: * Register Transport for this Conduit. RTP and RTCP frames from the VideoEngine michael@0: * shall be passed to the registered transport for transporting externally. michael@0: */ michael@0: virtual MediaConduitErrorCode AttachTransport(mozilla::RefPtr aTransport); michael@0: michael@0: /** michael@0: * Function to select and change the encoding resolution based on incoming frame size michael@0: * and current available bandwidth. michael@0: * @param width, height: dimensions of the frame michael@0: */ michael@0: virtual bool SelectSendResolution(unsigned short width, michael@0: unsigned short height); michael@0: michael@0: /** michael@0: * Function to deliver a capture video frame for encoding and transport michael@0: * @param video_frame: pointer to captured video-frame. michael@0: * @param video_frame_length: size of the frame michael@0: * @param width, height: dimensions of the frame michael@0: * @param video_type: Type of the video frame - I420, RAW michael@0: * @param captured_time: timestamp when the frame was captured. michael@0: * if 0 timestamp is automatcally generated by the engine. michael@0: *NOTE: ConfigureSendMediaCodec() SHOULD be called before this function can be invoked michael@0: * This ensures the inserted video-frames can be transmitted by the conduit michael@0: */ michael@0: virtual MediaConduitErrorCode SendVideoFrame(unsigned char* video_frame, michael@0: unsigned int video_frame_length, michael@0: unsigned short width, michael@0: unsigned short height, michael@0: VideoType video_type, michael@0: uint64_t capture_time); michael@0: michael@0: /** michael@0: * Set an external encoder object |encoder| to the payload type |pltype| michael@0: * for sender side codec. michael@0: */ michael@0: virtual MediaConduitErrorCode SetExternalSendCodec(int pltype, michael@0: VideoEncoder* encoder); michael@0: michael@0: /** michael@0: * Set an external decoder object |decoder| to the payload type |pltype| michael@0: * for receiver side codec. michael@0: */ michael@0: virtual MediaConduitErrorCode SetExternalRecvCodec(int pltype, michael@0: VideoDecoder* decoder); michael@0: michael@0: michael@0: /** michael@0: * Webrtc transport implementation to send and receive RTP packet. michael@0: * VideoConduit registers itself as ExternalTransport to the VideoEngine michael@0: */ michael@0: virtual int SendPacket(int channel, const void *data, int len) ; michael@0: michael@0: /** michael@0: * Webrtc transport implementation to send and receive RTCP packet. michael@0: * VideoConduit registers itself as ExternalTransport to the VideoEngine michael@0: */ michael@0: virtual int SendRTCPPacket(int channel, const void *data, int len) ; michael@0: michael@0: michael@0: /** michael@0: * Webrtc External Renderer Implementation APIs. michael@0: * Raw I420 Frames are delivred to the VideoConduit by the VideoEngine michael@0: */ michael@0: virtual int FrameSizeChange(unsigned int, unsigned int, unsigned int); michael@0: michael@0: virtual int DeliverFrame(unsigned char*,int, uint32_t , int64_t, michael@0: void *handle); michael@0: michael@0: /** michael@0: * Does DeliverFrame() support a null buffer and non-null handle michael@0: * (video texture)? michael@0: * B2G support it (when using HW video decoder with graphic buffer output). michael@0: * XXX Investigate! Especially for Android michael@0: */ michael@0: virtual bool IsTextureSupported() { michael@0: #ifdef WEBRTC_GONK michael@0: return true; michael@0: #else michael@0: return false; michael@0: #endif michael@0: } michael@0: michael@0: unsigned short SendingWidth() { michael@0: return mSendingWidth; michael@0: } michael@0: michael@0: unsigned short SendingHeight() { michael@0: return mSendingHeight; michael@0: } michael@0: michael@0: unsigned int SendingMaxFs() { michael@0: if(mCurSendCodecConfig) { michael@0: return mCurSendCodecConfig->mMaxFrameSize; michael@0: } michael@0: return 0; michael@0: } michael@0: michael@0: unsigned int SendingMaxFr() { michael@0: if(mCurSendCodecConfig) { michael@0: return mCurSendCodecConfig->mMaxFrameRate; michael@0: } michael@0: return 0; michael@0: } michael@0: michael@0: WebrtcVideoConduit(): michael@0: mOtherDirection(nullptr), michael@0: mShutDown(false), michael@0: mVideoEngine(nullptr), michael@0: mTransport(nullptr), michael@0: mRenderer(nullptr), michael@0: mPtrExtCapture(nullptr), michael@0: mEngineTransmitting(false), michael@0: mEngineReceiving(false), michael@0: mChannel(-1), michael@0: mCapId(-1), michael@0: mCurSendCodecConfig(nullptr), michael@0: mSendingWidth(0), michael@0: mSendingHeight(0), michael@0: mReceivingWidth(640), michael@0: mReceivingHeight(480), michael@0: mVideoLatencyTestEnable(false), michael@0: mVideoLatencyAvg(0) michael@0: { michael@0: } michael@0: michael@0: virtual ~WebrtcVideoConduit() ; michael@0: michael@0: MediaConduitErrorCode Init(WebrtcVideoConduit *other); michael@0: michael@0: int GetChannel() { return mChannel; } michael@0: webrtc::VideoEngine* GetVideoEngine() { return mVideoEngine; } michael@0: bool GetLocalSSRC(unsigned int* ssrc); michael@0: bool GetRemoteSSRC(unsigned int* ssrc); michael@0: bool GetAVStats(int32_t* jitterBufferDelayMs, michael@0: int32_t* playoutBufferDelayMs, michael@0: int32_t* avSyncOffsetMs); michael@0: bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost); michael@0: bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp, michael@0: uint32_t* jitterMs, michael@0: uint32_t* packetsReceived, michael@0: uint64_t* bytesReceived, michael@0: uint32_t* cumulativeLost, michael@0: int32_t* rttMs); michael@0: bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp, michael@0: unsigned int* packetsSent, michael@0: uint64_t* bytesSent); michael@0: uint64_t MozVideoLatencyAvg(); michael@0: michael@0: private: michael@0: michael@0: WebrtcVideoConduit(const WebrtcVideoConduit& other) MOZ_DELETE; michael@0: void operator=(const WebrtcVideoConduit& other) MOZ_DELETE; michael@0: michael@0: //Local database of currently applied receive codecs michael@0: typedef std::vector RecvCodecList; michael@0: michael@0: //Function to convert between WebRTC and Conduit codec structures michael@0: void CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo, michael@0: webrtc::VideoCodec& cinst); michael@0: michael@0: // Function to copy a codec structure to Conduit's database michael@0: bool CopyCodecToDB(const VideoCodecConfig* codecInfo); michael@0: michael@0: // Functions to verify if the codec passed is already in michael@0: // conduits database michael@0: bool CheckCodecForMatch(const VideoCodecConfig* codecInfo) const; michael@0: bool CheckCodecsForMatch(const VideoCodecConfig* curCodecConfig, michael@0: const VideoCodecConfig* codecInfo) const; michael@0: michael@0: //Checks the codec to be applied michael@0: MediaConduitErrorCode ValidateCodecConfig(const VideoCodecConfig* codecInfo, bool send) const; michael@0: michael@0: //Utility function to dump recv codec database michael@0: void DumpCodecDB() const; michael@0: michael@0: // Video Latency Test averaging filter michael@0: void VideoLatencyUpdate(uint64_t new_sample); michael@0: michael@0: // The two sides of a send/receive pair of conduits each keep a pointer to the other. michael@0: // They also share a single VideoEngine and mChannel. Shutdown must be coordinated michael@0: // carefully to avoid double-freeing or accessing after one frees. michael@0: WebrtcVideoConduit* mOtherDirection; michael@0: // The other side has shut down our mChannel and related items already michael@0: bool mShutDown; michael@0: michael@0: // A few of these are shared by both directions. They're released by the last michael@0: // conduit to die. michael@0: webrtc::VideoEngine* mVideoEngine; // shared michael@0: mozilla::RefPtr mTransport; michael@0: mozilla::RefPtr mRenderer; michael@0: michael@0: ScopedCustomReleasePtr mPtrViEBase; michael@0: ScopedCustomReleasePtr mPtrViECapture; michael@0: ScopedCustomReleasePtr mPtrViECodec; michael@0: ScopedCustomReleasePtr mPtrViENetwork; michael@0: ScopedCustomReleasePtr mPtrViERender; michael@0: ScopedCustomReleasePtr mPtrRTP; michael@0: ScopedCustomReleasePtr mPtrExtCodec; michael@0: michael@0: webrtc::ViEExternalCapture* mPtrExtCapture; // shared michael@0: michael@0: // Engine state we are concerned with. michael@0: bool mEngineTransmitting; //If true ==> Transmit Sub-system is up and running michael@0: bool mEngineReceiving; // if true ==> Receive Sus-sysmtem up and running michael@0: michael@0: int mChannel; // Video Channel for this conduit michael@0: int mCapId; // Capturer for this conduit michael@0: RecvCodecList mRecvCodecList; michael@0: VideoCodecConfig* mCurSendCodecConfig; michael@0: unsigned short mSendingWidth; michael@0: unsigned short mSendingHeight; michael@0: unsigned short mReceivingWidth; michael@0: unsigned short mReceivingHeight; michael@0: bool mVideoLatencyTestEnable; michael@0: uint64_t mVideoLatencyAvg; michael@0: michael@0: static const unsigned int sAlphaNum = 7; michael@0: static const unsigned int sAlphaDen = 8; michael@0: static const unsigned int sRoundingPadding = 1024; michael@0: michael@0: mozilla::RefPtr mSyncedTo; michael@0: }; michael@0: michael@0: } // end namespace michael@0: michael@0: #endif