diff --git a/channels/rdpecam/client/camera.h b/channels/rdpecam/client/camera.h index 68282f28f..a0a1e7a1a 100644 --- a/channels/rdpecam/client/camera.h +++ b/channels/rdpecam/client/camera.h @@ -153,20 +153,85 @@ typedef UINT (*ICamHalEnumCallback)(CameraPlugin* ecam, GENERIC_CHANNEL_CALLBACK typedef UINT (*ICamHalSampleCapturedCallback)(CameraDevice* dev, int streamIndex, const BYTE* sample, size_t size); +/** @brief interface to implement for the camera HAL*/ struct s_ICamHal { + /** callback to enumerate available camera calling callback for each found item + * + * @param ihal the hal interface + * @param callback the enum callback + * @param ecam the camera plugin + * @param hchannel the generic freerdp channel + * @return the number of found cameras + */ UINT(*Enumerate) (ICamHal* ihal, ICamHalEnumCallback callback, CameraPlugin* ecam, GENERIC_CHANNEL_CALLBACK* hchannel); + + /** + * callback to activate a given camera device + * @param ihal the hal interface + * @param deviceId the name of the device + * @param errorCode a pointer to an error code set if the call failed + * @return if the operation was successful + * @since 3.18.0 + */ + BOOL (*Activate)(ICamHal* ihal, const char* deviceId, UINT32* errorCode); + + /** + * callback to deactivate a given camera device + * @param ihal the hal interface + * @param deviceId the name of the device + * @param errorCode a pointer to an error code set if the call failed + * @return if the operation was successful + * @since 3.18.0 + */ + BOOL (*Deactivate)(ICamHal* ihal, const char* deviceId, UINT32* errorCode); + + /** + * callback that returns the list of compatible media types given a set of supported formats + * @param ihal the hal interface + * @param deviceId the name of the device + * @param streamIndex stream index number + * @param supportedFormats a pointer to supported formats + * @param nSupportedFormats number of supported formats + * @param mediaTypes resulting media type descriptors + * @param nMediaTypes output number of media descriptors + * @return number of matched supported formats + */ INT16(*GetMediaTypeDescriptions) (ICamHal* ihal, const char* deviceId, int streamIndex, const CAM_MEDIA_FORMAT_INFO* supportedFormats, size_t nSupportedFormats, CAM_MEDIA_TYPE_DESCRIPTION* mediaTypes, size_t* nMediaTypes); + + /** + * callback to start a stream + * @param ihal the hal interface + * @param dev + * @param streamIndex stream index number + * @param mediaType + * @param callback + * @return 0 on success, a CAM_Error otherwise + */ UINT(*StartStream) (ICamHal* ihal, CameraDevice* dev, int streamIndex, const CAM_MEDIA_TYPE_DESCRIPTION* mediaType, ICamHalSampleCapturedCallback callback); + + /** + * callback to stop a stream + * @param ihal the hal interface + * @param deviceId the name of the device + * @param streamIndex stream index number + * @return 0 on success, a CAM_Error otherwise + */ UINT (*StopStream)(ICamHal* ihal, const char* deviceId, int streamIndex); - UINT (*Free)(ICamHal* hal); + + /** + * callback to free the ICamHal + * @param hal the hal interface + * @return 0 on success, a CAM_Error otherwise + */ + UINT (*Free)(ICamHal* ihal); }; typedef UINT (*PREGISTERCAMERAHAL)(IWTSPlugin* plugin, ICamHal* hal); diff --git a/channels/rdpecam/client/camera_device_main.c b/channels/rdpecam/client/camera_device_main.c index 463214b41..6bb3a16f4 100644 --- a/channels/rdpecam/client/camera_device_main.c +++ b/channels/rdpecam/client/camera_device_main.c @@ -555,9 +555,12 @@ static UINT ecam_dev_process_activate_device_request(CameraDevice* dev, WINPR_ATTR_UNUSED wStream* s) { WINPR_ASSERT(dev); + UINT32 errorCode = 0; - /* TODO: TBD if this is required */ - return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse); + if (dev->ihal->Activate(dev->ihal, dev->deviceId, &errorCode)) + return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse); + + return ecam_channel_send_error_response(dev->ecam, hchannel, errorCode); } /** @@ -575,7 +578,11 @@ static UINT ecam_dev_process_deactivate_device_request(CameraDevice* dev, for (size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++) ecam_dev_stop_stream(dev, i); - return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse); + UINT32 errorCode = 0; + if (dev->ihal->Deactivate(dev->ihal, dev->deviceId, &errorCode)) + return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse); + + return ecam_channel_send_error_response(dev->ecam, hchannel, errorCode); } /** diff --git a/channels/rdpecam/client/v4l/camera_v4l.c b/channels/rdpecam/client/v4l/camera_v4l.c index 0f2d1afbb..e604f6468 100644 --- a/channels/rdpecam/client/v4l/camera_v4l.c +++ b/channels/rdpecam/client/v4l/camera_v4l.c @@ -154,6 +154,24 @@ static int cam_v4l_open_device(const char* deviceId, int flags) return fd; } +static BOOL cam_v4l_activate(ICamHal* ihal, const char* deviceId, UINT32* errorCode) +{ + WINPR_UNUSED(ihal); + WINPR_UNUSED(deviceId); + + *errorCode = 0; + return TRUE; +} + +static BOOL cam_v4l_deactivate(ICamHal* ihal, const char* deviceId, UINT32* errorCode) +{ + WINPR_UNUSED(ihal); + WINPR_UNUSED(deviceId); + + *errorCode = 0; + return TRUE; +} + /** * Function description * @@ -781,6 +799,8 @@ FREERDP_ENTRY_POINT(UINT VCAPITYPE v4l_freerdp_rdpecam_client_subsystem_entry( hal->iHal.Enumerate = cam_v4l_enumerate; hal->iHal.GetMediaTypeDescriptions = cam_v4l_get_media_type_descriptions; + hal->iHal.Activate = cam_v4l_activate; + hal->iHal.Deactivate = cam_v4l_deactivate; hal->iHal.StartStream = cam_v4l_stream_start; hal->iHal.StopStream = cam_v4l_stream_stop_by_device_id; hal->iHal.Free = cam_v4l_free;