Esempio n. 1
0
static BOOL tsmf_stream_process_ack(void* arg, BOOL force)
{
	TSMF_STREAM* stream = arg;
	TSMF_SAMPLE* sample;
	UINT64 ack_time;
	BOOL rc = FALSE;

	if (!stream)
		return FALSE;

	Queue_Lock(stream->sample_ack_list);
	sample = (TSMF_SAMPLE*) Queue_Peek(stream->sample_ack_list);

	if (!sample)
		goto finally;

	if (!force)
	{
		ack_time = get_current_time();

		if (sample->ack_time > ack_time)
			goto finally;
	}

	sample = Queue_Dequeue(stream->sample_ack_list);
	tsmf_sample_ack(sample);
	tsmf_sample_free(sample);

finally:
	Queue_Unlock(stream->sample_ack_list);
	return rc;
}
Esempio n. 2
0
RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc)
{
	DWORD dwMilliseconds;
	DWORD result;
	dwMilliseconds = rpc->client->SynchronousReceive ? SYNCHRONOUS_TIMEOUT : 0;
	result = WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds);

	if (result != WAIT_OBJECT_0)
		return NULL;

	return (RPC_PDU*)Queue_Peek(rpc->client->ReceiveQueue);
}
Esempio n. 3
0
/* Returns TRUE if no more samples are currently available
 * Returns FALSE otherwise
 */
static BOOL tsmf_stream_process_ack(void* arg, BOOL force)
{
	TSMF_STREAM* stream = arg;
	TSMF_SAMPLE* sample;
	UINT64 ack_time;
	BOOL rc = FALSE;

	if (!stream)
		return TRUE;

	Queue_Lock(stream->sample_ack_list);
	sample = (TSMF_SAMPLE*) Queue_Peek(stream->sample_ack_list);

	if (!sample)
	{
		rc = TRUE;
		goto finally;
	}

	if (!force)
	{
		/* Do some min/max ack limiting if we have access to Buffer level information */
		if (stream->decoder && stream->decoder->BufferLevel)
		{
			/* Try to keep buffer level below max by withholding acks */
			if (stream->currentBufferLevel > stream->maxBufferLevel)
				goto finally;
			/* Try to keep buffer level above min by pushing acks through quickly */
			else if (stream->currentBufferLevel < stream->minBufferLevel)
				goto dequeue;
		}

		/* Time based acks only */
		ack_time = get_current_time();

		if (sample->ack_time > ack_time)
			goto finally;
	}

dequeue:
	sample = Queue_Dequeue(stream->sample_ack_list);

	if (sample)
	{
		tsmf_sample_ack(sample);
		tsmf_sample_free(sample);
	}

finally:
	Queue_Unlock(stream->sample_ack_list);
	return rc;
}
Esempio n. 4
0
RPC_PDU* rpc_recv_peek_pdu(rdpRpc* rpc)
{
	RPC_PDU* pdu;
	DWORD dwMilliseconds;

	pdu = NULL;
	dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0;

	if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0)
	{
		pdu = (RPC_PDU*) Queue_Peek(rpc->client->ReceiveQueue);
		return pdu;
	}

	return pdu;
}
Esempio n. 5
0
void rdpsnd_count_frames(rdpsndIOSPlugin* p)
{
	int targetFrames;
	waveItem* peek;
	
	peek = Queue_Peek(p->waveQ);
	if (!peek)
	{
		printf("empty waveQ!\n");
		return;
	}
	
	
	targetFrames = peek->numFrames;
	//printf("count %d/%d frames\n", p->frameCnt, targetFrames);
	
	if (p->frameCnt >= targetFrames)
	{
		UINT16 tB;
		UINT16 diff;
		
		tB = (UINT16)GetTickCount();
		diff = tB - peek->localTimeStampA;
		
		//frameCnt = frameCnt - peek->numFrames;
		p->frameCnt = 0;
		
		peek = Queue_Dequeue(p->waveQ);
		
		rdpsnd_send_wave_confirm_pdu(p->device.rdpsnd, peek->remoteTimeStampA + diff, peek->ID);
		//printf("confirm with latency:%d\n", diff);
		
		printf("\tConfirm %02X timeStamp A:%d B:%d diff %d (qCount=%d)\n"
		       , peek->ID,
		       peek->remoteTimeStampA,
		       peek->remoteTimeStampA + diff,
		       diff,
		       Queue_Count(p->waveQ));
		
		free(peek);
	}
}
Esempio n. 6
0
static void tsmf_stream_process_ack(TSMF_STREAM* stream)
{
	TSMF_SAMPLE* sample;
	UINT64 ack_time;

	ack_time = get_current_time();

	while ((Queue_Count(stream->sample_ack_list) > 0) && !(WaitForSingleObject(stream->stopEvent, 0) == WAIT_OBJECT_0))
	{
		sample = (TSMF_SAMPLE*) Queue_Peek(stream->sample_ack_list);

		if (!sample || (sample->ack_time > ack_time))
			break;

		sample = Queue_Dequeue(stream->sample_ack_list);

		tsmf_sample_ack(sample);
		tsmf_sample_free(sample);
	}
}
Esempio n. 7
0
static void video_timer(VideoClientContext *video, UINT64 now)
{
	PresentationContext *presentation;
	VideoClientContextPriv *priv = video->priv;
	VideoFrame *peekFrame, *frame = NULL;

	EnterCriticalSection(&priv->framesLock);
	do
	{
		peekFrame = (VideoFrame *)Queue_Peek(priv->frames);
		if (!peekFrame)
			break;

		if (peekFrame->publishTime > now)
			break;

		if (frame)
		{
			WLog_DBG(TAG, "dropping frame @%"PRIu64, frame->publishTime);
			priv->droppedFrames++;
			VideoFrame_free(&frame);
		}
		frame = peekFrame;
		Queue_Dequeue(priv->frames);
	}
	while (1);
	LeaveCriticalSection(&priv->framesLock);

	if (!frame)
		goto treat_feedback;

	presentation = frame->presentation;

	priv->publishedFrames++;
	memcpy(presentation->surfaceData, frame->surfaceData, frame->w * frame->h * 4);

	video->showSurface(video, presentation->surface);

	VideoFrame_free(&frame);

treat_feedback:
	if (priv->nextFeedbackTime < now)
	{
		/* we can compute some feedback only if we have some published frames and
		 * a current presentation
		 */
		if (priv->publishedFrames && priv->currentPresentation)
		{
			UINT32 computedRate;

			InterlockedIncrement(&priv->currentPresentation->refCounter);

			if (priv->droppedFrames)
			{
				/**
				 * some dropped frames, looks like we're asking too many frames per seconds,
				 * try lowering rate. We go directly from unlimited rate to 24 frames/seconds
				 * otherwise we lower rate by 2 frames by seconds
				 */
				if (priv->lastSentRate == XF_VIDEO_UNLIMITED_RATE)
					computedRate = 24;
				else
				{
					computedRate = priv->lastSentRate - 2;
					if (!computedRate)
						computedRate = 2;
				}
			}
			else
			{
				/**
				 * we treat all frames ok, so either ask the server to send more,
				 * or stay unlimited
			 */
				if (priv->lastSentRate == XF_VIDEO_UNLIMITED_RATE)
					computedRate = XF_VIDEO_UNLIMITED_RATE; /* stay unlimited */
				else
				{
					computedRate = priv->lastSentRate + 2;
					if (computedRate > XF_VIDEO_UNLIMITED_RATE)
						computedRate = XF_VIDEO_UNLIMITED_RATE;
				}
			}

			if (computedRate != priv->lastSentRate)
			{
				TSMM_CLIENT_NOTIFICATION notif;
				notif.PresentationId = priv->currentPresentation->PresentationId;
				notif.NotificationType = TSMM_CLIENT_NOTIFICATION_TYPE_FRAMERATE_OVERRIDE;
				if (computedRate == XF_VIDEO_UNLIMITED_RATE)
				{
					notif.FramerateOverride.Flags = 0x01;
					notif.FramerateOverride.DesiredFrameRate = 0x00;
				}
				else
				{
					notif.FramerateOverride.Flags = 0x02;
					notif.FramerateOverride.DesiredFrameRate = computedRate;
				}

				video_control_send_client_notification(video, &notif);
				priv->lastSentRate = computedRate;

				WLog_DBG(TAG, "server notified with rate %d published=%d dropped=%d", priv->lastSentRate,
						priv->publishedFrames, priv->droppedFrames);
			}

			PresentationContext_unref(priv->currentPresentation);
		}

		WLog_DBG(TAG, "currentRate=%d published=%d dropped=%d", priv->lastSentRate,
				priv->publishedFrames, priv->droppedFrames);

		priv->droppedFrames = 0;
		priv->publishedFrames = 0;
		priv->nextFeedbackTime = now + 1000;
	}
}