2 * FreeRDP: A Remote Desktop Protocol client.
3 * Video Redirection Virtual Channel - Interface Manipulation
5 * Copyright 2010-2011 Vic Lee
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
23 #include <freerdp/utils/memory.h>
24 #include <freerdp/utils/stream.h>
26 #include "drdynvc_types.h"
27 #include "tsmf_constants.h"
28 #include "tsmf_media.h"
29 #include "tsmf_codec.h"
31 #include "tsmf_ifman.h"
33 int tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman)
35 uint32 CapabilityValue;
37 stream_read_uint32(ifman->input, CapabilityValue);
38 DEBUG_DVC("server CapabilityValue %d", CapabilityValue);
40 stream_check_size(ifman->output, 8);
41 stream_write_uint32(ifman->output, 1); /* CapabilityValue */
42 stream_write_uint32(ifman->output, 0); /* Result */
47 int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
52 uint32 CapabilityType;
53 uint32 cbCapabilityLength;
54 uint32 numHostCapabilities;
56 pos = stream_get_pos(ifman->output);
57 stream_check_size(ifman->output, ifman->input_size + 4);
58 stream_copy(ifman->output, ifman->input, ifman->input_size);
60 stream_set_pos(ifman->output, pos);
61 stream_read_uint32(ifman->output, numHostCapabilities);
62 for (i = 0; i < numHostCapabilities; i++)
64 stream_read_uint32(ifman->output, CapabilityType);
65 stream_read_uint32(ifman->output, cbCapabilityLength);
66 pos = stream_get_pos(ifman->output);
67 switch (CapabilityType)
69 case 1: /* Protocol version request */
70 stream_read_uint32(ifman->output, v);
71 DEBUG_DVC("server protocol version %d", v);
73 case 2: /* Supported platform */
74 stream_peek_uint32(ifman->output, v);
75 DEBUG_DVC("server supported platform %d", v);
76 /* Claim that we support both MF and DShow platforms. */
77 stream_write_uint32(ifman->output,
78 MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW);
81 DEBUG_WARN("unknown capability type %d", CapabilityType);
84 stream_set_pos(ifman->output, pos + cbCapabilityLength);
86 stream_write_uint32(ifman->output, 0); /* Result */
88 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
93 int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
96 uint32 PlatformCookie;
97 uint32 FormatSupported = 1;
99 stream_read_uint32(ifman->input, PlatformCookie);
100 stream_seek_uint32(ifman->input); /* NoRolloverFlags (4 bytes) */
101 stream_read_uint32(ifman->input, numMediaType);
103 DEBUG_DVC("PlatformCookie %d numMediaType %d", PlatformCookie, numMediaType);
105 if (!tsmf_codec_check_media_type(ifman->input))
109 DEBUG_DVC("format ok.");
111 stream_check_size(ifman->output, 12);
112 stream_write_uint32(ifman->output, FormatSupported);
113 stream_write_uint32(ifman->output, PlatformCookie);
114 stream_write_uint32(ifman->output, 0); /* Result */
116 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
121 int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
124 TSMF_PRESENTATION* presentation;
128 presentation = tsmf_presentation_new(stream_get_tail(ifman->input), ifman->channel_callback);
129 if (presentation == NULL)
131 tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device);
132 ifman->output_pending = true;
136 int tsmf_ifman_add_stream(TSMF_IFMAN* ifman)
141 TSMF_PRESENTATION* presentation;
145 presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
146 stream_seek(ifman->input, 16);
148 if (presentation == NULL)
152 stream_read_uint32(ifman->input, StreamId);
153 stream_seek_uint32(ifman->input); /* numMediaType */
154 stream = tsmf_stream_new(presentation, StreamId);
156 tsmf_stream_set_format(stream, ifman->decoder_name, ifman->input);
158 ifman->output_pending = true;
162 int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman)
166 stream_check_size(ifman->output, 8);
167 stream_write_uint32(ifman->output, 1); /* TopologyReady */
168 stream_write_uint32(ifman->output, 0); /* Result */
169 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
173 int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
178 TSMF_PRESENTATION* presentation;
182 presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
183 stream_seek(ifman->input, 16);
185 if (presentation == NULL)
189 stream_read_uint32(ifman->input, StreamId);
190 stream = tsmf_stream_find_by_id(presentation, StreamId);
192 tsmf_stream_free(stream);
196 ifman->output_pending = true;
200 int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
202 TSMF_PRESENTATION* presentation;
206 presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
208 tsmf_presentation_free(presentation);
210 stream_check_size(ifman->output, 4);
211 stream_write_uint32(ifman->output, 0); /* Result */
212 ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
216 int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
219 ifman->output_pending = true;
223 int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman)
226 ifman->output_pending = true;
230 int tsmf_ifman_set_video_window(TSMF_IFMAN* ifman)
233 ifman->output_pending = true;
237 int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
239 TSMF_PRESENTATION* presentation;
240 uint32 numGeometryInfo;
245 uint32 cbVisibleRect;
246 RDP_RECT* rects = NULL;
252 presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
253 stream_seek(ifman->input, 16);
255 stream_read_uint32(ifman->input, numGeometryInfo);
256 pos = stream_get_pos(ifman->input);
258 stream_seek(ifman->input, 12); /* VideoWindowId (8 bytes), VideoWindowState (4 bytes) */
259 stream_read_uint32(ifman->input, Width);
260 stream_read_uint32(ifman->input, Height);
261 stream_read_uint32(ifman->input, Left);
262 stream_read_uint32(ifman->input, Top);
264 stream_set_pos(ifman->input, pos + numGeometryInfo);
265 stream_read_uint32(ifman->input, cbVisibleRect);
266 num_rects = cbVisibleRect / 16;
268 DEBUG_DVC("numGeometryInfo %d Width %d Height %d Left %d Top %d cbVisibleRect %d num_rects %d",
269 numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects);
271 if (presentation == NULL)
277 rects = (RDP_RECT*) xzalloc(sizeof(RDP_RECT) * num_rects);
278 for (i = 0; i < num_rects; i++)
280 stream_read_uint16(ifman->input, rects[i].y); /* Top */
281 stream_seek_uint16(ifman->input);
282 stream_read_uint16(ifman->input, rects[i].x); /* Left */
283 stream_seek_uint16(ifman->input);
284 stream_read_uint16(ifman->input, rects[i].height); /* Bottom */
285 stream_seek_uint16(ifman->input);
286 stream_read_uint16(ifman->input, rects[i].width); /* Right */
287 stream_seek_uint16(ifman->input);
288 rects[i].width -= rects[i].x;
289 rects[i].height -= rects[i].y;
291 DEBUG_DVC("rect %d: %d %d %d %d", i,
292 rects[i].x, rects[i].y, rects[i].width, rects[i].height);
295 tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height, num_rects, rects);
297 ifman->output_pending = true;
301 int tsmf_ifman_set_allocator(TSMF_IFMAN* ifman)
304 ifman->output_pending = true;
308 int tsmf_ifman_notify_preroll(TSMF_IFMAN* ifman)
311 ifman->output_pending = true;
315 int tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
317 TSMF_PRESENTATION* presentation;
320 uint64 SampleStartTime;
321 uint64 SampleEndTime;
322 uint64 ThrottleDuration;
323 uint32 SampleExtensions;
326 stream_seek(ifman->input, 16);
327 stream_read_uint32(ifman->input, StreamId);
328 stream_seek_uint32(ifman->input); /* numSample */
329 stream_read_uint64(ifman->input, SampleStartTime);
330 stream_read_uint64(ifman->input, SampleEndTime);
331 stream_read_uint64(ifman->input, ThrottleDuration);
332 stream_seek_uint32(ifman->input); /* SampleFlags */
333 stream_read_uint32(ifman->input, SampleExtensions);
334 stream_read_uint32(ifman->input, cbData);
336 DEBUG_DVC("MessageId %d StreamId %d SampleStartTime %d SampleEndTime %d "
337 "ThrottleDuration %d SampleExtensions %d cbData %d",
338 ifman->message_id, StreamId, (int)SampleStartTime, (int)SampleEndTime,
339 (int)ThrottleDuration, SampleExtensions, cbData);
341 presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
342 if (presentation == NULL)
344 DEBUG_WARN("unknown presentation id");
347 stream = tsmf_stream_find_by_id(presentation, StreamId);
350 DEBUG_WARN("unknown stream id");
353 tsmf_stream_push_sample(stream, ifman->channel_callback,
354 ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions,
355 cbData, stream_get_tail(ifman->input));
357 ifman->output_pending = true;
361 int tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
363 TSMF_PRESENTATION* presentation;
366 stream_seek(ifman->input, 16);
367 stream_read_uint32(ifman->input, StreamId);
368 DEBUG_DVC("StreamId %d", StreamId);
370 presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
371 if (presentation == NULL)
373 DEBUG_WARN("unknown presentation id");
377 tsmf_presentation_flush(presentation);
379 ifman->output_pending = true;
383 int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
385 TSMF_PRESENTATION* presentation;
389 presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
390 stream_seek(ifman->input, 16);
391 stream_read_uint32(ifman->input, StreamId);
392 stream = tsmf_stream_find_by_id(presentation, StreamId);
393 tsmf_stream_end(stream);
395 DEBUG_DVC("StreamId %d", StreamId);
397 stream_check_size(ifman->output, 16);
398 stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
399 stream_write_uint32(ifman->output, StreamId); /* StreamId */
400 stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */
401 stream_write_uint32(ifman->output, 0); /* cbData */
402 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
407 int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
409 TSMF_PRESENTATION* presentation;
413 presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
415 tsmf_presentation_start(presentation);
417 DEBUG_WARN("unknown presentation id");
419 stream_check_size(ifman->output, 16);
420 stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
421 stream_write_uint32(ifman->output, 0); /* StreamId */
422 stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */
423 stream_write_uint32(ifman->output, 0); /* cbData */
424 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
429 int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
432 ifman->output_pending = true;
436 int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman)
439 ifman->output_pending = true;
443 int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman)
445 TSMF_PRESENTATION* presentation;
449 presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
451 tsmf_presentation_stop(presentation);
453 DEBUG_WARN("unknown presentation id");
455 stream_check_size(ifman->output, 16);
456 stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
457 stream_write_uint32(ifman->output, 0); /* StreamId */
458 stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */
459 stream_write_uint32(ifman->output, 0); /* cbData */
460 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
465 int tsmf_ifman_on_playback_rate_changed(TSMF_IFMAN * ifman)
469 stream_check_size(ifman->output, 16);
470 stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
471 stream_write_uint32(ifman->output, 0); /* StreamId */
472 stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_MONITORCHANGED); /* EventId */
473 stream_write_uint32(ifman->output, 0); /* cbData */
474 ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;