rdpsnd/client: Fix handling of WaveConfirm PDUs (#7910)
Currently, all FreeRDP-based clients don't send any WaveConfirm PDUs for received samples, when using a dynamic channel for audio output redirection. [MS-RDPEA] 2.2.3.8 Wave Confirm PDU mentions, that a WaveConfirm PDU MUST be sent, when a WaveInfo PDU + Wave PDU, or Wave2 PDU is received and when the audio data sample is emitted to completion by the client. The first WaveConfirm PDU is used by the server to determine the network latency and the second WaveConfirm PDU is used by the server to determine the render latency. So, fix the current behaviour, where FreeRDP currently does not send any WaveConfirm PDU, when using the dynamic channel, or only sends one WaveConfirm PDU for the sample. For the first WaveConfirm PDU, use the same timestamp, that was included in the first WaveInfo/Wave2 PDU. For the second WaveConfirm PDU, add the render latency on top of the arrival timestamp.
This commit is contained in:
parent
13d56dbfb2
commit
7d18ca4dc2
@ -608,6 +608,7 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size)
|
||||
UINT64 end;
|
||||
UINT64 diffMS, ts;
|
||||
UINT latency = 0;
|
||||
UINT error;
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, size))
|
||||
return ERROR_BAD_LENGTH;
|
||||
@ -615,6 +616,15 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size)
|
||||
if (rdpsnd->wCurrentFormatNo >= rdpsnd->NumberOfClientFormats)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
/*
|
||||
* Send the first WaveConfirm PDU. The server side uses this to determine the
|
||||
* network latency.
|
||||
* See also [MS-RDPEA] 2.2.3.8 Wave Confirm PDU
|
||||
*/
|
||||
error = rdpsnd_send_wave_confirm_pdu(rdpsnd, rdpsnd->wTimeStamp, rdpsnd->cBlockNo);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
data = Stream_Pointer(s);
|
||||
format = &rdpsnd->ClientFormats[rdpsnd->wCurrentFormatNo];
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG,
|
||||
@ -647,10 +657,11 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size)
|
||||
diffMS = end - rdpsnd->wArrivalTime + latency;
|
||||
ts = (rdpsnd->wTimeStamp + diffMS) % UINT16_MAX;
|
||||
|
||||
/* Don't send wave confirm PDU if on dynamic channel */
|
||||
if (rdpsnd->dynamic)
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
/*
|
||||
* Send the second WaveConfirm PDU. With the first WaveConfirm PDU,
|
||||
* the server side uses this second WaveConfirm PDU to determine the actual
|
||||
* render latency.
|
||||
*/
|
||||
return rdpsnd_send_wave_confirm_pdu(rdpsnd, (UINT16)ts, rdpsnd->cBlockNo);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user