blob: 41fa5e6206eef160fc5e3774d23555d091bf3c8e [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>
Per Kjellander16999812019-10-10 12:57:28 +020015#include <vector>
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010016
Paul Hallakfe3dd512021-05-21 18:08:04 +020017#include "api/units/timestamp.h"
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +010018#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010019#include "rtc_base/checks.h"
20#include "rtc_base/event.h"
Danil Chapovalov1aa75812019-03-05 11:11:35 +010021#include "rtc_base/task_utils/to_queued_task.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "rtc_base/time_utils.h"
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010023
24namespace webrtc {
25
26RtcpTransceiver::RtcpTransceiver(const RtcpTransceiverConfig& config)
Paul Hallakfe3dd512021-05-21 18:08:04 +020027 : clock_(config.clock),
28 task_queue_(config.task_queue),
Mirko Bonadei317a1f02019-09-17 17:06:18 +020029 rtcp_transceiver_(std::make_unique<RtcpTransceiverImpl>(config)) {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010030 RTC_DCHECK(task_queue_);
31}
32
33RtcpTransceiver::~RtcpTransceiver() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020034 if (!rtcp_transceiver_)
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010035 return;
Danil Chapovalov3d164742019-09-16 18:57:57 +020036 auto rtcp_transceiver = std::move(rtcp_transceiver_);
Danil Chapovalovf351cff2020-03-05 15:43:24 +010037 task_queue_->PostTask(
38 ToQueuedTask([rtcp_transceiver = std::move(rtcp_transceiver)] {
39 rtcp_transceiver->StopPeriodicTask();
40 }));
Danil Chapovalov792df6b2018-09-07 13:03:32 +020041 RTC_DCHECK(!rtcp_transceiver_);
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010042}
43
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020044void RtcpTransceiver::Stop(std::function<void()> on_destroyed) {
45 RTC_DCHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +020046 auto rtcp_transceiver = std::move(rtcp_transceiver_);
47 task_queue_->PostTask(ToQueuedTask(
48 [rtcp_transceiver = std::move(rtcp_transceiver)] {
49 rtcp_transceiver->StopPeriodicTask();
50 },
51 std::move(on_destroyed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020052 RTC_DCHECK(!rtcp_transceiver_);
53}
54
Danil Chapovalova32d7102017-12-14 17:28:27 +010055void RtcpTransceiver::AddMediaReceiverRtcpObserver(
56 uint32_t remote_ssrc,
57 MediaReceiverRtcpObserver* observer) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020058 RTC_CHECK(rtcp_transceiver_);
59 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +010060 task_queue_->PostTask(ToQueuedTask([ptr, remote_ssrc, observer] {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020061 ptr->AddMediaReceiverRtcpObserver(remote_ssrc, observer);
Danil Chapovalovf351cff2020-03-05 15:43:24 +010062 }));
Danil Chapovalova32d7102017-12-14 17:28:27 +010063}
64
65void RtcpTransceiver::RemoveMediaReceiverRtcpObserver(
66 uint32_t remote_ssrc,
67 MediaReceiverRtcpObserver* observer,
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020068 std::function<void()> on_removed) {
69 RTC_CHECK(rtcp_transceiver_);
70 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
71 auto remove = [ptr, remote_ssrc, observer] {
72 ptr->RemoveMediaReceiverRtcpObserver(remote_ssrc, observer);
73 };
Danil Chapovalov1aa75812019-03-05 11:11:35 +010074 task_queue_->PostTask(ToQueuedTask(std::move(remove), std::move(on_removed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020075}
76
Danil Chapovalove3927c52018-03-06 14:33:20 +010077void RtcpTransceiver::SetReadyToSend(bool ready) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020078 RTC_CHECK(rtcp_transceiver_);
79 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +010080 task_queue_->PostTask(
81 ToQueuedTask([ptr, ready] { ptr->SetReadyToSend(ready); }));
Danil Chapovalove3927c52018-03-06 14:33:20 +010082}
83
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010084void RtcpTransceiver::ReceivePacket(rtc::CopyOnWriteBuffer packet) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020085 RTC_CHECK(rtcp_transceiver_);
86 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Paul Hallakfe3dd512021-05-21 18:08:04 +020087 Timestamp now = clock_->CurrentTime();
88 task_queue_->PostTask(
89 ToQueuedTask([ptr, packet, now] { ptr->ReceivePacket(packet, now); }));
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010090}
91
92void RtcpTransceiver::SendCompoundPacket() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020093 RTC_CHECK(rtcp_transceiver_);
94 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +010095 task_queue_->PostTask(ToQueuedTask([ptr] { ptr->SendCompoundPacket(); }));
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010096}
97
Danil Chapovalov1de4b622017-12-13 13:35:10 +010098void RtcpTransceiver::SetRemb(int64_t bitrate_bps,
99 std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200100 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200101 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100102 task_queue_->PostTask(
103 ToQueuedTask([ptr, bitrate_bps, ssrcs = std::move(ssrcs)]() mutable {
104 ptr->SetRemb(bitrate_bps, std::move(ssrcs));
105 }));
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100106}
107
108void RtcpTransceiver::UnsetRemb() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200109 RTC_CHECK(rtcp_transceiver_);
110 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100111 task_queue_->PostTask(ToQueuedTask([ptr] { ptr->UnsetRemb(); }));
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100112}
113
Per Kjellander16999812019-10-10 12:57:28 +0200114void RtcpTransceiver::SendCombinedRtcpPacket(
115 std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) {
116 RTC_CHECK(rtcp_transceiver_);
117 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
118 task_queue_->PostTask(
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100119 ToQueuedTask([ptr, rtcp_packets = std::move(rtcp_packets)]() mutable {
Per Kjellander16999812019-10-10 12:57:28 +0200120 ptr->SendCombinedRtcpPacket(std::move(rtcp_packets));
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100121 }));
Per Kjellander16999812019-10-10 12:57:28 +0200122}
123
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100124void RtcpTransceiver::SendNack(uint32_t ssrc,
125 std::vector<uint16_t> sequence_numbers) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200126 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200127 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100128 task_queue_->PostTask(ToQueuedTask(
Danil Chapovalov3d164742019-09-16 18:57:57 +0200129 [ptr, ssrc, sequence_numbers = std::move(sequence_numbers)]() mutable {
130 ptr->SendNack(ssrc, std::move(sequence_numbers));
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100131 }));
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100132}
133
Danil Chapovalov8d19e032017-11-28 19:53:33 +0100134void RtcpTransceiver::SendPictureLossIndication(uint32_t ssrc) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200135 RTC_CHECK(rtcp_transceiver_);
136 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100137 task_queue_->PostTask(
138 ToQueuedTask([ptr, ssrc] { ptr->SendPictureLossIndication(ssrc); }));
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100139}
140
141void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs) {
Evan Shrubsole577b88d2019-12-04 13:50:28 +0100142 return SendFullIntraRequest(std::move(ssrcs), true);
143}
144
145void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs,
146 bool new_request) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200147 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200148 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf351cff2020-03-05 15:43:24 +0100149 task_queue_->PostTask(
150 ToQueuedTask([ptr, ssrcs = std::move(ssrcs), new_request] {
151 ptr->SendFullIntraRequest(ssrcs, new_request);
152 }));
Danil Chapovalova7e418c2017-11-21 11:08:53 +0100153}
154
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100155} // namespace webrtc