OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 // user. When all frontends to this consider removing the black frame business. | 51 // user. When all frontends to this consider removing the black frame business. |
52 const int kNumBlackFramesOnMute = 30; | 52 const int kNumBlackFramesOnMute = 30; |
53 | 53 |
54 // MessageHandler constants. | 54 // MessageHandler constants. |
55 enum { | 55 enum { |
56 MSG_DO_PAUSE = 0, | 56 MSG_DO_PAUSE = 0, |
57 MSG_DO_UNPAUSE, | 57 MSG_DO_UNPAUSE, |
58 MSG_STATE_CHANGE | 58 MSG_STATE_CHANGE |
59 }; | 59 }; |
60 | 60 |
61 static const int64 kMaxDistance = ~(static_cast<int64>(1) << 63); | 61 static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63); |
62 #ifdef LINUX | 62 #ifdef LINUX |
63 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index. | 63 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index. |
64 #endif | 64 #endif |
65 static const int kDefaultScreencastFps = 5; | 65 static const int kDefaultScreencastFps = 5; |
66 typedef rtc::TypedMessageData<CaptureState> StateChangeParams; | 66 typedef rtc::TypedMessageData<CaptureState> StateChangeParams; |
67 | 67 |
68 // Limit stats data collections to ~20 seconds of 30fps data before dropping | 68 // Limit stats data collections to ~20 seconds of 30fps data before dropping |
69 // old data in case stats aren't reset for long periods of time. | 69 // old data in case stats aren't reset for long periods of time. |
70 static const size_t kMaxAccumulatorSize = 600; | 70 static const size_t kMaxAccumulatorSize = 600; |
71 | 71 |
72 } // namespace | 72 } // namespace |
73 | 73 |
74 ///////////////////////////////////////////////////////////////////// | 74 ///////////////////////////////////////////////////////////////////// |
75 // Implementation of struct CapturedFrame | 75 // Implementation of struct CapturedFrame |
76 ///////////////////////////////////////////////////////////////////// | 76 ///////////////////////////////////////////////////////////////////// |
77 CapturedFrame::CapturedFrame() | 77 CapturedFrame::CapturedFrame() |
78 : width(0), | 78 : width(0), |
79 height(0), | 79 height(0), |
80 fourcc(0), | 80 fourcc(0), |
81 pixel_width(0), | 81 pixel_width(0), |
82 pixel_height(0), | 82 pixel_height(0), |
83 elapsed_time(0), | 83 elapsed_time(0), |
84 time_stamp(0), | 84 time_stamp(0), |
85 data_size(0), | 85 data_size(0), |
86 rotation(0), | 86 rotation(0), |
87 data(NULL) {} | 87 data(NULL) {} |
88 | 88 |
89 // TODO(fbarchard): Remove this function once lmimediaengine stops using it. | 89 // TODO(fbarchard): Remove this function once lmimediaengine stops using it. |
90 bool CapturedFrame::GetDataSize(uint32* size) const { | 90 bool CapturedFrame::GetDataSize(uint32_t* size) const { |
91 if (!size || data_size == CapturedFrame::kUnknownDataSize) { | 91 if (!size || data_size == CapturedFrame::kUnknownDataSize) { |
92 return false; | 92 return false; |
93 } | 93 } |
94 *size = data_size; | 94 *size = data_size; |
95 return true; | 95 return true; |
96 } | 96 } |
97 | 97 |
98 webrtc::VideoRotation CapturedFrame::GetRotation() const { | 98 webrtc::VideoRotation CapturedFrame::GetRotation() const { |
99 ASSERT(rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270); | 99 ASSERT(rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270); |
100 return static_cast<webrtc::VideoRotation>(rotation); | 100 return static_cast<webrtc::VideoRotation>(rotation); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 bool VideoCapturer::GetBestCaptureFormat(const VideoFormat& format, | 269 bool VideoCapturer::GetBestCaptureFormat(const VideoFormat& format, |
270 VideoFormat* best_format) { | 270 VideoFormat* best_format) { |
271 // TODO(fbarchard): Directly support max_format. | 271 // TODO(fbarchard): Directly support max_format. |
272 UpdateFilteredSupportedFormats(); | 272 UpdateFilteredSupportedFormats(); |
273 const std::vector<VideoFormat>* supported_formats = GetSupportedFormats(); | 273 const std::vector<VideoFormat>* supported_formats = GetSupportedFormats(); |
274 | 274 |
275 if (supported_formats->empty()) { | 275 if (supported_formats->empty()) { |
276 return false; | 276 return false; |
277 } | 277 } |
278 LOG(LS_INFO) << " Capture Requested " << format.ToString(); | 278 LOG(LS_INFO) << " Capture Requested " << format.ToString(); |
279 int64 best_distance = kMaxDistance; | 279 int64_t best_distance = kMaxDistance; |
280 std::vector<VideoFormat>::const_iterator best = supported_formats->end(); | 280 std::vector<VideoFormat>::const_iterator best = supported_formats->end(); |
281 std::vector<VideoFormat>::const_iterator i; | 281 std::vector<VideoFormat>::const_iterator i; |
282 for (i = supported_formats->begin(); i != supported_formats->end(); ++i) { | 282 for (i = supported_formats->begin(); i != supported_formats->end(); ++i) { |
283 int64 distance = GetFormatDistance(format, *i); | 283 int64_t distance = GetFormatDistance(format, *i); |
284 // TODO(fbarchard): Reduce to LS_VERBOSE if/when camera capture is | 284 // TODO(fbarchard): Reduce to LS_VERBOSE if/when camera capture is |
285 // relatively bug free. | 285 // relatively bug free. |
286 LOG(LS_INFO) << " Supported " << i->ToString() << " distance " << distance; | 286 LOG(LS_INFO) << " Supported " << i->ToString() << " distance " << distance; |
287 if (distance < best_distance) { | 287 if (distance < best_distance) { |
288 best_distance = distance; | 288 best_distance = distance; |
289 best = i; | 289 best = i; |
290 } | 290 } |
291 } | 291 } |
292 if (supported_formats->end() == best) { | 292 if (supported_formats->end() == best) { |
293 LOG(LS_ERROR) << " No acceptable camera format found"; | 293 LOG(LS_ERROR) << " No acceptable camera format found"; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } else { | 356 } else { |
357 --black_frame_count_down_; | 357 --black_frame_count_down_; |
358 } | 358 } |
359 } | 359 } |
360 | 360 |
361 if (SignalVideoFrame.is_empty()) { | 361 if (SignalVideoFrame.is_empty()) { |
362 return; | 362 return; |
363 } | 363 } |
364 | 364 |
365 // Use a temporary buffer to scale | 365 // Use a temporary buffer to scale |
366 rtc::scoped_ptr<uint8[]> scale_buffer; | 366 rtc::scoped_ptr<uint8_t[]> scale_buffer; |
367 | 367 |
368 if (IsScreencast()) { | 368 if (IsScreencast()) { |
369 int scaled_width, scaled_height; | 369 int scaled_width, scaled_height; |
370 if (screencast_max_pixels_ > 0) { | 370 if (screencast_max_pixels_ > 0) { |
371 ComputeScaleMaxPixels(captured_frame->width, captured_frame->height, | 371 ComputeScaleMaxPixels(captured_frame->width, captured_frame->height, |
372 screencast_max_pixels_, &scaled_width, &scaled_height); | 372 screencast_max_pixels_, &scaled_width, &scaled_height); |
373 } else { | 373 } else { |
374 int desired_screencast_fps = capture_format_.get() ? | 374 int desired_screencast_fps = capture_format_.get() ? |
375 VideoFormat::IntervalToFps(capture_format_->interval) : | 375 VideoFormat::IntervalToFps(capture_format_->interval) : |
376 kDefaultScreencastFps; | 376 kDefaultScreencastFps; |
377 ComputeScale(captured_frame->width, captured_frame->height, | 377 ComputeScale(captured_frame->width, captured_frame->height, |
378 desired_screencast_fps, &scaled_width, &scaled_height); | 378 desired_screencast_fps, &scaled_width, &scaled_height); |
379 } | 379 } |
380 | 380 |
381 if (FOURCC_ARGB == captured_frame->fourcc && | 381 if (FOURCC_ARGB == captured_frame->fourcc && |
382 (scaled_width != captured_frame->width || | 382 (scaled_width != captured_frame->width || |
383 scaled_height != captured_frame->height)) { | 383 scaled_height != captured_frame->height)) { |
384 if (scaled_width != scaled_width_ || scaled_height != scaled_height_) { | 384 if (scaled_width != scaled_width_ || scaled_height != scaled_height_) { |
385 LOG(LS_INFO) << "Scaling Screencast from " | 385 LOG(LS_INFO) << "Scaling Screencast from " |
386 << captured_frame->width << "x" | 386 << captured_frame->width << "x" |
387 << captured_frame->height << " to " | 387 << captured_frame->height << " to " |
388 << scaled_width << "x" << scaled_height; | 388 << scaled_width << "x" << scaled_height; |
389 scaled_width_ = scaled_width; | 389 scaled_width_ = scaled_width; |
390 scaled_height_ = scaled_height; | 390 scaled_height_ = scaled_height; |
391 } | 391 } |
392 CapturedFrame* modified_frame = | 392 CapturedFrame* modified_frame = |
393 const_cast<CapturedFrame*>(captured_frame); | 393 const_cast<CapturedFrame*>(captured_frame); |
394 const int modified_frame_size = scaled_width * scaled_height * 4; | 394 const int modified_frame_size = scaled_width * scaled_height * 4; |
395 scale_buffer.reset(new uint8[modified_frame_size]); | 395 scale_buffer.reset(new uint8_t[modified_frame_size]); |
396 // Compute new width such that width * height is less than maximum but | 396 // Compute new width such that width * height is less than maximum but |
397 // maintains original captured frame aspect ratio. | 397 // maintains original captured frame aspect ratio. |
398 // Round down width to multiple of 4 so odd width won't round up beyond | 398 // Round down width to multiple of 4 so odd width won't round up beyond |
399 // maximum, and so chroma channel is even width to simplify spatial | 399 // maximum, and so chroma channel is even width to simplify spatial |
400 // resampling. | 400 // resampling. |
401 libyuv::ARGBScale(reinterpret_cast<const uint8*>(captured_frame->data), | 401 libyuv::ARGBScale(reinterpret_cast<const uint8_t*>(captured_frame->data), |
402 captured_frame->width * 4, captured_frame->width, | 402 captured_frame->width * 4, captured_frame->width, |
403 captured_frame->height, | 403 captured_frame->height, scale_buffer.get(), |
404 scale_buffer.get(), | |
405 scaled_width * 4, scaled_width, scaled_height, | 404 scaled_width * 4, scaled_width, scaled_height, |
406 libyuv::kFilterBilinear); | 405 libyuv::kFilterBilinear); |
407 modified_frame->width = scaled_width; | 406 modified_frame->width = scaled_width; |
408 modified_frame->height = scaled_height; | 407 modified_frame->height = scaled_height; |
409 modified_frame->data_size = scaled_width * 4 * scaled_height; | 408 modified_frame->data_size = scaled_width * 4 * scaled_height; |
410 modified_frame->data = scale_buffer.get(); | 409 modified_frame->data = scale_buffer.get(); |
411 } | 410 } |
412 } | 411 } |
413 | 412 |
414 const int kYuy2Bpp = 2; | 413 const int kYuy2Bpp = 2; |
415 const int kArgbBpp = 4; | 414 const int kArgbBpp = 4; |
416 // TODO(fbarchard): Make a helper function to adjust pixels to square. | 415 // TODO(fbarchard): Make a helper function to adjust pixels to square. |
417 // TODO(fbarchard): Hook up experiment to scaling. | 416 // TODO(fbarchard): Hook up experiment to scaling. |
418 // TODO(fbarchard): Avoid scale and convert if muted. | 417 // TODO(fbarchard): Avoid scale and convert if muted. |
419 // Temporary buffer is scoped here so it will persist until i420_frame.Init() | 418 // Temporary buffer is scoped here so it will persist until i420_frame.Init() |
420 // makes a copy of the frame, converting to I420. | 419 // makes a copy of the frame, converting to I420. |
421 rtc::scoped_ptr<uint8[]> temp_buffer; | 420 rtc::scoped_ptr<uint8_t[]> temp_buffer; |
422 // YUY2 can be scaled vertically using an ARGB scaler. Aspect ratio is only | 421 // YUY2 can be scaled vertically using an ARGB scaler. Aspect ratio is only |
423 // a problem on OSX. OSX always converts webcams to YUY2 or UYVY. | 422 // a problem on OSX. OSX always converts webcams to YUY2 or UYVY. |
424 bool can_scale = | 423 bool can_scale = |
425 FOURCC_YUY2 == CanonicalFourCC(captured_frame->fourcc) || | 424 FOURCC_YUY2 == CanonicalFourCC(captured_frame->fourcc) || |
426 FOURCC_UYVY == CanonicalFourCC(captured_frame->fourcc); | 425 FOURCC_UYVY == CanonicalFourCC(captured_frame->fourcc); |
427 | 426 |
428 // If pixels are not square, optionally use vertical scaling to make them | 427 // If pixels are not square, optionally use vertical scaling to make them |
429 // square. Square pixels simplify the rest of the pipeline, including | 428 // square. Square pixels simplify the rest of the pipeline, including |
430 // effects and rendering. | 429 // effects and rendering. |
431 if (can_scale && square_pixel_aspect_ratio_ && | 430 if (can_scale && square_pixel_aspect_ratio_ && |
(...skipping 13 matching lines...) Expand all Loading... |
445 << captured_frame->width << "x" | 444 << captured_frame->width << "x" |
446 << captured_frame->height << " to " | 445 << captured_frame->height << " to " |
447 << scaled_width << "x" << scaled_height | 446 << scaled_width << "x" << scaled_height |
448 << " for PAR " | 447 << " for PAR " |
449 << captured_frame->pixel_width << "x" | 448 << captured_frame->pixel_width << "x" |
450 << captured_frame->pixel_height; | 449 << captured_frame->pixel_height; |
451 scaled_width_ = scaled_width; | 450 scaled_width_ = scaled_width; |
452 scaled_height_ = scaled_height; | 451 scaled_height_ = scaled_height; |
453 } | 452 } |
454 const int modified_frame_size = scaled_width * scaled_height * kYuy2Bpp; | 453 const int modified_frame_size = scaled_width * scaled_height * kYuy2Bpp; |
455 uint8* temp_buffer_data; | 454 uint8_t* temp_buffer_data; |
456 // Pixels are wide and short; Increasing height. Requires temporary buffer. | 455 // Pixels are wide and short; Increasing height. Requires temporary buffer. |
457 if (scaled_height > captured_frame->height) { | 456 if (scaled_height > captured_frame->height) { |
458 temp_buffer.reset(new uint8[modified_frame_size]); | 457 temp_buffer.reset(new uint8_t[modified_frame_size]); |
459 temp_buffer_data = temp_buffer.get(); | 458 temp_buffer_data = temp_buffer.get(); |
460 } else { | 459 } else { |
461 // Pixels are narrow and tall; Decreasing height. Scale will be done | 460 // Pixels are narrow and tall; Decreasing height. Scale will be done |
462 // in place. | 461 // in place. |
463 temp_buffer_data = reinterpret_cast<uint8*>(captured_frame->data); | 462 temp_buffer_data = reinterpret_cast<uint8_t*>(captured_frame->data); |
464 } | 463 } |
465 | 464 |
466 // Use ARGBScaler to vertically scale the YUY2 image, adjusting for 16 bpp. | 465 // Use ARGBScaler to vertically scale the YUY2 image, adjusting for 16 bpp. |
467 libyuv::ARGBScale(reinterpret_cast<const uint8*>(captured_frame->data), | 466 libyuv::ARGBScale(reinterpret_cast<const uint8_t*>(captured_frame->data), |
468 captured_frame->width * kYuy2Bpp, // Stride for YUY2. | 467 captured_frame->width * kYuy2Bpp, // Stride for YUY2. |
469 captured_frame->width * kYuy2Bpp / kArgbBpp, // Width. | 468 captured_frame->width * kYuy2Bpp / kArgbBpp, // Width. |
470 abs(captured_frame->height), // Height. | 469 abs(captured_frame->height), // Height. |
471 temp_buffer_data, | 470 temp_buffer_data, |
472 scaled_width * kYuy2Bpp, // Stride for YUY2. | 471 scaled_width * kYuy2Bpp, // Stride for YUY2. |
473 scaled_width * kYuy2Bpp / kArgbBpp, // Width. | 472 scaled_width * kYuy2Bpp / kArgbBpp, // Width. |
474 abs(scaled_height), // New height. | 473 abs(scaled_height), // New height. |
475 libyuv::kFilterBilinear); | 474 libyuv::kFilterBilinear); |
476 modified_frame->width = scaled_width; | 475 modified_frame->width = scaled_width; |
477 modified_frame->height = scaled_height; | 476 modified_frame->height = scaled_height; |
478 modified_frame->pixel_width = 1; | 477 modified_frame->pixel_width = 1; |
479 modified_frame->pixel_height = 1; | 478 modified_frame->pixel_height = 1; |
480 modified_frame->data_size = modified_frame_size; | 479 modified_frame->data_size = modified_frame_size; |
481 modified_frame->data = temp_buffer_data; | 480 modified_frame->data = temp_buffer_data; |
482 } | 481 } |
483 | 482 |
484 // Size to crop captured frame to. This adjusts the captured frames | 483 // Size to crop captured frame to. This adjusts the captured frames |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 } | 583 } |
585 } | 584 } |
586 | 585 |
587 // Get the distance between the supported and desired formats. | 586 // Get the distance between the supported and desired formats. |
588 // Prioritization is done according to this algorithm: | 587 // Prioritization is done according to this algorithm: |
589 // 1) Width closeness. If not same, we prefer wider. | 588 // 1) Width closeness. If not same, we prefer wider. |
590 // 2) Height closeness. If not same, we prefer higher. | 589 // 2) Height closeness. If not same, we prefer higher. |
591 // 3) Framerate closeness. If not same, we prefer faster. | 590 // 3) Framerate closeness. If not same, we prefer faster. |
592 // 4) Compression. If desired format has a specific fourcc, we need exact match; | 591 // 4) Compression. If desired format has a specific fourcc, we need exact match; |
593 // otherwise, we use preference. | 592 // otherwise, we use preference. |
594 int64 VideoCapturer::GetFormatDistance(const VideoFormat& desired, | 593 int64_t VideoCapturer::GetFormatDistance(const VideoFormat& desired, |
595 const VideoFormat& supported) { | 594 const VideoFormat& supported) { |
596 int64 distance = kMaxDistance; | 595 int64_t distance = kMaxDistance; |
597 | 596 |
598 // Check fourcc. | 597 // Check fourcc. |
599 uint32 supported_fourcc = CanonicalFourCC(supported.fourcc); | 598 uint32_t supported_fourcc = CanonicalFourCC(supported.fourcc); |
600 int64 delta_fourcc = kMaxDistance; | 599 int64_t delta_fourcc = kMaxDistance; |
601 if (FOURCC_ANY == desired.fourcc) { | 600 if (FOURCC_ANY == desired.fourcc) { |
602 // Any fourcc is OK for the desired. Use preference to find best fourcc. | 601 // Any fourcc is OK for the desired. Use preference to find best fourcc. |
603 std::vector<uint32> preferred_fourccs; | 602 std::vector<uint32_t> preferred_fourccs; |
604 if (!GetPreferredFourccs(&preferred_fourccs)) { | 603 if (!GetPreferredFourccs(&preferred_fourccs)) { |
605 return distance; | 604 return distance; |
606 } | 605 } |
607 | 606 |
608 for (size_t i = 0; i < preferred_fourccs.size(); ++i) { | 607 for (size_t i = 0; i < preferred_fourccs.size(); ++i) { |
609 if (supported_fourcc == CanonicalFourCC(preferred_fourccs[i])) { | 608 if (supported_fourcc == CanonicalFourCC(preferred_fourccs[i])) { |
610 delta_fourcc = i; | 609 delta_fourcc = i; |
611 #ifdef LINUX | 610 #ifdef LINUX |
612 // For HD avoid YU12 which is a software conversion and has 2 bugs | 611 // For HD avoid YU12 which is a software conversion and has 2 bugs |
613 // b/7326348 b/6960899. Reenable when fixed. | 612 // b/7326348 b/6960899. Reenable when fixed. |
(...skipping 10 matching lines...) Expand all Loading... |
624 } | 623 } |
625 | 624 |
626 if (kMaxDistance == delta_fourcc) { | 625 if (kMaxDistance == delta_fourcc) { |
627 // Failed to match fourcc. | 626 // Failed to match fourcc. |
628 return distance; | 627 return distance; |
629 } | 628 } |
630 | 629 |
631 // Check resolution and fps. | 630 // Check resolution and fps. |
632 int desired_width = desired.width; | 631 int desired_width = desired.width; |
633 int desired_height = desired.height; | 632 int desired_height = desired.height; |
634 int64 delta_w = supported.width - desired_width; | 633 int64_t delta_w = supported.width - desired_width; |
635 float supported_fps = VideoFormat::IntervalToFpsFloat(supported.interval); | 634 float supported_fps = VideoFormat::IntervalToFpsFloat(supported.interval); |
636 float delta_fps = | 635 float delta_fps = |
637 supported_fps - VideoFormat::IntervalToFpsFloat(desired.interval); | 636 supported_fps - VideoFormat::IntervalToFpsFloat(desired.interval); |
638 // Check height of supported height compared to height we would like it to be. | 637 // Check height of supported height compared to height we would like it to be. |
639 int64 aspect_h = | 638 int64_t aspect_h = desired_width |
640 desired_width ? supported.width * desired_height / desired_width | 639 ? supported.width * desired_height / desired_width |
641 : desired_height; | 640 : desired_height; |
642 int64 delta_h = supported.height - aspect_h; | 641 int64_t delta_h = supported.height - aspect_h; |
643 | 642 |
644 distance = 0; | 643 distance = 0; |
645 // Set high penalty if the supported format is lower than the desired format. | 644 // Set high penalty if the supported format is lower than the desired format. |
646 // 3x means we would prefer down to down to 3/4, than up to double. | 645 // 3x means we would prefer down to down to 3/4, than up to double. |
647 // But we'd prefer up to double than down to 1/2. This is conservative, | 646 // But we'd prefer up to double than down to 1/2. This is conservative, |
648 // strongly avoiding going down in resolution, similar to | 647 // strongly avoiding going down in resolution, similar to |
649 // the old method, but not completely ruling it out in extreme situations. | 648 // the old method, but not completely ruling it out in extreme situations. |
650 // It also ignores framerate, which is often very low at high resolutions. | 649 // It also ignores framerate, which is often very low at high resolutions. |
651 // TODO(fbarchard): Improve logic to use weighted factors. | 650 // TODO(fbarchard): Improve logic to use weighted factors. |
652 static const int kDownPenalty = -3; | 651 static const int kDownPenalty = -3; |
653 if (delta_w < 0) { | 652 if (delta_w < 0) { |
654 delta_w = delta_w * kDownPenalty; | 653 delta_w = delta_w * kDownPenalty; |
655 } | 654 } |
656 if (delta_h < 0) { | 655 if (delta_h < 0) { |
657 delta_h = delta_h * kDownPenalty; | 656 delta_h = delta_h * kDownPenalty; |
658 } | 657 } |
659 // Require camera fps to be at least 80% of what is requested if resolution | 658 // Require camera fps to be at least 80% of what is requested if resolution |
660 // matches. | 659 // matches. |
661 // Require camera fps to be at least 96% of what is requested, or higher, | 660 // Require camera fps to be at least 96% of what is requested, or higher, |
662 // if resolution differs. 96% allows for slight variations in fps. e.g. 29.97 | 661 // if resolution differs. 96% allows for slight variations in fps. e.g. 29.97 |
663 if (delta_fps < 0) { | 662 if (delta_fps < 0) { |
664 float min_desirable_fps = delta_w ? | 663 float min_desirable_fps = delta_w ? |
665 VideoFormat::IntervalToFpsFloat(desired.interval) * 28.f / 30.f : | 664 VideoFormat::IntervalToFpsFloat(desired.interval) * 28.f / 30.f : |
666 VideoFormat::IntervalToFpsFloat(desired.interval) * 23.f / 30.f; | 665 VideoFormat::IntervalToFpsFloat(desired.interval) * 23.f / 30.f; |
667 delta_fps = -delta_fps; | 666 delta_fps = -delta_fps; |
668 if (supported_fps < min_desirable_fps) { | 667 if (supported_fps < min_desirable_fps) { |
669 distance |= static_cast<int64>(1) << 62; | 668 distance |= static_cast<int64_t>(1) << 62; |
670 } else { | 669 } else { |
671 distance |= static_cast<int64>(1) << 15; | 670 distance |= static_cast<int64_t>(1) << 15; |
672 } | 671 } |
673 } | 672 } |
674 int64 idelta_fps = static_cast<int>(delta_fps); | 673 int64_t idelta_fps = static_cast<int>(delta_fps); |
675 | 674 |
676 // 12 bits for width and height and 8 bits for fps and fourcc. | 675 // 12 bits for width and height and 8 bits for fps and fourcc. |
677 distance |= | 676 distance |= |
678 (delta_w << 28) | (delta_h << 16) | (idelta_fps << 8) | delta_fourcc; | 677 (delta_w << 28) | (delta_h << 16) | (idelta_fps << 8) | delta_fourcc; |
679 | 678 |
680 return distance; | 679 return distance; |
681 } | 680 } |
682 | 681 |
683 void VideoCapturer::UpdateFilteredSupportedFormats() { | 682 void VideoCapturer::UpdateFilteredSupportedFormats() { |
684 filtered_supported_formats_.clear(); | 683 filtered_supported_formats_.clear(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 void VideoCapturer::GetVariableSnapshot( | 732 void VideoCapturer::GetVariableSnapshot( |
734 const rtc::RollingAccumulator<T>& data, | 733 const rtc::RollingAccumulator<T>& data, |
735 VariableInfo<T>* stats) { | 734 VariableInfo<T>* stats) { |
736 stats->max_val = data.ComputeMax(); | 735 stats->max_val = data.ComputeMax(); |
737 stats->mean = data.ComputeMean(); | 736 stats->mean = data.ComputeMean(); |
738 stats->min_val = data.ComputeMin(); | 737 stats->min_val = data.ComputeMin(); |
739 stats->variance = data.ComputeVariance(); | 738 stats->variance = data.ComputeVariance(); |
740 } | 739 } |
741 | 740 |
742 } // namespace cricket | 741 } // namespace cricket |
OLD | NEW |