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

Side by Side Diff: content/renderer/media/media_stream_video_source.cc

Issue 246433006: Change MediaStreamVideoSource to output different resolutions to different tracks depending on the … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/media_stream_video_source.h" 5 #include "content/renderer/media/media_stream_video_source.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 10
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "content/renderer/media/media_stream_dependency_factory.h"
15 #include "content/renderer/media/media_stream_video_track.h" 14 #include "content/renderer/media/media_stream_video_track.h"
16 #include "content/renderer/media/video_frame_deliverer.h" 15 #include "content/renderer/media/video_track_adapter.h"
17 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
18 16
19 namespace content { 17 namespace content {
20 18
21 // Constraint keys. Specified by draft-alvestrand-constraints-resolution-00b 19 // Constraint keys. Specified by draft-alvestrand-constraints-resolution-00b
22 const char MediaStreamVideoSource::kMinAspectRatio[] = "minAspectRatio"; 20 const char MediaStreamVideoSource::kMinAspectRatio[] = "minAspectRatio";
23 const char MediaStreamVideoSource::kMaxAspectRatio[] = "maxAspectRatio"; 21 const char MediaStreamVideoSource::kMaxAspectRatio[] = "maxAspectRatio";
24 const char MediaStreamVideoSource::kMaxWidth[] = "maxWidth"; 22 const char MediaStreamVideoSource::kMaxWidth[] = "maxWidth";
25 const char MediaStreamVideoSource::kMinWidth[] = "minWidth"; 23 const char MediaStreamVideoSource::kMinWidth[] = "minWidth";
26 const char MediaStreamVideoSource::kMaxHeight[] = "maxHeight"; 24 const char MediaStreamVideoSource::kMaxHeight[] = "maxHeight";
27 const char MediaStreamVideoSource::kMinHeight[] = "minHeight"; 25 const char MediaStreamVideoSource::kMinHeight[] = "minHeight";
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 return true; 80 return true;
83 } 81 }
84 82
85 // Ignore Chrome specific Tab capture constraints. 83 // Ignore Chrome specific Tab capture constraints.
86 if (constraint_name == kMediaStreamSource || 84 if (constraint_name == kMediaStreamSource ||
87 constraint_name == kMediaStreamSourceId) 85 constraint_name == kMediaStreamSourceId)
88 return true; 86 return true;
89 87
90 if (constraint_name == MediaStreamVideoSource::kMinAspectRatio || 88 if (constraint_name == MediaStreamVideoSource::kMinAspectRatio ||
91 constraint_name == MediaStreamVideoSource::kMaxAspectRatio) { 89 constraint_name == MediaStreamVideoSource::kMaxAspectRatio) {
92 double double_value = 0; 90 return true;
93 base::StringToDouble(constraint_value, &double_value);
94
95 // The aspect ratio in |constraint.m_value| has been converted to a string
96 // and back to a double, so it may have a rounding error.
97 // E.g if the value 1/3 is converted to a string, the string will not have
98 // infinite length.
99 // We add a margin of 0.0005 which is high enough to detect the same aspect
100 // ratio but small enough to avoid matching wrong aspect ratios.
101 const double kRoundingTruncation = 0.0005;
102 double ratio = static_cast<double>(format->frame_size.width()) /
103 format->frame_size.height();
104 if (constraint_name == MediaStreamVideoSource::kMinAspectRatio)
105 return (double_value <= ratio + kRoundingTruncation);
106 // Subtract 0.0005 to avoid rounding problems. Same as above.
107 return (double_value >= ratio - kRoundingTruncation);
108 } 91 }
109 92
110 int value; 93 int value;
111 if (!base::StringToInt(constraint_value, &value)) { 94 if (!base::StringToInt(constraint_value, &value)) {
112 DLOG(WARNING) << "Can't parse MediaStream constraint. Name:" 95 DLOG(WARNING) << "Can't parse MediaStream constraint. Name:"
113 << constraint_name << " Value:" << constraint_value; 96 << constraint_name << " Value:" << constraint_value;
114 return false; 97 return false;
115 } 98 }
116 if (constraint_name == MediaStreamVideoSource::kMinWidth) { 99 if (constraint_name == MediaStreamVideoSource::kMinWidth) {
117 return (value <= format->frame_size.width()); 100 return (value <= format->frame_size.width());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 int* value) { 193 int* value) {
211 blink::WebString value_str; 194 blink::WebString value_str;
212 bool ret = mandatory ? 195 bool ret = mandatory ?
213 constraints.getMandatoryConstraintValue(name, value_str) : 196 constraints.getMandatoryConstraintValue(name, value_str) :
214 constraints.getOptionalConstraintValue(name, value_str); 197 constraints.getOptionalConstraintValue(name, value_str);
215 if (ret) 198 if (ret)
216 base::StringToInt(value_str.utf8(), value); 199 base::StringToInt(value_str.utf8(), value);
217 return ret; 200 return ret;
218 } 201 }
219 202
203 bool GetConstraintValue(const blink::WebMediaConstraints& constraints,
204 bool mandatory, const blink::WebString& name,
205 double* value) {
206 blink::WebString value_str;
207 bool ret = mandatory ?
208 constraints.getMandatoryConstraintValue(name, value_str) :
209 constraints.getOptionalConstraintValue(name, value_str);
210 if (ret)
211 base::StringToDouble(value_str.utf8(), value);
212 return ret;
213 }
214
220 // Returns true if |constraint| has mandatory constraints. 215 // Returns true if |constraint| has mandatory constraints.
221 bool HasMandatoryConstraints(const blink::WebMediaConstraints& constraints) { 216 bool HasMandatoryConstraints(const blink::WebMediaConstraints& constraints) {
222 blink::WebVector<blink::WebMediaConstraint> mandatory_constraints; 217 blink::WebVector<blink::WebMediaConstraint> mandatory_constraints;
223 constraints.getMandatoryConstraints(mandatory_constraints); 218 constraints.getMandatoryConstraints(mandatory_constraints);
224 return !mandatory_constraints.isEmpty(); 219 return !mandatory_constraints.isEmpty();
225 } 220 }
226 221
227 // Retrieve the desired max width and height from |constraints|. 222 // Retrieve the desired max width and height from |constraints|. If not set,
223 // the |desired_width| and |desired_height| is to
224 // std::numeric_limits<int>::max();
228 void GetDesiredMaxWidthAndHeight(const blink::WebMediaConstraints& constraints, 225 void GetDesiredMaxWidthAndHeight(const blink::WebMediaConstraints& constraints,
229 int* desired_width, int* desired_height) { 226 int* desired_width, int* desired_height) {
227 *desired_width = std::numeric_limits<int>::max();
228 *desired_height = std::numeric_limits<int>::max();;
230 bool mandatory = GetConstraintValue(constraints, true, 229 bool mandatory = GetConstraintValue(constraints, true,
231 MediaStreamVideoSource::kMaxWidth, 230 MediaStreamVideoSource::kMaxWidth,
232 desired_width); 231 desired_width);
233 mandatory |= GetConstraintValue(constraints, true, 232 mandatory |= GetConstraintValue(constraints, true,
234 MediaStreamVideoSource::kMaxHeight, 233 MediaStreamVideoSource::kMaxHeight,
235 desired_height); 234 desired_height);
236 if (mandatory) 235 if (mandatory)
237 return; 236 return;
238 237
239 GetConstraintValue(constraints, false, MediaStreamVideoSource::kMaxWidth, 238 GetConstraintValue(constraints, false, MediaStreamVideoSource::kMaxWidth,
240 desired_width); 239 desired_width);
241 GetConstraintValue(constraints, false, MediaStreamVideoSource::kMaxHeight, 240 GetConstraintValue(constraints, false, MediaStreamVideoSource::kMaxHeight,
242 desired_height); 241 desired_height);
243 } 242 }
244 243
244 void GetDesiredMinAndMaxAspectRatio(
245 const blink::WebMediaConstraints& constraints,
246 double* min_aspect_ratio,
247 double* max_aspect_ratio) {
248 *min_aspect_ratio = 0;
249 *max_aspect_ratio = std::numeric_limits<double>::max();
250
251 bool mandatory = GetConstraintValue(constraints, true,
252 MediaStreamVideoSource::kMinAspectRatio,
253 min_aspect_ratio);
254 mandatory |= GetConstraintValue(constraints, true,
255 MediaStreamVideoSource::kMaxAspectRatio,
256 max_aspect_ratio);
257 if (!mandatory &&
258 !GetConstraintValue(constraints, false,
259 MediaStreamVideoSource::kMinAspectRatio,
260 min_aspect_ratio) &&
261 !GetConstraintValue(constraints, false,
262 MediaStreamVideoSource::kMaxAspectRatio,
263 max_aspect_ratio)) {
264 return;
265 }
266 // The aspect ratio in |constraint.m_value| has been converted to a string
267 // and back to a double, so it may have a rounding error.
268 // E.g if the value 1/3 is converted to a string, the string will not have
269 // infinite length.
270 // We add a margin of 0.0005 which is high enough to detect the same aspect
271 // ratio but small enough to avoid matching wrong aspect ratios.
272 const double kRoundingTruncation = 0.0005;
273 if (*min_aspect_ratio != 0)
mcasas 2014/05/07 14:10:43 |min_aspect_ratio| is a double, so this comparison
perkj_chrome 2014/05/08 11:29:47 Why would it be true? I set it to 0 at line 248?
mcasas 2014/05/09 07:46:24 A float cannot be 0.0 exactly, and the most likely
274 *min_aspect_ratio += kRoundingTruncation;
275 if (*max_aspect_ratio != std::numeric_limits<double>::max())
276 *max_aspect_ratio -= kRoundingTruncation;
277 }
278
245 const media::VideoCaptureFormat& GetBestFormatBasedOnArea( 279 const media::VideoCaptureFormat& GetBestFormatBasedOnArea(
246 const media::VideoCaptureFormats& formats, 280 const media::VideoCaptureFormats& formats,
247 int area) { 281 int area) {
248 media::VideoCaptureFormats::const_iterator it = formats.begin(); 282 media::VideoCaptureFormats::const_iterator it = formats.begin();
249 media::VideoCaptureFormats::const_iterator best_it = formats.begin(); 283 media::VideoCaptureFormats::const_iterator best_it = formats.begin();
250 int best_diff = std::numeric_limits<int>::max(); 284 int best_diff = std::numeric_limits<int>::max();
251 for (; it != formats.end(); ++it) { 285 for (; it != formats.end(); ++it) {
252 int diff = abs(area - it->frame_size.width() * it->frame_size.height()); 286 int diff = abs(area - it->frame_size.width() * it->frame_size.height());
253 if (diff < best_diff) { 287 if (diff < best_diff) {
254 best_diff = diff; 288 best_diff = diff;
255 best_it = it; 289 best_it = it;
256 } 290 }
257 } 291 }
258 return *best_it; 292 return *best_it;
259 } 293 }
260 294
261 // Find the format that best matches the default video size. 295 // Find the format that best matches the default video size.
262 // This algorithm is chosen since a resolution must be picked even if no 296 // This algorithm is chosen since a resolution must be picked even if no
263 // constraints are provided. We don't just select the maximum supported 297 // constraints are provided. We don't just select the maximum supported
264 // resolution since higher resolutions cost more in terms of complexity and 298 // resolution since higher resolutions cost more in terms of complexity and
265 // many cameras have lower frame rate and have more noise in the image at 299 // many cameras have lower frame rate and have more noise in the image at
266 // their maximum supported resolution. 300 // their maximum supported resolution.
267 void GetBestCaptureFormat( 301 void GetBestCaptureFormat(
268 const media::VideoCaptureFormats& formats, 302 const media::VideoCaptureFormats& formats,
269 const blink::WebMediaConstraints& constraints, 303 const blink::WebMediaConstraints& constraints,
270 media::VideoCaptureFormat* capture_format, 304 media::VideoCaptureFormat* capture_format) {
271 gfx::Size* max_frame_output_size) {
272 DCHECK(!formats.empty()); 305 DCHECK(!formats.empty());
273 DCHECK(max_frame_output_size);
274 306
275 int max_width = std::numeric_limits<int>::max(); 307 int max_width = std::numeric_limits<int>::max();
276 int max_height = std::numeric_limits<int>::max();; 308 int max_height = std::numeric_limits<int>::max();;
277 GetDesiredMaxWidthAndHeight(constraints, &max_width, &max_height); 309 GetDesiredMaxWidthAndHeight(constraints, &max_width, &max_height);
278 310
279 *capture_format = GetBestFormatBasedOnArea( 311 *capture_format = GetBestFormatBasedOnArea(
280 formats, 312 formats,
281 std::min(max_width, MediaStreamVideoSource::kDefaultWidth) * 313 std::min(max_width, MediaStreamVideoSource::kDefaultWidth) *
282 std::min(max_height, MediaStreamVideoSource::kDefaultHeight)); 314 std::min(max_height, MediaStreamVideoSource::kDefaultHeight));
283
284 max_frame_output_size->set_width(max_width);
285 max_frame_output_size->set_height(max_height);
286 }
287
288 // Empty method used for keeping a reference to the original media::VideoFrame
289 // in MediaStreamVideoSource::FrameDeliverer::DeliverFrameOnIO if cropping is
290 // needed. The reference to |frame| is kept in the closure that calls this
291 // method.
292 void ReleaseOriginalFrame(
293 const scoped_refptr<media::VideoFrame>& frame) {
294 } 315 }
295 316
296 } // anonymous namespace 317 } // anonymous namespace
297 318
298 // Helper class used for delivering video frames to all registered tracks
299 // on the IO-thread.
300 class MediaStreamVideoSource::FrameDeliverer : public VideoFrameDeliverer {
301 public:
302 FrameDeliverer(
303 const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
304 : VideoFrameDeliverer(io_message_loop) {
305 }
306
307 // Register |callback| to receive video frames of max size
308 // |max_frame_output_size| on the IO thread.
309 // TODO(perkj): Currently |max_frame_output_size| must be the same for all
310 // |callbacks|.
311 void AddCallback(void* id,
312 const VideoCaptureDeliverFrameCB& callback,
313 const gfx::Size& max_frame_output_size) {
314 DCHECK(thread_checker().CalledOnValidThread());
315 io_message_loop()->PostTask(
316 FROM_HERE,
317 base::Bind(
318 &FrameDeliverer::AddCallbackWithResolutionOnIO,
319 this, id, callback, max_frame_output_size));
320 }
321
322 virtual void DeliverFrameOnIO(
323 const scoped_refptr<media::VideoFrame>& frame,
324 const media::VideoCaptureFormat& format) OVERRIDE {
325 DCHECK(io_message_loop()->BelongsToCurrentThread());
326 TRACE_EVENT0("video", "MediaStreamVideoSource::DeliverFrameOnIO");
327 if (max_output_size_.IsEmpty())
328 return; // Frame received before the output has been decided.
329
330 scoped_refptr<media::VideoFrame> video_frame(frame);
331 const gfx::Size& visible_size = frame->visible_rect().size();
332 if (visible_size.width() > max_output_size_.width() ||
333 visible_size.height() > max_output_size_.height()) {
334 // If |frame| is not the size that is expected, we need to crop it by
335 // providing a new |visible_rect|. The new visible rect must be within the
336 // original |visible_rect|.
337 gfx::Rect output_rect = frame->visible_rect();
338 output_rect.ClampToCenteredSize(max_output_size_);
339 // TODO(perkj): Allow cropping of textures once http://crbug/362521 is
340 // fixed.
341 if (frame->format() != media::VideoFrame::NATIVE_TEXTURE) {
342 video_frame = media::VideoFrame::WrapVideoFrame(
343 frame,
344 output_rect,
345 output_rect.size(),
346 base::Bind(&ReleaseOriginalFrame, frame));
347 }
348 }
349 VideoFrameDeliverer::DeliverFrameOnIO(video_frame, format);
350 }
351
352 protected:
353 virtual ~FrameDeliverer() {
354 }
355
356 void AddCallbackWithResolutionOnIO(
357 void* id,
358 const VideoCaptureDeliverFrameCB& callback,
359 const gfx::Size& max_frame_output_size) {
360 DCHECK(io_message_loop()->BelongsToCurrentThread());
361 // Currently we only support one frame output size.
362 DCHECK(!max_frame_output_size.IsEmpty() &&
363 (max_output_size_.IsEmpty() ||
364 max_output_size_ == max_frame_output_size));
365 max_output_size_ = max_frame_output_size;
366 VideoFrameDeliverer::AddCallbackOnIO(id, callback);
367 }
368
369 private:
370 gfx::Size max_output_size_;
371 };
372
373 // static 319 // static
374 MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource( 320 MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource(
375 const blink::WebMediaStreamSource& source) { 321 const blink::WebMediaStreamSource& source) {
376 return static_cast<MediaStreamVideoSource*>(source.extraData()); 322 return static_cast<MediaStreamVideoSource*>(source.extraData());
377 } 323 }
378 324
379 // static 325 // static
380 bool MediaStreamVideoSource::IsConstraintSupported(const std::string& name) { 326 bool MediaStreamVideoSource::IsConstraintSupported(const std::string& name) {
381 for (size_t i = 0; i < arraysize(kSupportedConstraints); ++i) { 327 for (size_t i = 0; i < arraysize(kSupportedConstraints); ++i) {
382 if (kSupportedConstraints[i] == name) 328 if (kSupportedConstraints[i] == name)
383 return true; 329 return true;
384 } 330 }
385 return false; 331 return false;
386 } 332 }
387 333
388 MediaStreamVideoSource::MediaStreamVideoSource( 334 MediaStreamVideoSource::MediaStreamVideoSource(
389 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) 335 const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
390 : state_(NEW), 336 : state_(NEW),
391 frame_deliverer_( 337 track_adapter_(
392 new MediaStreamVideoSource::FrameDeliverer(io_message_loop)), 338 new VideoTrackAdapter(io_message_loop)),
mcasas 2014/05/07 14:10:43 nit: Fits in one line.
perkj_chrome 2014/05/08 11:29:47 Done.
393 weak_factory_(this) { 339 weak_factory_(this) {
394 } 340 }
395 341
396 MediaStreamVideoSource::~MediaStreamVideoSource() { 342 MediaStreamVideoSource::~MediaStreamVideoSource() {
397 DVLOG(3) << "~MediaStreamVideoSource()"; 343 DVLOG(3) << "~MediaStreamVideoSource()";
398 } 344 }
399 345
400 void MediaStreamVideoSource::AddTrack( 346 void MediaStreamVideoSource::AddTrack(
401 MediaStreamVideoTrack* track, 347 MediaStreamVideoTrack* track,
402 const VideoCaptureDeliverFrameCB& frame_callback, 348 const VideoCaptureDeliverFrameCB& frame_callback,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 } 388 }
443 } 389 }
444 } 390 }
445 391
446 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { 392 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) {
447 DCHECK(CalledOnValidThread()); 393 DCHECK(CalledOnValidThread());
448 std::vector<MediaStreamVideoTrack*>::iterator it = 394 std::vector<MediaStreamVideoTrack*>::iterator it =
449 std::find(tracks_.begin(), tracks_.end(), video_track); 395 std::find(tracks_.begin(), tracks_.end(), video_track);
450 DCHECK(it != tracks_.end()); 396 DCHECK(it != tracks_.end());
451 tracks_.erase(it); 397 tracks_.erase(it);
452 // Call |RemoveCallback| here even if adding the track has failed and 398
453 // frame_deliverer_->AddCallback has not been called. 399 // Check if the track is waiting for applying new constraints and remove
454 frame_deliverer_->RemoveCallback(video_track); 400 // it in that case.
401 for (std::vector<RequestedConstraints>::iterator it =
402 requested_constraints_.begin();
403 it != requested_constraints_.end(); ++it) {
404 if (it->track == video_track) {
405 requested_constraints_.erase(it);
406 break;
407 }
408 }
409 // Call |frame_adapter_->RemoveTrack| here even if adding the track has
410 // failed and |frame_adapter_->AddCallback| has not been called.
411 track_adapter_->RemoveTrack(video_track);
455 412
456 if (tracks_.empty()) 413 if (tracks_.empty())
457 StopSource(); 414 StopSource();
458 } 415 }
459 416
460 const scoped_refptr<base::MessageLoopProxy>& 417 const scoped_refptr<base::MessageLoopProxy>&
461 MediaStreamVideoSource::io_message_loop() const { 418 MediaStreamVideoSource::io_message_loop() const {
462 return frame_deliverer_->io_message_loop(); 419 return track_adapter_->io_message_loop();
mcasas 2014/05/07 14:10:43 I think nobody uses this getter anymore.
perkj_chrome 2014/05/08 11:29:47 no- its used by a few of the classes that inherits
463 } 420 }
464 421
465 void MediaStreamVideoSource::DoStopSource() { 422 void MediaStreamVideoSource::DoStopSource() {
466 DCHECK(CalledOnValidThread()); 423 DCHECK(CalledOnValidThread());
467 DVLOG(3) << "DoStopSource()"; 424 DVLOG(3) << "DoStopSource()";
468 if (state_ == ENDED) 425 if (state_ == ENDED)
469 return; 426 return;
470 StopSourceImpl(); 427 StopSourceImpl();
471 state_ = ENDED; 428 state_ = ENDED;
472 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); 429 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
473 } 430 }
474 431
475 void MediaStreamVideoSource::OnSupportedFormats( 432 void MediaStreamVideoSource::OnSupportedFormats(
476 const media::VideoCaptureFormats& formats) { 433 const media::VideoCaptureFormats& formats) {
477 DCHECK(CalledOnValidThread()); 434 DCHECK(CalledOnValidThread());
478 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); 435 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_);
479 436
480 supported_formats_ = formats; 437 supported_formats_ = formats;
481 if (!FindBestFormatWithConstraints(supported_formats_, 438 if (!FindBestFormatWithConstraints(supported_formats_,
482 &current_format_, 439 &current_format_)) {
483 &max_frame_output_size_,
484 &current_constraints_)) {
485 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); 440 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
486 // This object can be deleted after calling FinalizeAddTrack. See comment 441 // This object can be deleted after calling FinalizeAddTrack. See comment
487 // in the header file. 442 // in the header file.
488 FinalizeAddTrack(); 443 FinalizeAddTrack();
489 return; 444 return;
490 } 445 }
491 446
492 state_ = STARTING; 447 state_ = STARTING;
493 DVLOG(3) << "Starting the capturer with" 448 DVLOG(3) << "Starting the capturer with"
494 << " width = " << current_format_.frame_size.width() 449 << " width = " << current_format_.frame_size.width()
495 << " height = " << current_format_.frame_size.height() 450 << " height = " << current_format_.frame_size.height()
496 << " frame rate = " << current_format_.frame_rate; 451 << " frame rate = " << current_format_.frame_rate;
497 452
498 media::VideoCaptureParams params; 453 media::VideoCaptureParams params;
499 params.requested_format = current_format_; 454 params.requested_format = current_format_;
500 StartSourceImpl( 455 StartSourceImpl(
501 params, 456 params,
502 base::Bind(&MediaStreamVideoSource::FrameDeliverer::DeliverFrameOnIO, 457 base::Bind(&VideoTrackAdapter::DeliverFrameOnIO, track_adapter_));
503 frame_deliverer_));
504 } 458 }
505 459
506 bool MediaStreamVideoSource::FindBestFormatWithConstraints( 460 bool MediaStreamVideoSource::FindBestFormatWithConstraints(
507 const media::VideoCaptureFormats& formats, 461 const media::VideoCaptureFormats& formats,
508 media::VideoCaptureFormat* best_format, 462 media::VideoCaptureFormat* best_format) {
509 gfx::Size* max_frame_output_size,
510 blink::WebMediaConstraints* resulting_constraints) {
511 // Find the first constraints that we can fulfill. 463 // Find the first constraints that we can fulfill.
512 for (std::vector<RequestedConstraints>::iterator request_it = 464 for (std::vector<RequestedConstraints>::iterator request_it =
513 requested_constraints_.begin(); 465 requested_constraints_.begin();
514 request_it != requested_constraints_.end(); ++request_it) { 466 request_it != requested_constraints_.end(); ++request_it) {
515 const blink::WebMediaConstraints& requested_constraints = 467 const blink::WebMediaConstraints& requested_constraints =
516 request_it->constraints; 468 request_it->constraints;
517 469
518 // If the source doesn't support capability enumeration it is still ok if 470 // If the source doesn't support capability enumeration it is still ok if
519 // no mandatory constraints have been specified. That just means that 471 // no mandatory constraints have been specified. That just means that
520 // we will start with whatever format is native to the source. 472 // we will start with whatever format is native to the source.
521 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) { 473 if (formats.empty() && !HasMandatoryConstraints(requested_constraints)) {
522 *best_format = media::VideoCaptureFormat(); 474 *best_format = media::VideoCaptureFormat();
523 *resulting_constraints = requested_constraints;
524 *max_frame_output_size = gfx::Size(std::numeric_limits<int>::max(),
525 std::numeric_limits<int>::max());
526 return true; 475 return true;
527 } 476 }
528 media::VideoCaptureFormats filtered_formats = 477 media::VideoCaptureFormats filtered_formats =
529 FilterFormats(requested_constraints, formats); 478 FilterFormats(requested_constraints, formats);
530 if (filtered_formats.size() > 0) { 479 if (filtered_formats.size() > 0) {
531 // A request with constraints that can be fulfilled. 480 // A request with constraints that can be fulfilled.
532 GetBestCaptureFormat(filtered_formats, 481 GetBestCaptureFormat(filtered_formats,
533 requested_constraints, 482 requested_constraints,
534 best_format, 483 best_format);
535 max_frame_output_size);
536 *resulting_constraints= requested_constraints;
537 return true; 484 return true;
538 } 485 }
539 } 486 }
540 return false; 487 return false;
541 } 488 }
542 489
543 void MediaStreamVideoSource::OnStartDone(bool success) { 490 void MediaStreamVideoSource::OnStartDone(bool success) {
544 DCHECK(CalledOnValidThread()); 491 DCHECK(CalledOnValidThread());
545 DVLOG(3) << "OnStartDone({success =" << success << "})"; 492 DVLOG(3) << "OnStartDone({success =" << success << "})";
546 if (success) { 493 if (success) {
(...skipping 21 matching lines...) Expand all
568 it != callbacks.end(); ++it) { 515 it != callbacks.end(); ++it) {
569 // The track has been added successfully if the source has started and 516 // The track has been added successfully if the source has started and
570 // there are either no mandatory constraints and the source doesn't expose 517 // there are either no mandatory constraints and the source doesn't expose
571 // its format capabilities, or the constraints and the format match. 518 // its format capabilities, or the constraints and the format match.
572 // For example, a remote source doesn't expose its format capabilities. 519 // For example, a remote source doesn't expose its format capabilities.
573 bool success = 520 bool success =
574 state_ == STARTED && 521 state_ == STARTED &&
575 ((!current_format_.IsValid() && !HasMandatoryConstraints( 522 ((!current_format_.IsValid() && !HasMandatoryConstraints(
576 it->constraints)) || 523 it->constraints)) ||
577 !FilterFormats(it->constraints, formats).empty()); 524 !FilterFormats(it->constraints, formats).empty());
525
578 if (success) { 526 if (success) {
579 frame_deliverer_->AddCallback(it->track, it->frame_callback, 527 int max_width = std::numeric_limits<int>::max();
580 max_frame_output_size_); 528 int max_height = std::numeric_limits<int>::max();
529 GetDesiredMaxWidthAndHeight(it->constraints, &max_width, &max_height);
mcasas 2014/05/07 14:10:43 nit: Inside GetDesiredMaxWidthAndHeight(), |max_wi
perkj_chrome 2014/05/08 11:29:47 done
530 double max_aspect_ratio = std::numeric_limits<double>::max();
531 double min_aspect_ratio = 0;
532 GetDesiredMinAndMaxAspectRatio(it->constraints,
533 &min_aspect_ratio,
534 &max_aspect_ratio);
535 track_adapter_->AddTrack(it->track,it->frame_callback,
536 max_width, max_height,
537 min_aspect_ratio, max_aspect_ratio);
581 } 538 }
539
582 DVLOG(3) << "FinalizeAddTrack() success " << success; 540 DVLOG(3) << "FinalizeAddTrack() success " << success;
541
583 if (!it->callback.is_null()) 542 if (!it->callback.is_null())
584 it->callback.Run(this, success); 543 it->callback.Run(this, success);
585 } 544 }
586 } 545 }
587 546
588 void MediaStreamVideoSource::SetReadyState( 547 void MediaStreamVideoSource::SetReadyState(
589 blink::WebMediaStreamSource::ReadyState state) { 548 blink::WebMediaStreamSource::ReadyState state) {
590 if (!owner().isNull()) { 549 if (!owner().isNull()) {
591 owner().setReadyState(state); 550 owner().setReadyState(state);
592 } 551 }
(...skipping 11 matching lines...) Expand all
604 : track(track), 563 : track(track),
605 frame_callback(frame_callback), 564 frame_callback(frame_callback),
606 constraints(constraints), 565 constraints(constraints),
607 callback(callback) { 566 callback(callback) {
608 } 567 }
609 568
610 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { 569 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() {
611 } 570 }
612 571
613 } // namespace content 572 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698