bool WebrtcAudioConduit::SetLocalSSRC(unsigned int ssrc) { unsigned int oldSsrc; if (!GetLocalSSRC(&oldSsrc)) { MOZ_ASSERT(false, "GetLocalSSRC failed"); return false; } if (oldSsrc == ssrc) { return true; } bool wasTransmitting = mEngineTransmitting; if (StopTransmitting() != kMediaConduitNoError) { return false; } if (mPtrRTP->SetLocalSSRC(mChannel, ssrc)) { return false; } if (wasTransmitting) { if (StartTransmitting() != kMediaConduitNoError) { return false; } } return true; }
/** * 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) { return condError; } } condError = StopTransmitting(); if (condError != kMediaConduitNoError) { return condError; } if (mExternalSendCodec && codecConfig->mType == mExternalSendCodec->mType) { CSFLogError(logTag, "%s Configuring External H264 Send Codec", __FUNCTION__); // width/height will be overridden on the first frame video_codec.width = 320; video_codec.height = 240; #ifdef MOZ_WEBRTC_OMX if (codecConfig->mType == webrtc::kVideoCodecH264) { video_codec.resolution_divisor = 16; } else { video_codec.resolution_divisor = 1; // We could try using it to handle odd resolutions } #else video_codec.resolution_divisor = 1; // We could try using it to handle odd resolutions #endif video_codec.qpMax = 56; video_codec.numberOfSimulcastStreams = 1; video_codec.mode = webrtc::kRealtimeVideo; codecFound = true; } else { // we should be good here to set the new codec. for(int idx=0; idx < mPtrViECodec->NumberOfCodecs(); idx++) { if(0 == mPtrViECodec->GetCodec(idx, video_codec)) { payloadName = video_codec.plName; if(codecConfig->mName.compare(payloadName) == 0) { // Note: side-effect of this is that video_codec is filled in // by GetCodec() codecFound = true; break; } } }//for } if(codecFound == false) { CSFLogError(logTag, "%s Codec Mismatch ", __FUNCTION__); return kMediaConduitInvalidSendCodec; } // Note: only for overriding parameters from GetCodec()! CodecConfigToWebRTCCodec(codecConfig, video_codec); if(mPtrViECodec->SetSendCodec(mChannel, video_codec) == -1) { error = mPtrViEBase->LastError(); if(error == kViECodecInvalidCodec) { CSFLogError(logTag, "%s Invalid Send Codec", __FUNCTION__); return kMediaConduitInvalidSendCodec; } CSFLogError(logTag, "%s SetSendCodec Failed %d ", __FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitUnknownError; } if (!mVideoCodecStat) { mVideoCodecStat = new VideoCodecStatistics(mChannel, mPtrViECodec); } mVideoCodecStat->Register(true); mSendingWidth = 0; mSendingHeight = 0; mSendingFramerate = video_codec.maxFramerate; if(codecConfig->RtcpFbNackIsSet("")) { CSFLogDebug(logTag, "Enabling NACK (send) for video stream\n"); if (mPtrRTP->SetNACKStatus(mChannel, true) != 0) { CSFLogError(logTag, "%s NACKStatus Failed %d ", __FUNCTION__, mPtrViEBase->LastError()); return kMediaConduitNACKStatusError; } } condError = StartTransmitting(); if (condError != kMediaConduitNoError) { return condError; } { MutexAutoLock lock(mCodecMutex); //Copy the applied config for future reference. mCurSendCodecConfig = new VideoCodecConfig(*codecConfig); } mPtrRTP->SetRembStatus(mChannel, true, false); return kMediaConduitNoError; }
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) { return condError; } condError = StopTransmitting(); if (condError != kMediaConduitNoError) { return condError; } if(!CodecConfigToWebRTCCodec(codecConfig,cinst)) { CSFLogError(logTag,"%s CodecConfig to WebRTC Codec Failed ",__FUNCTION__); return kMediaConduitMalformedArgument; } if(mPtrVoECodec->SetSendCodec(mChannel, cinst) == -1) { error = mPtrVoEBase->LastError(); CSFLogError(logTag, "%s SetSendCodec - Invalid Codec %d ",__FUNCTION__, error); if(error == VE_CANNOT_SET_SEND_CODEC || error == VE_CODEC_ERROR) { CSFLogError(logTag, "%s Invalid Send Codec", __FUNCTION__); return kMediaConduitInvalidSendCodec; } CSFLogError(logTag, "%s SetSendCodec Failed %d ", __FUNCTION__, mPtrVoEBase->LastError()); return kMediaConduitUnknownError; } #if !defined(MOZILLA_EXTERNAL_LINKAGE) // TEMPORARY - see bug 694814 comment 2 nsresult rv; nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs); if (branch) { branch->GetIntPref("media.peerconnection.capture_delay", &mCaptureDelay); } } #endif condError = StartTransmitting(); if (condError != kMediaConduitNoError) { return condError; } //Copy the applied config for future reference. delete mCurSendCodecConfig; mCurSendCodecConfig = new AudioCodecConfig(codecConfig->mType, codecConfig->mName, codecConfig->mFreq, codecConfig->mPacSize, codecConfig->mChannels, codecConfig->mRate); return kMediaConduitNoError; }