blob: 0d626de692a05dfd7830458d3466c943d2c6ea2d [file] [log] [blame]
pbos@webrtc.org96684672013-08-12 12:59:04 +00001/*
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 06:47:31 +020010#include "test/direct_transport.h"
pbos@webrtc.org96684672013-08-12 12:59:04 +000011
Karl Wiberg918f50c2018-07-05 11:40:33 +020012#include "absl/memory/memory.h"
Danil Chapovalovba2ba592019-09-27 11:10:45 +020013#include "api/task_queue/task_queue_base.h"
14#include "api/units/time_delta.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "call/call.h"
Artem Titov46c4e602018-08-17 14:26:54 +020016#include "call/fake_network_pipe.h"
Danil Chapovalovba2ba592019-09-27 11:10:45 +020017#include "rtc_base/task_utils/repeating_task.h"
Sebastian Jansson11c012a2019-03-29 14:17:26 +010018#include "rtc_base/time_utils.h"
Tommi25eb47c2019-08-29 16:39:05 +020019#include "test/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "test/single_threaded_task_queue.h"
pbos@webrtc.org96684672013-08-12 12:59:04 +000021
22namespace webrtc {
23namespace test {
24
Sebastian Jansson09408112018-04-24 14:41:22 +020025Demuxer::Demuxer(const std::map<uint8_t, MediaType>& payload_type_map)
26 : payload_type_map_(payload_type_map) {}
27
28MediaType Demuxer::GetMediaType(const uint8_t* packet_data,
29 const size_t packet_length) const {
30 if (!RtpHeaderParser::IsRtcp(packet_data, packet_length)) {
31 RTC_CHECK_GE(packet_length, 2);
32 const uint8_t payload_type = packet_data[1] & 0x7f;
33 std::map<uint8_t, MediaType>::const_iterator it =
34 payload_type_map_.find(payload_type);
35 RTC_CHECK(it != payload_type_map_.end())
36 << "payload type " << static_cast<int>(payload_type) << " unknown.";
37 return it->second;
38 }
39 return MediaType::ANY;
40}
41
minyue20c84cc2017-04-10 16:57:57 -070042DirectTransport::DirectTransport(
Danil Chapovalovba2ba592019-09-27 11:10:45 +020043 TaskQueueBase* task_queue,
Artem Titov46c4e602018-08-17 14:26:54 +020044 std::unique_ptr<SimulatedPacketReceiverInterface> pipe,
Sebastian Jansson09408112018-04-24 14:41:22 +020045 Call* send_call,
46 const std::map<uint8_t, MediaType>& payload_type_map)
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020047 : send_call_(send_call),
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020048 task_queue_(task_queue),
Sebastian Jansson09408112018-04-24 14:41:22 +020049 demuxer_(payload_type_map),
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020050 fake_network_(std::move(pipe)) {
51 Start();
pbos@webrtc.org96684672013-08-12 12:59:04 +000052}
53
eladalon413ee9a2017-08-22 04:02:52 -070054DirectTransport::~DirectTransport() {
Danil Chapovalovba2ba592019-09-27 11:10:45 +020055 next_process_task_.Stop();
pbos@webrtc.org468e19a2013-08-12 14:28:00 +000056}
pbos@webrtc.org96684672013-08-12 12:59:04 +000057
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000058void DirectTransport::SetReceiver(PacketReceiver* receiver) {
Sebastian Jansson836fee12019-02-08 16:08:10 +010059 rtc::CritScope cs(&process_lock_);
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020060 fake_network_->SetReceiver(receiver);
pbos@webrtc.org96684672013-08-12 12:59:04 +000061}
62
stefan1d8a5062015-10-02 03:39:33 -070063bool DirectTransport::SendRtp(const uint8_t* data,
64 size_t length,
65 const PacketOptions& options) {
stefanf116bd02015-10-27 08:29:42 -070066 if (send_call_) {
Sebastian Jansson11c012a2019-03-29 14:17:26 +010067 rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis());
Sebastian Jansson03789972018-10-09 18:27:57 +020068 sent_packet.info.included_in_feedback = options.included_in_feedback;
69 sent_packet.info.included_in_allocation = options.included_in_allocation;
Sebastian Jansson156d11d2018-09-28 17:21:34 +020070 sent_packet.info.packet_size_bytes = length;
71 sent_packet.info.packet_type = rtc::PacketType::kData;
stefanf116bd02015-10-27 08:29:42 -070072 send_call_->OnSentPacket(sent_packet);
73 }
Sebastian Jansson09408112018-04-24 14:41:22 +020074 SendPacket(data, length);
pbos@webrtc.org96684672013-08-12 12:59:04 +000075 return true;
76}
77
pbos@webrtc.org27326b62013-11-20 12:17:04 +000078bool DirectTransport::SendRtcp(const uint8_t* data, size_t length) {
Sebastian Jansson09408112018-04-24 14:41:22 +020079 SendPacket(data, length);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000080 return true;
pbos@webrtc.org96684672013-08-12 12:59:04 +000081}
82
Sebastian Jansson09408112018-04-24 14:41:22 +020083void DirectTransport::SendPacket(const uint8_t* data, size_t length) {
84 MediaType media_type = demuxer_.GetMediaType(data, length);
Sebastian Jansson11c012a2019-03-29 14:17:26 +010085 int64_t send_time_us = rtc::TimeMicros();
Sebastian Jansson09408112018-04-24 14:41:22 +020086 fake_network_->DeliverPacket(media_type, rtc::CopyOnWriteBuffer(data, length),
Sebastian Jansson11c012a2019-03-29 14:17:26 +010087 send_time_us);
Sebastian Jansson836fee12019-02-08 16:08:10 +010088 rtc::CritScope cs(&process_lock_);
Danil Chapovalovba2ba592019-09-27 11:10:45 +020089 if (!next_process_task_.Running())
Sebastian Jansson836fee12019-02-08 16:08:10 +010090 ProcessPackets();
Sebastian Jansson09408112018-04-24 14:41:22 +020091}
92
Stefan Holmerff2a6352016-01-14 10:00:21 +010093int DirectTransport::GetAverageDelayMs() {
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020094 return fake_network_->AverageDelay();
95}
96
97void DirectTransport::Start() {
98 RTC_DCHECK(task_queue_);
99 if (send_call_) {
100 send_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
101 send_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
102 }
Stefan Holmerff2a6352016-01-14 10:00:21 +0100103}
104
Sebastian Jansson836fee12019-02-08 16:08:10 +0100105void DirectTransport::ProcessPackets() {
Danil Chapovalovba2ba592019-09-27 11:10:45 +0200106 absl::optional<int64_t> initial_delay_ms =
107 fake_network_->TimeUntilNextProcess();
108 if (initial_delay_ms == absl::nullopt)
109 return;
110
111 next_process_task_ = RepeatingTaskHandle::DelayedStart(
112 task_queue_, TimeDelta::ms(*initial_delay_ms), [this] {
113 fake_network_->Process();
114 if (auto delay_ms = fake_network_->TimeUntilNextProcess())
115 return TimeDelta::ms(*delay_ms);
116 // Otherwise stop the task.
117 rtc::CritScope cs(&process_lock_);
118 next_process_task_.Stop();
119 // Since this task is stopped, return value doesn't matter.
120 return TimeDelta::Zero();
121 });
pbos@webrtc.org96684672013-08-12 12:59:04 +0000122}
123} // namespace test
124} // namespace webrtc