1 // Copyright 2018 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
5 #ifndef MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_UTILS_WIN_H_
6 #define MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_UTILS_WIN_H_
7
8 // Avoid including strsafe.h via dshow as it will cause build warnings.
9 #define NO_DSHOW_STRSAFE
10 #include <dshow.h>
11 #include <windows.h>
12
13 #include "media/base/video_facing.h"
14 #include "media/capture/mojom/image_capture_types.h"
15
16 namespace media {
17
18 // Windows platform stores pan and tilt (min, max, step and current) in
19 // degrees. Spec expects them in arc seconds.
20 // https://docs.microsoft.com/en-us/windows/win32/api/strmif/ne-strmif-cameracontrolproperty
21 // spec: https://w3c.github.io/mediacapture-image/#pan
22 long CaptureAngleToPlatformValue(double arc_seconds);
23 double PlatformAngleToCaptureValue(long degrees);
24 double PlatformAngleToCaptureStep(long step, double min, double max);
25
26 // Windows platform stores exposure time (min, max and current) in log base 2
27 // seconds. If value is n, exposure time is 2^n seconds. Spec expects exposure
28 // times in 100 micro seconds.
29 // https://docs.microsoft.com/en-us/windows/win32/api/strmif/ne-strmif-cameracontrolproperty
30 // spec: https://w3c.github.io/mediacapture-image/#exposure-time
31 long CaptureExposureTimeToPlatformValue(double hundreds_of_microseconds);
32 double PlatformExposureTimeToCaptureValue(long log_seconds);
33 double PlatformExposureTimeToCaptureStep(long log_step, double min, double max);
34
35 // Returns the rotation of the camera. Returns 0 if it's not a built-in camera,
36 // or auto-rotation is not enabled, or only displays on external monitors.
37 int GetCameraRotation(VideoFacingMode facing);
38
39 bool IsAutoRotationEnabled();
40 bool IsInternalCamera(VideoFacingMode facing);
41
42 // Returns true if target device has active internal display panel, e.g. the
43 // screen attached to tablets or laptops, and stores its device info in
44 // |internal_display_device|.
45 bool HasActiveInternalDisplayDevice(DISPLAY_DEVICE* internal_display_device);
46
47 // Returns S_OK if the path info of the target display device with input
48 // |device_name| shows it is an internal display panel.
49 HRESULT CheckPathInfoForInternal(const PCWSTR device_name);
50
51 // Returns true if this is an integrated display panel.
52 bool IsInternalVideoOutput(
53 const DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY video_output_tech_type);
54
PlatformToCaptureValue(long value)55 static double PlatformToCaptureValue(long value) {
56 return value;
57 }
PlatformToCaptureStep(long step,double min,double max)58 static double PlatformToCaptureStep(long step, double min, double max) {
59 return step;
60 }
61
62 // Retrieves the control range and value using the provided getters, and
63 // optionally returns the associated supported and current mode.
64 template <typename RangeGetter, typename CurrentValueGetter>
65 static mojom::RangePtr RetrieveControlRangeAndCurrent(
66 RangeGetter range_getter,
67 CurrentValueGetter current_value_getter,
68 std::vector<mojom::MeteringMode>* supported_modes = nullptr,
69 mojom::MeteringMode* current_mode = nullptr,
70 double (*value_converter)(long) = PlatformToCaptureValue,
71 double (*step_converter)(long, double, double) = PlatformToCaptureStep) {
72 auto control_range = mojom::Range::New();
73
74 long min, max, step, default_value, flags;
75 HRESULT hr = range_getter(&min, &max, &step, &default_value, &flags);
76 DLOG_IF(ERROR, FAILED(hr)) << "Control range reading failed: "
77 << logging::SystemErrorCodeToString(hr);
78 if (SUCCEEDED(hr)) {
79 control_range->min = value_converter(min);
80 control_range->max = value_converter(max);
81 control_range->step =
82 step_converter(step, control_range->min, control_range->max);
83 if (supported_modes != nullptr) {
84 if (flags & CameraControl_Flags_Auto)
85 supported_modes->push_back(mojom::MeteringMode::CONTINUOUS);
86 if (flags & CameraControl_Flags_Manual)
87 supported_modes->push_back(mojom::MeteringMode::MANUAL);
88 }
89 }
90
91 long current;
92 hr = current_value_getter(¤t, &flags);
93 DLOG_IF(ERROR, FAILED(hr)) << "Control value reading failed: "
94 << logging::SystemErrorCodeToString(hr);
95 if (SUCCEEDED(hr)) {
96 control_range->current = value_converter(current);
97 if (current_mode != nullptr) {
98 if (flags & CameraControl_Flags_Auto)
99 *current_mode = mojom::MeteringMode::CONTINUOUS;
100 else if (flags & CameraControl_Flags_Manual)
101 *current_mode = mojom::MeteringMode::MANUAL;
102 }
103 }
104
105 return control_range;
106 }
107
108 } // namespace media
109
110 #endif // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_UTILS_WIN_H_
111