LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/media/base - videobroadcaster.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 63 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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.
       9             :  */
      10             : 
      11             : #include "webrtc/media/base/videobroadcaster.h"
      12             : 
      13             : #include <limits>
      14             : 
      15             : #include "webrtc/api/video/i420_buffer.h"
      16             : #include "webrtc/base/checks.h"
      17             : #include "webrtc/base/logging.h"
      18             : 
      19             : namespace rtc {
      20             : 
      21           0 : VideoBroadcaster::VideoBroadcaster() {
      22           0 :   thread_checker_.DetachFromThread();
      23           0 : }
      24             : 
      25           0 : void VideoBroadcaster::AddOrUpdateSink(
      26             :     VideoSinkInterface<webrtc::VideoFrame>* sink,
      27             :     const VideoSinkWants& wants) {
      28           0 :   RTC_DCHECK(thread_checker_.CalledOnValidThread());
      29           0 :   RTC_DCHECK(sink != nullptr);
      30           0 :   rtc::CritScope cs(&sinks_and_wants_lock_);
      31           0 :   VideoSourceBase::AddOrUpdateSink(sink, wants);
      32           0 :   UpdateWants();
      33           0 : }
      34             : 
      35           0 : void VideoBroadcaster::RemoveSink(
      36             :     VideoSinkInterface<webrtc::VideoFrame>* sink) {
      37           0 :   RTC_DCHECK(thread_checker_.CalledOnValidThread());
      38           0 :   RTC_DCHECK(sink != nullptr);
      39           0 :   rtc::CritScope cs(&sinks_and_wants_lock_);
      40           0 :   VideoSourceBase::RemoveSink(sink);
      41           0 :   UpdateWants();
      42           0 : }
      43             : 
      44           0 : bool VideoBroadcaster::frame_wanted() const {
      45           0 :   rtc::CritScope cs(&sinks_and_wants_lock_);
      46           0 :   return !sink_pairs().empty();
      47             : }
      48             : 
      49           0 : VideoSinkWants VideoBroadcaster::wants() const {
      50           0 :   rtc::CritScope cs(&sinks_and_wants_lock_);
      51           0 :   return current_wants_;
      52             : }
      53             : 
      54           0 : void VideoBroadcaster::OnFrame(const webrtc::VideoFrame& frame) {
      55           0 :   rtc::CritScope cs(&sinks_and_wants_lock_);
      56           0 :   for (auto& sink_pair : sink_pairs()) {
      57           0 :     if (sink_pair.wants.rotation_applied &&
      58           0 :         frame.rotation() != webrtc::kVideoRotation_0) {
      59             :       // Calls to OnFrame are not synchronized with changes to the sink wants.
      60             :       // When rotation_applied is set to true, one or a few frames may get here
      61             :       // with rotation still pending. Protect sinks that don't expect any
      62             :       // pending rotation.
      63           0 :       LOG(LS_VERBOSE) << "Discarding frame with unexpected rotation.";
      64           0 :       continue;
      65             :     }
      66           0 :     if (sink_pair.wants.black_frames) {
      67           0 :       sink_pair.sink->OnFrame(webrtc::VideoFrame(
      68             :           GetBlackFrameBuffer(frame.width(), frame.height()), frame.rotation(),
      69           0 :           frame.timestamp_us()));
      70             :     } else {
      71           0 :       sink_pair.sink->OnFrame(frame);
      72             :     }
      73             :   }
      74           0 : }
      75             : 
      76           0 : void VideoBroadcaster::UpdateWants() {
      77           0 :   RTC_DCHECK(thread_checker_.CalledOnValidThread());
      78             : 
      79           0 :   VideoSinkWants wants;
      80           0 :   wants.rotation_applied = false;
      81           0 :   for (auto& sink : sink_pairs()) {
      82             :     // wants.rotation_applied == ANY(sink.wants.rotation_applied)
      83           0 :     if (sink.wants.rotation_applied) {
      84           0 :       wants.rotation_applied = true;
      85             :     }
      86             :     // wants.max_pixel_count == MIN(sink.wants.max_pixel_count)
      87           0 :     if (sink.wants.max_pixel_count &&
      88           0 :         (!wants.max_pixel_count ||
      89           0 :          (*sink.wants.max_pixel_count < *wants.max_pixel_count))) {
      90           0 :       wants.max_pixel_count = sink.wants.max_pixel_count;
      91             :     }
      92             :     // wants.max_pixel_count_step_up == MIN(sink.wants.max_pixel_count_step_up)
      93           0 :     if (sink.wants.max_pixel_count_step_up &&
      94           0 :         (!wants.max_pixel_count_step_up ||
      95           0 :          (*sink.wants.max_pixel_count_step_up <
      96           0 :           *wants.max_pixel_count_step_up))) {
      97           0 :       wants.max_pixel_count_step_up = sink.wants.max_pixel_count_step_up;
      98             :     }
      99             :   }
     100             : 
     101           0 :   if (wants.max_pixel_count && wants.max_pixel_count_step_up &&
     102           0 :       *wants.max_pixel_count_step_up >= *wants.max_pixel_count) {
     103           0 :     wants.max_pixel_count_step_up = Optional<int>();
     104             :   }
     105           0 :   current_wants_ = wants;
     106           0 : }
     107             : 
     108             : const rtc::scoped_refptr<webrtc::VideoFrameBuffer>&
     109           0 : VideoBroadcaster::GetBlackFrameBuffer(int width, int height) {
     110           0 :   if (!black_frame_buffer_ || black_frame_buffer_->width() != width ||
     111           0 :       black_frame_buffer_->height() != height) {
     112             :     rtc::scoped_refptr<webrtc::I420Buffer> buffer =
     113           0 :         webrtc::I420Buffer::Create(width, height);
     114           0 :     webrtc::I420Buffer::SetBlack(buffer.get());
     115           0 :     black_frame_buffer_ = buffer;
     116             :   }
     117             : 
     118           0 :   return black_frame_buffer_;
     119             : }
     120             : 
     121             : }  // namespace rtc

Generated by: LCOV version 1.13