/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_END_FRAME_PDU pdu; RDPGFX_FRAME_ACKNOWLEDGE_PDU ack; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; if (Stream_GetRemainingLength(s) < RDPGFX_END_FRAME_PDU_SIZE) { WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ WLog_DBG(TAG, "RecvEndFramePdu: frameId: %lu", (unsigned long) pdu.frameId); if (context) { IFCALLRET(context->EndFrame, error, context, &pdu); if (error) { WLog_ERR(TAG, "context->EndFrame failed with error %u", error); return error; } } gfx->UnacknowledgedFrames--; gfx->TotalDecodedFrames++; ack.frameId = pdu.frameId; ack.totalFramesDecoded = gfx->TotalDecodedFrames; if (gfx->suspendFrameAcks) { ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT; if (gfx->TotalDecodedFrames == 1) if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack))) WLog_ERR(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %u", error); } else { ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE; if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack))) WLog_ERR(TAG, "rdpgfx_send_frame_acknowledge_pdu failed with error %u", error); } return error; }
int rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_END_FRAME_PDU pdu; RDPGFX_FRAME_ACKNOWLEDGE_PDU ack; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 4) return -1; Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ WLog_Print(gfx->log, WLOG_DEBUG, "RecvEndFramePdu: frameId: %d", pdu.frameId); if (context && context->EndFrame) { context->EndFrame(context, &pdu); } gfx->UnacknowledgedFrames--; gfx->TotalDecodedFrames++; ack.frameId = pdu.frameId; ack.totalFramesDecoded = gfx->TotalDecodedFrames; //ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT; ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE; rdpgfx_send_frame_acknowledge_pdu(callback, &ack); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_end_frame_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_END_FRAME_PDU pdu; RDPGFX_FRAME_ACKNOWLEDGE_PDU ack; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; UINT error = CHANNEL_RC_OK; if (Stream_GetRemainingLength(s) < RDPGFX_END_FRAME_PDU_SIZE) { WLog_Print(gfx->log, WLOG_ERROR, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT32(s, pdu.frameId); /* frameId (4 bytes) */ WLog_Print(gfx->log, WLOG_DEBUG, "RecvEndFramePdu: frameId: %"PRIu32"", pdu.frameId); if (context) { IFCALLRET(context->EndFrame, error, context, &pdu); if (error) { WLog_Print(gfx->log, WLOG_ERROR, "context->EndFrame failed with error %"PRIu32"", error); return error; } } gfx->UnacknowledgedFrames--; gfx->TotalDecodedFrames++; ack.frameId = pdu.frameId; ack.totalFramesDecoded = gfx->TotalDecodedFrames; if (gfx->suspendFrameAcks) { ack.queueDepth = SUSPEND_FRAME_ACKNOWLEDGEMENT; if (gfx->TotalDecodedFrames == 1) if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack))) WLog_Print(gfx->log, WLOG_ERROR, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error); } else { ack.queueDepth = QUEUE_DEPTH_UNAVAILABLE; if ((error = rdpgfx_send_frame_acknowledge_pdu(callback, &ack))) WLog_Print(gfx->log, WLOG_DEBUG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error); } switch(gfx->ConnectionCaps.version) { case RDPGFX_CAPVERSION_10: case RDPGFX_CAPVERSION_102: case RDPGFX_CAPVERSION_103: if (gfx->SendQoeAck) { RDPGFX_QOE_FRAME_ACKNOWLEDGE_PDU qoe; UINT32 diff = (GetTickCountPrecise() - gfx->StartDecodingTime); if (diff > 65000) diff = 0; qoe.frameId = pdu.frameId; qoe.timestamp = gfx->StartDecodingTime; qoe.timeDiffSE = diff; qoe.timeDiffEDR = 1; if ((error = rdpgfx_send_qoe_frame_acknowledge_pdu(callback, &qoe))) WLog_Print(gfx->log, WLOG_DEBUG, "rdpgfx_send_frame_acknowledge_pdu failed with error %"PRIu32"", error); } break; default: break; } return error; }