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);
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));
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;
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;
"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 {
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");
}
}
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);
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");
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;
}
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;
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));
} else {
GST_WARNING ("Failed to change pin state to %s",
ks_state_to_string (next_state));
+
return FALSE;
}
}
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);
gboolean worker_pending_run;
gboolean worker_run_result;
+ gulong worker_error_code;
+
/* Statistics */
GstClockTime last_sampling;
guint count;
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));
}
} 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);
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)
}
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;
}
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;
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);
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;
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;
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;
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;
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;
}
*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;
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;
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
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;
}
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 *
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);
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);
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);
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;