blob: 84273b0830dd87f01fce879b2f7964514aaf51af [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"
pbos@webrtc.org96684672013-08-12 12:59:04 +000020
21namespace webrtc {
22namespace test {
23
Sebastian Jansson09408112018-04-24 14:41:22 +020024Demuxer::Demuxer(const std::map<uint8_t, MediaType>& payload_type_map)
25 : payload_type_map_(payload_type_map) {}
26
27MediaType Demuxer::GetMediaType(const uint8_t* packet_data,
28 const size_t packet_length) const {
29 if (!RtpHeaderParser::IsRtcp(packet_data, packet_length)) {
30 RTC_CHECK_GE(packet_length, 2);
31 const uint8_t payload_type = packet_data[1] & 0x7f;
32 std::map<uint8_t, MediaType>::const_iterator it =
33 payload_type_map_.find(payload_type);
34 RTC_CHECK(it != payload_type_map_.end())
35 << "payload type " << static_cast<int>(payload_type) << " unknown.";
36 return it->second;
37 }
38 return MediaType::ANY;
39}
40
minyue20c84cc2017-04-10 16:57:57 -070041DirectTransport::DirectTransport(
Danil Chapovalovba2ba592019-09-27 11:10:45 +020042 TaskQueueBase* task_queue,
Artem Titov46c4e602018-08-17 14:26:54 +020043 std::unique_ptr<SimulatedPacketReceiverInterface> pipe,
Sebastian Jansson09408112018-04-24 14:41:22 +020044 Call* send_call,
45 const std::map<uint8_t, MediaType>& payload_type_map)
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020046 : send_call_(send_call),
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020047 task_queue_(task_queue),
Sebastian Jansson09408112018-04-24 14:41:22 +020048 demuxer_(payload_type_map),
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020049 fake_network_(std::move(pipe)) {
50 Start();
pbos@webrtc.org96684672013-08-12 12:59:04 +000051}
52
eladalon413ee9a2017-08-22 04:02:52 -070053DirectTransport::~DirectTransport() {
Danil Chapovalovba2ba592019-09-27 11:10:45 +020054 next_process_task_.Stop();
pbos@webrtc.org468e19a2013-08-12 14:28:00 +000055}
pbos@webrtc.org96684672013-08-12 12:59:04 +000056
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000057void DirectTransport::SetReceiver(PacketReceiver* receiver) {
Sebastian Jansson836fee12019-02-08 16:08:10 +010058 rtc::CritScope cs(&process_lock_);
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020059 fake_network_->SetReceiver(receiver);
pbos@webrtc.org96684672013-08-12 12:59:04 +000060}
61
stefan1d8a5062015-10-02 03:39:33 -070062bool DirectTransport::SendRtp(const uint8_t* data,
63 size_t length,
64 const PacketOptions& options) {
stefanf116bd02015-10-27 08:29:42 -070065 if (send_call_) {
Sebastian Jansson11c012a2019-03-29 14:17:26 +010066 rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis());
Sebastian Jansson03789972018-10-09 18:27:57 +020067 sent_packet.info.included_in_feedback = options.included_in_feedback;
68 sent_packet.info.included_in_allocation = options.included_in_allocation;
Sebastian Jansson156d11d2018-09-28 17:21:34 +020069 sent_packet.info.packet_size_bytes = length;
70 sent_packet.info.packet_type = rtc::PacketType::kData;
stefanf116bd02015-10-27 08:29:42 -070071 send_call_->OnSentPacket(sent_packet);
72 }
Sebastian Jansson09408112018-04-24 14:41:22 +020073 SendPacket(data, length);
pbos@webrtc.org96684672013-08-12 12:59:04 +000074 return true;
75}
76
pbos@webrtc.org27326b62013-11-20 12:17:04 +000077bool DirectTransport::SendRtcp(const uint8_t* data, size_t length) {
Sebastian Jansson09408112018-04-24 14:41:22 +020078 SendPacket(data, length);
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000079 return true;
pbos@webrtc.org96684672013-08-12 12:59:04 +000080}
81
Sebastian Jansson09408112018-04-24 14:41:22 +020082void DirectTransport::SendPacket(const uint8_t* data, size_t length) {
83 MediaType media_type = demuxer_.GetMediaType(data, length);
Sebastian Jansson11c012a2019-03-29 14:17:26 +010084 int64_t send_time_us = rtc::TimeMicros();
Sebastian Jansson09408112018-04-24 14:41:22 +020085 fake_network_->DeliverPacket(media_type, rtc::CopyOnWriteBuffer(data, length),
Sebastian Jansson11c012a2019-03-29 14:17:26 +010086 send_time_us);
Sebastian Jansson836fee12019-02-08 16:08:10 +010087 rtc::CritScope cs(&process_lock_);
Danil Chapovalovba2ba592019-09-27 11:10:45 +020088 if (!next_process_task_.Running())
Sebastian Jansson836fee12019-02-08 16:08:10 +010089 ProcessPackets();
Sebastian Jansson09408112018-04-24 14:41:22 +020090}
91
Stefan Holmerff2a6352016-01-14 10:00:21 +010092int DirectTransport::GetAverageDelayMs() {
Christoffer Rodbrod2817d82017-10-24 16:26:49 +020093 return fake_network_->AverageDelay();
94}
95
96void DirectTransport::Start() {
97 RTC_DCHECK(task_queue_);
98 if (send_call_) {
99 send_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
100 send_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
101 }
Stefan Holmerff2a6352016-01-14 10:00:21 +0100102}
103
Sebastian Jansson836fee12019-02-08 16:08:10 +0100104void DirectTransport::ProcessPackets() {
Danil Chapovalovba2ba592019-09-27 11:10:45 +0200105 absl::optional<int64_t> initial_delay_ms =
106 fake_network_->TimeUntilNextProcess();
107 if (initial_delay_ms == absl::nullopt)
108 return;
109
110 next_process_task_ = RepeatingTaskHandle::DelayedStart(
111 task_queue_, TimeDelta::ms(*initial_delay_ms), [this] {
112 fake_network_->Process();
113 if (auto delay_ms = fake_network_->TimeUntilNextProcess())
114 return TimeDelta::ms(*delay_ms);
115 // Otherwise stop the task.
116 rtc::CritScope cs(&process_lock_);
117 next_process_task_.Stop();
118 // Since this task is stopped, return value doesn't matter.
119 return TimeDelta::Zero();
120 });
pbos@webrtc.org96684672013-08-12 12:59:04 +0000121}
122} // namespace test
123} // namespace webrtc