Saves a lot of boilerplate across all files.
/* 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", msg);
- g_free (msg);
- return -1;
- }
+ HR_FAILED_RET (hr, IAudioClient::GetCurrentPadding, -1);
GST_DEBUG_OBJECT (self, "%i unread frames (padding)", n_frames_padding);
hr = IAudioClient_GetDevicePeriod (self->client, &default_period,
&min_period);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::GetDevicePeriod failed");
- return FALSE;
- }
+ HR_FAILED_RET (hr, IAudioClient::GetDevicePeriod, FALSE);
GST_INFO_OBJECT (self, "wasapi default period: %" G_GINT64_FORMAT
", min period: %" G_GINT64_FORMAT, default_period, min_period);
/* Calculate a new aligned period. First get the aligned buffer size. */
hr = IAudioClient_GetBufferSize (self->client, &n_frames);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ELEMENT_ERROR (self, RESOURCE, OPEN_WRITE, (NULL),
- ("IAudioClient::GetBufferSize() failed: %s", msg));
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_RET (hr, IAudioClient::GetBufferSize, FALSE);
device_period = (GST_SECOND / 100) * n_frames / rate;
AUDCLNT_STREAMFLAGS_EVENTCALLBACK, device_period,
device_period, self->mix_format, NULL);
}
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ELEMENT_ERROR (self, RESOURCE, OPEN_WRITE, (NULL),
- ("IAudioClient::Initialize () failed: %s", msg));
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::Initialize, beach);
/* Total size of the allocated buffer that we will write to */
hr = IAudioClient_GetBufferSize (self->client, &self->buffer_frame_count);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::GetBufferSize failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetBufferSize, beach);
+
GST_INFO_OBJECT (self, "buffer size is %i frames, bpf is %i bytes, "
"rate is %i Hz", self->buffer_frame_count, bpf, rate);
/* Get latency for logging */
hr = IAudioClient_GetStreamLatency (self->client, &latency_rt);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::GetStreamLatency failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetStreamLatency, beach);
+
GST_INFO_OBJECT (self, "wasapi stream latency: %" G_GINT64_FORMAT " (%"
G_GINT64_FORMAT "ms)", latency_rt, latency_rt / 10000);
/* Set the event handler which will trigger writes */
hr = IAudioClient_SetEventHandle (self->client, self->event_handle);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::SetEventHandle failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::SetEventHandle, beach);
/* Get render sink client and start it up */
if (!gst_wasapi_util_get_render_client (GST_ELEMENT (self), self->client,
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", msg));
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioRenderClient::GetBuffer, beach);
GST_DEBUG_OBJECT (self, "pre-wrote %i bytes of silence", len);
hr = IAudioRenderClient_ReleaseBuffer (self->render_client, n_frames,
AUDCLNT_BUFFERFLAGS_SILENT);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (self, "IAudioRenderClient::ReleaseBuffer failed: %s",
- msg);
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioRenderClient::ReleaseBuffer, beach);
}
hr = IAudioClient_Start (self->client);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::Start failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::Start, beach);
gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SINK
(self)->ringbuffer, self->positions);
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", msg));
- g_free (msg);
- length = 0;
- goto beach;
- }
+ HR_FAILED_AND (hr, IAudioRenderClient::GetBuffer, length = 0; goto beach);
memcpy (dst, data, write_len);
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",
- msg);
- g_free (msg);
- length = 0;
- goto beach;
- }
+ HR_FAILED_AND (hr, IAudioRenderClient::ReleaseBuffer, length = 0;
+ goto beach);
pending -= write_len;
}
HRESULT hr;
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", msg));
- g_free (msg);
- }
+ HR_FAILED_RET (hr, IAudioClient::GetCurrentPadding, 0);
return delay;
}
GstWasapiSink *self = GST_WASAPI_SINK (asink);
HRESULT hr;
- if (self->client) {
- hr = IAudioClient_Stop (self->client);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (self, "IAudioClient::Stop () failed: %s", msg);
- g_free (msg);
- return;
- }
+ if (!self->client)
+ return;
- hr = IAudioClient_Reset (self->client);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (self, "IAudioClient::Reset () failed: %s", msg);
- g_free (msg);
- return;
- }
- }
+ hr = IAudioClient_Stop (self->client);
+ HR_FAILED_RET (hr, IAudioClient::Stop,);
+
+ hr = IAudioClient_Reset (self->client);
+ HR_FAILED_RET (hr, IAudioClient::Reset,);
}
hr = IAudioClient_GetDevicePeriod (self->client, &default_period,
&min_period);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::GetDevicePeriod failed");
- return FALSE;
- }
+ HR_FAILED_RET (hr, IAudioClient::GetDevicePeriod, FALSE);
+
GST_INFO_OBJECT (self, "wasapi default period: %" G_GINT64_FORMAT
", min period: %" G_GINT64_FORMAT, default_period, min_period);
/* Calculate a new aligned period. First get the aligned buffer size. */
hr = IAudioClient_GetBufferSize (self->client, &n_frames);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ELEMENT_ERROR (self, RESOURCE, OPEN_WRITE, (NULL),
- ("IAudioClient::GetBufferSize() failed: %s", msg));
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetBufferSize, beach);
device_period = (GST_SECOND / 100) * n_frames / rate;
AUDCLNT_STREAMFLAGS_EVENTCALLBACK, device_period,
device_period, 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", msg));
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::Initialize, beach);
/* Total size in frames of the allocated buffer that we will read from */
hr = IAudioClient_GetBufferSize (self->client, &buffer_frames);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::GetBufferSize failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetBufferSize, beach);
GST_INFO_OBJECT (self, "buffer size is %i frames, bpf is %i bytes, "
"rate is %i Hz", buffer_frames, bpf, rate);
/* Get WASAPI latency for logging */
hr = IAudioClient_GetStreamLatency (self->client, &latency_rt);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::GetStreamLatency failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetStreamLatency, beach);
+
GST_INFO_OBJECT (self, "wasapi stream latency: %" G_GINT64_FORMAT " (%"
G_GINT64_FORMAT " ms)", latency_rt, latency_rt / 10000);
/* Set the event handler which will trigger reads */
hr = IAudioClient_SetEventHandle (self->client, self->event_handle);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::SetEventHandle failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::SetEventHandle, beach);
/* Get the clock and the clock freq */
if (!gst_wasapi_util_get_clock (GST_ELEMENT (self), self->client,
- &self->client_clock)) {
+ &self->client_clock))
goto beach;
- }
hr = IAudioClock_GetFrequency (self->client_clock, &self->client_clock_freq);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClock::GetFrequency failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClock::GetFrequency, beach);
/* Get capture source client and start it up */
if (!gst_wasapi_util_get_capture_client (GST_ELEMENT (self), self->client,
}
hr = IAudioClient_Start (self->client);
- if (hr != S_OK) {
- GST_ERROR_OBJECT (self, "IAudioClient::Start failed");
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClock::Start, beach);
gst_audio_ring_buffer_set_channel_positions (GST_AUDIO_BASE_SRC
(self)->ringbuffer, self->positions);
/* 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", msg);
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_AND (hr, IAudioClock::ReleaseBuffer, goto beach);
}
HRESULT hr;
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", msg));
- g_free (msg);
- }
+ HR_FAILED_RET (hr, IAudioClock::GetCurrentPadding, 0);
return delay;
}
GstWasapiSrc *self = GST_WASAPI_SRC (asrc);
HRESULT hr;
- if (self->client) {
- hr = IAudioClient_Stop (self->client);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (self, "IAudioClient::Stop () failed: %s", msg);
- g_free (msg);
- return;
- }
+ if (!self->client)
+ return;
- hr = IAudioClient_Reset (self->client);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (self, "IAudioClient::Reset () failed: %s", msg);
- g_free (msg);
- return;
- }
- }
+ hr = IAudioClient_Stop (self->client);
+ HR_FAILED_RET (hr, IAudioClock::Stop,);
+
+ hr = IAudioClient_Reset (self->client);
+ HR_FAILED_RET (hr, IAudioClock::Reset,);
}
static GstClockTime
return GST_CLOCK_TIME_NONE;
hr = IAudioClock_GetPosition (self->client_clock, &devpos, NULL);
- if (G_UNLIKELY (hr != S_OK))
- return GST_CLOCK_TIME_NONE;
+ HR_FAILED_RET (hr, IAudioClock::GetPosition, GST_CLOCK_TIME_NONE);
result = gst_util_uint64_scale_int (devpos, GST_SECOND,
self->client_clock_freq);
}
static IMMDeviceEnumerator *
-gst_wasapi_util_get_device_enumerator (GstElement * element)
+gst_wasapi_util_get_device_enumerator (GstElement * self)
{
HRESULT hr;
IMMDeviceEnumerator *enumerator = NULL;
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", msg);
- g_free (msg);
- return NULL;
- }
+ HR_FAILED_RET (hr, CoCreateInstance (MMDeviceEnumerator), NULL);
return enumerator;
}
gboolean
-gst_wasapi_util_get_devices (GstElement * element, gboolean active,
+gst_wasapi_util_get_devices (GstElement * self, gboolean active,
GList ** devices)
{
- gboolean ret = FALSE;
+ gboolean res = FALSE;
static GstStaticCaps scaps = GST_STATIC_CAPS (GST_WASAPI_STATIC_CAPS);
DWORD dwStateMask = active ? DEVICE_STATE_ACTIVE : DEVICE_STATEMASK_ALL;
IMMDeviceCollection *device_collection = NULL;
*devices = NULL;
- enumerator = gst_wasapi_util_get_device_enumerator (element);
+ enumerator = gst_wasapi_util_get_device_enumerator (self);
if (!enumerator)
return FALSE;
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", msg);
- g_free (msg);
- goto err;
- }
+ HR_FAILED_GOTO (hr, IMMDeviceEnumerator::EnumAudioEndpoints, err);
hr = IMMDeviceCollection_GetCount (device_collection, &count);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (element, "Failed to count devices: %s", msg);
- g_free (msg);
- goto err;
- }
+ HR_FAILED_GOTO (hr, IMMDeviceCollection::GetCount, err);
/* Create a GList of GstDevices* to return */
for (ii = 0; ii < count; ii++) {
(void **) &client);
if (hr != S_OK) {
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (element, "IMMDevice::Activate (IID_IAudioClient) failed"
+ GST_ERROR_OBJECT (self, "IMMDevice::Activate (IID_IAudioClient) failed"
"on %s: %s", strid, msg);
g_free (msg);
goto next;
g_free (strid);
}
- ret = TRUE;
+ res = TRUE;
err:
if (enumerator)
IUnknown_Release (enumerator);
if (device_collection)
IUnknown_Release (device_collection);
- return ret;
+ return res;
}
gboolean
-gst_wasapi_util_get_device_format (GstElement * element,
+gst_wasapi_util_get_device_format (GstElement * self,
gint device_mode, IMMDevice * device, IAudioClient * client,
WAVEFORMATEX ** ret_format)
{
*ret_format = NULL;
hr = IAudioClient_GetMixFormat (client, &format);
- if (hr != S_OK || format == NULL) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (element, "GetMixFormat failed: %s", msg);
- g_free (msg);
- return FALSE;
- }
+ HR_FAILED_RET (hr, IAudioClient::GetMixFormat, FALSE);
/* WASAPI always accepts the format returned by GetMixFormat in shared mode */
if (device_mode == AUDCLNT_SHAREMODE_SHARED)
IPropertyStore *prop_store = NULL;
hr = IMMDevice_OpenPropertyStore (device, STGM_READ, &prop_store);
- if (hr != S_OK) {
- gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (element, "OpenPropertyStore failed: %s", msg);
- g_free (msg);
- return FALSE;
- }
+ HR_FAILED_RET (hr, IMMDevice::OpenPropertyStore, FALSE);
hr = IPropertyStore_GetValue (prop_store, &PKEY_AudioEngine_DeviceFormat,
&var);
if (hr != S_OK) {
gchar *msg = gst_wasapi_util_hresult_to_string (hr);
- GST_ERROR_OBJECT (element, "GetValue failed: %s", msg);
+ GST_ERROR_OBJECT (self, "GetValue failed: %s", msg);
g_free (msg);
IUnknown_Release (prop_store);
return FALSE;
if (hr == S_OK)
goto out;
- GST_ERROR_OBJECT (element, "AudioEngine DeviceFormat not supported");
+ GST_ERROR_OBJECT (self, "AudioEngine DeviceFormat not supported");
free (format);
return FALSE;
}
gboolean
-gst_wasapi_util_get_device_client (GstElement * element,
+gst_wasapi_util_get_device_client (GstElement * self,
gboolean capture, gint role, const wchar_t * device_strid,
IMMDevice ** ret_device, IAudioClient ** ret_client)
{
IMMDevice *device = NULL;
IAudioClient *client = NULL;
- if (!(enumerator = gst_wasapi_util_get_device_enumerator (element)))
+ if (!(enumerator = gst_wasapi_util_get_device_enumerator (self)))
goto beach;
if (!device_strid) {
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", msg);
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IMMDeviceEnumerator::GetDefaultAudioEndpoint, 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"
+ GST_ERROR_OBJECT (self, "IMMDeviceEnumerator::GetDevice (%S) failed"
": %s", device_strid, msg);
g_free (msg);
goto beach;
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", msg);
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IMMDevice::Activate (IID_IAudioClient), beach);
IUnknown_AddRef (client);
IUnknown_AddRef (device);
}
gboolean
-gst_wasapi_util_get_render_client (GstElement * element, IAudioClient * client,
+gst_wasapi_util_get_render_client (GstElement * self, IAudioClient * client,
IAudioRenderClient ** ret_render_client)
{
gboolean res = FALSE;
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", msg);
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetService, beach);
*ret_render_client = render_client;
res = TRUE;
}
gboolean
-gst_wasapi_util_get_capture_client (GstElement * element, IAudioClient * client,
+gst_wasapi_util_get_capture_client (GstElement * self, IAudioClient * client,
IAudioCaptureClient ** ret_capture_client)
{
gboolean res = FALSE;
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", msg);
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetService, beach);
*ret_capture_client = capture_client;
res = TRUE;
}
gboolean
-gst_wasapi_util_get_clock (GstElement * element, IAudioClient * client,
+gst_wasapi_util_get_clock (GstElement * self, IAudioClient * client,
IAudioClock ** ret_clock)
{
gboolean res = FALSE;
IAudioClock *clock = NULL;
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", msg);
- g_free (msg);
- goto beach;
- }
+ HR_FAILED_GOTO (hr, IAudioClient::GetService, beach);
*ret_clock = clock;
res = TRUE;
"rate = " GST_AUDIO_RATE_RANGE ", " \
"channels = " GST_AUDIO_CHANNELS_RANGE
+/* Standard error path */
+#define HR_FAILED_AND(hr,func,and) \
+ do { \
+ if (hr != S_OK) { \
+ gchar *msg = gst_wasapi_util_hresult_to_string (hr); \
+ GST_ERROR_OBJECT (self, #func " failed: %s", msg); \
+ g_free (msg); \
+ and; \
+ } \
+ } while (0)
+
+#define HR_FAILED_RET(hr,func,ret) HR_FAILED_AND(hr,func,return ret)
+
+#define HR_FAILED_GOTO(hr,func,where) HR_FAILED_AND(hr,func,res = FALSE; goto where)
+
/* Device role enum property */
typedef enum
{