1 /* Webcamoid, webcam capture application.
2 * Copyright (C) 2018 Gonzalo Exequiel Pedone
3 *
4 * Webcamoid is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Webcamoid is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Webcamoid. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Web-Site: http://webcamoid.github.io/
18 */
19
20 #include <map>
21 #include <vector>
22 #include <dshow.h>
23
24 #include "videoprocamp.h"
25 #include "PlatformUtils/src/utils.h"
26 #include "VCamUtils/src/utils.h"
27
28 #define AK_CUR_INTERFACE "VideoProcAmp"
29
30 namespace AkVCam
31 {
32 class VideoProcAmpPrivate
33 {
34 public:
35 std::map<LONG, LONG> m_control;
36 };
37
38 class ProcAmpPrivate
39 {
40 public:
41 LONG property;
42 LONG min;
43 LONG max;
44 LONG step;
45 LONG defaultValue;
46 LONG flags;
47
controls()48 inline static const std::vector<ProcAmpPrivate> &controls()
49 {
50 static const std::vector<ProcAmpPrivate> controls {
51 {VideoProcAmp_Brightness , -255, 255, 1, 0, CameraControl_Flags_Manual},
52 {VideoProcAmp_Contrast , -255, 255, 1, 0, CameraControl_Flags_Manual},
53 {VideoProcAmp_Saturation , -255, 255, 1, 0, CameraControl_Flags_Manual},
54 {VideoProcAmp_Gamma , -255, 255, 1, 0, CameraControl_Flags_Manual},
55 {VideoProcAmp_Hue , -359, 359, 1, 0, CameraControl_Flags_Manual},
56 {VideoProcAmp_ColorEnable, 0, 1, 1, 1, CameraControl_Flags_Manual}
57 };
58
59 return controls;
60 }
61
byProperty(LONG property)62 static inline const ProcAmpPrivate *byProperty(LONG property)
63 {
64 for (auto &control: controls())
65 if (control.property == property)
66 return &control;
67
68 return nullptr;
69 }
70 };
71 }
72
VideoProcAmp()73 AkVCam::VideoProcAmp::VideoProcAmp():
74 CUnknown(this, IID_IAMVideoProcAmp)
75 {
76 this->d = new VideoProcAmpPrivate;
77 }
78
~VideoProcAmp()79 AkVCam::VideoProcAmp::~VideoProcAmp()
80 {
81 delete this->d;
82 }
83
GetRange(LONG Property,LONG * pMin,LONG * pMax,LONG * pSteppingDelta,LONG * pDefault,LONG * pCapsFlags)84 HRESULT AkVCam::VideoProcAmp::GetRange(LONG Property,
85 LONG *pMin,
86 LONG *pMax,
87 LONG *pSteppingDelta,
88 LONG *pDefault,
89 LONG *pCapsFlags)
90 {
91 AkLogMethod();
92
93 if (!pMin || !pMax || !pSteppingDelta || !pDefault || !pCapsFlags)
94 return E_POINTER;
95
96 *pMin = 0;
97 *pMax = 0;
98 *pSteppingDelta = 0;
99 *pDefault = 0;
100 *pCapsFlags = 0;
101
102 for (auto &control: ProcAmpPrivate::controls())
103 if (control.property == Property) {
104 *pMin = control.min;
105 *pMax = control.max;
106 *pSteppingDelta = control.step;
107 *pDefault = control.defaultValue;
108 *pCapsFlags = control.flags;
109
110 return S_OK;
111 }
112
113 return E_PROP_ID_UNSUPPORTED;
114 }
115
Set(LONG Property,LONG lValue,LONG Flags)116 HRESULT AkVCam::VideoProcAmp::Set(LONG Property, LONG lValue, LONG Flags)
117 {
118 AkLogMethod();
119
120 for (auto &control: ProcAmpPrivate::controls())
121 if (control.property == Property) {
122 if (lValue < control.min
123 || lValue > control.max
124 || Flags != control.flags)
125 return E_INVALIDARG;
126
127 this->d->m_control[Property] = lValue;
128 AKVCAM_EMIT(this, PropertyChanged, Property, lValue, Flags)
129
130 return S_OK;
131 }
132
133 return E_PROP_ID_UNSUPPORTED;
134 }
135
Get(LONG Property,LONG * lValue,LONG * Flags)136 HRESULT AkVCam::VideoProcAmp::Get(LONG Property, LONG *lValue, LONG *Flags)
137 {
138 AkLogMethod();
139
140 if (!lValue || !Flags)
141 return E_POINTER;
142
143 *lValue = 0;
144 *Flags = 0;
145
146 for (auto &control: ProcAmpPrivate::controls())
147 if (control.property == Property) {
148 if (this->d->m_control.count(Property))
149 *lValue = this->d->m_control[Property];
150 else
151 *lValue = control.defaultValue;
152
153 *Flags = control.flags;
154
155 return S_OK;
156 }
157
158 return E_PROP_ID_UNSUPPORTED;
159 }
160