commit
a7022e9a57
@ -223,6 +223,15 @@ static BOOL rdpsnd_alsa_set_format(rdpsndDevicePlugin* device, const AUDIO_FORMA
|
||||
return (rdpsnd_alsa_set_params(alsa) == 0);
|
||||
}
|
||||
|
||||
static void rdpsnd_alsa_close_mixer(rdpsndAlsaPlugin* alsa)
|
||||
{
|
||||
if (alsa && alsa->mixer_handle)
|
||||
{
|
||||
snd_mixer_close(alsa->mixer_handle);
|
||||
alsa->mixer_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa)
|
||||
{
|
||||
int status;
|
||||
@ -235,7 +244,7 @@ static BOOL rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa)
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "snd_mixer_open failed");
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = snd_mixer_attach(alsa->mixer_handle, alsa->device_name);
|
||||
@ -243,8 +252,7 @@ static BOOL rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa)
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "snd_mixer_attach failed");
|
||||
snd_mixer_close(alsa->mixer_handle);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = snd_mixer_selem_register(alsa->mixer_handle, NULL, NULL);
|
||||
@ -252,8 +260,7 @@ static BOOL rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa)
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "snd_mixer_selem_register failed");
|
||||
snd_mixer_close(alsa->mixer_handle);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = snd_mixer_load(alsa->mixer_handle);
|
||||
@ -261,11 +268,23 @@ static BOOL rdpsnd_alsa_open_mixer(rdpsndAlsaPlugin* alsa)
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "snd_mixer_load failed");
|
||||
snd_mixer_close(alsa->mixer_handle);
|
||||
return FALSE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
fail:
|
||||
rdpsnd_alsa_close_mixer(alsa);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void rdpsnd_alsa_pcm_close(rdpsndAlsaPlugin* alsa)
|
||||
{
|
||||
if (alsa && alsa->pcm_handle)
|
||||
{
|
||||
snd_pcm_drain(alsa->pcm_handle);
|
||||
snd_pcm_close(alsa->pcm_handle);
|
||||
alsa->pcm_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL rdpsnd_alsa_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format, UINT32 latency)
|
||||
@ -293,37 +312,19 @@ static BOOL rdpsnd_alsa_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* for
|
||||
|
||||
static void rdpsnd_alsa_close(rdpsndDevicePlugin* device)
|
||||
{
|
||||
int status;
|
||||
snd_htimestamp_t tstamp;
|
||||
snd_pcm_uframes_t frames;
|
||||
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
|
||||
|
||||
if (!alsa->pcm_handle)
|
||||
if (!alsa)
|
||||
return;
|
||||
|
||||
status = snd_pcm_htimestamp(alsa->pcm_handle, &frames, &tstamp);
|
||||
|
||||
if (status != 0)
|
||||
frames = 0;
|
||||
rdpsnd_alsa_close_mixer(alsa);
|
||||
}
|
||||
|
||||
static void rdpsnd_alsa_free(rdpsndDevicePlugin* device)
|
||||
{
|
||||
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
|
||||
|
||||
if (alsa->pcm_handle)
|
||||
{
|
||||
snd_pcm_drain(alsa->pcm_handle);
|
||||
snd_pcm_close(alsa->pcm_handle);
|
||||
alsa->pcm_handle = 0;
|
||||
}
|
||||
|
||||
if (alsa->mixer_handle)
|
||||
{
|
||||
snd_mixer_close(alsa->mixer_handle);
|
||||
alsa->mixer_handle = NULL;
|
||||
}
|
||||
|
||||
rdpsnd_alsa_pcm_close(alsa);
|
||||
rdpsnd_alsa_close_mixer(alsa);
|
||||
free(alsa->device_name);
|
||||
free(alsa);
|
||||
}
|
||||
@ -361,8 +362,8 @@ static UINT32 rdpsnd_alsa_get_volume(rdpsndDevicePlugin* device)
|
||||
dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */
|
||||
dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */
|
||||
|
||||
if (!alsa->mixer_handle)
|
||||
rdpsnd_alsa_open_mixer(alsa);
|
||||
if (!rdpsnd_alsa_open_mixer(alsa))
|
||||
return 0;
|
||||
|
||||
for (elem = snd_mixer_first_elem(alsa->mixer_handle); elem; elem = snd_mixer_elem_next(elem))
|
||||
{
|
||||
@ -392,7 +393,7 @@ static BOOL rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, UINT32 value)
|
||||
snd_mixer_elem_t* elem;
|
||||
rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*) device;
|
||||
|
||||
if (!alsa->mixer_handle && !rdpsnd_alsa_open_mixer(alsa))
|
||||
if (!rdpsnd_alsa_open_mixer(alsa))
|
||||
return FALSE;
|
||||
|
||||
left = (value & 0xFFFF);
|
||||
@ -438,8 +439,7 @@ static UINT rdpsnd_alsa_play(rdpsndDevicePlugin* device, const BYTE* data, size_
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "status: %d\n", status);
|
||||
snd_pcm_close(alsa->pcm_handle);
|
||||
alsa->pcm_handle = NULL;
|
||||
rdpsnd_alsa_close(alsa);
|
||||
rdpsnd_alsa_open((rdpsndDevicePlugin*) alsa, NULL, alsa->latency);
|
||||
break;
|
||||
}
|
||||
|
@ -50,10 +50,47 @@ struct rdpsnd_pulse_plugin
|
||||
pa_sample_spec sample_spec;
|
||||
pa_stream* stream;
|
||||
UINT32 latency;
|
||||
UINT32 volume;
|
||||
};
|
||||
|
||||
static BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format);
|
||||
|
||||
static void rdpsnd_pulse_get_sink_info(pa_context* c, const pa_sink_info* i, int eol,
|
||||
void* userdata)
|
||||
{
|
||||
uint8_t x;
|
||||
UINT16 dwVolumeLeft = ((50 * 0xFFFF) / 100); /* 50% */;
|
||||
UINT16 dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */;
|
||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*) userdata;
|
||||
|
||||
if (!pulse || !c || !i)
|
||||
return;
|
||||
|
||||
for (x = 0; x < i->volume.channels; x++)
|
||||
{
|
||||
pa_volume_t volume = i->volume.values[x];
|
||||
|
||||
if (volume >= PA_VOLUME_NORM)
|
||||
volume = PA_VOLUME_NORM - 1;
|
||||
|
||||
switch (x)
|
||||
{
|
||||
case 0:
|
||||
dwVolumeLeft = (UINT16)volume;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
dwVolumeRight = (UINT16)volume;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pulse->volume = ((UINT32)dwVolumeLeft << 16U) | dwVolumeRight;
|
||||
}
|
||||
|
||||
static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userdata)
|
||||
{
|
||||
pa_context_state_t state;
|
||||
@ -78,6 +115,7 @@ static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userd
|
||||
|
||||
static BOOL rdpsnd_pulse_connect(rdpsndDevicePlugin* device)
|
||||
{
|
||||
pa_operation* o;
|
||||
pa_context_state_t state;
|
||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*) device;
|
||||
|
||||
@ -112,6 +150,11 @@ static BOOL rdpsnd_pulse_connect(rdpsndDevicePlugin* device)
|
||||
pa_threaded_mainloop_wait(pulse->mainloop);
|
||||
}
|
||||
|
||||
o = pa_context_get_sink_info_by_index(pulse->context, 0, rdpsnd_pulse_get_sink_info, pulse);
|
||||
|
||||
if (o)
|
||||
pa_operation_unref(o);
|
||||
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
|
||||
if (state == PA_CONTEXT_READY)
|
||||
@ -347,11 +390,6 @@ static void rdpsnd_pulse_free(rdpsndDevicePlugin* device)
|
||||
|
||||
BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format)
|
||||
{
|
||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device;
|
||||
|
||||
if (!pulse->context)
|
||||
return FALSE;
|
||||
|
||||
switch (format->wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
@ -381,6 +419,24 @@ BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMA
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static UINT32 rdpsnd_pulse_get_volume(rdpsndDevicePlugin* device)
|
||||
{
|
||||
pa_operation* o;
|
||||
rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*) device;
|
||||
|
||||
if (!pulse)
|
||||
return 0;
|
||||
|
||||
if (!pulse->context || !pulse->mainloop)
|
||||
return 0;
|
||||
|
||||
pa_threaded_mainloop_lock(pulse->mainloop);
|
||||
o = pa_context_get_sink_info_by_index(pulse->context, 0, rdpsnd_pulse_get_sink_info, pulse);
|
||||
pa_operation_unref(o);
|
||||
pa_threaded_mainloop_unlock(pulse->mainloop);
|
||||
return pulse->volume;
|
||||
}
|
||||
|
||||
static BOOL rdpsnd_pulse_set_volume(rdpsndDevicePlugin* device, UINT32 value)
|
||||
{
|
||||
pa_cvolume cv;
|
||||
@ -532,6 +588,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p
|
||||
|
||||
pulse->device.Open = rdpsnd_pulse_open;
|
||||
pulse->device.FormatSupported = rdpsnd_pulse_format_supported;
|
||||
pulse->device.GetVolume = rdpsnd_pulse_get_volume;
|
||||
pulse->device.SetVolume = rdpsnd_pulse_set_volume;
|
||||
pulse->device.Play = rdpsnd_pulse_play;
|
||||
pulse->device.Start = rdpsnd_pulse_start;
|
||||
|
@ -332,6 +332,48 @@ static UINT rdpsnd_recv_training_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
return rdpsnd_send_training_confirm_pdu(rdpsnd, wTimeStamp, wPackSize);
|
||||
}
|
||||
|
||||
static BOOL rdpsnd_ensure_device_is_open(rdpsndPlugin* rdpsnd, UINT32 wFormatNo,
|
||||
const AUDIO_FORMAT* format)
|
||||
{
|
||||
if (!rdpsnd)
|
||||
return FALSE;
|
||||
|
||||
if (!rdpsnd->isOpen || (wFormatNo != rdpsnd->wCurrentFormatNo))
|
||||
{
|
||||
BOOL rc;
|
||||
BOOL supported;
|
||||
AUDIO_FORMAT deviceFormat = *format;
|
||||
rdpsnd_recv_close_pdu(rdpsnd);
|
||||
supported = IFCALLRESULT(FALSE, rdpsnd->device->FormatSupported, rdpsnd->device, format);
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
deviceFormat.wFormatTag = WAVE_FORMAT_PCM;
|
||||
deviceFormat.wBitsPerSample = 16;
|
||||
deviceFormat.cbSize = 0;
|
||||
}
|
||||
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Opening device with format %s [backend %s]",
|
||||
audio_format_get_tag_string(format->wFormatTag),
|
||||
audio_format_get_tag_string(deviceFormat.wFormatTag));
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->Open, rdpsnd->device, &deviceFormat, rdpsnd->latency);
|
||||
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
|
||||
if (!supported)
|
||||
{
|
||||
if (!freerdp_dsp_context_reset(rdpsnd->dsp_context, format))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rdpsnd->isOpen = TRUE;
|
||||
rdpsnd->wCurrentFormatNo = wFormatNo;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@ -361,36 +403,8 @@ static UINT rdpsnd_recv_wave_info_pdu(rdpsndPlugin* rdpsnd, wStream* s,
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "WaveInfo: cBlockNo: %"PRIu8" wFormatNo: %"PRIu16" [%s]",
|
||||
rdpsnd->cBlockNo, wFormatNo, audio_format_get_tag_string(format->wFormatTag));
|
||||
|
||||
if (!rdpsnd->isOpen || (wFormatNo != rdpsnd->wCurrentFormatNo))
|
||||
{
|
||||
BOOL rc;
|
||||
AUDIO_FORMAT deviceFormat = *format;
|
||||
rdpsnd_recv_close_pdu(rdpsnd);
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->FormatSupported, rdpsnd->device, format);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
deviceFormat.wFormatTag = WAVE_FORMAT_PCM;
|
||||
deviceFormat.wBitsPerSample = 16;
|
||||
deviceFormat.cbSize = 0;
|
||||
}
|
||||
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->Open, rdpsnd->device, &deviceFormat, rdpsnd->latency);
|
||||
|
||||
if (!rc)
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->FormatSupported, rdpsnd->device, format);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
if (!freerdp_dsp_context_reset(rdpsnd->dsp_context, format))
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
|
||||
rdpsnd->isOpen = TRUE;
|
||||
rdpsnd->wCurrentFormatNo = wFormatNo;
|
||||
}
|
||||
if (!rdpsnd_ensure_device_is_open(rdpsnd, wFormatNo, format))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
rdpsnd->expectingWave = TRUE;
|
||||
return CHANNEL_RC_OK;
|
||||
@ -435,8 +449,8 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size)
|
||||
|
||||
data = Stream_Pointer(s);
|
||||
format = &rdpsnd->ClientFormats[rdpsnd->wCurrentFormatNo];
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Wave: cBlockNo: %"PRIu8" wTimeStamp: %"PRIu16"",
|
||||
rdpsnd->cBlockNo, rdpsnd->wTimeStamp);
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Wave: cBlockNo: %"PRIu8" wTimeStamp: %"PRIu16", size: %"PRIdz,
|
||||
rdpsnd->cBlockNo, rdpsnd->wTimeStamp, size);
|
||||
|
||||
if (rdpsnd->device && rdpsnd->attached)
|
||||
{
|
||||
@ -474,12 +488,16 @@ static UINT rdpsnd_treat_wave(rdpsndPlugin* rdpsnd, wStream* s, size_t size)
|
||||
static UINT rdpsnd_recv_wave_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
{
|
||||
rdpsnd->expectingWave = FALSE;
|
||||
|
||||
/**
|
||||
* The Wave PDU is a special case: it is always sent after a Wave Info PDU,
|
||||
* and we do not process its header. Instead, the header is pad that needs
|
||||
* to be filled with the first four bytes of the audio sample data sent as
|
||||
* part of the preceding Wave Info PDU.
|
||||
*/
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
CopyMemory(Stream_Buffer(s), rdpsnd->waveData, 4);
|
||||
return rdpsnd_treat_wave(rdpsnd, s, rdpsnd->waveDataSize);
|
||||
}
|
||||
@ -501,51 +519,25 @@ static UINT rdpsnd_recv_wave2_pdu(rdpsndPlugin* rdpsnd, wStream* s, UINT16 BodyS
|
||||
rdpsnd->waveDataSize = BodySize - 12;
|
||||
format = &rdpsnd->ClientFormats[wFormatNo];
|
||||
rdpsnd->wArrivalTime = GetTickCount();
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Wave2PDU: cBlockNo: %"PRIu8" wFormatNo: %"PRIu16"",
|
||||
rdpsnd->cBlockNo, wFormatNo);
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Wave2PDU: cBlockNo: %"PRIu8" wFormatNo: %"PRIu16", align=%hu",
|
||||
rdpsnd->cBlockNo, wFormatNo, format->nBlockAlign);
|
||||
|
||||
if (!rdpsnd->isOpen || (wFormatNo != rdpsnd->wCurrentFormatNo))
|
||||
{
|
||||
BOOL rc;
|
||||
AUDIO_FORMAT deviceFormat = *format;
|
||||
rdpsnd_recv_close_pdu(rdpsnd);
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->FormatSupported, rdpsnd->device, format);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
deviceFormat.wFormatTag = WAVE_FORMAT_PCM;
|
||||
deviceFormat.wBitsPerSample = 16;
|
||||
deviceFormat.cbSize = 0;
|
||||
}
|
||||
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->Open, rdpsnd->device, &deviceFormat, rdpsnd->latency);
|
||||
|
||||
if (!rc)
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->FormatSupported, rdpsnd->device, format);
|
||||
|
||||
if (!rc)
|
||||
{
|
||||
if (!freerdp_dsp_context_reset(rdpsnd->dsp_context, format))
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
|
||||
rdpsnd->isOpen = TRUE;
|
||||
rdpsnd->wCurrentFormatNo = wFormatNo;
|
||||
}
|
||||
if (!rdpsnd_ensure_device_is_open(rdpsnd, wFormatNo, format))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
return rdpsnd_treat_wave(rdpsnd, s, rdpsnd->waveDataSize);
|
||||
}
|
||||
|
||||
static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd)
|
||||
{
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Close");
|
||||
|
||||
if (rdpsnd->isOpen)
|
||||
{
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Closing device");
|
||||
IFCALL(rdpsnd->device->Close, rdpsnd->device);
|
||||
|
||||
rdpsnd->isOpen = FALSE;
|
||||
rdpsnd->isOpen = FALSE;
|
||||
}
|
||||
else
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Device already closed");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -555,7 +547,7 @@ static void rdpsnd_recv_close_pdu(rdpsndPlugin* rdpsnd)
|
||||
*/
|
||||
static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
{
|
||||
BOOL error;
|
||||
BOOL rc;
|
||||
UINT32 dwVolume;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
@ -563,9 +555,9 @@ static UINT rdpsnd_recv_volume_pdu(rdpsndPlugin* rdpsnd, wStream* s)
|
||||
|
||||
Stream_Read_UINT32(s, dwVolume);
|
||||
WLog_Print(rdpsnd->log, WLOG_DEBUG, "Volume: 0x%08"PRIX32"", dwVolume);
|
||||
error = IFCALLRESULT(FALSE, rdpsnd->device->SetVolume, rdpsnd->device, dwVolume);
|
||||
rc = IFCALLRESULT(FALSE, rdpsnd->device->SetVolume, rdpsnd->device, dwVolume);
|
||||
|
||||
if (error)
|
||||
if (!rc)
|
||||
{
|
||||
WLog_ERR(TAG, "error setting volume");
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
|
@ -379,6 +379,26 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static BOOL rdpsnd_server_align_wave_pdu(wStream* s, UINT32 alignment)
|
||||
{
|
||||
size_t size;
|
||||
Stream_SealLength(s);
|
||||
size = Stream_Length(s);
|
||||
|
||||
if ((size % alignment) != 0)
|
||||
{
|
||||
size_t offset = alignment - size % alignment;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, offset))
|
||||
return FALSE;
|
||||
|
||||
Stream_Zero(s, offset);
|
||||
}
|
||||
|
||||
Stream_SealLength(s);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
* context->priv->lock should be obtained before calling this function
|
||||
@ -410,10 +430,13 @@ static UINT rdpsnd_server_send_wave_pdu(RdpsndServerContext* context,
|
||||
length = context->priv->out_pending_frames * context->priv->src_bytes_per_frame;
|
||||
|
||||
if (!freerdp_dsp_encode(context->priv->dsp_context, format, src, length, s))
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
else
|
||||
{
|
||||
/* Set stream size */
|
||||
if (!rdpsnd_server_align_wave_pdu(s, format->nBlockAlign))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
end = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 2);
|
||||
Stream_Write_UINT16(s, end - start + 8);
|
||||
@ -486,18 +509,23 @@ static UINT rdpsnd_server_send_wave2_pdu(RdpsndServerContext* context,
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
else
|
||||
{
|
||||
BOOL rc;
|
||||
|
||||
/* Set stream size */
|
||||
if (!rdpsnd_server_align_wave_pdu(s, format->nBlockAlign))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
end = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 2);
|
||||
Stream_Write_UINT16(s, end - 4);
|
||||
Stream_SetPosition(s, end);
|
||||
Stream_SealLength(s);
|
||||
context->block_no = (context->block_no + 1) % 256;
|
||||
rc = WTSVirtualChannelWrite(context->priv->ChannelHandle,
|
||||
(PCHAR) Stream_Buffer(s), end, &written);
|
||||
|
||||
if (!WTSVirtualChannelWrite(context->priv->ChannelHandle,
|
||||
(PCHAR) Stream_Buffer(s), Stream_Length(s), &written))
|
||||
if (!rc || (end != written))
|
||||
{
|
||||
WLog_ERR(TAG, "WTSVirtualChannelWrite failed!");
|
||||
WLog_ERR(TAG, "WTSVirtualChannelWrite failed! [stream length=%"PRIdz" - written=%"PRIu32, end,
|
||||
written);
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
@ -715,7 +743,6 @@ static UINT rdpsnd_server_start(RdpsndServerContext* context)
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
out_stopEvent:
|
||||
CloseHandle(context->priv->StopEvent);
|
||||
context->priv->StopEvent = NULL;
|
||||
|
@ -87,20 +87,17 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp)
|
||||
|
||||
static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s)
|
||||
{
|
||||
SURFACE_BITS_COMMAND* cmd = calloc(1, sizeof(SURFACE_BITS_COMMAND));
|
||||
|
||||
if (!cmd)
|
||||
return FALSE;
|
||||
SURFACE_BITS_COMMAND cmd = {0};
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
goto fail;
|
||||
|
||||
Stream_Read_UINT16(s, cmd->destLeft);
|
||||
Stream_Read_UINT16(s, cmd->destTop);
|
||||
Stream_Read_UINT16(s, cmd->destRight);
|
||||
Stream_Read_UINT16(s, cmd->destBottom);
|
||||
Stream_Read_UINT16(s, cmd.destLeft);
|
||||
Stream_Read_UINT16(s, cmd.destTop);
|
||||
Stream_Read_UINT16(s, cmd.destRight);
|
||||
Stream_Read_UINT16(s, cmd.destBottom);
|
||||
|
||||
if (!update_recv_surfcmd_bitmap_ex(s, &cmd->bmp))
|
||||
if (!update_recv_surfcmd_bitmap_ex(s, &cmd.bmp))
|
||||
goto fail;
|
||||
|
||||
if (!update->SurfaceBits)
|
||||
@ -109,9 +106,8 @@ static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return update->SurfaceBits(update->context, cmd);
|
||||
return update->SurfaceBits(update->context, &cmd);
|
||||
fail:
|
||||
free_surface_bits_command(update->context, cmd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user