20#include <winpr/assert.h>
21#include <winpr/cast.h>
22#include <winpr/interlocked.h>
23#include <winpr/sysinfo.h>
26#include "rdpecam-utils.h"
28#define TAG CHANNELS_TAG("rdpecam-device.client")
44 const CAM_MEDIA_FORMAT available[] = { CAM_MEDIA_FORMAT_H264, CAM_MEDIA_FORMAT_MJPG,
45 CAM_MEDIA_FORMAT_YUY2, CAM_MEDIA_FORMAT_NV12,
46 CAM_MEDIA_FORMAT_I420, CAM_MEDIA_FORMAT_RGB24,
47 CAM_MEDIA_FORMAT_RGB32 };
50 formats[ARRAYSIZE(available) * ARRAYSIZE(available)];
51 static size_t count = 0;
52 static BOOL initialized = FALSE;
56 for (
size_t dst = 0; dst < ARRAYSIZE(available); dst++)
58 const CAM_MEDIA_FORMAT dstFormat = available[dst];
60 for (
size_t src = 0; src < ARRAYSIZE(available); src++)
62 const CAM_MEDIA_FORMAT srcFormat = available[src];
63 if (freerdp_video_conversion_supported(ecamToVideoFormat(srcFormat),
64 ecamToVideoFormat(dstFormat)))
79 WINPR_ASSERT(mediaType);
81 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, mediaType->Format));
82 Stream_Write_UINT32(s, mediaType->Width);
83 Stream_Write_UINT32(s, mediaType->Height);
84 Stream_Write_UINT32(s, mediaType->FrameRateNumerator);
85 Stream_Write_UINT32(s, mediaType->FrameRateDenominator);
86 Stream_Write_UINT32(s, mediaType->PixelAspectRatioNumerator);
87 Stream_Write_UINT32(s, mediaType->PixelAspectRatioDenominator);
88 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, mediaType->Flags));
93 WINPR_ASSERT(mediaType);
95 const uint8_t format = Stream_Get_UINT8(s);
96 if (!rdpecam_valid_CamMediaFormat(format))
99 mediaType->Format = WINPR_ASSERTING_INT_CAST(CAM_MEDIA_FORMAT, format);
100 mediaType->Width = Stream_Get_UINT32(s);
101 mediaType->Height = Stream_Get_UINT32(s);
102 mediaType->FrameRateNumerator = Stream_Get_UINT32(s);
103 mediaType->FrameRateDenominator = Stream_Get_UINT32(s);
104 mediaType->PixelAspectRatioNumerator = Stream_Get_UINT32(s);
105 mediaType->PixelAspectRatioDenominator = Stream_Get_UINT32(s);
107 if (mediaType->FrameRateNumerator == 0)
109 if (mediaType->FrameRateDenominator == 0)
111 if (mediaType->PixelAspectRatioNumerator == 0)
113 if (mediaType->PixelAspectRatioDenominator == 0)
116 const uint8_t flags = Stream_Get_UINT8(s);
117 if (!rdpecam_valid_MediaTypeDescriptionFlags(flags))
119 mediaType->Flags = WINPR_ASSERTING_INT_CAST(CAM_MEDIA_TYPE_DESCRIPTION_FLAGS, flags);
125 WINPR_ASSERT(mediaType);
127 WLog_DBG(TAG,
"Format: %u, width: %u, height: %u, fps: %u, flags: %u", mediaType->Format,
128 mediaType->Width, mediaType->Height, mediaType->FrameRateNumerator, mediaType->Flags);
142 CAM_MSG_ID msg = CAM_MSG_ID_SampleResponse;
144 Stream_ResetPosition(stream->sampleRespBuffer);
145 if (!Stream_EnsureRemainingCapacity(stream->sampleRespBuffer, 3))
148 Stream_Write_UINT8(stream->sampleRespBuffer,
149 WINPR_ASSERTING_INT_CAST(uint8_t, dev->ecam->version));
150 Stream_Write_UINT8(stream->sampleRespBuffer, WINPR_ASSERTING_INT_CAST(uint8_t, msg));
151 Stream_Write_UINT8(stream->sampleRespBuffer, WINPR_ASSERTING_INT_CAST(uint8_t, streamIndex));
153 return stream->sampleRespBuffer;
156static BOOL mediaSupportDrops(CAM_MEDIA_FORMAT format)
160 case CAM_MEDIA_FORMAT_H264:
167static UINT ecam_dev_send_sample_error_response(
CameraDevice* dev,
169 size_t streamIndex, CAM_ERROR_CODE errorCode)
173 wStream* s = Stream_New(
nullptr, CAM_HEADER_SIZE + 5);
175 return ERROR_NOT_ENOUGH_MEMORY;
177 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, dev->ecam->version));
178 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, CAM_MSG_ID_SampleErrorResponse));
179 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, streamIndex));
180 Stream_Write_UINT32(s, (UINT32)errorCode);
182 return ecam_channel_write(dev->ecam, hchannel, CAM_MSG_ID_SampleErrorResponse, s, TRUE);
188 WINPR_ASSERT(stream);
190 if (stream->samplesRequested <= 0)
192 WLog_VRB(TAG,
"Frame delayed: No sample requested");
193 return CHANNEL_RC_OK;
196 if (!stream->haveSample)
198 WLog_VRB(TAG,
"Frame response delayed: No sample available");
199 return CHANNEL_RC_OK;
202 wStream* output = ecam_dev_prepare_sample_response(dev, streamIndex);
204 return CHANNEL_RC_OK;
206 const BYTE* encodedSample = Stream_Buffer(stream->pendingSample);
207 const size_t encodedSize = Stream_Length(stream->pendingSample);
208 if (!ecam_encoder_compress(stream, encodedSample, encodedSize, output))
210 WLog_DBG(TAG,
"Frame dropped: error in ecam_encoder_compress");
211 stream->haveSample = FALSE;
212 return CHANNEL_RC_OK;
215 if (!stream->streaming)
217 WLog_DBG(TAG,
"Frame delayed/dropped: stream stopped");
218 return CHANNEL_RC_OK;
221 stream->samplesRequested--;
222 stream->haveSample = FALSE;
225 return ecam_channel_write(dev->ecam, stream->hSampleReqChannel, CAM_MSG_ID_SampleResponse,
229static UINT ecam_dev_sample_captured_callback(
CameraDevice* dev,
size_t streamIndex,
230 const BYTE* sample,
size_t size)
234 if (streamIndex >= ECAM_DEVICE_MAX_STREAMS)
235 return ERROR_INVALID_INDEX;
239 if (!stream->streaming)
241 WLog_DBG(TAG,
"Frame drop: stream not running");
242 return CHANNEL_RC_OK;
245 EnterCriticalSection(&stream->lock);
246 UINT ret = CHANNEL_RC_NO_MEMORY;
247 if (dev->ihal->RequestDrivenCapture && (stream->samplesRequested <= 0))
252 const UINT64 idle = GetTickCount64() - stream->lastSampleRequestTime;
253 if (idle >= ECAM_CAPTURE_IDLE_TIMEOUT_MS)
255 WLog_DBG(TAG,
"No sample requested for %" PRIu64
" ms, releasing capture device", idle);
256 stream->captureRunning = FALSE;
257 ret = ECAM_SAMPLE_CAPTURE_DRAINED;
267 if (stream->haveSample && !mediaSupportDrops(stream->formats.inputFormat))
276 DWORD waitDelay = (1000 * stream->currMediaType.FrameRateDenominator) /
277 stream->currMediaType.FrameRateNumerator;
283 while (stream->haveSample && stream->streaming)
285 LeaveCriticalSection(&stream->lock);
287 SleepEx(waitDelay, TRUE);
289 EnterCriticalSection(&stream->lock);
292 if (!stream->streaming)
294 WLog_DBG(TAG,
"Frame drop: stream not running");
300 Stream_ResetPosition(stream->pendingSample);
301 if (!Stream_EnsureRemainingCapacity(stream->pendingSample, size))
304 Stream_Write(stream->pendingSample, sample, size);
305 Stream_SealLength(stream->pendingSample);
306 stream->haveSample = TRUE;
308 ret = ecam_dev_send_pending(dev, streamIndex, stream);
311 LeaveCriticalSection(&stream->lock);
315static void ecam_dev_stop_stream(
CameraDevice* dev,
size_t streamIndex)
319 if (streamIndex >= ECAM_DEVICE_MAX_STREAMS)
324 if (stream->streaming)
326 stream->streaming = FALSE;
327 stream->captureRunning = FALSE;
328 dev->ihal->StopStream(dev->ihal, dev->deviceId, 0);
330 DeleteCriticalSection(&stream->lock);
333 Stream_Free(stream->sampleRespBuffer, TRUE);
334 stream->sampleRespBuffer =
nullptr;
336 Stream_Free(stream->pendingSample, TRUE);
337 stream->pendingSample =
nullptr;
339 ecam_encoder_context_free(stream);
347static UINT ecam_dev_process_stop_streams_request(
CameraDevice* dev,
353 for (
size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++)
354 ecam_dev_stop_stream(dev, i);
356 return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse);
360static BOOL media_type_valid(
CameraDevice* dev, UINT8 streamIndex,
367 size_t nMediaTypes = ARRAYSIZE(supported);
369 size_t nSupportedFormats = 0;
372 dev->ihal->GetMediaTypeDescriptions(dev->ihal, dev->deviceId, streamIndex, supportedFormats,
373 nSupportedFormats, supported, &nMediaTypes);
377 for (
size_t x = 0; x < nMediaTypes; x++)
380 cur.Format = supportedFormats[formatIndex].outputFormat;
381 cur.Flags = CAM_MEDIA_TYPE_DESCRIPTION_FLAG_DecodingRequired;
393static UINT ecam_dev_process_start_streams_request(
CameraDevice* dev,
396 BYTE streamIndex = 0;
401 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1 + 26))
402 return ERROR_INVALID_DATA;
404 Stream_Read_UINT8(s, streamIndex);
406 if (streamIndex >= ECAM_DEVICE_MAX_STREAMS)
408 WLog_ERR(TAG,
"Incorrect streamIndex %" PRIu8, streamIndex);
409 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_InvalidStreamNumber);
410 return ERROR_INVALID_INDEX;
413 if (!ecam_dev_read_media_type(s, &mediaType))
415 WLog_ERR(TAG,
"Unable to read MEDIA_TYPE_DESCRIPTION");
416 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_InvalidMessage);
417 return ERROR_INVALID_DATA;
420 ecam_dev_print_media_type(&mediaType);
421 if (!media_type_valid(dev, streamIndex, &mediaType))
423 WLog_ERR(TAG,
"Unannounced MEDIA_TYPE_DESCRIPTION");
424 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_InvalidMessage);
425 return ERROR_INVALID_DATA;
430 if (stream->streaming)
432 WLog_ERR(TAG,
"Streaming already in progress, device %s, streamIndex %u", dev->deviceId,
434 return CAM_ERROR_CODE_UnexpectedError;
440 stream->currMediaType = mediaType;
442 if (!ecam_encoder_context_init(stream))
444 WLog_ERR(TAG,
"stream_ecam_encoder_init failed");
445 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_UnexpectedError);
446 return ERROR_INVALID_DATA;
449 stream->sampleRespBuffer = Stream_New(
nullptr, ECAM_SAMPLE_RESPONSE_BUFFER_SIZE);
450 if (!stream->sampleRespBuffer)
452 WLog_ERR(TAG,
"Stream_New failed");
453 ecam_dev_stop_stream(dev, streamIndex);
454 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_OutOfMemory);
455 return ERROR_INVALID_DATA;
459 mediaType.Format = streamInputFormat(stream);
461 stream->samplesRequested = 0;
462 stream->lastSampleRequestTime = GetTickCount64();
463 stream->haveSample = FALSE;
465 if (!InitializeCriticalSectionEx(&stream->lock, 0, 0))
467 WLog_ERR(TAG,
"InitializeCriticalSectionEx failed");
468 ecam_dev_stop_stream(dev, streamIndex);
469 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_OutOfMemory);
470 return ERROR_INVALID_DATA;
473 stream->pendingSample = Stream_New(
nullptr, 4ull * mediaType.Width * mediaType.Height);
474 if (!stream->pendingSample)
476 WLog_ERR(TAG,
"pending stream failed");
477 ecam_dev_stop_stream(dev, streamIndex);
478 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_OutOfMemory);
479 return ERROR_INVALID_DATA;
482 stream->captureRunning = TRUE;
483 const CAM_ERROR_CODE error = dev->ihal->StartStream(dev->ihal, dev, streamIndex, &mediaType,
484 ecam_dev_sample_captured_callback);
487 stream->captureRunning = FALSE;
488 WLog_ERR(TAG,
"StartStream failure");
489 ecam_dev_stop_stream(dev, streamIndex);
490 ecam_channel_send_error_response(dev->ecam, hchannel, error);
491 return ERROR_INVALID_DATA;
494 stream->streaming = TRUE;
495 return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse);
503static UINT ecam_dev_process_property_list_request(
CameraDevice* dev,
510 return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_PropertyListResponse);
518static UINT ecam_dev_send_current_media_type_response(
CameraDevice* dev,
522 CAM_MSG_ID msg = CAM_MSG_ID_CurrentMediaTypeResponse;
529 WLog_ERR(TAG,
"Stream_New failed");
530 return ERROR_NOT_ENOUGH_MEMORY;
533 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, dev->ecam->version));
534 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, msg));
536 ecam_dev_write_media_type(s, mediaType);
538 return ecam_channel_write(dev->ecam, hchannel, msg, s, TRUE);
549 BYTE streamIndex = 0;
553 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
554 return ERROR_INVALID_DATA;
556 Stream_Read_UINT8(s, streamIndex);
558 if (streamIndex >= ECAM_DEVICE_MAX_STREAMS)
560 WLog_ERR(TAG,
"Incorrect streamIndex %u", streamIndex);
561 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_InvalidStreamNumber);
562 return ERROR_INVALID_INDEX;
566 BOOL startCapture = FALSE;
569 EnterCriticalSection(&stream->lock);
572 if (stream->hSampleReqChannel != hchannel)
573 stream->hSampleReqChannel = hchannel;
575 stream->samplesRequested++;
576 stream->lastSampleRequestTime = GetTickCount64();
577 const UINT ret = ecam_dev_send_pending(dev, streamIndex, stream);
578 if (dev->ihal->RequestDrivenCapture && (ret == CHANNEL_RC_OK) && !stream->captureRunning)
580 stream->captureRunning = TRUE;
581 mediaType = stream->currMediaType;
582 mediaType.Format = streamInputFormat(stream);
586 LeaveCriticalSection(&stream->lock);
590 WLog_DBG(TAG,
"Sample requested, restarting capture device");
591 const CAM_ERROR_CODE error = dev->ihal->StartStream(dev->ihal, dev, streamIndex, &mediaType,
592 ecam_dev_sample_captured_callback);
595 WLog_ERR(TAG,
"StartStream failure");
596 EnterCriticalSection(&stream->lock);
597 stream->captureRunning = FALSE;
598 if (stream->samplesRequested > 0)
599 stream->samplesRequested--;
600 LeaveCriticalSection(&stream->lock);
601 ecam_dev_send_sample_error_response(dev, hchannel, streamIndex, error);
602 return ERROR_INVALID_DATA;
614static UINT ecam_dev_process_current_media_type_request(
CameraDevice* dev,
618 BYTE streamIndex = 0;
622 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
623 return ERROR_INVALID_DATA;
625 Stream_Read_UINT8(s, streamIndex);
627 if (streamIndex >= ECAM_DEVICE_MAX_STREAMS)
629 WLog_ERR(TAG,
"Incorrect streamIndex %u", streamIndex);
630 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_InvalidStreamNumber);
631 return ERROR_INVALID_INDEX;
636 if (stream->currMediaType.Format == 0)
638 WLog_ERR(TAG,
"Current media type unknown for streamIndex %u", streamIndex);
639 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_NotInitialized);
640 return ERROR_DEVICE_REINITIALIZATION_NEEDED;
643 return ecam_dev_send_current_media_type_response(dev, hchannel, &stream->currMediaType);
651static UINT ecam_dev_send_media_type_list_response(
CameraDevice* dev,
656 CAM_MSG_ID msg = CAM_MSG_ID_MediaTypeListResponse;
660 wStream* s = Stream_New(
nullptr, CAM_HEADER_SIZE + ECAM_MAX_MEDIA_TYPE_DESCRIPTORS *
664 WLog_ERR(TAG,
"Stream_New failed");
665 return ERROR_NOT_ENOUGH_MEMORY;
668 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, dev->ecam->version));
669 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, msg));
671 for (
size_t i = 0; i < nMediaTypes; i++, mediaTypes++)
673 ecam_dev_write_media_type(s, mediaTypes);
676 return ecam_channel_write(dev->ecam, hchannel, msg, s, TRUE);
684static UINT ecam_dev_process_media_type_list_request(
CameraDevice* dev,
687 UINT error = CHANNEL_RC_OK;
688 BYTE streamIndex = 0;
690 size_t nMediaTypes = ECAM_MAX_MEDIA_TYPE_DESCRIPTORS;
694 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
695 return ERROR_INVALID_DATA;
697 Stream_Read_UINT8(s, streamIndex);
699 if (streamIndex >= ECAM_DEVICE_MAX_STREAMS)
701 WLog_ERR(TAG,
"Incorrect streamIndex %u", streamIndex);
702 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_InvalidStreamNumber);
703 return ERROR_INVALID_INDEX;
711 WLog_ERR(TAG,
"calloc failed");
712 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_OutOfMemory);
713 return CHANNEL_RC_NO_MEMORY;
716 size_t nSupportedFormats = 0;
720 dev->ihal->GetMediaTypeDescriptions(dev->ihal, dev->deviceId, streamIndex, supportedFormats,
721 nSupportedFormats, mediaTypes, &nMediaTypes);
722 if (formatIndex == -1 || nMediaTypes == 0)
724 WLog_ERR(TAG,
"Camera doesn't support any compatible video formats");
725 ecam_channel_send_error_response(dev->ecam, hchannel, CAM_ERROR_CODE_ItemNotFound);
726 error = ERROR_DEVICE_FEATURE_NOT_SUPPORTED;
730 stream->formats = supportedFormats[formatIndex];
733 for (
size_t i = 0; i < nMediaTypes; i++)
735 mediaTypes[i].Format = streamOutputFormat(stream);
736 mediaTypes[i].Flags = CAM_MEDIA_TYPE_DESCRIPTION_FLAG_DecodingRequired;
739 if (stream->currMediaType.Format == 0)
742 stream->currMediaType = mediaTypes[0];
745 error = ecam_dev_send_media_type_list_response(dev, hchannel, mediaTypes, nMediaTypes);
757static UINT ecam_dev_send_stream_list_response(
CameraDevice* dev,
760 CAM_MSG_ID msg = CAM_MSG_ID_StreamListResponse;
767 WLog_ERR(TAG,
"Stream_New failed");
768 return ERROR_NOT_ENOUGH_MEMORY;
771 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, dev->ecam->version));
772 Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, msg));
775 Stream_Write_UINT16(s, CAM_STREAM_FRAME_SOURCE_TYPE_Color);
776 Stream_Write_UINT8(s, CAM_STREAM_CATEGORY_Capture);
777 Stream_Write_UINT8(s, TRUE );
778 Stream_Write_UINT8(s, FALSE );
780 return ecam_channel_write(dev->ecam, hchannel, msg, s, TRUE);
788static UINT ecam_dev_process_stream_list_request(
CameraDevice* dev,
792 return ecam_dev_send_stream_list_response(dev, hchannel);
800static UINT ecam_dev_process_activate_device_request(
CameraDevice* dev,
805 CAM_ERROR_CODE errorCode = CAM_ERROR_CODE_None;
807 if (dev->ihal->Activate(dev->ihal, dev->deviceId, &errorCode))
808 return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse);
810 return ecam_channel_send_error_response(dev->ecam, hchannel, errorCode);
818static UINT ecam_dev_process_deactivate_device_request(
CameraDevice* dev,
825 for (
size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++)
826 ecam_dev_stop_stream(dev, i);
828 CAM_ERROR_CODE errorCode = CAM_ERROR_CODE_None;
829 if (dev->ihal->Deactivate(dev->ihal, dev->deviceId, &errorCode))
830 return ecam_channel_send_generic_msg(dev->ecam, hchannel, CAM_MSG_ID_SuccessResponse);
832 return ecam_channel_send_error_response(dev->ecam, hchannel, errorCode);
840static UINT ecam_dev_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
wStream* data)
842 UINT error = CHANNEL_RC_OK;
847 if (!hchannel || !data)
848 return ERROR_INVALID_PARAMETER;
853 return ERROR_INTERNAL_ERROR;
855 if (!Stream_CheckAndLogRequiredLength(TAG, data, CAM_HEADER_SIZE))
856 return ERROR_NO_DATA;
858 Stream_Read_UINT8(data, version);
859 Stream_Read_UINT8(data, messageId);
860 WLog_DBG(TAG,
"ChannelId=%" PRIu32
", MessageId=0x%02" PRIx8
", Version=%d",
861 hchannel->channel_mgr->GetChannelId(hchannel->channel), messageId, version);
865 case CAM_MSG_ID_ActivateDeviceRequest:
866 error = ecam_dev_process_activate_device_request(dev, hchannel, data);
869 case CAM_MSG_ID_DeactivateDeviceRequest:
870 error = ecam_dev_process_deactivate_device_request(dev, hchannel, data);
873 case CAM_MSG_ID_StreamListRequest:
874 error = ecam_dev_process_stream_list_request(dev, hchannel, data);
877 case CAM_MSG_ID_MediaTypeListRequest:
878 error = ecam_dev_process_media_type_list_request(dev, hchannel, data);
881 case CAM_MSG_ID_CurrentMediaTypeRequest:
882 error = ecam_dev_process_current_media_type_request(dev, hchannel, data);
885 case CAM_MSG_ID_PropertyListRequest:
886 error = ecam_dev_process_property_list_request(dev, hchannel, data);
889 case CAM_MSG_ID_StartStreamsRequest:
890 error = ecam_dev_process_start_streams_request(dev, hchannel, data);
893 case CAM_MSG_ID_StopStreamsRequest:
894 error = ecam_dev_process_stop_streams_request(dev, hchannel, data);
897 case CAM_MSG_ID_SampleRequest:
898 error = ecam_dev_process_sample_request(dev, hchannel, data);
902 WLog_WARN(TAG,
"unknown MessageId=0x%02" PRIx8
"", messageId);
903 error = ERROR_INVALID_DATA;
904 ecam_channel_send_error_response(dev->ecam, hchannel,
905 CAM_ERROR_CODE_OperationNotSupported);
917static UINT ecam_dev_on_open(WINPR_ATTR_UNUSED IWTSVirtualChannelCallback* pChannelCallback)
919 WLog_DBG(TAG,
"entered");
920 return CHANNEL_RC_OK;
928static UINT ecam_dev_on_close(IWTSVirtualChannelCallback* pChannelCallback)
931 WINPR_ASSERT(hchannel);
936 WLog_DBG(TAG,
"entered");
938 for (
size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++)
939 ecam_dev_stop_stream(dev, i);
942 for (
size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++)
943 if (dev->streams[i].hSampleReqChannel == hchannel)
944 dev->streams[i].hSampleReqChannel =
nullptr;
947 return CHANNEL_RC_OK;
955static UINT ecam_dev_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
956 IWTSVirtualChannel* pChannel,
957 WINPR_ATTR_UNUSED BYTE* Data,
958 WINPR_ATTR_UNUSED BOOL* pbAccept,
959 IWTSVirtualChannelCallback** ppCallback)
963 if (!hlistener || !hlistener->plugin)
964 return ERROR_INTERNAL_ERROR;
966 WLog_DBG(TAG,
"entered");
972 WLog_ERR(TAG,
"calloc failed");
973 return CHANNEL_RC_NO_MEMORY;
976 hchannel->iface.OnDataReceived = ecam_dev_on_data_received;
977 hchannel->iface.OnOpen = ecam_dev_on_open;
978 hchannel->iface.OnClose = ecam_dev_on_close;
979 hchannel->plugin = hlistener->plugin;
980 hchannel->channel_mgr = hlistener->channel_mgr;
981 hchannel->channel = pChannel;
982 *ppCallback = (IWTSVirtualChannelCallback*)hchannel;
983 return CHANNEL_RC_OK;
992 WINPR_ATTR_UNUSED
const char* deviceName)
995 WINPR_ASSERT(ecam->hlistener);
997 IWTSVirtualChannelManager* pChannelMgr = ecam->hlistener->channel_mgr;
998 WINPR_ASSERT(pChannelMgr);
1000 WLog_DBG(TAG,
"entered for %s", deviceId);
1006 WLog_ERR(TAG,
"calloc failed");
1011 dev->ihal = ecam->ihal;
1012 strncpy(dev->deviceId, deviceId,
sizeof(dev->deviceId) - 1);
1015 if (!dev->hlistener)
1018 WLog_ERR(TAG,
"calloc failed");
1022 dev->hlistener->iface.OnNewChannelConnection = ecam_dev_on_new_channel_connection;
1023 dev->hlistener->plugin = (IWTSPlugin*)dev;
1024 dev->hlistener->channel_mgr = pChannelMgr;
1025 if (CHANNEL_RC_OK != pChannelMgr->CreateListener(pChannelMgr, deviceId, 0,
1026 &dev->hlistener->iface, &dev->listener))
1028 free(dev->hlistener);
1030 WLog_ERR(TAG,
"CreateListener failed");
1048 WLog_DBG(TAG,
"entered for %s", dev->deviceId);
1052 IWTSVirtualChannelManager* mgr = dev->hlistener->channel_mgr;
1054 IFCALL(mgr->DestroyListener, mgr, dev->listener);
1057 free(dev->hlistener);
1059 for (
size_t i = 0; i < ECAM_DEVICE_MAX_STREAMS; i++)
1060 ecam_dev_stop_stream(dev, i);