video_capture_metrics.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/capture/video/video_capture_metrics.h"
  5. #include "base/containers/fixed_flat_map.h"
  6. #include "base/containers/flat_set.h"
  7. #include "base/containers/span.h"
  8. #include "base/logging.h"
  9. #include "base/metrics/histogram_functions.h"
  10. #include "base/metrics/histogram_macros.h"
  11. #include "ui/gfx/geometry/size.h"
  12. namespace {
  13. // These resolutions are ones supported on a test webcam. Names given
  14. // where possible, from https://en.wikipedia.org/wiki/List_of_common_resolutions
  15. enum class VideoResolutionDesignation {
  16. kUnknown = 0, // Catch-all for resolutions not understood.
  17. // Video Graphics Array resolutions
  18. kQQVGA = 1, // 160x120
  19. kHQVGA = 2, // 240x160
  20. kQVGA = 3, // 320x240
  21. kWQVGA = 4, // 432x240
  22. kHVGA = 5, // 480x320
  23. kVGA = 6, // 640x480
  24. kWVGA = 7, // 720x480
  25. kWSVGA = 8, // 1024x576
  26. kSVGA = 9, // 800x600
  27. // Extended Graphics Array resolutions
  28. kSXGA_MINUS = 10, // 1280x960
  29. kUXGA = 11, // 1600x1200
  30. kQXGA = 12, // 2048x1536
  31. // Common Intermediate Format resolutions
  32. kQCIF = 13, // 176x144
  33. kCIF = 14, // 352x288
  34. // High-definition resolutions.
  35. kNHD = 15, // 640x360
  36. kQHD = 16, // 960x540
  37. kHD_FULLSCREEN = 17, // 960x720
  38. kHD = 18, // 1280x720
  39. kHD_PLUS = 19, // 1600x900
  40. kFHD = 20, // 1920x1080
  41. kWQHD = 21, // 2560x1440
  42. kQHD_PLUS = 22, // 3200x1800
  43. k4K_UHD = 23, // 3840x2160
  44. kDCI_4K = 24, // 4096x2160
  45. k5K = 25, // 5120x2880
  46. k8K_UHD = 26, // 7680x4320
  47. // Odd resolutions with no name
  48. k160x90 = 27,
  49. k320x176 = 28,
  50. k320x180 = 29,
  51. k480x270 = 30,
  52. k544x288 = 31,
  53. k752x416 = 32,
  54. k864x480 = 33,
  55. k800x448 = 34,
  56. k960x544 = 35,
  57. k1184x656 = 36,
  58. k1392x768 = 37,
  59. k1504x832 = 38,
  60. k1600x896 = 39,
  61. k1712x960 = 40,
  62. k1792x1008 = 41,
  63. k2592x1944 = 42,
  64. kMaxValue = k2592x1944,
  65. };
  66. struct FrameSizeCompare {
  67. // Return true iff lhs < rhs.
  68. constexpr bool operator()(const gfx::Size& lhs, const gfx::Size& rhs) const {
  69. return (lhs.height() < rhs.height() ||
  70. (lhs.height() == rhs.height() && lhs.width() < rhs.width()));
  71. }
  72. };
  73. constexpr auto kResolutions =
  74. base::MakeFixedFlatMap<gfx::Size, VideoResolutionDesignation>(
  75. {
  76. {{160, 120}, VideoResolutionDesignation::kQQVGA},
  77. {{240, 160}, VideoResolutionDesignation::kHQVGA},
  78. {{320, 240}, VideoResolutionDesignation::kQVGA},
  79. {{432, 240}, VideoResolutionDesignation::kWQVGA},
  80. {{480, 320}, VideoResolutionDesignation::kHVGA},
  81. {{640, 480}, VideoResolutionDesignation::kVGA},
  82. {{720, 480}, VideoResolutionDesignation::kWVGA},
  83. {{1024, 576}, VideoResolutionDesignation::kWSVGA},
  84. {{800, 600}, VideoResolutionDesignation::kSVGA},
  85. {{1280, 960}, VideoResolutionDesignation::kSXGA_MINUS},
  86. {{1600, 1200}, VideoResolutionDesignation::kUXGA},
  87. {{2048, 1536}, VideoResolutionDesignation::kQXGA},
  88. {{176, 144}, VideoResolutionDesignation::kQCIF},
  89. {{352, 288}, VideoResolutionDesignation::kCIF},
  90. {{640, 360}, VideoResolutionDesignation::kNHD},
  91. {{960, 540}, VideoResolutionDesignation::kQHD},
  92. {{960, 720}, VideoResolutionDesignation::kHD_FULLSCREEN},
  93. {{1280, 720}, VideoResolutionDesignation::kHD},
  94. {{1600, 900}, VideoResolutionDesignation::kHD_PLUS},
  95. {{1920, 1080}, VideoResolutionDesignation::kFHD},
  96. {{2560, 1440}, VideoResolutionDesignation::kWQHD},
  97. {{3200, 1800}, VideoResolutionDesignation::kQHD_PLUS},
  98. {{3840, 2160}, VideoResolutionDesignation::k4K_UHD},
  99. {{4096, 2160}, VideoResolutionDesignation::kDCI_4K},
  100. {{5120, 2880}, VideoResolutionDesignation::k5K},
  101. {{7680, 4320}, VideoResolutionDesignation::k8K_UHD},
  102. {{160, 90}, VideoResolutionDesignation::k160x90},
  103. {{320, 176}, VideoResolutionDesignation::k320x176},
  104. {{320, 180}, VideoResolutionDesignation::k320x180},
  105. {{480, 270}, VideoResolutionDesignation::k480x270},
  106. {{544, 288}, VideoResolutionDesignation::k544x288},
  107. {{752, 416}, VideoResolutionDesignation::k752x416},
  108. {{864, 480}, VideoResolutionDesignation::k864x480},
  109. {{800, 448}, VideoResolutionDesignation::k800x448},
  110. {{960, 544}, VideoResolutionDesignation::k960x544},
  111. {{1184, 656}, VideoResolutionDesignation::k1184x656},
  112. {{1392, 768}, VideoResolutionDesignation::k1392x768},
  113. {{1504, 832}, VideoResolutionDesignation::k1504x832},
  114. {{1600, 896}, VideoResolutionDesignation::k1600x896},
  115. {{1712, 960}, VideoResolutionDesignation::k1712x960},
  116. {{1792, 1008}, VideoResolutionDesignation::k1792x1008},
  117. {{2592, 1944}, VideoResolutionDesignation::k2592x1944},
  118. },
  119. FrameSizeCompare());
  120. static_assert(kResolutions.size() ==
  121. static_cast<size_t>(VideoResolutionDesignation::kMaxValue),
  122. "Each resolution must have one entry in kResolutions.");
  123. VideoResolutionDesignation ResolutionNameFromSize(gfx::Size frame_size) {
  124. // Rotate such that we are always in landscape.
  125. if (frame_size.width() < frame_size.height()) {
  126. int tmp = frame_size.width();
  127. frame_size.set_width(frame_size.height());
  128. frame_size.set_width(tmp);
  129. }
  130. auto* it = kResolutions.find(frame_size);
  131. return it != kResolutions.end() ? it->second
  132. : VideoResolutionDesignation::kUnknown;
  133. }
  134. } // namespace
  135. namespace media {
  136. void LogCaptureDeviceMetrics(
  137. base::span<const media::VideoCaptureDeviceInfo> devices_info) {
  138. for (const auto& device : devices_info) {
  139. base::flat_set<media::VideoPixelFormat> supported_pixel_formats;
  140. base::flat_set<gfx::Size, FrameSizeCompare> resolutions;
  141. for (const auto& format : device.supported_formats) {
  142. VLOG(2) << "Device supports "
  143. << media::VideoPixelFormatToString(format.pixel_format) << " at "
  144. << format.frame_size.ToString() << " ("
  145. << static_cast<int>(ResolutionNameFromSize(format.frame_size))
  146. << ")";
  147. media::VideoPixelFormat pixel_format = format.pixel_format;
  148. bool inserted = supported_pixel_formats.insert(pixel_format).second;
  149. if (inserted) {
  150. base::UmaHistogramEnumeration(
  151. "Media.VideoCapture.Device.SupportedPixelFormat", pixel_format,
  152. media::VideoPixelFormat::PIXEL_FORMAT_MAX);
  153. }
  154. if (!resolutions.contains(format.frame_size)) {
  155. resolutions.insert(format.frame_size);
  156. base::UmaHistogramEnumeration(
  157. "Media.VideoCapture.Device.SupportedResolution",
  158. ResolutionNameFromSize(format.frame_size));
  159. }
  160. }
  161. }
  162. }
  163. } // namespace media