| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/media/base/videobroadcaster.h" | 11 #include "webrtc/media/base/videobroadcaster.h" |
| 12 | 12 |
| 13 #include <limits> | 13 #include <limits> |
| 14 | 14 |
| 15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
| 16 | 16 |
| 17 namespace rtc { | 17 namespace rtc { |
| 18 | 18 |
| 19 VideoBroadcaster::VideoBroadcaster() { | 19 VideoBroadcaster::VideoBroadcaster() { |
| 20 thread_checker_.DetachFromThread(); | 20 thread_checker_.DetachFromThread(); |
| 21 } | 21 } |
| 22 | 22 |
| 23 void VideoBroadcaster::AddOrUpdateSink( | 23 void VideoBroadcaster::AddOrUpdateSink( |
| 24 VideoSinkInterface<cricket::VideoFrame>* sink, | 24 VideoSinkInterface<cricket::VideoFrame>* sink, |
| 25 const VideoSinkWants& wants) { | 25 const VideoSinkWants& wants) { |
| 26 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 26 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 27 RTC_DCHECK(sink != nullptr); | 27 RTC_DCHECK(sink != nullptr); |
| 28 rtc::CritScope cs(&sinks_and_wants_lock_); | 28 rtc::CritScope cs(&sinks_and_wants_lock_); |
| 29 | 29 VideoSourceBase::AddOrUpdateSink(sink, wants); |
| 30 SinkPair* sink_pair = FindSinkPair(sink); | |
| 31 if (!sink_pair) { | |
| 32 sinks_.push_back(SinkPair(sink, wants)); | |
| 33 } else { | |
| 34 sink_pair->wants = wants; | |
| 35 } | |
| 36 UpdateWants(); | 30 UpdateWants(); |
| 37 } | 31 } |
| 38 | 32 |
| 39 void VideoBroadcaster::RemoveSink( | 33 void VideoBroadcaster::RemoveSink( |
| 40 VideoSinkInterface<cricket::VideoFrame>* sink) { | 34 VideoSinkInterface<cricket::VideoFrame>* sink) { |
| 41 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 35 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 42 RTC_DCHECK(sink != nullptr); | 36 RTC_DCHECK(sink != nullptr); |
| 43 rtc::CritScope cs(&sinks_and_wants_lock_); | 37 rtc::CritScope cs(&sinks_and_wants_lock_); |
| 44 RTC_DCHECK(FindSinkPair(sink)); | 38 VideoSourceBase::RemoveSink(sink); |
| 45 sinks_.erase(std::remove_if(sinks_.begin(), sinks_.end(), | |
| 46 [sink](const SinkPair& sink_pair) { | |
| 47 return sink_pair.sink == sink; | |
| 48 }), | |
| 49 sinks_.end()); | |
| 50 UpdateWants(); | 39 UpdateWants(); |
| 51 } | 40 } |
| 52 | 41 |
| 53 bool VideoBroadcaster::frame_wanted() const { | 42 bool VideoBroadcaster::frame_wanted() const { |
| 54 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 43 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 55 rtc::CritScope cs(&sinks_and_wants_lock_); | 44 rtc::CritScope cs(&sinks_and_wants_lock_); |
| 56 return !sinks_.empty(); | 45 return !sink_pairs().empty(); |
| 57 } | 46 } |
| 58 | 47 |
| 59 VideoSinkWants VideoBroadcaster::wants() const { | 48 VideoSinkWants VideoBroadcaster::wants() const { |
| 60 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 49 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 61 rtc::CritScope cs(&sinks_and_wants_lock_); | 50 rtc::CritScope cs(&sinks_and_wants_lock_); |
| 62 return current_wants_; | 51 return current_wants_; |
| 63 } | 52 } |
| 64 | 53 |
| 65 void VideoBroadcaster::OnFrame(const cricket::VideoFrame& frame) { | 54 void VideoBroadcaster::OnFrame(const cricket::VideoFrame& frame) { |
| 66 rtc::CritScope cs(&sinks_and_wants_lock_); | 55 rtc::CritScope cs(&sinks_and_wants_lock_); |
| 67 for (auto& sink_pair : sinks_) { | 56 for (auto& sink_pair : sink_pairs()) { |
| 68 sink_pair.sink->OnFrame(frame); | 57 if (sink_pair.wants.black_frames) { |
| 58 sink_pair.sink->OnFrame(GetBlackFrame(frame)); |
| 59 } else { |
| 60 sink_pair.sink->OnFrame(frame); |
| 61 } |
| 69 } | 62 } |
| 70 } | 63 } |
| 71 | 64 |
| 72 VideoBroadcaster::SinkPair* VideoBroadcaster::FindSinkPair( | |
| 73 const VideoSinkInterface<cricket::VideoFrame>* sink) { | |
| 74 auto sink_pair_it = std::find_if( | |
| 75 sinks_.begin(), sinks_.end(), | |
| 76 [sink](const SinkPair& sink_pair) { return sink_pair.sink == sink; }); | |
| 77 if (sink_pair_it != sinks_.end()) { | |
| 78 return &*sink_pair_it; | |
| 79 } | |
| 80 return nullptr; | |
| 81 } | |
| 82 | |
| 83 void VideoBroadcaster::UpdateWants() { | 65 void VideoBroadcaster::UpdateWants() { |
| 84 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 66 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 85 | 67 |
| 86 VideoSinkWants wants; | 68 VideoSinkWants wants; |
| 87 wants.rotation_applied = false; | 69 wants.rotation_applied = false; |
| 88 for (auto& sink : sinks_) { | 70 for (auto& sink : sink_pairs()) { |
| 89 // wants.rotation_applied == ANY(sink.wants.rotation_applied) | 71 // wants.rotation_applied == ANY(sink.wants.rotation_applied) |
| 90 if (sink.wants.rotation_applied) { | 72 if (sink.wants.rotation_applied) { |
| 91 wants.rotation_applied = true; | 73 wants.rotation_applied = true; |
| 92 } | 74 } |
| 93 // wants.max_pixel_count == MIN(sink.wants.max_pixel_count) | 75 // wants.max_pixel_count == MIN(sink.wants.max_pixel_count) |
| 94 if (sink.wants.max_pixel_count && | 76 if (sink.wants.max_pixel_count && |
| 95 (!wants.max_pixel_count || | 77 (!wants.max_pixel_count || |
| 96 (*sink.wants.max_pixel_count < *wants.max_pixel_count))) { | 78 (*sink.wants.max_pixel_count < *wants.max_pixel_count))) { |
| 97 wants.max_pixel_count = sink.wants.max_pixel_count; | 79 wants.max_pixel_count = sink.wants.max_pixel_count; |
| 98 } | 80 } |
| 99 // wants.max_pixel_count_step_up == MIN(sink.wants.max_pixel_count_step_up) | 81 // wants.max_pixel_count_step_up == MIN(sink.wants.max_pixel_count_step_up) |
| 100 if (sink.wants.max_pixel_count_step_up && | 82 if (sink.wants.max_pixel_count_step_up && |
| 101 (!wants.max_pixel_count_step_up || | 83 (!wants.max_pixel_count_step_up || |
| 102 (*sink.wants.max_pixel_count_step_up < | 84 (*sink.wants.max_pixel_count_step_up < |
| 103 *wants.max_pixel_count_step_up))) { | 85 *wants.max_pixel_count_step_up))) { |
| 104 wants.max_pixel_count_step_up = sink.wants.max_pixel_count_step_up; | 86 wants.max_pixel_count_step_up = sink.wants.max_pixel_count_step_up; |
| 105 } | 87 } |
| 106 } | 88 } |
| 107 | 89 |
| 108 if (wants.max_pixel_count && wants.max_pixel_count_step_up && | 90 if (wants.max_pixel_count && wants.max_pixel_count_step_up && |
| 109 *wants.max_pixel_count_step_up >= *wants.max_pixel_count) { | 91 *wants.max_pixel_count_step_up >= *wants.max_pixel_count) { |
| 110 wants.max_pixel_count_step_up = Optional<int>(); | 92 wants.max_pixel_count_step_up = Optional<int>(); |
| 111 } | 93 } |
| 112 current_wants_ = wants; | 94 current_wants_ = wants; |
| 113 } | 95 } |
| 114 | 96 |
| 97 const cricket::VideoFrame& VideoBroadcaster::GetBlackFrame( |
| 98 const cricket::VideoFrame& frame) { |
| 99 if (black_frame_ && black_frame_->GetWidth() == frame.GetWidth() && |
| 100 black_frame_->GetHeight() == frame.GetHeight() && |
| 101 black_frame_->GetVideoRotation() == frame.GetVideoRotation()) { |
| 102 black_frame_->SetTimeStamp(frame.GetTimeStamp()); |
| 103 return *black_frame_; |
| 104 } |
| 105 black_frame_.reset(new cricket::WebRtcVideoFrame( |
| 106 new rtc::RefCountedObject<webrtc::I420Buffer>( |
| 107 static_cast<int>(frame.GetWidth()), |
| 108 static_cast<int>(frame.GetHeight())), |
| 109 frame.GetTimeStamp(), frame.GetVideoRotation())); |
| 110 black_frame_->SetToBlack(); |
| 111 return *black_frame_; |
| 112 } |
| 113 |
| 115 } // namespace rtc | 114 } // namespace rtc |
| OLD | NEW |