blob: 9fb20d6c00705591500c46ad7409bdd273c41af1 [file] [log] [blame]
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +01001/*
2 * Copyright (c) 2017 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 */
10
11#include "modules/rtp_rtcp/source/rtcp_transceiver.h"
12
13#include <utility>
14
Karl Wiberg918f50c2018-07-05 11:40:33 +020015#include "absl/memory/memory.h"
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +010016#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010017#include "rtc_base/checks.h"
18#include "rtc_base/event.h"
Danil Chapovalov1aa75812019-03-05 11:11:35 +010019#include "rtc_base/task_utils/to_queued_task.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "rtc_base/time_utils.h"
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010021
22namespace webrtc {
Danil Chapovalov792df6b2018-09-07 13:03:32 +020023namespace {
24struct Destructor {
Danil Chapovalov6318f132019-03-07 11:15:14 +010025 void operator()() {
26 rtcp_transceiver->StopPeriodicTask();
27 rtcp_transceiver = nullptr;
28 }
Danil Chapovalov792df6b2018-09-07 13:03:32 +020029 std::unique_ptr<RtcpTransceiverImpl> rtcp_transceiver;
30};
31} // namespace
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010032
33RtcpTransceiver::RtcpTransceiver(const RtcpTransceiverConfig& config)
34 : task_queue_(config.task_queue),
Danil Chapovalovf0076d32018-09-05 16:46:40 +020035 rtcp_transceiver_(absl::make_unique<RtcpTransceiverImpl>(config)) {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010036 RTC_DCHECK(task_queue_);
37}
38
39RtcpTransceiver::~RtcpTransceiver() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020040 if (!rtcp_transceiver_)
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010041 return;
Danil Chapovalov792df6b2018-09-07 13:03:32 +020042 task_queue_->PostTask(Destructor{std::move(rtcp_transceiver_)});
43 RTC_DCHECK(!rtcp_transceiver_);
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010044}
45
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020046void RtcpTransceiver::Stop(std::function<void()> on_destroyed) {
47 RTC_DCHECK(rtcp_transceiver_);
Danil Chapovalov1aa75812019-03-05 11:11:35 +010048 task_queue_->PostTask(ToQueuedTask(Destructor{std::move(rtcp_transceiver_)},
49 std::move(on_destroyed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020050 RTC_DCHECK(!rtcp_transceiver_);
51}
52
Danil Chapovalova32d7102017-12-14 17:28:27 +010053void RtcpTransceiver::AddMediaReceiverRtcpObserver(
54 uint32_t remote_ssrc,
55 MediaReceiverRtcpObserver* observer) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020056 RTC_CHECK(rtcp_transceiver_);
57 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalova32d7102017-12-14 17:28:27 +010058 task_queue_->PostTask([ptr, remote_ssrc, observer] {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020059 ptr->AddMediaReceiverRtcpObserver(remote_ssrc, observer);
Danil Chapovalova32d7102017-12-14 17:28:27 +010060 });
61}
62
63void RtcpTransceiver::RemoveMediaReceiverRtcpObserver(
64 uint32_t remote_ssrc,
65 MediaReceiverRtcpObserver* observer,
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020066 std::function<void()> on_removed) {
67 RTC_CHECK(rtcp_transceiver_);
68 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
69 auto remove = [ptr, remote_ssrc, observer] {
70 ptr->RemoveMediaReceiverRtcpObserver(remote_ssrc, observer);
71 };
Danil Chapovalov1aa75812019-03-05 11:11:35 +010072 task_queue_->PostTask(ToQueuedTask(std::move(remove), std::move(on_removed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020073}
74
Danil Chapovalove3927c52018-03-06 14:33:20 +010075void RtcpTransceiver::SetReadyToSend(bool ready) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020076 RTC_CHECK(rtcp_transceiver_);
77 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +020078 task_queue_->PostTask([ptr, ready] { ptr->SetReadyToSend(ready); });
Danil Chapovalove3927c52018-03-06 14:33:20 +010079}
80
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010081void RtcpTransceiver::ReceivePacket(rtc::CopyOnWriteBuffer packet) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020082 RTC_CHECK(rtcp_transceiver_);
83 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010084 int64_t now_us = rtc::TimeMicros();
Jonas Olssona4d87372019-07-05 19:08:33 +020085 task_queue_->PostTask(
86 [ptr, packet, now_us] { ptr->ReceivePacket(packet, now_us); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010087}
88
89void RtcpTransceiver::SendCompoundPacket() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020090 RTC_CHECK(rtcp_transceiver_);
91 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +020092 task_queue_->PostTask([ptr] { ptr->SendCompoundPacket(); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010093}
94
Danil Chapovalov1de4b622017-12-13 13:35:10 +010095void RtcpTransceiver::SetRemb(int64_t bitrate_bps,
96 std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020097 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010098 // TODO(danilchap): Replace with lambda with move capture when available.
99 struct SetRembClosure {
Jonas Olssona4d87372019-07-05 19:08:33 +0200100 void operator()() { ptr->SetRemb(bitrate_bps, std::move(ssrcs)); }
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100101
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200102 RtcpTransceiverImpl* ptr;
Danil Chapovalov1de4b622017-12-13 13:35:10 +0100103 int64_t bitrate_bps;
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100104 std::vector<uint32_t> ssrcs;
105 };
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200106 task_queue_->PostTask(
107 SetRembClosure{rtcp_transceiver_.get(), bitrate_bps, std::move(ssrcs)});
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100108}
109
110void RtcpTransceiver::UnsetRemb() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200111 RTC_CHECK(rtcp_transceiver_);
112 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +0200113 task_queue_->PostTask([ptr] { ptr->UnsetRemb(); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100114}
115
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100116uint32_t RtcpTransceiver::SSRC() const {
117 return rtcp_transceiver_->sender_ssrc();
118}
119
120bool RtcpTransceiver::SendFeedbackPacket(
121 const rtcp::TransportFeedback& packet) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200122 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100123 struct Closure {
Jonas Olssona4d87372019-07-05 19:08:33 +0200124 void operator()() { ptr->SendRawPacket(raw_packet); }
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200125 RtcpTransceiverImpl* ptr;
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100126 rtc::Buffer raw_packet;
127 };
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200128 task_queue_->PostTask(Closure{rtcp_transceiver_.get(), packet.Build()});
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100129 return true;
130}
131
Sebastian Janssone1795f42019-07-24 11:38:03 +0200132bool RtcpTransceiver::SendNetworkStateEstimatePacket(
133 const rtcp::RemoteEstimate& packet) {
134 RTC_CHECK(rtcp_transceiver_);
135 struct Closure {
136 void operator()() { ptr->SendRawPacket(raw_packet); }
137 RtcpTransceiverImpl* ptr;
138 rtc::Buffer raw_packet;
139 };
140 task_queue_->PostTask(Closure{rtcp_transceiver_.get(), packet.Build()});
141 return true;
142}
143
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100144void RtcpTransceiver::SendNack(uint32_t ssrc,
145 std::vector<uint16_t> sequence_numbers) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200146 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100147 // TODO(danilchap): Replace with lambda with move capture when available.
148 struct Closure {
Jonas Olssona4d87372019-07-05 19:08:33 +0200149 void operator()() { ptr->SendNack(ssrc, std::move(sequence_numbers)); }
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100150
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200151 RtcpTransceiverImpl* ptr;
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100152 uint32_t ssrc;
153 std::vector<uint16_t> sequence_numbers;
154 };
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200155 task_queue_->PostTask(
156 Closure{rtcp_transceiver_.get(), ssrc, std::move(sequence_numbers)});
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100157}
158
Danil Chapovalov8d19e032017-11-28 19:53:33 +0100159void RtcpTransceiver::SendPictureLossIndication(uint32_t ssrc) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200160 RTC_CHECK(rtcp_transceiver_);
161 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
162 task_queue_->PostTask([ptr, ssrc] { ptr->SendPictureLossIndication(ssrc); });
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100163}
164
165void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200166 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100167 // TODO(danilchap): Replace with lambda with move capture when available.
168 struct Closure {
Jonas Olssona4d87372019-07-05 19:08:33 +0200169 void operator()() { ptr->SendFullIntraRequest(ssrcs); }
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100170
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200171 RtcpTransceiverImpl* ptr;
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100172 std::vector<uint32_t> ssrcs;
173 };
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200174 task_queue_->PostTask(Closure{rtcp_transceiver_.get(), std::move(ssrcs)});
Danil Chapovalova7e418c2017-11-21 11:08:53 +0100175}
176
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100177} // namespace webrtc