blob: a5dd8dc9412d251a52de4d1b13d743d1f9399ed8 [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
70void RtcpTransceiver::SetRemb(int bitrate_bps, std::vector<uint32_t> ssrcs) {
71 // TODO(danilchap): Replace with lambda with move capture when available.
72 struct SetRembClosure {
73 void operator()() {
74 if (ptr)
75 ptr->SetRemb(bitrate_bps, std::move(ssrcs));
76 }
77
78 rtc::WeakPtr<RtcpTransceiverImpl> ptr;
79 int bitrate_bps;
80 std::vector<uint32_t> ssrcs;
81 };
82 task_queue_->PostTask(SetRembClosure{ptr_, bitrate_bps, std::move(ssrcs)});
83}
84
85void RtcpTransceiver::UnsetRemb() {
86 rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
87 task_queue_->PostTask([ptr] {
88 if (ptr)
89 ptr->UnsetRemb();
90 });
91}
92
Danil Chapovalov327c43c2017-11-27 17:23:04 +010093void RtcpTransceiver::SendNack(uint32_t ssrc,
94 std::vector<uint16_t> sequence_numbers) {
95 // TODO(danilchap): Replace with lambda with move capture when available.
96 struct Closure {
97 void operator()() {
98 if (ptr)
99 ptr->SendNack(ssrc, std::move(sequence_numbers));
100 }
101
102 rtc::WeakPtr<RtcpTransceiverImpl> ptr;
103 uint32_t ssrc;
104 std::vector<uint16_t> sequence_numbers;
105 };
106 task_queue_->PostTask(Closure{ptr_, ssrc, std::move(sequence_numbers)});
107}
108
Danil Chapovalov8d19e032017-11-28 19:53:33 +0100109void RtcpTransceiver::SendPictureLossIndication(uint32_t ssrc) {
110 rtc::WeakPtr<RtcpTransceiverImpl> ptr = ptr_;
111 task_queue_->PostTask([ptr, ssrc] {
112 if (ptr)
113 ptr->SendPictureLossIndication(ssrc);
114 });
Danil Chapovalov2ddf98d2017-11-22 14:00:41 +0100115}
116
117void RtcpTransceiver::SendFullIntraRequest(std::vector<uint32_t> ssrcs) {
118 // TODO(danilchap): Replace with lambda with move capture when available.
119 struct Closure {
120 void operator()() {
121 if (ptr)
122 ptr->SendFullIntraRequest(ssrcs);
123 }
124
125 rtc::WeakPtr<RtcpTransceiverImpl> ptr;
126 std::vector<uint32_t> ssrcs;
127 };
128 task_queue_->PostTask(Closure{ptr_, std::move(ssrcs)});
Danil Chapovalova7e418c2017-11-21 11:08:53 +0100129}
130
Danil Chapovalovc0fd5f92017-11-16 14:35:32 +0100131} // namespace webrtc