2
* FreeRDP: A Remote Desktop Protocol Implementation
3
* Video Redirection Virtual Channel - Interface Manipulation
5
* Copyright 2010-2011 Vic Lee
6
* Copyright 2012 Hewlett-Packard Development Company, L.P.
8
* Licensed under the Apache License, Version 2.0 (the "License");
9
* you may not use this file except in compliance with the License.
10
* You may obtain a copy of the License at
12
* http://www.apache.org/licenses/LICENSE-2.0
14
* Unless required by applicable law or agreed to in writing, software
15
* distributed under the License is distributed on an "AS IS" BASIS,
16
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
* See the License for the specific language governing permissions and
18
* limitations under the License.
29
#include <winpr/crt.h>
31
#include <winpr/stream.h>
33
#include "tsmf_types.h"
34
#include "tsmf_constants.h"
35
#include "tsmf_media.h"
36
#include "tsmf_codec.h"
38
#include "tsmf_ifman.h"
40
int tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman)
42
UINT32 CapabilityValue;
44
Stream_Read_UINT32(ifman->input, CapabilityValue);
45
DEBUG_DVC("server CapabilityValue %d", CapabilityValue);
47
Stream_EnsureRemainingCapacity(ifman->output, 8);
48
Stream_Write_UINT32(ifman->output, 1); /* CapabilityValue */
49
Stream_Write_UINT32(ifman->output, 0); /* Result */
54
int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
59
UINT32 CapabilityType;
60
UINT32 cbCapabilityLength;
61
UINT32 numHostCapabilities;
63
pos = Stream_GetPosition(ifman->output);
64
Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4);
65
Stream_Copy(ifman->output, ifman->input, ifman->input_size);
67
Stream_SetPosition(ifman->output, pos);
68
Stream_Read_UINT32(ifman->output, numHostCapabilities);
70
for (i = 0; i < numHostCapabilities; i++)
72
Stream_Read_UINT32(ifman->output, CapabilityType);
73
Stream_Read_UINT32(ifman->output, cbCapabilityLength);
74
pos = Stream_GetPosition(ifman->output);
76
switch (CapabilityType)
78
case 1: /* Protocol version request */
79
Stream_Read_UINT32(ifman->output, v);
80
DEBUG_DVC("server protocol version %d", v);
82
case 2: /* Supported platform */
83
Stream_Peek_UINT32(ifman->output, v);
84
DEBUG_DVC("server supported platform %d", v);
85
/* Claim that we support both MF and DShow platforms. */
86
Stream_Write_UINT32(ifman->output,
87
MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW);
90
DEBUG_WARN("unknown capability type %d", CapabilityType);
93
Stream_SetPosition(ifman->output, pos + cbCapabilityLength);
95
Stream_Write_UINT32(ifman->output, 0); /* Result */
97
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
102
int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
105
UINT32 PlatformCookie;
106
UINT32 FormatSupported = 1;
108
Stream_Read_UINT32(ifman->input, PlatformCookie);
109
Stream_Seek_UINT32(ifman->input); /* NoRolloverFlags (4 bytes) */
110
Stream_Read_UINT32(ifman->input, numMediaType);
112
DEBUG_DVC("PlatformCookie %d numMediaType %d", PlatformCookie, numMediaType);
114
if (!tsmf_codec_check_media_type(ifman->input))
118
DEBUG_DVC("format ok.");
120
Stream_EnsureRemainingCapacity(ifman->output, 12);
121
Stream_Write_UINT32(ifman->output, FormatSupported);
122
Stream_Write_UINT32(ifman->output, PlatformCookie);
123
Stream_Write_UINT32(ifman->output, 0); /* Result */
125
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
130
int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
133
TSMF_PRESENTATION* presentation;
137
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
140
DEBUG_DVC("Presentation already exists");
141
ifman->output_pending = FALSE;
146
presentation = tsmf_presentation_new(Stream_Pointer(ifman->input), ifman->channel_callback);
148
if (presentation == NULL)
151
tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device);
153
ifman->output_pending = TRUE;
158
int tsmf_ifman_add_stream(TSMF_IFMAN* ifman)
163
TSMF_PRESENTATION* presentation;
167
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
168
Stream_Seek(ifman->input, 16);
170
if (presentation == NULL)
176
Stream_Read_UINT32(ifman->input, StreamId);
177
Stream_Seek_UINT32(ifman->input); /* numMediaType */
178
stream = tsmf_stream_new(presentation, StreamId);
181
tsmf_stream_set_format(stream, ifman->decoder_name, ifman->input);
184
ifman->output_pending = TRUE;
189
int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman)
193
Stream_EnsureRemainingCapacity(ifman->output, 8);
194
Stream_Write_UINT32(ifman->output, 1); /* TopologyReady */
195
Stream_Write_UINT32(ifman->output, 0); /* Result */
196
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
201
int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
206
TSMF_PRESENTATION* presentation;
210
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
211
Stream_Seek(ifman->input, 16);
213
if (presentation == NULL)
219
Stream_Read_UINT32(ifman->input, StreamId);
220
stream = tsmf_stream_find_by_id(presentation, StreamId);
222
tsmf_stream_free(stream);
227
ifman->output_pending = TRUE;
232
float tsmf_stream_read_float(wStream* s)
237
Stream_Read_UINT32(s, iValue);
238
CopyMemory(&fValue, &iValue, 4);
243
int tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman)
248
TSMF_PRESENTATION* presentation;
252
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
253
Stream_Seek(ifman->input, 16);
261
Left = tsmf_stream_read_float(ifman->input); /* Left (4 bytes) */
262
Top = tsmf_stream_read_float(ifman->input); /* Top (4 bytes) */
263
Right = tsmf_stream_read_float(ifman->input); /* Right (4 bytes) */
264
Bottom = tsmf_stream_read_float(ifman->input); /* Bottom (4 bytes) */
266
DEBUG_DVC("SetSourceVideoRect: Left: %f Top: %f Right: %f Bottom: %f",
267
Left, Top, Right, Bottom);
270
ifman->output_pending = TRUE;
275
int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
277
TSMF_PRESENTATION* presentation;
281
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
284
tsmf_presentation_free(presentation);
286
DEBUG_WARN("unknown presentation id");
288
Stream_EnsureRemainingCapacity(ifman->output, 4);
289
Stream_Write_UINT32(ifman->output, 0); /* Result */
290
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
295
int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
297
TSMF_PRESENTATION* presentation;
299
DEBUG_DVC("on stream volume");
301
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
308
Stream_Seek(ifman->input, 16);
309
Stream_Read_UINT32(ifman->input, newVolume);
310
DEBUG_DVC("on stream volume: new volume=[%d]", newVolume);
311
Stream_Read_UINT32(ifman->input, muted);
312
DEBUG_DVC("on stream volume: muted=[%d]", muted);
313
tsmf_presentation_volume_changed(presentation, newVolume, muted);
317
DEBUG_WARN("unknown presentation id");
320
ifman->output_pending = TRUE;
325
int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman)
327
TSMF_PRESENTATION* presentation;
329
DEBUG_DVC("on channel volume");
331
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
335
UINT32 channelVolume;
336
UINT32 changedChannel;
338
Stream_Seek(ifman->input, 16);
339
Stream_Read_UINT32(ifman->input, channelVolume);
340
DEBUG_DVC("on channel volume: channel volume=[%d]", channelVolume);
341
Stream_Read_UINT32(ifman->input, changedChannel);
342
DEBUG_DVC("on stream volume: changed channel=[%d]", changedChannel);
345
ifman->output_pending = TRUE;
350
int tsmf_ifman_set_video_window(TSMF_IFMAN* ifman)
353
ifman->output_pending = TRUE;
357
int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
359
TSMF_PRESENTATION* presentation;
360
UINT32 numGeometryInfo;
365
UINT32 cbVisibleRect;
366
RDP_RECT* rects = NULL;
372
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
373
Stream_Seek(ifman->input, 16);
375
Stream_Read_UINT32(ifman->input, numGeometryInfo);
376
pos = Stream_GetPosition(ifman->input);
378
Stream_Seek(ifman->input, 12); /* VideoWindowId (8 bytes), VideoWindowState (4 bytes) */
379
Stream_Read_UINT32(ifman->input, Width);
380
Stream_Read_UINT32(ifman->input, Height);
381
Stream_Read_UINT32(ifman->input, Left);
382
Stream_Read_UINT32(ifman->input, Top);
384
Stream_SetPosition(ifman->input, pos + numGeometryInfo);
385
Stream_Read_UINT32(ifman->input, cbVisibleRect);
386
num_rects = cbVisibleRect / 16;
388
DEBUG_DVC("numGeometryInfo %d Width %d Height %d Left %d Top %d cbVisibleRect %d num_rects %d",
389
numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects);
391
if (presentation == NULL)
399
rects = (RDP_RECT*) malloc(sizeof(RDP_RECT) * num_rects);
400
ZeroMemory(rects, sizeof(RDP_RECT) * num_rects);
402
for (i = 0; i < num_rects; i++)
404
Stream_Read_UINT16(ifman->input, rects[i].y); /* Top */
405
Stream_Seek_UINT16(ifman->input);
406
Stream_Read_UINT16(ifman->input, rects[i].x); /* Left */
407
Stream_Seek_UINT16(ifman->input);
408
Stream_Read_UINT16(ifman->input, rects[i].height); /* Bottom */
409
Stream_Seek_UINT16(ifman->input);
410
Stream_Read_UINT16(ifman->input, rects[i].width); /* Right */
411
Stream_Seek_UINT16(ifman->input);
412
rects[i].width -= rects[i].x;
413
rects[i].height -= rects[i].y;
415
DEBUG_DVC("rect %d: %d %d %d %d", i,
416
rects[i].x, rects[i].y, rects[i].width, rects[i].height);
419
tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height, num_rects, rects);
422
ifman->output_pending = TRUE;
427
int tsmf_ifman_set_allocator(TSMF_IFMAN* ifman)
430
ifman->output_pending = TRUE;
434
int tsmf_ifman_notify_preroll(TSMF_IFMAN* ifman)
437
ifman->output_pending = TRUE;
441
int tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
443
TSMF_PRESENTATION* presentation;
446
UINT64 SampleStartTime;
447
UINT64 SampleEndTime;
448
UINT64 ThrottleDuration;
449
UINT32 SampleExtensions;
452
Stream_Seek(ifman->input, 16);
453
Stream_Read_UINT32(ifman->input, StreamId);
454
Stream_Seek_UINT32(ifman->input); /* numSample */
455
Stream_Read_UINT64(ifman->input, SampleStartTime);
456
Stream_Read_UINT64(ifman->input, SampleEndTime);
457
Stream_Read_UINT64(ifman->input, ThrottleDuration);
458
Stream_Seek_UINT32(ifman->input); /* SampleFlags */
459
Stream_Read_UINT32(ifman->input, SampleExtensions);
460
Stream_Read_UINT32(ifman->input, cbData);
462
DEBUG_DVC("MessageId %d StreamId %d SampleStartTime %d SampleEndTime %d "
463
"ThrottleDuration %d SampleExtensions %d cbData %d",
464
ifman->message_id, StreamId, (int)SampleStartTime, (int)SampleEndTime,
465
(int)ThrottleDuration, SampleExtensions, cbData);
467
presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
469
if (presentation == NULL)
471
DEBUG_WARN("unknown presentation id");
475
stream = tsmf_stream_find_by_id(presentation, StreamId);
479
DEBUG_WARN("unknown stream id");
483
tsmf_stream_push_sample(stream, ifman->channel_callback,
484
ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions,
485
cbData, Stream_Pointer(ifman->input));
487
ifman->output_pending = TRUE;
492
int tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
495
TSMF_PRESENTATION* presentation;
497
Stream_Seek(ifman->input, 16);
498
Stream_Read_UINT32(ifman->input, StreamId);
499
DEBUG_DVC("StreamId %d", StreamId);
501
presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
503
if (presentation == NULL)
505
DEBUG_WARN("unknown presentation id");
509
tsmf_presentation_flush(presentation);
511
ifman->output_pending = TRUE;
516
int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
520
TSMF_PRESENTATION* presentation;
522
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
523
Stream_Seek(ifman->input, 16);
524
Stream_Read_UINT32(ifman->input, StreamId);
528
stream = tsmf_stream_find_by_id(presentation, StreamId);
530
tsmf_stream_end(stream);
532
DEBUG_DVC("StreamId %d", StreamId);
534
Stream_EnsureRemainingCapacity(ifman->output, 16);
535
Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
536
Stream_Write_UINT32(ifman->output, StreamId); /* StreamId */
537
Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */
538
Stream_Write_UINT32(ifman->output, 0); /* cbData */
539
ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
544
int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
546
TSMF_PRESENTATION* presentation;
550
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
553
tsmf_presentation_start(presentation);
555
DEBUG_WARN("unknown presentation id");
557
Stream_EnsureRemainingCapacity(ifman->output, 16);
558
Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
559
Stream_Write_UINT32(ifman->output, 0); /* StreamId */
560
Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */
561
Stream_Write_UINT32(ifman->output, 0); /* cbData */
562
ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
567
int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
569
TSMF_PRESENTATION* presentation;
572
ifman->output_pending = TRUE;
574
/* Added pause control so gstreamer pipeline can be paused accordingly */
576
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
579
tsmf_presentation_paused(presentation);
581
DEBUG_WARN("unknown presentation id");
586
int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman)
588
TSMF_PRESENTATION* presentation;
591
ifman->output_pending = TRUE;
593
/* Added restart control so gstreamer pipeline can be resumed accordingly */
595
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
598
tsmf_presentation_restarted(presentation);
600
DEBUG_WARN("unknown presentation id");
605
int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman)
607
TSMF_PRESENTATION* presentation;
611
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
614
tsmf_presentation_stop(presentation);
616
DEBUG_WARN("unknown presentation id");
618
Stream_EnsureRemainingCapacity(ifman->output, 16);
619
Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
620
Stream_Write_UINT32(ifman->output, 0); /* StreamId */
621
Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */
622
Stream_Write_UINT32(ifman->output, 0); /* cbData */
623
ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
628
int tsmf_ifman_on_playback_rate_changed(TSMF_IFMAN * ifman)
632
Stream_EnsureRemainingCapacity(ifman->output, 16);
633
Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
634
Stream_Write_UINT32(ifman->output, 0); /* StreamId */
635
Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_MONITORCHANGED); /* EventId */
636
Stream_Write_UINT32(ifman->output, 0); /* cbData */
637
ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;