blob: 7b1790de7bc4ba512a23ec3d78e060e24dc58326 [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
Danil Chapovalovd5cae4d2017-12-14 11:14:35 +010017#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010018#include "rtc_base/checks.h"
19#include "rtc_base/event.h"
Danil Chapovalov1aa75812019-03-05 11:11:35 +010020#include "rtc_base/task_utils/to_queued_task.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/time_utils.h"
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010022
23namespace webrtc {
24
25RtcpTransceiver::RtcpTransceiver(const RtcpTransceiverConfig& config)
26 : task_queue_(config.task_queue),
Mirko Bonadei317a1f02019-09-17 17:06:18 +020027 rtcp_transceiver_(std::make_unique<RtcpTransceiverImpl>(config)) {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010028 RTC_DCHECK(task_queue_);
29}
30
31RtcpTransceiver::~RtcpTransceiver() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020032 if (!rtcp_transceiver_)
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010033 return;
Danil Chapovalov3d164742019-09-16 18:57:57 +020034 auto rtcp_transceiver = std::move(rtcp_transceiver_);
35 task_queue_->PostTask([rtcp_transceiver = std::move(rtcp_transceiver)] {
36 rtcp_transceiver->StopPeriodicTask();
37 });
Danil Chapovalov792df6b2018-09-07 13:03:32 +020038 RTC_DCHECK(!rtcp_transceiver_);
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010039}
40
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020041void RtcpTransceiver::Stop(std::function<void()> on_destroyed) {
42 RTC_DCHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +020043 auto rtcp_transceiver = std::move(rtcp_transceiver_);
44 task_queue_->PostTask(ToQueuedTask(
45 [rtcp_transceiver = std::move(rtcp_transceiver)] {
46 rtcp_transceiver->StopPeriodicTask();
47 },
48 std::move(on_destroyed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020049 RTC_DCHECK(!rtcp_transceiver_);
50}
51
Danil Chapovalova32d7102017-12-14 17:28:27 +010052void RtcpTransceiver::AddMediaReceiverRtcpObserver(
53 uint32_t remote_ssrc,
54 MediaReceiverRtcpObserver* observer) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020055 RTC_CHECK(rtcp_transceiver_);
56 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalova32d7102017-12-14 17:28:27 +010057 task_queue_->PostTask([ptr, remote_ssrc, observer] {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020058 ptr->AddMediaReceiverRtcpObserver(remote_ssrc, observer);
Danil Chapovalova32d7102017-12-14 17:28:27 +010059 });
60}
61
62void RtcpTransceiver::RemoveMediaReceiverRtcpObserver(
63 uint32_t remote_ssrc,
64 MediaReceiverRtcpObserver* observer,
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020065 std::function<void()> on_removed) {
66 RTC_CHECK(rtcp_transceiver_);
67 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
68 auto remove = [ptr, remote_ssrc, observer] {
69 ptr->RemoveMediaReceiverRtcpObserver(remote_ssrc, observer);
70 };
Danil Chapovalov1aa75812019-03-05 11:11:35 +010071 task_queue_->PostTask(ToQueuedTask(std::move(remove), std::move(on_removed)));
Danil Chapovalov98f5f6c2018-10-22 14:22:31 +020072}
73
Danil Chapovalove3927c52018-03-06 14:33:20 +010074void RtcpTransceiver::SetReadyToSend(bool ready) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020075 RTC_CHECK(rtcp_transceiver_);
76 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +020077 task_queue_->PostTask([ptr, ready] { ptr->SetReadyToSend(ready); });
Danil Chapovalove3927c52018-03-06 14:33:20 +010078}
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();
Jonas Olssona4d87372019-07-05 19:08:33 +020084 task_queue_->PostTask(
85 [ptr, packet, now_us] { ptr->ReceivePacket(packet, now_us); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010086}
87
88void RtcpTransceiver::SendCompoundPacket() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020089 RTC_CHECK(rtcp_transceiver_);
90 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +020091 task_queue_->PostTask([ptr] { ptr->SendCompoundPacket(); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010092}
93
Danil Chapovalov1de4b622017-12-13 13:35:10 +010094void RtcpTransceiver::SetRemb(int64_t bitrate_bps,
95 std::vector<uint32_t> ssrcs) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +020096 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +020097 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
98 task_queue_->PostTask([ptr, bitrate_bps, ssrcs = std::move(ssrcs)]() mutable {
99 ptr->SetRemb(bitrate_bps, std::move(ssrcs));
100 });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100101}
102
103void RtcpTransceiver::UnsetRemb() {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200104 RTC_CHECK(rtcp_transceiver_);
105 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Jonas Olssona4d87372019-07-05 19:08:33 +0200106 task_queue_->PostTask([ptr] { ptr->UnsetRemb(); });
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100107}
108
Per Kjellander16999812019-10-10 12:57:28 +0200109void RtcpTransceiver::SendCombinedRtcpPacket(
110 std::vector<std::unique_ptr<rtcp::RtcpPacket>> rtcp_packets) {
111 RTC_CHECK(rtcp_transceiver_);
112 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
113 task_queue_->PostTask(
114 [ptr, rtcp_packets = std::move(rtcp_packets)]() mutable {
115 ptr->SendCombinedRtcpPacket(std::move(rtcp_packets));
116 });
117}
118
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100119void RtcpTransceiver::SendNack(uint32_t ssrc,
120 std::vector<uint16_t> sequence_numbers) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200121 RTC_CHECK(rtcp_transceiver_);
Danil Chapovalov3d164742019-09-16 18:57:57 +0200122 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200123 task_queue_->PostTask(
Danil Chapovalov3d164742019-09-16 18:57:57 +0200124 [ptr, ssrc, sequence_numbers = std::move(sequence_numbers)]() mutable {
125 ptr->SendNack(ssrc, std::move(sequence_numbers));
126 });
Danil Chapovalov327c43c2017-11-27 17:23:04 +0100127}
128
Danil Chapovalov8d19e032017-11-28 19:53:33 +0100129void RtcpTransceiver::SendPictureLossIndication(uint32_t ssrc) {
Danil Chapovalovf0076d32018-09-05 16:46:40 +0200130 RTC_CHECK(rtcp_transceiver_);
131 RtcpTransceiverImpl* ptr = rtcp_transceiver_.get();
132 task_queue_->PostTask([ptr, ssrc] { ptr->SendPictureLossIndication(ssrc); });
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100133}
134
135void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs) {
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();
138 task_queue_->PostTask(
139 [ptr, ssrcs = std::move(ssrcs)] { ptr->SendFullIntraRequest(ssrcs); });
Danil Chapovalova7e418c2017-11-21 11:08:53 +0100140}
141
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100142} // namespace webrtc