xref: /aosp_15_r20/external/webrtc/pc/video_track.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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