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(&current, &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