henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 1 | /* |
kjellander | b24317b | 2016-02-10 15:54:43 | [diff] [blame] | 2 | * Copyright 2011 The WebRTC project authors. All Rights Reserved. |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 3 | * |
kjellander | b24317b | 2016-02-10 15:54:43 | [diff] [blame] | 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. |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 9 | */ |
jlmiller@webrtc.org | 5f93d0a | 2015-01-20 21:36:13 | [diff] [blame] | 10 | |
Jonas Olsson | a4d8737 | 2019-07-05 17:08:33 | [diff] [blame] | 11 | #include "pc/video_track.h" |
| 12 | |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 13 | #include <utility> |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 14 | #include <vector> |
Steve Anton | 36b29d1 | 2017-10-30 16:57:42 | [diff] [blame] | 15 | |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 16 | #include "api/notifier.h" |
Artem Titov | d15a575 | 2021-02-10 13:31:24 | [diff] [blame] | 17 | #include "api/sequence_checker.h" |
Yves Gerey | 3e70781 | 2018-11-28 15:47:49 | [diff] [blame] | 18 | #include "rtc_base/checks.h" |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 19 | |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 20 | namespace webrtc { |
| 21 | |
Tommi | 09f5713 | 2022-02-17 12:19:55 | [diff] [blame] | 22 | VideoTrack::VideoTrack( |
Niels Möller | c397fc6 | 2022-05-30 09:26:40 | [diff] [blame] | 23 | absl::string_view label, |
Tommi | 09f5713 | 2022-02-17 12:19:55 | [diff] [blame] | 24 | rtc::scoped_refptr< |
| 25 | VideoTrackSourceProxyWithInternal<VideoTrackSourceInterface>> source, |
| 26 | rtc::Thread* worker_thread) |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 27 | : MediaStreamTrack<VideoTrackInterface>(label), |
perkj | 773be36 | 2017-08-01 06:22:01 | [diff] [blame] | 28 | worker_thread_(worker_thread), |
Tommi | 09f5713 | 2022-02-17 12:19:55 | [diff] [blame] | 29 | video_source_(std::move(source)), |
pbos | 5214a0a | 2016-12-16 23:39:11 | [diff] [blame] | 30 | content_hint_(ContentHint::kNone) { |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 31 | RTC_DCHECK_RUN_ON(&signaling_thread_); |
| 32 | // Detach the thread checker for VideoSourceBaseGuarded since we'll make calls |
| 33 | // to VideoSourceBaseGuarded on the worker thread, but we're currently on the |
| 34 | // signaling thread. |
| 35 | source_sequence_.Detach(); |
perkj | c8f952d | 2016-03-23 07:33:56 | [diff] [blame] | 36 | video_source_->RegisterObserver(this); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | VideoTrack::~VideoTrack() { |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 40 | RTC_DCHECK_RUN_ON(&signaling_thread_); |
perkj | c8f952d | 2016-03-23 07:33:56 | [diff] [blame] | 41 | video_source_->UnregisterObserver(this); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | std::string VideoTrack::kind() const { |
deadbeef | fac0655 | 2015-11-25 19:26:01 | [diff] [blame] | 45 | return kVideoKind; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 46 | } |
| 47 | |
nisse | 5b68ab5 | 2016-04-07 14:45:54 | [diff] [blame] | 48 | // AddOrUpdateSink and RemoveSink should be called on the worker |
| 49 | // thread. |
nisse | acd935b | 2016-11-11 11:55:13 | [diff] [blame] | 50 | void VideoTrack::AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink, |
| 51 | const rtc::VideoSinkWants& wants) { |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 52 | RTC_DCHECK_RUN_ON(worker_thread_); |
| 53 | VideoSourceBaseGuarded::AddOrUpdateSink(sink, wants); |
perkj | d6c3954 | 2016-03-17 09:35:23 | [diff] [blame] | 54 | rtc::VideoSinkWants modified_wants = wants; |
Tomas Gunnarsson | 250c31d | 2022-02-14 22:48:41 | [diff] [blame] | 55 | modified_wants.black_frames = !enabled_w_; |
Tommi | 34cd1d3 | 2022-02-17 12:28:57 | [diff] [blame] | 56 | video_source_->internal()->AddOrUpdateSink(sink, modified_wants); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 57 | } |
| 58 | |
nisse | acd935b | 2016-11-11 11:55:13 | [diff] [blame] | 59 | void VideoTrack::RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) { |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 60 | RTC_DCHECK_RUN_ON(worker_thread_); |
| 61 | VideoSourceBaseGuarded::RemoveSink(sink); |
Tommi | 34cd1d3 | 2022-02-17 12:28:57 | [diff] [blame] | 62 | video_source_->internal()->RemoveSink(sink); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 63 | } |
| 64 | |
Markus Handell | dbef2bd | 2021-12-22 09:47:27 | [diff] [blame] | 65 | void VideoTrack::RequestRefreshFrame() { |
| 66 | RTC_DCHECK_RUN_ON(worker_thread_); |
Tommi | 34cd1d3 | 2022-02-17 12:28:57 | [diff] [blame] | 67 | video_source_->internal()->RequestRefreshFrame(); |
Markus Handell | dbef2bd | 2021-12-22 09:47:27 | [diff] [blame] | 68 | } |
| 69 | |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 70 | VideoTrackSourceInterface* VideoTrack::GetSource() const { |
| 71 | // Callable from any thread. |
| 72 | return video_source_.get(); |
| 73 | } |
| 74 | |
Tommi | 34cd1d3 | 2022-02-17 12:28:57 | [diff] [blame] | 75 | VideoTrackSourceInterface* VideoTrack::GetSourceInternal() const { |
| 76 | return video_source_->internal(); |
| 77 | } |
| 78 | |
pbos | 5214a0a | 2016-12-16 23:39:11 | [diff] [blame] | 79 | VideoTrackInterface::ContentHint VideoTrack::content_hint() const { |
Tomas Gunnarsson | dfd69c2 | 2022-02-15 12:56:50 | [diff] [blame] | 80 | RTC_DCHECK_RUN_ON(&signaling_thread_); |
pbos | 5214a0a | 2016-12-16 23:39:11 | [diff] [blame] | 81 | return content_hint_; |
| 82 | } |
| 83 | |
| 84 | void VideoTrack::set_content_hint(ContentHint hint) { |
Tomas Gunnarsson | dfd69c2 | 2022-02-15 12:56:50 | [diff] [blame] | 85 | RTC_DCHECK_RUN_ON(&signaling_thread_); |
pbos | 5214a0a | 2016-12-16 23:39:11 | [diff] [blame] | 86 | if (content_hint_ == hint) |
| 87 | return; |
| 88 | content_hint_ = hint; |
| 89 | Notifier<VideoTrackInterface>::FireOnChanged(); |
| 90 | } |
| 91 | |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 92 | bool VideoTrack::set_enabled(bool enable) { |
Tomas Gunnarsson | 250c31d | 2022-02-14 22:48:41 | [diff] [blame] | 93 | RTC_DCHECK_RUN_ON(&signaling_thread_); |
| 94 | |
| 95 | bool ret = MediaStreamTrack<VideoTrackInterface>::set_enabled(enable); |
| 96 | |
Danil Chapovalov | 9e09a1f | 2022-09-08 16:38:10 | [diff] [blame] | 97 | worker_thread_->BlockingCall([&]() { |
Tomas Gunnarsson | 250c31d | 2022-02-14 22:48:41 | [diff] [blame] | 98 | RTC_DCHECK_RUN_ON(worker_thread_); |
| 99 | enabled_w_ = enable; |
| 100 | for (auto& sink_pair : sink_pairs()) { |
| 101 | rtc::VideoSinkWants modified_wants = sink_pair.wants; |
| 102 | modified_wants.black_frames = !enable; |
| 103 | video_source_->AddOrUpdateSink(sink_pair.sink, modified_wants); |
| 104 | } |
| 105 | }); |
| 106 | |
| 107 | return ret; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 108 | } |
| 109 | |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 110 | bool VideoTrack::enabled() const { |
Tomas Gunnarsson | 250c31d | 2022-02-14 22:48:41 | [diff] [blame] | 111 | if (worker_thread_->IsCurrent()) { |
| 112 | RTC_DCHECK_RUN_ON(worker_thread_); |
| 113 | return enabled_w_; |
| 114 | } |
| 115 | RTC_DCHECK_RUN_ON(&signaling_thread_); |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 116 | return MediaStreamTrack<VideoTrackInterface>::enabled(); |
| 117 | } |
| 118 | |
| 119 | MediaStreamTrackInterface::TrackState VideoTrack::state() const { |
Tomas Gunnarsson | e7b4c13 | 2022-02-14 11:03:29 | [diff] [blame] | 120 | RTC_DCHECK_RUN_ON(worker_thread_); |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 121 | return MediaStreamTrack<VideoTrackInterface>::state(); |
| 122 | } |
| 123 | |
perkj | c8f952d | 2016-03-23 07:33:56 | [diff] [blame] | 124 | void VideoTrack::OnChanged() { |
Tommi | 816134a | 2021-05-24 14:54:41 | [diff] [blame] | 125 | RTC_DCHECK_RUN_ON(&signaling_thread_); |
Tomas Gunnarsson | dfd69c2 | 2022-02-15 12:56:50 | [diff] [blame] | 126 | rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls; |
| 127 | MediaSourceInterface::SourceState state = video_source_->state(); |
| 128 | set_state(state == MediaSourceInterface::kEnded ? kEnded : kLive); |
perkj | c8f952d | 2016-03-23 07:33:56 | [diff] [blame] | 129 | } |
| 130 | |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 | [diff] [blame] | 131 | rtc::scoped_refptr<VideoTrack> VideoTrack::Create( |
Niels Möller | c397fc6 | 2022-05-30 09:26:40 | [diff] [blame] | 132 | absl::string_view id, |
Niels Möller | 769de49 | 2022-03-21 09:40:09 | [diff] [blame] | 133 | rtc::scoped_refptr<VideoTrackSourceInterface> source, |
perkj | 773be36 | 2017-08-01 06:22:01 | [diff] [blame] | 134 | rtc::Thread* worker_thread) { |
Tommi | 09f5713 | 2022-02-17 12:19:55 | [diff] [blame] | 135 | rtc::scoped_refptr< |
| 136 | VideoTrackSourceProxyWithInternal<VideoTrackSourceInterface>> |
Tomas Gunnarsson | 0d5ce62 | 2022-03-18 14:57:15 | [diff] [blame] | 137 | source_proxy = VideoTrackSourceProxy::Create( |
Niels Möller | 769de49 | 2022-03-21 09:40:09 | [diff] [blame] | 138 | rtc::Thread::Current(), worker_thread, std::move(source)); |
Tommi | 09f5713 | 2022-02-17 12:19:55 | [diff] [blame] | 139 | |
| 140 | return rtc::make_ref_counted<VideoTrack>(id, std::move(source_proxy), |
| 141 | worker_thread); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | } // namespace webrtc |