Chromium Code Reviews| 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 a4354d393ea99cea9a6a0964a77c962fe8d6ab4b..89a2fa754b0e2256373dbae8e2b29e8ebd1e530b 100644 |
| --- a/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc |
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_payload_registry.cc |
| @@ -10,55 +10,85 @@ |
| #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
|
danilchap
2016/11/24 13:24:36
#include <algorithm>
for std::max
magjed_webrtc
2016/11/24 14:29:29
Done.
|
| +#include "webrtc/base/checks.h" |
| #include "webrtc/base/logging.h" |
| #include "webrtc/common_types.h" |
| #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| namespace webrtc { |
| -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) {} |
| +namespace { |
| -RTPPayloadRegistry::~RTPPayloadRegistry() { |
| - while (!payload_type_map_.empty()) { |
| - RtpUtility::PayloadTypeMap::iterator it = payload_type_map_.begin(); |
| - delete it->second; |
| - payload_type_map_.erase(it); |
| - } |
| +bool PayloadIsCompatible(const RtpUtility::Payload& payload, |
| + const CodecInst& audio_codec) { |
| + if (!payload.audio) |
| + return false; |
| + if (!RtpUtility::StringCompare(payload.name, audio_codec.plname)) |
| + 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); |
| } |
| -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); |
| +bool PayloadIsCompatible(const RtpUtility::Payload& payload, |
| + const VideoCodec& video_codec) { |
| + return !payload.audio && |
| + RtpUtility::StringCompare(payload.name, video_codec.plName); |
| } |
| -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); |
| +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; |
| } |
| -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) { |
| +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; |
| +} |
| + |
| +} // anonymous namespace |
|
danilchap
2016/11/24 13:24:36
remove 'anonymous ':
} // namespace
magjed_webrtc
2016/11/24 14:29:29
Done.
|
| + |
| +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; |
| + |
| +bool IsPayloadTypeValid(int8_t payload_type) { |
|
danilchap
2016/11/24 13:24:36
move this function into unnamed namespace too.
magjed_webrtc
2016/11/24 14:29:29
Done.
|
| assert(payload_type >= 0); |
| - assert(payload_name); |
| - *created_new_payload = false; |
| // Sanity check. |
| switch (payload_type) { |
| @@ -74,59 +104,67 @@ int32_t RTPPayloadRegistry::RegisterReceivePayload( |
| case 79: // 207 Extended report. |
| LOG(LS_ERROR) << "Can't register invalid receiver payload type: " |
| << payload_type; |
| - return -1; |
| + return false; |
| default: |
| - break; |
| + return true; |
| } |
| +} |
| - size_t payload_name_length = strlen(payload_name); |
| +int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec, |
| + bool* created_new_payload) { |
| + *created_new_payload = false; |
| + if (!IsPayloadTypeValid(audio_codec.pltype)) |
| + return -1; |
| - rtc::CritScope cs(&crit_sect_); |
| + const uint32_t rate = std::max(0, audio_codec.rate); |
| - RtpUtility::PayloadTypeMap::iterator it = |
| - payload_type_map_.find(payload_type); |
| + 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. |
| - 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; |
| - } |
| + // 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 = rate; |
| + return 0; |
| } |
| - LOG(LS_ERROR) << "Payload type already registered: " |
| - << static_cast<int>(payload_type); |
| + LOG(LS_ERROR) << "Payload type already registered: " << audio_codec.pltype; |
| return -1; |
| } |
| - 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); |
| + // Audio codecs must be unique. |
| + DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(audio_codec); |
| - payload_type_map_[payload_type] = payload; |
| + payload_type_map_[audio_codec.pltype] = CreatePayloadType(audio_codec); |
| *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. |
| + last_received_payload_type_ = -1; |
| + last_received_media_payload_type_ = -1; |
| + 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; |
| @@ -137,11 +175,7 @@ int32_t RTPPayloadRegistry::RegisterReceivePayload( |
| int32_t RTPPayloadRegistry::DeRegisterReceivePayload( |
| const int8_t payload_type) { |
| rtc::CritScope cs(&crit_sect_); |
| - RtpUtility::PayloadTypeMap::iterator it = |
| - payload_type_map_.find(payload_type); |
| - assert(it != payload_type_map_.end()); |
| - delete it->second; |
| - payload_type_map_.erase(it); |
| + payload_type_map_.erase(payload_type); |
| return 0; |
| } |
| @@ -149,95 +183,40 @@ int32_t RTPPayloadRegistry::DeRegisterReceivePayload( |
| // for audio codecs, but there can for video. |
| // Always called from within a critical section. |
| void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType( |
| - 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; |
| - } |
| + 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; |
| } |
| } |
| } |
| int32_t RTPPayloadRegistry::ReceivePayloadType(const CodecInst& audio_codec, |
| int8_t* payload_type) const { |
| - return ReceivePayloadType(audio_codec.plname, audio_codec.plfreq, |
| - audio_codec.channels, std::max(0, audio_codec.rate), |
| - payload_type); |
| -} |
| + assert(payload_type); |
| + rtc::CritScope cs(&crit_sect_); |
| -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); |
| + for (const auto& it : payload_type_map_) { |
| + if (PayloadIsCompatible(it.second, audio_codec)) { |
| + *payload_type = it.first; |
| + return 0; |
| + } |
| + } |
| + return -1; |
| } |
| -int32_t RTPPayloadRegistry::ReceivePayloadType(const char* const payload_name, |
| - const uint32_t frequency, |
| - const size_t channels, |
| - const uint32_t rate, |
| +int32_t RTPPayloadRegistry::ReceivePayloadType(const VideoCodec& video_codec, |
| int8_t* payload_type) const { |
| assert(payload_type); |
| - 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; |
| - } |
| + for (const auto& it : payload_type_map_) { |
| + if (PayloadIsCompatible(it.second, video_codec)) { |
| + *payload_type = it.first; |
| + return 0; |
| } |
| } |
| return -1; |
| @@ -333,7 +312,9 @@ void RTPPayloadRegistry::SetRtxPayloadType(int payload_type, |
| bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const { |
| rtc::CritScope cs(&crit_sect_); |
| - return red_payload_type_ == header.payloadType; |
| + auto it = payload_type_map_.find(header.payloadType); |
| + return it != payload_type_map_.end() && |
| + RtpUtility::StringCompare(it->second.name, "red"); |
| } |
| bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const { |
| @@ -343,14 +324,13 @@ bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const { |
| bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type, |
| PayloadUnion* payload) const { |
| rtc::CritScope cs(&crit_sect_); |
| - RtpUtility::PayloadTypeMap::const_iterator it = |
| - payload_type_map_.find(payload_type); |
| + auto 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; |
| } |
| @@ -361,22 +341,22 @@ int RTPPayloadRegistry::GetPayloadTypeFrequency( |
| return -1; |
| } |
| rtc::CritScope cs(&crit_sect_); |
| - return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload); |
| + return payload->audio ? payload->typeSpecific.Audio.frequency |
| + : kVideoPayloadTypeFrequency; |
| } |
| const RtpUtility::Payload* RTPPayloadRegistry::PayloadTypeToPayload( |
| uint8_t payload_type) const { |
| rtc::CritScope cs(&crit_sect_); |
| - RtpUtility::PayloadTypeMap::const_iterator it = |
| - payload_type_map_.find(payload_type); |
| + auto 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) { |
| @@ -395,106 +375,15 @@ bool RTPPayloadRegistry::ReportMediaPayloadType(uint8_t media_payload_type) { |
| return false; |
| } |
| -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(); |
| +// 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 (RtpUtility::StringCompare(it.second.name, payload_name)) |
| + return it.first; |
| } |
| + return -1; |
| } |
| } // namespace webrtc |