Bug 1165520: Negotiate rtcp-fb r=jesup

--HG--
extra : rebase_source : 108cc130bf5596cbda38765d74d57c306d0f3591
This commit is contained in:
Byron Campen [:bwc] 2015-05-15 12:19:19 -07:00
parent 57dc7c8b04
commit e38fb6ec6f
3 changed files with 87 additions and 100 deletions

View File

@ -94,18 +94,6 @@ struct JsepCodecDescription {
return true;
}
UniquePtr<JsepCodecDescription>
MakeNegotiatedCodec(const SdpMediaSection& remoteMsection) const
{
UniquePtr<JsepCodecDescription> negotiated(Clone());
if (!negotiated->Negotiate(remoteMsection)) {
negotiated.reset();
}
return negotiated;
}
virtual bool
Negotiate(const SdpMediaSection& remoteMsection)
{
@ -131,30 +119,6 @@ struct JsepCodecDescription {
return nullptr;
}
UniquePtr<JsepCodecDescription>
MakeSendCodec(const mozilla::SdpMediaSection& remoteMsection) const
{
UniquePtr<JsepCodecDescription> sendCodec(Clone());
if (!sendCodec->LoadSendParameters(remoteMsection)) {
sendCodec.reset();
}
return sendCodec;
}
UniquePtr<JsepCodecDescription>
MakeRecvCodec(const mozilla::SdpMediaSection& remoteMsection) const
{
UniquePtr<JsepCodecDescription> recvCodec(Clone());
if (!recvCodec->LoadRecvParameters(remoteMsection)) {
recvCodec.reset();
}
return recvCodec;
}
virtual bool LoadSendParameters(
const mozilla::SdpMediaSection& remoteMsection)
{
@ -277,8 +241,16 @@ struct JsepVideoCodecDescription : public JsepCodecDescription {
mMaxMbps(0),
mMaxCpb(0),
mMaxDpb(0),
mMaxBr(0)
mMaxBr(0),
mUseTmmbr(false)
{
// Add supported rtcp-fb types
mNackFbTypes.push_back("");
mNackFbTypes.push_back(SdpRtcpFbAttributeList::pli);
mCcmFbTypes.push_back(SdpRtcpFbAttributeList::fir);
if (mUseTmmbr) {
mCcmFbTypes.push_back(SdpRtcpFbAttributeList::tmmbr);
}
}
virtual void
@ -318,15 +290,14 @@ struct JsepVideoCodecDescription : public JsepCodecDescription {
virtual void
AddRtcpFbs(SdpRtcpFbAttributeList& rtcpfb) const override
{
// Just hard code for now
rtcpfb.PushEntry(mDefaultPt, SdpRtcpFbAttributeList::kNack);
rtcpfb.PushEntry(
mDefaultPt, SdpRtcpFbAttributeList::kNack, SdpRtcpFbAttributeList::pli);
rtcpfb.PushEntry(
mDefaultPt, SdpRtcpFbAttributeList::kCcm, SdpRtcpFbAttributeList::fir);
if (mUseTmmbr) {
rtcpfb.PushEntry(
mDefaultPt, SdpRtcpFbAttributeList::kCcm, SdpRtcpFbAttributeList::tmmbr);
for (const std::string& type : mAckFbTypes) {
rtcpfb.PushEntry(mDefaultPt, SdpRtcpFbAttributeList::kAck, type);
}
for (const std::string& type : mNackFbTypes) {
rtcpfb.PushEntry(mDefaultPt, SdpRtcpFbAttributeList::kNack, type);
}
for (const std::string& type : mCcmFbTypes) {
rtcpfb.PushEntry(mDefaultPt, SdpRtcpFbAttributeList::kCcm, type);
}
}
@ -367,6 +338,54 @@ struct JsepVideoCodecDescription : public JsepCodecDescription {
return result;
}
static bool
HasRtcpFb(const SdpMediaSection& msection,
const std::string& pt,
SdpRtcpFbAttributeList::Type type,
const std::string& subType)
{
const SdpAttributeList& attrs(msection.GetAttributeList());
if (!attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) {
return false;
}
for (auto& rtcpfb : attrs.GetRtcpFb().mFeedbacks) {
if (rtcpfb.type == type) {
if (rtcpfb.pt == "*" || rtcpfb.pt == pt) {
if (rtcpfb.parameter == subType) {
return true;
}
}
}
}
return false;
}
void
NegotiateRtcpFb(const SdpMediaSection& remoteMsection,
SdpRtcpFbAttributeList::Type type,
std::vector<std::string>* supportedTypes)
{
std::vector<std::string> temp;
for (auto& subType : *supportedTypes) {
if (HasRtcpFb(remoteMsection, mDefaultPt, type, subType)) {
temp.push_back(subType);
}
}
*supportedTypes = temp;
}
void
NegotiateRtcpFb(const SdpMediaSection& remote)
{
// Removes rtcp-fb types that the other side doesn't support
NegotiateRtcpFb(remote, SdpRtcpFbAttributeList::kAck, &mAckFbTypes);
NegotiateRtcpFb(remote, SdpRtcpFbAttributeList::kNack, &mNackFbTypes);
NegotiateRtcpFb(remote, SdpRtcpFbAttributeList::kCcm, &mCcmFbTypes);
}
virtual bool
Negotiate(const SdpMediaSection& remoteMsection) override
{
@ -382,6 +401,7 @@ struct JsepVideoCodecDescription : public JsepCodecDescription {
// TODO(bug 1143709): max-recv-level support
}
NegotiateRtcpFb(remoteMsection);
return JsepCodecDescription::Negotiate(remoteMsection);
}
@ -467,47 +487,15 @@ struct JsepVideoCodecDescription : public JsepCodecDescription {
mMaxFs = vp8Params.max_fs;
mMaxFr = vp8Params.max_fr;
}
NegotiateRtcpFb(remoteMsection);
return true;
}
virtual bool
LoadRecvParameters(const mozilla::SdpMediaSection& remoteMsection) override
{
const SdpAttributeList& attrs(remoteMsection.GetAttributeList());
if (attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute)) {
auto& rtcpfbs = attrs.GetRtcpFb().mFeedbacks;
for (auto i = rtcpfbs.begin(); i != rtcpfbs.end(); ++i) {
if (i->pt == mDefaultPt || i->pt == "*") {
switch (i->type) {
case SdpRtcpFbAttributeList::kAck:
mAckFbTypes.push_back(i->parameter);
break;
case SdpRtcpFbAttributeList::kCcm:
mCcmFbTypes.push_back(i->parameter);
break;
case SdpRtcpFbAttributeList::kNack:
mNackFbTypes.push_back(i->parameter);
break;
case SdpRtcpFbAttributeList::kApp:
case SdpRtcpFbAttributeList::kTrrInt:
// We don't support these, ignore.
{}
}
}
}
}
if (mName == "H264") {
SdpFmtpAttributeList::H264Parameters h264Params(
GetH264Parameters(mDefaultPt, remoteMsection));
if (!h264Params.level_asymmetry_allowed) {
SetSaneH264Level(std::min(GetSaneH264Level(h264Params.profile_level_id),
GetSaneH264Level(mProfileLevelId)),
&mProfileLevelId);
}
}
return true;
return Negotiate(remoteMsection);
}
enum Subprofile {

View File

@ -1176,11 +1176,9 @@ JsepSessionImpl::CreateAnswerMSection(const JsepAnswerOptions& options,
PtrVector<JsepCodecDescription> matchingCodecs(
GetCommonCodecs(remoteMsection));
for (const JsepCodecDescription* codec : matchingCodecs.values) {
UniquePtr<JsepCodecDescription> negotiated(
codec->MakeNegotiatedCodec(remoteMsection));
if (negotiated) {
negotiated->AddToMediaSection(msection);
for (JsepCodecDescription* codec : matchingCodecs.values) {
if (codec->Negotiate(remoteMsection)) {
codec->AddToMediaSection(msection);
// TODO(bug 1099351): Once bug 1073475 is fixed on all supported
// versions, we can remove this limitation.
break;
@ -1721,34 +1719,31 @@ JsepSessionImpl::NegotiateTrack(const SdpMediaSection& remoteMsection,
PtrVector<JsepCodecDescription> commonCodecs(
GetCommonCodecs(remoteMsection));
for (const JsepCodecDescription* codec : commonCodecs.values) {
for (JsepCodecDescription* codec : commonCodecs.values) {
bool sending = (direction == JsepTrack::kJsepTrackSending);
// Everywhere else in JsepSessionImpl, a JsepCodecDescription describes
// what one side puts in its SDP. However, we don't want that here; we want
// a JsepCodecDescription that instead encapsulates all the parameters
// that deal with sending (or receiving). For sending, some of these
// parameters will come from the local codec config (eg; rtcp-fb), others
// will come from the remote SDP (eg; max-fps), and still others can only be
// determined by inspecting both local config and remote SDP (eg;
// parameters will come from the remote SDP (eg; max-fps), and others can
// only be determined by inspecting both local config and remote SDP (eg;
// profile-level-id when level-asymmetry-allowed is 0).
UniquePtr<JsepCodecDescription> sendOrReceiveCodec;
if (sending) {
sendOrReceiveCodec = Move(codec->MakeSendCodec(remoteMsection));
if (!codec->LoadSendParameters(remoteMsection)) {
continue;
}
} else {
sendOrReceiveCodec = Move(codec->MakeRecvCodec(remoteMsection));
}
if (!sendOrReceiveCodec) {
continue;
if (!codec->LoadRecvParameters(remoteMsection)) {
continue;
}
}
if (remoteMsection.GetMediaType() == SdpMediaSection::kAudio ||
remoteMsection.GetMediaType() == SdpMediaSection::kVideo) {
// Sanity-check that payload type can work with RTP
uint16_t payloadType;
if (!sendOrReceiveCodec->GetPtAsInt(&payloadType) ||
if (!codec->GetPtAsInt(&payloadType) ||
payloadType > UINT8_MAX) {
JSEP_SET_ERROR("audio/video payload type is not an 8 bit unsigned int: "
<< codec->mDefaultPt);
@ -1756,7 +1751,7 @@ JsepSessionImpl::NegotiateTrack(const SdpMediaSection& remoteMsection,
}
}
negotiatedDetails->mCodecs.values.push_back(sendOrReceiveCodec.release());
negotiatedDetails->mCodecs.values.push_back(codec->Clone());
break;
}

View File

@ -2008,6 +2008,8 @@ public:
a1_->SetExpectedFrameRequestType(frameRequestType);
a1_->mExpectNack = expectNack;
// Since we don't support rewriting rtcp-fb in answers, a2 still thinks it
// will be doing all of the normal rtcp-fb
WaitForCompleted();
CheckPipelines();
@ -2028,6 +2030,8 @@ public:
std::string modifiedOffer = HardcodeRtcpFb(a1_->offer(), feedback);
a2_->SetRemote(TestObserver::OFFER, modifiedOffer);
a1_->SetExpectedFrameRequestType(frameRequestType);
a1_->mExpectNack = expectNack;
a2_->SetExpectedFrameRequestType(frameRequestType);
a2_->mExpectNack = expectNack;