| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_UTILS_WIN_H_ |
| #define MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_UTILS_WIN_H_ |
| |
| // Avoid including strsafe.h via dshow as it will cause build warnings. |
| #define NO_DSHOW_STRSAFE |
| #include <dshow.h> |
| #include <windows.h> |
| |
| #include "media/base/video_facing.h" |
| #include "media/capture/mojom/image_capture_types.h" |
| |
| namespace media { |
| |
| // Windows platform stores pan and tilt (min, max, step and current) in |
| // degrees. Spec expects them in arc seconds. |
| // https://docs.microsoft.com/en-us/windows/win32/api/strmif/ne-strmif-cameracontrolproperty |
| // spec: https://w3c.github.io/mediacapture-image/#pan |
| long CaptureAngleToPlatformValue(double arc_seconds); |
| double PlatformAngleToCaptureValue(long degrees); |
| double PlatformAngleToCaptureStep(long step, double min, double max); |
| |
| // Windows platform stores exposure time (min, max and current) in log base 2 |
| // seconds. If value is n, exposure time is 2^n seconds. Spec expects exposure |
| // times in 100 micro seconds. |
| // https://docs.microsoft.com/en-us/windows/win32/api/strmif/ne-strmif-cameracontrolproperty |
| // spec: https://w3c.github.io/mediacapture-image/#exposure-time |
| long CaptureExposureTimeToPlatformValue(double hundreds_of_microseconds); |
| double PlatformExposureTimeToCaptureValue(long log_seconds); |
| double PlatformExposureTimeToCaptureStep(long log_step, double min, double max); |
| |
| // Returns the rotation of the camera. Returns 0 if it's not a built-in camera, |
| // or auto-rotation is not enabled, or only displays on external monitors. |
| int GetCameraRotation(VideoFacingMode facing); |
| |
| bool IsAutoRotationEnabled(); |
| bool IsInternalCamera(VideoFacingMode facing); |
| |
| // Returns true if target device has active internal display panel, e.g. the |
| // screen attached to tablets or laptops, and stores its device info in |
| // |internal_display_device|. |
| bool HasActiveInternalDisplayDevice(DISPLAY_DEVICE* internal_display_device); |
| |
| // Returns S_OK if the path info of the target display device with input |
| // |device_name| shows it is an internal display panel. |
| HRESULT CheckPathInfoForInternal(const PCWSTR device_name); |
| |
| // Returns true if this is an integrated display panel. |
| bool IsInternalVideoOutput( |
| const DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY video_output_tech_type); |
| |
| static inline double PlatformToCaptureValue(long value) { |
| return value; |
| } |
| static inline double PlatformToCaptureStep(long step, double min, double max) { |
| return step; |
| } |
| |
| // Retrieves the control range and value using the provided getters, and |
| // optionally returns the associated supported and current mode. |
| template <typename RangeGetter, typename CurrentValueGetter> |
| static mojom::RangePtr RetrieveControlRangeAndCurrent( |
| RangeGetter range_getter, |
| CurrentValueGetter current_value_getter, |
| std::vector<mojom::MeteringMode>* supported_modes = nullptr, |
| mojom::MeteringMode* current_mode = nullptr, |
| double (*value_converter)(long) = PlatformToCaptureValue, |
| double (*step_converter)(long, double, double) = PlatformToCaptureStep) { |
| auto control_range = mojom::Range::New(); |
| |
| long min, max, step, default_value, flags; |
| HRESULT hr = range_getter(&min, &max, &step, &default_value, &flags); |
| DLOG_IF(ERROR, FAILED(hr)) << "Control range reading failed: " |
| << logging::SystemErrorCodeToString(hr); |
| if (SUCCEEDED(hr)) { |
| control_range->min = value_converter(min); |
| control_range->max = value_converter(max); |
| control_range->step = |
| step_converter(step, control_range->min, control_range->max); |
| if (supported_modes != nullptr) { |
| if (flags & CameraControl_Flags_Auto) |
| supported_modes->push_back(mojom::MeteringMode::CONTINUOUS); |
| if (flags & CameraControl_Flags_Manual) |
| supported_modes->push_back(mojom::MeteringMode::MANUAL); |
| } |
| } |
| |
| long current; |
| hr = current_value_getter(¤t, &flags); |
| DLOG_IF(ERROR, FAILED(hr)) << "Control value reading failed: " |
| << logging::SystemErrorCodeToString(hr); |
| if (SUCCEEDED(hr)) { |
| control_range->current = value_converter(current); |
| if (current_mode != nullptr) { |
| if (flags & CameraControl_Flags_Auto) |
| *current_mode = mojom::MeteringMode::CONTINUOUS; |
| else if (flags & CameraControl_Flags_Manual) |
| *current_mode = mojom::MeteringMode::MANUAL; |
| } |
| } |
| |
| return control_range; |
| } |
| |
| } // namespace media |
| |
| #endif // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_UTILS_WIN_H_ |