author | Phil Ringnalda <philringnalda@gmail.com> |
Fri, 05 Jun 2015 19:41:53 -0700 | |
changeset 247552 | 038159ccffe6983e5d3cf90a0b6b8da6c0713bd9 |
parent 247551 | 3efceac245c08eb3e98ba1371cbc689d2c688ca1 |
child 247553 | 9a757393241c0891f7e13ace1815f7b086c25628 |
push id | 28870 |
push user | cbook@mozilla.com |
push date | Mon, 08 Jun 2015 09:58:36 +0000 |
treeherder | mozilla-central@4700d1cdf489 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1132318 |
milestone | 41.0a1 |
backs out | 08acee81ae6489fcab10f002431478701bbd2c68 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp @@ -64,16 +64,17 @@ WebrtcAudioConduit::~WebrtcAudioConduit( { NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); CSFLogDebug(logTag, "%s ", __FUNCTION__); for(std::vector<AudioCodecConfig*>::size_type i=0;i < mRecvCodecList.size();i++) { delete mRecvCodecList[i]; } + delete mCurSendCodecConfig; // The first one of a pair to be deleted shuts down media for both if(mPtrVoEXmedia) { mPtrVoEXmedia->SetExternalRecordingStatus(false); mPtrVoEXmedia->SetExternalPlayoutStatus(false); } @@ -354,22 +355,20 @@ WebrtcAudioConduit::SetReceiverTransport MediaConduitErrorCode WebrtcAudioConduit::ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig) { CSFLogDebug(logTag, "%s ", __FUNCTION__); MediaConduitErrorCode condError = kMediaConduitNoError; int error = 0;//webrtc engine errors webrtc::CodecInst cinst; + //validate codec param + if((condError = ValidateCodecConfig(codecConfig, true)) != kMediaConduitNoError) { - //validate codec param - if((condError = ValidateCodecConfig(codecConfig, true)) != kMediaConduitNoError) - { - return condError; - } + return condError; } condError = StopTransmitting(); if (condError != kMediaConduitNoError) { return condError; } if(!CodecConfigToWebRTCCodec(codecConfig,cinst)) @@ -407,27 +406,26 @@ WebrtcAudioConduit::ConfigureSendMediaCo } #endif condError = StartTransmitting(); if (condError != kMediaConduitNoError) { return condError; } - { - MutexAutoLock lock(mCodecMutex); + //Copy the applied config for future reference. + delete mCurSendCodecConfig; - //Copy the applied config for future reference. - mCurSendCodecConfig = new AudioCodecConfig(codecConfig->mType, - codecConfig->mName, - codecConfig->mFreq, - codecConfig->mPacSize, - codecConfig->mChannels, - codecConfig->mRate); - } + mCurSendCodecConfig = new AudioCodecConfig(codecConfig->mType, + codecConfig->mName, + codecConfig->mFreq, + codecConfig->mPacSize, + codecConfig->mChannels, + codecConfig->mRate); + return kMediaConduitNoError; } MediaConduitErrorCode WebrtcAudioConduit::ConfigureRecvMediaCodecs( const std::vector<AudioCodecConfig*>& codecConfigList) { CSFLogDebug(logTag, "%s ", __FUNCTION__); @@ -1015,17 +1013,17 @@ WebrtcAudioConduit::CheckCodecForMatch(c /** * Perform validation on the codecConfig to be applied. * Verifies if the codec is already applied. */ MediaConduitErrorCode WebrtcAudioConduit::ValidateCodecConfig(const AudioCodecConfig* codecInfo, - bool send) + bool send) const { bool codecAppliedAlready = false; if(!codecInfo) { CSFLogError(logTag, "%s Null CodecConfig ", __FUNCTION__); return kMediaConduitMalformedArgument; } @@ -1042,18 +1040,16 @@ WebrtcAudioConduit::ValidateCodecConfig( { CSFLogError(logTag, "%s Channel Unsupported ", __FUNCTION__); return kMediaConduitMalformedArgument; } //check if we have the same codec already applied if(send) { - MutexAutoLock lock(mCodecMutex); - codecAppliedAlready = CheckCodecsForMatch(mCurSendCodecConfig,codecInfo); } else { codecAppliedAlready = CheckCodecForMatch(codecInfo); } if(codecAppliedAlready) { CSFLogDebug(logTag, "%s Codec %s Already Applied ", __FUNCTION__, codecInfo->mName.c_str());
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.h +++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h @@ -164,17 +164,17 @@ public: WebrtcAudioConduit(): mVoiceEngine(nullptr), mTransportMonitor("WebrtcAudioConduit"), mTransmitterTransport(nullptr), mReceiverTransport(nullptr), mEngineTransmitting(false), mEngineReceiving(false), mChannel(-1), - mCodecMutex("AudioConduit codec db"), + mCurSendCodecConfig(nullptr), mCaptureDelay(150), #if !defined(MOZILLA_EXTERNAL_LINKAGE) mLastTimestamp(0), #endif // MOZILLA_INTERNAL_API mSamples(0), mLastSyncLog(0) { } @@ -240,17 +240,17 @@ private: bool CopyCodecToDB(const AudioCodecConfig* codecInfo); // Functions to verify if the codec passed is already in // conduits database bool CheckCodecForMatch(const AudioCodecConfig* codecInfo) const; bool CheckCodecsForMatch(const AudioCodecConfig* curCodecConfig, const AudioCodecConfig* codecInfo) const; //Checks the codec to be applied - MediaConduitErrorCode ValidateCodecConfig(const AudioCodecConfig* codecInfo, bool send); + MediaConduitErrorCode ValidateCodecConfig(const AudioCodecConfig* codecInfo, bool send) const; //Utility function to dump recv codec database void DumpCodecDB() const; webrtc::VoiceEngine* mVoiceEngine; mozilla::ReentrantMonitor mTransportMonitor; mozilla::RefPtr<TransportInterface> mTransmitterTransport; mozilla::RefPtr<TransportInterface> mReceiverTransport; @@ -272,19 +272,17 @@ private: struct Processing { TimeStamp mTimeStamp; uint32_t mRTPTimeStamp; // RTP timestamps received }; nsAutoTArray<Processing,8> mProcessing; int mChannel; RecvCodecList mRecvCodecList; - - Mutex mCodecMutex; // protects mCurSendCodecConfig - nsAutoPtr<AudioCodecConfig> mCurSendCodecConfig; + AudioCodecConfig* mCurSendCodecConfig; // Current "capture" delay (really output plus input delay) int32_t mCaptureDelay; #if !defined(MOZILLA_EXTERNAL_LINKAGE) uint32_t mLastTimestamp; #endif // MOZILLA_INTERNAL_API
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -69,17 +69,17 @@ WebrtcVideoConduit::WebrtcVideoConduit() mTransmitterTransport(nullptr), mReceiverTransport(nullptr), mRenderer(nullptr), mPtrExtCapture(nullptr), mEngineTransmitting(false), mEngineReceiving(false), mChannel(-1), mCapId(-1), - mCodecMutex("VideoConduit codec db"), + mCurSendCodecConfig(nullptr), mSendingWidth(0), mSendingHeight(0), mReceivingWidth(640), mReceivingHeight(480), mSendingFramerate(DEFAULT_VIDEO_MAX_FRAMERATE), mLastFramerateTenths(DEFAULT_VIDEO_MAX_FRAMERATE*10), mNumReceivingStreams(1), mVideoLatencyTestEnable(false), @@ -96,16 +96,18 @@ WebrtcVideoConduit::~WebrtcVideoConduit( NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); CSFLogDebug(logTag, "%s ", __FUNCTION__); for(std::vector<VideoCodecConfig*>::size_type i=0;i < mRecvCodecList.size();i++) { delete mRecvCodecList[i]; } + delete mCurSendCodecConfig; + // The first one of a pair to be deleted shuts down media for both //Deal with External Capturer if(mPtrViECapture) { mPtrViECapture->DisconnectCaptureDevice(mCapId); mPtrViECapture->ReleaseCaptureDevice(mCapId); mPtrExtCapture = nullptr; } @@ -230,17 +232,17 @@ bool WebrtcVideoConduit::GetVideoEncoder // We scale by *10 because mozilla::Atomic<> doesn't do 'double' or 'float'. double framerate = mLastFramerateTenths/10.0; // fetch once if (std::abs(*framerateMean - framerate)/framerate > 0.1 && *framerateMean >= 0.5) { // unchanged resolution, but adjust bandwidth limits to match camera fps CSFLogDebug(logTag, "Encoder frame rate changed from %f to %f", (mLastFramerateTenths/10.0), *framerateMean); mLastFramerateTenths = *framerateMean * 10; - SelectSendResolution(mSendingWidth, mSendingHeight); + SelectSendResolution(mSendingWidth, mSendingHeight, true); } return true; } bool WebrtcVideoConduit::GetVideoDecoderStats(double* framerateMean, double* framerateStdDev, double* bitrateMean, double* bitrateStdDev, @@ -588,41 +590,39 @@ WebrtcVideoConduit::ConfigureCodecMode(w { CSFLogDebug(logTag, "%s ", __FUNCTION__); mCodecMode = mode; return kMediaConduitNoError; } /** * Note: Setting the send-codec on the Video Engine will restart the encoder, * sets up new SSRC and reset RTP_RTCP module with the new codec setting. - * - * Note: this is called from MainThread, and the codec settings are read on - * videoframe delivery threads (i.e in SendVideoFrame(). With - * renegotiation/reconfiguration, this now needs a lock! Alternatively - * changes could be queued until the next frame is delivered using an - * Atomic pointer and swaps. */ MediaConduitErrorCode WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig) { CSFLogDebug(logTag, "%s for %s", __FUNCTION__, codecConfig ? codecConfig->mName.c_str() : "<null>"); bool codecFound = false; MediaConduitErrorCode condError = kMediaConduitNoError; int error = 0; //webrtc engine errors webrtc::VideoCodec video_codec; std::string payloadName; memset(&video_codec, 0, sizeof(video_codec)); + //validate basic params + if((condError = ValidateCodecConfig(codecConfig,true)) != kMediaConduitNoError) { - //validate basic params - if((condError = ValidateCodecConfig(codecConfig,true)) != kMediaConduitNoError) - { - return condError; - } + return condError; + } + + //Check if we have same codec already applied + if(CheckCodecsForMatch(mCurSendCodecConfig, codecConfig)) + { + CSFLogDebug(logTag, "%s Codec has been applied already ", __FUNCTION__); } condError = StopTransmitting(); if (condError != kMediaConduitNoError) { return condError; } if (mExternalSendCodec && @@ -704,22 +704,20 @@ WebrtcVideoConduit::ConfigureSendMediaCo } } condError = StartTransmitting(); if (condError != kMediaConduitNoError) { return condError; } - { - MutexAutoLock lock(mCodecMutex); + //Copy the applied config for future reference. + delete mCurSendCodecConfig; - //Copy the applied config for future reference. - mCurSendCodecConfig = new VideoCodecConfig(*codecConfig); - } + mCurSendCodecConfig = new VideoCodecConfig(*codecConfig); mPtrRTP->SetRembStatus(mChannel, true, false); return kMediaConduitNoError; } MediaConduitErrorCode WebrtcVideoConduit::ConfigureRecvMediaCodecs( @@ -994,22 +992,21 @@ WebrtcVideoConduit::SelectBandwidth(webr // Mostly this would be ultra-low-light situations/mobile or screensharing. vie_codec.minBitrate = vie_codec.minBitrate * ((10-(framerate/2))/30); vie_codec.maxBitrate = vie_codec.maxBitrate * ((10-(framerate/2))/30); } } // XXX we need to figure out how to feed back changes in preferred capture // resolution to the getUserMedia source -// Invoked under lock of mCodecMutex! bool WebrtcVideoConduit::SelectSendResolution(unsigned short width, - unsigned short height) + unsigned short height, + bool force) { - mCodecMutex.AssertCurrentThreadOwns(); // XXX This will do bandwidth-resolution adaptation as well - bug 877954 // Limit resolution to max-fs while keeping same aspect ratio as the // incoming image. if (mCurSendCodecConfig && mCurSendCodecConfig->mMaxFrameSize) { unsigned int cur_fs, max_width, max_height, mb_width, mb_height, mb_max; @@ -1069,94 +1066,102 @@ WebrtcVideoConduit::SelectSendResolution // Favor even multiples of pixels for width and height. width = std::max(width & ~1, 2); height = std::max(height & ~1, 2); } // Adapt to getUserMedia resolution changes // check if we need to reconfigure the sending resolution. - bool changed = false; - if (mSendingWidth != width || mSendingHeight != height) + // force tells us to do it regardless, such as when the FPS changes + if (mSendingWidth != width || mSendingHeight != height || force) { // This will avoid us continually retrying this operation if it fails. // If the resolution changes, we'll try again. In the meantime, we'll // keep using the old size in the encoder. mSendingWidth = width; mSendingHeight = height; - changed = true; - } - // uses mSendingWidth/Height - unsigned int framerate = SelectSendFrameRate(mSendingFramerate); - if (mSendingFramerate != framerate) { - mSendingFramerate = framerate; - changed = true; - } - - if (changed) { // Get current vie codec. webrtc::VideoCodec vie_codec; int32_t err; if ((err = mPtrViECodec->GetSendCodec(mChannel, vie_codec)) != 0) { CSFLogError(logTag, "%s: GetSendCodec failed, err %d", __FUNCTION__, err); return false; } - // Likely spurious unless there was some error, but rarely checked - if (vie_codec.width != width || vie_codec.height != height || - vie_codec.maxFramerate != mSendingFramerate) + if (vie_codec.width != width || vie_codec.height != height || force) { vie_codec.width = width; vie_codec.height = height; - vie_codec.maxFramerate = mSendingFramerate; SelectBandwidth(vie_codec, width, height); if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0) { CSFLogError(logTag, "%s: SetSendCodec(%ux%u) failed, err %d", __FUNCTION__, width, height, err); return false; } - CSFLogDebug(logTag, "%s: Encoder resolution changed to %ux%u @ %ufps, bitrate %u:%u", - __FUNCTION__, width, height, mSendingFramerate, + CSFLogDebug(logTag, "%s: Encoder resolution changed to %ux%u, bitrate %u:%u", + __FUNCTION__, width, height, vie_codec.minBitrate, vie_codec.maxBitrate); } // else no change; mSendingWidth likely was 0 } return true; } - -// Invoked under lock of mCodecMutex! -unsigned int -WebrtcVideoConduit::SelectSendFrameRate(unsigned int framerate) const +// TODO(ruil2@cisco.com):combine SelectSendResolution with SelectSendFrameRate Bug 1132318 +bool +WebrtcVideoConduit::SelectSendFrameRate(unsigned int framerate) { - mCodecMutex.AssertCurrentThreadOwns(); - unsigned int new_framerate = framerate; - // Limit frame rate based on max-mbps + mSendingFramerate = framerate; if (mCurSendCodecConfig && mCurSendCodecConfig->mMaxMBPS) { unsigned int cur_fs, mb_width, mb_height, max_fps; mb_width = (mSendingWidth + 15) >> 4; mb_height = (mSendingHeight + 15) >> 4; cur_fs = mb_width * mb_height; max_fps = mCurSendCodecConfig->mMaxMBPS/cur_fs; if (max_fps < mSendingFramerate) { - new_framerate = max_fps; + mSendingFramerate = max_fps; } if (mCurSendCodecConfig->mMaxFrameRate != 0 && mCurSendCodecConfig->mMaxFrameRate < mSendingFramerate) { - new_framerate = mCurSendCodecConfig->mMaxFrameRate; + mSendingFramerate = mCurSendCodecConfig->mMaxFrameRate; } } - return new_framerate; + if (mSendingFramerate != framerate) + { + // Get current vie codec. + webrtc::VideoCodec vie_codec; + int32_t err; + + if ((err = mPtrViECodec->GetSendCodec(mChannel, vie_codec)) != 0) + { + CSFLogError(logTag, "%s: GetSendCodec failed, err %d", __FUNCTION__, err); + return false; + } + if (vie_codec.maxFramerate != mSendingFramerate) + { + vie_codec.maxFramerate = mSendingFramerate; + if ((err = mPtrViECodec->SetSendCodec(mChannel, vie_codec)) != 0) + { + CSFLogError(logTag, "%s: SetSendCodec(%u) failed, err %d", + __FUNCTION__, mSendingFramerate, err); + return false; + } + CSFLogDebug(logTag, "%s: Encoder framerate changed to %u", + __FUNCTION__, mSendingFramerate); + } + } + return true; } MediaConduitErrorCode WebrtcVideoConduit::SetExternalSendCodec(VideoCodecConfig* config, VideoEncoder* encoder) { if (!mPtrExtCodec->RegisterExternalSendCodec(mChannel, config->mType, static_cast<WebrtcVideoEncoder*>(encoder), @@ -1211,22 +1216,23 @@ WebrtcVideoConduit::SendVideoFrame(unsig // Transmission should be enabled before we insert any frames. if(!mEngineTransmitting) { CSFLogError(logTag, "%s Engine not transmitting ", __FUNCTION__); return kMediaConduitSessionNotInited; } + if (!SelectSendResolution(width, height, false)) { - MutexAutoLock lock(mCodecMutex); - if (!SelectSendResolution(width, height)) - { - return kMediaConduitCaptureError; - } + return kMediaConduitCaptureError; + } + if (!SelectSendFrameRate(mSendingFramerate)) + { + return kMediaConduitCaptureError; } // insert the frame to video engine in I420 format only MOZ_ASSERT(mPtrExtCapture); if(mPtrExtCapture->IncomingFrame(video_frame, video_frame_length, width, height, type, (unsigned long long)capture_time) == -1) @@ -1598,17 +1604,17 @@ WebrtcVideoConduit::CheckCodecForMatch(c } /** * Perform validation on the codecConfig to be applied * Verifies if the codec is already applied. */ MediaConduitErrorCode WebrtcVideoConduit::ValidateCodecConfig(const VideoCodecConfig* codecInfo, - bool send) + bool send) const { bool codecAppliedAlready = false; if(!codecInfo) { CSFLogError(logTag, "%s Null CodecConfig ", __FUNCTION__); return kMediaConduitMalformedArgument; } @@ -1618,18 +1624,16 @@ WebrtcVideoConduit::ValidateCodecConfig( { CSFLogError(logTag, "%s Invalid Payload Name Length ", __FUNCTION__); return kMediaConduitMalformedArgument; } //check if we have the same codec already applied if(send) { - MutexAutoLock lock(mCodecMutex); - codecAppliedAlready = CheckCodecsForMatch(mCurSendCodecConfig,codecInfo); } else { codecAppliedAlready = CheckCodecForMatch(codecInfo); } if(codecAppliedAlready) { CSFLogDebug(logTag, "%s Codec %s Already Applied ", __FUNCTION__, codecInfo->mName.c_str());
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h @@ -140,25 +140,25 @@ public: unsigned short height); /** * Function to select and change the encoding resolution based on incoming frame size * and current available bandwidth. * @param width, height: dimensions of the frame * @param force: force setting the codec config if framerate may require a bandwidth change */ bool SelectSendResolution(unsigned short width, - unsigned short height); + unsigned short height, + bool force); /** * Function to select and change the encoding frame rate based on incoming frame rate * and max-mbps setting. - * @param current framerate - * @result new framerate + * @param framerate */ - unsigned int SelectSendFrameRate(unsigned int framerate) const; + bool SelectSendFrameRate(unsigned int framerate); /** * Function to deliver a capture video frame for encoding and transport * @param video_frame: pointer to captured video-frame. * @param video_frame_length: size of the frame * @param width, height: dimensions of the frame * @param video_type: Type of the video frame - I420, RAW * @param captured_time: timestamp when the frame was captured. @@ -301,17 +301,17 @@ private: // Functions to verify if the codec passed is already in // conduits database bool CheckCodecForMatch(const VideoCodecConfig* codecInfo) const; bool CheckCodecsForMatch(const VideoCodecConfig* curCodecConfig, const VideoCodecConfig* codecInfo) const; //Checks the codec to be applied - MediaConduitErrorCode ValidateCodecConfig(const VideoCodecConfig* codecInfo, bool send); + MediaConduitErrorCode ValidateCodecConfig(const VideoCodecConfig* codecInfo, bool send) const; //Utility function to dump recv codec database void DumpCodecDB() const; // Video Latency Test averaging filter void VideoLatencyUpdate(uint64_t new_sample); webrtc::VideoEngine* mVideoEngine; @@ -332,20 +332,17 @@ private: // Engine state we are concerned with. mozilla::Atomic<bool> mEngineTransmitting; //If true ==> Transmit Sub-system is up and running mozilla::Atomic<bool> mEngineReceiving; // if true ==> Receive Sus-sysmtem up and running int mChannel; // Video Channel for this conduit int mCapId; // Capturer for this conduit RecvCodecList mRecvCodecList; - - Mutex mCodecMutex; // protects mCurrSendCodecConfig - nsAutoPtr<VideoCodecConfig> mCurSendCodecConfig; - + VideoCodecConfig* mCurSendCodecConfig; unsigned short mSendingWidth; unsigned short mSendingHeight; unsigned short mReceivingWidth; unsigned short mReceivingHeight; unsigned int mSendingFramerate; // scaled by *10 because Atomic<double/float> isn't supported mozilla::Atomic<int32_t, mozilla::Relaxed> mLastFramerateTenths; unsigned short mNumReceivingStreams;