Bug 1279049 - add sdp handling for audio FEC, r=jesup
MozReview-Commit-ID: J0ax8TnR3p8
--- a/media/webrtc/signaling/src/jsep/JsepCodecDescription.h
+++ b/media/webrtc/signaling/src/jsep/JsepCodecDescription.h
@@ -167,31 +167,36 @@ class JsepAudioCodecDescription : public
GetOpusParameters(mDefaultPt, msection));
if (mMaxPlaybackRate) {
opusParams.maxplaybackrate = mMaxPlaybackRate;
}
if (mChannels == 2 && !mForceMono) {
// We prefer to receive stereo, if available.
opusParams.stereo = 1;
}
+ opusParams.useInBandFec = mFECEnabled ? 1 : 0;
msection.SetFmtp(SdpFmtpAttributeList::Fmtp(mDefaultPt, opusParams));
}
}
bool
Negotiate(const std::string& pt,
const SdpMediaSection& remoteMsection) override
{
JsepCodecDescription::Negotiate(pt, remoteMsection);
if (mName == "opus" && mDirection == sdp::kSend) {
SdpFmtpAttributeList::OpusParameters opusParams(
GetOpusParameters(mDefaultPt, remoteMsection));
mMaxPlaybackRate = opusParams.maxplaybackrate;
mForceMono = !opusParams.stereo;
+ // draft-ietf-rtcweb-fec-03.txt section 4.2 says support for FEC
+ // at the received side is declarative and can be negotiated
+ // separately for either media direction.
+ mFECEnabled = opusParams.useInBandFec;
}
return true;
}
uint32_t mPacketSize;
uint32_t mBitrate;
uint32_t mMaxPlaybackRate;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -870,17 +870,18 @@ class ConfigureCodec {
mH264Enabled(false),
mVP9Enabled(false),
mH264Level(13), // minimum suggested for WebRTC spec
mH264MaxBr(0), // Unlimited
mH264MaxMbps(0), // Unlimited
mVP8MaxFs(0),
mVP8MaxFr(0),
mUseTmmbr(false),
- mUseRemb(false)
+ mUseRemb(false),
+ mUseAudioFec(false)
{
#ifdef MOZ_WEBRTC_OMX
// Check to see if what HW codecs are available (not in use) at this moment.
// Note that streaming video decode can reserve a decoder
// XXX See bug 1018791 Implement W3 codec reservation policy
// Note that currently, OMXCodecReservation needs to be held by an sp<> because it puts
// 'this' into an sp<EventListener> to talk to the resource reservation code
@@ -939,23 +940,31 @@ class ConfigureCodec {
mVP8MaxFr = 60; // We must specify something other than 0
}
// TMMBR is enabled from a pref in about:config
branch->GetBoolPref("media.navigator.video.use_tmmbr", &mUseTmmbr);
// REMB is enabled by default, but can be disabled from about:config
branch->GetBoolPref("media.navigator.video.use_remb", &mUseRemb);
+
+ branch->GetBoolPref("media.navigator.audio.use_fec", &mUseAudioFec);
}
void operator()(JsepCodecDescription* codec) const
{
switch (codec->mType) {
case SdpMediaSection::kAudio:
- // Nothing to configure here, for now.
+ {
+ JsepAudioCodecDescription& audioCodec =
+ static_cast<JsepAudioCodecDescription&>(*codec);
+ if (audioCodec.mName == "opus") {
+ audioCodec.mFECEnabled = mUseAudioFec;
+ }
+ }
break;
case SdpMediaSection::kVideo:
{
JsepVideoCodecDescription& videoCodec =
static_cast<JsepVideoCodecDescription&>(*codec);
if (videoCodec.mName == "H264") {
// Override level
@@ -1010,16 +1019,17 @@ class ConfigureCodec {
bool mVP9Enabled;
int32_t mH264Level;
int32_t mH264MaxBr;
int32_t mH264MaxMbps;
int32_t mVP8MaxFs;
int32_t mVP8MaxFr;
bool mUseTmmbr;
bool mUseRemb;
+ bool mUseAudioFec;
};
nsresult
PeerConnectionImpl::ConfigureJsepSessionCodecs() {
nsresult res;
nsCOMPtr<nsIPrefService> prefs =
do_GetService("@mozilla.org/preferences-service;1", &res);
--- a/media/webrtc/signaling/src/sdp/SdpAttribute.h
+++ b/media/webrtc/signaling/src/sdp/SdpAttribute.h
@@ -1238,38 +1238,42 @@ public:
unsigned int max_fs;
unsigned int max_fr;
};
class OpusParameters : public Parameters
{
public:
enum { kDefaultMaxPlaybackRate = 48000,
- kDefaultStereo = 0 };
+ kDefaultStereo = 0,
+ kDefaultUseInBandFec = 0 };
OpusParameters() :
Parameters(SdpRtpmapAttributeList::kOpus),
maxplaybackrate(kDefaultMaxPlaybackRate),
- stereo(kDefaultStereo)
+ stereo(kDefaultStereo),
+ useInBandFec(kDefaultUseInBandFec)
{}
Parameters*
Clone() const override
{
return new OpusParameters(*this);
}
void
Serialize(std::ostream& os) const override
{
- os << "maxplaybackrate=" << maxplaybackrate << ";"
- << "stereo=" << stereo;
+ os << "maxplaybackrate=" << maxplaybackrate
+ << ";stereo=" << stereo
+ << ";useinbandfec=" << useInBandFec;
}
unsigned int maxplaybackrate;
unsigned int stereo;
+ unsigned int useInBandFec;
};
class Fmtp
{
public:
Fmtp(const std::string& aFormat, UniquePtr<Parameters> aParameters)
: format(aFormat),
parameters(Move(aParameters))
--- a/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp
+++ b/media/webrtc/signaling/src/sdp/SipccSdpAttributeList.cpp
@@ -721,16 +721,17 @@ SipccSdpAttributeList::LoadFmtp(sdp_t* s
parameters.reset(vp8Parameters);
} break;
case RTP_OPUS: {
SdpFmtpAttributeList::OpusParameters* opusParameters(
new SdpFmtpAttributeList::OpusParameters);
opusParameters->maxplaybackrate = fmtp->maxplaybackrate;
opusParameters->stereo = fmtp->stereo;
+ opusParameters->useInBandFec = fmtp->useinbandfec;
parameters.reset(opusParameters);
} break;
default: {
}
}
fmtps->PushEntry(osPayloadType.str(), Move(parameters));
}
--- a/media/webrtc/signaling/test/sdp_unittests.cpp
+++ b/media/webrtc/signaling/test/sdp_unittests.cpp
@@ -1556,17 +1556,17 @@ const std::string kH264AudioVideoOffer =
"a=mid:first" CRLF
"a=rtpmap:109 opus/48000/2" CRLF
"a=ptime:20" CRLF
"a=maxptime:20" CRLF
"a=rtpmap:9 G722/8000" CRLF
"a=rtpmap:0 PCMU/8000" CRLF
"a=rtpmap:8 PCMA/8000" CRLF
"a=rtpmap:101 telephone-event/8000" CRLF
-"a=fmtp:109 maxplaybackrate=32000;stereo=1" CRLF
+"a=fmtp:109 maxplaybackrate=32000;stereo=1;useinbandfec=1" CRLF
"a=ice-ufrag:00000000" CRLF
"a=ice-pwd:0000000000000000000000000000000" CRLF
"a=sendonly" CRLF
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF
"a=setup:actpass" CRLF
"a=rtcp-mux" CRLF
"a=msid:stream track" CRLF
"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF
@@ -1618,16 +1618,17 @@ TEST_P(NewSdpTest, CheckFormatParameters
ASSERT_EQ(1U, audio_format_params.size());
ASSERT_EQ("109", audio_format_params[0].format);
ASSERT_TRUE(!!audio_format_params[0].parameters);
const SdpFmtpAttributeList::OpusParameters* opus_parameters =
static_cast<SdpFmtpAttributeList::OpusParameters*>(
audio_format_params[0].parameters.get());
ASSERT_EQ(32000U, opus_parameters->maxplaybackrate);
ASSERT_EQ(1U, opus_parameters->stereo);
+ ASSERT_EQ(1U, opus_parameters->useInBandFec);
ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
SdpAttribute::kFmtpAttribute));
auto video_format_params =
mSdp->GetMediaSection(1).GetAttributeList().GetFmtp().mFmtps;
ASSERT_EQ(3U, video_format_params.size());
ASSERT_EQ("97", video_format_params[0].format);
ASSERT_TRUE(!!video_format_params[0].parameters);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -394,17 +394,17 @@ pref("media.navigator.load_adapt", true)
pref("media.navigator.load_adapt.measure_interval",1000);
pref("media.navigator.load_adapt.avg_seconds",3);
pref("media.navigator.load_adapt.high_load","0.90");
pref("media.navigator.load_adapt.low_load","0.40");
pref("media.navigator.video.default_fps",30);
pref("media.navigator.video.default_minfps",10);
pref("media.navigator.video.use_remb", true);
pref("media.navigator.video.use_tmmbr", true);
-
+pref("media.navigator.audio.use_fec", true);
pref("media.webrtc.debug.trace_mask", 0);
pref("media.webrtc.debug.multi_log", false);
pref("media.webrtc.debug.aec_log_dir", "");
pref("media.webrtc.debug.log_file", "");
pref("media.webrtc.debug.aec_dump_max_size", 4194304); // 4MB
#ifdef MOZ_WIDGET_GONK