コード例 #1
0
static void
bus_sync_message (GstBus * bus, GstMessage * message,
                  GstDeviceMonitor * monitor)
{
    GstMessageType type = GST_MESSAGE_TYPE (message);

    if (type == GST_MESSAGE_DEVICE_ADDED || type == GST_MESSAGE_DEVICE_REMOVED) {
        gboolean matches;
        GstDevice *device;
        GstDeviceProvider *provider;

        if (type == GST_MESSAGE_DEVICE_ADDED)
            gst_message_parse_device_added (message, &device);
        else
            gst_message_parse_device_removed (message, &device);

        GST_OBJECT_LOCK (monitor);
        provider =
            GST_DEVICE_PROVIDER (gst_object_get_parent (GST_OBJECT (device)));
        if (is_provider_hidden (monitor, monitor->priv->hidden, provider)) {
            matches = FALSE;
        } else if (monitor->priv->filters->len) {
            guint i;

            for (i = 0; i < monitor->priv->filters->len; i++) {
                struct DeviceFilter *filter =
                    g_ptr_array_index (monitor->priv->filters, i);
                GstCaps *caps;

                caps = gst_device_get_caps (device);
                matches = gst_caps_can_intersect (filter->caps, caps) &&
                          gst_device_has_classesv (device, filter->classesv);
                gst_caps_unref (caps);
                if (matches)
                    break;
            }
        } else {
            matches = TRUE;
        }
        GST_OBJECT_UNLOCK (monitor);

        gst_object_unref (provider);
        gst_object_unref (device);

        if (matches)
            gst_bus_post (monitor->priv->bus, gst_message_ref (message));
    }
}
コード例 #2
0
static void
uevent_cb (GUdevClient * client, const gchar * action, GUdevDevice * device,
    GstV4l2DeviceProvider * self)
{
  GstDeviceProvider *provider = GST_DEVICE_PROVIDER (self);

  /* Not V4L2, ignoring */
  if (g_udev_device_get_property_as_int (device, "ID_V4L_VERSION") != 2)
    return;

  if (!strcmp (action, "add")) {
    GstDevice *gstdev = NULL;

    gstdev = gst_v4l2_device_provider_device_from_udev (self, device);

    if (gstdev)
      gst_device_provider_device_add (provider, gstdev);
  } else if (!strcmp (action, "remove")) {
    GstV4l2Device *gstdev = NULL;
    GList *item;

    GST_OBJECT_LOCK (self);
    for (item = provider->devices; item; item = item->next) {
      gstdev = item->data;

      if (!strcmp (gstdev->syspath, g_udev_device_get_sysfs_path (device))) {
        gst_object_ref (gstdev);
        break;
      }

      gstdev = NULL;
    }
    GST_OBJECT_UNLOCK (provider);

    if (gstdev) {
      gst_device_provider_device_remove (provider, GST_DEVICE (gstdev));
      g_object_unref (gstdev);
    }
  } else {
    GST_WARNING ("Unhandled action %s", action);
  }
}
コード例 #3
0
static gpointer
provider_thread (gpointer data)
{
  GstV4l2DeviceProvider *provider = data;
  GMainContext *context = NULL;
  GMainLoop *loop = NULL;
  GUdevClient *client;
  GList *devices;
  static const gchar *subsystems[] = { "video4linux", NULL };

  GST_OBJECT_LOCK (provider);
  if (provider->context)
    context = g_main_context_ref (provider->context);
  if (provider->loop)
    loop = g_main_loop_ref (provider->loop);

  if (context == NULL || loop == NULL) {
    provider->started = TRUE;
    g_cond_broadcast (&provider->started_cond);
    GST_OBJECT_UNLOCK (provider);
    return NULL;
  }
  GST_OBJECT_UNLOCK (provider);

  g_main_context_push_thread_default (context);

  client = g_udev_client_new (subsystems);

  g_signal_connect (client, "uevent", G_CALLBACK (uevent_cb), provider);

  devices = g_udev_client_query_by_subsystem (client, "video4linux");

  while (devices) {
    GUdevDevice *udev_device = devices->data;
    GstDevice *gstdev;

    devices = g_list_remove (devices, udev_device);

    if (g_udev_device_get_property_as_int (udev_device, "ID_V4L_VERSION") == 2) {
      gstdev =
          gst_v4l2_device_provider_device_from_udev (provider, udev_device);
      if (gstdev)
        gst_device_provider_device_add (GST_DEVICE_PROVIDER (provider), gstdev);
    }

    g_object_unref (udev_device);
  }

  GST_OBJECT_LOCK (provider);
  provider->started = TRUE;
  g_cond_broadcast (&provider->started_cond);
  GST_OBJECT_UNLOCK (provider);

  g_main_loop_run (loop);
  g_main_loop_unref (loop);

  g_object_unref (client);
  g_main_context_unref (context);

  gst_object_unref (provider);

  return NULL;
}