Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(878)

Unified Diff: webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc

Issue 2528993002: Revert of Remove RTPPayloadStrategy and simplify RTPPayloadRegistry (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc b/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc
index 7d4afc6e36199f77baa394779aa026be203bb9c1..a4354d393ea99cea9a6a0964a77c962fe8d6ab4b 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc
@@ -10,76 +10,55 @@
#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
-#include <algorithm>
-
-#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
-#include "webrtc/base/stringutils.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
namespace webrtc {
-namespace {
-
-bool PayloadIsCompatible(const RtpUtility::Payload& payload,
- const CodecInst& audio_codec) {
- if (!payload.audio)
- return false;
- if (_stricmp(payload.name, audio_codec.plname) != 0)
- return false;
- const AudioPayload& audio_payload = payload.typeSpecific.Audio;
- const uint32_t rate = std::max(0, audio_codec.rate);
- return audio_payload.frequency == static_cast<uint32_t>(audio_codec.plfreq) &&
- audio_payload.channels == audio_codec.channels &&
- (audio_payload.rate == rate || audio_payload.rate == 0 || rate == 0);
-}
-
-bool PayloadIsCompatible(const RtpUtility::Payload& payload,
- const VideoCodec& video_codec) {
- return !payload.audio && _stricmp(payload.name, video_codec.plName) == 0;
-}
-
-RtpUtility::Payload CreatePayloadType(const CodecInst& audio_codec) {
- RtpUtility::Payload payload;
- payload.name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
- strncpy(payload.name, audio_codec.plname, RTP_PAYLOAD_NAME_SIZE - 1);
- RTC_DCHECK_GE(audio_codec.plfreq, 1000);
- payload.typeSpecific.Audio.frequency = audio_codec.plfreq;
- payload.typeSpecific.Audio.channels = audio_codec.channels;
- payload.typeSpecific.Audio.rate = std::max(0, audio_codec.rate);
- payload.audio = true;
- return payload;
-}
-
-RtpVideoCodecTypes ConvertToRtpVideoCodecType(VideoCodecType type) {
- switch (type) {
- case kVideoCodecVP8:
- return kRtpVideoVp8;
- case kVideoCodecVP9:
- return kRtpVideoVp9;
- case kVideoCodecH264:
- return kRtpVideoH264;
- case kVideoCodecRED:
- case kVideoCodecULPFEC:
- return kRtpVideoNone;
- default:
- return kRtpVideoGeneric;
- }
-}
-
-RtpUtility::Payload CreatePayloadType(const VideoCodec& video_codec) {
- RtpUtility::Payload payload;
- payload.name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
- strncpy(payload.name, video_codec.plName, RTP_PAYLOAD_NAME_SIZE - 1);
- payload.typeSpecific.Video.videoCodecType =
- ConvertToRtpVideoCodecType(video_codec.codecType);
- payload.audio = false;
- return payload;
-}
-
-bool IsPayloadTypeValid(int8_t payload_type) {
+RTPPayloadRegistry::RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy)
+ : rtp_payload_strategy_(rtp_payload_strategy),
+ red_payload_type_(-1),
+ ulpfec_payload_type_(-1),
+ incoming_payload_type_(-1),
+ last_received_payload_type_(-1),
+ last_received_media_payload_type_(-1),
+ rtx_(false),
+ ssrc_rtx_(0) {}
+
+RTPPayloadRegistry::~RTPPayloadRegistry() {
+ while (!payload_type_map_.empty()) {
+ RtpUtility::PayloadTypeMap::iterator it = payload_type_map_.begin();
+ delete it->second;
+ payload_type_map_.erase(it);
+ }
+}
+
+int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec,
+ bool* created_new_payload) {
+ return RegisterReceivePayload(
+ audio_codec.plname, audio_codec.pltype, audio_codec.plfreq,
+ audio_codec.channels, std::max(0, audio_codec.rate), created_new_payload);
+}
+
+int32_t RTPPayloadRegistry::RegisterReceivePayload(
+ const VideoCodec& video_codec) {
+ bool dummy_created_new_payload;
+ return RegisterReceivePayload(video_codec.plName, video_codec.plType,
+ kVideoPayloadTypeFrequency, 0 /* channels */,
+ 0 /* rate */, &dummy_created_new_payload);
+}
+
+int32_t RTPPayloadRegistry::RegisterReceivePayload(
+ const char* const payload_name,
+ const int8_t payload_type,
+ const uint32_t frequency,
+ const size_t channels,
+ const uint32_t rate,
+ bool* created_new_payload) {
assert(payload_type >= 0);
+ assert(payload_name);
+ *created_new_payload = false;
// Sanity check.
switch (payload_type) {
@@ -95,48 +74,58 @@
case 79: // 207 Extended report.
LOG(LS_ERROR) << "Can't register invalid receiver payload type: "
<< payload_type;
- return false;
+ return -1;
default:
- return true;
- }
-}
-
-} // namespace
-
-RTPPayloadRegistry::RTPPayloadRegistry()
- : incoming_payload_type_(-1),
- last_received_payload_type_(-1),
- last_received_media_payload_type_(-1),
- rtx_(false),
- ssrc_rtx_(0) {}
-
-RTPPayloadRegistry::~RTPPayloadRegistry() = default;
-
-int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec,
- bool* created_new_payload) {
- *created_new_payload = false;
- if (!IsPayloadTypeValid(audio_codec.pltype))
+ break;
+ }
+
+ size_t payload_name_length = strlen(payload_name);
+
+ rtc::CritScope cs(&crit_sect_);
+
+ RtpUtility::PayloadTypeMap::iterator it =
+ payload_type_map_.find(payload_type);
+
+ if (it != payload_type_map_.end()) {
+ // We already use this payload type.
+ RtpUtility::Payload* payload = it->second;
+
+ assert(payload);
+
+ size_t name_length = strlen(payload->name);
+
+ // Check if it's the same as we already have.
+ // If same, ignore sending an error.
+ if (payload_name_length == name_length &&
+ RtpUtility::StringCompare(
+ payload->name, payload_name, payload_name_length)) {
+ if (rtp_payload_strategy_->PayloadIsCompatible(*payload, frequency,
+ channels, rate)) {
+ rtp_payload_strategy_->UpdatePayloadRate(payload, rate);
+ return 0;
+ }
+ }
+ LOG(LS_ERROR) << "Payload type already registered: "
+ << static_cast<int>(payload_type);
return -1;
-
- rtc::CritScope cs(&crit_sect_);
-
- auto it = payload_type_map_.find(audio_codec.pltype);
- if (it != payload_type_map_.end()) {
- // We already use this payload type. Check if it's the same as we already
- // have. If same, ignore sending an error.
- if (PayloadIsCompatible(it->second, audio_codec)) {
- it->second.typeSpecific.Audio.rate = std::max(0, audio_codec.rate);
- return 0;
- }
- LOG(LS_ERROR) << "Payload type already registered: " << audio_codec.pltype;
- return -1;
- }
-
- // Audio codecs must be unique.
- DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(audio_codec);
-
- payload_type_map_[audio_codec.pltype] = CreatePayloadType(audio_codec);
+ }
+
+ if (rtp_payload_strategy_->CodecsMustBeUnique()) {
+ DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
+ payload_name, payload_name_length, frequency, channels, rate);
+ }
+
+ RtpUtility::Payload* payload = rtp_payload_strategy_->CreatePayloadType(
+ payload_name, payload_type, frequency, channels, rate);
+
+ payload_type_map_[payload_type] = payload;
*created_new_payload = true;
+
+ if (RtpUtility::StringCompare(payload_name, "red", 3)) {
+ red_payload_type_ = payload_type;
+ } else if (RtpUtility::StringCompare(payload_name, "ulpfec", 6)) {
+ ulpfec_payload_type_ = payload_type;
+ }
// Successful set of payload type, clear the value of last received payload
// type since it might mean something else.
@@ -145,37 +134,14 @@
return 0;
}
-int32_t RTPPayloadRegistry::RegisterReceivePayload(
- const VideoCodec& video_codec) {
- if (!IsPayloadTypeValid(video_codec.plType))
- return -1;
-
- rtc::CritScope cs(&crit_sect_);
-
- auto it = payload_type_map_.find(video_codec.plType);
- if (it != payload_type_map_.end()) {
- // We already use this payload type. Check if it's the same as we already
- // have. If same, ignore sending an error.
- if (PayloadIsCompatible(it->second, video_codec))
- return 0;
- LOG(LS_ERROR) << "Payload type already registered: "
- << static_cast<int>(video_codec.plType);
- return -1;
- }
-
- payload_type_map_[video_codec.plType] = CreatePayloadType(video_codec);
-
- // Successful set of payload type, clear the value of last received payload
- // type since it might mean something else.
- last_received_payload_type_ = -1;
- last_received_media_payload_type_ = -1;
- return 0;
-}
-
int32_t RTPPayloadRegistry::DeRegisterReceivePayload(
const int8_t payload_type) {
rtc::CritScope cs(&crit_sect_);
- payload_type_map_.erase(payload_type);
+ RtpUtility::PayloadTypeMap::iterator it =
+ payload_type_map_.find(payload_type);
+ assert(it != payload_type_map_.end());
+ delete it->second;
+ payload_type_map_.erase(it);
return 0;
}
@@ -183,40 +149,95 @@
// for audio codecs, but there can for video.
// Always called from within a critical section.
void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
- const CodecInst& audio_codec) {
- for (auto iterator = payload_type_map_.begin();
- iterator != payload_type_map_.end(); ++iterator) {
- if (PayloadIsCompatible(iterator->second, audio_codec)) {
- // Remove old setting.
- payload_type_map_.erase(iterator);
- break;
+ const char* const payload_name,
+ const size_t payload_name_length,
+ const uint32_t frequency,
+ const size_t channels,
+ const uint32_t rate) {
+ RtpUtility::PayloadTypeMap::iterator iterator = payload_type_map_.begin();
+ for (; iterator != payload_type_map_.end(); ++iterator) {
+ RtpUtility::Payload* payload = iterator->second;
+ size_t name_length = strlen(payload->name);
+
+ if (payload_name_length == name_length &&
+ RtpUtility::StringCompare(
+ payload->name, payload_name, payload_name_length)) {
+ // We found the payload name in the list.
+ // If audio, check frequency and rate.
+ if (payload->audio) {
+ if (rtp_payload_strategy_->PayloadIsCompatible(*payload, frequency,
+ channels, rate)) {
+ // Remove old setting.
+ delete payload;
+ payload_type_map_.erase(iterator);
+ break;
+ }
+ } else if (RtpUtility::StringCompare(payload_name, "red", 3)) {
+ delete payload;
+ payload_type_map_.erase(iterator);
+ break;
+ }
}
}
}
int32_t RTPPayloadRegistry::ReceivePayloadType(const CodecInst& audio_codec,
int8_t* payload_type) const {
- assert(payload_type);
- rtc::CritScope cs(&crit_sect_);
-
- for (const auto& it : payload_type_map_) {
- if (PayloadIsCompatible(it.second, audio_codec)) {
- *payload_type = it.first;
- return 0;
- }
- }
- return -1;
+ return ReceivePayloadType(audio_codec.plname, audio_codec.plfreq,
+ audio_codec.channels, std::max(0, audio_codec.rate),
+ payload_type);
}
int32_t RTPPayloadRegistry::ReceivePayloadType(const VideoCodec& video_codec,
int8_t* payload_type) const {
+ return ReceivePayloadType(video_codec.plName, kVideoPayloadTypeFrequency,
+ 0 /* channels */, 0 /* rate */, payload_type);
+}
+
+int32_t RTPPayloadRegistry::ReceivePayloadType(const char* const payload_name,
+ const uint32_t frequency,
+ const size_t channels,
+ const uint32_t rate,
+ int8_t* payload_type) const {
assert(payload_type);
- rtc::CritScope cs(&crit_sect_);
-
- for (const auto& it : payload_type_map_) {
- if (PayloadIsCompatible(it.second, video_codec)) {
- *payload_type = it.first;
- return 0;
+ size_t payload_name_length = strlen(payload_name);
+
+ rtc::CritScope cs(&crit_sect_);
+
+ RtpUtility::PayloadTypeMap::const_iterator it = payload_type_map_.begin();
+
+ for (; it != payload_type_map_.end(); ++it) {
+ RtpUtility::Payload* payload = it->second;
+ assert(payload);
+
+ size_t name_length = strlen(payload->name);
+ if (payload_name_length == name_length &&
+ RtpUtility::StringCompare(
+ payload->name, payload_name, payload_name_length)) {
+ // Name matches.
+ if (payload->audio) {
+ if (rate == 0) {
+ // [default] audio, check freq and channels.
+ if (payload->typeSpecific.Audio.frequency == frequency &&
+ payload->typeSpecific.Audio.channels == channels) {
+ *payload_type = it->first;
+ return 0;
+ }
+ } else {
+ // Non-default audio, check freq, channels and rate.
+ if (payload->typeSpecific.Audio.frequency == frequency &&
+ payload->typeSpecific.Audio.channels == channels &&
+ payload->typeSpecific.Audio.rate == rate) {
+ // extra rate condition added
+ *payload_type = it->first;
+ return 0;
+ }
+ }
+ } else {
+ // Video.
+ *payload_type = it->first;
+ return 0;
+ }
}
}
return -1;
@@ -312,8 +333,7 @@
bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const {
rtc::CritScope cs(&crit_sect_);
- auto it = payload_type_map_.find(header.payloadType);
- return it != payload_type_map_.end() && _stricmp(it->second.name, "red") == 0;
+ return red_payload_type_ == header.payloadType;
}
bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const {
@@ -323,13 +343,14 @@
bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type,
PayloadUnion* payload) const {
rtc::CritScope cs(&crit_sect_);
- auto it = payload_type_map_.find(payload_type);
+ RtpUtility::PayloadTypeMap::const_iterator it =
+ payload_type_map_.find(payload_type);
// Check that this is a registered payload type.
if (it == payload_type_map_.end()) {
return false;
}
- *payload = it->second.typeSpecific;
+ *payload = it->second->typeSpecific;
return true;
}
@@ -340,22 +361,22 @@
return -1;
}
rtc::CritScope cs(&crit_sect_);
- return payload->audio ? payload->typeSpecific.Audio.frequency
- : kVideoPayloadTypeFrequency;
+ return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload);
}
const RtpUtility::Payload* RTPPayloadRegistry::PayloadTypeToPayload(
uint8_t payload_type) const {
rtc::CritScope cs(&crit_sect_);
- auto it = payload_type_map_.find(payload_type);
+ RtpUtility::PayloadTypeMap::const_iterator it =
+ payload_type_map_.find(payload_type);
// Check that this is a registered payload type.
if (it == payload_type_map_.end()) {
return nullptr;
}
- return &it->second;
+ return it->second;
}
void RTPPayloadRegistry::SetIncomingPayloadType(const RTPHeader& header) {
@@ -374,15 +395,106 @@
return false;
}
-// Returns -1 if a payload with name |payload_name| is not registered.
-int8_t RTPPayloadRegistry::GetPayloadTypeWithName(
- const char* payload_name) const {
- rtc::CritScope cs(&crit_sect_);
- for (const auto& it : payload_type_map_) {
- if (_stricmp(it.second.name, payload_name) == 0)
- return it.first;
- }
- return -1;
+class RTPPayloadAudioStrategy : public RTPPayloadStrategy {
+ public:
+ bool CodecsMustBeUnique() const override { return true; }
+
+ bool PayloadIsCompatible(const RtpUtility::Payload& payload,
+ const uint32_t frequency,
+ const size_t channels,
+ const uint32_t rate) const override {
+ return
+ payload.audio &&
+ payload.typeSpecific.Audio.frequency == frequency &&
+ payload.typeSpecific.Audio.channels == channels &&
+ (payload.typeSpecific.Audio.rate == rate ||
+ payload.typeSpecific.Audio.rate == 0 || rate == 0);
+ }
+
+ void UpdatePayloadRate(RtpUtility::Payload* payload,
+ const uint32_t rate) const override {
+ payload->typeSpecific.Audio.rate = rate;
+ }
+
+ RtpUtility::Payload* CreatePayloadType(const char* const payloadName,
+ const int8_t payloadType,
+ const uint32_t frequency,
+ const size_t channels,
+ const uint32_t rate) const override {
+ RtpUtility::Payload* payload = new RtpUtility::Payload;
+ payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
+ strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
+ assert(frequency >= 1000);
+ payload->typeSpecific.Audio.frequency = frequency;
+ payload->typeSpecific.Audio.channels = channels;
+ payload->typeSpecific.Audio.rate = rate;
+ payload->audio = true;
+ return payload;
+ }
+
+ int GetPayloadTypeFrequency(
+ const RtpUtility::Payload& payload) const override {
+ return payload.typeSpecific.Audio.frequency;
+ }
+};
+
+class RTPPayloadVideoStrategy : public RTPPayloadStrategy {
+ public:
+ bool CodecsMustBeUnique() const override { return false; }
+
+ bool PayloadIsCompatible(const RtpUtility::Payload& payload,
+ const uint32_t frequency,
+ const size_t channels,
+ const uint32_t rate) const override {
+ return !payload.audio;
+ }
+
+ void UpdatePayloadRate(RtpUtility::Payload* payload,
+ const uint32_t rate) const override {}
+
+ RtpUtility::Payload* CreatePayloadType(const char* const payloadName,
+ const int8_t payloadType,
+ const uint32_t frequency,
+ const size_t channels,
+ const uint32_t rate) const override {
+ RtpVideoCodecTypes videoType = kRtpVideoGeneric;
+
+ if (RtpUtility::StringCompare(payloadName, "VP8", 3)) {
+ videoType = kRtpVideoVp8;
+ } else if (RtpUtility::StringCompare(payloadName, "VP9", 3)) {
+ videoType = kRtpVideoVp9;
+ } else if (RtpUtility::StringCompare(payloadName, "H264", 4)) {
+ videoType = kRtpVideoH264;
+ } else if (RtpUtility::StringCompare(payloadName, "I420", 4)) {
+ videoType = kRtpVideoGeneric;
+ } else if (RtpUtility::StringCompare(payloadName, "ULPFEC", 6) ||
+ RtpUtility::StringCompare(payloadName, "RED", 3)) {
+ videoType = kRtpVideoNone;
+ } else {
+ videoType = kRtpVideoGeneric;
+ }
+ RtpUtility::Payload* payload = new RtpUtility::Payload;
+
+ payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
+ strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
+ payload->typeSpecific.Video.videoCodecType = videoType;
+ payload->audio = false;
+ return payload;
+ }
+
+ int GetPayloadTypeFrequency(
+ const RtpUtility::Payload& payload) const override {
+ return kVideoPayloadTypeFrequency;
+ }
+};
+
+RTPPayloadStrategy* RTPPayloadStrategy::CreateStrategy(
+ const bool handling_audio) {
+ if (handling_audio) {
+ return new RTPPayloadAudioStrategy();
+ } else {
+ return new RTPPayloadVideoStrategy();
+ }
}
} // namespace webrtc
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc ('k') | webrtc/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698