Пример #1
0
TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
{
	TSMF_STREAM* stream;

	stream = tsmf_stream_find_by_id(presentation, stream_id);

	if (stream)
	{
		DEBUG_WARN("duplicated stream id %d!", stream_id);
		return NULL;
	}

	stream = (TSMF_STREAM*) malloc(sizeof(TSMF_STREAM));
	ZeroMemory(stream, sizeof(TSMF_STREAM));

	stream->stream_id = stream_id;
	stream->presentation = presentation;

	stream->started = FALSE;

	stream->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	stream->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);

	stream->sample_list = Queue_New(TRUE, -1, -1);
	stream->sample_ack_list = Queue_New(TRUE, -1, -1);

	WaitForSingleObject(presentation->mutex, INFINITE);
	list_enqueue(presentation->stream_list, stream);
	ReleaseMutex(presentation->mutex);

	return stream;
}
Пример #2
0
TSMF_STREAM *tsmf_stream_new(TSMF_PRESENTATION *presentation, UINT32 stream_id)
{
	TSMF_STREAM *stream;
	stream = tsmf_stream_find_by_id(presentation, stream_id);

	if (stream)
	{
		CLOG_ERR("duplicated stream id %d!", stream_id);
		return NULL;
	}

	stream = (TSMF_STREAM *) calloc(1, sizeof(TSMF_STREAM));

	if (!stream)
	{
		CLOG_ERR("Calloc failed");
		return NULL;
	}

	stream->stream_id = stream_id;
	stream->presentation = presentation;
	stream->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	stream->ready = CreateEvent(NULL, TRUE, TRUE, NULL);
	stream->sample_list = Queue_New(TRUE, -1, -1);
	stream->sample_list->object.fnObjectFree = tsmf_sample_free;
	stream->sample_ack_list = Queue_New(TRUE, -1, -1);
	stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free;
	stream->play_thread = CreateThread(NULL, 0,
									   (LPTHREAD_START_ROUTINE)tsmf_stream_playback_func, stream, 0, NULL);
	stream->ack_thread = CreateThread(NULL, 0,
									  (LPTHREAD_START_ROUTINE)tsmf_stream_ack_func, stream, 0, NULL);
	ArrayList_Add(presentation->stream_list, stream);
	return stream;
}
Пример #3
0
int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
{
	UINT32 StreamId;
	TSMF_STREAM* stream;
	TSMF_PRESENTATION* presentation;

	presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
	Stream_Seek(ifman->input, 16);
	Stream_Read_UINT32(ifman->input, StreamId);

	if (presentation)
	{
		stream = tsmf_stream_find_by_id(presentation, StreamId);
		if (stream)
			tsmf_stream_end(stream);
	}
	DEBUG_DVC("StreamId %d", StreamId);

	Stream_EnsureRemainingCapacity(ifman->output, 16);
	Stream_Write_UINT32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
	Stream_Write_UINT32(ifman->output, StreamId); /* StreamId */
	Stream_Write_UINT32(ifman->output, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */
	Stream_Write_UINT32(ifman->output, 0); /* cbData */
	ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;

	return 0;
}
Пример #4
0
int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
{
	int status = 0;
	UINT32 StreamId;
	TSMF_STREAM* stream;
	TSMF_PRESENTATION* presentation;

	DEBUG_DVC("");

	presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));
	Stream_Seek(ifman->input, 16);

	if (presentation == NULL)
	{
		status = 1;
	}
	else
	{
		Stream_Read_UINT32(ifman->input, StreamId);
		stream = tsmf_stream_find_by_id(presentation, StreamId);
		if (stream)
			tsmf_stream_free(stream);
		else
			status = 1;
	}

	ifman->output_pending = TRUE;

	return status;
}
Пример #5
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman)
{
	UINT32 StreamId;
	TSMF_STREAM* stream = NULL;
	TSMF_PRESENTATION* presentation;

	if (Stream_GetRemainingLength(ifman->input) < 20)
		return ERROR_INVALID_DATA;

	presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));

	Stream_Seek(ifman->input, 16);
	Stream_Read_UINT32(ifman->input, StreamId);

	if (presentation)
	{
		stream = tsmf_stream_find_by_id(presentation, StreamId);

		if (stream)
                	tsmf_stream_end(stream, ifman->message_id, ifman->channel_callback);
	}

	DEBUG_TSMF("StreamId %d", StreamId);

	ifman->output_pending = TRUE;

	ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;
	return CHANNEL_RC_OK;
}
Пример #6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT tsmf_ifman_remove_stream(TSMF_IFMAN* ifman)
{
	int status = CHANNEL_RC_OK;
	UINT32 StreamId;
	TSMF_STREAM* stream;
	TSMF_PRESENTATION* presentation;

	DEBUG_TSMF("");

	if (Stream_GetRemainingLength(ifman->input) < 20)
		return ERROR_INVALID_DATA;

	presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input));

	Stream_Seek(ifman->input, GUID_SIZE);

	if (!presentation)
	{
		status = ERROR_NOT_FOUND;
	}
	else
	{
		Stream_Read_UINT32(ifman->input, StreamId);
		stream = tsmf_stream_find_by_id(presentation, StreamId);

		if (stream)
			tsmf_stream_free(stream);
		else
			status = ERROR_NOT_FOUND;
	}

	ifman->output_pending = TRUE;

	return status;
}
Пример #7
0
int tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
{
	TSMF_PRESENTATION* presentation;
	TSMF_STREAM* stream;
	UINT32 StreamId;
	UINT64 SampleStartTime;
	UINT64 SampleEndTime;
	UINT64 ThrottleDuration;
	UINT32 SampleExtensions;
	UINT32 cbData;

	Stream_Seek(ifman->input, 16);
	Stream_Read_UINT32(ifman->input, StreamId);
	Stream_Seek_UINT32(ifman->input); /* numSample */
	Stream_Read_UINT64(ifman->input, SampleStartTime);
	Stream_Read_UINT64(ifman->input, SampleEndTime);
	Stream_Read_UINT64(ifman->input, ThrottleDuration);
	Stream_Seek_UINT32(ifman->input); /* SampleFlags */
	Stream_Read_UINT32(ifman->input, SampleExtensions);
	Stream_Read_UINT32(ifman->input, cbData);
	
	DEBUG_DVC("MessageId %d StreamId %d SampleStartTime %d SampleEndTime %d "
		"ThrottleDuration %d SampleExtensions %d cbData %d",
		ifman->message_id, StreamId, (int)SampleStartTime, (int)SampleEndTime,
		(int)ThrottleDuration, SampleExtensions, cbData);

	presentation = tsmf_presentation_find_by_id(ifman->presentation_id);

	if (presentation == NULL)
	{
		DEBUG_WARN("unknown presentation id");
		return 1;
	}

	stream = tsmf_stream_find_by_id(presentation, StreamId);

	if (stream == NULL)
	{
		DEBUG_WARN("unknown stream id");
		return 1;
	}

	tsmf_stream_push_sample(stream, ifman->channel_callback,
		ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions,
		cbData, Stream_Pointer(ifman->input));

	ifman->output_pending = TRUE;

	return 0;
}
Пример #8
0
int
tsmf_ifman_on_sample(TSMF_IFMAN * ifman)
{
	TSMF_PRESENTATION * presentation;
	TSMF_STREAM * stream;
	uint32 StreamId;
	uint64 SampleStartTime;
	uint64 SampleEndTime;
	uint64 ThrottleDuration;
	uint32 SampleExtensions;
	uint32 cbData;

	StreamId = GET_UINT32(ifman->input_buffer, 16);
	SampleStartTime = GET_UINT64(ifman->input_buffer, 24);
	SampleEndTime = GET_UINT64(ifman->input_buffer, 32);
	ThrottleDuration = GET_UINT64(ifman->input_buffer, 40);
	SampleExtensions = GET_UINT32(ifman->input_buffer, 52);
	cbData = GET_UINT32(ifman->input_buffer, 56);
	
	LLOGLN(10, ("tsmf_ifman_on_sample: MessageId %d StreamId %d SampleStartTime %d SampleEndTime %d "
		"ThrottleDuration %d SampleExtensions %d cbData %d",
		ifman->message_id, StreamId, (int)SampleStartTime, (int)SampleEndTime,
		(int)ThrottleDuration, SampleExtensions, cbData));

	presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
	if (presentation == NULL)
	{
		LLOGLN(0, ("tsmf_ifman_on_sample: unknown presentation id"));
		return 1;
	}
	stream = tsmf_stream_find_by_id(presentation, StreamId);
	if (stream == NULL)
	{
		LLOGLN(0, ("tsmf_ifman_on_sample: unknown stream id"));
		return 1;
	}
	tsmf_stream_push_sample(stream, ifman->channel_callback,
		ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions,
		cbData, ifman->input_buffer + 60);

	ifman->output_pending = 1;
	return 0;
}
Пример #9
0
static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback)
{
	TSMF_STREAM* stream;
	TSMF_PRESENTATION* presentation;
	TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback;

	DEBUG_DVC("");

	if (callback->stream_id)
	{
		presentation = tsmf_presentation_find_by_id(callback->presentation_id);
		if (presentation)
		{
			stream = tsmf_stream_find_by_id(presentation, callback->stream_id);
			if (stream)
				tsmf_stream_free(stream);
		}
	}
	xfree(pChannelCallback);

	return 0;
}
Пример #10
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT tsmf_ifman_on_flush(TSMF_IFMAN* ifman)
{
	UINT32 StreamId;
	TSMF_PRESENTATION* presentation;
	TSMF_STREAM* stream;

	if (Stream_GetRemainingLength(ifman->input) < 20)
		return ERROR_INVALID_DATA;

	Stream_Seek(ifman->input, 16);
	Stream_Read_UINT32(ifman->input, StreamId);

	DEBUG_TSMF("StreamId %d", StreamId);

	presentation = tsmf_presentation_find_by_id(ifman->presentation_id);
	if (!presentation)
	{
		WLog_ERR(TAG, "unknown presentation id");
		return ERROR_NOT_FOUND;
	}

	/* Flush message is for a stream, not the entire presentation
	 * therefore we only flush the stream as intended per the MS-RDPEV spec
	 */
	stream = tsmf_stream_find_by_id(presentation, StreamId);
	if (stream)
	{
		if (!tsmf_stream_flush(stream))
			return ERROR_INVALID_OPERATION;
	}
	else
		WLog_ERR(TAG, "unknown stream id");

	ifman->output_pending = TRUE;

	return CHANNEL_RC_OK;
}
Пример #11
0
int
tsmf_ifman_on_end_of_stream(TSMF_IFMAN * ifman)
{
	TSMF_PRESENTATION * presentation;
	TSMF_STREAM * stream;
	uint32 StreamId;

	presentation = tsmf_presentation_find_by_id(ifman->input_buffer);
	StreamId = GET_UINT32(ifman->input_buffer, 16);
	stream = tsmf_stream_find_by_id(presentation, StreamId);
	tsmf_stream_end(stream);

	LLOGLN(0, ("tsmf_ifman_on_end_of_stream: StreamId %d", StreamId));

	ifman->output_buffer_size = 16;
	ifman->output_buffer = malloc(16);
	SET_UINT32(ifman->output_buffer, 0, CLIENT_EVENT_NOTIFICATION); /* FunctionId */
	SET_UINT32(ifman->output_buffer, 4, StreamId); /* StreamId */
	SET_UINT32(ifman->output_buffer, 8, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */
	SET_UINT32(ifman->output_buffer, 12, 0); /* cbData */
	ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY;

	return 0;
}
Пример #12
0
int
tsmf_ifman_remove_stream(TSMF_IFMAN * ifman)
{
	TSMF_PRESENTATION * presentation;
	TSMF_STREAM * stream;
	uint32 StreamId;
	int error = 0;

	LLOGLN(0, ("tsmf_ifman_remove_stream:"));
	presentation = tsmf_presentation_find_by_id(ifman->input_buffer);
	if (presentation == NULL)
		error = 1;
	else
	{
		StreamId = GET_UINT32(ifman->input_buffer, 16);
		stream = tsmf_stream_find_by_id(presentation, StreamId);
		if (stream)
			tsmf_stream_free(stream);
		else
			error = 1;
	}
	ifman->output_pending = 1;
	return error;
}
Пример #13
0
TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id, rdpContext* rdpcontext)
{
	TSMF_STREAM* stream;
	stream = tsmf_stream_find_by_id(presentation, stream_id);

	if (stream)
	{
		WLog_ERR(TAG, "duplicated stream id %d!", stream_id);
		return NULL;
	}

	stream = (TSMF_STREAM*) calloc(1, sizeof(TSMF_STREAM));
	if (!stream)
	{
		WLog_ERR(TAG, "Calloc failed");
		return NULL;
	}

	stream->minBufferLevel = VIDEO_MIN_BUFFER_LEVEL;
	stream->maxBufferLevel = VIDEO_MAX_BUFFER_LEVEL;
	stream->currentBufferLevel = 1;

	stream->seeking = FALSE;
	stream->eos = 0;
	stream->eos_message_id = 0;
	stream->eos_channel_callback = NULL;
	stream->stream_id = stream_id;
	stream->presentation = presentation;
	stream->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (!stream->stopEvent)
		goto error_stopEvent;
	stream->ready = CreateEvent(NULL, TRUE, TRUE, NULL);
	if (!stream->ready)
		goto error_ready;
	stream->sample_list = Queue_New(TRUE, -1, -1);
	if (!stream->sample_list)
		goto error_sample_list;
	stream->sample_list->object.fnObjectFree = tsmf_sample_free;
	stream->sample_ack_list = Queue_New(TRUE, -1, -1);
	if (!stream->sample_ack_list)
		goto error_sample_ack_list;
	stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free;

	stream->play_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, CREATE_SUSPENDED, NULL);
	stream->ack_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tsmf_stream_ack_func, stream, CREATE_SUSPENDED, NULL);

	stream->rdpcontext = rdpcontext;

	return stream;

error_add:
	SetEvent(stream->stopEvent);
	if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED)
		WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
error_ack_thread:
	SetEvent(stream->stopEvent);
	if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED)
		WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
error_play_thread:
	Queue_Free(stream->sample_ack_list);
error_sample_ack_list:
	Queue_Free(stream->sample_list);
error_sample_list:
	CloseHandle(stream->ready);
error_ready:
	CloseHandle(stream->stopEvent);
error_stopEvent:
	free(stream);
	return NULL;
}
Пример #14
0
TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
{
	TSMF_STREAM* stream;
	stream = tsmf_stream_find_by_id(presentation, stream_id);

	if (stream)
	{
		WLog_ERR(TAG, "duplicated stream id %d!", stream_id);
		return NULL;
	}

	stream = (TSMF_STREAM*) calloc(1, sizeof(TSMF_STREAM));
	if (!stream)
	{
		WLog_ERR(TAG, "Calloc failed");
		return NULL;
	}

	stream->stream_id = stream_id;
	stream->presentation = presentation;
	stream->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (!stream->stopEvent)
		goto error_stopEvent;
	stream->ready = CreateEvent(NULL, TRUE, TRUE, NULL);
	if (!stream->ready)
		goto error_ready;
	stream->sample_list = Queue_New(TRUE, -1, -1);
	if (!stream->sample_list)
		goto error_sample_list;
	stream->sample_list->object.fnObjectFree = tsmf_sample_free;
	stream->sample_ack_list = Queue_New(TRUE, -1, -1);
	if (!stream->sample_ack_list)
		goto error_sample_ack_list;
	stream->sample_ack_list->object.fnObjectFree = tsmf_sample_free;

	stream->play_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tsmf_stream_playback_func, stream, 0, NULL);
	if (!stream->play_thread)
		goto error_play_thread;
	stream->ack_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tsmf_stream_ack_func, stream, 0, NULL);
	if (!stream->ack_thread)
		goto error_ack_thread;

	if (ArrayList_Add(presentation->stream_list, stream) < 0)
		goto error_add;

	return stream;

error_add:
	SetEvent(stream->stopEvent);
	WaitForSingleObject(stream->ack_thread, INFINITE);
error_ack_thread:
	SetEvent(stream->stopEvent);
	WaitForSingleObject(stream->play_thread, INFINITE);
error_play_thread:
	Queue_Free(stream->sample_ack_list);
error_sample_ack_list:
	Queue_Free(stream->sample_list);
error_sample_list:
	CloseHandle(stream->ready);
error_ready:
	CloseHandle(stream->stopEvent);
error_stopEvent:
	free(stream);
	return NULL;
}
Пример #15
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT tsmf_ifman_on_sample(TSMF_IFMAN* ifman)
{
	TSMF_PRESENTATION* presentation;
	TSMF_STREAM* stream;
	UINT32 StreamId;
	UINT64 SampleStartTime;
	UINT64 SampleEndTime;
	UINT64 ThrottleDuration;
	UINT32 SampleExtensions;
	UINT32 cbData;
    UINT error;

	if (Stream_GetRemainingLength(ifman->input) < 60)
		return ERROR_INVALID_DATA;
	Stream_Seek(ifman->input, 16);
	Stream_Read_UINT32(ifman->input, StreamId);
	Stream_Seek_UINT32(ifman->input); /* numSample */
	Stream_Read_UINT64(ifman->input, SampleStartTime);
	Stream_Read_UINT64(ifman->input, SampleEndTime);
	Stream_Read_UINT64(ifman->input, ThrottleDuration);
	Stream_Seek_UINT32(ifman->input); /* SampleFlags */
	Stream_Read_UINT32(ifman->input, SampleExtensions);
	Stream_Read_UINT32(ifman->input, cbData);

	if (Stream_GetRemainingLength(ifman->input) < cbData)
		return ERROR_INVALID_DATA;

	DEBUG_TSMF("MessageId %d StreamId %d SampleStartTime %lu SampleEndTime %lu "
			   "ThrottleDuration %d SampleExtensions %d cbData %d",
			   ifman->message_id, StreamId, SampleStartTime, SampleEndTime,
			   (int)ThrottleDuration, SampleExtensions, cbData);

	presentation = tsmf_presentation_find_by_id(ifman->presentation_id);

	if (!presentation)
	{
		WLog_ERR(TAG, "unknown presentation id");
		return ERROR_NOT_FOUND;
	}

	stream = tsmf_stream_find_by_id(presentation, StreamId);

	if (!stream)
	{
		WLog_ERR(TAG, "unknown stream id");
		return ERROR_NOT_FOUND;
	}

	if (!tsmf_stream_push_sample(stream, ifman->channel_callback,
			ifman->message_id, SampleStartTime, SampleEndTime,
			ThrottleDuration, SampleExtensions, cbData, Stream_Pointer(ifman->input)))
	{
		WLog_ERR(TAG, "unable to push sample");
		return ERROR_OUTOFMEMORY;
	}

	if ((error = tsmf_presentation_sync(presentation)))
    {
        WLog_ERR(TAG, "tsmf_presentation_sync failed with error %lu", error);
        return error;
    }
	ifman->output_pending = TRUE;

	return CHANNEL_RC_OK;
}