FreeRDP
Loading...
Searching...
No Matches
camera.h
1
20#ifndef FREERDP_CLIENT_CAMERA_H
21#define FREERDP_CLIENT_CAMERA_H
22
23#include <errno.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include <winpr/wlog.h>
29#include <winpr/wtypes.h>
30
31#include <freerdp/api.h>
32#include <freerdp/types.h>
33
34#include <freerdp/client/channels.h>
35#include <freerdp/channels/log.h>
36#include <freerdp/channels/rdpecam.h>
37#include <freerdp/codecs.h>
38#include <freerdp/codec/video.h>
39#include <freerdp/primitives.h>
40
41#define ECAM_PROTO_VERSION 0x02
42/* currently supporting 1 stream per device */
43#define ECAM_DEVICE_MAX_STREAMS 1
44#define ECAM_MAX_MEDIA_TYPE_DESCRIPTORS 256
45
46/* Allow to send up to that many unsolicited samples.
47 * For example, to support 30 fps with 250 ms round trip
48 * ECAM_MAX_SAMPLE_CREDITS has to be at least 8.
49 */
50#define ECAM_MAX_SAMPLE_CREDITS 8
51
52/* Having this hardcoded allows to preallocate and reuse buffer
53 * for sample responses. Excessive size is to make sure any sample
54 * will fit in, even with highest resolution.
55 */
56#define ECAM_SAMPLE_RESPONSE_BUFFER_SIZE (1024ULL * 4050ULL)
57
58typedef struct s_ICamHal ICamHal;
59
60typedef struct
61{
62 IWTSPlugin iface;
63 IWTSListener* listener;
65
66 /* HAL interface */
67 ICamHal* ihal;
68 char* subsystem;
69
70 BOOL initialized;
71 BOOL attached;
72
73 UINT32 version;
74 wHashTable* devices;
75
76 BOOL connected;
78
79typedef struct
80{
81 CAM_MEDIA_FORMAT inputFormat; /* camera side */
82 CAM_MEDIA_FORMAT outputFormat; /* network side */
83
85
86typedef struct
87{
88 BOOL streaming;
89 /* The protocol stream can remain active while the capture device is released. */
90 BOOL captureRunning;
92 CAM_MEDIA_TYPE_DESCRIPTION currMediaType;
93
94 GENERIC_CHANNEL_CALLBACK* hSampleReqChannel;
96 volatile LONG samplesRequested;
97 /* GetTickCount64() of the last SampleRequest, or of the stream start */
98 UINT64 lastSampleRequestTime;
99 wStream* pendingSample;
100 volatile BOOL haveSample;
101 wStream* sampleRespBuffer;
102
103 FREERDP_VIDEO_CONTEXT* video;
105
106/* Internal callback result asking a request-driven HAL to release the capture device. */
107#define ECAM_SAMPLE_CAPTURE_DRAINED 0x00010000u
108
109/* Release the capture device once the server stopped requesting samples for this long (ms).
110 * Windows requests samples one at a time, so a zero request count between two requests is
111 * normal and must not close the device. */
112#define ECAM_CAPTURE_IDLE_TIMEOUT_MS 2000ULL
113
114WINPR_ATTR_NODISCARD
115static inline CAM_MEDIA_FORMAT streamInputFormat(CameraDeviceStream* stream)
116{
117 return stream->formats.inputFormat;
118}
119
120WINPR_ATTR_NODISCARD
121static inline CAM_MEDIA_FORMAT streamOutputFormat(CameraDeviceStream* stream)
122{
123 return stream->formats.outputFormat;
124}
125
126typedef struct
127{
128 IWTSListener* listener;
129 GENERIC_LISTENER_CALLBACK* hlistener;
130 CameraPlugin* ecam;
131 ICamHal* ihal; /* HAL interface, same as used by CameraPlugin */
132 char deviceId[32];
133 CameraDeviceStream streams[ECAM_DEVICE_MAX_STREAMS];
134
136
141typedef UINT (*ICamHalEnumCallback)(CameraPlugin* ecam, GENERIC_CHANNEL_CALLBACK* hchannel,
142 const char* deviceId, const char* deviceName);
143
144/* may run in context of different thread */
145typedef UINT (*ICamHalSampleCapturedCallback)(CameraDevice* dev, size_t streamIndex,
146 const BYTE* sample, size_t size);
147
150{
151 /* The HAL can release capture when there are no sample requests and restart it later. */
152 BOOL RequestDrivenCapture;
153
162 WINPR_ATTR_NODISCARD UINT (*Enumerate)(ICamHal* ihal, ICamHalEnumCallback callback,
163 CameraPlugin* ecam, GENERIC_CHANNEL_CALLBACK* hchannel);
164
173 WINPR_ATTR_NODISCARD BOOL (*Activate)(ICamHal* ihal, const char* deviceId,
174 CAM_ERROR_CODE* errorCode);
175
184 WINPR_ATTR_NODISCARD BOOL (*Deactivate)(ICamHal* ihal, const char* deviceId,
185 CAM_ERROR_CODE* errorCode);
186
198 WINPR_ATTR_NODISCARD INT16 (*GetMediaTypeDescriptions)(
199 ICamHal* ihal, const char* deviceId, size_t streamIndex,
200 const CAM_MEDIA_FORMAT_INFO* supportedFormats, size_t nSupportedFormats,
201 CAM_MEDIA_TYPE_DESCRIPTION* mediaTypes, size_t* nMediaTypes);
202
212 WINPR_ATTR_NODISCARD CAM_ERROR_CODE (*StartStream)(ICamHal* ihal, CameraDevice* dev,
213 size_t streamIndex,
214 const CAM_MEDIA_TYPE_DESCRIPTION* mediaType,
215 ICamHalSampleCapturedCallback callback);
216
224 CAM_ERROR_CODE (*StopStream)(ICamHal* ihal, const char* deviceId, size_t streamIndex);
225
231 CAM_ERROR_CODE (*Free)(ICamHal* ihal);
232};
233
234typedef UINT (*PREGISTERCAMERAHAL)(IWTSPlugin* plugin, ICamHal* hal);
235
236typedef struct
237{
238 IWTSPlugin* plugin;
239 WINPR_ATTR_NODISCARD PREGISTERCAMERAHAL pRegisterCameraHal;
240 CameraPlugin* ecam;
241 const ADDIN_ARGV* args;
242
244
246
247/* entry point called by addin manager */
248typedef UINT(VCAPITYPE* PFREERDP_CAMERA_HAL_ENTRY)(PFREERDP_CAMERA_HAL_ENTRY_POINTS pEntryPoints);
249
250/* common functions */
251WINPR_ATTR_NODISCARD FREERDP_LOCAL UINT ecam_channel_send_generic_msg(
252 CameraPlugin* ecam, GENERIC_CHANNEL_CALLBACK* hchannel, CAM_MSG_ID msg);
253
254FREERDP_LOCAL UINT ecam_channel_send_error_response(CameraPlugin* ecam,
255 GENERIC_CHANNEL_CALLBACK* hchannel,
256 CAM_ERROR_CODE code);
257
258WINPR_ATTR_NODISCARD FREERDP_LOCAL UINT ecam_channel_write(CameraPlugin* ecam,
259 GENERIC_CHANNEL_CALLBACK* hchannel,
260 CAM_MSG_ID msg, wStream* out,
261 BOOL freeStream);
262
263/* ecam device interface */
264FREERDP_LOCAL void ecam_dev_destroy(CameraDevice* dev);
265
266WINPR_ATTR_MALLOC(ecam_dev_destroy, 1)
267WINPR_ATTR_NODISCARD
268FREERDP_LOCAL CameraDevice* ecam_dev_create(CameraPlugin* ecam, const char* deviceId,
269 const char* deviceName);
270
271/* video encoding interface */
272WINPR_ATTR_NODISCARD FREERDP_LOCAL BOOL ecam_encoder_context_init(CameraDeviceStream* stream);
273
274FREERDP_LOCAL BOOL ecam_encoder_context_free(CameraDeviceStream* stream);
275
276WINPR_ATTR_NODISCARD FREERDP_LOCAL BOOL ecam_encoder_compress(CameraDeviceStream* stream,
277 const BYTE* srcData, size_t srcSize,
278 wStream* output);
279
280WINPR_ATTR_NODISCARD FREERDP_LOCAL UINT32 h264_get_max_bitrate(UINT32 height);
281
282WINPR_ATTR_NODISCARD
283FREERDP_LOCAL FREERDP_VIDEO_FORMAT ecamToVideoFormat(CAM_MEDIA_FORMAT ecamFormat);
284
285#endif /* FREERDP_CLIENT_CAMERA_H */
Definition camera.h:237
interface to implement for the camera HAL
Definition camera.h:150
WINPR_ATTR_NODISCARD BOOL(* Deactivate)(ICamHal *ihal, const char *deviceId, CAM_ERROR_CODE *errorCode)
Definition camera.h:184
WINPR_ATTR_NODISCARD INT16(* GetMediaTypeDescriptions)(ICamHal *ihal, const char *deviceId, size_t streamIndex, const CAM_MEDIA_FORMAT_INFO *supportedFormats, size_t nSupportedFormats, CAM_MEDIA_TYPE_DESCRIPTION *mediaTypes, size_t *nMediaTypes)
Definition camera.h:198
WINPR_ATTR_NODISCARD UINT(* Enumerate)(ICamHal *ihal, ICamHalEnumCallback callback, CameraPlugin *ecam, GENERIC_CHANNEL_CALLBACK *hchannel)
Definition camera.h:162
WINPR_ATTR_NODISCARD BOOL(* Activate)(ICamHal *ihal, const char *deviceId, CAM_ERROR_CODE *errorCode)
Definition camera.h:173
CAM_ERROR_CODE(* StopStream)(ICamHal *ihal, const char *deviceId, size_t streamIndex)
Definition camera.h:224
WINPR_ATTR_NODISCARD CAM_ERROR_CODE(* StartStream)(ICamHal *ihal, CameraDevice *dev, size_t streamIndex, const CAM_MEDIA_TYPE_DESCRIPTION *mediaType, ICamHalSampleCapturedCallback callback)
Definition camera.h:212
CAM_ERROR_CODE(* Free)(ICamHal *ihal)
Definition camera.h:231