blob: 52b2a683ce44d58f14836c681a8f19c5913ed498 [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
15#include "rtc_base/checks.h"
16#include "rtc_base/event.h"
17#include "rtc_base/ptr_util.h"
18#include "rtc_base/timeutils.h"
19
20namespace webrtc {
21
22RtcpTransceiver::RtcpTransceiver(const RtcpTransceiverConfig& config)
23 : task_queue_(config.task_queue),
24 rtcp_transceiver_(rtc::MakeUnique<RtcpTransceiverImpl>(config)),
25 ptr_factory_(rtcp_transceiver_.get()),
26 // Creating first weak ptr can be done on any thread, but is not
27 // thread-safe, thus do it at construction. Creating second (e.g. making a
28 // copy) is thread-safe.
29 ptr_(ptr_factory_.GetWeakPtr()) {
30 RTC_DCHECK(task_queue_);
31}
32
33RtcpTransceiver::~RtcpTransceiver() {
34 if (task_queue_->IsCurrent())
35 return;
36
37 rtc::Event done(false, false);
38 // TODO(danilchap): Merge cleanup into main closure when task queue does not
39 // silently drop tasks.
40 task_queue_->PostTask(rtc::NewClosure(
41 [this] {
42 // Destructor steps that has to run on the task_queue_.
43 ptr_factory_.InvalidateWeakPtrs();
44 rtcp_transceiver_.reset();
45 },
46 /*cleanup=*/[&done] { done.Set(); }));
47 // Wait until destruction is complete to be sure weak pointers invalidated and
48 // rtcp_transceiver destroyed on the queue while |this| still valid.
49 done.Wait(rtc::Event::kForever);
50 RTC_CHECK(!rtcp_transceiver_) << "Task queue is too busy to handle rtcp";
51}
52
53void RtcpTransceiver::ReceivePacket(rtc::CopyOnWriteBuffer packet) {
54 rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
55 int64_t now_us = rtc::TimeMicros();
56 task_queue_->PostTask([ptr, packet, now_us] {
57 if (ptr)
58 ptr->ReceivePacket(packet, now_us);
59 });
60}
61
62void RtcpTransceiver::SendCompoundPacket() {
63 rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
64 task_queue_->PostTask([ptr] {
65 if (ptr)
66 ptr->SendCompoundPacket();
67 });
68}
69
Danil Chapovalov1de4b622017-12-13 13:35:10 +010070void RtcpTransceiver::SetRemb(int64_t bitrate_bps,
71 std::vector<uint32_t> ssrcs) {
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010072 // TODO(danilchap): Replace with lambda with move capture when available.
73 struct SetRembClosure {
74 void operator()() {
75 if (ptr)
76 ptr->SetRemb(bitrate_bps, std::move(ssrcs));
77 }
78
79 rtc::WeakPtr<RtcpTransceiverImpl> ptr;
Danil Chapovalov1de4b622017-12-13 13:35:10 +010080 int64_t bitrate_bps;
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +010081 std::vector<uint32_t> ssrcs;
82 };
83 task_queue_->PostTask(SetRembClosure{ptr_, bitrate_bps, std::move(ssrcs)});
84}
85
86void RtcpTransceiver::UnsetRemb() {
87 rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
88 task_queue_->PostTask([ptr] {
89 if (ptr)
90 ptr->UnsetRemb();
91 });
92}
93
Danil Chapovalov327c43c2017-11-27 17:23:04 +010094void RtcpTransceiver::SendNack(uint32_t ssrc,
95 std::vector<uint16_t> sequence_numbers) {
96 // TODO(danilchap): Replace with lambda with move capture when available.
97 struct Closure {
98 void operator()() {
99 if (ptr)
100 ptr->SendNack(ssrc, std::move(sequence_numbers));
101 }
102
103 rtc::WeakPtr<RtcpTransceiverImpl> ptr;
104 uint32_t ssrc;
105 std::vector<uint16_t> sequence_numbers;
106 };
107 task_queue_->PostTask(Closure{ptr_, ssrc, std::move(sequence_numbers)});
108}
109
Danil Chapovalov8d19e032017-11-28 19:53:33 +0100110void RtcpTransceiver::SendPictureLossIndication(uint32_t ssrc) {
111 rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
112 task_queue_->PostTask([ptr, ssrc] {
113 if (ptr)
114 ptr->SendPictureLossIndication(ssrc);
115 });
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100116}
117
118void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs) {
119 // TODO(danilchap): Replace with lambda with move capture when available.
120 struct Closure {
121 void operator()() {
122 if (ptr)
123 ptr->SendFullIntraRequest(ssrcs);
124 }
125
126 rtc::WeakPtr<RtcpTransceiverImpl> ptr;
127 std::vector<uint32_t> ssrcs;
128 };
129 task_queue_->PostTask(Closure{ptr_, std::move(ssrcs)});
Danil Chapovalova7e418c2017-11-21 11:08:53 +0100130}
131
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100132} // namespace webrtc