Exemplo n.º 1
0
void tsmf_stream_free(TSMF_STREAM* stream)
{
	TSMF_PRESENTATION* presentation = stream->presentation;

	tsmf_stream_stop(stream);
	tsmf_stream_flush(stream);

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

	Queue_Free(stream->sample_list);
	Queue_Free(stream->sample_ack_list);

	if (stream->decoder)
	{
		stream->decoder->Free(stream->decoder);
		stream->decoder = 0;
	}

	SetEvent(stream->thread);

	free(stream);
	stream = 0;
}
Exemplo n.º 2
0
void _tsmf_stream_free(TSMF_STREAM *stream)
{
	assert(stream);
	tsmf_stream_stop(stream);
	tsmf_stream_flush(stream);
	SetEvent(stream->stopEvent);

	if (stream->play_thread)
	{
		WaitForSingleObject(stream->play_thread, INFINITE);
		CloseHandle(stream->play_thread);
		stream->play_thread = NULL;
	}

	if (stream->ack_thread)
	{
		WaitForSingleObject(stream->ack_thread, INFINITE);
		CloseHandle(stream->ack_thread);
		stream->ack_thread = NULL;
	}

	Queue_Free(stream->sample_list);
	Queue_Free(stream->sample_ack_list);

	if (stream->decoder && stream->decoder->Free)
	{
		stream->decoder->Free(stream->decoder);
		stream->decoder = NULL;
	}

	CloseHandle(stream->stopEvent);
	CloseHandle(stream->ready);
	memset(stream, 0, sizeof(TSMF_STREAM));
	free(stream);
}
Exemplo n.º 3
0
void tsmf_presentation_flush(TSMF_PRESENTATION* presentation)
{
	LIST_ITEM* item;
	TSMF_STREAM * stream;

	for (item = presentation->stream_list->head; item; item = item->next)
	{
		stream = (TSMF_STREAM*) item->data;
		tsmf_stream_flush(stream);
	}

	presentation->eos = 0;
	presentation->audio_start_time = 0;
	presentation->audio_end_time = 0;
}
Exemplo n.º 4
0
void _tsmf_stream_free(TSMF_STREAM* stream)
{
	if (!stream)
		return;

	if (tsmf_stream_stop(stream))
		tsmf_stream_flush(stream);
	SetEvent(stream->stopEvent);

	if (stream->play_thread)
	{
		if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED)
        {
            WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
            return;
        }

		CloseHandle(stream->play_thread);
		stream->play_thread = NULL;
	}

	if (stream->ack_thread)
	{
		if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED)
        {
            WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
            return;
        }
		CloseHandle(stream->ack_thread);
		stream->ack_thread = NULL;
	}

	Queue_Free(stream->sample_list);
	Queue_Free(stream->sample_ack_list);

	if (stream->decoder && stream->decoder->Free)
	{
		stream->decoder->Free(stream->decoder);
		stream->decoder = NULL;
	}

	CloseHandle(stream->stopEvent);
	CloseHandle(stream->ready);
	ZeroMemory(stream, sizeof(TSMF_STREAM));
	free(stream);
}
Exemplo n.º 5
0
void tsmf_presentation_flush(TSMF_PRESENTATION* presentation)
{
	UINT32 index;
	UINT32 count;
	TSMF_STREAM* stream;
	ArrayList_Lock(presentation->stream_list);
	count = ArrayList_Count(presentation->stream_list);

	for (index = 0; index < count; index++)
	{
		stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
		tsmf_stream_flush(stream);
	}

	ArrayList_Unlock(presentation->stream_list);
	presentation->eos = 0;
	presentation->audio_start_time = 0;
	presentation->audio_end_time = 0;
}
Exemplo n.º 6
0
static BOOL tsmf_stream_stop(TSMF_STREAM* stream)
{
	if (!stream || !stream->decoder || !stream->decoder->Control)
		return TRUE;

	/* If stopping after eos - we delay until the eos has been processed
	 * this allows us to process any buffers that have been acked even though
	 * they have not actually been completely processes by the decoder
	 */
	if (stream->eos)
	{
		DEBUG_TSMF("Setting up a delayed stop for once the eos has been processed.");
		stream->delayed_stop = 1;
		return TRUE;
	}
	/* Otherwise force stop immediately */
	else
	{
		DEBUG_TSMF("Stop with no pending eos response, so do it immediately.");
		tsmf_stream_flush(stream);
		return stream->decoder->Control(stream->decoder, Control_Stop, NULL);
	}
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
static void* tsmf_stream_ack_func(void *arg)
{
	HANDLE hdl[2];
	TSMF_STREAM* stream = (TSMF_STREAM*) arg;
	UINT error = CHANNEL_RC_OK;
	DEBUG_TSMF("in %d", stream->stream_id);

	hdl[0] = stream->stopEvent;
	hdl[1] = Queue_Event(stream->sample_ack_list);

	while (1)
	{
		DWORD ev = WaitForMultipleObjects(2, hdl, FALSE, 1000);

		if (ev == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error);
			break;
		}

		if (stream->decoder)
			if (stream->decoder->BufferLevel)
				stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);

		if (stream->eos)
		{
			while ((stream->currentBufferLevel > 0) || !(tsmf_stream_process_ack(stream, TRUE)))
			{
				DEBUG_TSMF("END OF STREAM PROCESSING!");
				if (stream->decoder->BufferLevel)
					stream->currentBufferLevel = stream->decoder->BufferLevel(stream->decoder);
				else
					stream->currentBufferLevel = 1;

				USleep(1000);
			}

			tsmf_send_eos_response(stream->eos_channel_callback, stream->eos_message_id);
			stream->eos = 0;

			if (stream->delayed_stop)
			{
				DEBUG_TSMF("Finishing delayed stream stop, now that eos has processed.");
				tsmf_stream_flush(stream);

				if (stream->decoder->Control)
					stream->decoder->Control(stream->decoder, Control_Stop, NULL);
			}
		}

		/* Stream stopped force all of the acks to happen */
		if (ev == WAIT_OBJECT_0)
		{
			DEBUG_TSMF("ack: Stream stopped!");
			while(1)
			{
				if (tsmf_stream_process_ack(stream, TRUE))
					break;
				USleep(1000);
			}
			break;
		}

		if (tsmf_stream_process_ack(stream, FALSE))
			continue;

		if (stream->currentBufferLevel > stream->minBufferLevel)
			USleep(1000);
	}

	if (error && stream->rdpcontext)
		setChannelError(stream->rdpcontext, error, "tsmf_stream_ack_func reported an error");

	DEBUG_TSMF("out %d", stream->stream_id);
	ExitThread(0);
	return NULL;
}