Merge pull request #3707 from akallabeth/AMV007-patch-2

Rebased #2541
This commit is contained in:
Bernhard Miklautz 2017-01-18 13:45:34 +01:00 committed by GitHub
commit 497db0d53e
3 changed files with 102 additions and 82 deletions

View File

@ -50,15 +50,15 @@ UINT tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman)
if (Stream_GetRemainingLength(ifman->input) < 4) if (Stream_GetRemainingLength(ifman->input) < 4)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
Stream_Read_UINT32(ifman->input, CapabilityValue);
Stream_Read_UINT32(ifman->input, CapabilityValue);
DEBUG_TSMF("server CapabilityValue %"PRIu32"", CapabilityValue); DEBUG_TSMF("server CapabilityValue %"PRIu32"", CapabilityValue);
if (!Stream_EnsureRemainingCapacity(ifman->output, 8)) if (!Stream_EnsureRemainingCapacity(ifman->output, 8))
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
Stream_Write_UINT32(ifman->output, 1); /* CapabilityValue */ Stream_Write_UINT32(ifman->output, 1); /* CapabilityValue */
Stream_Write_UINT32(ifman->output, 0); /* Result */ Stream_Write_UINT32(ifman->output, 0); /* Result */
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -78,12 +78,14 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
if (!Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4)) if (!Stream_EnsureRemainingCapacity(ifman->output, ifman->input_size + 4))
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
pos = Stream_GetPosition(ifman->output); pos = Stream_GetPosition(ifman->output);
Stream_Copy(ifman->input, ifman->output, ifman->input_size); Stream_Copy(ifman->input, ifman->output, ifman->input_size);
Stream_SetPosition(ifman->output, pos); Stream_SetPosition(ifman->output, pos);
if (Stream_GetRemainingLength(ifman->output) < 4) if (Stream_GetRemainingLength(ifman->output) < 4)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
Stream_Read_UINT32(ifman->output, numHostCapabilities); Stream_Read_UINT32(ifman->output, numHostCapabilities);
for (i = 0; i < numHostCapabilities; i++) for (i = 0; i < numHostCapabilities; i++)
@ -108,6 +110,7 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
Stream_Read_UINT32(ifman->output, v); Stream_Read_UINT32(ifman->output, v);
DEBUG_TSMF("server protocol version %"PRIu32"", v); DEBUG_TSMF("server protocol version %"PRIu32"", v);
break; break;
case 2: /* Supported platform */ case 2: /* Supported platform */
if (Stream_GetRemainingLength(ifman->output) < 4) if (Stream_GetRemainingLength(ifman->output) < 4)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
@ -115,18 +118,20 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman)
Stream_Peek_UINT32(ifman->output, v); Stream_Peek_UINT32(ifman->output, v);
DEBUG_TSMF("server supported platform %"PRIu32"", v); DEBUG_TSMF("server supported platform %"PRIu32"", v);
/* Claim that we support both MF and DShow platforms. */ /* Claim that we support both MF and DShow platforms. */
Stream_Write_UINT32(ifman->output, MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW); Stream_Write_UINT32(ifman->output,
MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW);
break; break;
default: default:
WLog_ERR(TAG, "skipping unknown capability type %"PRIu32"", CapabilityType); WLog_ERR(TAG, "skipping unknown capability type %"PRIu32"", CapabilityType);
break; break;
} }
Stream_SetPosition(ifman->output, pos + cbCapabilityLength); Stream_SetPosition(ifman->output, pos + cbCapabilityLength);
} }
Stream_Write_UINT32(ifman->output, 0); /* Result */ Stream_Write_UINT32(ifman->output, 0); /* Result */
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -147,7 +152,6 @@ UINT tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
Stream_Read_UINT32(ifman->input, PlatformCookie); Stream_Read_UINT32(ifman->input, PlatformCookie);
Stream_Seek_UINT32(ifman->input); /* NoRolloverFlags (4 bytes) */ Stream_Seek_UINT32(ifman->input); /* NoRolloverFlags (4 bytes) */
Stream_Read_UINT32(ifman->input, numMediaType); Stream_Read_UINT32(ifman->input, numMediaType);
DEBUG_TSMF("PlatformCookie %"PRIu32" numMediaType %"PRIu32"", PlatformCookie, numMediaType); DEBUG_TSMF("PlatformCookie %"PRIu32" numMediaType %"PRIu32"", PlatformCookie, numMediaType);
if (!tsmf_codec_check_media_type(ifman->decoder_name, ifman->input)) if (!tsmf_codec_check_media_type(ifman->decoder_name, ifman->input))
@ -158,11 +162,11 @@ UINT tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman)
if (!Stream_EnsureRemainingCapacity(ifman->output, 12)) if (!Stream_EnsureRemainingCapacity(ifman->output, 12))
return -1; return -1;
Stream_Write_UINT32(ifman->output, FormatSupported); Stream_Write_UINT32(ifman->output, FormatSupported);
Stream_Write_UINT32(ifman->output, PlatformCookie); Stream_Write_UINT32(ifman->output, PlatformCookie);
Stream_Write_UINT32(ifman->output, 0); /* Result */ Stream_Write_UINT32(ifman->output, 0); /* Result */
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -175,7 +179,6 @@ UINT tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
{ {
UINT status = CHANNEL_RC_OK; UINT status = CHANNEL_RC_OK;
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE) if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE)
@ -198,7 +201,6 @@ UINT tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman)
tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device); tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device);
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
return status; return status;
} }
@ -213,7 +215,6 @@ UINT tsmf_ifman_add_stream(TSMF_IFMAN* ifman, rdpContext* rdpcontext)
UINT status = CHANNEL_RC_OK; UINT status = CHANNEL_RC_OK;
TSMF_STREAM* stream; TSMF_STREAM* stream;
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8)
@ -232,6 +233,7 @@ UINT tsmf_ifman_add_stream(TSMF_IFMAN* ifman, rdpContext* rdpcontext)
Stream_Read_UINT32(ifman->input, StreamId); Stream_Read_UINT32(ifman->input, StreamId);
Stream_Seek_UINT32(ifman->input); /* numMediaType */ Stream_Seek_UINT32(ifman->input); /* numMediaType */
stream = tsmf_stream_new(presentation, StreamId, rdpcontext); stream = tsmf_stream_new(presentation, StreamId, rdpcontext);
if (!stream) if (!stream)
{ {
WLog_ERR(TAG, "failed to create stream"); WLog_ERR(TAG, "failed to create stream");
@ -243,6 +245,8 @@ UINT tsmf_ifman_add_stream(TSMF_IFMAN* ifman, rdpContext* rdpcontext)
WLog_ERR(TAG, "failed to set stream format"); WLog_ERR(TAG, "failed to set stream format");
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
tsmf_stream_start_threads(stream);
} }
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
@ -257,6 +261,7 @@ UINT tsmf_ifman_add_stream(TSMF_IFMAN* ifman, rdpContext* rdpcontext)
UINT tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman) UINT tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman)
{ {
DEBUG_TSMF(""); DEBUG_TSMF("");
if (!Stream_EnsureRemainingCapacity(ifman->output, 8)) if (!Stream_EnsureRemainingCapacity(ifman->output, 8))
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
@ -277,14 +282,12 @@ UINT tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
UINT32 StreamId; UINT32 StreamId;
TSMF_STREAM* stream; TSMF_STREAM* stream;
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
if (Stream_GetRemainingLength(ifman->input) < 20) if (Stream_GetRemainingLength(ifman->input) < 20)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
Stream_Seek(ifman->input, GUID_SIZE); Stream_Seek(ifman->input, GUID_SIZE);
if (!presentation) if (!presentation)
@ -303,11 +306,10 @@ UINT tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
} }
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
return status; return status;
} }
float tsmf_stream_read_float(wStream *s) float tsmf_stream_read_float(wStream* s)
{ {
float fValue; float fValue;
UINT32 iValue; UINT32 iValue;
@ -327,14 +329,12 @@ UINT tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman)
float Left, Top; float Left, Top;
float Right, Bottom; float Right, Bottom;
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
if (Stream_GetRemainingLength(ifman->input) < 32) if (Stream_GetRemainingLength(ifman->input) < 32)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
Stream_Seek(ifman->input, GUID_SIZE); Stream_Seek(ifman->input, GUID_SIZE);
if (!presentation) if (!presentation)
@ -348,11 +348,10 @@ UINT tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman)
Right = tsmf_stream_read_float(ifman->input); /* Right (4 bytes) */ Right = tsmf_stream_read_float(ifman->input); /* Right (4 bytes) */
Bottom = tsmf_stream_read_float(ifman->input); /* Bottom (4 bytes) */ Bottom = tsmf_stream_read_float(ifman->input); /* Bottom (4 bytes) */
DEBUG_TSMF("SetSourceVideoRect: Left: %f Top: %f Right: %f Bottom: %f", DEBUG_TSMF("SetSourceVideoRect: Left: %f Top: %f Right: %f Bottom: %f",
Left, Top, Right, Bottom); Left, Top, Right, Bottom);
} }
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
return status; return status;
} }
@ -364,13 +363,13 @@ UINT tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman)
UINT tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman) UINT tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE) if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
if (presentation) if (presentation)
tsmf_presentation_free(presentation); tsmf_presentation_free(presentation);
else else
@ -384,7 +383,6 @@ UINT tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman)
Stream_Write_UINT32(ifman->output, 0); /* Result */ Stream_Write_UINT32(ifman->output, 0); /* Result */
ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -398,7 +396,6 @@ UINT tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
UINT32 newVolume; UINT32 newVolume;
UINT32 muted; UINT32 muted;
DEBUG_TSMF("on stream volume"); DEBUG_TSMF("on stream volume");
if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8)
@ -422,7 +419,6 @@ UINT tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
return ERROR_INVALID_OPERATION; return ERROR_INVALID_OPERATION;
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
return 0; return 0;
} }
@ -434,13 +430,13 @@ UINT tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman)
UINT tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman) UINT tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF("on channel volume"); DEBUG_TSMF("on channel volume");
if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
if (presentation) if (presentation)
{ {
UINT32 channelVolume; UINT32 channelVolume;
@ -453,7 +449,6 @@ UINT tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman)
} }
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -483,7 +478,7 @@ UINT tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
UINT32 Width; UINT32 Width;
UINT32 Height; UINT32 Height;
UINT32 cbVisibleRect; UINT32 cbVisibleRect;
RDP_RECT *rects = NULL; RDP_RECT* rects = NULL;
int num_rects = 0; int num_rects = 0;
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
int i; int i;
@ -493,6 +488,7 @@ UINT tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
if (!presentation) if (!presentation)
return ERROR_NOT_FOUND; return ERROR_NOT_FOUND;
@ -504,12 +500,11 @@ UINT tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
Stream_Read_UINT32(ifman->input, Height); Stream_Read_UINT32(ifman->input, Height);
Stream_Read_UINT32(ifman->input, Left); Stream_Read_UINT32(ifman->input, Left);
Stream_Read_UINT32(ifman->input, Top); Stream_Read_UINT32(ifman->input, Top);
Stream_SetPosition(ifman->input, pos + numGeometryInfo); Stream_SetPosition(ifman->input, pos + numGeometryInfo);
Stream_Read_UINT32(ifman->input, cbVisibleRect); Stream_Read_UINT32(ifman->input, cbVisibleRect);
num_rects = cbVisibleRect / 16; num_rects = cbVisibleRect / 16;
DEBUG_TSMF("numGeometryInfo %"PRIu32" Width %"PRIu32" Height %"PRIu32" Left %"PRIu32" Top %"PRIu32" cbVisibleRect %"PRIu32" num_rects %d", DEBUG_TSMF("numGeometryInfo %"PRIu32" Width %"PRIu32" Height %"PRIu32" Left %"PRIu32" Top %"PRIu32" cbVisibleRect %"PRIu32" num_rects %d",
numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects); numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects);
if (num_rects > 0) if (num_rects > 0)
{ {
@ -528,7 +523,7 @@ UINT tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
rects[i].width -= rects[i].x; rects[i].width -= rects[i].x;
rects[i].height -= rects[i].y; rects[i].height -= rects[i].y;
DEBUG_TSMF("rect %d: %"PRId16" %"PRId16" %"PRId16" %"PRId16"", i, DEBUG_TSMF("rect %d: %"PRId16" %"PRId16" %"PRId16" %"PRId16"", i,
rects[i].x, rects[i].y, rects[i].width, rects[i].height); rects[i].x, rects[i].y, rects[i].width, rects[i].height);
} }
} }
@ -536,7 +531,6 @@ UINT tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman)
return ERROR_INVALID_OPERATION; return ERROR_INVALID_OPERATION;
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
return error; return error;
} }
@ -584,6 +578,7 @@ UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
if (Stream_GetRemainingLength(ifman->input) < 60) if (Stream_GetRemainingLength(ifman->input) < 60)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
Stream_Seek(ifman->input, 16); Stream_Seek(ifman->input, 16);
Stream_Read_UINT32(ifman->input, StreamId); Stream_Read_UINT32(ifman->input, StreamId);
Stream_Seek_UINT32(ifman->input); /* numSample */ Stream_Seek_UINT32(ifman->input); /* numSample */
@ -598,10 +593,9 @@ UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
DEBUG_TSMF("MessageId %"PRIu32" StreamId %"PRIu32" SampleStartTime %"PRIu64" SampleEndTime %"PRIu64" " DEBUG_TSMF("MessageId %"PRIu32" StreamId %"PRIu32" SampleStartTime %"PRIu64" SampleEndTime %"PRIu64" "
"ThrottleDuration %"PRIu64" SampleExtensions %"PRIu32" cbData %"PRIu32"", "ThrottleDuration %"PRIu64" SampleExtensions %"PRIu32" cbData %"PRIu32"",
ifman->message_id, StreamId, SampleStartTime, SampleEndTime, ifman->message_id, StreamId, SampleStartTime, SampleEndTime,
ThrottleDuration, SampleExtensions, cbData); ThrottleDuration, SampleExtensions, cbData);
presentation = tsmf_presentation_find_by_id(ifman->presentation_id); presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
if (!presentation) if (!presentation)
@ -619,20 +613,20 @@ UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
} }
if (!tsmf_stream_push_sample(stream, ifman->channel_callback, if (!tsmf_stream_push_sample(stream, ifman->channel_callback,
ifman->message_id, SampleStartTime, SampleEndTime, ifman->message_id, SampleStartTime, SampleEndTime,
ThrottleDuration, SampleExtensions, cbData, Stream_Pointer(ifman->input))) ThrottleDuration, SampleExtensions, cbData, Stream_Pointer(ifman->input)))
{ {
WLog_ERR(TAG, "unable to push sample"); WLog_ERR(TAG, "unable to push sample");
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
if ((error = tsmf_presentation_sync(presentation))) if ((error = tsmf_presentation_sync(presentation)))
{ {
WLog_ERR(TAG, "tsmf_presentation_sync failed with error %"PRIu32"", error); WLog_ERR(TAG, "tsmf_presentation_sync failed with error %"PRIu32"", error);
return error; return error;
} }
ifman->output_pending = TRUE;
ifman->output_pending = TRUE;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -652,10 +646,9 @@ UINT tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
Stream_Seek(ifman->input, 16); Stream_Seek(ifman->input, 16);
Stream_Read_UINT32(ifman->input, StreamId); Stream_Read_UINT32(ifman->input, StreamId);
DEBUG_TSMF("StreamId %"PRIu32"", StreamId); DEBUG_TSMF("StreamId %"PRIu32"", StreamId);
presentation = tsmf_presentation_find_by_id(ifman->presentation_id); presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
if (!presentation) if (!presentation)
{ {
WLog_ERR(TAG, "unknown presentation id"); WLog_ERR(TAG, "unknown presentation id");
@ -666,6 +659,7 @@ UINT tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
* therefore we only flush the stream as intended per the MS-RDPEV spec * therefore we only flush the stream as intended per the MS-RDPEV spec
*/ */
stream = tsmf_stream_find_by_id(presentation, StreamId); stream = tsmf_stream_find_by_id(presentation, StreamId);
if (stream) if (stream)
{ {
if (!tsmf_stream_flush(stream)) if (!tsmf_stream_flush(stream))
@ -675,7 +669,6 @@ UINT tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
WLog_ERR(TAG, "unknown stream id"); WLog_ERR(TAG, "unknown stream id");
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -694,7 +687,6 @@ UINT tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
Stream_Seek(ifman->input, 16); Stream_Seek(ifman->input, 16);
Stream_Read_UINT32(ifman->input, StreamId); Stream_Read_UINT32(ifman->input, StreamId);
@ -703,13 +695,11 @@ UINT tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
stream = tsmf_stream_find_by_id(presentation, StreamId); stream = tsmf_stream_find_by_id(presentation, StreamId);
if (stream) if (stream)
tsmf_stream_end(stream, ifman->message_id, ifman->channel_callback); tsmf_stream_end(stream, ifman->message_id, ifman->channel_callback);
} }
DEBUG_TSMF("StreamId %"PRIu32"", StreamId); DEBUG_TSMF("StreamId %"PRIu32"", StreamId);
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -722,7 +712,6 @@ UINT tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
UINT tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman) UINT tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
if (Stream_GetRemainingLength(ifman->input) < 16) if (Stream_GetRemainingLength(ifman->input) < 16)
@ -743,7 +732,6 @@ UINT tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */ Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */
Stream_Write_UINT32(ifman->output, 0); /* cbData */ Stream_Write_UINT32(ifman->output, 0); /* cbData */
ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
@ -755,10 +743,8 @@ UINT tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman)
UINT tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman) UINT tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
/* Added pause control so gstreamer pipeline can be paused accordingly */ /* Added pause control so gstreamer pipeline can be paused accordingly */
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
@ -781,12 +767,11 @@ UINT tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman)
UINT tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman) UINT tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
ifman->output_pending = TRUE; ifman->output_pending = TRUE;
/* Added restart control so gstreamer pipeline can be resumed accordingly */ /* Added restart control so gstreamer pipeline can be resumed accordingly */
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
if (presentation) if (presentation)
{ {
if (!tsmf_presentation_restarted(presentation)) if (!tsmf_presentation_restarted(presentation))
@ -806,10 +791,9 @@ UINT tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman)
UINT tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman) UINT tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman)
{ {
TSMF_PRESENTATION* presentation; TSMF_PRESENTATION* presentation;
DEBUG_TSMF(""); DEBUG_TSMF("");
presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
if (presentation) if (presentation)
{ {
if (!tsmf_presentation_stop(presentation)) if (!tsmf_presentation_stop(presentation))
@ -825,7 +809,6 @@ UINT tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman)
Stream_Write_UINT32(ifman->output, 0); /* StreamId */ Stream_Write_UINT32(ifman->output, 0); /* StreamId */
Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */ Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */
Stream_Write_UINT32(ifman->output, 0); /* cbData */ Stream_Write_UINT32(ifman->output, 0); /* cbData */
ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }

View File

@ -455,6 +455,26 @@ static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample)
event.framePixFmt = sample->pixfmt; event.framePixFmt = sample->pixfmt;
event.frameWidth = sample->stream->width; event.frameWidth = sample->stream->width;
event.frameHeight = sample->stream->height; event.frameHeight = sample->stream->height;
event.x = presentation->x;
event.y = presentation->y;
event.width = presentation->width;
event.height = presentation->height;
if (presentation->nr_rects > 0)
{
event.numVisibleRects = presentation->nr_rects;
event.visibleRects = (RECTANGLE_16*) calloc(1, event.numVisibleRects * sizeof(RECTANGLE_16));
if (!event.visibleRects)
{
WLog_ERR(TAG, "can't allocate memory for copy rectangles");
return FALSE;
}
memcpy(event.visibleRects, presentation->rects, presentation->nr_rects * sizeof(RDP_RECT));
presentation->nr_rects = 0;
}
#if 0 #if 0
/* Dump a .ppm image for every 30 frames. Assuming the frame is in YUV format, we /* Dump a .ppm image for every 30 frames. Assuming the frame is in YUV format, we
extract the Y values to create a grayscale image. */ extract the Y values to create a grayscale image. */
@ -486,6 +506,9 @@ static BOOL tsmf_sample_playback_video(TSMF_SAMPLE* sample)
tsmf->FrameEvent(tsmf, &event); tsmf->FrameEvent(tsmf, &event);
free(event.frameData); free(event.frameData);
if (event.visibleRects != NULL)
free(event.visibleRects);
} }
return TRUE; return TRUE;
@ -718,7 +741,6 @@ static void* tsmf_stream_ack_func(void* arg)
TSMF_STREAM* stream = (TSMF_STREAM*) arg; TSMF_STREAM* stream = (TSMF_STREAM*) arg;
UINT error = CHANNEL_RC_OK; UINT error = CHANNEL_RC_OK;
DEBUG_TSMF("in %"PRIu32"", stream->stream_id); DEBUG_TSMF("in %"PRIu32"", stream->stream_id);
hdl[0] = stream->stopEvent; hdl[0] = stream->stopEvent;
hdl[1] = Queue_Event(stream->sample_ack_list); hdl[1] = Queue_Event(stream->sample_ack_list);
@ -1109,6 +1131,10 @@ BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation,
presentation->width = width; presentation->width = width;
presentation->height = height; presentation->height = height;
tmp_rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects); tmp_rects = realloc(presentation->rects, sizeof(RDP_RECT) * num_rects);
if (!tmp_rects && num_rects)
return FALSE;
presentation->nr_rects = num_rects; presentation->nr_rects = num_rects;
presentation->rects = tmp_rects; presentation->rects = tmp_rects;
CopyMemory(presentation->rects, rects, sizeof(RDP_RECT) * num_rects); CopyMemory(presentation->rects, rects, sizeof(RDP_RECT) * num_rects);
@ -1231,14 +1257,14 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id,
goto error_sample_ack_list; goto error_sample_ack_list;
stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free; stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free;
stream->play_thread = CreateThread(NULL, 0, stream->play_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func,
(LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, 0, NULL); stream, CREATE_SUSPENDED, NULL);
if (!stream->play_thread) if (!stream->play_thread)
goto error_play_thread; goto error_play_thread;
stream->ack_thread = CreateThread(NULL, 0, stream->ack_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tsmf_stream_ack_func, stream,
(LPTHREAD_START_ROUTINE)tsmf_stream_ack_func, stream, 0, NULL); CREATE_SUSPENDED, NULL);
if (!stream->ack_thread) if (!stream->ack_thread)
goto error_ack_thread; goto error_ack_thread;
@ -1273,6 +1299,12 @@ error_stopEvent:
return NULL; return NULL;
} }
void tsmf_stream_start_threads(TSMF_STREAM* stream)
{
ResumeThread(stream->play_thread);
ResumeThread(stream->ack_thread);
}
TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation,
UINT32 stream_id) UINT32 stream_id)
{ {

View File

@ -36,33 +36,38 @@ typedef struct _TSMF_STREAM TSMF_STREAM;
typedef struct _TSMF_SAMPLE TSMF_SAMPLE; typedef struct _TSMF_SAMPLE TSMF_SAMPLE;
TSMF_PRESENTATION *tsmf_presentation_new(const BYTE *guid, IWTSVirtualChannelCallback *pChannelCallback); TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid,
TSMF_PRESENTATION *tsmf_presentation_find_by_id(const BYTE *guid); IWTSVirtualChannelCallback* pChannelCallback);
BOOL tsmf_presentation_start(TSMF_PRESENTATION *presentation); TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE* guid);
BOOL tsmf_presentation_stop(TSMF_PRESENTATION *presentation); BOOL tsmf_presentation_start(TSMF_PRESENTATION* presentation);
UINT tsmf_presentation_sync(TSMF_PRESENTATION *presentation); BOOL tsmf_presentation_stop(TSMF_PRESENTATION* presentation);
BOOL tsmf_presentation_paused(TSMF_PRESENTATION *presentation); UINT tsmf_presentation_sync(TSMF_PRESENTATION* presentation);
BOOL tsmf_presentation_restarted(TSMF_PRESENTATION *presentation); BOOL tsmf_presentation_paused(TSMF_PRESENTATION* presentation);
BOOL tsmf_presentation_volume_changed(TSMF_PRESENTATION *presentation, UINT32 newVolume, UINT32 muted); BOOL tsmf_presentation_restarted(TSMF_PRESENTATION* presentation);
BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION *presentation, BOOL tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 newVolume,
UINT32 x, UINT32 y, UINT32 width, UINT32 height, UINT32 muted);
int num_rects, RDP_RECT *rects); BOOL tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation,
void tsmf_presentation_set_audio_device(TSMF_PRESENTATION *presentation, UINT32 x, UINT32 y, UINT32 width, UINT32 height,
const char *name, const char *device); int num_rects, RDP_RECT* rects);
void tsmf_presentation_free(TSMF_PRESENTATION *presentation); void tsmf_presentation_set_audio_device(TSMF_PRESENTATION* presentation,
const char* name, const char* device);
void tsmf_presentation_free(TSMF_PRESENTATION* presentation);
TSMF_STREAM *tsmf_stream_new(TSMF_PRESENTATION *presentation, UINT32 stream_id, rdpContext* rdpcontext); TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id,
TSMF_STREAM *tsmf_stream_find_by_id(TSMF_PRESENTATION *presentation, UINT32 stream_id); rdpContext* rdpcontext);
BOOL tsmf_stream_set_format(TSMF_STREAM *stream, const char *name, wStream *s); TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, UINT32 stream_id);
void tsmf_stream_end(TSMF_STREAM *stream, UINT32 message_id, IWTSVirtualChannelCallback* pChannelCallback); BOOL tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s);
void tsmf_stream_free(TSMF_STREAM *stream); void tsmf_stream_end(TSMF_STREAM* stream, UINT32 message_id,
IWTSVirtualChannelCallback* pChannelCallback);
void tsmf_stream_free(TSMF_STREAM* stream);
BOOL tsmf_stream_flush(TSMF_STREAM* stream); BOOL tsmf_stream_flush(TSMF_STREAM* stream);
BOOL tsmf_stream_push_sample(TSMF_STREAM *stream, IWTSVirtualChannelCallback *pChannelCallback, BOOL tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pChannelCallback,
UINT32 sample_id, UINT64 start_time, UINT64 end_time, UINT64 duration, UINT32 extensions, UINT32 sample_id, UINT64 start_time, UINT64 end_time, UINT64 duration, UINT32 extensions,
UINT32 data_size, BYTE *data); UINT32 data_size, BYTE* data);
BOOL tsmf_media_init(void); BOOL tsmf_media_init(void);
void tsmf_stream_start_threads(TSMF_STREAM* stream);
#endif #endif