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
|
|
|
|
2015-10-28 16:39:33 +01:00
|
|
|
#include "webrtc/base/logging.h"
|
2015-03-17 16:42:49 +00:00
|
|
|
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
2013-01-17 16:10:45 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2015-04-21 20:24:50 +08:00
|
|
|
RTPPayloadRegistry::RTPPayloadRegistry(RTPPayloadStrategy* rtp_payload_strategy)
|
2016-04-14 03:05:31 -07:00
|
|
|
: rtp_payload_strategy_(rtp_payload_strategy),
|
2013-01-17 16:10:45 +00:00
|
|
|
red_payload_type_(-1),
|
2013-09-06 13:40:11 +00:00
|
|
|
ulpfec_payload_type_(-1),
|
|
|
|
|
incoming_payload_type_(-1),
|
2013-01-17 16:10:45 +00:00
|
|
|
last_received_payload_type_(-1),
|
2013-09-06 13:40:11 +00:00
|
|
|
last_received_media_payload_type_(-1),
|
|
|
|
|
rtx_(false),
|
2015-04-21 20:24:50 +08:00
|
|
|
rtx_payload_type_(-1),
|
2015-10-14 11:29:49 -07:00
|
|
|
ssrc_rtx_(0) {}
|
2013-01-17 16:10:45 +00:00
|
|
|
|
|
|
|
|
RTPPayloadRegistry::~RTPPayloadRegistry() {
|
|
|
|
|
while (!payload_type_map_.empty()) {
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::PayloadTypeMap::iterator it = payload_type_map_.begin();
|
2013-01-17 16:10:45 +00:00
|
|
|
delete it->second;
|
|
|
|
|
payload_type_map_.erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-08 11:08:41 +00:00
|
|
|
int32_t RTPPayloadRegistry::RegisterReceivePayload(
|
2013-01-17 16:10:45 +00:00
|
|
|
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
2013-04-08 11:08:41 +00:00
|
|
|
const int8_t payload_type,
|
|
|
|
|
const uint32_t frequency,
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
const size_t channels,
|
2013-04-08 11:08:41 +00:00
|
|
|
const uint32_t rate,
|
2013-02-04 13:23:07 +00:00
|
|
|
bool* created_new_payload) {
|
2013-04-05 13:27:38 +00:00
|
|
|
assert(payload_type >= 0);
|
2013-01-17 16:10:45 +00:00
|
|
|
assert(payload_name);
|
2013-02-04 13:23:07 +00:00
|
|
|
*created_new_payload = false;
|
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;
|
2013-01-17 16:10:45 +00:00
|
|
|
return -1;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-04-05 13:27:38 +00:00
|
|
|
|
2013-01-17 16:10:45 +00:00
|
|
|
size_t payload_name_length = strlen(payload_name);
|
|
|
|
|
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-09-06 13:40:11 +00:00
|
|
|
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::PayloadTypeMap::iterator it =
|
|
|
|
|
payload_type_map_.find(payload_type);
|
2013-01-17 16:10:45 +00:00
|
|
|
|
|
|
|
|
if (it != payload_type_map_.end()) {
|
|
|
|
|
// We already use this payload type.
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::Payload* payload = it->second;
|
2013-02-04 13:23:07 +00:00
|
|
|
|
2013-01-17 16:10:45 +00:00
|
|
|
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 &&
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::StringCompare(
|
2013-01-17 16:10:45 +00:00
|
|
|
payload->name, payload_name, payload_name_length)) {
|
2013-02-04 13:23:07 +00:00
|
|
|
if (rtp_payload_strategy_->PayloadIsCompatible(*payload, frequency,
|
|
|
|
|
channels, rate)) {
|
|
|
|
|
rtp_payload_strategy_->UpdatePayloadRate(payload, rate);
|
2013-01-17 16:10:45 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-01-30 19:53:42 +00:00
|
|
|
LOG(LS_ERROR) << "Payload type already registered: "
|
|
|
|
|
<< static_cast<int>(payload_type);
|
2013-01-17 16:10:45 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-04 13:23:07 +00:00
|
|
|
if (rtp_payload_strategy_->CodecsMustBeUnique()) {
|
|
|
|
|
DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
|
|
|
|
|
payload_name, payload_name_length, frequency, channels, rate);
|
|
|
|
|
}
|
2013-01-17 16:10:45 +00:00
|
|
|
|
2015-03-25 16:11:24 +01:00
|
|
|
RtpUtility::Payload* payload = rtp_payload_strategy_->CreatePayloadType(
|
|
|
|
|
payload_name, payload_type, frequency, channels, rate);
|
|
|
|
|
|
|
|
|
|
payload_type_map_[payload_type] = payload;
|
|
|
|
|
*created_new_payload = true;
|
2013-01-17 16:10:45 +00:00
|
|
|
|
2014-07-08 12:10:51 +00:00
|
|
|
if (RtpUtility::StringCompare(payload_name, "red", 3)) {
|
2013-01-17 16:10:45 +00:00
|
|
|
red_payload_type_ = payload_type;
|
2015-03-25 16:11:24 +01:00
|
|
|
} else if (RtpUtility::StringCompare(payload_name, "ulpfec", 6)) {
|
2013-09-06 13:40:11 +00:00
|
|
|
ulpfec_payload_type_ = payload_type;
|
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_);
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::PayloadTypeMap::iterator it =
|
2014-04-08 11:06:12 +00:00
|
|
|
payload_type_map_.find(payload_type);
|
|
|
|
|
assert(it != payload_type_map_.end());
|
2013-01-17 16:10:45 +00:00
|
|
|
delete it->second;
|
|
|
|
|
payload_type_map_.erase(it);
|
|
|
|
|
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(
|
|
|
|
|
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
|
|
|
|
const size_t payload_name_length,
|
2013-04-08 11:08:41 +00:00
|
|
|
const uint32_t frequency,
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
const size_t channels,
|
2013-04-08 11:08:41 +00:00
|
|
|
const uint32_t rate) {
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::PayloadTypeMap::iterator iterator = payload_type_map_.begin();
|
2013-02-04 13:23:07 +00:00
|
|
|
for (; iterator != payload_type_map_.end(); ++iterator) {
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::Payload* payload = iterator->second;
|
2013-02-04 13:23:07 +00:00
|
|
|
size_t name_length = strlen(payload->name);
|
|
|
|
|
|
2014-07-08 12:10:51 +00:00
|
|
|
if (payload_name_length == name_length &&
|
|
|
|
|
RtpUtility::StringCompare(
|
|
|
|
|
payload->name, payload_name, payload_name_length)) {
|
2013-02-04 13:23:07 +00:00
|
|
|
// 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;
|
|
|
|
|
}
|
2014-07-08 12:10:51 +00:00
|
|
|
} else if (RtpUtility::StringCompare(payload_name, "red", 3)) {
|
2013-02-04 13:23:07 +00:00
|
|
|
delete payload;
|
|
|
|
|
payload_type_map_.erase(iterator);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-08 11:08:41 +00:00
|
|
|
int32_t RTPPayloadRegistry::ReceivePayloadType(
|
2013-01-17 16:10:45 +00:00
|
|
|
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
2013-04-08 11:08:41 +00:00
|
|
|
const uint32_t frequency,
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
const size_t channels,
|
2013-04-08 11:08:41 +00:00
|
|
|
const uint32_t rate,
|
|
|
|
|
int8_t* payload_type) const {
|
2014-04-08 11:06:12 +00:00
|
|
|
assert(payload_type);
|
2013-01-17 16:10:45 +00:00
|
|
|
size_t payload_name_length = strlen(payload_name);
|
|
|
|
|
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-09-06 13:40:11 +00:00
|
|
|
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::PayloadTypeMap::const_iterator it = payload_type_map_.begin();
|
2013-01-17 16:10:45 +00:00
|
|
|
|
2013-02-04 13:23:07 +00:00
|
|
|
for (; it != payload_type_map_.end(); ++it) {
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::Payload* payload = it->second;
|
2013-01-17 16:10:45 +00:00
|
|
|
assert(payload);
|
|
|
|
|
|
|
|
|
|
size_t name_length = strlen(payload->name);
|
|
|
|
|
if (payload_name_length == name_length &&
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::StringCompare(
|
2013-01-17 16:10:45 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
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::IsRtx(const RTPHeader& header) const {
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2013-09-06 13:40:11 +00:00
|
|
|
return IsRtxInternal(header);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RTPPayloadRegistry::IsRtxInternal(const RTPHeader& header) const {
|
|
|
|
|
return rtx_ && ssrc_rtx_ == header.ssrc;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-14 11:29:49 -07:00
|
|
|
bool RTPPayloadRegistry::RestoreOriginalPacket(uint8_t* restored_packet,
|
2013-09-06 13:40:11 +00:00
|
|
|
const uint8_t* packet,
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
size_t* packet_length,
|
2013-09-06 13:40:11 +00:00
|
|
|
uint32_t original_ssrc,
|
|
|
|
|
const RTPHeader& header) const {
|
2015-07-01 05:35:53 -07:00
|
|
|
if (kRtxHeaderSize + header.headerLength + header.paddingLength >
|
|
|
|
|
*packet_length) {
|
2013-09-06 13:40:11 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
const uint8_t* rtx_header = packet + header.headerLength;
|
|
|
|
|
uint16_t original_sequence_number = (rtx_header[0] << 8) + rtx_header[1];
|
|
|
|
|
|
|
|
|
|
// Copy the packet into the restored packet, except for the RTX header.
|
2015-10-14 11:29:49 -07:00
|
|
|
memcpy(restored_packet, packet, header.headerLength);
|
|
|
|
|
memcpy(restored_packet + header.headerLength,
|
2013-09-06 13:40:11 +00:00
|
|
|
packet + header.headerLength + kRtxHeaderSize,
|
|
|
|
|
*packet_length - header.headerLength - kRtxHeaderSize);
|
|
|
|
|
*packet_length -= kRtxHeaderSize;
|
|
|
|
|
|
|
|
|
|
// Replace the SSRC and the sequence number with the originals.
|
2015-10-14 11:29:49 -07:00
|
|
|
ByteWriter<uint16_t>::WriteBigEndian(restored_packet + 2,
|
2015-03-17 16:42:49 +00:00
|
|
|
original_sequence_number);
|
2015-10-14 11:29:49 -07:00
|
|
|
ByteWriter<uint32_t>::WriteBigEndian(restored_packet + 8, original_ssrc);
|
2013-09-06 13:40:11 +00:00
|
|
|
|
2016-04-14 03:05:31 -07:00
|
|
|
rtc::CritScope cs(&crit_sect_);
|
2015-04-21 20:24:50 +08:00
|
|
|
if (!rtx_)
|
|
|
|
|
return true;
|
2013-09-06 13:40:11 +00:00
|
|
|
|
2015-10-14 11:29:49 -07:00
|
|
|
int associated_payload_type;
|
|
|
|
|
auto apt_mapping = rtx_payload_type_map_.find(header.payloadType);
|
2016-02-03 13:29:59 +01:00
|
|
|
if (apt_mapping == rtx_payload_type_map_.end())
|
|
|
|
|
return false;
|
|
|
|
|
associated_payload_type = apt_mapping->second;
|
|
|
|
|
if (red_payload_type_ != -1) {
|
|
|
|
|
// Assume red will be used if it's configured.
|
|
|
|
|
// This is a workaround for a Chrome sdp bug where rtx is associated
|
|
|
|
|
// with the media codec even though media is sent over red.
|
|
|
|
|
// TODO(holmer): Remove once the Chrome versions exposing this bug are
|
|
|
|
|
// old enough, which should be once Chrome Stable reaches M53 as this
|
|
|
|
|
// work-around went into M50.
|
|
|
|
|
associated_payload_type = red_payload_type_;
|
2015-04-21 20:24:50 +08:00
|
|
|
}
|
2015-10-14 11:29:49 -07:00
|
|
|
restored_packet[1] = static_cast<uint8_t>(associated_payload_type);
|
2015-04-21 20:24:50 +08:00
|
|
|
if (header.markerBit) {
|
2015-10-14 11:29:49 -07:00
|
|
|
restored_packet[1] |= kRtpMarkerBitMask; // Marker bit is set.
|
2013-09-06 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2015-04-21 20:24:50 +08:00
|
|
|
rtx_payload_type_ = payload_type;
|
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_);
|
2013-09-06 13:40:11 +00:00
|
|
|
return red_payload_type_ == header.payloadType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RTPPayloadRegistry::IsEncapsulated(const RTPHeader& header) const {
|
|
|
|
|
return IsRed(header) || IsRtx(header);
|
|
|
|
|
}
|
|
|
|
|
|
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_);
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::PayloadTypeMap::const_iterator 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;
|
|
|
|
|
}
|
|
|
|
|
*payload = it->second->typeSpecific;
|
|
|
|
|
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_);
|
2013-08-15 23:38:54 +00:00
|
|
|
return rtp_payload_strategy_->GetPayloadTypeFrequency(*payload);
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::PayloadTypeMap::const_iterator 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
|
|
|
|
2015-12-10 09:51:54 -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;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-04 13:23:07 +00:00
|
|
|
class RTPPayloadAudioStrategy : public RTPPayloadStrategy {
|
|
|
|
|
public:
|
2015-03-04 12:58:35 +00:00
|
|
|
bool CodecsMustBeUnique() const override { return true; }
|
2013-02-04 13:23:07 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
bool PayloadIsCompatible(const RtpUtility::Payload& payload,
|
|
|
|
|
const uint32_t frequency,
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
const size_t channels,
|
2015-03-04 12:58:35 +00:00
|
|
|
const uint32_t rate) const override {
|
2013-02-04 13:23:07 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void UpdatePayloadRate(RtpUtility::Payload* payload,
|
|
|
|
|
const uint32_t rate) const override {
|
2013-02-04 13:23:07 +00:00
|
|
|
payload->typeSpecific.Audio.rate = rate;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
RtpUtility::Payload* CreatePayloadType(
|
2013-02-04 13:23:07 +00:00
|
|
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
2013-04-08 11:08:41 +00:00
|
|
|
const int8_t payloadType,
|
|
|
|
|
const uint32_t frequency,
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
const size_t channels,
|
2015-03-04 12:58:35 +00:00
|
|
|
const uint32_t rate) const override {
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::Payload* payload = new RtpUtility::Payload;
|
2013-02-04 13:23:07 +00:00
|
|
|
payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
|
|
|
|
strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
|
2013-08-15 23:38:54 +00:00
|
|
|
assert(frequency >= 1000);
|
2013-02-04 13:23:07 +00:00
|
|
|
payload->typeSpecific.Audio.frequency = frequency;
|
|
|
|
|
payload->typeSpecific.Audio.channels = channels;
|
|
|
|
|
payload->typeSpecific.Audio.rate = rate;
|
|
|
|
|
payload->audio = true;
|
|
|
|
|
return payload;
|
|
|
|
|
}
|
2013-08-15 23:38:54 +00:00
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
int GetPayloadTypeFrequency(
|
|
|
|
|
const RtpUtility::Payload& payload) const override {
|
2013-08-15 23:38:54 +00:00
|
|
|
return payload.typeSpecific.Audio.frequency;
|
|
|
|
|
}
|
2013-02-04 13:23:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class RTPPayloadVideoStrategy : public RTPPayloadStrategy {
|
|
|
|
|
public:
|
2015-03-04 12:58:35 +00:00
|
|
|
bool CodecsMustBeUnique() const override { return false; }
|
2013-02-04 13:23:07 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
bool PayloadIsCompatible(const RtpUtility::Payload& payload,
|
|
|
|
|
const uint32_t frequency,
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
const size_t channels,
|
2015-03-04 12:58:35 +00:00
|
|
|
const uint32_t rate) const override {
|
2013-02-04 13:23:07 +00:00
|
|
|
return !payload.audio;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void UpdatePayloadRate(RtpUtility::Payload* payload,
|
2016-02-16 17:59:27 +01:00
|
|
|
const uint32_t rate) const override {}
|
2013-02-04 13:23:07 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
RtpUtility::Payload* CreatePayloadType(
|
2013-02-04 13:23:07 +00:00
|
|
|
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
2013-04-08 11:08:41 +00:00
|
|
|
const int8_t payloadType,
|
|
|
|
|
const uint32_t frequency,
|
Convert channel counts to size_t.
IIRC, this was originally requested by ajm during review of the other size_t conversions I did over the past year, and I agreed it made sense, but wanted to do it separately since those changes were already gargantuan.
BUG=chromium:81439
TEST=none
R=henrik.lundin@webrtc.org, henrika@webrtc.org, kjellander@webrtc.org, minyue@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1316523002 .
Cr-Commit-Position: refs/heads/master@{#11229}
2016-01-12 16:26:35 -08:00
|
|
|
const size_t channels,
|
2015-03-04 12:58:35 +00:00
|
|
|
const uint32_t rate) const override {
|
2013-08-15 23:38:54 +00:00
|
|
|
RtpVideoCodecTypes videoType = kRtpVideoGeneric;
|
2015-03-25 16:11:24 +01:00
|
|
|
|
2014-07-08 12:10:51 +00:00
|
|
|
if (RtpUtility::StringCompare(payloadName, "VP8", 3)) {
|
2013-08-15 23:38:54 +00:00
|
|
|
videoType = kRtpVideoVp8;
|
2015-07-31 06:10:09 -07:00
|
|
|
} else if (RtpUtility::StringCompare(payloadName, "VP9", 3)) {
|
|
|
|
|
videoType = kRtpVideoVp9;
|
2014-07-08 12:10:51 +00:00
|
|
|
} else if (RtpUtility::StringCompare(payloadName, "H264", 4)) {
|
2014-07-04 12:42:07 +00:00
|
|
|
videoType = kRtpVideoH264;
|
2014-07-08 12:10:51 +00:00
|
|
|
} else if (RtpUtility::StringCompare(payloadName, "I420", 4)) {
|
2013-08-15 23:38:54 +00:00
|
|
|
videoType = kRtpVideoGeneric;
|
2015-03-25 16:11:24 +01:00
|
|
|
} else if (RtpUtility::StringCompare(payloadName, "ULPFEC", 6) ||
|
|
|
|
|
RtpUtility::StringCompare(payloadName, "RED", 3)) {
|
2013-09-06 13:40:11 +00:00
|
|
|
videoType = kRtpVideoNone;
|
2013-02-04 13:23:07 +00:00
|
|
|
} else {
|
2013-08-15 23:38:54 +00:00
|
|
|
videoType = kRtpVideoGeneric;
|
2013-02-04 13:23:07 +00:00
|
|
|
}
|
2014-07-08 12:10:51 +00:00
|
|
|
RtpUtility::Payload* payload = new RtpUtility::Payload;
|
2013-02-04 13:23:07 +00:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2013-08-15 23:38:54 +00:00
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
int GetPayloadTypeFrequency(
|
|
|
|
|
const RtpUtility::Payload& payload) const override {
|
2013-08-15 23:38:54 +00:00
|
|
|
return kVideoPayloadTypeFrequency;
|
|
|
|
|
}
|
2013-02-04 13:23:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
RTPPayloadStrategy* RTPPayloadStrategy::CreateStrategy(
|
|
|
|
|
const bool handling_audio) {
|
|
|
|
|
if (handling_audio) {
|
|
|
|
|
return new RTPPayloadAudioStrategy();
|
|
|
|
|
} else {
|
|
|
|
|
return new RTPPayloadVideoStrategy();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-17 16:10:45 +00:00
|
|
|
} // namespace webrtc
|