blob: 4538301c2aaddd51a10c036ae24962563233f4f3 [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
Mirko Bonadei317a1f02019-09-17 17:06:18 +020013#include <memory>
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010014#include <utility>
15
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 {
23
24RtcpTransceiver::RtcpTransceiver(const RtcpTransceiverConfig& config)
25 : task_queue_(config.task_queue),
Mirko Bonadei317a1f02019-09-17 17:06:18 +020026 rtcp_transceiver_(std::make_unique<RtcpTransceiverImpl>(config)) {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010027 RTC_DCHECK(task_queue_);
28}
29
30RtcpTransceiver::~RtcpTransceiver() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020031 if (!rtcp_transceiver_)
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010032 return;
Danil Chapovalov3d164742019-09-16 18:57:57 +020033 auto rtcp_transceiver = std::move(rtcp_transceiver_);
34 task_queue_->PostTask([rtcp_transceiver = std::move(rtcp_transceiver)] {
35 rtcp_transceiver->StopPeriodicTask();
36 });
Danil Chapovalov792df6b2018-09-07 13:03:32 +020037 RTC_DCHECK(!rtcp_transceiver_);
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010038}
39
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020040void RtcpTransceiver::Stop(std::function<void()> on_destroyed) {
41 RTC_DCHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +020042 auto rtcp_transceiver = std::move(rtcp_transceiver_);
43 task_queue_->PostTask(ToQueuedTask(
44 [rtcp_transceiver = std::move(rtcp_transceiver)] {
45 rtcp_transceiver->StopPeriodicTask();
46 },
47 std::move(on_destroyed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020048 RTC_DCHECK(!rtcp_transceiver_);
49}
50
Danil Chapovalova32d7102017-12-14 17:28:27 +010051void RtcpTransceiver::AddMediaReceiverRtcpObserver(
52 uint32_t remote_ssrc,
53 MediaReceiverRtcpObserver* observer) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020054 RTC_CHECK(rtcp_transceiver_);
55 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalova32d7102017-12-14 17:28:27 +010056 task_queue_->PostTask([ptr, remote_ssrc, observer] {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020057 ptr->AddMediaReceiverRtcpObserver(remote_ssrc, observer);
Danil Chapovalova32d7102017-12-14 17:28:27 +010058 });
59}
60
61void RtcpTransceiver::RemoveMediaReceiverRtcpObserver(
62 uint32_t remote_ssrc,
63 MediaReceiverRtcpObserver* observer,
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020064 std::function<void()> on_removed) {
65 RTC_CHECK(rtcp_transceiver_);
66 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
67 auto remove = [ptr, remote_ssrc, observer] {
68 ptr->RemoveMediaReceiverRtcpObserver(remote_ssrc, observer);
69 };
Danil Chapovalov1aa75812019-03-05 11:11:35 +010070 task_queue_->PostTask(ToQueuedTask(std::move(remove), std::move(on_removed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020071}
72
Danil Chapovalove3927c52018-03-06 14:33:20 +010073void RtcpTransceiver::SetReadyToSend(bool ready) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020074 RTC_CHECK(rtcp_transceiver_);
75 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +020076 task_queue_->PostTask([ptr, ready] { ptr->SetReadyToSend(ready); });
Danil Chapovalove3927c52018-03-06 14:33:20 +010077}
78
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010079void RtcpTransceiver::ReceivePacket(rtc::CopyOnWriteBuffer packet) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020080 RTC_CHECK(rtcp_transceiver_);
81 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010082 int64_t now_us = rtc::TimeMicros();
Jonas Olssona4d87372019-07-05 19:08:33 +020083 task_queue_->PostTask(
84 [ptr, packet, now_us] { ptr->ReceivePacket(packet, now_us); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010085}
86
87void RtcpTransceiver::SendCompoundPacket() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020088 RTC_CHECK(rtcp_transceiver_);
89 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +020090 task_queue_->PostTask([ptr] { ptr->SendCompoundPacket(); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010091}
92
Danil Chapovalov1de4b622017-12-13 13:35:10 +010093void RtcpTransceiver::SetRemb(int64_t bitrate_bps,
94 std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020095 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +020096 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
97 task_queue_->PostTask([ptr, bitrate_bps, ssrcs = std::move(ssrcs)]() mutable {
98 ptr->SetRemb(bitrate_bps, std::move(ssrcs));
99 });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100100}
101
102void RtcpTransceiver::UnsetRemb() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200103 RTC_CHECK(rtcp_transceiver_);
104 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +0200105 task_queue_->PostTask([ptr] { ptr->UnsetRemb(); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100106}
107
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100108uint32_t RtcpTransceiver::SSRC() const {
109 return rtcp_transceiver_->sender_ssrc();
110}
111
112bool RtcpTransceiver::SendFeedbackPacket(
113 const rtcp::TransportFeedback& packet) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200114 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200115 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
116 rtc::Buffer raw_packet = packet.Build();
117 task_queue_->PostTask([ptr, raw_packet = std::move(raw_packet)] {
118 ptr->SendRawPacket(raw_packet);
119 });
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +0100120 return true;
121}
122
Sebastian Janssone1795f42019-07-24 11:38:03 +0200123bool RtcpTransceiver::SendNetworkStateEstimatePacket(
124 const rtcp::RemoteEstimate& packet) {
125 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200126 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
127 rtc::Buffer raw_packet = packet.Build();
128 task_queue_->PostTask([ptr, raw_packet = std::move(raw_packet)] {
129 ptr->SendRawPacket(raw_packet);
130 });
Sebastian Janssone1795f42019-07-24 11:38:03 +0200131 return true;
132}
133
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100134void RtcpTransceiver::SendNack(uint32_t ssrc,
135 std::vector<uint16_t> sequence_numbers) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200136 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200137 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200138 task_queue_->PostTask(
Danil Chapovalov3d164742019-09-16 18:57:57 +0200139 [ptr, ssrc, sequence_numbers = std::move(sequence_numbers)]() mutable {
140 ptr->SendNack(ssrc, std::move(sequence_numbers));
141 });
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100142}
143
Danil Chapovalov8d19e032017-11-28 19:53:33 +0100144void RtcpTransceiver::SendPictureLossIndication(uint32_t ssrc) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200145 RTC_CHECK(rtcp_transceiver_);
146 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
147 task_queue_->PostTask([ptr, ssrc] { ptr->SendPictureLossIndication(ssrc); });
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100148}
149
150void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200151 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200152 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
153 task_queue_->PostTask(
154 [ptr, ssrcs = std::move(ssrcs)] { ptr->SendFullIntraRequest(ssrcs); });
Danil Chapovalova7e418c2017-11-21 11:08:53 +0100155}
156
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100157} // namespace webrtc