Bug 1288904: Clean up RID header extension support r=jesup

This commit is contained in:
Randell Jesup 2016-09-23 21:55:08 -04:00
parent c6e92c6fe6
commit 26e9eaaec7
16 changed files with 119 additions and 28 deletions

View File

@ -2211,6 +2211,8 @@ void
JsepSessionImpl::SetupDefaultRtpExtensions()
{
AddAudioRtpExtension("urn:ietf:params:rtp-hdrext:ssrc-audio-level");
AddAudioRtpExtension("urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id");
AddVideoRtpExtension("urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id");
}
void

View File

@ -351,6 +351,14 @@ public:
virtual MediaConduitErrorCode SetExternalRecvCodec(VideoCodecConfig* config,
VideoDecoder* decoder) = 0;
/**
* Function to enable the RTP Stream ID (RID) extension
* @param enabled: enable extension
* @param id: id to be used for this rtp header extension
* NOTE: See VideoConduit for more information
*/
virtual MediaConduitErrorCode EnableRTPStreamIdExtension(bool enabled, uint8_t id) = 0;
/**
* These methods allow unit tests to double-check that the
* max-fs and max-fr related settings are as expected.

View File

@ -95,6 +95,8 @@ WebrtcVideoConduit::WebrtcVideoConduit():
mStartBitrate(0),
mMaxBitrate(0),
mMinBitrateEstimate(0),
mRtpStreamIdEnabled(false),
mRtpStreamIdExtId(0),
mCodecMode(webrtc::kRealtimeVideo)
{}
@ -661,6 +663,9 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
return condError;
}
if (mRtpStreamIdEnabled) {
video_codec.ridId = mRtpStreamIdExtId;
}
if (mExternalSendCodec &&
codecConfig->mType == mExternalSendCodec->mType) {
CSFLogError(logTag, "%s Configuring External H264 Send Codec", __FUNCTION__);
@ -1360,6 +1365,10 @@ WebrtcVideoConduit::ReconfigureSendCodec(unsigned short width,
"%s: Requesting resolution change to %ux%u (from %ux%u)",
__FUNCTION__, width, height, vie_codec.width, vie_codec.height);
if (mRtpStreamIdEnabled) {
vie_codec.ridId = mRtpStreamIdExtId;
}
vie_codec.width = width;
vie_codec.height = height;
vie_codec.maxFramerate = mSendingFramerate;
@ -1511,6 +1520,13 @@ WebrtcVideoConduit::SetExternalRecvCodec(VideoCodecConfig* config,
return kMediaConduitInvalidReceiveCodec;
}
MediaConduitErrorCode
WebrtcVideoConduit::EnableRTPStreamIdExtension(bool enabled, uint8_t id) {
mRtpStreamIdEnabled = enabled;
mRtpStreamIdExtId = id;
return kMediaConduitNoError;
}
MediaConduitErrorCode
WebrtcVideoConduit::SendVideoFrame(unsigned char* video_frame,
unsigned int video_frame_length,

View File

@ -213,6 +213,10 @@ public:
virtual MediaConduitErrorCode SetExternalRecvCodec(VideoCodecConfig* config,
VideoDecoder* decoder) override;
/**
* Enables use of Rtp Stream Id, and sets the extension ID.
*/
virtual MediaConduitErrorCode EnableRTPStreamIdExtension(bool enabled, uint8_t id) override;
/**
* Webrtc transport implementation to send and receive RTP packet.
@ -400,6 +404,9 @@ private:
uint32_t mMaxBitrate;
uint32_t mMinBitrateEstimate;
bool mRtpStreamIdEnabled;
uint8_t mRtpStreamIdExtId;
static const unsigned int sAlphaNum = 7;
static const unsigned int sAlphaDen = 8;
static const unsigned int sRoundingPadding = 1024;

View File

@ -863,8 +863,23 @@ MediaPipelineFactory::GetOrCreateVideoConduit(
return NS_ERROR_FAILURE;
}
auto error = conduit->ConfigureSendMediaCodec(configs.values[0]);
const SdpExtmapAttributeList::Extmap* rtpStreamIdExt =
aTrack.GetNegotiatedDetails()->GetExt(
"urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id");
if (rtpStreamIdExt) {
MOZ_MTLOG(ML_DEBUG, "Calling EnableRTPSenderIdExtension");
error = conduit->EnableRTPStreamIdExtension(true, rtpStreamIdExt->entry);
if (error) {
MOZ_MTLOG(ML_ERROR, "EnableRTPSenderIdExtension failed: " << error);
return NS_ERROR_FAILURE;
}
}
if (error) {
MOZ_MTLOG(ML_ERROR, "ConfigureSendMediaCodec failed: " << error);
return NS_ERROR_FAILURE;

View File

@ -15,6 +15,7 @@
#include <string>
#include <vector>
#include <algorithm>
#include "webrtc/common_types.h"
#include "webrtc/typedefs.h"
@ -52,6 +53,7 @@ struct RtpExtension {
static const char* kTOffset;
static const char* kAbsSendTime;
static const char* kVideoRotation;
static const char* kRtpStreamId;
std::string name;
int id;
};
@ -71,6 +73,18 @@ struct VideoStream {
int max_qp;
char rid[kRIDSize+1];
const std::string Rid() const {
return std::string(rid);
}
void SetRid(const std::string& aRid) {
static_assert(sizeof(rid) > kRIDSize,
"mRid must be large enought to hold a RID + null termination");
strncpy(&rid[0], aRid.c_str(), std::min((size_t)kRIDSize, aRid.length()));
rid[kRIDSize] = 0;
}
// Bitrate thresholds for enabling additional temporal layers. Since these are
// thresholds in between layers, we have one additional layer. One threshold
// gives two temporal layers, one below the threshold and one above, two give

View File

@ -81,7 +81,7 @@ enum RTPExtensionType {
kRtpExtensionAbsoluteSendTime,
kRtpExtensionVideoRotation,
kRtpExtensionTransportSequenceNumber,
kRtpExtensionRID,
kRtpExtensionRtpStreamId,
};
enum RTCPAppSubTypes

View File

@ -27,7 +27,7 @@ const size_t kAbsoluteSendTimeLength = 4;
const size_t kVideoRotationLength = 2;
const size_t kTransportSequenceNumberLength = 3;
// kRIDLength is variable
const size_t kRIDLength = 4; // max 1-byte header extension length
const size_t kRtpStreamIdLength = 4; // max 1-byte header extension length
struct HeaderExtension {
HeaderExtension(RTPExtensionType extension_type)
@ -60,8 +60,8 @@ struct HeaderExtension {
case kRtpExtensionTransportSequenceNumber:
length = kTransportSequenceNumberLength;
break;
case kRtpExtensionRID:
length = kRIDLength;
case kRtpExtensionRtpStreamId:
length = kRtpStreamIdLength;
break;
default:
assert(false);

View File

@ -1234,7 +1234,7 @@ uint16_t RTPSender::BuildRTPHeaderExtension(uint8_t* data_buffer,
case kRtpExtensionTransportSequenceNumber:
block_length = BuildTransportSequenceNumberExtension(extension_data);
break;
case kRtpExtensionRID:
case kRtpExtensionRtpStreamId:
block_length = BuildRIDExtension(extension_data);
break;
default:
@ -1422,9 +1422,10 @@ uint8_t RTPSender::BuildRIDExtension(
// Get id defined by user.
uint8_t id;
if (rtp_header_extension_map_.GetId(kRtpExtensionRID,
if (!rid_ ||
rtp_header_extension_map_.GetId(kRtpExtensionRtpStreamId,
&id) != 0) {
// Not registered.
// No RtpStreamId or not registered
return 0;
}
size_t pos = 0;

View File

@ -97,7 +97,7 @@ uint32_t GetCurrentRTP(Clock* clock, uint32_t freq) {
}
uint32_t ConvertNTPTimeToRTP(uint32_t NTPsec, uint32_t NTPfrac, uint32_t freq) {
float ftemp = (float)NTPfrac / (float)NTP_FRAC;
float ftemp = (float)NTPfrac / (float)NTP_FRAC;
uint32_t tmp = (uint32_t)(ftemp * freq);
return NTPsec * freq + tmp;
}
@ -490,7 +490,7 @@ void RtpHeaderParser::ParseOneByteExtensionHeader(
header.extension.hasTransportSequenceNumber = true;
break;
}
case kRtpExtensionRID: {
case kRtpExtensionRtpStreamId: {
// 0 1 2
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

View File

@ -42,11 +42,14 @@ const char* RtpExtension::kTOffset = "urn:ietf:params:rtp-hdrext:toffset";
const char* RtpExtension::kAbsSendTime =
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
const char* RtpExtension::kVideoRotation = "urn:3gpp:video-orientation";
const char* RtpExtension::kRtpStreamId =
"urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id";
bool RtpExtension::IsSupported(const std::string& name) {
return name == webrtc::RtpExtension::kTOffset ||
name == webrtc::RtpExtension::kAbsSendTime ||
name == webrtc::RtpExtension::kVideoRotation;
name == webrtc::RtpExtension::kVideoRotation ||
name == webrtc::RtpExtension::kRtpStreamId;
}
VideoEncoder* VideoEncoder::Create(VideoEncoder::EncoderType codec_type) {

View File

@ -140,6 +140,8 @@ VideoSendStream::VideoSendStream(
CHECK_EQ(0, rtp_rtcp_->SetSendAbsoluteSendTimeStatus(channel_, true, id));
} else if (extension == RtpExtension::kVideoRotation) {
CHECK_EQ(0, rtp_rtcp_->SetSendVideoRotationStatus(channel_, true, id));
} else if (extension == RtpExtension::kRtpStreamId) {
RTC_CHECK_EQ(0, vie_channel_->SetSendRtpStreamId(true,id));
} else {
RTC_NOTREACHED() << "Registering unsupported RTP extension.";
}

View File

@ -368,7 +368,10 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
packet_router_->RemoveRtpModule(rtp_rtcp_.get());
for (RtpRtcp* module : simulcast_rtp_rtcp_)
packet_router_->RemoveRtpModule(module);
if (rtp_rtcp_->Sending() && new_stream) {
// Set the RtpSenderId
rid_extension_id_ = video_codec.ridId;
if (rtp_rtcp_->Sending()) {
restart_rtp = true;
rtp_rtcp_->SetSendingStatus(false);
int i = 0;
@ -378,11 +381,11 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
(*it)->SetSendingMediaStatus(false);
if (video_codec.simulcastStream[i].rid[0] != 0) {
(*it)->RegisterSendRtpHeaderExtension(
kRtpExtensionRID, video_codec.ridId);
kRtpExtensionRtpStreamId, video_codec.ridId);
(*it)->SetRID(video_codec.simulcastStream[i].rid);
} else {
(*it)->DeregisterSendRtpHeaderExtension(
kRtpExtensionRID);
kRtpExtensionRtpStreamId);
}
}
}
@ -398,6 +401,24 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
if (video_codec.numberOfSimulcastStreams > 0) {
// Set RTP Stream ID of primary stream
if (rid_extension_id_ != kInvalidRtpExtensionId) {
// Deregister in case the extension was previously enabled.
rtp_rtcp_->DeregisterSendRtpHeaderExtension(
kRtpExtensionRtpStreamId);
if (rtp_rtcp_->RegisterSendRtpHeaderExtension(
kRtpExtensionRtpStreamId,
rid_extension_id_) != 0) {
LOG(LS_WARNING) << "Register RID extension failed";
} else {
rtp_rtcp_->SetRID(video_codec.simulcastStream[0].rid);
}
} else {
rtp_rtcp_->DeregisterSendRtpHeaderExtension(
kRtpExtensionRtpStreamId);
}
// Set correct bitrate to base layer.
// Create our simulcast RTP modules.
int num_modules_to_add =
@ -516,15 +537,17 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
if (rid_extension_id_ != kInvalidRtpExtensionId) {
// Deregister in case the extension was previously enabled.
rtp_rtcp->DeregisterSendRtpHeaderExtension(
kRtpExtensionRID);
kRtpExtensionRtpStreamId);
if (rtp_rtcp->RegisterSendRtpHeaderExtension(
kRtpExtensionRID,
kRtpExtensionRtpStreamId,
rid_extension_id_) != 0) {
LOG(LS_WARNING) << "Register RID extension failed";
} else {
(*it)->SetRID(video_codec.simulcastStream[idx].rid);
}
} else {
rtp_rtcp->DeregisterSendRtpHeaderExtension(
kRtpExtensionRID);
kRtpExtensionRtpStreamId);
}
rtp_rtcp->RegisterRtcpStatisticsCallback(
rtp_rtcp_->GetRtcpStatisticsCallback());
@ -989,34 +1012,34 @@ int ViEChannel::SetReceiveVideoRotationStatus(bool enable, int id) {
return vie_receiver_.SetReceiveVideoRotationStatus(enable, id) ? 0 : -1;
}
int ViEChannel::SetSendRIDStatus(bool enable, int id, const char *rid) {
int ViEChannel::SetSendRtpStreamId(bool enable, int id, const char* rid) {
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
int error = 0;
if (enable) {
// Enable the extension, but disable possible old id to avoid errors.
rid_extension_id_ = id;
rtp_rtcp_->DeregisterSendRtpHeaderExtension(
kRtpExtensionRID);
kRtpExtensionRtpStreamId);
error = rtp_rtcp_->RegisterSendRtpHeaderExtension(
kRtpExtensionRID, id);
kRtpExtensionRtpStreamId, id);
rtp_rtcp_->SetRID(rid);
// NOTE: simulcast streams must be set via the SetSendCodec() API
} else {
// Disable the extension.
rid_extension_id_ = kInvalidRtpExtensionId;
rtp_rtcp_->DeregisterSendRtpHeaderExtension(
kRtpExtensionRID);
kRtpExtensionRtpStreamId);
// This may be overkill...
for (std::list<RtpRtcp*>::iterator it = simulcast_rtp_rtcp_.begin();
it != simulcast_rtp_rtcp_.end(); it++) {
(*it)->DeregisterSendRtpHeaderExtension(
kRtpExtensionRID);
kRtpExtensionRtpStreamId);
}
}
return error;
}
int ViEChannel::SetReceiveRIDStatus(bool enable, int id) {
int ViEChannel::SetReceiveRtpStreamId(bool enable, int id) {
return vie_receiver_.SetReceiveRIDStatus(enable, id) ? 0 : -1;
}

View File

@ -138,8 +138,8 @@ class ViEChannel
bool GetReceiveAbsoluteSendTimeStatus() const;
int SetSendVideoRotationStatus(bool enable, int id);
int SetReceiveVideoRotationStatus(bool enable, int id);
int SetSendRIDStatus(bool enable, int id, const char *rid);
int SetReceiveRIDStatus(bool enable, int id);
int SetSendRtpStreamId(bool enable, int id, const char* rid);
int SetReceiveRtpStreamId(bool enable, int id);
void SetRtcpXrRrtrStatus(bool enable);
void SetTransmissionSmoothingStatus(bool enable);
void EnableTMMBR(bool enable);

View File

@ -214,7 +214,7 @@ bool ViEReceiver::SetReceiveVideoRotationStatus(bool enable, int id) {
bool ViEReceiver::SetReceiveRIDStatus(bool enable, int id) {
if (enable) {
if (rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionRID, id)) {
kRtpExtensionRtpStreamId, id)) {
receiving_rid_enabled_ = true;
return true;
} else {
@ -223,7 +223,7 @@ bool ViEReceiver::SetReceiveRIDStatus(bool enable, int id) {
} else {
receiving_rid_enabled_ = false;
return rtp_header_parser_->DeregisterRtpHeaderExtension(
kRtpExtensionRID);
kRtpExtensionRtpStreamId);
}
}

View File

@ -711,7 +711,7 @@ int ViERTP_RTCPImpl::SetSendRIDStatus(int video_channel,
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetSendRIDStatus(enable, id, rid) != 0) {
if (vie_channel->SetSendRtpStreamId(enable, id, rid) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}
@ -729,7 +729,7 @@ int ViERTP_RTCPImpl::SetReceiveRIDStatus(int video_channel,
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->SetReceiveRIDStatus(enable, id) != 0) {
if (vie_channel->SetReceiveRtpStreamId(enable, id) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}