2019-02-01 14:13:29 +01:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "modules/rtp_rtcp/source/rtp_sender_audio.h"
|
2019-07-05 19:08:33 +02:00
|
|
|
|
2019-10-28 15:51:36 +01:00
|
|
|
#include <memory>
|
2019-02-01 14:13:29 +01:00
|
|
|
#include <vector>
|
|
|
|
|
|
2024-08-29 18:28:07 +02:00
|
|
|
#include "api/environment/environment.h"
|
|
|
|
|
#include "api/environment/environment_factory.h"
|
2019-02-01 14:13:29 +01:00
|
|
|
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
|
|
|
|
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
|
|
|
|
|
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
2020-06-03 08:54:39 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
|
2022-05-20 09:12:57 +02:00
|
|
|
#include "rtc_base/thread.h"
|
2019-02-01 14:13:29 +01:00
|
|
|
#include "test/gmock.h"
|
|
|
|
|
#include "test/gtest.h"
|
|
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
|
|
|
|
namespace {
|
Reland "Delete test/constants.h"
This reverts commit 4f36b7a478c2763463c7a9ea970548ec68bc3ea6.
Reason for revert: Failing tests fixed.
Original change's description:
> Revert "Delete test/constants.h"
>
> This reverts commit 389b1672a32f2dd49af6c6ed40e8ddf394b986de.
>
> Reason for revert: Causes failure (and empty result list) in CallPerfTest.PadsToMinTransmitBitrate
>
> Original change's description:
> > Delete test/constants.h
> >
> > It's not possible to use constants.h for all RTP extensions
> > after the number of extensions exceeds 14, which is the maximum
> > number of one-byte RTP extensions. This is because some extensions
> > would have to be assigned a number greater than 14, even if the
> > test only involves 14 extensions or less.
> >
> > For uniformity's sake, this CL also edits some files to use an
> > enum as the files involved in this CL, rather than free-floating
> > const-ints.
> >
> > Bug: webrtc:10288
> > Change-Id: Ib5e58ad72c4d3756f4c4f6521f140ec59617f3f5
> > Reviewed-on: https://webrtc-review.googlesource.com/c/123048
> > Commit-Queue: Elad Alon <eladalon@webrtc.org>
> > Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
> > Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#26728}
>
> TBR=danilchap@webrtc.org,kwiberg@webrtc.org,eladalon@webrtc.org,sprang@webrtc.org
>
> Bug: webrtc:10288, chromium:933127
> Change-Id: If1de0bd8992137c52bf0b877b3cb0a2bafc809d4
> Reviewed-on: https://webrtc-review.googlesource.com/c/123381
> Commit-Queue: Oleh Prypin <oprypin@webrtc.org>
> Reviewed-by: Oleh Prypin <oprypin@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26744}
TBR=danilchap@webrtc.org,oprypin@webrtc.org,kwiberg@webrtc.org,eladalon@webrtc.org,sprang@webrtc.org
Change-Id: I65e391325d3a6df6db3c0739185e2002e70fb954
Bug: webrtc:10288, chromium:933127
Reviewed-on: https://webrtc-review.googlesource.com/c/123384
Reviewed-by: Elad Alon <eladalon@webrtc.org>
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26750}
2019-02-18 23:45:57 +01:00
|
|
|
enum : int { // The first valid value is 1.
|
|
|
|
|
kAudioLevelExtensionId = 1,
|
2020-01-07 16:40:17 +03:00
|
|
|
kAbsoluteCaptureTimeExtensionId = 2,
|
Reland "Delete test/constants.h"
This reverts commit 4f36b7a478c2763463c7a9ea970548ec68bc3ea6.
Reason for revert: Failing tests fixed.
Original change's description:
> Revert "Delete test/constants.h"
>
> This reverts commit 389b1672a32f2dd49af6c6ed40e8ddf394b986de.
>
> Reason for revert: Causes failure (and empty result list) in CallPerfTest.PadsToMinTransmitBitrate
>
> Original change's description:
> > Delete test/constants.h
> >
> > It's not possible to use constants.h for all RTP extensions
> > after the number of extensions exceeds 14, which is the maximum
> > number of one-byte RTP extensions. This is because some extensions
> > would have to be assigned a number greater than 14, even if the
> > test only involves 14 extensions or less.
> >
> > For uniformity's sake, this CL also edits some files to use an
> > enum as the files involved in this CL, rather than free-floating
> > const-ints.
> >
> > Bug: webrtc:10288
> > Change-Id: Ib5e58ad72c4d3756f4c4f6521f140ec59617f3f5
> > Reviewed-on: https://webrtc-review.googlesource.com/c/123048
> > Commit-Queue: Elad Alon <eladalon@webrtc.org>
> > Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
> > Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#26728}
>
> TBR=danilchap@webrtc.org,kwiberg@webrtc.org,eladalon@webrtc.org,sprang@webrtc.org
>
> Bug: webrtc:10288, chromium:933127
> Change-Id: If1de0bd8992137c52bf0b877b3cb0a2bafc809d4
> Reviewed-on: https://webrtc-review.googlesource.com/c/123381
> Commit-Queue: Oleh Prypin <oprypin@webrtc.org>
> Reviewed-by: Oleh Prypin <oprypin@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26744}
TBR=danilchap@webrtc.org,oprypin@webrtc.org,kwiberg@webrtc.org,eladalon@webrtc.org,sprang@webrtc.org
Change-Id: I65e391325d3a6df6db3c0739185e2002e70fb954
Bug: webrtc:10288, chromium:933127
Reviewed-on: https://webrtc-review.googlesource.com/c/123384
Reviewed-by: Elad Alon <eladalon@webrtc.org>
Commit-Queue: Elad Alon <eladalon@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26750}
2019-02-18 23:45:57 +01:00
|
|
|
};
|
|
|
|
|
|
2019-02-01 14:13:29 +01:00
|
|
|
const uint16_t kSeqNum = 33;
|
|
|
|
|
const uint32_t kSsrc = 725242;
|
|
|
|
|
const uint64_t kStartTime = 123456789;
|
|
|
|
|
|
|
|
|
|
using ::testing::ElementsAreArray;
|
|
|
|
|
|
|
|
|
|
class LoopbackTransportTest : public webrtc::Transport {
|
|
|
|
|
public:
|
|
|
|
|
LoopbackTransportTest() {
|
2024-02-22 11:26:04 -08:00
|
|
|
receivers_extensions_.Register<AudioLevelExtension>(kAudioLevelExtensionId);
|
2020-01-07 16:40:17 +03:00
|
|
|
receivers_extensions_.Register<AbsoluteCaptureTimeExtension>(
|
|
|
|
|
kAbsoluteCaptureTimeExtensionId);
|
2019-02-01 14:13:29 +01:00
|
|
|
}
|
|
|
|
|
|
2023-08-15 11:41:45 +00:00
|
|
|
bool SendRtp(rtc::ArrayView<const uint8_t> data,
|
2019-02-01 14:13:29 +01:00
|
|
|
const PacketOptions& /*options*/) override {
|
|
|
|
|
sent_packets_.push_back(RtpPacketReceived(&receivers_extensions_));
|
2023-08-15 11:41:45 +00:00
|
|
|
EXPECT_TRUE(sent_packets_.back().Parse(data));
|
2019-02-01 14:13:29 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
2023-08-15 11:41:45 +00:00
|
|
|
bool SendRtcp(rtc::ArrayView<const uint8_t> data) override { return false; }
|
2019-02-01 14:13:29 +01:00
|
|
|
const RtpPacketReceived& last_sent_packet() { return sent_packets_.back(); }
|
|
|
|
|
int packets_sent() { return sent_packets_.size(); }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
RtpHeaderExtensionMap receivers_extensions_;
|
|
|
|
|
std::vector<RtpPacketReceived> sent_packets_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
class RtpSenderAudioTest : public ::testing::Test {
|
|
|
|
|
public:
|
|
|
|
|
RtpSenderAudioTest()
|
|
|
|
|
: fake_clock_(kStartTime),
|
2024-08-29 18:28:07 +02:00
|
|
|
env_(CreateEnvironment(&fake_clock_)),
|
|
|
|
|
rtp_module_(env_,
|
|
|
|
|
{.audio = true,
|
|
|
|
|
.outgoing_transport = &transport_,
|
|
|
|
|
.local_media_ssrc = kSsrc}),
|
2020-08-20 16:18:31 +02:00
|
|
|
rtp_sender_audio_(
|
|
|
|
|
std::make_unique<RTPSenderAudio>(&fake_clock_,
|
2024-08-29 18:28:07 +02:00
|
|
|
rtp_module_.RtpSender())) {
|
|
|
|
|
rtp_module_.SetSequenceNumber(kSeqNum);
|
2019-02-01 14:13:29 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-20 09:12:57 +02:00
|
|
|
rtc::AutoThread main_thread_;
|
2019-02-01 14:13:29 +01:00
|
|
|
SimulatedClock fake_clock_;
|
2024-08-29 18:28:07 +02:00
|
|
|
const Environment env_;
|
2019-02-01 14:13:29 +01:00
|
|
|
LoopbackTransportTest transport_;
|
2024-08-29 18:28:07 +02:00
|
|
|
ModuleRtpRtcpImpl2 rtp_module_;
|
2020-08-20 16:18:31 +02:00
|
|
|
std::unique_ptr<RTPSenderAudio> rtp_sender_audio_;
|
2019-02-01 14:13:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(RtpSenderAudioTest, SendAudio) {
|
|
|
|
|
const char payload_name[] = "PAYLOAD_NAME";
|
|
|
|
|
const uint8_t payload_type = 127;
|
2020-08-20 16:18:31 +02:00
|
|
|
ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
|
2019-02-01 14:13:29 +01:00
|
|
|
payload_name, payload_type, 48000, 0, 1500));
|
|
|
|
|
uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
|
|
|
2023-09-04 12:27:59 +02:00
|
|
|
ASSERT_TRUE(rtp_sender_audio_->SendAudio(
|
|
|
|
|
{.payload = payload, .payload_id = payload_type}));
|
2019-02-01 14:13:29 +01:00
|
|
|
|
|
|
|
|
auto sent_payload = transport_.last_sent_packet().payload();
|
|
|
|
|
EXPECT_THAT(sent_payload, ElementsAreArray(payload));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
|
2023-09-04 12:27:59 +02:00
|
|
|
const uint8_t kAudioLevel = 0x5a;
|
2024-08-29 18:28:07 +02:00
|
|
|
rtp_module_.RegisterRtpHeaderExtension(AudioLevelExtension::Uri(),
|
|
|
|
|
kAudioLevelExtensionId);
|
2019-02-01 14:13:29 +01:00
|
|
|
|
|
|
|
|
const char payload_name[] = "PAYLOAD_NAME";
|
|
|
|
|
const uint8_t payload_type = 127;
|
2020-08-20 16:18:31 +02:00
|
|
|
ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
|
2019-02-01 14:13:29 +01:00
|
|
|
payload_name, payload_type, 48000, 0, 1500));
|
|
|
|
|
|
|
|
|
|
uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
|
|
|
2020-08-20 16:18:31 +02:00
|
|
|
ASSERT_TRUE(
|
2023-09-04 12:27:59 +02:00
|
|
|
rtp_sender_audio_->SendAudio({.type = AudioFrameType::kAudioFrameCN,
|
|
|
|
|
.payload = payload,
|
|
|
|
|
.payload_id = payload_type,
|
|
|
|
|
.audio_level_dbov = kAudioLevel}));
|
2019-02-01 14:13:29 +01:00
|
|
|
|
|
|
|
|
auto sent_payload = transport_.last_sent_packet().payload();
|
|
|
|
|
EXPECT_THAT(sent_payload, ElementsAreArray(payload));
|
|
|
|
|
// Verify AudioLevel extension.
|
2024-03-21 18:08:54 -07:00
|
|
|
AudioLevel audio_level;
|
2024-02-22 11:26:04 -08:00
|
|
|
EXPECT_TRUE(transport_.last_sent_packet().GetExtension<AudioLevelExtension>(
|
2024-03-21 18:08:54 -07:00
|
|
|
&audio_level));
|
|
|
|
|
EXPECT_EQ(kAudioLevel, audio_level.level());
|
|
|
|
|
EXPECT_FALSE(audio_level.voice_activity());
|
2019-02-01 14:13:29 +01:00
|
|
|
}
|
|
|
|
|
|
2020-01-07 16:40:17 +03:00
|
|
|
TEST_F(RtpSenderAudioTest, SendAudioWithoutAbsoluteCaptureTime) {
|
2023-09-04 12:27:59 +02:00
|
|
|
constexpr Timestamp kAbsoluteCaptureTimestamp = Timestamp::Millis(521);
|
2020-01-07 16:40:17 +03:00
|
|
|
const char payload_name[] = "audio";
|
|
|
|
|
const uint8_t payload_type = 127;
|
2020-08-20 16:18:31 +02:00
|
|
|
ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
|
2020-01-07 16:40:17 +03:00
|
|
|
payload_name, payload_type, 48000, 0, 1500));
|
|
|
|
|
uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
|
|
|
2020-08-20 16:18:31 +02:00
|
|
|
ASSERT_TRUE(rtp_sender_audio_->SendAudio(
|
2023-09-04 12:27:59 +02:00
|
|
|
{.payload = payload,
|
|
|
|
|
.payload_id = payload_type,
|
|
|
|
|
.capture_time = kAbsoluteCaptureTimestamp}));
|
2020-01-07 16:40:17 +03:00
|
|
|
|
2023-09-04 12:27:59 +02:00
|
|
|
// AbsoluteCaptureTimeExtension wasn't registered, thus can't be sent.
|
2020-01-07 16:40:17 +03:00
|
|
|
EXPECT_FALSE(transport_.last_sent_packet()
|
|
|
|
|
.HasExtension<AbsoluteCaptureTimeExtension>());
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-20 16:18:31 +02:00
|
|
|
TEST_F(RtpSenderAudioTest,
|
|
|
|
|
SendAudioWithAbsoluteCaptureTimeWithCaptureClockOffset) {
|
2024-08-29 18:28:07 +02:00
|
|
|
rtp_module_.RegisterRtpHeaderExtension(AbsoluteCaptureTimeExtension::Uri(),
|
|
|
|
|
kAbsoluteCaptureTimeExtensionId);
|
2023-09-04 12:27:59 +02:00
|
|
|
constexpr Timestamp kAbsoluteCaptureTimestamp = Timestamp::Millis(521);
|
2020-08-20 16:18:31 +02:00
|
|
|
const char payload_name[] = "audio";
|
|
|
|
|
const uint8_t payload_type = 127;
|
|
|
|
|
ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
|
|
|
|
|
payload_name, payload_type, 48000, 0, 1500));
|
|
|
|
|
uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(rtp_sender_audio_->SendAudio(
|
2023-09-04 12:27:59 +02:00
|
|
|
{.payload = payload,
|
|
|
|
|
.payload_id = payload_type,
|
|
|
|
|
.capture_time = kAbsoluteCaptureTimestamp}));
|
2020-08-20 16:18:31 +02:00
|
|
|
|
|
|
|
|
auto absolute_capture_time =
|
|
|
|
|
transport_.last_sent_packet()
|
|
|
|
|
.GetExtension<AbsoluteCaptureTimeExtension>();
|
2023-03-23 18:29:55 +01:00
|
|
|
ASSERT_TRUE(absolute_capture_time);
|
2023-09-04 12:27:59 +02:00
|
|
|
EXPECT_EQ(NtpTime(absolute_capture_time->absolute_capture_timestamp),
|
|
|
|
|
fake_clock_.ConvertTimestampToNtpTime(kAbsoluteCaptureTimestamp));
|
2023-03-23 18:29:55 +01:00
|
|
|
EXPECT_EQ(absolute_capture_time->estimated_capture_clock_offset, 0);
|
2020-01-07 16:40:17 +03:00
|
|
|
}
|
|
|
|
|
|
2019-02-01 14:13:29 +01:00
|
|
|
// As RFC4733, named telephone events are carried as part of the audio stream
|
|
|
|
|
// and must use the same sequence number and timestamp base as the regular
|
|
|
|
|
// audio channel.
|
|
|
|
|
// This test checks the marker bit for the first packet and the consequent
|
|
|
|
|
// packets of the same telephone event. Since it is specifically for DTMF
|
|
|
|
|
// events, ignoring audio packets and sending kEmptyFrame instead of those.
|
|
|
|
|
TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
|
|
|
|
|
const char* kDtmfPayloadName = "telephone-event";
|
|
|
|
|
const uint32_t kPayloadFrequency = 8000;
|
|
|
|
|
const uint8_t kPayloadType = 126;
|
2020-08-20 16:18:31 +02:00
|
|
|
ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
|
2019-02-01 14:13:29 +01:00
|
|
|
kDtmfPayloadName, kPayloadType, kPayloadFrequency, 0, 0));
|
|
|
|
|
// For Telephone events, payload is not added to the registered payload list,
|
|
|
|
|
// it will register only the payload used for audio stream.
|
|
|
|
|
// Registering the payload again for audio stream with different payload name.
|
|
|
|
|
const char* kPayloadName = "payload_name";
|
2020-08-20 16:18:31 +02:00
|
|
|
ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
|
2019-02-01 14:13:29 +01:00
|
|
|
kPayloadName, kPayloadType, kPayloadFrequency, 1, 0));
|
|
|
|
|
// Start time is arbitrary.
|
2023-09-04 12:27:59 +02:00
|
|
|
uint32_t capture_timestamp = 12345;
|
2019-02-01 14:13:29 +01:00
|
|
|
// DTMF event key=9, duration=500 and attenuationdB=10
|
2020-08-20 16:18:31 +02:00
|
|
|
rtp_sender_audio_->SendTelephoneEvent(9, 500, 10);
|
2019-02-01 14:13:29 +01:00
|
|
|
// During start, it takes the starting timestamp as last sent timestamp.
|
|
|
|
|
// The duration is calculated as the difference of current and last sent
|
|
|
|
|
// timestamp. So for first call it will skip since the duration is zero.
|
2023-09-04 12:27:59 +02:00
|
|
|
ASSERT_TRUE(
|
|
|
|
|
rtp_sender_audio_->SendAudio({.type = AudioFrameType::kEmptyFrame,
|
|
|
|
|
.payload_id = kPayloadType,
|
|
|
|
|
.rtp_timestamp = capture_timestamp}));
|
2020-01-07 16:40:17 +03:00
|
|
|
|
2019-02-01 14:13:29 +01:00
|
|
|
// DTMF Sample Length is (Frequency/1000) * Duration.
|
|
|
|
|
// So in this case, it is (8000/1000) * 500 = 4000.
|
|
|
|
|
// Sending it as two packets.
|
2023-09-04 12:27:59 +02:00
|
|
|
ASSERT_TRUE(rtp_sender_audio_->SendAudio(
|
|
|
|
|
{.type = AudioFrameType::kEmptyFrame,
|
|
|
|
|
.payload_id = kPayloadType,
|
|
|
|
|
.rtp_timestamp = capture_timestamp + 2000}));
|
2019-02-01 14:13:29 +01:00
|
|
|
|
|
|
|
|
// Marker Bit should be set to 1 for first packet.
|
|
|
|
|
EXPECT_TRUE(transport_.last_sent_packet().Marker());
|
|
|
|
|
|
2023-09-04 12:27:59 +02:00
|
|
|
ASSERT_TRUE(rtp_sender_audio_->SendAudio(
|
|
|
|
|
{.type = AudioFrameType::kEmptyFrame,
|
|
|
|
|
.payload_id = kPayloadType,
|
|
|
|
|
.rtp_timestamp = capture_timestamp + 4000}));
|
|
|
|
|
|
2019-02-01 14:13:29 +01:00
|
|
|
// Marker Bit should be set to 0 for rest of the packets.
|
|
|
|
|
EXPECT_FALSE(transport_.last_sent_packet().Marker());
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-07 12:39:40 +01:00
|
|
|
TEST_F(RtpSenderAudioTest, SendsCsrcs) {
|
|
|
|
|
const char payload_name[] = "audio";
|
|
|
|
|
const uint8_t payload_type = 127;
|
|
|
|
|
ASSERT_EQ(0, rtp_sender_audio_->RegisterAudioPayload(
|
|
|
|
|
payload_name, payload_type, 48000, 0, 1500));
|
|
|
|
|
uint8_t payload[] = {47, 11, 32, 93, 89};
|
|
|
|
|
|
|
|
|
|
std::vector<uint32_t> csrcs({123, 456, 789});
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(rtp_sender_audio_->SendAudio(
|
|
|
|
|
{.payload = payload, .payload_id = payload_type, .csrcs = csrcs}));
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ(transport_.last_sent_packet().Csrcs(), csrcs);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-01 14:13:29 +01:00
|
|
|
} // namespace webrtc
|