From 5521a73e9097949f61ff39e70c8a365e76d7312e Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 28 Apr 2022 17:49:42 +0200 Subject: [PATCH] Some rdpsnd debug improvements --- channels/rdpsnd/client/pulse/rdpsnd_pulse.c | 137 +++++++++++++++----- channels/rdpsnd/client/rdpsnd_main.c | 8 +- 2 files changed, 109 insertions(+), 36 deletions(-) diff --git a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c index 683c0bb53..f3498e36b 100644 --- a/channels/rdpsnd/client/pulse/rdpsnd_pulse.c +++ b/channels/rdpsnd/client/pulse/rdpsnd_pulse.c @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -49,6 +50,35 @@ typedef struct UINT32 volume; } rdpsndPulsePlugin; +static BOOL rdpsnd_check_pulse(rdpsndPulsePlugin* pulse, BOOL haveStream) +{ + BOOL rc = TRUE; + WINPR_ASSERT(pulse); + + if (!pulse->context) + { + WLog_WARN(TAG, "pulse->context=%p", pulse->context); + rc = FALSE; + } + + if (haveStream) + { + if (!pulse->stream) + { + WLog_WARN(TAG, "pulse->stream=%p", pulse->stream); + rc = FALSE; + } + } + + if (!pulse->mainloop) + { + WLog_WARN(TAG, "pulse->mainloop=%p", pulse->mainloop); + rc = FALSE; + } + + return rc; +} + 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, @@ -59,7 +89,8 @@ static void rdpsnd_pulse_get_sink_info(pa_context* c, const pa_sink_info* i, int UINT16 dwVolumeRight = ((50 * 0xFFFF) / 100); /* 50% */ rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; - if (!pulse || !c || !i) + WINPR_ASSERT(c); + if (!rdpsnd_check_pulse(pulse, FALSE) || !i) return; for (x = 0; x < i->volume.channels; x++) @@ -91,6 +122,10 @@ static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userd { pa_context_state_t state; rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + + WINPR_ASSERT(context); + WINPR_ASSERT(pulse); + state = pa_context_get_state(context); switch (state) @@ -115,7 +150,7 @@ static BOOL rdpsnd_pulse_connect(rdpsndDevicePlugin* device) pa_context_state_t state; rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; - if (!pulse->context) + if (!rdpsnd_check_pulse(pulse, FALSE)) return FALSE; if (pa_context_connect(pulse->context, NULL, 0, NULL)) @@ -167,11 +202,18 @@ static BOOL rdpsnd_pulse_connect(rdpsndDevicePlugin* device) static void rdpsnd_pulse_stream_success_callback(pa_stream* stream, int success, void* userdata) { rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + + if (!rdpsnd_check_pulse(pulse, TRUE)) + return; + pa_threaded_mainloop_signal(pulse->mainloop, 0); } static void rdpsnd_pulse_wait_for_operation(rdpsndPulsePlugin* pulse, pa_operation* operation) { + if (!rdpsnd_check_pulse(pulse, TRUE)) + return; + if (!operation) return; @@ -187,6 +229,11 @@ static void rdpsnd_pulse_stream_state_callback(pa_stream* stream, void* userdata { pa_stream_state_t state; rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + + WINPR_ASSERT(stream); + if (!rdpsnd_check_pulse(pulse, TRUE)) + return; + state = pa_stream_get_state(stream); switch (state) @@ -208,6 +255,11 @@ static void rdpsnd_pulse_stream_state_callback(pa_stream* stream, void* userdata static void rdpsnd_pulse_stream_request_callback(pa_stream* stream, size_t length, void* userdata) { rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + + WINPR_ASSERT(stream); + if (!rdpsnd_check_pulse(pulse, TRUE)) + return; + pa_threaded_mainloop_signal(pulse->mainloop, 0); } @@ -215,15 +267,20 @@ static void rdpsnd_pulse_close(rdpsndDevicePlugin* device) { rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; - if (!pulse->context || !pulse->stream) + WINPR_ASSERT(pulse); + + if (!rdpsnd_check_pulse(pulse, FALSE)) return; pa_threaded_mainloop_lock(pulse->mainloop); - rdpsnd_pulse_wait_for_operation( - pulse, pa_stream_drain(pulse->stream, rdpsnd_pulse_stream_success_callback, pulse)); - pa_stream_disconnect(pulse->stream); - pa_stream_unref(pulse->stream); - pulse->stream = NULL; + if (pulse->stream) + { + rdpsnd_pulse_wait_for_operation( + pulse, pa_stream_drain(pulse->stream, rdpsnd_pulse_stream_success_callback, pulse)); + pa_stream_disconnect(pulse->stream); + pa_stream_unref(pulse->stream); + pulse->stream = NULL; + } pa_threaded_mainloop_unlock(pulse->mainloop); } @@ -231,7 +288,9 @@ static BOOL rdpsnd_pulse_set_format_spec(rdpsndPulsePlugin* pulse, const AUDIO_F { pa_sample_spec sample_spec = { 0 }; - if (!pulse->context) + WINPR_ASSERT(format); + + if (!rdpsnd_check_pulse(pulse, FALSE)) return FALSE; if (!rdpsnd_pulse_format_supported(&pulse->device, format)) @@ -281,10 +340,12 @@ static BOOL rdpsnd_pulse_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* fo pa_stream_state_t state; pa_stream_flags_t flags; pa_buffer_attr buffer_attr = { 0 }; - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX]; + char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = { 0 }; rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; - if (!pulse->context || pulse->stream) + WINPR_ASSERT(format); + + if (!rdpsnd_check_pulse(pulse, FALSE)) return TRUE; if (!rdpsnd_pulse_set_format_spec(pulse, format)) @@ -363,9 +424,7 @@ static void rdpsnd_pulse_free(rdpsndDevicePlugin* device) rdpsnd_pulse_close(device); if (pulse->mainloop) - { pa_threaded_mainloop_stop(pulse->mainloop); - } if (pulse->context) { @@ -388,6 +447,7 @@ static BOOL rdpsnd_pulse_default_format(rdpsndDevicePlugin* device, const AUDIO_ AUDIO_FORMAT* defaultFormat) { rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + if (!pulse || !defaultFormat) return FALSE; @@ -409,6 +469,9 @@ static BOOL rdpsnd_pulse_default_format(rdpsndDevicePlugin* device, const AUDIO_ BOOL rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, const AUDIO_FORMAT* format) { + WINPR_ASSERT(device); + WINPR_ASSERT(format); + switch (format->wFormatTag) { case WAVE_FORMAT_PCM: @@ -441,10 +504,7 @@ static UINT32 rdpsnd_pulse_get_volume(rdpsndDevicePlugin* device) pa_operation* o; rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; - if (!pulse) - return 0; - - if (!pulse->context || !pulse->mainloop) + if (!rdpsnd_check_pulse(pulse, FALSE)) return 0; pa_threaded_mainloop_lock(pulse->mainloop); @@ -454,26 +514,40 @@ static UINT32 rdpsnd_pulse_get_volume(rdpsndDevicePlugin* device) return pulse->volume; } +static void rdpsnd_set_volume_success_cb(pa_context* c, int success, void* userdata) +{ + rdpsndPulsePlugin* pulse = userdata; + + if (!rdpsnd_check_pulse(pulse, TRUE)) + return; + WINPR_ASSERT(c); + + WLog_INFO(TAG, "%s: %d", __FUNCTION__, success); +} + static BOOL rdpsnd_pulse_set_volume(rdpsndDevicePlugin* device, UINT32 value) { - pa_cvolume cv; + pa_cvolume cv = { 0 }; pa_volume_t left; pa_volume_t right; pa_operation* operation; rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; - if (!pulse->context || !pulse->stream) + if (!rdpsnd_check_pulse(pulse, TRUE)) + { + WLog_WARN(TAG, "%s called before pulse backend was initialized"); return FALSE; + } left = (pa_volume_t)(value & 0xFFFF); right = (pa_volume_t)((value >> 16) & 0xFFFF); pa_cvolume_init(&cv); cv.channels = 2; - cv.values[0] = PA_VOLUME_MUTED + (left * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / 0xFFFF; - cv.values[1] = PA_VOLUME_MUTED + (right * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / 0xFFFF; + cv.values[0] = PA_VOLUME_MUTED + (left * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / PA_VOLUME_NORM; + cv.values[1] = PA_VOLUME_MUTED + (right * (PA_VOLUME_NORM - PA_VOLUME_MUTED)) / PA_VOLUME_NORM; pa_threaded_mainloop_lock(pulse->mainloop); operation = pa_context_set_sink_input_volume(pulse->context, pa_stream_get_index(pulse->stream), - &cv, NULL, NULL); + &cv, rdpsnd_set_volume_success_cb, pulse); if (operation) pa_operation_unref(operation); @@ -490,7 +564,7 @@ static UINT rdpsnd_pulse_play(rdpsndDevicePlugin* device, const BYTE* data, size int negative; rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; - if (!pulse->stream || !data) + if (!rdpsnd_check_pulse(pulse, TRUE) || !data) return 0; pa_threaded_mainloop_lock(pulse->mainloop); @@ -524,11 +598,6 @@ static UINT rdpsnd_pulse_play(rdpsndDevicePlugin* device, const BYTE* data, size return latency / 1000; } -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, const ADDIN_ARGV* args) { int status; @@ -540,6 +609,10 @@ static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, const ADDI { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; flags = COMMAND_LINE_SIGIL_NONE | COMMAND_LINE_SEPARATOR_COLON | COMMAND_LINE_IGN_UNKNOWN_KEYWORD; + + WINPR_ASSERT(pulse); + WINPR_ASSERT(args); + status = CommandLineParseArgumentsA(args->argc, args->argv, rdpsnd_pulse_args, flags, pulse, NULL, NULL); @@ -566,16 +639,14 @@ static UINT rdpsnd_pulse_parse_addin_args(rdpsndDevicePlugin* device, const ADDI return CHANNEL_RC_OK; } -/** - * Function description - * - * @return 0 on success, otherwise a Win32 error code - */ UINT pulse_freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) { const ADDIN_ARGV* args; rdpsndPulsePlugin* pulse; UINT ret; + + WINPR_ASSERT(pEntryPoints); + pulse = (rdpsndPulsePlugin*)calloc(1, sizeof(rdpsndPulsePlugin)); if (!pulse) diff --git a/channels/rdpsnd/client/rdpsnd_main.c b/channels/rdpsnd/client/rdpsnd_main.c index ec4a60fdc..7fcc9e31b 100644 --- a/channels/rdpsnd/client/rdpsnd_main.c +++ b/channels/rdpsnd/client/rdpsnd_main.c @@ -123,6 +123,8 @@ struct rdpsnd_plugin HANDLE thread; wMessageQueue* queue; BOOL initialized; + + UINT16 wVersion; }; static const char* rdpsnd_is_dyn_str(BOOL dynamic) @@ -268,9 +270,9 @@ static UINT rdpsnd_send_client_audio_formats(rdpsndPlugin* rdpsnd) static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* s) { UINT16 index; - UINT16 wVersion; UINT16 wNumberOfFormats; UINT ret = ERROR_BAD_LENGTH; + WINPR_ASSERT(rdpsnd); audio_formats_free(rdpsnd->ServerFormats, rdpsnd->NumberOfServerFormats); rdpsnd->NumberOfServerFormats = 0; @@ -286,7 +288,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* Stream_Seek_UINT16(s); /* wDGramPort */ Stream_Read_UINT16(s, wNumberOfFormats); Stream_Read_UINT8(s, rdpsnd->cBlockNo); /* cLastBlockConfirmed */ - Stream_Read_UINT16(s, wVersion); /* wVersion */ + Stream_Read_UINT16(s, rdpsnd->wVersion); /* wVersion */ Stream_Seek_UINT8(s); /* bPad */ rdpsnd->NumberOfServerFormats = wNumberOfFormats; @@ -313,7 +315,7 @@ static UINT rdpsnd_recv_server_audio_formats_pdu(rdpsndPlugin* rdpsnd, wStream* if (ret == CHANNEL_RC_OK) { - if (wVersion >= CHANNEL_VERSION_WIN_7) + if (rdpsnd->wVersion >= CHANNEL_VERSION_WIN_7) ret = rdpsnd_send_quality_mode_pdu(rdpsnd); }