1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2011 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "pc/video_track.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <utility>
14*d9f75844SAndroid Build Coastguard Worker #include <vector>
15*d9f75844SAndroid Build Coastguard Worker
16*d9f75844SAndroid Build Coastguard Worker #include "api/notifier.h"
17*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
19*d9f75844SAndroid Build Coastguard Worker
20*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
21*d9f75844SAndroid Build Coastguard Worker
VideoTrack(absl::string_view label,rtc::scoped_refptr<VideoTrackSourceProxyWithInternal<VideoTrackSourceInterface>> source,rtc::Thread * worker_thread)22*d9f75844SAndroid Build Coastguard Worker VideoTrack::VideoTrack(
23*d9f75844SAndroid Build Coastguard Worker absl::string_view label,
24*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<
25*d9f75844SAndroid Build Coastguard Worker VideoTrackSourceProxyWithInternal<VideoTrackSourceInterface>> source,
26*d9f75844SAndroid Build Coastguard Worker rtc::Thread* worker_thread)
27*d9f75844SAndroid Build Coastguard Worker : MediaStreamTrack<VideoTrackInterface>(label),
28*d9f75844SAndroid Build Coastguard Worker worker_thread_(worker_thread),
29*d9f75844SAndroid Build Coastguard Worker video_source_(std::move(source)),
30*d9f75844SAndroid Build Coastguard Worker content_hint_(ContentHint::kNone) {
31*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&signaling_thread_);
32*d9f75844SAndroid Build Coastguard Worker // Detach the thread checker for VideoSourceBaseGuarded since we'll make calls
33*d9f75844SAndroid Build Coastguard Worker // to VideoSourceBaseGuarded on the worker thread, but we're currently on the
34*d9f75844SAndroid Build Coastguard Worker // signaling thread.
35*d9f75844SAndroid Build Coastguard Worker source_sequence_.Detach();
36*d9f75844SAndroid Build Coastguard Worker video_source_->RegisterObserver(this);
37*d9f75844SAndroid Build Coastguard Worker }
38*d9f75844SAndroid Build Coastguard Worker
~VideoTrack()39*d9f75844SAndroid Build Coastguard Worker VideoTrack::~VideoTrack() {
40*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&signaling_thread_);
41*d9f75844SAndroid Build Coastguard Worker video_source_->UnregisterObserver(this);
42*d9f75844SAndroid Build Coastguard Worker }
43*d9f75844SAndroid Build Coastguard Worker
kind() const44*d9f75844SAndroid Build Coastguard Worker std::string VideoTrack::kind() const {
45*d9f75844SAndroid Build Coastguard Worker return kVideoKind;
46*d9f75844SAndroid Build Coastguard Worker }
47*d9f75844SAndroid Build Coastguard Worker
48*d9f75844SAndroid Build Coastguard Worker // AddOrUpdateSink and RemoveSink should be called on the worker
49*d9f75844SAndroid Build Coastguard Worker // thread.
AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame> * sink,const rtc::VideoSinkWants & wants)50*d9f75844SAndroid Build Coastguard Worker void VideoTrack::AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
51*d9f75844SAndroid Build Coastguard Worker const rtc::VideoSinkWants& wants) {
52*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
53*d9f75844SAndroid Build Coastguard Worker VideoSourceBaseGuarded::AddOrUpdateSink(sink, wants);
54*d9f75844SAndroid Build Coastguard Worker rtc::VideoSinkWants modified_wants = wants;
55*d9f75844SAndroid Build Coastguard Worker modified_wants.black_frames = !enabled_w_;
56*d9f75844SAndroid Build Coastguard Worker video_source_->internal()->AddOrUpdateSink(sink, modified_wants);
57*d9f75844SAndroid Build Coastguard Worker }
58*d9f75844SAndroid Build Coastguard Worker
RemoveSink(rtc::VideoSinkInterface<VideoFrame> * sink)59*d9f75844SAndroid Build Coastguard Worker void VideoTrack::RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
60*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
61*d9f75844SAndroid Build Coastguard Worker VideoSourceBaseGuarded::RemoveSink(sink);
62*d9f75844SAndroid Build Coastguard Worker video_source_->internal()->RemoveSink(sink);
63*d9f75844SAndroid Build Coastguard Worker }
64*d9f75844SAndroid Build Coastguard Worker
RequestRefreshFrame()65*d9f75844SAndroid Build Coastguard Worker void VideoTrack::RequestRefreshFrame() {
66*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
67*d9f75844SAndroid Build Coastguard Worker video_source_->internal()->RequestRefreshFrame();
68*d9f75844SAndroid Build Coastguard Worker }
69*d9f75844SAndroid Build Coastguard Worker
GetSource() const70*d9f75844SAndroid Build Coastguard Worker VideoTrackSourceInterface* VideoTrack::GetSource() const {
71*d9f75844SAndroid Build Coastguard Worker // Callable from any thread.
72*d9f75844SAndroid Build Coastguard Worker return video_source_.get();
73*d9f75844SAndroid Build Coastguard Worker }
74*d9f75844SAndroid Build Coastguard Worker
GetSourceInternal() const75*d9f75844SAndroid Build Coastguard Worker VideoTrackSourceInterface* VideoTrack::GetSourceInternal() const {
76*d9f75844SAndroid Build Coastguard Worker return video_source_->internal();
77*d9f75844SAndroid Build Coastguard Worker }
78*d9f75844SAndroid Build Coastguard Worker
content_hint() const79*d9f75844SAndroid Build Coastguard Worker VideoTrackInterface::ContentHint VideoTrack::content_hint() const {
80*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&signaling_thread_);
81*d9f75844SAndroid Build Coastguard Worker return content_hint_;
82*d9f75844SAndroid Build Coastguard Worker }
83*d9f75844SAndroid Build Coastguard Worker
set_content_hint(ContentHint hint)84*d9f75844SAndroid Build Coastguard Worker void VideoTrack::set_content_hint(ContentHint hint) {
85*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&signaling_thread_);
86*d9f75844SAndroid Build Coastguard Worker if (content_hint_ == hint)
87*d9f75844SAndroid Build Coastguard Worker return;
88*d9f75844SAndroid Build Coastguard Worker content_hint_ = hint;
89*d9f75844SAndroid Build Coastguard Worker Notifier<VideoTrackInterface>::FireOnChanged();
90*d9f75844SAndroid Build Coastguard Worker }
91*d9f75844SAndroid Build Coastguard Worker
set_enabled(bool enable)92*d9f75844SAndroid Build Coastguard Worker bool VideoTrack::set_enabled(bool enable) {
93*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&signaling_thread_);
94*d9f75844SAndroid Build Coastguard Worker
95*d9f75844SAndroid Build Coastguard Worker bool ret = MediaStreamTrack<VideoTrackInterface>::set_enabled(enable);
96*d9f75844SAndroid Build Coastguard Worker
97*d9f75844SAndroid Build Coastguard Worker worker_thread_->BlockingCall([&]() {
98*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
99*d9f75844SAndroid Build Coastguard Worker enabled_w_ = enable;
100*d9f75844SAndroid Build Coastguard Worker for (auto& sink_pair : sink_pairs()) {
101*d9f75844SAndroid Build Coastguard Worker rtc::VideoSinkWants modified_wants = sink_pair.wants;
102*d9f75844SAndroid Build Coastguard Worker modified_wants.black_frames = !enable;
103*d9f75844SAndroid Build Coastguard Worker video_source_->AddOrUpdateSink(sink_pair.sink, modified_wants);
104*d9f75844SAndroid Build Coastguard Worker }
105*d9f75844SAndroid Build Coastguard Worker });
106*d9f75844SAndroid Build Coastguard Worker
107*d9f75844SAndroid Build Coastguard Worker return ret;
108*d9f75844SAndroid Build Coastguard Worker }
109*d9f75844SAndroid Build Coastguard Worker
enabled() const110*d9f75844SAndroid Build Coastguard Worker bool VideoTrack::enabled() const {
111*d9f75844SAndroid Build Coastguard Worker if (worker_thread_->IsCurrent()) {
112*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
113*d9f75844SAndroid Build Coastguard Worker return enabled_w_;
114*d9f75844SAndroid Build Coastguard Worker }
115*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&signaling_thread_);
116*d9f75844SAndroid Build Coastguard Worker return MediaStreamTrack<VideoTrackInterface>::enabled();
117*d9f75844SAndroid Build Coastguard Worker }
118*d9f75844SAndroid Build Coastguard Worker
state() const119*d9f75844SAndroid Build Coastguard Worker MediaStreamTrackInterface::TrackState VideoTrack::state() const {
120*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
121*d9f75844SAndroid Build Coastguard Worker return MediaStreamTrack<VideoTrackInterface>::state();
122*d9f75844SAndroid Build Coastguard Worker }
123*d9f75844SAndroid Build Coastguard Worker
OnChanged()124*d9f75844SAndroid Build Coastguard Worker void VideoTrack::OnChanged() {
125*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&signaling_thread_);
126*d9f75844SAndroid Build Coastguard Worker rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
127*d9f75844SAndroid Build Coastguard Worker MediaSourceInterface::SourceState state = video_source_->state();
128*d9f75844SAndroid Build Coastguard Worker set_state(state == MediaSourceInterface::kEnded ? kEnded : kLive);
129*d9f75844SAndroid Build Coastguard Worker }
130*d9f75844SAndroid Build Coastguard Worker
Create(absl::string_view id,rtc::scoped_refptr<VideoTrackSourceInterface> source,rtc::Thread * worker_thread)131*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<VideoTrack> VideoTrack::Create(
132*d9f75844SAndroid Build Coastguard Worker absl::string_view id,
133*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<VideoTrackSourceInterface> source,
134*d9f75844SAndroid Build Coastguard Worker rtc::Thread* worker_thread) {
135*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<
136*d9f75844SAndroid Build Coastguard Worker VideoTrackSourceProxyWithInternal<VideoTrackSourceInterface>>
137*d9f75844SAndroid Build Coastguard Worker source_proxy = VideoTrackSourceProxy::Create(
138*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), worker_thread, std::move(source));
139*d9f75844SAndroid Build Coastguard Worker
140*d9f75844SAndroid Build Coastguard Worker return rtc::make_ref_counted<VideoTrack>(id, std::move(source_proxy),
141*d9f75844SAndroid Build Coastguard Worker worker_thread);
142*d9f75844SAndroid Build Coastguard Worker }
143*d9f75844SAndroid Build Coastguard Worker
144*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
145