Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: webrtc/media/base/videocapturer.cc

Issue 1740963002: Revert of Removed unused cricket::VideoCapturer methods (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/media/base/videocapturer.h ('k') | webrtc/media/base/videocapturer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 // Implementation file of class VideoCapturer. 11 // Implementation file of class VideoCapturer.
12 12
13 #include "webrtc/media/base/videocapturer.h" 13 #include "webrtc/media/base/videocapturer.h"
14 14
15 #include <algorithm> 15 #include <algorithm>
16 16
17 #include "libyuv/scale_argb.h" 17 #include "libyuv/scale_argb.h"
18 #include "webrtc/base/common.h" 18 #include "webrtc/base/common.h"
19 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
20 #include "webrtc/base/systeminfo.h" 20 #include "webrtc/base/systeminfo.h"
21 #include "webrtc/media/base/videoframefactory.h" 21 #include "webrtc/media/base/videoframefactory.h"
22
23 #if defined(HAVE_WEBRTC_VIDEO)
22 #include "webrtc/media/engine/webrtcvideoframe.h" 24 #include "webrtc/media/engine/webrtcvideoframe.h"
23 #include "webrtc/media/engine/webrtcvideoframefactory.h" 25 #include "webrtc/media/engine/webrtcvideoframefactory.h"
26 #endif // HAVE_WEBRTC_VIDEO
24 27
25 namespace cricket { 28 namespace cricket {
26 29
27 namespace { 30 namespace {
28 31
32 // TODO(thorcarpenter): This is a BIG hack to flush the system with black
33 // frames. Frontends should coordinate to update the video state of a muted
34 // user. When all frontends to this consider removing the black frame business.
35 const int kNumBlackFramesOnMute = 30;
36
37 // MessageHandler constants.
38 enum {
39 MSG_DO_PAUSE = 0,
40 MSG_DO_UNPAUSE,
41 MSG_STATE_CHANGE
42 };
43
29 static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63); 44 static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63);
30 #ifdef WEBRTC_LINUX 45 #ifdef WEBRTC_LINUX
31 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index. 46 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index.
32 #endif 47 #endif
33 static const int kDefaultScreencastFps = 5; 48 static const int kDefaultScreencastFps = 5;
49 typedef rtc::TypedMessageData<CaptureState> StateChangeParams;
34 50
35 // Limit stats data collections to ~20 seconds of 30fps data before dropping 51 // 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. 52 // old data in case stats aren't reset for long periods of time.
37 static const size_t kMaxAccumulatorSize = 600; 53 static const size_t kMaxAccumulatorSize = 600;
38 54
39 } // namespace 55 } // namespace
40 56
41 ///////////////////////////////////////////////////////////////////// 57 /////////////////////////////////////////////////////////////////////
42 // Implementation of struct CapturedFrame 58 // Implementation of struct CapturedFrame
43 ///////////////////////////////////////////////////////////////////// 59 /////////////////////////////////////////////////////////////////////
(...skipping 14 matching lines...) Expand all
58 return false; 74 return false;
59 } 75 }
60 *size = data_size; 76 *size = data_size;
61 return true; 77 return true;
62 } 78 }
63 79
64 ///////////////////////////////////////////////////////////////////// 80 /////////////////////////////////////////////////////////////////////
65 // Implementation of class VideoCapturer 81 // Implementation of class VideoCapturer
66 ///////////////////////////////////////////////////////////////////// 82 /////////////////////////////////////////////////////////////////////
67 VideoCapturer::VideoCapturer() 83 VideoCapturer::VideoCapturer()
68 : adapt_frame_drops_data_(kMaxAccumulatorSize), 84 : thread_(rtc::Thread::Current()),
85 adapt_frame_drops_data_(kMaxAccumulatorSize),
69 frame_time_data_(kMaxAccumulatorSize), 86 frame_time_data_(kMaxAccumulatorSize),
70 apply_rotation_(true) { 87 apply_rotation_(true) {
71 thread_checker_.DetachFromThread(); 88 Construct();
89 }
90
91 VideoCapturer::VideoCapturer(rtc::Thread* thread)
92 : thread_(thread),
93 adapt_frame_drops_data_(kMaxAccumulatorSize),
94 frame_time_data_(kMaxAccumulatorSize),
95 apply_rotation_(true) {
72 Construct(); 96 Construct();
73 } 97 }
74 98
75 void VideoCapturer::Construct() { 99 void VideoCapturer::Construct() {
76 ratio_w_ = 0; 100 ClearAspectRatio();
77 ratio_h_ = 0;
78 enable_camera_list_ = false; 101 enable_camera_list_ = false;
79 square_pixel_aspect_ratio_ = false; 102 square_pixel_aspect_ratio_ = false;
80 capture_state_ = CS_STOPPED; 103 capture_state_ = CS_STOPPED;
81 SignalFrameCaptured.connect(this, &VideoCapturer::OnFrameCaptured); 104 SignalFrameCaptured.connect(this, &VideoCapturer::OnFrameCaptured);
82 // TODO(perkj) SignalVideoFrame is used directly by Chrome remoting. 105 // TODO(perkj) SignalVideoFrame is used directly by Chrome remoting.
83 // Before that is refactored, SignalVideoFrame must forward frames to the 106 // Before that is refactored, SignalVideoFrame must forward frames to the
84 // |VideoBroadcaster|; 107 // |VideoBroadcaster|;
85 SignalVideoFrame.connect(this, &VideoCapturer::OnFrame); 108 SignalVideoFrame.connect(this, &VideoCapturer::OnFrame);
86 scaled_width_ = 0; 109 scaled_width_ = 0;
87 scaled_height_ = 0; 110 scaled_height_ = 0;
111 muted_ = false;
112 black_frame_count_down_ = kNumBlackFramesOnMute;
88 enable_video_adapter_ = true; 113 enable_video_adapter_ = true;
89 adapt_frame_drops_ = 0; 114 adapt_frame_drops_ = 0;
90 previous_frame_time_ = 0.0; 115 previous_frame_time_ = 0.0;
116 #ifdef HAVE_WEBRTC_VIDEO
91 // There are lots of video capturers out there that don't call 117 // 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 118 // set_frame_factory. We can either go change all of them, or we
93 // can set this default. 119 // can set this default.
94 // TODO(pthatcher): Remove this hack and require the frame factory 120 // TODO(pthatcher): Remove this hack and require the frame factory
95 // to be passed in the constructor. 121 // to be passed in the constructor.
96 set_frame_factory(new WebRtcVideoFrameFactory()); 122 set_frame_factory(new WebRtcVideoFrameFactory());
123 #endif
97 } 124 }
98 125
99 const std::vector<VideoFormat>* VideoCapturer::GetSupportedFormats() const { 126 const std::vector<VideoFormat>* VideoCapturer::GetSupportedFormats() const {
100 return &filtered_supported_formats_; 127 return &filtered_supported_formats_;
101 } 128 }
102 129
103 bool VideoCapturer::StartCapturing(const VideoFormat& capture_format) { 130 bool VideoCapturer::StartCapturing(const VideoFormat& capture_format) {
104 RTC_DCHECK(thread_checker_.CalledOnValidThread());
105 previous_frame_time_ = frame_length_time_reporter_.TimerNow(); 131 previous_frame_time_ = frame_length_time_reporter_.TimerNow();
106 CaptureState result = Start(capture_format); 132 CaptureState result = Start(capture_format);
107 const bool success = (result == CS_RUNNING) || (result == CS_STARTING); 133 const bool success = (result == CS_RUNNING) || (result == CS_STARTING);
108 if (!success) { 134 if (!success) {
109 return false; 135 return false;
110 } 136 }
111 if (result == CS_RUNNING) { 137 if (result == CS_RUNNING) {
112 SetCaptureState(result); 138 SetCaptureState(result);
113 } 139 }
114 return true; 140 return true;
115 } 141 }
116 142
143 void VideoCapturer::UpdateAspectRatio(int ratio_w, int ratio_h) {
144 if (ratio_w == 0 || ratio_h == 0) {
145 LOG(LS_WARNING) << "UpdateAspectRatio ignored invalid ratio: "
146 << ratio_w << "x" << ratio_h;
147 return;
148 }
149 ratio_w_ = ratio_w;
150 ratio_h_ = ratio_h;
151 }
152
153 void VideoCapturer::ClearAspectRatio() {
154 ratio_w_ = 0;
155 ratio_h_ = 0;
156 }
157
158 // Override this to have more control of how your device is started/stopped.
159 bool VideoCapturer::Pause(bool pause) {
160 if (pause) {
161 if (capture_state() == CS_PAUSED) {
162 return true;
163 }
164 bool is_running = capture_state() == CS_STARTING ||
165 capture_state() == CS_RUNNING;
166 if (!is_running) {
167 LOG(LS_ERROR) << "Cannot pause a stopped camera.";
168 return false;
169 }
170 LOG(LS_INFO) << "Pausing a camera.";
171 rtc::scoped_ptr<VideoFormat> capture_format_when_paused(
172 capture_format_ ? new VideoFormat(*capture_format_) : NULL);
173 Stop();
174 SetCaptureState(CS_PAUSED);
175 // If you override this function be sure to restore the capture format
176 // after calling Stop().
177 SetCaptureFormat(capture_format_when_paused.get());
178 } else { // Unpause.
179 if (capture_state() != CS_PAUSED) {
180 LOG(LS_WARNING) << "Cannot unpause a camera that hasn't been paused.";
181 return false;
182 }
183 if (!capture_format_) {
184 LOG(LS_ERROR) << "Missing capture_format_, cannot unpause a camera.";
185 return false;
186 }
187 if (muted_) {
188 LOG(LS_WARNING) << "Camera cannot be unpaused while muted.";
189 return false;
190 }
191 LOG(LS_INFO) << "Unpausing a camera.";
192 if (!Start(*capture_format_)) {
193 LOG(LS_ERROR) << "Camera failed to start when unpausing.";
194 return false;
195 }
196 }
197 return true;
198 }
199
200 bool VideoCapturer::Restart(const VideoFormat& capture_format) {
201 if (!IsRunning()) {
202 return StartCapturing(capture_format);
203 }
204
205 if (GetCaptureFormat() != NULL && *GetCaptureFormat() == capture_format) {
206 // The reqested format is the same; nothing to do.
207 return true;
208 }
209
210 Stop();
211 return StartCapturing(capture_format);
212 }
213
214 bool VideoCapturer::MuteToBlackThenPause(bool muted) {
215 if (muted == IsMuted()) {
216 return true;
217 }
218
219 LOG(LS_INFO) << (muted ? "Muting" : "Unmuting") << " this video capturer.";
220 muted_ = muted; // Do this before calling Pause().
221 if (muted) {
222 // Reset black frame count down.
223 black_frame_count_down_ = kNumBlackFramesOnMute;
224 // Following frames will be overritten with black, then the camera will be
225 // paused.
226 return true;
227 }
228 // Start the camera.
229 thread_->Clear(this, MSG_DO_PAUSE);
230 return Pause(false);
231 }
232
117 void VideoCapturer::SetSupportedFormats( 233 void VideoCapturer::SetSupportedFormats(
118 const std::vector<VideoFormat>& formats) { 234 const std::vector<VideoFormat>& formats) {
119 // This method is OK to call during initialization on a separate thread.
120 RTC_DCHECK(capture_state_ == CS_STOPPED ||
121 thread_checker_.CalledOnValidThread());
122 supported_formats_ = formats; 235 supported_formats_ = formats;
123 UpdateFilteredSupportedFormats(); 236 UpdateFilteredSupportedFormats();
124 } 237 }
125 238
126 bool VideoCapturer::GetBestCaptureFormat(const VideoFormat& format, 239 bool VideoCapturer::GetBestCaptureFormat(const VideoFormat& format,
127 VideoFormat* best_format) { 240 VideoFormat* best_format) {
128 RTC_DCHECK(thread_checker_.CalledOnValidThread());
129 // TODO(fbarchard): Directly support max_format. 241 // TODO(fbarchard): Directly support max_format.
130 UpdateFilteredSupportedFormats(); 242 UpdateFilteredSupportedFormats();
131 const std::vector<VideoFormat>* supported_formats = GetSupportedFormats(); 243 const std::vector<VideoFormat>* supported_formats = GetSupportedFormats();
132 244
133 if (supported_formats->empty()) { 245 if (supported_formats->empty()) {
134 return false; 246 return false;
135 } 247 }
136 LOG(LS_INFO) << " Capture Requested " << format.ToString(); 248 LOG(LS_INFO) << " Capture Requested " << format.ToString();
137 int64_t best_distance = kMaxDistance; 249 int64_t best_distance = kMaxDistance;
138 std::vector<VideoFormat>::const_iterator best = supported_formats->end(); 250 std::vector<VideoFormat>::const_iterator best = supported_formats->end();
(...skipping 18 matching lines...) Expand all
157 best_format->height = best->height; 269 best_format->height = best->height;
158 best_format->fourcc = best->fourcc; 270 best_format->fourcc = best->fourcc;
159 best_format->interval = best->interval; 271 best_format->interval = best->interval;
160 LOG(LS_INFO) << " Best " << best_format->ToString() << " Interval " 272 LOG(LS_INFO) << " Best " << best_format->ToString() << " Interval "
161 << best_format->interval << " distance " << best_distance; 273 << best_format->interval << " distance " << best_distance;
162 } 274 }
163 return true; 275 return true;
164 } 276 }
165 277
166 void VideoCapturer::ConstrainSupportedFormats(const VideoFormat& max_format) { 278 void VideoCapturer::ConstrainSupportedFormats(const VideoFormat& max_format) {
167 RTC_DCHECK(thread_checker_.CalledOnValidThread());
168 max_format_.reset(new VideoFormat(max_format)); 279 max_format_.reset(new VideoFormat(max_format));
169 LOG(LS_VERBOSE) << " ConstrainSupportedFormats " << max_format.ToString(); 280 LOG(LS_VERBOSE) << " ConstrainSupportedFormats " << max_format.ToString();
170 UpdateFilteredSupportedFormats(); 281 UpdateFilteredSupportedFormats();
171 } 282 }
172 283
173 std::string VideoCapturer::ToString(const CapturedFrame* captured_frame) const { 284 std::string VideoCapturer::ToString(const CapturedFrame* captured_frame) const {
174 std::string fourcc_name = GetFourccName(captured_frame->fourcc) + " "; 285 std::string fourcc_name = GetFourccName(captured_frame->fourcc) + " ";
175 for (std::string::const_iterator i = fourcc_name.begin(); 286 for (std::string::const_iterator i = fourcc_name.begin();
176 i < fourcc_name.end(); ++i) { 287 i < fourcc_name.end(); ++i) {
177 // Test character is printable; Avoid isprint() which asserts on negatives. 288 // Test character is printable; Avoid isprint() which asserts on negatives.
(...skipping 23 matching lines...) Expand all
201 GetVariableSnapshot(adapt_frame_drops_data_, adapt_drops_stats); 312 GetVariableSnapshot(adapt_frame_drops_data_, adapt_drops_stats);
202 GetVariableSnapshot(frame_time_data_, frame_time_stats); 313 GetVariableSnapshot(frame_time_data_, frame_time_stats);
203 *last_captured_frame_format = last_captured_frame_format_; 314 *last_captured_frame_format = last_captured_frame_format_;
204 315
205 adapt_frame_drops_data_.Reset(); 316 adapt_frame_drops_data_.Reset();
206 frame_time_data_.Reset(); 317 frame_time_data_.Reset();
207 } 318 }
208 319
209 void VideoCapturer::RemoveSink( 320 void VideoCapturer::RemoveSink(
210 rtc::VideoSinkInterface<cricket::VideoFrame>* sink) { 321 rtc::VideoSinkInterface<cricket::VideoFrame>* sink) {
211 RTC_DCHECK(thread_checker_.CalledOnValidThread());
212 broadcaster_.RemoveSink(sink); 322 broadcaster_.RemoveSink(sink);
213 } 323 }
214 324
215 void VideoCapturer::AddOrUpdateSink( 325 void VideoCapturer::AddOrUpdateSink(
216 rtc::VideoSinkInterface<cricket::VideoFrame>* sink, 326 rtc::VideoSinkInterface<cricket::VideoFrame>* sink,
217 const rtc::VideoSinkWants& wants) { 327 const rtc::VideoSinkWants& wants) {
218 RTC_DCHECK(thread_checker_.CalledOnValidThread());
219 broadcaster_.AddOrUpdateSink(sink, wants); 328 broadcaster_.AddOrUpdateSink(sink, wants);
220 OnSinkWantsChanged(broadcaster_.wants()); 329 OnSinkWantsChanged(broadcaster_.wants());
221 } 330 }
222 331
223 void VideoCapturer::OnSinkWantsChanged(const rtc::VideoSinkWants& wants) { 332 void VideoCapturer::OnSinkWantsChanged(const rtc::VideoSinkWants& wants) {
224 RTC_DCHECK(thread_checker_.CalledOnValidThread());
225 apply_rotation_ = wants.rotation_applied; 333 apply_rotation_ = wants.rotation_applied;
226 if (frame_factory_) { 334 if (frame_factory_) {
227 frame_factory_->SetApplyRotation(apply_rotation_); 335 frame_factory_->SetApplyRotation(apply_rotation_);
228 } 336 }
229 } 337 }
230 338
231 void VideoCapturer::OnFrameCaptured(VideoCapturer*, 339 void VideoCapturer::OnFrameCaptured(VideoCapturer*,
232 const CapturedFrame* captured_frame) { 340 const CapturedFrame* captured_frame) {
341 if (muted_) {
342 if (black_frame_count_down_ == 0) {
343 thread_->Post(this, MSG_DO_PAUSE, NULL);
344 } else {
345 --black_frame_count_down_;
346 }
347 }
348
233 if (!broadcaster_.frame_wanted()) { 349 if (!broadcaster_.frame_wanted()) {
234 return; 350 return;
235 } 351 }
236 352
237 // Use a temporary buffer to scale 353 // Use a temporary buffer to scale
238 rtc::scoped_ptr<uint8_t[]> scale_buffer; 354 rtc::scoped_ptr<uint8_t[]> scale_buffer;
355
239 if (IsScreencast()) { 356 if (IsScreencast()) {
240 int scaled_width, scaled_height; 357 int scaled_width, scaled_height;
241 int desired_screencast_fps = 358 int desired_screencast_fps = capture_format_.get() ?
242 capture_format_.get() 359 VideoFormat::IntervalToFps(capture_format_->interval) :
243 ? VideoFormat::IntervalToFps(capture_format_->interval) 360 kDefaultScreencastFps;
244 : kDefaultScreencastFps;
245 ComputeScale(captured_frame->width, captured_frame->height, 361 ComputeScale(captured_frame->width, captured_frame->height,
246 desired_screencast_fps, &scaled_width, &scaled_height); 362 desired_screencast_fps, &scaled_width, &scaled_height);
247 363
248 if (FOURCC_ARGB == captured_frame->fourcc && 364 if (FOURCC_ARGB == captured_frame->fourcc &&
249 (scaled_width != captured_frame->width || 365 (scaled_width != captured_frame->width ||
250 scaled_height != captured_frame->height)) { 366 scaled_height != captured_frame->height)) {
251 if (scaled_width != scaled_width_ || scaled_height != scaled_height_) { 367 if (scaled_width != scaled_width_ || scaled_height != scaled_height_) {
252 LOG(LS_INFO) << "Scaling Screencast from " << captured_frame->width 368 LOG(LS_INFO) << "Scaling Screencast from "
253 << "x" << captured_frame->height << " to " << scaled_width 369 << captured_frame->width << "x"
254 << "x" << scaled_height; 370 << captured_frame->height << " to "
371 << scaled_width << "x" << scaled_height;
255 scaled_width_ = scaled_width; 372 scaled_width_ = scaled_width;
256 scaled_height_ = scaled_height; 373 scaled_height_ = scaled_height;
257 } 374 }
258 CapturedFrame* modified_frame = 375 CapturedFrame* modified_frame =
259 const_cast<CapturedFrame*>(captured_frame); 376 const_cast<CapturedFrame*>(captured_frame);
260 const int modified_frame_size = scaled_width * scaled_height * 4; 377 const int modified_frame_size = scaled_width * scaled_height * 4;
261 scale_buffer.reset(new uint8_t[modified_frame_size]); 378 scale_buffer.reset(new uint8_t[modified_frame_size]);
262 // Compute new width such that width * height is less than maximum but 379 // Compute new width such that width * height is less than maximum but
263 // maintains original captured frame aspect ratio. 380 // maintains original captured frame aspect ratio.
264 // Round down width to multiple of 4 so odd width won't round up beyond 381 // Round down width to multiple of 4 so odd width won't round up beyond
265 // maximum, and so chroma channel is even width to simplify spatial 382 // maximum, and so chroma channel is even width to simplify spatial
266 // resampling. 383 // resampling.
267 libyuv::ARGBScale(reinterpret_cast<const uint8_t*>(captured_frame->data), 384 libyuv::ARGBScale(reinterpret_cast<const uint8_t*>(captured_frame->data),
268 captured_frame->width * 4, captured_frame->width, 385 captured_frame->width * 4, captured_frame->width,
269 captured_frame->height, scale_buffer.get(), 386 captured_frame->height, scale_buffer.get(),
270 scaled_width * 4, scaled_width, scaled_height, 387 scaled_width * 4, scaled_width, scaled_height,
271 libyuv::kFilterBilinear); 388 libyuv::kFilterBilinear);
272 modified_frame->width = scaled_width; 389 modified_frame->width = scaled_width;
273 modified_frame->height = scaled_height; 390 modified_frame->height = scaled_height;
274 modified_frame->data_size = scaled_width * 4 * scaled_height; 391 modified_frame->data_size = scaled_width * 4 * scaled_height;
275 modified_frame->data = scale_buffer.get(); 392 modified_frame->data = scale_buffer.get();
276 } 393 }
277 } 394 }
278 395
279 const int kYuy2Bpp = 2; 396 const int kYuy2Bpp = 2;
280 const int kArgbBpp = 4; 397 const int kArgbBpp = 4;
281 // TODO(fbarchard): Make a helper function to adjust pixels to square. 398 // TODO(fbarchard): Make a helper function to adjust pixels to square.
282 // TODO(fbarchard): Hook up experiment to scaling. 399 // TODO(fbarchard): Hook up experiment to scaling.
400 // TODO(fbarchard): Avoid scale and convert if muted.
283 // Temporary buffer is scoped here so it will persist until i420_frame.Init() 401 // Temporary buffer is scoped here so it will persist until i420_frame.Init()
284 // makes a copy of the frame, converting to I420. 402 // makes a copy of the frame, converting to I420.
285 rtc::scoped_ptr<uint8_t[]> temp_buffer; 403 rtc::scoped_ptr<uint8_t[]> temp_buffer;
286 // YUY2 can be scaled vertically using an ARGB scaler. Aspect ratio is only 404 // YUY2 can be scaled vertically using an ARGB scaler. Aspect ratio is only
287 // a problem on OSX. OSX always converts webcams to YUY2 or UYVY. 405 // a problem on OSX. OSX always converts webcams to YUY2 or UYVY.
288 bool can_scale = 406 bool can_scale =
289 FOURCC_YUY2 == CanonicalFourCC(captured_frame->fourcc) || 407 FOURCC_YUY2 == CanonicalFourCC(captured_frame->fourcc) ||
290 FOURCC_UYVY == CanonicalFourCC(captured_frame->fourcc); 408 FOURCC_UYVY == CanonicalFourCC(captured_frame->fourcc);
291 409
292 // If pixels are not square, optionally use vertical scaling to make them 410 // If pixels are not square, optionally use vertical scaling to make them
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 adapted_width, adapted_height)); 518 adapted_width, adapted_height));
401 519
402 if (!adapted_frame) { 520 if (!adapted_frame) {
403 // TODO(fbarchard): LOG more information about captured frame attributes. 521 // TODO(fbarchard): LOG more information about captured frame attributes.
404 LOG(LS_ERROR) << "Couldn't convert to I420! " 522 LOG(LS_ERROR) << "Couldn't convert to I420! "
405 << "From " << ToString(captured_frame) << " To " 523 << "From " << ToString(captured_frame) << " To "
406 << cropped_width << " x " << cropped_height; 524 << cropped_width << " x " << cropped_height;
407 return; 525 return;
408 } 526 }
409 527
528 if (muted_) {
529 // TODO(pthatcher): Use frame_factory_->CreateBlackFrame() instead.
530 adapted_frame->SetToBlack();
531 }
410 SignalVideoFrame(this, adapted_frame.get()); 532 SignalVideoFrame(this, adapted_frame.get());
411 UpdateStats(captured_frame); 533 UpdateStats(captured_frame);
412 } 534 }
413 535
414 void VideoCapturer::OnFrame(VideoCapturer* capturer, const VideoFrame* frame) { 536 void VideoCapturer::OnFrame(VideoCapturer* capturer, const VideoFrame* frame) {
415 broadcaster_.OnFrame(*frame); 537 broadcaster_.OnFrame(*frame);
416 } 538 }
417 539
418 void VideoCapturer::SetCaptureState(CaptureState state) { 540 void VideoCapturer::SetCaptureState(CaptureState state) {
419 RTC_DCHECK(thread_checker_.CalledOnValidThread());
420 if (state == capture_state_) { 541 if (state == capture_state_) {
421 // Don't trigger a state changed callback if the state hasn't changed. 542 // Don't trigger a state changed callback if the state hasn't changed.
422 return; 543 return;
423 } 544 }
545 StateChangeParams* state_params = new StateChangeParams(state);
424 capture_state_ = state; 546 capture_state_ = state;
425 SignalStateChange(this, capture_state_); 547 thread_->Post(this, MSG_STATE_CHANGE, state_params);
548 }
549
550 void VideoCapturer::OnMessage(rtc::Message* message) {
551 switch (message->message_id) {
552 case MSG_STATE_CHANGE: {
553 rtc::scoped_ptr<StateChangeParams> p(
554 static_cast<StateChangeParams*>(message->pdata));
555 SignalStateChange(this, p->data());
556 break;
557 }
558 case MSG_DO_PAUSE: {
559 Pause(true);
560 break;
561 }
562 case MSG_DO_UNPAUSE: {
563 Pause(false);
564 break;
565 }
566 default: {
567 ASSERT(false);
568 }
569 }
426 } 570 }
427 571
428 // Get the distance between the supported and desired formats. 572 // Get the distance between the supported and desired formats.
429 // Prioritization is done according to this algorithm: 573 // Prioritization is done according to this algorithm:
430 // 1) Width closeness. If not same, we prefer wider. 574 // 1) Width closeness. If not same, we prefer wider.
431 // 2) Height closeness. If not same, we prefer higher. 575 // 2) Height closeness. If not same, we prefer higher.
432 // 3) Framerate closeness. If not same, we prefer faster. 576 // 3) Framerate closeness. If not same, we prefer faster.
433 // 4) Compression. If desired format has a specific fourcc, we need exact match; 577 // 4) Compression. If desired format has a specific fourcc, we need exact match;
434 // otherwise, we use preference. 578 // otherwise, we use preference.
435 int64_t VideoCapturer::GetFormatDistance(const VideoFormat& desired, 579 int64_t VideoCapturer::GetFormatDistance(const VideoFormat& desired,
436 const VideoFormat& supported) { 580 const VideoFormat& supported) {
437 RTC_DCHECK(thread_checker_.CalledOnValidThread());
438 int64_t distance = kMaxDistance; 581 int64_t distance = kMaxDistance;
439 582
440 // Check fourcc. 583 // Check fourcc.
441 uint32_t supported_fourcc = CanonicalFourCC(supported.fourcc); 584 uint32_t supported_fourcc = CanonicalFourCC(supported.fourcc);
442 int64_t delta_fourcc = kMaxDistance; 585 int64_t delta_fourcc = kMaxDistance;
443 if (FOURCC_ANY == desired.fourcc) { 586 if (FOURCC_ANY == desired.fourcc) {
444 // Any fourcc is OK for the desired. Use preference to find best fourcc. 587 // Any fourcc is OK for the desired. Use preference to find best fourcc.
445 std::vector<uint32_t> preferred_fourccs; 588 std::vector<uint32_t> preferred_fourccs;
446 if (!GetPreferredFourccs(&preferred_fourccs)) { 589 if (!GetPreferredFourccs(&preferred_fourccs)) {
447 return distance; 590 return distance;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 } 681 }
539 if (filtered_supported_formats_.empty()) { 682 if (filtered_supported_formats_.empty()) {
540 // The device only captures at resolutions higher than |max_format_| this 683 // The device only captures at resolutions higher than |max_format_| this
541 // indicates that |max_format_| should be ignored as it is better to capture 684 // indicates that |max_format_| should be ignored as it is better to capture
542 // at too high a resolution than to not capture at all. 685 // at too high a resolution than to not capture at all.
543 filtered_supported_formats_ = supported_formats_; 686 filtered_supported_formats_ = supported_formats_;
544 } 687 }
545 } 688 }
546 689
547 bool VideoCapturer::ShouldFilterFormat(const VideoFormat& format) const { 690 bool VideoCapturer::ShouldFilterFormat(const VideoFormat& format) const {
548 RTC_DCHECK(thread_checker_.CalledOnValidThread());
549 if (!enable_camera_list_) { 691 if (!enable_camera_list_) {
550 return false; 692 return false;
551 } 693 }
552 return format.width > max_format_->width || 694 return format.width > max_format_->width ||
553 format.height > max_format_->height; 695 format.height > max_format_->height;
554 } 696 }
555 697
556 void VideoCapturer::UpdateStats(const CapturedFrame* captured_frame) { 698 void VideoCapturer::UpdateStats(const CapturedFrame* captured_frame) {
557 // Update stats protected from fetches from different thread. 699 // Update stats protected from fetches from different thread.
558 rtc::CritScope cs(&frame_stats_crit_); 700 rtc::CritScope cs(&frame_stats_crit_);
(...skipping 17 matching lines...) Expand all
576 void VideoCapturer::GetVariableSnapshot( 718 void VideoCapturer::GetVariableSnapshot(
577 const rtc::RollingAccumulator<T>& data, 719 const rtc::RollingAccumulator<T>& data,
578 VariableInfo<T>* stats) { 720 VariableInfo<T>* stats) {
579 stats->max_val = data.ComputeMax(); 721 stats->max_val = data.ComputeMax();
580 stats->mean = data.ComputeMean(); 722 stats->mean = data.ComputeMean();
581 stats->min_val = data.ComputeMin(); 723 stats->min_val = data.ComputeMin();
582 stats->variance = data.ComputeVariance(); 724 stats->variance = data.ComputeVariance();
583 } 725 }
584 726
585 } // namespace cricket 727 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/media/base/videocapturer.h ('k') | webrtc/media/base/videocapturer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698