rdpecam: add some new callbacks to the HAL

This patch adds Activate and Deactivate callbacks to the HAL, matching the messages
exchanged on the channel. This is to prepare the support of a windows HAL using the
microsoft media fundation framework.
This commit is contained in:
David Fort
2025-09-10 14:57:28 +02:00
parent abdd85bcbd
commit ae2e951af6
3 changed files with 96 additions and 4 deletions

View File

@@ -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);

View File

@@ -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);
}
/**

View File

@@ -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;