/* Frames the card hasn't rendered yet */
hr = IAudioClient_GetCurrentPadding (self->client, &n_frames_padding);
- HR_FAILED_RET (hr, IAudioClient::GetCurrentPadding, -1);
+ HR_FAILED_ELEMENT_ERROR_RET (hr, IAudioClient::GetCurrentPadding, self, -1);
GST_DEBUG_OBJECT (self, "%i unread frames (padding)", n_frames_padding);
GST_OBJECT_LOCK (self);
if (self->client_needs_restart) {
hr = IAudioClient_Start (self->client);
- HR_FAILED_AND (hr, IAudioClient::Start, GST_OBJECT_UNLOCK (self);
- goto beach);
+ HR_FAILED_ELEMENT_ERROR_AND (hr, IAudioClient::Start, self,
+ GST_OBJECT_UNLOCK (self); goto err);
self->client_needs_restart = FALSE;
}
GST_OBJECT_UNLOCK (self);
if (dwWaitResult != WAIT_OBJECT_0) {
GST_ERROR_OBJECT (self, "Error waiting for event handle: %x",
(guint) dwWaitResult);
- goto beach;
+ goto err;
}
can_frames = gst_wasapi_sink_get_can_frames (self);
+ if (can_frames < 0) {
+ GST_ERROR_OBJECT (self, "Error getting frames to write to");
+ goto err;
+ }
/* In exclusive mode we need to fill the whole buffer in one go or
* GetBuffer will error out */
if (can_frames != have_frames) {
GST_ERROR_OBJECT (self,
"Need at %i frames to write for exclusive mode, but got %i",
can_frames, have_frames);
- written_len = -1;
- goto beach;
+ goto err;
}
} else {
/* In shared mode we can write parts of the buffer, so only wait
* in case we can't write anything */
can_frames = gst_wasapi_sink_get_can_frames (self);
+ if (can_frames < 0) {
+ GST_ERROR_OBJECT (self, "Error getting frames to write to");
+ goto err;
+ }
if (can_frames == 0) {
dwWaitResult = WaitForSingleObject (self->event_handle, INFINITE);
if (dwWaitResult != WAIT_OBJECT_0) {
GST_ERROR_OBJECT (self, "Error waiting for event handle: %x",
(guint) dwWaitResult);
- goto beach;
+ goto err;
}
can_frames = gst_wasapi_sink_get_can_frames (self);
+ if (can_frames < 0) {
+ GST_ERROR_OBJECT (self, "Error getting frames to write to");
+ goto err;
+ }
}
}
hr = IAudioRenderClient_GetBuffer (self->render_client, n_frames,
(BYTE **) & dst);
- HR_FAILED_AND (hr, IAudioRenderClient::GetBuffer, goto beach);
+ HR_FAILED_ELEMENT_ERROR_AND (hr, IAudioRenderClient::GetBuffer, self,
+ goto err);
memcpy (dst, data, write_len);
hr = IAudioRenderClient_ReleaseBuffer (self->render_client, n_frames,
self->mute ? AUDCLNT_BUFFERFLAGS_SILENT : 0);
- HR_FAILED_AND (hr, IAudioRenderClient::ReleaseBuffer, goto beach);
+ HR_FAILED_ELEMENT_ERROR_AND (hr, IAudioRenderClient::ReleaseBuffer, self,
+ goto err);
written_len = write_len;
-beach:
-
+out:
return written_len;
+
+err:
+ written_len = -1;
+ goto out;
}
static guint
GST_OBJECT_LOCK (self);
if (self->client_needs_restart) {
hr = IAudioClient_Start (self->client);
- HR_FAILED_AND (hr, IAudioClient::Start, length = 0; goto beach);
+ HR_FAILED_ELEMENT_ERROR_AND (hr, IAudioClient::Start, self,
+ GST_OBJECT_UNLOCK (self); goto err);
self->client_needs_restart = FALSE;
}
GST_OBJECT_UNLOCK (self);
if (dwWaitResult != WAIT_OBJECT_0) {
GST_ERROR_OBJECT (self, "Error waiting for event handle: %x",
(guint) dwWaitResult);
- length = 0;
- goto beach;
+ goto err;
}
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)
+ if (hr == AUDCLNT_S_BUFFER_EMPTY) {
+ gchar *msg = gst_wasapi_util_hresult_to_string (hr);
GST_WARNING_OBJECT (self, "IAudioCaptureClient::GetBuffer failed: %s"
", retrying", msg);
- else
- GST_ERROR_OBJECT (self, "IAudioCaptureClient::GetBuffer failed: %s",
- msg);
- g_free (msg);
- length = 0;
- goto beach;
+ g_free (msg);
+ length = 0;
+ goto out;
+ }
+ HR_FAILED_ELEMENT_ERROR_AND (hr, IAudioCaptureClient::GetBuffer, self,
+ goto err);
}
if (flags != 0)
/* Always release all captured buffers if we've captured any at all */
hr = IAudioCaptureClient_ReleaseBuffer (self->capture_client, have_frames);
- HR_FAILED_AND (hr, IAudioClock::ReleaseBuffer, goto beach);
+ HR_FAILED_ELEMENT_ERROR_AND (hr, IAudioCaptureClient::ReleaseBuffer, self,
+ goto err);
}
-beach:
-
+out:
return length;
+
+err:
+ length = -1;
+ goto out;
}
static guint
/* Standard error path */
#define HR_FAILED_AND(hr,func,and) \
- do { \
+ G_STMT_START { \
if (FAILED (hr)) { \
gchar *msg = gst_wasapi_util_hresult_to_string (hr); \
GST_ERROR_OBJECT (self, #func " failed (%x): %s", (guint) hr, msg); \
g_free (msg); \
and; \
} \
- } while (0)
+ } G_STMT_END
#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)
+#define HR_FAILED_ELEMENT_ERROR_AND(hr,func,el,and) \
+ G_STMT_START { \
+ if (FAILED (hr)) { \
+ gchar *msg = gst_wasapi_util_hresult_to_string (hr); \
+ GST_ERROR_OBJECT (el, #func " failed (%x): %s", (guint) hr, msg); \
+ if (GST_IS_AUDIO_SRC (el)) \
+ GST_ELEMENT_ERROR(el, RESOURCE, READ, \
+ (#func " failed (%x): %s", (guint) hr, msg), (NULL)); \
+ else \
+ GST_ELEMENT_ERROR(el, RESOURCE, WRITE, \
+ (#func " failed (%x): %s", (guint) hr, msg), (NULL)); \
+ g_free (msg); \
+ and; \
+ } \
+ } G_STMT_END
+
+#define HR_FAILED_ELEMENT_ERROR_RET(hr,func,el,ret) \
+ HR_FAILED_ELEMENT_ERROR_AND(hr,func,el,return ret)
+
+
/* Device role enum property */
typedef enum
{