4

I am trying to query a list of available video capture devices (webcams) on windows using gstreamer 1.0 in c++.

I am using ksvideosrc as source and i am able to capture the video input but i can't query a list of available devices (and their caps).

On gstreamer 0.10 it has been possible through GstPropertyProbe which is removed in gstreamer 1.0. The documentation suggests using GstDeviceMonitor. But i have no luck using that either.

Has anyone succeeded in acquiring a list of device names? Or can you suggests another way of retrieving the available device names and their caps?

3 Answers3

2


You can use GstDeviceMonitor and gst_device_monitor_get_devices () function.

First initialize GstDeviceMonitor by gst_device_monitor_new().
Second start the monitor by gst_device_monitor_start(pMonitor).
Third, get devices list by gst_device_monitor_get_devices(pMonitor).

Code would be like this:

GstDeviceMonitor* monitor= gst_device_monitor_new();
if(!gst_device_monitor_start(monitor)){
    printf("WARNING: Monitor couldn't started!!\n");
}

GList* devices = gst_device_monitor_get_devices(monitor);

My references: https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstDeviceMonitor.html#gst-device-monitor-get-devices

xskxzr
  • 12,442
  • 12
  • 37
  • 77
astarakastara
  • 475
  • 5
  • 17
1

Although I haven't figured out how to enumerate the device names, I've come up with a workaround to at least get the available ksvideosrc device indexes. Below is the code in Python, but you should be able to port it to C++ fairly easily, thanks to the GObject introspection bindings.

from gi.repository import Gst


def get_ksvideosrc_device_indexes():
    device_index = 0
    video_src = Gst.ElementFactory.make('ksvideosrc')
    state_change_code = None

    while True:
        video_src.set_state(Gst.State.NULL)
        video_src.set_property('device-index', device_index)
        state_change_code = video_src.set_state(Gst.State.READY)
        if state_change_code != Gst.StateChangeReturn.SUCCESS:
            video_src.set_state(Gst.State.NULL)
            break
        device_index += 1
    return range(device_index)


if __name__ == '__main__':
    Gst.init()
    print get_ksvideosrc_device_indexes()

Note that the video source device-name property is None as of GStreamer version 1.4.5.0 on Windows for the ksvideosrc.

naitsirhc
  • 5,274
  • 2
  • 23
  • 16
0

It's very late, but for the future...

The Gst.DeviceMonitor can be used to enumerate devices, and register an addition or removal of a device. Here's how to get device names in C# with GStreamer 1.14

static class Devices
{
    public static void Run(string[] args)
    {
        Application.Init(ref args);
        GtkSharp.GstreamerSharp.ObjectManager.Initialize();

        var devmon = new DeviceMonitor();
// to show only cameras     
//            var caps = new Caps("video/x-raw");
//            var filtId = devmon.AddFilter("Video/Source", caps);      
        var bus = devmon.Bus;
        bus.AddWatch(OnBusMessage);
        if (!devmon.Start())
        {
            "Device monitor cannot start".PrintErr();
            return;
        }
        Console.WriteLine("Video devices count = " + devmon.Devices.Length);
        foreach (var dev in devmon.Devices)
            DumpDevice(dev);
        var loop = new GLib.MainLoop();
        loop.Run();
    }

    static void DumpDevice(Device d)
    {
        Console.WriteLine($"{d.DeviceClass} : {d.DisplayName} : {d.Name} ");
    }

    static bool OnBusMessage(Bus bus, Message message)
    {
        switch (message.Type)
        {
            case MessageType.DeviceAdded:
                {
                    var dev = message.ParseDeviceAdded();
                    Console.WriteLine("Device added: ");
                    DumpDevice(dev);
                    break;
                }
            case MessageType.DeviceRemoved:
                {
                    var dev = message.ParseDeviceRemoved();
                    Console.WriteLine("Device removed: ");
                    DumpDevice(dev);
                    break;
                }
        }
        return true;
    }
}