summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorOle André Vadla Ravnås <oravnas@cisco.com>2009-10-12 17:26:15 +0200
committerOle André Vadla Ravnås <oravnas@cisco.com>2010-10-28 17:08:41 +0200
commitd282a1d38066c1615ba6240bfd1e16b00d6b3489 (patch)
treed38048291929c4ad03ccae93962568a1ead0aec8 /sys
parentcddfa50d92d45a9648fcedbc9688a1dc23d759c1 (diff)
winks: improve error-handling
Most important part here is special-casing "device busy" so the application is able to provide better feedback when another application is using the device.
Diffstat (limited to 'sys')
-rw-r--r--sys/winks/gstksclock.c6
-rw-r--r--sys/winks/gstksvideodevice.c20
-rw-r--r--sys/winks/gstksvideodevice.h2
-rw-r--r--sys/winks/gstksvideosrc.c32
-rw-r--r--sys/winks/kshelpers.c78
-rw-r--r--sys/winks/kshelpers.h12
-rw-r--r--sys/winks/ksvideohelpers.c10
7 files changed, 97 insertions, 63 deletions
diff --git a/sys/winks/gstksclock.c b/sys/winks/gstksclock.c
index db1a8a16b..33c3e4d00 100644
--- a/sys/winks/gstksclock.c
+++ b/sys/winks/gstksclock.c
@@ -151,7 +151,7 @@ gst_ks_clock_open (GstKsClock * self)
state = KSSTATE_STOP;
if (!ks_object_set_property (priv->clock_handle, KSPROPSETID_Clock,
- KSPROPERTY_CLOCK_STATE, &state, sizeof (state)))
+ KSPROPERTY_CLOCK_STATE, &state, sizeof (state), NULL))
goto error;
ks_device_list_free (devices);
@@ -193,7 +193,7 @@ gst_ks_clock_set_state_unlocked (GstKsClock * self, KSSTATE state)
ks_state_to_string (priv->state), ks_state_to_string (next_state));
if (ks_object_set_property (priv->clock_handle, KSPROPSETID_Clock,
- KSPROPERTY_CLOCK_STATE, &next_state, sizeof (next_state))) {
+ KSPROPERTY_CLOCK_STATE, &next_state, sizeof (next_state), NULL)) {
priv->state = next_state;
GST_DEBUG ("Changed clock state to %s", ks_state_to_string (priv->state));
@@ -298,7 +298,7 @@ gst_ks_clock_worker_thread_func (gpointer data)
now /= 100;
if (ks_object_set_property (priv->clock_handle, KSPROPSETID_Clock,
- KSPROPERTY_CLOCK_TIME, &now, sizeof (now))) {
+ KSPROPERTY_CLOCK_TIME, &now, sizeof (now), NULL)) {
GST_DEBUG ("clock synchronized");
gst_object_unref (priv->master_clock);
priv->master_clock = NULL;
diff --git a/sys/winks/gstksvideodevice.c b/sys/winks/gstksvideodevice.c
index 0b95e3d2d..ec094185d 100644
--- a/sys/winks/gstksvideodevice.c
+++ b/sys/winks/gstksvideodevice.c
@@ -556,7 +556,7 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
alignment = 0;
if (ks_object_get_property (pin_handle, KSPROPSETID_Connection,
- KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, &framing_ex, NULL)) {
+ KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, &framing_ex, NULL, NULL)) {
if (framing_ex->CountItems >= 1) {
*num_outstanding = framing_ex->FramingItem[0].Frames;
alignment = framing_ex->FramingItem[0].FileAlignment;
@@ -568,7 +568,8 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
"ALLOCATORFRAMING");
if (ks_object_get_property (pin_handle, KSPROPSETID_Connection,
- KSPROPERTY_CONNECTION_ALLOCATORFRAMING, &framing, &framing_size)) {
+ KSPROPERTY_CONNECTION_ALLOCATORFRAMING, &framing, &framing_size,
+ NULL)) {
*num_outstanding = framing->Frames;
alignment = framing->FileAlignment;
} else {
@@ -597,7 +598,7 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
mem_transport = 0; /* REVISIT: use the constant here */
if (!ks_object_set_property (pin_handle, KSPROPSETID_MemoryTransport,
KSPROPERTY_MEMORY_TRANSPORT, &mem_transport,
- sizeof (mem_transport))) {
+ sizeof (mem_transport), NULL)) {
GST_DEBUG ("failed to set memory transport, sticking with the default");
}
}
@@ -611,7 +612,7 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
if (ks_object_get_property (pin_handle, KSPROPSETID_Stream,
KSPROPERTY_STREAM_MASTERCLOCK, (gpointer *) & cur_clock_handle,
- &cur_clock_handle_size)) {
+ &cur_clock_handle_size, NULL)) {
GST_DEBUG ("current master clock handle: 0x%08x", *cur_clock_handle);
CloseHandle (*cur_clock_handle);
g_free (cur_clock_handle);
@@ -620,7 +621,7 @@ gst_ks_video_device_create_pin (GstKsVideoDevice * self,
if (ks_object_set_property (pin_handle, KSPROPSETID_Stream,
KSPROPERTY_STREAM_MASTERCLOCK, &new_clock_handle,
- sizeof (new_clock_handle))) {
+ sizeof (new_clock_handle), NULL)) {
gst_ks_clock_prepare (priv->clock);
} else {
GST_WARNING ("failed to set pin's master clock");
@@ -660,7 +661,7 @@ gst_ks_video_device_close_current_pin (GstKsVideoDevice * self)
if (!ks_is_valid_handle (priv->pin_handle))
return;
- gst_ks_video_device_set_state (self, KSSTATE_STOP);
+ gst_ks_video_device_set_state (self, KSSTATE_STOP, NULL);
CloseHandle (priv->pin_handle);
priv->pin_handle = INVALID_HANDLE_VALUE;
@@ -801,7 +802,8 @@ same_caps:
}
gboolean
-gst_ks_video_device_set_state (GstKsVideoDevice * self, KSSTATE state)
+gst_ks_video_device_set_state (GstKsVideoDevice * self, KSSTATE state,
+ gulong * error_code)
{
GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self);
KSSTATE initial_state;
@@ -828,7 +830,8 @@ gst_ks_video_device_set_state (GstKsVideoDevice * self, KSSTATE state)
GST_DEBUG ("Changing pin state from %s to %s",
ks_state_to_string (priv->state), ks_state_to_string (next_state));
- if (ks_object_set_connection_state (priv->pin_handle, next_state)) {
+ if (ks_object_set_connection_state (priv->pin_handle, next_state,
+ error_code)) {
priv->state = next_state;
GST_DEBUG ("Changed pin state to %s", ks_state_to_string (priv->state));
@@ -840,6 +843,7 @@ gst_ks_video_device_set_state (GstKsVideoDevice * self, KSSTATE state)
} else {
GST_WARNING ("Failed to change pin state to %s",
ks_state_to_string (next_state));
+
return FALSE;
}
}
diff --git a/sys/winks/gstksvideodevice.h b/sys/winks/gstksvideodevice.h
index 1d110ad36..d830492fc 100644
--- a/sys/winks/gstksvideodevice.h
+++ b/sys/winks/gstksvideodevice.h
@@ -71,7 +71,7 @@ GstCaps * gst_ks_video_device_get_available_caps (GstKsVideoDevice * self);
gboolean gst_ks_video_device_has_caps (GstKsVideoDevice * self);
gboolean gst_ks_video_device_set_caps (GstKsVideoDevice * self, GstCaps * caps);
-gboolean gst_ks_video_device_set_state (GstKsVideoDevice * self, KSSTATE state);
+gboolean gst_ks_video_device_set_state (GstKsVideoDevice * self, KSSTATE state, gulong * error_code);
GstClockTime gst_ks_video_device_get_duration (GstKsVideoDevice * self);
gboolean gst_ks_video_device_get_latency (GstKsVideoDevice * self, GstClockTime * min_latency, GstClockTime * max_latency);
diff --git a/sys/winks/gstksvideosrc.c b/sys/winks/gstksvideosrc.c
index df920a18f..577bef5e6 100644
--- a/sys/winks/gstksvideosrc.c
+++ b/sys/winks/gstksvideosrc.c
@@ -114,6 +114,8 @@ struct _GstKsVideoSrcPrivate
gboolean worker_pending_run;
gboolean worker_run_result;
+ gulong worker_error_code;
+
/* Statistics */
GstClockTime last_sampling;
guint count;
@@ -555,15 +557,15 @@ error_no_devices:
error_no_match:
{
if (priv->device_path != NULL) {
- GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
+ GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
("Specified video capture device with path '%s' not found",
priv->device_path), (NULL));
} else if (priv->device_name != NULL) {
- GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
+ GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
("Specified video capture device with name '%s' not found",
priv->device_name), (NULL));
} else {
- GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS,
+ GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
("Specified video capture device with index %d not found",
priv->device_index), (NULL));
}
@@ -633,8 +635,8 @@ gst_ks_video_src_worker_func (gpointer data)
} else if (priv->worker_pending_run) {
if (priv->ksclock != NULL)
gst_ks_clock_start (priv->ksclock);
- priv->worker_run_result =
- gst_ks_video_device_set_state (priv->device, KSSTATE_RUN);
+ priv->worker_run_result = gst_ks_video_device_set_state (priv->device,
+ KSSTATE_RUN, &priv->worker_error_code);
priv->worker_pending_run = FALSE;
KS_WORKER_NOTIFY_RESULT (priv);
@@ -1014,6 +1016,7 @@ gst_ks_video_src_create (GstPushSrc * pushsrc, GstBuffer ** buf)
while (priv->worker_pending_run)
KS_WORKER_WAIT_FOR_RESULT (priv);
priv->running = priv->worker_run_result;
+ error_code = priv->worker_error_code;
KS_WORKER_UNLOCK (priv);
if (!priv->running)
@@ -1051,9 +1054,22 @@ error_no_caps:
}
error_start_capture:
{
- GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
- ("could not start capture"),
- ("failed to change pin state to KSSTATE_RUN"));
+ const gchar *debug_str = "failed to change pin state to KSSTATE_RUN";
+
+ switch (error_code) {
+ case ERROR_FILE_NOT_FOUND:
+ GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND,
+ ("failed to start capture (device unplugged)"), (debug_str));
+ break;
+ case ERROR_NO_SYSTEM_RESOURCES:
+ GST_ELEMENT_ERROR (self, RESOURCE, BUSY,
+ ("failed to start capture (device already in use)"), (debug_str));
+ break;
+ default:
+ GST_ELEMENT_ERROR (self, RESOURCE, FAILED,
+ ("failed to start capture (0x%08x)", error_code), (debug_str));
+ break;
+ }
return GST_FLOW_ERROR;
}
diff --git a/sys/winks/kshelpers.c b/sys/winks/kshelpers.c
index 0f96dc75e..d170180a4 100644
--- a/sys/winks/kshelpers.c
+++ b/sys/winks/kshelpers.c
@@ -127,7 +127,7 @@ ks_device_list_free (GList * devices)
static gboolean
ks_sync_device_io_control (HANDLE device, gulong io_control_code,
gpointer in_buffer, gulong in_buffer_size, gpointer out_buffer,
- gulong out_buffer_size, gulong * bytes_returned)
+ gulong out_buffer_size, gulong * bytes_returned, gulong * error)
{
OVERLAPPED overlapped = { 0, };
BOOL success;
@@ -136,8 +136,18 @@ ks_sync_device_io_control (HANDLE device, gulong io_control_code,
success = DeviceIoControl (device, io_control_code, in_buffer,
in_buffer_size, out_buffer, out_buffer_size, bytes_returned, &overlapped);
- if (!success && GetLastError () == ERROR_IO_PENDING)
- success = GetOverlappedResult (device, &overlapped, bytes_returned, TRUE);
+ if (!success) {
+ DWORD err;
+
+ if ((err = GetLastError ()) == ERROR_IO_PENDING) {
+ success = GetOverlappedResult (device, &overlapped, bytes_returned, TRUE);
+ if (!success)
+ err = GetLastError ();
+ }
+
+ if (error != NULL)
+ *error = err;
+ }
CloseHandle (overlapped.hEvent);
@@ -146,7 +156,8 @@ ks_sync_device_io_control (HANDLE device, gulong io_control_code,
gboolean
ks_filter_get_pin_property (HANDLE filter_handle, gulong pin_id,
- GUID prop_set, gulong prop_id, gpointer value, gulong value_size)
+ GUID prop_set, gulong prop_id, gpointer value, gulong value_size,
+ gulong * error)
{
KSP_PIN prop = { 0, };
DWORD bytes_returned = 0;
@@ -157,15 +168,16 @@ ks_filter_get_pin_property (HANDLE filter_handle, gulong pin_id,
prop.Property.Flags = KSPROPERTY_TYPE_GET;
return ks_sync_device_io_control (filter_handle, IOCTL_KS_PROPERTY, &prop,
- sizeof (prop), value, value_size, &bytes_returned);
+ sizeof (prop), value, value_size, &bytes_returned, error);
}
gboolean
ks_filter_get_pin_property_multi (HANDLE filter_handle, gulong pin_id,
- GUID prop_set, gulong prop_id, KSMULTIPLE_ITEM ** items)
+ GUID prop_set, gulong prop_id, KSMULTIPLE_ITEM ** items, gulong * error)
{
KSP_PIN prop = { 0, };
DWORD items_size = 0, bytes_written = 0;
+ gulong err;
gboolean ret;
*items = NULL;
@@ -176,23 +188,23 @@ ks_filter_get_pin_property_multi (HANDLE filter_handle, gulong pin_id,
prop.Property.Flags = KSPROPERTY_TYPE_GET;
ret = ks_sync_device_io_control (filter_handle, IOCTL_KS_PROPERTY,
- &prop.Property, sizeof (prop), NULL, 0, &items_size);
- if (!ret) {
- DWORD err = GetLastError ();
- if (err != ERROR_INSUFFICIENT_BUFFER && err != ERROR_MORE_DATA)
- goto error;
- }
+ &prop.Property, sizeof (prop), NULL, 0, &items_size, &err);
+ if (!ret && err != ERROR_INSUFFICIENT_BUFFER && err != ERROR_MORE_DATA)
+ goto ioctl_failed;
*items = g_malloc0 (items_size);
ret = ks_sync_device_io_control (filter_handle, IOCTL_KS_PROPERTY, &prop,
- sizeof (prop), *items, items_size, &bytes_written);
+ sizeof (prop), *items, items_size, &bytes_written, &err);
if (!ret)
- goto error;
+ goto ioctl_failed;
return ret;
-error:
+ioctl_failed:
+ if (error != NULL)
+ *error = err;
+
g_free (*items);
*items = NULL;
@@ -201,10 +213,11 @@ error:
gboolean
ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id,
- gulong prop_flags, gpointer * value, gulong * value_size)
+ gulong prop_flags, gpointer * value, gulong * value_size, gulong * error)
{
KSPROPERTY prop = { 0, };
DWORD req_value_size = 0, bytes_written = 0;
+ gulong err;
gboolean ret;
*value = NULL;
@@ -215,12 +228,9 @@ ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id,
if (value_size == NULL || *value_size == 0) {
ret = ks_sync_device_io_control (handle, IOCTL_KS_PROPERTY,
- &prop, sizeof (prop), NULL, 0, &req_value_size);
- if (!ret) {
- DWORD err = GetLastError ();
- if (err != ERROR_INSUFFICIENT_BUFFER && err != ERROR_MORE_DATA)
- goto error;
- }
+ &prop, sizeof (prop), NULL, 0, &req_value_size, &err);
+ if (!ret && err != ERROR_INSUFFICIENT_BUFFER && err != ERROR_MORE_DATA)
+ goto ioctl_failed;
} else {
req_value_size = *value_size;
}
@@ -228,16 +238,19 @@ ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id,
*value = g_malloc0 (req_value_size);
ret = ks_sync_device_io_control (handle, IOCTL_KS_PROPERTY, &prop,
- sizeof (prop), *value, req_value_size, &bytes_written);
+ sizeof (prop), *value, req_value_size, &bytes_written, &err);
if (!ret)
- goto error;
+ goto ioctl_failed;
if (value_size != NULL)
*value_size = bytes_written;
return ret;
-error:
+ioctl_failed:
+ if (error != NULL)
+ *error = err;
+
g_free (*value);
*value = NULL;
@@ -249,15 +262,15 @@ error:
gboolean
ks_object_get_property (HANDLE handle, GUID prop_set, gulong prop_id,
- gpointer * value, gulong * value_size)
+ gpointer * value, gulong * value_size, gulong * error)
{
return ks_object_query_property (handle, prop_set, prop_id,
- KSPROPERTY_TYPE_GET, value, value_size);
+ KSPROPERTY_TYPE_GET, value, value_size, error);
}
gboolean
ks_object_set_property (HANDLE handle, GUID prop_set, gulong prop_id,
- gpointer value, gulong value_size)
+ gpointer value, gulong value_size, gulong * error)
{
KSPROPERTY prop = { 0, };
DWORD bytes_returned;
@@ -267,7 +280,7 @@ ks_object_set_property (HANDLE handle, GUID prop_set, gulong prop_id,
prop.Flags = KSPROPERTY_TYPE_SET;
return ks_sync_device_io_control (handle, IOCTL_KS_PROPERTY, &prop,
- sizeof (prop), value, value_size, &bytes_returned);
+ sizeof (prop), value, value_size, &bytes_returned, error);
}
gboolean
@@ -275,12 +288,13 @@ ks_object_get_supported_property_sets (HANDLE handle, GUID ** propsets,
gulong * len)
{
gulong size = 0;
+ gulong error;
*propsets = NULL;
*len = 0;
if (ks_object_query_property (handle, GUID_NULL, 0,
- KSPROPERTY_TYPE_SETSUPPORT, propsets, &size)) {
+ KSPROPERTY_TYPE_SETSUPPORT, propsets, &size, &error)) {
if (size % sizeof (GUID) == 0) {
*len = size / sizeof (GUID);
return TRUE;
@@ -294,10 +308,10 @@ ks_object_get_supported_property_sets (HANDLE handle, GUID ** propsets,
}
gboolean
-ks_object_set_connection_state (HANDLE handle, KSSTATE state)
+ks_object_set_connection_state (HANDLE handle, KSSTATE state, gulong * error)
{
return ks_object_set_property (handle, KSPROPSETID_Connection,
- KSPROPERTY_CONNECTION_STATE, &state, sizeof (state));
+ KSPROPERTY_CONNECTION_STATE, &state, sizeof (state), error);
}
gchar *
diff --git a/sys/winks/kshelpers.h b/sys/winks/kshelpers.h
index a233722e8..b84fcde36 100644
--- a/sys/winks/kshelpers.h
+++ b/sys/winks/kshelpers.h
@@ -41,16 +41,16 @@ GList * ks_enumerate_devices (const GUID * category);
void ks_device_entry_free (KsDeviceEntry * entry);
void ks_device_list_free (GList * devices);
-gboolean ks_filter_get_pin_property (HANDLE filter_handle, gulong pin_id, GUID prop_set, gulong prop_id, gpointer value, gulong value_size);
-gboolean ks_filter_get_pin_property_multi (HANDLE filter_handle, gulong pin_id, GUID prop_set, gulong prop_id, KSMULTIPLE_ITEM ** items);
+gboolean ks_filter_get_pin_property (HANDLE filter_handle, gulong pin_id, GUID prop_set, gulong prop_id, gpointer value, gulong value_size, gulong * error);
+gboolean ks_filter_get_pin_property_multi (HANDLE filter_handle, gulong pin_id, GUID prop_set, gulong prop_id, KSMULTIPLE_ITEM ** items, gulong * error);
-gboolean ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id, gulong prop_flags, gpointer * value, gulong * value_size);
-gboolean ks_object_get_property (HANDLE handle, GUID prop_set, gulong prop_id, gpointer * value, gulong * value_size);
-gboolean ks_object_set_property (HANDLE handle, GUID prop_set, gulong prop_id, gpointer value, gulong value_size);
+gboolean ks_object_query_property (HANDLE handle, GUID prop_set, gulong prop_id, gulong prop_flags, gpointer * value, gulong * value_size, gulong * error);
+gboolean ks_object_get_property (HANDLE handle, GUID prop_set, gulong prop_id, gpointer * value, gulong * value_size, gulong * error);
+gboolean ks_object_set_property (HANDLE handle, GUID prop_set, gulong prop_id, gpointer value, gulong value_size, gulong * error);
gboolean ks_object_get_supported_property_sets (HANDLE handle, GUID ** propsets, gulong * len);
-gboolean ks_object_set_connection_state (HANDLE handle, KSSTATE state);
+gboolean ks_object_set_connection_state (HANDLE handle, KSSTATE state, gulong * error);
gchar * ks_guid_to_string (const GUID * guid);
const gchar * ks_state_to_string (KSSTATE state);
diff --git a/sys/winks/ksvideohelpers.c b/sys/winks/ksvideohelpers.c
index e93f71b1d..69b4311b2 100644
--- a/sys/winks/ksvideohelpers.c
+++ b/sys/winks/ksvideohelpers.c
@@ -427,7 +427,7 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
guint pin_id;
if (!ks_filter_get_pin_property (filter_handle, 0, KSPROPSETID_Pin,
- KSPROPERTY_PIN_CTYPES, &pin_count, sizeof (pin_count)))
+ KSPROPERTY_PIN_CTYPES, &pin_count, sizeof (pin_count), NULL))
goto beach;
GST_DEBUG ("pin_count = %d", pin_count);
@@ -438,15 +438,15 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
GUID pin_cat;
if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin,
- KSPROPERTY_PIN_COMMUNICATION, &pin_comm, sizeof (pin_comm)))
+ KSPROPERTY_PIN_COMMUNICATION, &pin_comm, sizeof (pin_comm), NULL))
continue;
if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin,
- KSPROPERTY_PIN_DATAFLOW, &pin_flow, sizeof (pin_flow)))
+ KSPROPERTY_PIN_DATAFLOW, &pin_flow, sizeof (pin_flow), NULL))
continue;
if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin,
- KSPROPERTY_PIN_CATEGORY, &pin_cat, sizeof (pin_cat)))
+ KSPROPERTY_PIN_CATEGORY, &pin_cat, sizeof (pin_cat), NULL))
continue;
GST_DEBUG ("pin[%u]: pin_comm=%d, pin_flow=%d", pin_id, pin_comm, pin_flow);
@@ -456,7 +456,7 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
KSMULTIPLE_ITEM *items;
if (ks_filter_get_pin_property_multi (filter_handle, pin_id,
- KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &items)) {
+ KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &items, NULL)) {
KSDATARANGE *range = (KSDATARANGE *) (items + 1);
guint i;