| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2010 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 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 namespace cricket { | 25 namespace cricket { |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63); | 29 static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63); |
| 30 #ifdef WEBRTC_LINUX | 30 #ifdef WEBRTC_LINUX |
| 31 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index. | 31 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index. |
| 32 #endif | 32 #endif |
| 33 static const int kDefaultScreencastFps = 5; | 33 static const int kDefaultScreencastFps = 5; |
| 34 | 34 |
| 35 // Limit stats data collections to ~20 seconds of 30fps data before dropping | |
| 36 // old data in case stats aren't reset for long periods of time. | |
| 37 static const size_t kMaxAccumulatorSize = 600; | |
| 38 | |
| 39 } // namespace | 35 } // namespace |
| 40 | 36 |
| 41 ///////////////////////////////////////////////////////////////////// | 37 ///////////////////////////////////////////////////////////////////// |
| 42 // Implementation of struct CapturedFrame | 38 // Implementation of struct CapturedFrame |
| 43 ///////////////////////////////////////////////////////////////////// | 39 ///////////////////////////////////////////////////////////////////// |
| 44 CapturedFrame::CapturedFrame() | 40 CapturedFrame::CapturedFrame() |
| 45 : width(0), | 41 : width(0), |
| 46 height(0), | 42 height(0), |
| 47 fourcc(0), | 43 fourcc(0), |
| 48 pixel_width(0), | 44 pixel_width(0), |
| 49 pixel_height(0), | 45 pixel_height(0), |
| 50 time_stamp(0), | 46 time_stamp(0), |
| 51 data_size(0), | 47 data_size(0), |
| 52 rotation(webrtc::kVideoRotation_0), | 48 rotation(webrtc::kVideoRotation_0), |
| 53 data(NULL) {} | 49 data(NULL) {} |
| 54 | 50 |
| 55 // TODO(fbarchard): Remove this function once lmimediaengine stops using it. | 51 // TODO(fbarchard): Remove this function once lmimediaengine stops using it. |
| 56 bool CapturedFrame::GetDataSize(uint32_t* size) const { | 52 bool CapturedFrame::GetDataSize(uint32_t* size) const { |
| 57 if (!size || data_size == CapturedFrame::kUnknownDataSize) { | 53 if (!size || data_size == CapturedFrame::kUnknownDataSize) { |
| 58 return false; | 54 return false; |
| 59 } | 55 } |
| 60 *size = data_size; | 56 *size = data_size; |
| 61 return true; | 57 return true; |
| 62 } | 58 } |
| 63 | 59 |
| 64 ///////////////////////////////////////////////////////////////////// | 60 ///////////////////////////////////////////////////////////////////// |
| 65 // Implementation of class VideoCapturer | 61 // Implementation of class VideoCapturer |
| 66 ///////////////////////////////////////////////////////////////////// | 62 ///////////////////////////////////////////////////////////////////// |
| 67 VideoCapturer::VideoCapturer() | 63 VideoCapturer::VideoCapturer() : apply_rotation_(true) { |
| 68 : adapt_frame_drops_data_(kMaxAccumulatorSize), | |
| 69 frame_time_data_(kMaxAccumulatorSize), | |
| 70 apply_rotation_(true) { | |
| 71 thread_checker_.DetachFromThread(); | 64 thread_checker_.DetachFromThread(); |
| 72 Construct(); | 65 Construct(); |
| 73 } | 66 } |
| 74 | 67 |
| 75 void VideoCapturer::Construct() { | 68 void VideoCapturer::Construct() { |
| 76 ratio_w_ = 0; | 69 ratio_w_ = 0; |
| 77 ratio_h_ = 0; | 70 ratio_h_ = 0; |
| 78 enable_camera_list_ = false; | 71 enable_camera_list_ = false; |
| 79 square_pixel_aspect_ratio_ = false; | 72 square_pixel_aspect_ratio_ = false; |
| 80 capture_state_ = CS_STOPPED; | 73 capture_state_ = CS_STOPPED; |
| 81 SignalFrameCaptured.connect(this, &VideoCapturer::OnFrameCaptured); | 74 SignalFrameCaptured.connect(this, &VideoCapturer::OnFrameCaptured); |
| 82 // TODO(perkj) SignalVideoFrame is used directly by Chrome remoting. | 75 // TODO(perkj) SignalVideoFrame is used directly by Chrome remoting. |
| 83 // Before that is refactored, SignalVideoFrame must forward frames to the | 76 // Before that is refactored, SignalVideoFrame must forward frames to the |
| 84 // |VideoBroadcaster|; | 77 // |VideoBroadcaster|; |
| 85 SignalVideoFrame.connect(this, &VideoCapturer::OnFrame); | 78 SignalVideoFrame.connect(this, &VideoCapturer::OnFrame); |
| 86 scaled_width_ = 0; | 79 scaled_width_ = 0; |
| 87 scaled_height_ = 0; | 80 scaled_height_ = 0; |
| 88 enable_video_adapter_ = true; | 81 enable_video_adapter_ = true; |
| 89 adapt_frame_drops_ = 0; | |
| 90 previous_frame_time_ = 0.0; | |
| 91 // There are lots of video capturers out there that don't call | 82 // There are lots of video capturers out there that don't call |
| 92 // set_frame_factory. We can either go change all of them, or we | 83 // set_frame_factory. We can either go change all of them, or we |
| 93 // can set this default. | 84 // can set this default. |
| 94 // TODO(pthatcher): Remove this hack and require the frame factory | 85 // TODO(pthatcher): Remove this hack and require the frame factory |
| 95 // to be passed in the constructor. | 86 // to be passed in the constructor. |
| 96 set_frame_factory(new WebRtcVideoFrameFactory()); | 87 set_frame_factory(new WebRtcVideoFrameFactory()); |
| 97 } | 88 } |
| 98 | 89 |
| 99 const std::vector<VideoFormat>* VideoCapturer::GetSupportedFormats() const { | 90 const std::vector<VideoFormat>* VideoCapturer::GetSupportedFormats() const { |
| 100 return &filtered_supported_formats_; | 91 return &filtered_supported_formats_; |
| 101 } | 92 } |
| 102 | 93 |
| 103 bool VideoCapturer::StartCapturing(const VideoFormat& capture_format) { | 94 bool VideoCapturer::StartCapturing(const VideoFormat& capture_format) { |
| 104 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 95 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 105 previous_frame_time_ = frame_length_time_reporter_.TimerNow(); | |
| 106 CaptureState result = Start(capture_format); | 96 CaptureState result = Start(capture_format); |
| 107 const bool success = (result == CS_RUNNING) || (result == CS_STARTING); | 97 const bool success = (result == CS_RUNNING) || (result == CS_STARTING); |
| 108 if (!success) { | 98 if (!success) { |
| 109 return false; | 99 return false; |
| 110 } | 100 } |
| 111 if (result == CS_RUNNING) { | 101 if (result == CS_RUNNING) { |
| 112 SetCaptureState(result); | 102 SetCaptureState(result); |
| 113 } | 103 } |
| 114 return true; | 104 return true; |
| 115 } | 105 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 return ss.str(); | 176 return ss.str(); |
| 187 } | 177 } |
| 188 | 178 |
| 189 void VideoCapturer::set_frame_factory(VideoFrameFactory* frame_factory) { | 179 void VideoCapturer::set_frame_factory(VideoFrameFactory* frame_factory) { |
| 190 frame_factory_.reset(frame_factory); | 180 frame_factory_.reset(frame_factory); |
| 191 if (frame_factory) { | 181 if (frame_factory) { |
| 192 frame_factory->SetApplyRotation(apply_rotation_); | 182 frame_factory->SetApplyRotation(apply_rotation_); |
| 193 } | 183 } |
| 194 } | 184 } |
| 195 | 185 |
| 196 void VideoCapturer::GetStats(VariableInfo<int>* adapt_drops_stats, | 186 void VideoCapturer::GetStats(VideoFormat* last_captured_frame_format) { |
| 197 VariableInfo<int>* effect_drops_stats, | |
| 198 VariableInfo<double>* frame_time_stats, | |
| 199 VideoFormat* last_captured_frame_format) { | |
| 200 rtc::CritScope cs(&frame_stats_crit_); | 187 rtc::CritScope cs(&frame_stats_crit_); |
| 201 GetVariableSnapshot(adapt_frame_drops_data_, adapt_drops_stats); | |
| 202 GetVariableSnapshot(frame_time_data_, frame_time_stats); | |
| 203 *last_captured_frame_format = last_captured_frame_format_; | 188 *last_captured_frame_format = last_captured_frame_format_; |
| 204 | |
| 205 adapt_frame_drops_data_.Reset(); | |
| 206 frame_time_data_.Reset(); | |
| 207 } | 189 } |
| 208 | 190 |
| 209 void VideoCapturer::RemoveSink( | 191 void VideoCapturer::RemoveSink( |
| 210 rtc::VideoSinkInterface<cricket::VideoFrame>* sink) { | 192 rtc::VideoSinkInterface<cricket::VideoFrame>* sink) { |
| 211 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 193 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 212 broadcaster_.RemoveSink(sink); | 194 broadcaster_.RemoveSink(sink); |
| 213 OnSinkWantsChanged(broadcaster_.wants()); | 195 OnSinkWantsChanged(broadcaster_.wants()); |
| 214 } | 196 } |
| 215 | 197 |
| 216 void VideoCapturer::AddOrUpdateSink( | 198 void VideoCapturer::AddOrUpdateSink( |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 &cropped_width, &cropped_height); | 363 &cropped_width, &cropped_height); |
| 382 } | 364 } |
| 383 | 365 |
| 384 int adapted_width = cropped_width; | 366 int adapted_width = cropped_width; |
| 385 int adapted_height = cropped_height; | 367 int adapted_height = cropped_height; |
| 386 if (enable_video_adapter_ && !IsScreencast()) { | 368 if (enable_video_adapter_ && !IsScreencast()) { |
| 387 const VideoFormat adapted_format = | 369 const VideoFormat adapted_format = |
| 388 video_adapter_.AdaptFrameResolution(cropped_width, cropped_height); | 370 video_adapter_.AdaptFrameResolution(cropped_width, cropped_height); |
| 389 if (adapted_format.IsSize0x0()) { | 371 if (adapted_format.IsSize0x0()) { |
| 390 // VideoAdapter dropped the frame. | 372 // VideoAdapter dropped the frame. |
| 391 ++adapt_frame_drops_; | |
| 392 return; | 373 return; |
| 393 } | 374 } |
| 394 adapted_width = adapted_format.width; | 375 adapted_width = adapted_format.width; |
| 395 adapted_height = adapted_format.height; | 376 adapted_height = adapted_format.height; |
| 396 } | 377 } |
| 397 | 378 |
| 398 if (!frame_factory_) { | 379 if (!frame_factory_) { |
| 399 LOG(LS_ERROR) << "No video frame factory."; | 380 LOG(LS_ERROR) << "No video frame factory."; |
| 400 return; | 381 return; |
| 401 } | 382 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 | 542 |
| 562 void VideoCapturer::UpdateStats(const CapturedFrame* captured_frame) { | 543 void VideoCapturer::UpdateStats(const CapturedFrame* captured_frame) { |
| 563 // Update stats protected from fetches from different thread. | 544 // Update stats protected from fetches from different thread. |
| 564 rtc::CritScope cs(&frame_stats_crit_); | 545 rtc::CritScope cs(&frame_stats_crit_); |
| 565 | 546 |
| 566 last_captured_frame_format_.width = captured_frame->width; | 547 last_captured_frame_format_.width = captured_frame->width; |
| 567 last_captured_frame_format_.height = captured_frame->height; | 548 last_captured_frame_format_.height = captured_frame->height; |
| 568 // TODO(ronghuawu): Useful to report interval as well? | 549 // TODO(ronghuawu): Useful to report interval as well? |
| 569 last_captured_frame_format_.interval = 0; | 550 last_captured_frame_format_.interval = 0; |
| 570 last_captured_frame_format_.fourcc = captured_frame->fourcc; | 551 last_captured_frame_format_.fourcc = captured_frame->fourcc; |
| 571 | |
| 572 double time_now = frame_length_time_reporter_.TimerNow(); | |
| 573 if (previous_frame_time_ != 0.0) { | |
| 574 adapt_frame_drops_data_.AddSample(adapt_frame_drops_); | |
| 575 frame_time_data_.AddSample(time_now - previous_frame_time_); | |
| 576 } | |
| 577 previous_frame_time_ = time_now; | |
| 578 adapt_frame_drops_ = 0; | |
| 579 } | |
| 580 | |
| 581 template<class T> | |
| 582 void VideoCapturer::GetVariableSnapshot( | |
| 583 const rtc::RollingAccumulator<T>& data, | |
| 584 VariableInfo<T>* stats) { | |
| 585 stats->max_val = data.ComputeMax(); | |
| 586 stats->mean = data.ComputeMean(); | |
| 587 stats->min_val = data.ComputeMin(); | |
| 588 stats->variance = data.ComputeVariance(); | |
| 589 } | 552 } |
| 590 | 553 |
| 591 } // namespace cricket | 554 } // namespace cricket |
| OLD | NEW |