From ebeb98b7b8e344e5fd76e1d94dd5bd9e9a592c17 Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Thu, 8 Dec 2016 10:11:18 -1000 Subject: [PATCH] Bug 1320101 - Support renegotiations with changes to TIAS and simulcast params. r=bwc,jesup MozReview-Commit-ID: GNWRNnwX9pk --HG-- extra : rebase_source : 5f17c8a478934efd708dd3b9a5a7880f124e6861 --- .../src/common/EncodingConstraints.h | 12 +++ .../signaling/src/media-conduit/CodecConfig.h | 14 ++++ .../src/media-conduit/VideoConduit.cpp | 74 ++++++++++++++----- 3 files changed, 81 insertions(+), 19 deletions(-) diff --git a/media/webrtc/signaling/src/common/EncodingConstraints.h b/media/webrtc/signaling/src/common/EncodingConstraints.h index efba7c51c61a..9c6ee25c5e68 100644 --- a/media/webrtc/signaling/src/common/EncodingConstraints.h +++ b/media/webrtc/signaling/src/common/EncodingConstraints.h @@ -42,6 +42,18 @@ public: scaleDownBy == constraints.scaleDownBy; } + /** + * This returns true if the constraints affecting resolution are equal. + */ + bool ResolutionEquals(const EncodingConstraints& constraints) const + { + return + maxWidth == constraints.maxWidth && + maxHeight == constraints.maxHeight && + maxFs == constraints.maxFs && + scaleDownBy == constraints.scaleDownBy; + } + uint32_t maxWidth; uint32_t maxHeight; uint32_t maxFps; diff --git a/media/webrtc/signaling/src/media-conduit/CodecConfig.h b/media/webrtc/signaling/src/media-conduit/CodecConfig.h index 153229fa4dd0..53ce811ac8c6 100755 --- a/media/webrtc/signaling/src/media-conduit/CodecConfig.h +++ b/media/webrtc/signaling/src/media-conduit/CodecConfig.h @@ -127,6 +127,20 @@ public: } } + bool ResolutionEquals(const VideoCodecConfig& aConfig) const + { + if (mSimulcastEncodings.size() != aConfig.mSimulcastEncodings.size()) { + return false; + } + for (size_t i = 0; i < mSimulcastEncodings.size(); ++i) { + if (!mSimulcastEncodings[i].constraints.ResolutionEquals( + aConfig.mSimulcastEncodings[i].constraints)) { + return false; + } + } + return true; + } + // Nothing seems to use this right now. Do we intend to support this // someday? bool RtcpFbAckIsSet(const std::string& type) const diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp index 3d2e0d919d6c..752c1e0dd246 100755 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -303,7 +303,6 @@ WebrtcVideoConduit::InitMain() { if (temp >= 0) { mPrefMaxBitrate = temp; - mNegotiatedMaxBitrate = temp; // simplifies logic in SelectBitrate (don't have to do two limit tests) } } if (mMinBitrate != 0 && mMinBitrate < webrtc::kViEMinCodecBitrate) { @@ -727,7 +726,7 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig) }//for } - if(codecFound == false) + if(!codecFound) { CSFLogError(logTag, "%s Codec Mismatch ", __FUNCTION__); return kMediaConduitInvalidSendCodec; @@ -738,26 +737,63 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig) // Note: only for overriding parameters from GetCodec()! CodecConfigToWebRTCCodec(codecConfig, video_codec); - if (mSendingWidth != 0) { - // We're already in a call and are reconfiguring (perhaps due to - // ReplaceTrack). Set to match the last frame we sent. - - // We could also set mLastWidth to 0, to force immediate reconfig - - // more expensive, but perhaps less risk of missing something. Really - // on ReplaceTrack we should just call ConfigureCodecMode(), and if the - // mode changed, we re-configure. - // Do this after CodecConfigToWebRTCCodec() to avoid messing up simulcast - video_codec.width = mSendingWidth; - video_codec.height = mSendingHeight; - video_codec.maxFramerate = mSendingFramerate; - } else { - mSendingWidth = 0; - mSendingHeight = 0; - mSendingFramerate = video_codec.maxFramerate; - } video_codec.mode = mCodecMode; + if (mSendingWidth != 0) { + bool resolutionChanged; + { + MutexAutoLock lock(mCodecMutex); + resolutionChanged = !mCurSendCodecConfig->ResolutionEquals(*codecConfig); + } + + if (resolutionChanged) { + // We're already in a call and due to renegotiation an encoder parameter + // that requires reconfiguration has changed. Resetting these members + // triggers reconfig on the next frame. + mLastWidth = 0; + mLastHeight = 0; + mSendingWidth = 0; + mSendingHeight = 0; + } else { + // We're already in a call but changes don't require a reconfiguration. + // We update the resolutions in the send codec to match the current + // settings. + webrtc::VideoCodec oldSendCodec; + if ((error = mPtrViECodec->GetSendCodec(mChannel, oldSendCodec)) != 0) { + CSFLogError(logTag, "%s: GetSendCodec failed, err %d", __FUNCTION__, error); + return kMediaConduitInvalidSendCodec; + } + + if (video_codec.numberOfSimulcastStreams != + oldSendCodec.numberOfSimulcastStreams) { + MOZ_ASSERT(false); + return kMediaConduitInvalidSendCodec; + } + + video_codec.width = oldSendCodec.width; + video_codec.height = oldSendCodec.height; + SelectBitrates(video_codec.width, video_codec.height, + video_codec.maxBitrate, + mLastFramerateTenths, + video_codec.minBitrate, + video_codec.targetBitrate, + video_codec.maxBitrate); + for (size_t i = 0; i < video_codec.numberOfSimulcastStreams; ++i) { + webrtc::SimulcastStream& stream(video_codec.simulcastStream[i]); + stream.width = oldSendCodec.simulcastStream[i].width; + stream.height = oldSendCodec.simulcastStream[i].height; + SelectBitrates(stream.width, + stream.height, + MinIgnoreZero(stream.jsMaxBitrate, video_codec.maxBitrate), + mLastFramerateTenths, + stream.minBitrate, + stream.targetBitrate, + stream.maxBitrate); + } + } + } + if(mPtrViECodec->SetSendCodec(mChannel, video_codec) == -1) { error = mPtrViEBase->LastError();