summaryrefslogtreecommitdiff
path: root/chromium/media/capture/video/win/video_capture_device_win.h
blob: e135f077618fe62a515cac6f0ed9aff045114f36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// 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"

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_(NULL) {}
    ~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 void GetDeviceCapabilityList(const std::string& device_id,
                                      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 HRESULT GetDeviceFilter(const std::string& device_id,
                                 IBaseFilter** filter);
  static Microsoft::WRL::ComPtr<IPin> GetPin(IBaseFilter* filter,
                                             PIN_DIRECTION pin_dir,
                                             REFGUID category,
                                             REFGUID major_type);
  static VideoPixelFormat TranslateMediaSubtypeToPixelFormat(
      const GUID& sub_type);

  explicit VideoCaptureDeviceWin(
      const VideoCaptureDeviceDescriptor& device_descriptor);
  ~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.
  };

  bool InitializeVideoAndCameraControls();

  // Implements SinkFilterObserver.
  void FrameReceived(const uint8_t* buffer,
                     int length,
                     const VideoCaptureFormat& format,
                     base::TimeDelta timestamp) 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_;

  base::TimeTicks first_ref_time_;

  base::queue<TakePhotoCallback> take_photo_callbacks_;

  base::ThreadChecker thread_checker_;

  bool enable_get_photo_state_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceWin);
};

}  // namespace media

#endif  // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_WIN_H_