blob: 3aa85082c4c7b713ee6c020f2f3188ed526b0a2b [file] [log] [blame]
pbos@webrtc.org96684672013-08-12 12:59:041/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
Mirko Bonadei92ea95e2017-09-15 04:47:3110#include "test/direct_transport.h"
pbos@webrtc.org96684672013-08-12 12:59:0411
Per Kjellander89870ff2023-01-19 15:45:5812#include "api/media_types.h"
Danil Chapovalovba2ba592019-09-27 09:10:4513#include "api/task_queue/task_queue_base.h"
14#include "api/units/time_delta.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3115#include "call/call.h"
Artem Titov46c4e602018-08-17 12:26:5416#include "call/fake_network_pipe.h"
Per Kjellander89870ff2023-01-19 15:45:5817#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Danil Chapovalov00ca0042021-07-05 17:06:1718#include "modules/rtp_rtcp/source/rtp_util.h"
Per Kjellander89870ff2023-01-19 15:45:5819#include "rtc_base/checks.h"
Danil Chapovalovba2ba592019-09-27 09:10:4520#include "rtc_base/task_utils/repeating_task.h"
Sebastian Jansson11c012a2019-03-29 13:17:2621#include "rtc_base/time_utils.h"
pbos@webrtc.org96684672013-08-12 12:59:0422
23namespace webrtc {
24namespace test {
25
Sebastian Jansson09408112018-04-24 12:41:2226Demuxer::Demuxer(const std::map<uint8_t, MediaType>& payload_type_map)
27 : payload_type_map_(payload_type_map) {}
28
29MediaType Demuxer::GetMediaType(const uint8_t* packet_data,
30 const size_t packet_length) const {
Danil Chapovalov00ca0042021-07-05 17:06:1731 if (IsRtpPacket(rtc::MakeArrayView(packet_data, packet_length))) {
Sebastian Jansson09408112018-04-24 12:41:2232 RTC_CHECK_GE(packet_length, 2);
33 const uint8_t payload_type = packet_data[1] & 0x7f;
34 std::map<uint8_t, MediaType>::const_iterator it =
35 payload_type_map_.find(payload_type);
36 RTC_CHECK(it != payload_type_map_.end())
37 << "payload type " << static_cast<int>(payload_type) << " unknown.";
38 return it->second;
39 }
40 return MediaType::ANY;
41}
42
minyue20c84cc2017-04-10 23:57:5743DirectTransport::DirectTransport(
Danil Chapovalovba2ba592019-09-27 09:10:4544 TaskQueueBase* task_queue,
Artem Titov46c4e602018-08-17 12:26:5445 std::unique_ptr<SimulatedPacketReceiverInterface> pipe,
Sebastian Jansson09408112018-04-24 12:41:2246 Call* send_call,
Per Kjellander89870ff2023-01-19 15:45:5847 const std::map<uint8_t, MediaType>& payload_type_map,
48 rtc::ArrayView<const RtpExtension> audio_extensions,
49 rtc::ArrayView<const RtpExtension> video_extensions)
Christoffer Rodbrod2817d82017-10-24 14:26:4950 : send_call_(send_call),
Christoffer Rodbrod2817d82017-10-24 14:26:4951 task_queue_(task_queue),
Sebastian Jansson09408112018-04-24 12:41:2252 demuxer_(payload_type_map),
Per Kjellander89870ff2023-01-19 15:45:5853 fake_network_(std::move(pipe)),
Per Kjellander89870ff2023-01-19 15:45:5854 audio_extensions_(audio_extensions),
55 video_extensions_(video_extensions) {
Christoffer Rodbrod2817d82017-10-24 14:26:4956 Start();
pbos@webrtc.org96684672013-08-12 12:59:0457}
58
eladalon413ee9a2017-08-22 11:02:5259DirectTransport::~DirectTransport() {
Danil Chapovalovba2ba592019-09-27 09:10:4560 next_process_task_.Stop();
pbos@webrtc.org468e19a2013-08-12 14:28:0061}
pbos@webrtc.org96684672013-08-12 12:59:0462
pbos@webrtc.org74fa4892013-08-23 09:19:3063void DirectTransport::SetReceiver(PacketReceiver* receiver) {
Christoffer Rodbrod2817d82017-10-24 14:26:4964 fake_network_->SetReceiver(receiver);
pbos@webrtc.org96684672013-08-12 12:59:0465}
66
Harald Alvestrandd43af912023-08-15 11:41:4567bool DirectTransport::SendRtp(rtc::ArrayView<const uint8_t> data,
stefan1d8a5062015-10-02 10:39:3368 const PacketOptions& options) {
stefanf116bd02015-10-27 15:29:4269 if (send_call_) {
Sebastian Jansson11c012a2019-03-29 13:17:2670 rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis());
Sebastian Jansson03789972018-10-09 16:27:5771 sent_packet.info.included_in_feedback = options.included_in_feedback;
72 sent_packet.info.included_in_allocation = options.included_in_allocation;
Harald Alvestrandd43af912023-08-15 11:41:4573 sent_packet.info.packet_size_bytes = data.size();
Sebastian Jansson156d11d2018-09-28 15:21:3474 sent_packet.info.packet_type = rtc::PacketType::kData;
stefanf116bd02015-10-27 15:29:4275 send_call_->OnSentPacket(sent_packet);
76 }
Per Kjellander89870ff2023-01-19 15:45:5877
Per K664cf142023-01-25 14:19:1178 const RtpHeaderExtensionMap* extensions = nullptr;
Harald Alvestrandd43af912023-08-15 11:41:4579 MediaType media_type = demuxer_.GetMediaType(data.data(), data.size());
80 switch (demuxer_.GetMediaType(data.data(), data.size())) {
Per K664cf142023-01-25 14:19:1181 case webrtc::MediaType::AUDIO:
82 extensions = &audio_extensions_;
83 break;
84 case webrtc::MediaType::VIDEO:
85 extensions = &video_extensions_;
86 break;
87 default:
88 RTC_CHECK_NOTREACHED();
Per Kjellander89870ff2023-01-19 15:45:5889 }
Per K664cf142023-01-25 14:19:1190 RtpPacketReceived packet(extensions, Timestamp::Micros(rtc::TimeMicros()));
91 if (media_type == MediaType::VIDEO) {
92 packet.set_payload_type_frequency(kVideoPayloadTypeFrequency);
93 }
Harald Alvestrandd43af912023-08-15 11:41:4594 RTC_CHECK(packet.Parse(rtc::CopyOnWriteBuffer(data)));
Per K664cf142023-01-25 14:19:1195 fake_network_->DeliverRtpPacket(
96 media_type, std::move(packet),
97 [](const RtpPacketReceived& packet) { return false; });
98
Per Kjellander89870ff2023-01-19 15:45:5899 MutexLock lock(&process_lock_);
100 if (!next_process_task_.Running())
101 ProcessPackets();
pbos@webrtc.org96684672013-08-12 12:59:04102 return true;
103}
104
Harald Alvestrandd43af912023-08-15 11:41:45105bool DirectTransport::SendRtcp(rtc::ArrayView<const uint8_t> data) {
106 fake_network_->DeliverRtcpPacket(rtc::CopyOnWriteBuffer(data));
Per Kjellander89870ff2023-01-19 15:45:58107 MutexLock lock(&process_lock_);
108 if (!next_process_task_.Running())
109 ProcessPackets();
stefan@webrtc.orgfaada6e2013-12-18 20:28:25110 return true;
pbos@webrtc.org96684672013-08-12 12:59:04111}
112
Stefan Holmerff2a6352016-01-14 09:00:21113int DirectTransport::GetAverageDelayMs() {
Christoffer Rodbrod2817d82017-10-24 14:26:49114 return fake_network_->AverageDelay();
115}
116
117void DirectTransport::Start() {
118 RTC_DCHECK(task_queue_);
119 if (send_call_) {
120 send_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
121 send_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
122 }
Stefan Holmerff2a6352016-01-14 09:00:21123}
124
Sebastian Jansson836fee12019-02-08 15:08:10125void DirectTransport::ProcessPackets() {
Danil Chapovalovba2ba592019-09-27 09:10:45126 absl::optional<int64_t> initial_delay_ms =
127 fake_network_->TimeUntilNextProcess();
128 if (initial_delay_ms == absl::nullopt)
129 return;
130
131 next_process_task_ = RepeatingTaskHandle::DelayedStart(
Danil Chapovalov0c626af2020-02-10 10:16:00132 task_queue_, TimeDelta::Millis(*initial_delay_ms), [this] {
Danil Chapovalovba2ba592019-09-27 09:10:45133 fake_network_->Process();
134 if (auto delay_ms = fake_network_->TimeUntilNextProcess())
Danil Chapovalov0c626af2020-02-10 10:16:00135 return TimeDelta::Millis(*delay_ms);
Danil Chapovalovba2ba592019-09-27 09:10:45136 // Otherwise stop the task.
Markus Handella5a4be12020-07-08 14:09:21137 MutexLock lock(&process_lock_);
Danil Chapovalovba2ba592019-09-27 09:10:45138 next_process_task_.Stop();
139 // Since this task is stopped, return value doesn't matter.
140 return TimeDelta::Zero();
141 });
pbos@webrtc.org96684672013-08-12 12:59:04142}
143} // namespace test
144} // namespace webrtc