blob: 6c0e0b74f53d2f5ffa265d6308033138a1445f58 [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"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "rtc_base/time_utils.h"
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010020
21namespace webrtc {
Danil Chapovalov792df6b2018-09-07 13:03:32 +020022namespace {
23struct Destructor {
24 void operator()() { rtcp_transceiver = nullptr; }
25 std::unique_ptr<RtcpTransceiverImpl> rtcp_transceiver;
26};
27} // namespace
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010028
29RtcpTransceiver::RtcpTransceiver(const RtcpTransceiverConfig& config)
30 : task_queue_(config.task_queue),
Danil Chapovalovf0076d32018-09-05 16:46:40 +020031 rtcp_transceiver_(absl::make_unique<RtcpTransceiverImpl>(config)) {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010032 RTC_DCHECK(task_queue_);
33}
34
35RtcpTransceiver::~RtcpTransceiver() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020036 if (!rtcp_transceiver_)
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010037 return;
Danil Chapovalov792df6b2018-09-07 13:03:32 +020038 task_queue_->PostTask(Destructor{std::move(rtcp_transceiver_)});
39 RTC_DCHECK(!rtcp_transceiver_);
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010040}
41
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020042void RtcpTransceiver::Stop(std::function<void()> on_destroyed) {
43 RTC_DCHECK(rtcp_transceiver_);
44 task_queue_->PostTask(rtc::NewClosure(
45 Destructor{std::move(rtcp_transceiver_)}, std::move(on_destroyed)));
46 RTC_DCHECK(!rtcp_transceiver_);
47}
48
Danil Chapovalova32d7102017-12-14 17:28:27 +010049void RtcpTransceiver::AddMediaReceiverRtcpObserver(
50 uint32_t remote_ssrc,
51 MediaReceiverRtcpObserver* observer) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020052 RTC_CHECK(rtcp_transceiver_);
53 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalova32d7102017-12-14 17:28:27 +010054 task_queue_->PostTask([ptr, remote_ssrc, observer] {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020055 ptr->AddMediaReceiverRtcpObserver(remote_ssrc, observer);
Danil Chapovalova32d7102017-12-14 17:28:27 +010056 });
57}
58
59void RtcpTransceiver::RemoveMediaReceiverRtcpObserver(
60 uint32_t remote_ssrc,
61 MediaReceiverRtcpObserver* observer,
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020062 std::function<void()> on_removed) {
63 RTC_CHECK(rtcp_transceiver_);
64 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
65 auto remove = [ptr, remote_ssrc, observer] {
66 ptr->RemoveMediaReceiverRtcpObserver(remote_ssrc, observer);
67 };
68 task_queue_->PostTask(
69 rtc::NewClosure(std::move(remove), std::move(on_removed)));
70}
71
Danil Chapovalove3927c52018-03-06 14:33:20 +010072void RtcpTransceiver::SetReadyToSend(bool ready) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020073 RTC_CHECK(rtcp_transceiver_);
74 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalove3927c52018-03-06 14:33:20 +010075 task_queue_->PostTask([ptr, ready] {
Danil Chapovalove3927c52018-03-06 14:33:20 +010076 ptr->SetReadyToSend(ready);
77 });
78}
79
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010080void RtcpTransceiver::ReceivePacket(rtc::CopyOnWriteBuffer packet) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020081 RTC_CHECK(rtcp_transceiver_);
82 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010083 int64_t now_us = rtc::TimeMicros();
84 task_queue_->PostTask([ptr, packet, now_us] {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010085 ptr->ReceivePacket(packet, now_us);
86 });
87}
88
89void RtcpTransceiver::SendCompoundPacket() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020090 RTC_CHECK(rtcp_transceiver_);
91 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010092 task_queue_->PostTask([ptr] {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010093 ptr->SendCompoundPacket();
94 });
95}
96
Danil Chapovalov1de4b622017-12-13 13:35:10 +010097void RtcpTransceiver::SetRemb(int64_t bitrate_bps,
98 std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020099 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100100 // TODO(danilchap): Replace with lambda with move capture when available.
101 struct SetRembClosure {
102 void operator()() {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100103 ptr->SetRemb(bitrate_bps, std::move(ssrcs));
104 }
105
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200106 RtcpTransceiverImpl* ptr;
Danil Chapovalov1de4b622017-12-13 13:35:10 +0100107 int64_t bitrate_bps;
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100108 std::vector<uint32_t> ssrcs;
109 };
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200110 task_queue_->PostTask(
111 SetRembClosure{rtcp_transceiver_.get(), bitrate_bps, std::move(ssrcs)});
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100112}
113
114void RtcpTransceiver::UnsetRemb() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200115 RTC_CHECK(rtcp_transceiver_);
116 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100117 task_queue_->PostTask([ptr] {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100118 ptr->UnsetRemb();
119 });
120}
121
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100122uint32_t RtcpTransceiver::SSRC() const {
123 return rtcp_transceiver_->sender_ssrc();
124}
125
126bool RtcpTransceiver::SendFeedbackPacket(
127 const rtcp::TransportFeedback& packet) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200128 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100129 struct Closure {
130 void operator()() {
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100131 ptr->SendRawPacket(raw_packet);
132 }
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200133 RtcpTransceiverImpl* ptr;
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100134 rtc::Buffer raw_packet;
135 };
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200136 task_queue_->PostTask(Closure{rtcp_transceiver_.get(), packet.Build()});
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100137 return true;
138}
139
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100140void RtcpTransceiver::SendNack(uint32_t ssrc,
141 std::vector<uint16_t> sequence_numbers) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200142 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100143 // TODO(danilchap): Replace with lambda with move capture when available.
144 struct Closure {
145 void operator()() {
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100146 ptr->SendNack(ssrc, std::move(sequence_numbers));
147 }
148
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200149 RtcpTransceiverImpl* ptr;
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100150 uint32_t ssrc;
151 std::vector<uint16_t> sequence_numbers;
152 };
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200153 task_queue_->PostTask(
154 Closure{rtcp_transceiver_.get(), ssrc, std::move(sequence_numbers)});
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100155}
156
Danil Chapovalov8d19e032017-11-28 19:53:33 +0100157void RtcpTransceiver::SendPictureLossIndication(uint32_t ssrc) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200158 RTC_CHECK(rtcp_transceiver_);
159 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
160 task_queue_->PostTask([ptr, ssrc] { ptr->SendPictureLossIndication(ssrc); });
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100161}
162
163void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200164 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100165 // TODO(danilchap): Replace with lambda with move capture when available.
166 struct Closure {
167 void operator()() {
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100168 ptr->SendFullIntraRequest(ssrcs);
169 }
170
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