23#include <freerdp/config.h>
32#include <winpr/stream.h>
34#include "tsmf_types.h"
35#include "tsmf_constants.h"
36#include "tsmf_media.h"
37#include "tsmf_codec.h"
39#include "tsmf_ifman.h"
46UINT tsmf_ifman_rim_exchange_capability_request(
TSMF_IFMAN* ifman)
48 UINT32 CapabilityValue = 0;
50 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 4))
51 return ERROR_INVALID_DATA;
53 Stream_Read_UINT32(ifman->input, CapabilityValue);
54 DEBUG_TSMF(
"server CapabilityValue %" PRIu32
"", CapabilityValue);
56 if (!Stream_EnsureRemainingCapacity(ifman->output, 8))
57 return ERROR_INVALID_DATA;
59 Stream_Write_UINT32(ifman->output, 1);
60 Stream_Write_UINT32(ifman->output, 0);
69UINT tsmf_ifman_exchange_capability_request(
TSMF_IFMAN* ifman)
71 UINT32 CapabilityType = 0;
72 UINT32 cbCapabilityLength = 0;
73 UINT32 numHostCapabilities = 0;
76 if (!Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4))
77 return ERROR_OUTOFMEMORY;
79 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, ifman->input_size))
80 return ERROR_INVALID_DATA;
82 const size_t xpos = Stream_GetPosition(ifman->output);
83 Stream_Copy(ifman->input, ifman->output, ifman->input_size);
84 if (!Stream_SetPosition(ifman->output, xpos))
85 return ERROR_INVALID_DATA;
87 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 4))
88 return ERROR_INVALID_DATA;
90 Stream_Read_UINT32(ifman->output, numHostCapabilities);
92 for (UINT32 i = 0; i < numHostCapabilities; i++)
94 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 8))
95 return ERROR_INVALID_DATA;
97 Stream_Read_UINT32(ifman->output, CapabilityType);
98 Stream_Read_UINT32(ifman->output, cbCapabilityLength);
100 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, cbCapabilityLength))
101 return ERROR_INVALID_DATA;
103 const size_t pos = Stream_GetPosition(ifman->output);
105 switch (CapabilityType)
109 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 4))
110 return ERROR_INVALID_DATA;
112 const UINT32 v = Stream_Get_UINT32(ifman->output);
114 DEBUG_TSMF(
"server protocol version %" PRIu32
"", v);
120 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 4))
121 return ERROR_INVALID_DATA;
123 const UINT32 v = Stream_Get_UINT32(ifman->output);
125 DEBUG_TSMF(
"server supported platform %" PRIu32
"", v);
127 Stream_Write_UINT32(ifman->output, MMREDIR_CAPABILITY_PLATFORM_MF |
128 MMREDIR_CAPABILITY_PLATFORM_DSHOW);
133 WLog_ERR(TAG,
"skipping unknown capability type %" PRIu32
"", CapabilityType);
137 if (!Stream_SetPosition(ifman->output, pos + cbCapabilityLength))
138 return ERROR_INVALID_DATA;
141 Stream_Write_UINT32(ifman->output, 0);
142 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
143 return CHANNEL_RC_OK;
151UINT tsmf_ifman_check_format_support_request(
TSMF_IFMAN* ifman)
153 UINT32 numMediaType = 0;
154 UINT32 PlatformCookie = 0;
155 UINT32 FormatSupported = 1;
157 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 12))
158 return ERROR_INVALID_DATA;
160 Stream_Read_UINT32(ifman->input, PlatformCookie);
161 Stream_Seek_UINT32(ifman->input);
162 Stream_Read_UINT32(ifman->input, numMediaType);
163 DEBUG_TSMF(
"PlatformCookie %" PRIu32
" numMediaType %" PRIu32
"", PlatformCookie, numMediaType);
165 if (!tsmf_codec_check_media_type(ifman->decoder_name, ifman->input))
169 DEBUG_TSMF(
"format ok.");
171 if (!Stream_EnsureRemainingCapacity(ifman->output, 12))
174 Stream_Write_UINT32(ifman->output, FormatSupported);
175 Stream_Write_UINT32(ifman->output, PlatformCookie);
176 Stream_Write_UINT32(ifman->output, 0);
177 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
178 return CHANNEL_RC_OK;
186UINT tsmf_ifman_on_new_presentation(
TSMF_IFMAN* ifman)
188 UINT status = CHANNEL_RC_OK;
189 TSMF_PRESENTATION* presentation =
nullptr;
192 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE))
193 return ERROR_INVALID_DATA;
195 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
199 DEBUG_TSMF(
"Presentation already exists");
200 ifman->output_pending = FALSE;
201 return CHANNEL_RC_OK;
204 presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback);
207 status = ERROR_OUTOFMEMORY;
209 tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device);
211 ifman->output_pending = TRUE;
220UINT tsmf_ifman_add_stream(
TSMF_IFMAN* ifman, rdpContext* rdpcontext)
223 UINT status = CHANNEL_RC_OK;
224 TSMF_STREAM* stream =
nullptr;
225 TSMF_PRESENTATION* presentation =
nullptr;
228 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 8))
229 return ERROR_INVALID_DATA;
231 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
232 Stream_Seek(ifman->input, GUID_SIZE);
236 WLog_ERR(TAG,
"unknown presentation id");
237 status = ERROR_NOT_FOUND;
241 Stream_Read_UINT32(ifman->input, StreamId);
242 Stream_Seek_UINT32(ifman->input);
243 stream = tsmf_stream_new(presentation, StreamId, rdpcontext);
247 WLog_ERR(TAG,
"failed to create stream");
248 return ERROR_OUTOFMEMORY;
251 if (!tsmf_stream_set_format(stream, ifman->decoder_name, ifman->input))
253 WLog_ERR(TAG,
"failed to set stream format");
254 return ERROR_OUTOFMEMORY;
257 tsmf_stream_start_threads(stream);
260 ifman->output_pending = TRUE;
269UINT tsmf_ifman_set_topology_request(
TSMF_IFMAN* ifman)
273 if (!Stream_EnsureRemainingCapacity(ifman->output, 8))
274 return ERROR_OUTOFMEMORY;
276 Stream_Write_UINT32(ifman->output, 1);
277 Stream_Write_UINT32(ifman->output, 0);
278 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
279 return CHANNEL_RC_OK;
287UINT tsmf_ifman_remove_stream(
TSMF_IFMAN* ifman)
289 int status = CHANNEL_RC_OK;
291 TSMF_STREAM* stream =
nullptr;
292 TSMF_PRESENTATION* presentation =
nullptr;
295 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 20))
296 return ERROR_INVALID_DATA;
298 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
299 Stream_Seek(ifman->input, GUID_SIZE);
303 status = ERROR_NOT_FOUND;
307 Stream_Read_UINT32(ifman->input, StreamId);
308 stream = tsmf_stream_find_by_id(presentation, StreamId);
311 tsmf_stream_free(stream);
313 status = ERROR_NOT_FOUND;
316 ifman->output_pending = TRUE;
320static float tsmf_stream_read_float(
wStream* s)
324 Stream_Read_UINT32(s, iValue);
325 CopyMemory(&fValue, &iValue, 4);
334UINT tsmf_ifman_set_source_video_rect(
TSMF_IFMAN* ifman)
336 UINT status = CHANNEL_RC_OK;
337 TSMF_PRESENTATION* presentation =
nullptr;
340 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 32))
341 return ERROR_INVALID_DATA;
343 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
344 Stream_Seek(ifman->input, GUID_SIZE);
348 status = ERROR_NOT_FOUND;
352#ifdef WITH_DEBUG_TSMF
353 const float Left = tsmf_stream_read_float(ifman->input);
354 const float Top = tsmf_stream_read_float(ifman->input);
355 const float Right = tsmf_stream_read_float(ifman->input);
356 const float Bottom = tsmf_stream_read_float(ifman->input);
357 DEBUG_TSMF(
"SetSourceVideoRect: Left: %f Top: %f Right: %f Bottom: %f", Left, Top, Right,
362 ifman->output_pending = TRUE;
371UINT tsmf_ifman_shutdown_presentation(
TSMF_IFMAN* ifman)
373 TSMF_PRESENTATION* presentation =
nullptr;
376 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE))
377 return ERROR_INVALID_DATA;
379 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
382 tsmf_presentation_free(presentation);
385 WLog_ERR(TAG,
"unknown presentation id");
386 return ERROR_NOT_FOUND;
389 if (!Stream_EnsureRemainingCapacity(ifman->output, 4))
390 return ERROR_OUTOFMEMORY;
392 Stream_Write_UINT32(ifman->output, 0);
393 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
394 return CHANNEL_RC_OK;
402UINT tsmf_ifman_on_stream_volume(
TSMF_IFMAN* ifman)
404 TSMF_PRESENTATION* presentation =
nullptr;
405 UINT32 newVolume = 0;
407 DEBUG_TSMF(
"on stream volume");
409 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 8))
410 return ERROR_INVALID_DATA;
412 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
416 WLog_ERR(TAG,
"unknown presentation id");
417 return ERROR_NOT_FOUND;
420 Stream_Seek(ifman->input, 16);
421 Stream_Read_UINT32(ifman->input, newVolume);
422 DEBUG_TSMF(
"on stream volume: new volume=[%" PRIu32
"]", newVolume);
423 Stream_Read_UINT32(ifman->input, muted);
424 DEBUG_TSMF(
"on stream volume: muted=[%" PRIu32
"]", muted);
426 if (!tsmf_presentation_volume_changed(presentation, newVolume, muted))
427 return ERROR_INVALID_OPERATION;
429 ifman->output_pending = TRUE;
438UINT tsmf_ifman_on_channel_volume(
TSMF_IFMAN* ifman)
440 TSMF_PRESENTATION* presentation =
nullptr;
441 DEBUG_TSMF(
"on channel volume");
443 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 8))
444 return ERROR_INVALID_DATA;
446 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
450 UINT32 channelVolume = 0;
451 UINT32 changedChannel = 0;
452 Stream_Seek(ifman->input, 16);
453 Stream_Read_UINT32(ifman->input, channelVolume);
454 DEBUG_TSMF(
"on channel volume: channel volume=[%" PRIu32
"]", channelVolume);
455 Stream_Read_UINT32(ifman->input, changedChannel);
456 DEBUG_TSMF(
"on stream volume: changed channel=[%" PRIu32
"]", changedChannel);
459 ifman->output_pending = TRUE;
460 return CHANNEL_RC_OK;
468UINT tsmf_ifman_set_video_window(
TSMF_IFMAN* ifman)
471 ifman->output_pending = TRUE;
472 return CHANNEL_RC_OK;
480UINT tsmf_ifman_update_geometry_info(
TSMF_IFMAN* ifman)
482 TSMF_PRESENTATION* presentation =
nullptr;
483 UINT32 numGeometryInfo = 0;
488 UINT32 cbVisibleRect = 0;
490 UINT error = CHANNEL_RC_OK;
493 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, GUID_SIZE + 32))
494 return ERROR_INVALID_DATA;
496 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
499 return ERROR_NOT_FOUND;
501 Stream_Seek(ifman->input, 16);
502 Stream_Read_UINT32(ifman->input, numGeometryInfo);
503 pos = Stream_GetPosition(ifman->input);
504 Stream_Seek(ifman->input, 12);
505 Stream_Read_UINT32(ifman->input, Width);
506 Stream_Read_UINT32(ifman->input, Height);
507 Stream_Read_UINT32(ifman->input, Left);
508 Stream_Read_UINT32(ifman->input, Top);
509 if (!Stream_SetPosition(ifman->input, pos + numGeometryInfo))
510 return ERROR_INVALID_DATA;
511 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 4))
512 return ERROR_INVALID_DATA;
513 Stream_Read_UINT32(ifman->input, cbVisibleRect);
514 const UINT32 num_rects = cbVisibleRect / 16;
515 DEBUG_TSMF(
"numGeometryInfo %" PRIu32
" Width %" PRIu32
" Height %" PRIu32
" Left %" PRIu32
516 " Top %" PRIu32
" cbVisibleRect %" PRIu32
" num_rects %d",
517 numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects);
521 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, ifman->input, num_rects, 16ull))
522 return ERROR_INVALID_DATA;
526 return ERROR_OUTOFMEMORY;
528 for (
size_t i = 0; i < num_rects; i++)
530 Stream_Read_UINT32(ifman->input, rects[i].top);
531 Stream_Read_UINT32(ifman->input, rects[i].left);
532 Stream_Read_UINT32(ifman->input, rects[i].height);
533 Stream_Read_UINT32(ifman->input, rects[i].width);
534 rects[i].width -= rects[i].left;
535 rects[i].height -= rects[i].top;
536 DEBUG_TSMF(
"rect %d: %" PRId16
" %" PRId16
" %" PRId16
" %" PRId16
"", i, rects[i].x,
537 rects[i].y, rects[i].width, rects[i].height);
541 const BOOL rc = tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height,
545 return ERROR_INVALID_OPERATION;
547 ifman->output_pending = TRUE;
556UINT tsmf_ifman_set_allocator(
TSMF_IFMAN* ifman)
559 ifman->output_pending = TRUE;
560 return CHANNEL_RC_OK;
568UINT tsmf_ifman_notify_preroll(
TSMF_IFMAN* ifman)
571 tsmf_ifman_on_playback_paused(ifman);
572 ifman->output_pending = TRUE;
573 return CHANNEL_RC_OK;
583 TSMF_PRESENTATION* presentation =
nullptr;
584 TSMF_STREAM* stream =
nullptr;
586 UINT64 SampleStartTime = 0;
587 UINT64 SampleEndTime = 0;
588 UINT64 ThrottleDuration = 0;
589 UINT32 SampleExtensions = 0;
593 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 60))
594 return ERROR_INVALID_DATA;
596 Stream_Seek(ifman->input, 16);
597 Stream_Read_UINT32(ifman->input, StreamId);
598 Stream_Seek_UINT32(ifman->input);
599 Stream_Read_UINT64(ifman->input, SampleStartTime);
600 Stream_Read_UINT64(ifman->input, SampleEndTime);
601 Stream_Read_UINT64(ifman->input, ThrottleDuration);
602 Stream_Seek_UINT32(ifman->input);
603 Stream_Read_UINT32(ifman->input, SampleExtensions);
604 Stream_Read_UINT32(ifman->input, cbData);
606 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, cbData))
607 return ERROR_INVALID_DATA;
609 DEBUG_TSMF(
"MessageId %" PRIu32
" StreamId %" PRIu32
" SampleStartTime %" PRIu64
610 " SampleEndTime %" PRIu64
" "
611 "ThrottleDuration %" PRIu64
" SampleExtensions %" PRIu32
" cbData %" PRIu32
"",
612 ifman->message_id, StreamId, SampleStartTime, SampleEndTime, ThrottleDuration,
613 SampleExtensions, cbData);
614 presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
618 WLog_ERR(TAG,
"unknown presentation id");
619 return ERROR_NOT_FOUND;
622 stream = tsmf_stream_find_by_id(presentation, StreamId);
626 WLog_ERR(TAG,
"unknown stream id");
627 return ERROR_NOT_FOUND;
630 if (!tsmf_stream_push_sample(stream, ifman->channel_callback, ifman->message_id,
631 SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions,
632 cbData, Stream_Pointer(ifman->input)))
634 WLog_ERR(TAG,
"unable to push sample");
635 return ERROR_OUTOFMEMORY;
638 if ((error = tsmf_presentation_sync(presentation)))
640 WLog_ERR(TAG,
"tsmf_presentation_sync failed with error %" PRIu32
"", error);
644 ifman->output_pending = TRUE;
645 return CHANNEL_RC_OK;
656 TSMF_PRESENTATION* presentation =
nullptr;
657 TSMF_STREAM* stream =
nullptr;
659 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 20))
660 return ERROR_INVALID_DATA;
662 Stream_Seek(ifman->input, 16);
663 Stream_Read_UINT32(ifman->input, StreamId);
664 DEBUG_TSMF(
"StreamId %" PRIu32
"", StreamId);
665 presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
669 WLog_ERR(TAG,
"unknown presentation id");
670 return ERROR_NOT_FOUND;
676 stream = tsmf_stream_find_by_id(presentation, StreamId);
680 if (!tsmf_stream_flush(stream))
681 return ERROR_INVALID_OPERATION;
684 WLog_ERR(TAG,
"unknown stream id");
686 ifman->output_pending = TRUE;
687 return CHANNEL_RC_OK;
695UINT tsmf_ifman_on_end_of_stream(
TSMF_IFMAN* ifman)
698 TSMF_STREAM* stream =
nullptr;
699 TSMF_PRESENTATION* presentation =
nullptr;
701 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 20))
702 return ERROR_INVALID_DATA;
704 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
705 Stream_Seek(ifman->input, 16);
706 Stream_Read_UINT32(ifman->input, StreamId);
710 stream = tsmf_stream_find_by_id(presentation, StreamId);
713 tsmf_stream_end(stream, ifman->message_id, ifman->channel_callback);
716 DEBUG_TSMF(
"StreamId %" PRIu32
"", StreamId);
717 ifman->output_pending = TRUE;
718 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
719 return CHANNEL_RC_OK;
727UINT tsmf_ifman_on_playback_started(
TSMF_IFMAN* ifman)
729 TSMF_PRESENTATION* presentation =
nullptr;
732 if (!Stream_CheckAndLogRequiredLength(TAG, ifman->input, 16))
733 return ERROR_INVALID_DATA;
735 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
738 tsmf_presentation_start(presentation);
740 WLog_ERR(TAG,
"unknown presentation id");
742 if (!Stream_EnsureRemainingCapacity(ifman->output, 16))
743 return ERROR_OUTOFMEMORY;
745 Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION);
746 Stream_Write_UINT32(ifman->output, 0);
747 Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED);
748 Stream_Write_UINT32(ifman->output, 0);
749 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
750 return CHANNEL_RC_OK;
758UINT tsmf_ifman_on_playback_paused(
TSMF_IFMAN* ifman)
760 TSMF_PRESENTATION* presentation =
nullptr;
762 ifman->output_pending = TRUE;
764 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
768 if (!tsmf_presentation_paused(presentation))
769 return ERROR_INVALID_OPERATION;
772 WLog_ERR(TAG,
"unknown presentation id");
774 return CHANNEL_RC_OK;
782UINT tsmf_ifman_on_playback_restarted(
TSMF_IFMAN* ifman)
784 TSMF_PRESENTATION* presentation =
nullptr;
786 ifman->output_pending = TRUE;
788 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
792 if (!tsmf_presentation_restarted(presentation))
793 return ERROR_INVALID_OPERATION;
796 WLog_ERR(TAG,
"unknown presentation id");
798 return CHANNEL_RC_OK;
806UINT tsmf_ifman_on_playback_stopped(
TSMF_IFMAN* ifman)
808 TSMF_PRESENTATION* presentation =
nullptr;
810 presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
814 if (!tsmf_presentation_stop(presentation))
815 return ERROR_INVALID_OPERATION;
818 WLog_ERR(TAG,
"unknown presentation id");
820 if (!Stream_EnsureRemainingCapacity(ifman->output, 16))
821 return ERROR_OUTOFMEMORY;
823 Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION);
824 Stream_Write_UINT32(ifman->output, 0);
825 Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED);
826 Stream_Write_UINT32(ifman->output, 0);
827 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
828 return CHANNEL_RC_OK;
836UINT tsmf_ifman_on_playback_rate_changed(
TSMF_IFMAN* ifman)
840 if (!Stream_EnsureRemainingCapacity(ifman->output, 16))
841 return ERROR_OUTOFMEMORY;
843 Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION);
844 Stream_Write_UINT32(ifman->output, 0);
845 Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_MONITORCHANGED);
846 Stream_Write_UINT32(ifman->output, 0);
847 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
848 return CHANNEL_RC_OK;