RTPPayloadRegistry: Use SdpAudioFormat to represent audio codecs
This is needed in the general case, now that we aim to support codecs other than those built-in to WebRTC. BUG=webrtc:8159 Change-Id: I40a41252bf69ad5d4d0208e3c1e8918da7394706 Reviewed-on: https://webrtc-review.googlesource.com/5380 Commit-Queue: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#20136}
This commit is contained in:
@ -85,6 +85,7 @@ rtc_source_set("rtp_rtcp_format") {
|
||||
"../../api:array_view",
|
||||
"../../api:libjingle_peerconnection_api",
|
||||
"../../api:optional",
|
||||
"../../api/audio_codecs:audio_codecs_api",
|
||||
"../../common_video",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../system_wrappers",
|
||||
@ -380,6 +381,7 @@ if (rtc_include_tests) {
|
||||
"../../test:rtp_test_utils",
|
||||
"../../test:test_common",
|
||||
"../../test:test_support",
|
||||
"../audio_coding:audio_format_conversion",
|
||||
"//testing/gmock",
|
||||
]
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct CodecInst;
|
||||
class VideoCodec;
|
||||
|
||||
class RTPPayloadRegistry {
|
||||
@ -35,13 +34,14 @@ class RTPPayloadRegistry {
|
||||
// Replace all audio receive payload types with the given map.
|
||||
void SetAudioReceivePayloads(std::map<int, SdpAudioFormat> codecs);
|
||||
|
||||
int32_t RegisterReceivePayload(const CodecInst& audio_codec,
|
||||
int32_t RegisterReceivePayload(int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
bool* created_new_payload_type);
|
||||
int32_t RegisterReceivePayload(const VideoCodec& video_codec);
|
||||
|
||||
int32_t DeRegisterReceivePayload(int8_t payload_type);
|
||||
|
||||
int32_t ReceivePayloadType(const CodecInst& audio_codec,
|
||||
int32_t ReceivePayloadType(const SdpAudioFormat& audio_format,
|
||||
int8_t* payload_type) const;
|
||||
int32_t ReceivePayloadType(const VideoCodec& video_codec,
|
||||
int8_t* payload_type) const;
|
||||
@ -96,7 +96,7 @@ class RTPPayloadRegistry {
|
||||
private:
|
||||
// Prunes the payload type map of the specific payload type, if it exists.
|
||||
void DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
|
||||
const CodecInst& audio_codec);
|
||||
const SdpAudioFormat& audio_format);
|
||||
|
||||
bool IsRtxInternal(const RTPHeader& header) const;
|
||||
// Returns the payload type for the payload with name |payload_name|, or -1 if
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct CodecInst;
|
||||
class RTPPayloadRegistry;
|
||||
class VideoCodec;
|
||||
|
||||
@ -61,7 +60,13 @@ class RtpReceiver {
|
||||
|
||||
// Registers a receive payload in the payload registry and notifies the media
|
||||
// receiver strategy.
|
||||
virtual int32_t RegisterReceivePayload(const CodecInst& audio_codec) = 0;
|
||||
virtual int32_t RegisterReceivePayload(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& audio_format) = 0;
|
||||
|
||||
// Deprecated version of the above.
|
||||
int32_t RegisterReceivePayload(const CodecInst& audio_codec);
|
||||
|
||||
// Registers a receive payload in the payload registry.
|
||||
virtual int32_t RegisterReceivePayload(const VideoCodec& video_codec) = 0;
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/include/module_common_types.h"
|
||||
#include "rtc_base/deprecation.h"
|
||||
@ -40,9 +41,8 @@ const int kBogusRtpRateForAudioRtcp = 8000;
|
||||
const uint8_t kRtpHeaderSize = 12;
|
||||
|
||||
struct AudioPayload {
|
||||
uint32_t frequency;
|
||||
size_t channels;
|
||||
uint32_t rate;
|
||||
SdpAudioFormat format;
|
||||
uint32_t rate;
|
||||
};
|
||||
|
||||
struct VideoPayload {
|
||||
@ -271,12 +271,9 @@ class RtpFeedback {
|
||||
/*
|
||||
* channels - number of channels in codec (1 = mono, 2 = stereo)
|
||||
*/
|
||||
virtual int32_t OnInitializeDecoder(
|
||||
int8_t payload_type,
|
||||
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
||||
int frequency,
|
||||
size_t channels,
|
||||
uint32_t rate) = 0;
|
||||
virtual int32_t OnInitializeDecoder(int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
uint32_t rate) = 0;
|
||||
|
||||
virtual void OnIncomingSSRCChanged(uint32_t ssrc) = 0;
|
||||
|
||||
@ -452,10 +449,8 @@ class NullRtpFeedback : public RtpFeedback {
|
||||
public:
|
||||
~NullRtpFeedback() override {}
|
||||
|
||||
int32_t OnInitializeDecoder(int8_t payload_type,
|
||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||
int frequency,
|
||||
size_t channels,
|
||||
int32_t OnInitializeDecoder(int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
uint32_t rate) override;
|
||||
|
||||
void OnIncomingSSRCChanged(uint32_t ssrc) override {}
|
||||
@ -463,10 +458,8 @@ class NullRtpFeedback : public RtpFeedback {
|
||||
};
|
||||
|
||||
inline int32_t NullRtpFeedback::OnInitializeDecoder(
|
||||
int8_t payload_type,
|
||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||
int frequency,
|
||||
size_t channels,
|
||||
int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
uint32_t rate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -23,14 +23,9 @@ namespace webrtc {
|
||||
namespace {
|
||||
|
||||
bool PayloadIsCompatible(const RtpUtility::Payload& payload,
|
||||
const CodecInst& audio_codec) {
|
||||
if (!payload.typeSpecific.is_audio())
|
||||
return false;
|
||||
if (_stricmp(payload.name, audio_codec.plname) != 0)
|
||||
return false;
|
||||
const AudioPayload& audio_payload = payload.typeSpecific.audio_payload();
|
||||
return audio_payload.frequency == static_cast<uint32_t>(audio_codec.plfreq) &&
|
||||
audio_payload.channels == audio_codec.channels;
|
||||
const SdpAudioFormat& audio_format) {
|
||||
return payload.typeSpecific.is_audio() &&
|
||||
audio_format.Matches(payload.typeSpecific.audio_payload().format);
|
||||
}
|
||||
|
||||
bool PayloadIsCompatible(const RtpUtility::Payload& payload,
|
||||
@ -46,12 +41,10 @@ bool PayloadIsCompatible(const RtpUtility::Payload& payload,
|
||||
return true;
|
||||
}
|
||||
|
||||
RtpUtility::Payload CreatePayloadType(const CodecInst& audio_codec) {
|
||||
RTC_DCHECK_GE(audio_codec.plfreq, 1000);
|
||||
return {audio_codec.plname,
|
||||
PayloadUnion(
|
||||
AudioPayload{rtc::dchecked_cast<uint32_t>(audio_codec.plfreq),
|
||||
audio_codec.channels, 0})};
|
||||
RtpUtility::Payload CreatePayloadType(const SdpAudioFormat& audio_format) {
|
||||
RTC_DCHECK_GE(audio_format.clockrate_hz, 1000);
|
||||
return {audio_format.name.c_str(),
|
||||
PayloadUnion(AudioPayload{audio_format, 0})};
|
||||
}
|
||||
|
||||
RtpVideoCodecTypes ConvertToRtpVideoCodecType(VideoCodecType type) {
|
||||
@ -125,10 +118,9 @@ void RTPPayloadRegistry::SetAudioReceivePayloads(
|
||||
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)));
|
||||
payload_type_map_.emplace(rtp_payload_type,
|
||||
CreatePayloadType(audio_format));
|
||||
}
|
||||
|
||||
// Clear the value of last received payload type since it might mean
|
||||
@ -137,8 +129,10 @@ void RTPPayloadRegistry::SetAudioReceivePayloads(
|
||||
last_received_media_payload_type_ = -1;
|
||||
}
|
||||
|
||||
int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec,
|
||||
bool* created_new_payload) {
|
||||
int32_t RTPPayloadRegistry::RegisterReceivePayload(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
bool* created_new_payload) {
|
||||
rtc::CritScope cs(&crit_sect_);
|
||||
|
||||
#if RTC_DCHECK_IS_ON
|
||||
@ -147,26 +141,26 @@ int32_t RTPPayloadRegistry::RegisterReceivePayload(const CodecInst& audio_codec,
|
||||
#endif
|
||||
|
||||
*created_new_payload = false;
|
||||
if (!IsPayloadTypeValid(audio_codec.pltype))
|
||||
if (!IsPayloadTypeValid(payload_type))
|
||||
return -1;
|
||||
|
||||
auto it = payload_type_map_.find(audio_codec.pltype);
|
||||
const auto it = payload_type_map_.find(payload_type);
|
||||
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)) {
|
||||
if (PayloadIsCompatible(it->second, audio_format)) {
|
||||
it->second.typeSpecific.audio_payload().rate = 0;
|
||||
return 0;
|
||||
}
|
||||
LOG(LS_ERROR) << "Payload type already registered: " << audio_codec.pltype;
|
||||
LOG(LS_ERROR) << "Payload type already registered: " << payload_type;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Audio codecs must be unique.
|
||||
DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(audio_codec);
|
||||
DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(audio_format);
|
||||
|
||||
const auto insert_status = payload_type_map_.emplace(
|
||||
audio_codec.pltype, CreatePayloadType(audio_codec));
|
||||
const auto insert_status =
|
||||
payload_type_map_.emplace(payload_type, CreatePayloadType(audio_format));
|
||||
RTC_DCHECK(insert_status.second); // Insertion succeeded.
|
||||
*created_new_payload = true;
|
||||
|
||||
@ -222,10 +216,10 @@ int32_t RTPPayloadRegistry::DeRegisterReceivePayload(
|
||||
// for audio codecs, but there can for video.
|
||||
// Always called from within a critical section.
|
||||
void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
|
||||
const CodecInst& audio_codec) {
|
||||
const SdpAudioFormat& audio_format) {
|
||||
for (auto iterator = payload_type_map_.begin();
|
||||
iterator != payload_type_map_.end(); ++iterator) {
|
||||
if (PayloadIsCompatible(iterator->second, audio_codec)) {
|
||||
if (PayloadIsCompatible(iterator->second, audio_format)) {
|
||||
// Remove old setting.
|
||||
payload_type_map_.erase(iterator);
|
||||
break;
|
||||
@ -233,13 +227,14 @@ void RTPPayloadRegistry::DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
|
||||
}
|
||||
}
|
||||
|
||||
int32_t RTPPayloadRegistry::ReceivePayloadType(const CodecInst& audio_codec,
|
||||
int8_t* payload_type) const {
|
||||
int32_t RTPPayloadRegistry::ReceivePayloadType(
|
||||
const SdpAudioFormat& audio_format,
|
||||
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)) {
|
||||
if (PayloadIsCompatible(it.second, audio_format)) {
|
||||
*payload_type = it.first;
|
||||
return 0;
|
||||
}
|
||||
@ -308,7 +303,7 @@ int RTPPayloadRegistry::GetPayloadTypeFrequency(
|
||||
}
|
||||
rtc::CritScope cs(&crit_sect_);
|
||||
return payload->typeSpecific.is_audio()
|
||||
? payload->typeSpecific.audio_payload().frequency
|
||||
? payload->typeSpecific.audio_payload().format.clockrate_hz
|
||||
: kVideoPayloadTypeFrequency;
|
||||
}
|
||||
|
||||
|
||||
@ -24,13 +24,6 @@ using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
using ::testing::_;
|
||||
|
||||
static const char* kTypicalPayloadName = "name";
|
||||
static const size_t kTypicalChannels = 1;
|
||||
static const uint32_t kTypicalFrequency = 44000;
|
||||
static const CodecInst kTypicalAudioCodec = {-1 /* pltype */, "name",
|
||||
kTypicalFrequency, 0 /* pacsize */,
|
||||
kTypicalChannels};
|
||||
|
||||
TEST(RtpPayloadRegistryTest,
|
||||
RegistersAndRemembersVideoPayloadsUntilDeregistered) {
|
||||
RTPPayloadRegistry rtp_payload_registry;
|
||||
@ -60,12 +53,11 @@ TEST(RtpPayloadRegistryTest,
|
||||
TEST(RtpPayloadRegistryTest,
|
||||
RegistersAndRemembersAudioPayloadsUntilDeregistered) {
|
||||
RTPPayloadRegistry rtp_payload_registry;
|
||||
uint8_t payload_type = 97;
|
||||
constexpr int payload_type = 97;
|
||||
const SdpAudioFormat audio_format("name", 44000, 1);
|
||||
bool new_payload_created = false;
|
||||
CodecInst audio_codec = kTypicalAudioCodec;
|
||||
audio_codec.pltype = payload_type;
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
audio_codec, &new_payload_created));
|
||||
payload_type, audio_format, &new_payload_created));
|
||||
|
||||
EXPECT_TRUE(new_payload_created) << "A new payload WAS created.";
|
||||
|
||||
@ -74,12 +66,10 @@ TEST(RtpPayloadRegistryTest,
|
||||
EXPECT_TRUE(retrieved_payload);
|
||||
|
||||
// We should get back the corresponding payload that we registered.
|
||||
EXPECT_STREQ(kTypicalPayloadName, retrieved_payload->name);
|
||||
EXPECT_STREQ("name", retrieved_payload->name);
|
||||
EXPECT_TRUE(retrieved_payload->typeSpecific.is_audio());
|
||||
EXPECT_EQ(kTypicalFrequency,
|
||||
retrieved_payload->typeSpecific.audio_payload().frequency);
|
||||
EXPECT_EQ(kTypicalChannels,
|
||||
retrieved_payload->typeSpecific.audio_payload().channels);
|
||||
EXPECT_EQ(audio_format,
|
||||
retrieved_payload->typeSpecific.audio_payload().format);
|
||||
|
||||
// Now forget about it and verify it's gone.
|
||||
EXPECT_EQ(0, rtp_payload_registry.DeRegisterReceivePayload(payload_type));
|
||||
@ -87,103 +77,77 @@ TEST(RtpPayloadRegistryTest,
|
||||
}
|
||||
|
||||
TEST(RtpPayloadRegistryTest, AudioRedWorkProperly) {
|
||||
const uint8_t kRedPayloadType = 127;
|
||||
const int kRedSampleRate = 8000;
|
||||
const size_t kRedChannels = 1;
|
||||
|
||||
RTPPayloadRegistry rtp_payload_registry;
|
||||
|
||||
bool new_payload_created = false;
|
||||
CodecInst red_audio_codec;
|
||||
strncpy(red_audio_codec.plname, "red", RTP_PAYLOAD_NAME_SIZE);
|
||||
red_audio_codec.pltype = kRedPayloadType;
|
||||
red_audio_codec.plfreq = kRedSampleRate;
|
||||
red_audio_codec.channels = kRedChannels;
|
||||
const SdpAudioFormat red_format("red", 8000, 1);
|
||||
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
red_audio_codec, &new_payload_created));
|
||||
127, red_format, &new_payload_created));
|
||||
EXPECT_TRUE(new_payload_created);
|
||||
|
||||
EXPECT_EQ(kRedPayloadType, rtp_payload_registry.red_payload_type());
|
||||
EXPECT_EQ(127, rtp_payload_registry.red_payload_type());
|
||||
|
||||
const auto retrieved_payload =
|
||||
rtp_payload_registry.PayloadTypeToPayload(kRedPayloadType);
|
||||
const auto retrieved_payload = rtp_payload_registry.PayloadTypeToPayload(127);
|
||||
EXPECT_TRUE(retrieved_payload);
|
||||
EXPECT_TRUE(retrieved_payload->typeSpecific.is_audio());
|
||||
EXPECT_STRCASEEQ("red", retrieved_payload->name);
|
||||
|
||||
// Sample rate is correctly registered.
|
||||
EXPECT_EQ(kRedSampleRate,
|
||||
rtp_payload_registry.GetPayloadTypeFrequency(kRedPayloadType));
|
||||
EXPECT_EQ(red_format, retrieved_payload->typeSpecific.audio_payload().format);
|
||||
}
|
||||
|
||||
TEST(RtpPayloadRegistryTest,
|
||||
DoesNotAcceptSamePayloadTypeTwiceExceptIfPayloadIsCompatible) {
|
||||
uint8_t payload_type = 97;
|
||||
constexpr int payload_type = 97;
|
||||
RTPPayloadRegistry rtp_payload_registry;
|
||||
|
||||
bool ignored = false;
|
||||
CodecInst audio_codec = kTypicalAudioCodec;
|
||||
audio_codec.pltype = payload_type;
|
||||
EXPECT_EQ(0,
|
||||
rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored));
|
||||
const SdpAudioFormat audio_format("name", 44000, 1);
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type, audio_format, &ignored));
|
||||
|
||||
CodecInst audio_codec_2 = kTypicalAudioCodec;
|
||||
audio_codec_2.pltype = payload_type;
|
||||
// Make |audio_codec_2| incompatible with |audio_codec| by changing
|
||||
// the frequency.
|
||||
audio_codec_2.plfreq = kTypicalFrequency + 1;
|
||||
EXPECT_EQ(
|
||||
-1, rtp_payload_registry.RegisterReceivePayload(audio_codec_2, &ignored))
|
||||
const SdpAudioFormat audio_format_2("name", 44001, 1); // Not compatible.
|
||||
EXPECT_EQ(-1, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type, audio_format_2, &ignored))
|
||||
<< "Adding incompatible codec with same payload type = bad.";
|
||||
|
||||
// Change payload type.
|
||||
audio_codec_2.pltype = payload_type - 1;
|
||||
EXPECT_EQ(
|
||||
0, rtp_payload_registry.RegisterReceivePayload(audio_codec_2, &ignored))
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type - 1, audio_format_2, &ignored))
|
||||
<< "With a different payload type is fine though.";
|
||||
|
||||
// Ensure both payloads are preserved.
|
||||
const auto retrieved_payload1 =
|
||||
rtp_payload_registry.PayloadTypeToPayload(payload_type);
|
||||
EXPECT_TRUE(retrieved_payload1);
|
||||
EXPECT_STREQ(kTypicalPayloadName, retrieved_payload1->name);
|
||||
EXPECT_STREQ("name", retrieved_payload1->name);
|
||||
EXPECT_TRUE(retrieved_payload1->typeSpecific.is_audio());
|
||||
EXPECT_EQ(kTypicalFrequency,
|
||||
retrieved_payload1->typeSpecific.audio_payload().frequency);
|
||||
EXPECT_EQ(kTypicalChannels,
|
||||
retrieved_payload1->typeSpecific.audio_payload().channels);
|
||||
EXPECT_EQ(audio_format,
|
||||
retrieved_payload1->typeSpecific.audio_payload().format);
|
||||
|
||||
const auto retrieved_payload2 =
|
||||
rtp_payload_registry.PayloadTypeToPayload(payload_type - 1);
|
||||
EXPECT_TRUE(retrieved_payload2);
|
||||
EXPECT_STREQ(kTypicalPayloadName, retrieved_payload2->name);
|
||||
EXPECT_STREQ("name", retrieved_payload2->name);
|
||||
EXPECT_TRUE(retrieved_payload2->typeSpecific.is_audio());
|
||||
EXPECT_EQ(kTypicalFrequency + 1,
|
||||
retrieved_payload2->typeSpecific.audio_payload().frequency);
|
||||
EXPECT_EQ(kTypicalChannels,
|
||||
retrieved_payload2->typeSpecific.audio_payload().channels);
|
||||
EXPECT_EQ(audio_format_2,
|
||||
retrieved_payload2->typeSpecific.audio_payload().format);
|
||||
|
||||
// Ok, update the rate for one of the codecs. If either the incoming rate or
|
||||
// the stored rate is zero it's not really an error to register the same
|
||||
// codec twice, and in that case roughly the following happens.
|
||||
EXPECT_EQ(0,
|
||||
rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored));
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type, audio_format, &ignored));
|
||||
}
|
||||
|
||||
TEST(RtpPayloadRegistryTest,
|
||||
RemovesCompatibleCodecsOnRegistryIfCodecsMustBeUnique) {
|
||||
uint8_t payload_type = 97;
|
||||
constexpr int payload_type = 97;
|
||||
RTPPayloadRegistry rtp_payload_registry;
|
||||
|
||||
bool ignored = false;
|
||||
CodecInst audio_codec = kTypicalAudioCodec;
|
||||
audio_codec.pltype = payload_type;
|
||||
EXPECT_EQ(0,
|
||||
rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored));
|
||||
CodecInst audio_codec_2 = kTypicalAudioCodec;
|
||||
audio_codec_2.pltype = payload_type - 1;
|
||||
EXPECT_EQ(
|
||||
0, rtp_payload_registry.RegisterReceivePayload(audio_codec_2, &ignored));
|
||||
const SdpAudioFormat audio_format("name", 44000, 1);
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type, audio_format, &ignored));
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type - 1, audio_format, &ignored));
|
||||
|
||||
EXPECT_FALSE(rtp_payload_registry.PayloadTypeToPayload(payload_type))
|
||||
<< "The first payload should be "
|
||||
@ -191,13 +155,11 @@ TEST(RtpPayloadRegistryTest,
|
||||
EXPECT_TRUE(rtp_payload_registry.PayloadTypeToPayload(payload_type - 1))
|
||||
<< "The second payload should still be registered though.";
|
||||
|
||||
// Now ensure non-compatible codecs aren't removed. Make |audio_codec_3|
|
||||
// Now ensure non-compatible codecs aren't removed. Make |audio_format_2|
|
||||
// incompatible by changing the frequency.
|
||||
CodecInst audio_codec_3 = kTypicalAudioCodec;
|
||||
audio_codec_3.pltype = payload_type + 1;
|
||||
audio_codec_3.plfreq = kTypicalFrequency + 1;
|
||||
EXPECT_EQ(
|
||||
0, rtp_payload_registry.RegisterReceivePayload(audio_codec_3, &ignored));
|
||||
const SdpAudioFormat audio_format_2("name", 44001, 1);
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type + 1, audio_format_2, &ignored));
|
||||
|
||||
EXPECT_TRUE(rtp_payload_registry.PayloadTypeToPayload(payload_type - 1))
|
||||
<< "Not compatible; both payloads should be kept.";
|
||||
@ -217,10 +179,10 @@ TEST(RtpPayloadRegistryTest,
|
||||
EXPECT_TRUE(media_type_unchanged);
|
||||
|
||||
bool ignored;
|
||||
CodecInst audio_codec = kTypicalAudioCodec;
|
||||
audio_codec.pltype = 34;
|
||||
EXPECT_EQ(0,
|
||||
rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored));
|
||||
constexpr int payload_type = 34;
|
||||
const SdpAudioFormat audio_format("name", 44000, 1);
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type, audio_format, &ignored));
|
||||
|
||||
EXPECT_EQ(-1, rtp_payload_registry.last_received_payload_type());
|
||||
media_type_unchanged = rtp_payload_registry.ReportMediaPayloadType(18);
|
||||
@ -235,13 +197,10 @@ TEST_P(ParameterizedRtpPayloadRegistryTest,
|
||||
RTPPayloadRegistry rtp_payload_registry;
|
||||
|
||||
bool ignored;
|
||||
CodecInst audio_codec;
|
||||
strncpy(audio_codec.plname, "whatever", RTP_PAYLOAD_NAME_SIZE);
|
||||
audio_codec.pltype = GetParam();
|
||||
audio_codec.plfreq = 1900;
|
||||
audio_codec.channels = 1;
|
||||
EXPECT_EQ(-1,
|
||||
rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored));
|
||||
const int payload_type = GetParam();
|
||||
const SdpAudioFormat audio_format("whatever", 1900, 1);
|
||||
EXPECT_EQ(-1, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type, audio_format, &ignored));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(TestKnownBadPayloadTypes,
|
||||
@ -254,14 +213,10 @@ TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) {
|
||||
RTPPayloadRegistry rtp_payload_registry;
|
||||
|
||||
bool ignored;
|
||||
CodecInst audio_codec;
|
||||
// Dummy values, except for payload_type.
|
||||
strncpy(audio_codec.plname, "generic-codec", RTP_PAYLOAD_NAME_SIZE);
|
||||
audio_codec.pltype = GetParam();
|
||||
audio_codec.plfreq = 1900;
|
||||
audio_codec.channels = 1;
|
||||
EXPECT_EQ(0,
|
||||
rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored));
|
||||
const int payload_type = GetParam();
|
||||
const SdpAudioFormat audio_format("generic-codec", 1900, 1); // Dummy values.
|
||||
EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
|
||||
payload_type, audio_format, &ignored));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(TestDynamicRange,
|
||||
|
||||
@ -35,7 +35,6 @@ RTPReceiverAudio::RTPReceiverAudio(RtpData* data_callback)
|
||||
cng_fb_payload_type_(-1),
|
||||
num_energy_(0),
|
||||
current_remote_energy_() {
|
||||
last_payload_.emplace(AudioPayload{0, 1, 0});
|
||||
memset(current_remote_energy_, 0, sizeof(current_remote_energy_));
|
||||
}
|
||||
|
||||
@ -104,22 +103,24 @@ bool RTPReceiverAudio::ShouldReportCsrcChanges(uint8_t payload_type) const {
|
||||
// -
|
||||
// - G7221 frame N/A
|
||||
int32_t RTPReceiverAudio::OnNewPayloadTypeCreated(
|
||||
const CodecInst& audio_codec) {
|
||||
int payload_type,
|
||||
const SdpAudioFormat& audio_format) {
|
||||
rtc::CritScope lock(&crit_sect_);
|
||||
|
||||
if (RtpUtility::StringCompare(audio_codec.plname, "telephone-event", 15)) {
|
||||
telephone_event_payload_type_ = audio_codec.pltype;
|
||||
if (RtpUtility::StringCompare(audio_format.name.c_str(), "telephone-event",
|
||||
15)) {
|
||||
telephone_event_payload_type_ = payload_type;
|
||||
}
|
||||
if (RtpUtility::StringCompare(audio_codec.plname, "cn", 2)) {
|
||||
if (RtpUtility::StringCompare(audio_format.name.c_str(), "cn", 2)) {
|
||||
// We support comfort noise at four different frequencies.
|
||||
if (audio_codec.plfreq == 8000) {
|
||||
cng_nb_payload_type_ = audio_codec.pltype;
|
||||
} else if (audio_codec.plfreq == 16000) {
|
||||
cng_wb_payload_type_ = audio_codec.pltype;
|
||||
} else if (audio_codec.plfreq == 32000) {
|
||||
cng_swb_payload_type_ = audio_codec.pltype;
|
||||
} else if (audio_codec.plfreq == 48000) {
|
||||
cng_fb_payload_type_ = audio_codec.pltype;
|
||||
if (audio_format.clockrate_hz == 8000) {
|
||||
cng_nb_payload_type_ = payload_type;
|
||||
} else if (audio_format.clockrate_hz == 16000) {
|
||||
cng_wb_payload_type_ = payload_type;
|
||||
} else if (audio_format.clockrate_hz == 32000) {
|
||||
cng_swb_payload_type_ = payload_type;
|
||||
} else if (audio_format.clockrate_hz == 48000) {
|
||||
cng_fb_payload_type_ = payload_type;
|
||||
} else {
|
||||
assert(false);
|
||||
return -1;
|
||||
@ -191,8 +192,7 @@ int32_t RTPReceiverAudio::InvokeOnInitializeDecoder(
|
||||
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
||||
const PayloadUnion& specific_payload) const {
|
||||
const auto& ap = specific_payload.audio_payload();
|
||||
if (callback->OnInitializeDecoder(payload_type, payload_name, ap.frequency,
|
||||
ap.channels, ap.rate) == -1) {
|
||||
if (callback->OnInitializeDecoder(payload_type, ap.format, ap.rate) == -1) {
|
||||
LOG(LS_ERROR) << "Failed to create decoder for payload type: "
|
||||
<< payload_name << "/" << static_cast<int>(payload_type);
|
||||
return -1;
|
||||
@ -301,7 +301,7 @@ int32_t RTPReceiverAudio::ParseAudioCodecSpecific(
|
||||
payload_data + 1, payload_data_length - 1, rtp_header);
|
||||
}
|
||||
|
||||
rtp_header->type.Audio.channel = audio_specific.channels;
|
||||
rtp_header->type.Audio.channel = audio_specific.format.num_channels;
|
||||
return data_callback_->OnReceivedPayloadData(payload_data,
|
||||
payload_data_length, rtp_header);
|
||||
}
|
||||
|
||||
@ -55,7 +55,8 @@ class RTPReceiverAudio : public RTPReceiverStrategy,
|
||||
|
||||
bool ShouldReportCsrcChanges(uint8_t payload_type) const override;
|
||||
|
||||
int32_t OnNewPayloadTypeCreated(const CodecInst& audio_codec) override;
|
||||
int32_t OnNewPayloadTypeCreated(int payload_type,
|
||||
const SdpAudioFormat& audio_format) override;
|
||||
|
||||
int32_t InvokeOnInitializeDecoder(
|
||||
RtpFeedback* callback,
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/audio_coding/codecs/audio_format_conversion.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_payload_registry.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_receiver_strategy.h"
|
||||
@ -57,6 +58,11 @@ RtpReceiver* RtpReceiver::CreateAudioReceiver(
|
||||
RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback));
|
||||
}
|
||||
|
||||
int32_t RtpReceiver::RegisterReceivePayload(const CodecInst& audio_codec) {
|
||||
return RegisterReceivePayload(audio_codec.pltype,
|
||||
CodecInstToSdp(audio_codec));
|
||||
}
|
||||
|
||||
RtpReceiverImpl::RtpReceiverImpl(Clock* clock,
|
||||
RtpFeedback* incoming_messages_callback,
|
||||
RTPPayloadRegistry* rtp_payload_registry,
|
||||
@ -81,7 +87,9 @@ RtpReceiverImpl::~RtpReceiverImpl() {
|
||||
}
|
||||
}
|
||||
|
||||
int32_t RtpReceiverImpl::RegisterReceivePayload(const CodecInst& audio_codec) {
|
||||
int32_t RtpReceiverImpl::RegisterReceivePayload(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& audio_format) {
|
||||
rtc::CritScope lock(&critical_section_rtp_receiver_);
|
||||
|
||||
// TODO(phoglund): Try to streamline handling of the RED codec and some other
|
||||
@ -89,11 +97,12 @@ int32_t RtpReceiverImpl::RegisterReceivePayload(const CodecInst& audio_codec) {
|
||||
// payload or not.
|
||||
bool created_new_payload = false;
|
||||
int32_t result = rtp_payload_registry_->RegisterReceivePayload(
|
||||
audio_codec, &created_new_payload);
|
||||
payload_type, audio_format, &created_new_payload);
|
||||
if (created_new_payload) {
|
||||
if (rtp_media_receiver_->OnNewPayloadTypeCreated(audio_codec) != 0) {
|
||||
LOG(LS_ERROR) << "Failed to register payload: " << audio_codec.plname
|
||||
<< "/" << static_cast<int>(audio_codec.pltype);
|
||||
if (rtp_media_receiver_->OnNewPayloadTypeCreated(payload_type,
|
||||
audio_format) != 0) {
|
||||
LOG(LS_ERROR) << "Failed to register payload: " << audio_format.name
|
||||
<< "/" << payload_type;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -240,10 +249,7 @@ bool RtpReceiverImpl::GetLatestTimestamps(uint32_t* timestamp,
|
||||
// Implementation note: must not hold critsect when called.
|
||||
void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
|
||||
bool new_ssrc = false;
|
||||
bool re_initialize_decoder = false;
|
||||
char payload_name[RTP_PAYLOAD_NAME_SIZE];
|
||||
size_t channels = 1;
|
||||
uint32_t rate = 0;
|
||||
rtc::Optional<AudioPayload> reinitialize_audio_payload;
|
||||
|
||||
{
|
||||
rtc::CritScope lock(&critical_section_rtp_receiver_);
|
||||
@ -262,18 +268,16 @@ void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
|
||||
if (ssrc_ != 0) {
|
||||
// Do we have the same codec? Then re-initialize coder.
|
||||
if (rtp_header.payloadType == last_received_payload_type) {
|
||||
re_initialize_decoder = true;
|
||||
|
||||
const auto payload = rtp_payload_registry_->PayloadTypeToPayload(
|
||||
rtp_header.payloadType);
|
||||
if (!payload) {
|
||||
return;
|
||||
}
|
||||
payload_name[RTP_PAYLOAD_NAME_SIZE - 1] = 0;
|
||||
strncpy(payload_name, payload->name, RTP_PAYLOAD_NAME_SIZE - 1);
|
||||
if (payload->typeSpecific.is_audio()) {
|
||||
channels = payload->typeSpecific.audio_payload().channels;
|
||||
rate = payload->typeSpecific.audio_payload().rate;
|
||||
reinitialize_audio_payload.emplace(
|
||||
payload->typeSpecific.audio_payload());
|
||||
} else {
|
||||
// OnInitializeDecoder() is only used for audio.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -287,11 +291,10 @@ void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader& rtp_header) {
|
||||
cb_rtp_feedback_->OnIncomingSSRCChanged(rtp_header.ssrc);
|
||||
}
|
||||
|
||||
if (re_initialize_decoder) {
|
||||
if (-1 ==
|
||||
cb_rtp_feedback_->OnInitializeDecoder(
|
||||
rtp_header.payloadType, payload_name,
|
||||
rtp_header.payload_type_frequency, channels, rate)) {
|
||||
if (reinitialize_audio_payload) {
|
||||
if (-1 == cb_rtp_feedback_->OnInitializeDecoder(
|
||||
rtp_header.payloadType, reinitialize_audio_payload->format,
|
||||
reinitialize_audio_payload->rate)) {
|
||||
// New stream, same codec.
|
||||
LOG(LS_ERROR) << "Failed to create decoder for payload type: "
|
||||
<< static_cast<int>(rtp_header.payloadType);
|
||||
|
||||
@ -36,7 +36,8 @@ class RtpReceiverImpl : public RtpReceiver {
|
||||
|
||||
virtual ~RtpReceiverImpl();
|
||||
|
||||
int32_t RegisterReceivePayload(const CodecInst& audio_codec) override;
|
||||
int32_t RegisterReceivePayload(int payload_type,
|
||||
const SdpAudioFormat& audio_format) override;
|
||||
int32_t RegisterReceivePayload(const VideoCodec& video_codec) override;
|
||||
|
||||
int32_t DeRegisterReceivePayload(const int8_t payload_type) override;
|
||||
|
||||
@ -56,7 +56,9 @@ class RTPReceiverStrategy {
|
||||
|
||||
// Notifies the strategy that we have created a new non-RED audio payload type
|
||||
// in the payload registry.
|
||||
virtual int32_t OnNewPayloadTypeCreated(const CodecInst& audio_codec) = 0;
|
||||
virtual int32_t OnNewPayloadTypeCreated(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& audio_format) = 0;
|
||||
|
||||
// Invokes the OnInitializeDecoder callback in a media-specific way.
|
||||
virtual int32_t InvokeOnInitializeDecoder(
|
||||
|
||||
@ -51,12 +51,8 @@ class RtpReceiverTest : public ::testing::Test {
|
||||
&mock_rtp_data_,
|
||||
nullptr,
|
||||
&rtp_payload_registry_)) {
|
||||
CodecInst voice_codec = {};
|
||||
voice_codec.pltype = kPcmuPayloadType;
|
||||
voice_codec.plfreq = 8000;
|
||||
voice_codec.rate = kTestRate;
|
||||
memcpy(voice_codec.plname, "PCMU", 5);
|
||||
rtp_receiver_->RegisterReceivePayload(voice_codec);
|
||||
rtp_receiver_->RegisterReceivePayload(kPcmuPayloadType,
|
||||
SdpAudioFormat("PCMU", 8000, 1));
|
||||
}
|
||||
~RtpReceiverTest() {}
|
||||
|
||||
@ -90,7 +86,8 @@ TEST_F(RtpReceiverTest, GetSources) {
|
||||
header.numCSRCs = 2;
|
||||
header.arrOfCSRCs[0] = kCsrc1;
|
||||
header.arrOfCSRCs[1] = kCsrc2;
|
||||
const PayloadUnion payload_specific{AudioPayload()};
|
||||
const PayloadUnion payload_specific{
|
||||
AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
|
||||
|
||||
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
|
||||
header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder));
|
||||
@ -140,7 +137,8 @@ TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) {
|
||||
header.payloadType = kPcmuPayloadType;
|
||||
header.ssrc = kSsrc1;
|
||||
header.timestamp = rtp_timestamp(now_ms);
|
||||
const PayloadUnion payload_specific{AudioPayload()};
|
||||
const PayloadUnion payload_specific{
|
||||
AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
|
||||
|
||||
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
|
||||
header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder));
|
||||
@ -191,7 +189,8 @@ TEST_F(RtpReceiverTest, GetSourcesRemoveOutdatedSource) {
|
||||
RTPHeader header;
|
||||
header.payloadType = kPcmuPayloadType;
|
||||
header.timestamp = rtp_timestamp(now_ms);
|
||||
const PayloadUnion payload_specific{AudioPayload()};
|
||||
const PayloadUnion payload_specific{
|
||||
AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
|
||||
header.numCSRCs = 1;
|
||||
size_t kSourceListSize = 20;
|
||||
|
||||
@ -265,7 +264,8 @@ TEST_F(RtpReceiverTest, GetSourcesContainsAudioLevelExtension) {
|
||||
header.timestamp = rtp_timestamp(time1_ms);
|
||||
header.extension.hasAudioLevel = true;
|
||||
header.extension.audioLevel = 10;
|
||||
const PayloadUnion payload_specific{AudioPayload()};
|
||||
const PayloadUnion payload_specific{
|
||||
AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
|
||||
|
||||
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
|
||||
header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder));
|
||||
@ -317,7 +317,8 @@ TEST_F(RtpReceiverTest,
|
||||
header.timestamp = rtp_timestamp(time1_ms);
|
||||
header.extension.hasAudioLevel = true;
|
||||
header.extension.audioLevel = 10;
|
||||
const PayloadUnion payload_specific{AudioPayload()};
|
||||
const PayloadUnion payload_specific{
|
||||
AudioPayload{SdpAudioFormat("foo", 8000, 1), 0}};
|
||||
|
||||
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
|
||||
header, kTestPayload, sizeof(kTestPayload), payload_specific, !kInOrder));
|
||||
|
||||
@ -44,7 +44,8 @@ bool RTPReceiverVideo::ShouldReportCsrcChanges(uint8_t payload_type) const {
|
||||
}
|
||||
|
||||
int32_t RTPReceiverVideo::OnNewPayloadTypeCreated(
|
||||
const CodecInst& audio_codec) {
|
||||
int payload_type,
|
||||
const SdpAudioFormat& audio_format) {
|
||||
RTC_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -38,7 +38,8 @@ class RTPReceiverVideo : public RTPReceiverStrategy {
|
||||
|
||||
bool ShouldReportCsrcChanges(uint8_t payload_type) const override;
|
||||
|
||||
int32_t OnNewPayloadTypeCreated(const CodecInst& audio_codec) override;
|
||||
int32_t OnNewPayloadTypeCreated(int payload_type,
|
||||
const SdpAudioFormat& audio_format) override;
|
||||
|
||||
int32_t InvokeOnInitializeDecoder(
|
||||
RtpFeedback* callback,
|
||||
|
||||
@ -241,7 +241,7 @@ int32_t RTPSender::RegisterPayload(
|
||||
payload->name, payload_name, RTP_PAYLOAD_NAME_SIZE - 1)) {
|
||||
if (audio_configured_ && payload->typeSpecific.is_audio()) {
|
||||
auto& p = payload->typeSpecific.audio_payload();
|
||||
if (p.frequency == frequency &&
|
||||
if (rtc::SafeEq(p.format.clockrate_hz, frequency) &&
|
||||
(p.rate == rate || p.rate == 0 || rate == 0)) {
|
||||
p.rate = rate;
|
||||
// Ensure that we update the rate if new or old is zero.
|
||||
|
||||
@ -66,7 +66,9 @@ int32_t RTPSenderAudio::RegisterAudioPayload(
|
||||
return 0;
|
||||
}
|
||||
*payload = new RtpUtility::Payload(
|
||||
payloadName, PayloadUnion(AudioPayload{frequency, channels, rate}));
|
||||
payloadName,
|
||||
PayloadUnion(AudioPayload{
|
||||
SdpAudioFormat(payloadName, frequency, channels), rate}));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/audio_coding/codecs/audio_format_conversion.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/rtp_receiver_audio.h"
|
||||
@ -70,10 +71,8 @@ class VerifyingAudioReceiver : public RtpData {
|
||||
|
||||
class RTPCallback : public NullRtpFeedback {
|
||||
public:
|
||||
int32_t OnInitializeDecoder(int8_t payloadType,
|
||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||
int frequency,
|
||||
size_t channels,
|
||||
int32_t OnInitializeDecoder(int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
uint32_t rate) override {
|
||||
EXPECT_EQ(0u, rate) << "The rate should be zero";
|
||||
return 0;
|
||||
@ -129,9 +128,11 @@ class RtpRtcpAudioTest : public ::testing::Test {
|
||||
|
||||
void RegisterPayload(const CodecInst& codec) {
|
||||
EXPECT_EQ(0, module1->RegisterSendPayload(codec));
|
||||
EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(codec));
|
||||
EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(codec.pltype,
|
||||
CodecInstToSdp(codec)));
|
||||
EXPECT_EQ(0, module2->RegisterSendPayload(codec));
|
||||
EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(codec));
|
||||
EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(codec.pltype,
|
||||
CodecInstToSdp(codec)));
|
||||
}
|
||||
|
||||
VerifyingAudioReceiver data_receiver1;
|
||||
@ -210,7 +211,8 @@ TEST_F(RtpRtcpAudioTest, DTMF) {
|
||||
memcpy(voice_codec.plname, "telephone-event", 16);
|
||||
|
||||
EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
|
||||
EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(voice_codec));
|
||||
EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
|
||||
voice_codec.pltype, CodecInstToSdp(voice_codec)));
|
||||
|
||||
// Start DTMF test.
|
||||
int timeStamp = 160;
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common_types.h" // NOLINT(build/include)
|
||||
#include "modules/audio_coding/codecs/audio_format_conversion.h"
|
||||
#include "modules/rtp_rtcp/include/receive_statistics.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
@ -133,9 +134,11 @@ class RtpRtcpRtcpTest : public ::testing::Test {
|
||||
memcpy(voice_codec.plname, "PCMU", 5);
|
||||
|
||||
EXPECT_EQ(0, module1->RegisterSendPayload(voice_codec));
|
||||
EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(voice_codec));
|
||||
EXPECT_EQ(0, rtp_receiver1_->RegisterReceivePayload(
|
||||
voice_codec.pltype, CodecInstToSdp(voice_codec)));
|
||||
EXPECT_EQ(0, module2->RegisterSendPayload(voice_codec));
|
||||
EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(voice_codec));
|
||||
EXPECT_EQ(0, rtp_receiver2_->RegisterReceivePayload(
|
||||
voice_codec.pltype, CodecInstToSdp(voice_codec)));
|
||||
|
||||
// We need to send one RTP packet to get the RTCP packet to be accepted by
|
||||
// the receiving module.
|
||||
|
||||
@ -287,10 +287,8 @@ void RtpVideoStreamReceiver::OnRecoveredPacket(const uint8_t* rtp_packet,
|
||||
// TODO(pbos): Remove as soon as audio can handle a changing payload type
|
||||
// without this callback.
|
||||
int32_t RtpVideoStreamReceiver::OnInitializeDecoder(
|
||||
const int8_t payload_type,
|
||||
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
||||
const int frequency,
|
||||
const size_t channels,
|
||||
const int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
const uint32_t rate) {
|
||||
RTC_NOTREACHED();
|
||||
return 0;
|
||||
|
||||
@ -112,10 +112,8 @@ class RtpVideoStreamReceiver : public RtpData,
|
||||
void OnRecoveredPacket(const uint8_t* packet, size_t packet_length) override;
|
||||
|
||||
// Implements RtpFeedback.
|
||||
int32_t OnInitializeDecoder(int8_t payload_type,
|
||||
const char payload_name[RTP_PAYLOAD_NAME_SIZE],
|
||||
int frequency,
|
||||
size_t channels,
|
||||
int32_t OnInitializeDecoder(int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
uint32_t rate) override;
|
||||
void OnIncomingSSRCChanged(uint32_t ssrc) override {}
|
||||
void OnIncomingCSRCChanged(uint32_t CSRC, bool added) override {}
|
||||
|
||||
@ -542,30 +542,12 @@ void Channel::OnIncomingCSRCChanged(uint32_t CSRC, bool added) {
|
||||
// TODO(saza): remove.
|
||||
}
|
||||
|
||||
int32_t Channel::OnInitializeDecoder(
|
||||
int8_t payloadType,
|
||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||
int frequency,
|
||||
size_t channels,
|
||||
uint32_t rate) {
|
||||
CodecInst receiveCodec = {0};
|
||||
CodecInst dummyCodec = {0};
|
||||
|
||||
receiveCodec.pltype = payloadType;
|
||||
receiveCodec.plfreq = frequency;
|
||||
receiveCodec.channels = channels;
|
||||
receiveCodec.rate = rate;
|
||||
strncpy(receiveCodec.plname, payloadName, RTP_PAYLOAD_NAME_SIZE - 1);
|
||||
|
||||
audio_coding_->Codec(payloadName, &dummyCodec, frequency, channels);
|
||||
receiveCodec.pacsize = dummyCodec.pacsize;
|
||||
|
||||
// Register the new codec to the ACM
|
||||
if (!audio_coding_->RegisterReceiveCodec(receiveCodec.pltype,
|
||||
CodecInstToSdp(receiveCodec))) {
|
||||
int32_t Channel::OnInitializeDecoder(int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
uint32_t rate) {
|
||||
if (!audio_coding_->RegisterReceiveCodec(payload_type, audio_format)) {
|
||||
LOG(LS_WARNING) << "Channel::OnInitializeDecoder() invalid codec (pt="
|
||||
<< payloadType << ", name=" << payloadName
|
||||
<< ") received - 1";
|
||||
<< payload_type << ", " << audio_format << ") received -1";
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1742,17 +1724,20 @@ void Channel::UpdatePlayoutTimestamp(bool rtcp) {
|
||||
}
|
||||
|
||||
void Channel::RegisterReceiveCodecsToRTPModule() {
|
||||
CodecInst codec;
|
||||
const uint8_t nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
|
||||
|
||||
// TODO(kwiberg): Iterate over the factory's supported codecs instead?
|
||||
const int nSupportedCodecs = AudioCodingModule::NumberOfCodecs();
|
||||
for (int idx = 0; idx < nSupportedCodecs; idx++) {
|
||||
// Open up the RTP/RTCP receiver for all supported codecs
|
||||
if ((audio_coding_->Codec(idx, &codec) == -1) ||
|
||||
(rtp_receiver_->RegisterReceivePayload(codec) == -1)) {
|
||||
LOG(LS_WARNING) << "Channel::RegisterReceiveCodecsToRTPModule() unable"
|
||||
<< " to register " << codec.plname << " (" << codec.pltype
|
||||
<< "/" << codec.plfreq << "/" << codec.channels << "/"
|
||||
<< codec.rate << ") to RTP/RTCP receiver";
|
||||
CodecInst codec;
|
||||
if (audio_coding_->Codec(idx, &codec) == -1) {
|
||||
LOG(LS_WARNING) << "Unable to register codec #" << idx
|
||||
<< " for RTP/RTCP receiver.";
|
||||
continue;
|
||||
}
|
||||
const SdpAudioFormat format = CodecInstToSdp(codec);
|
||||
if (!decoder_factory_->IsSupportedDecoder(format) ||
|
||||
rtp_receiver_->RegisterReceivePayload(codec.pltype, format) == -1) {
|
||||
LOG(LS_WARNING) << "Unable to register " << format
|
||||
<< " for RTP/RTCP receiver.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,10 +257,8 @@ class Channel
|
||||
const WebRtcRTPHeader* rtpHeader) override;
|
||||
|
||||
// From RtpFeedback in the RTP/RTCP module
|
||||
int32_t OnInitializeDecoder(int8_t payloadType,
|
||||
const char payloadName[RTP_PAYLOAD_NAME_SIZE],
|
||||
int frequency,
|
||||
size_t channels,
|
||||
int32_t OnInitializeDecoder(int payload_type,
|
||||
const SdpAudioFormat& audio_format,
|
||||
uint32_t rate) override;
|
||||
void OnIncomingSSRCChanged(uint32_t ssrc) override;
|
||||
void OnIncomingCSRCChanged(uint32_t CSRC, bool added) override;
|
||||
|
||||
Reference in New Issue
Block a user