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; }
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); }
/* 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; }
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; }
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); } }
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); } }
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, ¬if); 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; } }