blob: 54bf57ed64a3b0cdbabb26dfa1ebb3810a31d7df [file] [log] [blame]
// Copyright (c) 2012 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.
// Windows specific implementation of VideoCaptureDevice. DirectShow is used for
// capturing. DirectShow provide its own threads for capturing.
#ifndef MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_WIN_H_
#define MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_WIN_H_
// Avoid including strsafe.h via dshow as it will cause build warnings.
#define NO_DSHOW_STRSAFE
#include <dshow.h>
#include <stdint.h>
#include <vidcap.h>
#include <wrl/client.h>
#include <map>
#include <string>
#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/win/capability_list_win.h"
#include "media/capture/video/win/sink_filter_win.h"
#include "media/capture/video/win/sink_input_pin_win.h"
#include "media/capture/video_capture_types.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class Location;
} // namespace base
namespace media {
// All the methods in the class can only be run on a COM initialized thread.
class VideoCaptureDeviceWin : public VideoCaptureDevice,
public SinkFilterObserver {
public:
// A utility class that wraps the AM_MEDIA_TYPE type and guarantees that
// we free the structure when exiting the scope. DCHECKing is also done to
// avoid memory leaks.
class ScopedMediaType {
public:
ScopedMediaType() : media_type_(nullptr) {}
~ScopedMediaType() { Free(); }
AM_MEDIA_TYPE* operator->() { return media_type_; }
AM_MEDIA_TYPE* get() { return media_type_; }
void Free();
AM_MEDIA_TYPE** Receive();
private:
void FreeMediaType(AM_MEDIA_TYPE* mt);
void DeleteMediaType(AM_MEDIA_TYPE* mt);
AM_MEDIA_TYPE* media_type_;
};
static VideoCaptureControlSupport GetControlSupport(
Microsoft::WRL::ComPtr<IBaseFilter> capture_filter);
static void GetDeviceCapabilityList(
Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
bool query_detailed_frame_rates,
CapabilityList* out_capability_list);
static void GetPinCapabilityList(
Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
Microsoft::WRL::ComPtr<IPin> output_capture_pin,
bool query_detailed_frame_rates,
CapabilityList* out_capability_list);
static Microsoft::WRL::ComPtr<IPin> GetPin(
Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
PIN_DIRECTION pin_dir,
REFGUID category,
REFGUID major_type);
static VideoPixelFormat TranslateMediaSubtypeToPixelFormat(
const GUID& sub_type);
VideoCaptureDeviceWin(const VideoCaptureDeviceDescriptor& device_descriptor,
Microsoft::WRL::ComPtr<IBaseFilter> capture_filter);
~VideoCaptureDeviceWin() override;
// Opens the device driver for this device.
bool Init();
// VideoCaptureDevice implementation.
void AllocateAndStart(
const VideoCaptureParams& params,
std::unique_ptr<VideoCaptureDevice::Client> client) override;
void StopAndDeAllocate() override;
void TakePhoto(TakePhotoCallback callback) override;
void GetPhotoState(GetPhotoStateCallback callback) override;
void SetPhotoOptions(mojom::PhotoSettingsPtr settings,
SetPhotoOptionsCallback callback) override;
private:
enum InternalState {
kIdle, // The device driver is opened but camera is not in use.
kCapturing, // Video is being captured.
kError // Error accessing HW functions.
// User needs to recover by destroying the object.
};
static bool GetCameraAndVideoControls(
Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
ICameraControl** camera_control,
IVideoProcAmp** video_control);
// Implements SinkFilterObserver.
void FrameReceived(const uint8_t* buffer,
int length,
const VideoCaptureFormat& format,
base::TimeDelta timestamp,
bool flip_y) override;
void FrameDropped(VideoCaptureFrameDropReason reason) override;
bool CreateCapabilityMap();
void SetAntiFlickerInCaptureFilter(const VideoCaptureParams& params);
void SetErrorState(media::VideoCaptureError error,
const base::Location& from_here,
const std::string& reason,
HRESULT hr);
const VideoCaptureDeviceDescriptor device_descriptor_;
InternalState state_;
std::unique_ptr<VideoCaptureDevice::Client> client_;
Microsoft::WRL::ComPtr<IBaseFilter> capture_filter_;
Microsoft::WRL::ComPtr<IGraphBuilder> graph_builder_;
Microsoft::WRL::ComPtr<ICaptureGraphBuilder2> capture_graph_builder_;
Microsoft::WRL::ComPtr<IMediaControl> media_control_;
Microsoft::WRL::ComPtr<IPin> input_sink_pin_;
Microsoft::WRL::ComPtr<IPin> output_capture_pin_;
scoped_refptr<SinkFilter> sink_filter_;
// Map of all capabilities this device support.
CapabilityList capabilities_;
VideoCaptureFormat capture_format_;
Microsoft::WRL::ComPtr<ICameraControl> camera_control_;
Microsoft::WRL::ComPtr<IVideoProcAmp> video_control_;
// These flags keep the manual/auto mode between cycles of SetPhotoOptions().
bool white_balance_mode_manual_;
bool exposure_mode_manual_;
bool focus_mode_manual_;
base::TimeTicks first_ref_time_;
base::queue<TakePhotoCallback> take_photo_callbacks_;
base::ThreadChecker thread_checker_;
bool enable_get_photo_state_;
absl::optional<int> camera_rotation_;
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceWin);
};
} // namespace media
#endif // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_WIN_H_