2013-01-17 16:10:45 +00:00
|
|
|
/*
|
2013-02-04 13:23:07 +00:00
|
|
|
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
2013-01-17 16:10:45 +00:00
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-11-04 08:31:52 +01:00
|
|
|
#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
|
2013-01-17 16:10:45 +00:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
2016-11-24 09:34:46 -08:00
|
|
|
#include "webrtc/common_types.h"
|
2017-03-27 07:15:49 -07:00
|
|
|
#include "webrtc/modules/audio_coding/codecs/audio_format_conversion.h"
|
2017-07-06 19:44:34 +02:00
|
|
|
#include "webrtc/rtc_base/checks.h"
|
|
|
|
|
#include "webrtc/rtc_base/logging.h"
|
|
|
|
|
#include "webrtc/rtc_base/stringutils.h"
|
2013-01-17 16:10:45 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
namespace {
|
2016-11-24 09:34:46 -08:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
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;
|
|
|
|
|
return audio_payload.frequency == static_cast<uint32_t>(audio_codec.plfreq) &&
|
2016-12-06 03:52:18 -08:00
|
|
|
audio_payload.channels == audio_codec.channels;
|
2016-11-24 09:34:46 -08:00
|
|
|
}
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
bool PayloadIsCompatible(const RtpUtility::Payload& payload,
|
|
|
|
|
const VideoCodec& video_codec) {
|
2016-11-25 10:06:31 -08:00
|
|
|
if (payload.audio || _stricmp(payload.name, video_codec.plName) != 0)
|
|
|
|
|
return false;
|
|
|
|
|
// For H264, profiles must match as well.
|
|
|
|
|
if (video_codec.codecType == kVideoCodecH264) {
|
|
|
|
|
return video_codec.H264().profile ==
|
|
|
|
|
payload.typeSpecific.Video.h264_profile;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2016-11-24 10:43:42 -08:00
|
|
|
}
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
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;
|
2016-12-06 03:52:18 -08:00
|
|
|
payload.typeSpecific.Audio.rate = 0;
|
2016-11-25 06:40:25 -08:00
|
|
|
payload.audio = true;
|
|
|
|
|
return payload;
|
2016-11-24 10:43:42 -08:00
|
|
|
}
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
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);
|
2016-11-25 10:06:31 -08:00
|
|
|
if (video_codec.codecType == kVideoCodecH264)
|
|
|
|
|
payload.typeSpecific.Video.h264_profile = video_codec.H264().profile;
|
2016-11-25 06:40:25 -08:00
|
|
|
payload.audio = false;
|
|
|
|
|
return payload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsPayloadTypeValid(int8_t payload_type) {
|
2013-04-05 13:27:38 +00:00
|
|
|
assert(payload_type >= 0);
|
2013-01-17 16:10:45 +00:00
|
|
|
|
|
|
|
|
// Sanity check.
|
|
|
|
|
switch (payload_type) {
|
|
|
|
|
// Reserved payload types to avoid RTCP conflicts when marker bit is set.
|
|
|
|
|
case 64: // 192 Full INTRA-frame request.
|
|
|
|
|
case 72: // 200 Sender report.
|
|
|
|
|
case 73: // 201 Receiver report.
|
|
|
|
|
case 74: // 202 Source description.
|
|
|
|
|
case 75: // 203 Goodbye.
|
|
|
|
|
case 76: // 204 Application-defined.
|
|
|
|
|
case 77: // 205 Transport layer FB message.
|
|
|
|
|
case 78: // 206 Payload-specific FB message.
|
|
|
|
|
case 79: // 207 Extended report.
|
2014-04-08 11:06:12 +00:00
|
|
|
LOG(LS_ERROR) << "Can't register invalid receiver payload type: "
|
|
|
|
|
<< payload_type;
|
2016-11-25 06:40:25 -08:00
|
|
|
return false;
|
2013-01-17 16:10:45 +00:00
|
|
|
default:
|
2016-11-25 06:40:25 -08:00
|
|
|
return true;
|
2013-01-17 16:10:45 +00:00
|
|
|
}
|
2016-11-25 06:40:25 -08:00
|
|
|
}
|
2013-01-17 16:10:45 +00:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
} // namespace
|
2013-01-17 16:10:45 +00:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
RTPPayloadRegistry::RTPPayloadRegistry()
|
|
|
|
|
: incoming_payload_type_(-1),
|
|
|
|
|
last_received_payload_type_(-1),
|
|
|
|
|
last_received_media_payload_type_(-1),
|
|
|
|
|
rtx_(false),
|
|
|
|
|
ssrc_rtx_(0) {}
|
2016-11-24 10:43:42 -08:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
RTPPayloadRegistry::~RTPPayloadRegistry() = default;
|
2017-03-27 07:15:49 -07:00
|
|
|
|
|
|
|
|
void RTPPayloadRegistry::SetAudioReceivePayloads(
|
|
|
|
|
std::map<int, SdpAudioFormat> codecs) {
|
|
|
|
|
rtc::CritScope cs(&crit_sect_);
|
|
|
|
|
|
|
|
|
|
#if RTC_DCHECK_IS_ON
|
|
|
|
|
RTC_DCHECK(!used_for_video_);
|
|
|
|
|
used_for_audio_ = true;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
payload_type_map_.clear();
|
|
|
|
|
for (const auto& kv : codecs) {
|
|
|
|
|
const int& rtp_payload_type = kv.first;
|
|
|
|
|
const SdpAudioFormat& audio_format = kv.second;
|
|
|
|
|
const CodecInst ci = SdpToCodecInst(rtp_payload_type, audio_format);
|
|
|
|
|
RTC_DCHECK(IsPayloadTypeValid(rtp_payload_type));
|
|
|
|
|
payload_type_map_.insert(
|
|
|
|
|
std::make_pair(rtp_payload_type, CreatePayloadType(ci)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clear the value of last received payload type since it might mean
|
|
|
|
|
// something else now.
|
|
|
|
|
last_received_payload_type_ = -1;
|
|
|
|
|
last_received_media_payload_type_ = -1;
|
|
|
|
|
}
|
2016-11-25 06:40:25 -08:00
|
|
|
|
|
|
|
|
int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec,
|
|
|
|
|
bool* created_new_payload) {
|
2017-03-23 00:10:09 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
|
|
|
|
|
|
|
|
|
#if RTC_DCHECK_IS_ON
|
|
|
|
|
RTC_DCHECK(!used_for_video_);
|
|
|
|
|
used_for_audio_ = true;
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
*created_new_payload = false;
|
|
|
|
|
if (!IsPayloadTypeValid(audio_codec.pltype))
|
|
|
|
|
return -1;
|
2016-11-24 11:08:39 -08:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
auto it = payload_type_map_.find(audio_codec.pltype);
|
2013-01-17 16:10:45 +00:00
|
|
|
if (it != payload_type_map_.end()) {
|
2016-11-25 06:40:25 -08:00
|
|
|
// 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)) {
|
2016-12-06 03:52:18 -08:00
|
|
|
it->second.typeSpecific.Audio.rate = 0;
|
2016-11-25 06:40:25 -08:00
|
|
|
return 0;
|
2013-01-17 16:10:45 +00:00
|
|
|
}
|
2016-11-25 06:40:25 -08:00
|
|
|
LOG(LS_ERROR) << "Payload type already registered: " << audio_codec.pltype;
|
2013-01-17 16:10:45 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
// Audio codecs must be unique.
|
|
|
|
|
DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(audio_codec);
|
2016-11-24 10:43:42 -08:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
payload_type_map_[audio_codec.pltype] = CreatePayloadType(audio_codec);
|
2016-11-24 11:08:39 -08:00
|
|
|
*created_new_payload = true;
|
2016-11-24 10:43:42 -08:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
// 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) {
|
2017-03-23 00:10:09 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
|
|
|
|
|
|
|
|
|
#if RTC_DCHECK_IS_ON
|
|
|
|
|
RTC_DCHECK(!used_for_audio_);
|
|
|
|
|
used_for_video_ = true;
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
if (!IsPayloadTypeValid(video_codec.plType))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
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;
|
2013-01-17 16:10:45 +00:00
|
|
|
}
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
payload_type_map_[video_codec.plType] = CreatePayloadType(video_codec);
|
|
|
|
|
|
2013-01-17 16:10:45 +00:00
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-08 11:08:41 +00:00
|
|
|
int32_t RTPPayloadRegistry::DeRegisterReceivePayload(
|
|
|
|
|
const int8_t payload_type) {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2016-11-25 06:40:25 -08:00
|
|
|
payload_type_map_.erase(payload_type);
|
2013-01-17 16:10:45 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-04 13:23:07 +00:00
|
|
|
// There can't be several codecs with the same rate, frequency and channels
|
|
|
|
|
// for audio codecs, but there can for video.
|
2013-09-06 13:40:11 +00:00
|
|
|
// Always called from within a critical section.
|
2013-02-04 13:23:07 +00:00
|
|
|
void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
|
2016-11-25 06:40:25 -08:00
|
|
|
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;
|
2013-02-04 13:23:07 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-24 09:34:46 -08:00
|
|
|
int32_t RTPPayloadRegistry::ReceivePayloadType(const CodecInst& audio_codec,
|
|
|
|
|
int8_t* payload_type) const {
|
2016-11-25 06:40:25 -08:00
|
|
|
assert(payload_type);
|
|
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2016-11-24 09:34:46 -08:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
for (const auto& it : payload_type_map_) {
|
|
|
|
|
if (PayloadIsCompatible(it.second, audio_codec)) {
|
|
|
|
|
*payload_type = it.first;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
2016-11-24 11:08:39 -08:00
|
|
|
}
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
int32_t RTPPayloadRegistry::ReceivePayloadType(const VideoCodec& video_codec,
|
2016-11-24 11:08:39 -08:00
|
|
|
int8_t* payload_type) const {
|
2014-04-08 11:06:12 +00:00
|
|
|
assert(payload_type);
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-09-06 13:40:11 +00:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
for (const auto& it : payload_type_map_) {
|
|
|
|
|
if (PayloadIsCompatible(it.second, video_codec)) {
|
|
|
|
|
*payload_type = it.first;
|
|
|
|
|
return 0;
|
2013-01-17 16:10:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-06 13:40:11 +00:00
|
|
|
bool RTPPayloadRegistry::RtxEnabled() const {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-09-06 13:40:11 +00:00
|
|
|
return rtx_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const {
|
|
|
|
|
return rtx_ && ssrc_rtx_ == header.ssrc;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-05 08:25:29 +00:00
|
|
|
void RTPPayloadRegistry::SetRtxSsrc(uint32_t ssrc) {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2014-06-05 08:25:29 +00:00
|
|
|
ssrc_rtx_ = ssrc;
|
|
|
|
|
rtx_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-27 07:38:56 +00:00
|
|
|
bool RTPPayloadRegistry::GetRtxSsrc(uint32_t* ssrc) const {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2014-11-27 07:38:56 +00:00
|
|
|
*ssrc = ssrc_rtx_;
|
|
|
|
|
return rtx_;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-21 20:24:50 +08:00
|
|
|
void RTPPayloadRegistry::SetRtxPayloadType(int payload_type,
|
|
|
|
|
int associated_payload_type) {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2015-04-21 20:24:50 +08:00
|
|
|
if (payload_type < 0) {
|
|
|
|
|
LOG(LS_ERROR) << "Invalid RTX payload type: " << payload_type;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtx_payload_type_map_[payload_type] = associated_payload_type;
|
2014-06-05 08:25:29 +00:00
|
|
|
rtx_ = true;
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RTPPayloadRegistry::IsRed(const RTPHeader& header) const {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2016-11-25 06:40:25 -08:00
|
|
|
auto it = payload_type_map_.find(header.payloadType);
|
|
|
|
|
return it != payload_type_map_.end() && _stricmp(it->second.name, "red") == 0;
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
2013-08-15 23:38:54 +00:00
|
|
|
bool RTPPayloadRegistry::GetPayloadSpecifics(uint8_t payload_type,
|
|
|
|
|
PayloadUnion* payload) const {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2016-11-25 06:40:25 -08:00
|
|
|
auto it = payload_type_map_.find(payload_type);
|
2013-08-15 23:38:54 +00:00
|
|
|
|
|
|
|
|
// Check that this is a registered payload type.
|
|
|
|
|
if (it == payload_type_map_.end()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-11-25 06:40:25 -08:00
|
|
|
*payload = it->second.typeSpecific;
|
2013-08-15 23:38:54 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int RTPPayloadRegistry::GetPayloadTypeFrequency(
|
|
|
|
|
uint8_t payload_type) const {
|
2015-12-10 09:51:54 -08:00
|
|
|
const RtpUtility::Payload* payload = PayloadTypeToPayload(payload_type);
|
|
|
|
|
if (!payload) {
|
2013-08-15 23:38:54 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2016-11-25 06:40:25 -08:00
|
|
|
return payload->audio ? payload->typeSpecific.Audio.frequency
|
|
|
|
|
: kVideoPayloadTypeFrequency;
|
2013-08-15 23:38:54 +00:00
|
|
|
}
|
|
|
|
|
|
2015-12-10 09:51:54 -08:00
|
|
|
const RtpUtility::Payload* RTPPayloadRegistry::PayloadTypeToPayload(
|
|
|
|
|
uint8_t payload_type) const {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-01-17 16:10:45 +00:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
auto it = payload_type_map_.find(payload_type);
|
2013-01-17 16:10:45 +00:00
|
|
|
|
|
|
|
|
// Check that this is a registered payload type.
|
|
|
|
|
if (it == payload_type_map_.end()) {
|
2015-12-10 09:51:54 -08:00
|
|
|
return nullptr;
|
2013-01-17 16:10:45 +00:00
|
|
|
}
|
2013-08-15 23:38:54 +00:00
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
return &it->second;
|
2013-01-17 16:10:45 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-06 13:40:11 +00:00
|
|
|
void RTPPayloadRegistry::SetIncomingPayloadType(const RTPHeader& header) {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-09-06 13:40:11 +00:00
|
|
|
if (!IsRtxInternal(header))
|
|
|
|
|
incoming_payload_type_ = header.payloadType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RTPPayloadRegistry::ReportMediaPayloadType(uint8_t media_payload_type) {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-01-17 16:10:45 +00:00
|
|
|
if (last_received_media_payload_type_ == media_payload_type) {
|
|
|
|
|
// Media type unchanged.
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
last_received_media_payload_type_ = media_payload_type;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-25 06:40:25 -08:00
|
|
|
// 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;
|
2013-02-04 13:23:07 +00:00
|
|
|
}
|
2016-11-25 06:40:25 -08:00
|
|
|
return -1;
|
2013-02-04 13:23:07 +00:00
|
|
|
}
|
|
|
|
|
|
2013-01-17 16:10:45 +00:00
|
|
|
} // namespace webrtc
|