Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / channels / drdynvc / tsmf / tsmf_ifman.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol client.
3  * Video Redirection Virtual Channel - Interface Manipulation
4  *
5  * Copyright 2010-2011 Vic Lee
6  *
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <freerdp/utils/memory.h>
24 #include <freerdp/utils/stream.h>
25
26 #include "drdynvc_types.h"
27 #include "tsmf_constants.h"
28 #include "tsmf_media.h"
29 #include "tsmf_codec.h"
30
31 #include "tsmf_ifman.h"
32
33 int tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman)
34 {
35         uint32 CapabilityValue;
36
37         stream_read_uint32(ifman->input, CapabilityValue);
38         DEBUG_DVC("server CapabilityValue %d", CapabilityValue);
39
40         stream_check_size(ifman->output, 8);
41         stream_write_uint32(ifman->output, 1); /* CapabilityValue */
42         stream_write_uint32(ifman->output, 0); /* Result */
43
44         return 0;
45 }
46
47 int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
48 {
49         uint32 i;
50         uint32 v;
51         uint32 pos;
52         uint32 CapabilityType;
53         uint32 cbCapabilityLength;
54         uint32 numHostCapabilities;
55
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);
59
60         stream_set_pos(ifman->output, pos);
61         stream_read_uint32(ifman->output, numHostCapabilities);
62         for (i = 0; i < numHostCapabilities; i++)
63         {
64                 stream_read_uint32(ifman->output, CapabilityType);
65                 stream_read_uint32(ifman->output, cbCapabilityLength);
66                 pos = stream_get_pos(ifman->output);
67                 switch (CapabilityType)
68                 {
69                         case 1: /* Protocol version request */
70                                 stream_read_uint32(ifman->output, v);
71                                 DEBUG_DVC("server protocol version %d", v);
72                                 break;
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);
79                                 break;
80                         default:
81                                 DEBUG_WARN("unknown capability type %d", CapabilityType);
82                                 break;
83                 }
84                 stream_set_pos(ifman->output, pos + cbCapabilityLength);
85         }
86         stream_write_uint32(ifman->output, 0); /* Result */
87
88         ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
89
90         return 0;
91 }
92
93 int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
94 {
95         uint32 numMediaType;
96         uint32 PlatformCookie;
97         uint32 FormatSupported = 1;
98
99         stream_read_uint32(ifman->input, PlatformCookie);
100         stream_seek_uint32(ifman->input); /* NoRolloverFlags (4 bytes) */
101         stream_read_uint32(ifman->input, numMediaType);
102
103         DEBUG_DVC("PlatformCookie %d numMediaType %d", PlatformCookie, numMediaType);
104
105         if (!tsmf_codec_check_media_type(ifman->input))
106                 FormatSupported = 0;
107
108         if (FormatSupported)
109                 DEBUG_DVC("format ok.");
110
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 */
115
116         ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
117
118         return 0;
119 }
120
121 int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
122 {
123         int error = 0;
124         TSMF_PRESENTATION* presentation;
125
126         DEBUG_DVC("");
127
128         presentation = tsmf_presentation_new(stream_get_tail(ifman->input), ifman->channel_callback);
129         if (presentation == NULL)
130                 error = 1;
131         tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device);
132         ifman->output_pending = true;
133         return error;
134 }
135
136 int tsmf_ifman_add_stream(TSMF_IFMAN* ifman)
137 {
138         uint32 StreamId;
139         int error = 0;
140         TSMF_STREAM* stream;
141         TSMF_PRESENTATION* presentation;
142
143         DEBUG_DVC("");
144
145         presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
146         stream_seek(ifman->input, 16);
147
148         if (presentation == NULL)
149                 error = 1;
150         else
151         {
152                 stream_read_uint32(ifman->input, StreamId);
153                 stream_seek_uint32(ifman->input); /* numMediaType */
154                 stream = tsmf_stream_new(presentation, StreamId);
155                 if (stream)
156                         tsmf_stream_set_format(stream, ifman->decoder_name, ifman->input);
157         }
158         ifman->output_pending = true;
159         return error;
160 }
161
162 int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman)
163 {
164         DEBUG_DVC("");
165
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;
170         return 0;
171 }
172
173 int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
174 {
175         int error = 0;
176         uint32 StreamId;
177         TSMF_STREAM* stream;
178         TSMF_PRESENTATION* presentation;
179
180         DEBUG_DVC("");
181
182         presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
183         stream_seek(ifman->input, 16);
184
185         if (presentation == NULL)
186                 error = 1;
187         else
188         {
189                 stream_read_uint32(ifman->input, StreamId);
190                 stream = tsmf_stream_find_by_id(presentation, StreamId);
191                 if (stream)
192                         tsmf_stream_free(stream);
193                 else
194                         error = 1;
195         }
196         ifman->output_pending = true;
197         return error;
198 }
199
200 int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
201 {
202         TSMF_PRESENTATION* presentation;
203
204         DEBUG_DVC("");
205
206         presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
207         if (presentation)
208                 tsmf_presentation_free(presentation);
209
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;
213         return 0;
214 }
215
216 int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
217 {
218         DEBUG_DVC("");
219         ifman->output_pending = true;
220         return 0;
221 }
222
223 int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman)
224 {
225         DEBUG_DVC("");
226         ifman->output_pending = true;
227         return 0;
228 }
229
230 int tsmf_ifman_set_video_window(TSMF_IFMAN* ifman)
231 {
232         DEBUG_DVC("");
233         ifman->output_pending = true;
234         return 0;
235 }
236
237 int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
238 {
239         TSMF_PRESENTATION* presentation;
240         uint32 numGeometryInfo;
241         uint32 Left;
242         uint32 Top;
243         uint32 Width;
244         uint32 Height;
245         uint32 cbVisibleRect;
246         RDP_RECT* rects = NULL;
247         int num_rects = 0;
248         int error = 0;
249         int i;
250         int pos;
251
252         presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
253         stream_seek(ifman->input, 16);
254
255         stream_read_uint32(ifman->input, numGeometryInfo);
256         pos = stream_get_pos(ifman->input);
257
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);
263
264         stream_set_pos(ifman->input, pos + numGeometryInfo);
265         stream_read_uint32(ifman->input, cbVisibleRect);
266         num_rects = cbVisibleRect / 16;
267
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);
270
271         if (presentation == NULL)
272                 error = 1;
273         else
274         {
275                 if (num_rects > 0)
276                 {
277                         rects = (RDP_RECT*) xzalloc(sizeof(RDP_RECT) * num_rects);
278                         for (i = 0; i < num_rects; i++)
279                         {
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;
290
291                                 DEBUG_DVC("rect %d: %d %d %d %d", i,
292                                         rects[i].x, rects[i].y, rects[i].width, rects[i].height);
293                         }
294                 }
295                 tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height, num_rects, rects);
296         }
297         ifman->output_pending = true;
298         return error;
299 }
300
301 int tsmf_ifman_set_allocator(TSMF_IFMAN* ifman)
302 {
303         DEBUG_DVC("");
304         ifman->output_pending = true;
305         return 0;
306 }
307
308 int tsmf_ifman_notify_preroll(TSMF_IFMAN* ifman)
309 {
310         DEBUG_DVC("");
311         ifman->output_pending = true;
312         return 0;
313 }
314
315 int tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
316 {
317         TSMF_PRESENTATION* presentation;
318         TSMF_STREAM* stream;
319         uint32 StreamId;
320         uint64 SampleStartTime;
321         uint64 SampleEndTime;
322         uint64 ThrottleDuration;
323         uint32 SampleExtensions;
324         uint32 cbData;
325
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);
335         
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);
340
341         presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
342         if (presentation == NULL)
343         {
344                 DEBUG_WARN("unknown presentation id");
345                 return 1;
346         }
347         stream = tsmf_stream_find_by_id(presentation, StreamId);
348         if (stream == NULL)
349         {
350                 DEBUG_WARN("unknown stream id");
351                 return 1;
352         }
353         tsmf_stream_push_sample(stream, ifman->channel_callback,
354                 ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions,
355                 cbData, stream_get_tail(ifman->input));
356
357         ifman->output_pending = true;
358         return 0;
359 }
360
361 int tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
362 {
363         TSMF_PRESENTATION* presentation;
364         uint32 StreamId;
365
366         stream_seek(ifman->input, 16);
367         stream_read_uint32(ifman->input, StreamId);
368         DEBUG_DVC("StreamId %d", StreamId);
369
370         presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
371         if (presentation == NULL)
372         {
373                 DEBUG_WARN("unknown presentation id");
374                 return 1;
375         }
376
377         tsmf_presentation_flush(presentation);
378
379         ifman->output_pending = true;
380         return 0;
381 }
382
383 int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
384 {
385         TSMF_PRESENTATION* presentation;
386         TSMF_STREAM* stream;
387         uint32 StreamId;
388
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);
394
395         DEBUG_DVC("StreamId %d", StreamId);
396
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;
403
404         return 0;
405 }
406
407 int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
408 {
409         TSMF_PRESENTATION* presentation;
410
411         DEBUG_DVC("");
412
413         presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
414         if (presentation)
415                 tsmf_presentation_start(presentation);
416         else
417                 DEBUG_WARN("unknown presentation id");
418
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;
425
426         return 0;
427 }
428
429 int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
430 {
431         DEBUG_DVC("");
432         ifman->output_pending = true;
433         return 0;
434 }
435
436 int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman)
437 {
438         DEBUG_DVC("");
439         ifman->output_pending = true;
440         return 0;
441 }
442
443 int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman)
444 {
445         TSMF_PRESENTATION* presentation;
446
447         DEBUG_DVC("");
448
449         presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input));
450         if (presentation)
451                 tsmf_presentation_stop(presentation);
452         else
453                 DEBUG_WARN("unknown presentation id");
454
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;
461
462         return 0;
463 }
464
465 int tsmf_ifman_on_playback_rate_changed(TSMF_IFMAN * ifman)
466 {
467         DEBUG_DVC("");
468
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;
475
476         return 0;
477 }
478