mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 14:06:23 +00:00
wasapi: Cover more HRESULT error messages
This requires using allocated strings, but it's the best option. For instance, a call could fail because CoInitialize() wasn't called, or because some other thing in the stack failed. https://bugzilla.gnome.org/show_bug.cgi?id=793289
This commit is contained in:
parent
62b6224e37
commit
624de04fdb
4 changed files with 115 additions and 50 deletions
|
@ -410,9 +410,10 @@ gst_wasapi_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
|
|||
self->mix_format, NULL);
|
||||
}
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL),
|
||||
("IAudioClient::Initialize () failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr)));
|
||||
("IAudioClient::Initialize () failed: %s", msg));
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
|
@ -538,8 +539,10 @@ gst_wasapi_sink_write (GstAudioSink * asink, gpointer data, guint length)
|
|||
/* Frames the card hasn't rendered yet */
|
||||
hr = IAudioClient_GetCurrentPadding (self->client, &n_frames_padding);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::GetCurrentPadding failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
msg);
|
||||
g_free (msg);
|
||||
length = 0;
|
||||
goto beach;
|
||||
}
|
||||
|
@ -562,9 +565,10 @@ gst_wasapi_sink_write (GstAudioSink * asink, gpointer data, guint length)
|
|||
hr = IAudioRenderClient_GetBuffer (self->render_client, n_frames,
|
||||
(BYTE **) & dst);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, WRITE, (NULL),
|
||||
("IAudioRenderClient::GetBuffer failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr)));
|
||||
("IAudioRenderClient::GetBuffer failed: %s", msg));
|
||||
g_free (msg);
|
||||
length = 0;
|
||||
goto beach;
|
||||
}
|
||||
|
@ -574,8 +578,10 @@ gst_wasapi_sink_write (GstAudioSink * asink, gpointer data, guint length)
|
|||
hr = IAudioRenderClient_ReleaseBuffer (self->render_client, n_frames,
|
||||
self->mute ? AUDCLNT_BUFFERFLAGS_SILENT : 0);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (self, "IAudioRenderClient::ReleaseBuffer failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
msg);
|
||||
g_free (msg);
|
||||
length = 0;
|
||||
goto beach;
|
||||
}
|
||||
|
@ -597,9 +603,10 @@ gst_wasapi_sink_delay (GstAudioSink * asink)
|
|||
|
||||
hr = IAudioClient_GetCurrentPadding (self->client, &delay);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, READ, (NULL),
|
||||
("IAudioClient::GetCurrentPadding failed %s",
|
||||
gst_wasapi_util_hresult_to_string (hr)));
|
||||
("IAudioClient::GetCurrentPadding failed %s", msg));
|
||||
g_free (msg);
|
||||
}
|
||||
|
||||
return delay;
|
||||
|
@ -614,15 +621,17 @@ gst_wasapi_sink_reset (GstAudioSink * asink)
|
|||
if (self->client) {
|
||||
hr = IAudioClient_Stop (self->client);
|
||||
if (hr != S_OK) {
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Stop () failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Stop () failed: %s", msg);
|
||||
g_free (msg);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IAudioClient_Reset (self->client);
|
||||
if (hr != S_OK) {
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Reset () failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Reset () failed: %s", msg);
|
||||
g_free (msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,9 +405,10 @@ gst_wasapi_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
|
|||
self->mix_format, NULL);
|
||||
}
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ, (NULL),
|
||||
("IAudioClient::Initialize () failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr)));
|
||||
("IAudioClient::Initialize () failed: %s", msg));
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
|
@ -553,12 +554,14 @@ gst_wasapi_src_read (GstAudioSrc * asrc, gpointer data, guint length,
|
|||
hr = IAudioCaptureClient_GetBuffer (self->capture_client,
|
||||
(BYTE **) & from, &have_frames, &flags, NULL, NULL);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
if (hr == AUDCLNT_S_BUFFER_EMPTY)
|
||||
GST_WARNING_OBJECT (self, "IAudioCaptureClient::GetBuffer failed: %s"
|
||||
", retrying", gst_wasapi_util_hresult_to_string (hr));
|
||||
", retrying", msg);
|
||||
else
|
||||
GST_ERROR_OBJECT (self, "IAudioCaptureClient::GetBuffer failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
msg);
|
||||
g_free (msg);
|
||||
length = 0;
|
||||
goto beach;
|
||||
}
|
||||
|
@ -598,9 +601,10 @@ gst_wasapi_src_read (GstAudioSrc * asrc, gpointer data, guint length,
|
|||
/* Always release all captured buffers if we've captured any at all */
|
||||
hr = IAudioCaptureClient_ReleaseBuffer (self->capture_client, have_frames);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (self,
|
||||
"IAudioCaptureClient::ReleaseBuffer () failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
"IAudioCaptureClient::ReleaseBuffer () failed: %s", msg);
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
@ -620,9 +624,10 @@ gst_wasapi_src_delay (GstAudioSrc * asrc)
|
|||
|
||||
hr = IAudioClient_GetCurrentPadding (self->client, &delay);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ELEMENT_ERROR (self, RESOURCE, READ, (NULL),
|
||||
("IAudioClient::GetCurrentPadding failed %s",
|
||||
gst_wasapi_util_hresult_to_string (hr)));
|
||||
("IAudioClient::GetCurrentPadding failed %s", msg));
|
||||
g_free (msg);
|
||||
}
|
||||
|
||||
return delay;
|
||||
|
@ -637,15 +642,17 @@ gst_wasapi_src_reset (GstAudioSrc * asrc)
|
|||
if (self->client) {
|
||||
hr = IAudioClient_Stop (self->client);
|
||||
if (hr != S_OK) {
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Stop () failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Stop () failed: %s", msg);
|
||||
g_free (msg);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IAudioClient_Reset (self->client);
|
||||
if (hr != S_OK) {
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Reset () failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (self, "IAudioClient::Reset () failed: %s", msg);
|
||||
g_free (msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,8 +160,8 @@ gst_wasapi_erole_to_device_role (gint erole)
|
|||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gst_wasapi_util_hresult_to_string (HRESULT hr)
|
||||
static const gchar *
|
||||
hresult_to_string_fallback (HRESULT hr)
|
||||
{
|
||||
const gchar *s = "unknown error";
|
||||
|
||||
|
@ -247,6 +247,9 @@ gst_wasapi_util_hresult_to_string (HRESULT hr)
|
|||
case AUDCLNT_S_POSITION_STALLED:
|
||||
s = "AUDCLNT_S_POSITION_STALLED";
|
||||
break;
|
||||
case E_POINTER:
|
||||
s = "E_POINTER";
|
||||
break;
|
||||
case E_INVALIDARG:
|
||||
s = "E_INVALIDARG";
|
||||
break;
|
||||
|
@ -255,6 +258,33 @@ gst_wasapi_util_hresult_to_string (HRESULT hr)
|
|||
return s;
|
||||
}
|
||||
|
||||
gchar *
|
||||
gst_wasapi_util_hresult_to_string (HRESULT hr)
|
||||
{
|
||||
DWORD flags;
|
||||
gchar *ret_text;
|
||||
LPTSTR error_text = NULL;
|
||||
|
||||
flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||
| FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||
FormatMessage (flags, NULL, hr, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) & error_text, 0, NULL);
|
||||
|
||||
/* If we couldn't get the error msg, try the fallback switch statement */
|
||||
if (error_text == NULL)
|
||||
return g_strdup (hresult_to_string_fallback (hr));
|
||||
|
||||
#ifdef UNICODE
|
||||
/* If UNICODE is defined, LPTSTR is LPWSTR which is UTF-16 */
|
||||
ret_text = g_utf16_to_utf8 (error_text, 0, NULL, NULL, NULL);
|
||||
#else
|
||||
ret_text = g_strdup (error_text);
|
||||
#endif
|
||||
|
||||
LocalFree (error_text);
|
||||
return ret_text;
|
||||
}
|
||||
|
||||
static IMMDeviceEnumerator *
|
||||
gst_wasapi_util_get_device_enumerator (GstElement * element)
|
||||
{
|
||||
|
@ -264,8 +294,10 @@ gst_wasapi_util_get_device_enumerator (GstElement * element)
|
|||
hr = CoCreateInstance (&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||
&IID_IMMDeviceEnumerator, (void **) &enumerator);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "CoCreateInstance (MMDeviceEnumerator) failed"
|
||||
": %s", gst_wasapi_util_hresult_to_string (hr));
|
||||
": %s", msg);
|
||||
g_free (msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -294,15 +326,18 @@ gst_wasapi_util_get_devices (GstElement * element, gboolean active,
|
|||
hr = IMMDeviceEnumerator_EnumAudioEndpoints (enumerator, eAll, dwStateMask,
|
||||
&device_collection);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "IMMDeviceEnumerator::EnumAudioEndpoints "
|
||||
"failed: %s", gst_wasapi_util_hresult_to_string (hr));
|
||||
"failed: %s", msg);
|
||||
g_free (msg);
|
||||
goto err;
|
||||
}
|
||||
|
||||
hr = IMMDeviceCollection_GetCount (device_collection, &count);
|
||||
if (hr != S_OK) {
|
||||
GST_ERROR_OBJECT (element, "Failed to count devices: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "Failed to count devices: %s", msg);
|
||||
g_free (msg);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -368,15 +403,18 @@ gst_wasapi_util_get_devices (GstElement * element, gboolean active,
|
|||
hr = IMMDevice_Activate (item, &IID_IAudioClient, CLSCTX_ALL, NULL,
|
||||
(void **) &client);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "IMMDevice::Activate (IID_IAudioClient) failed"
|
||||
"on %s: %s", strid, gst_wasapi_util_hresult_to_string (hr));
|
||||
"on %s: %s", strid, msg);
|
||||
g_free (msg);
|
||||
goto next;
|
||||
}
|
||||
|
||||
hr = IAudioClient_GetMixFormat (client, &format);
|
||||
if (hr != S_OK || format == NULL) {
|
||||
GST_ERROR_OBJECT ("GetMixFormat failed on %s: %s", strid,
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT ("GetMixFormat failed on %s: %s", strid, msg);
|
||||
g_free (msg);
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
@ -437,8 +475,9 @@ gst_wasapi_util_get_device_format (GstElement * element,
|
|||
|
||||
hr = IAudioClient_GetMixFormat (client, &format);
|
||||
if (hr != S_OK || format == NULL) {
|
||||
GST_ERROR_OBJECT (element, "GetMixFormat failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "GetMixFormat failed: %s", msg);
|
||||
g_free (msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -462,16 +501,18 @@ gst_wasapi_util_get_device_format (GstElement * element,
|
|||
|
||||
hr = IMMDevice_OpenPropertyStore (device, STGM_READ, &prop_store);
|
||||
if (hr != S_OK) {
|
||||
GST_ERROR_OBJECT (element, "OpenPropertyStore failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "OpenPropertyStore failed: %s", msg);
|
||||
g_free (msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hr = IPropertyStore_GetValue (prop_store, &PKEY_AudioEngine_DeviceFormat,
|
||||
&var);
|
||||
if (hr != S_OK) {
|
||||
GST_ERROR_OBJECT (element, "GetValue failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "GetValue failed: %s", msg);
|
||||
g_free (msg);
|
||||
IUnknown_Release (prop_store);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -516,16 +557,19 @@ gst_wasapi_util_get_device_client (GstElement * element,
|
|||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint (enumerator,
|
||||
capture ? eCapture : eRender, role, &device);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element,
|
||||
"IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
"IMMDeviceEnumerator::GetDefaultAudioEndpoint failed: %s", msg);
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
} else {
|
||||
hr = IMMDeviceEnumerator_GetDevice (enumerator, device_strid, &device);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "IMMDeviceEnumerator::GetDevice (%S) failed"
|
||||
": %s", device_strid, gst_wasapi_util_hresult_to_string (hr));
|
||||
": %s", device_strid, msg);
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
@ -533,8 +577,10 @@ gst_wasapi_util_get_device_client (GstElement * element,
|
|||
hr = IMMDevice_Activate (device, &IID_IAudioClient, CLSCTX_ALL, NULL,
|
||||
(void **) &client);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element, "IMMDevice::Activate (IID_IAudioClient) failed"
|
||||
": %s", gst_wasapi_util_hresult_to_string (hr));
|
||||
": %s", msg);
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
|
@ -569,9 +615,10 @@ gst_wasapi_util_get_render_client (GstElement * element, IAudioClient * client,
|
|||
hr = IAudioClient_GetService (client, &IID_IAudioRenderClient,
|
||||
(void **) &render_client);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element,
|
||||
"IAudioClient::GetService (IID_IAudioRenderClient) failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
"IAudioClient::GetService (IID_IAudioRenderClient) failed: %s", msg);
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
|
@ -593,9 +640,10 @@ gst_wasapi_util_get_capture_client (GstElement * element, IAudioClient * client,
|
|||
hr = IAudioClient_GetService (client, &IID_IAudioCaptureClient,
|
||||
(void **) &capture_client);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element,
|
||||
"IAudioClient::GetService (IID_IAudioCaptureClient) failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
"IAudioClient::GetService (IID_IAudioCaptureClient) failed: %s", msg);
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
|
@ -616,9 +664,10 @@ gst_wasapi_util_get_clock (GstElement * element, IAudioClient * client,
|
|||
|
||||
hr = IAudioClient_GetService (client, &IID_IAudioClock, (void **) &clock);
|
||||
if (hr != S_OK) {
|
||||
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
|
||||
GST_ERROR_OBJECT (element,
|
||||
"IAudioClient::GetService (IID_IAudioClock) failed: %s",
|
||||
gst_wasapi_util_hresult_to_string (hr));
|
||||
"IAudioClient::GetService (IID_IAudioClock) failed: %s", msg);
|
||||
g_free (msg);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ gint gst_wasapi_device_role_to_erole (gint role);
|
|||
|
||||
gint gst_wasapi_erole_to_device_role (gint erole);
|
||||
|
||||
const gchar *gst_wasapi_util_hresult_to_string (HRESULT hr);
|
||||
gchar *gst_wasapi_util_hresult_to_string (HRESULT hr);
|
||||
|
||||
gboolean gst_wasapi_util_get_devices (GstElement * element, gboolean active,
|
||||
GList ** devices);
|
||||
|
|
Loading…
Reference in a new issue