Move implementation of LoopbackMediaTransport to .cc file
Needed for coming cls to be able to use rtc_base/timeutils.h, which shouldn't be included by api/ headers. Bug: webrtc:9719 Change-Id: Ia36c0a9218ad505e1eb4f2d9c26d44d5673c2632 Reviewed-on: https://webrtc-review.googlesource.com/c/112580 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25855}
This commit is contained in:
parent
b939d35e8e
commit
e0446cb80c
@ -648,6 +648,7 @@ if (rtc_include_tests) {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"test/loopback_media_transport.cc",
|
||||
"test/loopback_media_transport.h",
|
||||
]
|
||||
|
||||
@ -655,6 +656,7 @@ if (rtc_include_tests) {
|
||||
":libjingle_peerconnection_api",
|
||||
"../rtc_base:checks",
|
||||
"../rtc_base:rtc_base",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@ -124,6 +124,7 @@ void MediaTransportEncodedVideoFrame::Retain() {
|
||||
}
|
||||
|
||||
SendDataParams::SendDataParams() = default;
|
||||
SendDataParams::SendDataParams(const SendDataParams&) = default;
|
||||
|
||||
RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
|
||||
MediaTransportFactory::CreateMediaTransport(
|
||||
|
||||
@ -268,6 +268,7 @@ enum class DataMessageType {
|
||||
// unreliable delivery.
|
||||
struct SendDataParams {
|
||||
SendDataParams();
|
||||
SendDataParams(const SendDataParams&);
|
||||
|
||||
DataMessageType type = DataMessageType::kText;
|
||||
|
||||
|
||||
263
api/test/loopback_media_transport.cc
Normal file
263
api/test/loopback_media_transport.cc
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright 2018 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/test/loopback_media_transport.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
// Wrapper used to hand out unique_ptrs to loopback media transports without
|
||||
// ownership changes.
|
||||
class WrapperMediaTransport : public MediaTransportInterface {
|
||||
public:
|
||||
explicit WrapperMediaTransport(MediaTransportInterface* wrapped)
|
||||
: wrapped_(wrapped) {}
|
||||
|
||||
RTCError SendAudioFrame(uint64_t channel_id,
|
||||
MediaTransportEncodedAudioFrame frame) override {
|
||||
return wrapped_->SendAudioFrame(channel_id, std::move(frame));
|
||||
}
|
||||
|
||||
RTCError SendVideoFrame(
|
||||
uint64_t channel_id,
|
||||
const MediaTransportEncodedVideoFrame& frame) override {
|
||||
return wrapped_->SendVideoFrame(channel_id, frame);
|
||||
}
|
||||
|
||||
RTCError RequestKeyFrame(uint64_t channel_id) override {
|
||||
return wrapped_->RequestKeyFrame(channel_id);
|
||||
}
|
||||
|
||||
void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
|
||||
wrapped_->SetReceiveAudioSink(sink);
|
||||
}
|
||||
|
||||
void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {
|
||||
wrapped_->SetReceiveVideoSink(sink);
|
||||
}
|
||||
|
||||
void SetMediaTransportStateCallback(
|
||||
MediaTransportStateCallback* callback) override {
|
||||
wrapped_->SetMediaTransportStateCallback(callback);
|
||||
}
|
||||
|
||||
RTCError SendData(int channel_id,
|
||||
const SendDataParams& params,
|
||||
const rtc::CopyOnWriteBuffer& buffer) override {
|
||||
return wrapped_->SendData(channel_id, params, buffer);
|
||||
}
|
||||
|
||||
RTCError CloseChannel(int channel_id) override {
|
||||
return wrapped_->CloseChannel(channel_id);
|
||||
}
|
||||
|
||||
void SetDataSink(DataChannelSink* sink) override {
|
||||
wrapped_->SetDataSink(sink);
|
||||
}
|
||||
|
||||
private:
|
||||
MediaTransportInterface* wrapped_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
WrapperMediaTransportFactory::WrapperMediaTransportFactory(
|
||||
MediaTransportInterface* wrapped)
|
||||
: wrapped_(wrapped) {}
|
||||
|
||||
RTCErrorOr<std::unique_ptr<MediaTransportInterface>>
|
||||
WrapperMediaTransportFactory::CreateMediaTransport(
|
||||
rtc::PacketTransportInternal* packet_transport,
|
||||
rtc::Thread* network_thread,
|
||||
const MediaTransportSettings& settings) {
|
||||
return {absl::make_unique<WrapperMediaTransport>(wrapped_)};
|
||||
}
|
||||
|
||||
MediaTransportPair::LoopbackMediaTransport::LoopbackMediaTransport(
|
||||
rtc::Thread* thread,
|
||||
LoopbackMediaTransport* other)
|
||||
: thread_(thread), other_(other) {}
|
||||
|
||||
MediaTransportPair::LoopbackMediaTransport::~LoopbackMediaTransport() {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
RTC_CHECK(audio_sink_ == nullptr);
|
||||
RTC_CHECK(video_sink_ == nullptr);
|
||||
RTC_CHECK(data_sink_ == nullptr);
|
||||
}
|
||||
|
||||
RTCError MediaTransportPair::LoopbackMediaTransport::SendAudioFrame(
|
||||
uint64_t channel_id,
|
||||
MediaTransportEncodedAudioFrame frame) {
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.sent_audio_frames;
|
||||
}
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id, frame] {
|
||||
other_->OnData(channel_id, std::move(frame));
|
||||
});
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
RTCError MediaTransportPair::LoopbackMediaTransport::SendVideoFrame(
|
||||
uint64_t channel_id,
|
||||
const MediaTransportEncodedVideoFrame& frame) {
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.sent_video_frames;
|
||||
}
|
||||
// Ensure that we own the referenced data.
|
||||
MediaTransportEncodedVideoFrame frame_copy = frame;
|
||||
frame_copy.Retain();
|
||||
invoker_.AsyncInvoke<void>(
|
||||
RTC_FROM_HERE, thread_, [this, channel_id, frame_copy] {
|
||||
other_->OnData(channel_id, std::move(frame_copy));
|
||||
});
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
RTCError MediaTransportPair::LoopbackMediaTransport::RequestKeyFrame(
|
||||
uint64_t channel_id) {
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::SetReceiveAudioSink(
|
||||
MediaTransportAudioSinkInterface* sink) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (sink) {
|
||||
RTC_CHECK(audio_sink_ == nullptr);
|
||||
}
|
||||
audio_sink_ = sink;
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::SetReceiveVideoSink(
|
||||
MediaTransportVideoSinkInterface* sink) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (sink) {
|
||||
RTC_CHECK(video_sink_ == nullptr);
|
||||
}
|
||||
video_sink_ = sink;
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::SetMediaTransportStateCallback(
|
||||
MediaTransportStateCallback* callback) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
state_callback_ = callback;
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
|
||||
RTC_DCHECK_RUN_ON(thread_);
|
||||
OnStateChanged();
|
||||
});
|
||||
}
|
||||
|
||||
RTCError MediaTransportPair::LoopbackMediaTransport::SendData(
|
||||
int channel_id,
|
||||
const SendDataParams& params,
|
||||
const rtc::CopyOnWriteBuffer& buffer) {
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
|
||||
[this, channel_id, params, buffer] {
|
||||
other_->OnData(channel_id, params.type, buffer);
|
||||
});
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
RTCError MediaTransportPair::LoopbackMediaTransport::CloseChannel(
|
||||
int channel_id) {
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
|
||||
other_->OnRemoteCloseChannel(channel_id);
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (data_sink_) {
|
||||
data_sink_->OnChannelClosed(channel_id);
|
||||
}
|
||||
});
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::SetDataSink(
|
||||
DataChannelSink* sink) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
data_sink_ = sink;
|
||||
}
|
||||
void MediaTransportPair::LoopbackMediaTransport::SetState(
|
||||
MediaTransportState state) {
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
|
||||
RTC_DCHECK_RUN_ON(thread_);
|
||||
state_ = state;
|
||||
OnStateChanged();
|
||||
});
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::FlushAsyncInvokes() {
|
||||
invoker_.Flush(thread_);
|
||||
}
|
||||
|
||||
MediaTransportPair::Stats
|
||||
MediaTransportPair::LoopbackMediaTransport::GetStats() {
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
return stats_;
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::OnData(
|
||||
uint64_t channel_id,
|
||||
MediaTransportEncodedAudioFrame frame) {
|
||||
{
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (audio_sink_) {
|
||||
audio_sink_->OnData(channel_id, frame);
|
||||
}
|
||||
}
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.received_audio_frames;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::OnData(
|
||||
uint64_t channel_id,
|
||||
MediaTransportEncodedVideoFrame frame) {
|
||||
{
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (video_sink_) {
|
||||
video_sink_->OnData(channel_id, frame);
|
||||
}
|
||||
}
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.received_video_frames;
|
||||
}
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::OnData(
|
||||
int channel_id,
|
||||
DataMessageType type,
|
||||
const rtc::CopyOnWriteBuffer& buffer) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (data_sink_) {
|
||||
data_sink_->OnDataReceived(channel_id, type, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::OnRemoteCloseChannel(
|
||||
int channel_id) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (data_sink_) {
|
||||
data_sink_->OnChannelClosing(channel_id);
|
||||
data_sink_->OnChannelClosed(channel_id);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaTransportPair::LoopbackMediaTransport::OnStateChanged() {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (state_callback_) {
|
||||
state_callback_->OnStateChanged(state_);
|
||||
}
|
||||
}
|
||||
} // namespace webrtc
|
||||
@ -23,69 +23,15 @@
|
||||
namespace webrtc {
|
||||
|
||||
// Wrapper used to hand out unique_ptrs to loopback media transports without
|
||||
// ownership changes.
|
||||
class WrapperMediaTransport : public MediaTransportInterface {
|
||||
public:
|
||||
explicit WrapperMediaTransport(MediaTransportInterface* wrapped)
|
||||
: wrapped_(wrapped) {}
|
||||
|
||||
RTCError SendAudioFrame(uint64_t channel_id,
|
||||
MediaTransportEncodedAudioFrame frame) override {
|
||||
return wrapped_->SendAudioFrame(channel_id, std::move(frame));
|
||||
}
|
||||
|
||||
RTCError SendVideoFrame(
|
||||
uint64_t channel_id,
|
||||
const MediaTransportEncodedVideoFrame& frame) override {
|
||||
return wrapped_->SendVideoFrame(channel_id, frame);
|
||||
}
|
||||
|
||||
RTCError RequestKeyFrame(uint64_t channel_id) override {
|
||||
return wrapped_->RequestKeyFrame(channel_id);
|
||||
}
|
||||
|
||||
void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
|
||||
wrapped_->SetReceiveAudioSink(sink);
|
||||
}
|
||||
|
||||
void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {
|
||||
wrapped_->SetReceiveVideoSink(sink);
|
||||
}
|
||||
|
||||
void SetMediaTransportStateCallback(
|
||||
MediaTransportStateCallback* callback) override {
|
||||
wrapped_->SetMediaTransportStateCallback(callback);
|
||||
}
|
||||
|
||||
RTCError SendData(int channel_id,
|
||||
const SendDataParams& params,
|
||||
const rtc::CopyOnWriteBuffer& buffer) override {
|
||||
return wrapped_->SendData(channel_id, params, buffer);
|
||||
}
|
||||
|
||||
RTCError CloseChannel(int channel_id) override {
|
||||
return wrapped_->CloseChannel(channel_id);
|
||||
}
|
||||
|
||||
void SetDataSink(DataChannelSink* sink) override {
|
||||
wrapped_->SetDataSink(sink);
|
||||
}
|
||||
|
||||
private:
|
||||
MediaTransportInterface* wrapped_;
|
||||
};
|
||||
|
||||
// ownership changes to the underlying transport.
|
||||
class WrapperMediaTransportFactory : public MediaTransportFactory {
|
||||
public:
|
||||
explicit WrapperMediaTransportFactory(MediaTransportInterface* wrapped)
|
||||
: wrapped_(wrapped) {}
|
||||
explicit WrapperMediaTransportFactory(MediaTransportInterface* wrapped);
|
||||
|
||||
RTCErrorOr<std::unique_ptr<MediaTransportInterface>> CreateMediaTransport(
|
||||
rtc::PacketTransportInternal* packet_transport,
|
||||
rtc::Thread* network_thread,
|
||||
const MediaTransportSettings& settings) override {
|
||||
return {absl::make_unique<WrapperMediaTransport>(wrapped_)};
|
||||
}
|
||||
const MediaTransportSettings& settings) override;
|
||||
|
||||
private:
|
||||
MediaTransportInterface* wrapped_;
|
||||
@ -133,167 +79,52 @@ class MediaTransportPair {
|
||||
private:
|
||||
class LoopbackMediaTransport : public MediaTransportInterface {
|
||||
public:
|
||||
LoopbackMediaTransport(rtc::Thread* thread, LoopbackMediaTransport* other)
|
||||
: thread_(thread), other_(other) {}
|
||||
LoopbackMediaTransport(rtc::Thread* thread, LoopbackMediaTransport* other);
|
||||
|
||||
~LoopbackMediaTransport() {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
RTC_CHECK(audio_sink_ == nullptr);
|
||||
RTC_CHECK(video_sink_ == nullptr);
|
||||
RTC_CHECK(data_sink_ == nullptr);
|
||||
}
|
||||
~LoopbackMediaTransport() override;
|
||||
|
||||
RTCError SendAudioFrame(uint64_t channel_id,
|
||||
MediaTransportEncodedAudioFrame frame) override {
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.sent_audio_frames;
|
||||
}
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_,
|
||||
[this, channel_id, frame] {
|
||||
other_->OnData(channel_id, std::move(frame));
|
||||
});
|
||||
return RTCError::OK();
|
||||
};
|
||||
MediaTransportEncodedAudioFrame frame) override;
|
||||
|
||||
RTCError SendVideoFrame(
|
||||
uint64_t channel_id,
|
||||
const MediaTransportEncodedVideoFrame& frame) override {
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.sent_video_frames;
|
||||
}
|
||||
// Ensure that we own the referenced data.
|
||||
MediaTransportEncodedVideoFrame frame_copy = frame;
|
||||
frame_copy.Retain();
|
||||
invoker_.AsyncInvoke<void>(
|
||||
RTC_FROM_HERE, thread_, [this, channel_id, frame_copy] {
|
||||
other_->OnData(channel_id, std::move(frame_copy));
|
||||
});
|
||||
return RTCError::OK();
|
||||
}
|
||||
const MediaTransportEncodedVideoFrame& frame) override;
|
||||
|
||||
RTCError RequestKeyFrame(uint64_t channel_id) override {
|
||||
return RTCError::OK();
|
||||
}
|
||||
RTCError RequestKeyFrame(uint64_t channel_id) override;
|
||||
|
||||
void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (sink) {
|
||||
RTC_CHECK(audio_sink_ == nullptr);
|
||||
}
|
||||
audio_sink_ = sink;
|
||||
}
|
||||
void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override;
|
||||
|
||||
void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (sink) {
|
||||
RTC_CHECK(video_sink_ == nullptr);
|
||||
}
|
||||
video_sink_ = sink;
|
||||
}
|
||||
void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override;
|
||||
|
||||
void SetMediaTransportStateCallback(
|
||||
MediaTransportStateCallback* callback) override {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
state_callback_ = callback;
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this] {
|
||||
RTC_DCHECK_RUN_ON(thread_);
|
||||
OnStateChanged();
|
||||
});
|
||||
}
|
||||
MediaTransportStateCallback* callback) override;
|
||||
|
||||
RTCError SendData(int channel_id,
|
||||
const SendDataParams& params,
|
||||
const rtc::CopyOnWriteBuffer& buffer) override {
|
||||
invoker_.AsyncInvoke<void>(
|
||||
RTC_FROM_HERE, thread_, [this, channel_id, params, buffer] {
|
||||
other_->OnData(channel_id, params.type, buffer);
|
||||
});
|
||||
return RTCError::OK();
|
||||
}
|
||||
const rtc::CopyOnWriteBuffer& buffer) override;
|
||||
|
||||
RTCError CloseChannel(int channel_id) override {
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, channel_id] {
|
||||
other_->OnRemoteCloseChannel(channel_id);
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (data_sink_) {
|
||||
data_sink_->OnChannelClosed(channel_id);
|
||||
}
|
||||
});
|
||||
return RTCError::OK();
|
||||
}
|
||||
RTCError CloseChannel(int channel_id) override;
|
||||
|
||||
void SetDataSink(DataChannelSink* sink) override {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
data_sink_ = sink;
|
||||
}
|
||||
void SetDataSink(DataChannelSink* sink) override;
|
||||
|
||||
void SetState(MediaTransportState state) {
|
||||
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, thread_, [this, state] {
|
||||
RTC_DCHECK_RUN_ON(thread_);
|
||||
state_ = state;
|
||||
OnStateChanged();
|
||||
});
|
||||
}
|
||||
void SetState(MediaTransportState state);
|
||||
|
||||
void FlushAsyncInvokes() { invoker_.Flush(thread_); }
|
||||
void FlushAsyncInvokes();
|
||||
|
||||
Stats GetStats() {
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
return stats_;
|
||||
}
|
||||
Stats GetStats();
|
||||
|
||||
private:
|
||||
void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame) {
|
||||
{
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (audio_sink_) {
|
||||
audio_sink_->OnData(channel_id, frame);
|
||||
}
|
||||
}
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.received_audio_frames;
|
||||
}
|
||||
}
|
||||
void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame);
|
||||
|
||||
void OnData(uint64_t channel_id, MediaTransportEncodedVideoFrame frame) {
|
||||
{
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (video_sink_) {
|
||||
video_sink_->OnData(channel_id, frame);
|
||||
}
|
||||
}
|
||||
{
|
||||
rtc::CritScope lock(&stats_lock_);
|
||||
++stats_.received_video_frames;
|
||||
}
|
||||
}
|
||||
void OnData(uint64_t channel_id, MediaTransportEncodedVideoFrame frame);
|
||||
|
||||
void OnData(int channel_id,
|
||||
DataMessageType type,
|
||||
const rtc::CopyOnWriteBuffer& buffer) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (data_sink_) {
|
||||
data_sink_->OnDataReceived(channel_id, type, buffer);
|
||||
}
|
||||
}
|
||||
const rtc::CopyOnWriteBuffer& buffer);
|
||||
|
||||
void OnRemoteCloseChannel(int channel_id) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (data_sink_) {
|
||||
data_sink_->OnChannelClosing(channel_id);
|
||||
data_sink_->OnChannelClosed(channel_id);
|
||||
}
|
||||
}
|
||||
void OnRemoteCloseChannel(int channel_id);
|
||||
|
||||
void OnStateChanged() RTC_RUN_ON(thread_) {
|
||||
rtc::CritScope lock(&sink_lock_);
|
||||
if (state_callback_) {
|
||||
state_callback_->OnStateChanged(state_);
|
||||
}
|
||||
}
|
||||
void OnStateChanged() RTC_RUN_ON(thread_);
|
||||
|
||||
rtc::Thread* const thread_;
|
||||
rtc::CriticalSection sink_lock_;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user