GStreamerCaptureDeviceManager.cpp [plain text]
#include "config.h"
#if ENABLE(MEDIA_STREAM) && USE(GSTREAMER)
#include "GStreamerCaptureDeviceManager.h"
#include "GStreamerCommon.h"
namespace WebCore {
GStreamerAudioCaptureDeviceManager& GStreamerAudioCaptureDeviceManager::singleton()
{
static NeverDestroyed<GStreamerAudioCaptureDeviceManager> manager;
return manager;
}
GStreamerVideoCaptureDeviceManager& GStreamerVideoCaptureDeviceManager::singleton()
{
static NeverDestroyed<GStreamerVideoCaptureDeviceManager> manager;
return manager;
}
GStreamerDisplayCaptureDeviceManager& GStreamerDisplayCaptureDeviceManager::singleton()
{
static NeverDestroyed<GStreamerDisplayCaptureDeviceManager> manager;
return manager;
}
std::optional<GStreamerCaptureDevice> GStreamerCaptureDeviceManager::gstreamerDeviceWithUID(const String& deviceID)
{
captureDevices();
for (auto& device : m_gstreamerDevices) {
if (device.persistentId() == deviceID)
return device;
}
return std::nullopt;
}
const Vector<CaptureDevice>& GStreamerCaptureDeviceManager::captureDevices()
{
initializeGStreamer();
if (m_devices.isEmpty())
refreshCaptureDevices();
return m_devices;
}
void GStreamerCaptureDeviceManager::deviceAdded(GRefPtr<GstDevice>&& device)
{
GUniquePtr<GstStructure> properties(gst_device_get_properties(device.get()));
const char* klass = gst_structure_get_string(properties.get(), "device.class");
if (klass && !g_strcmp0(klass, "monitor"))
return;
CaptureDevice::DeviceType type = deviceType();
GUniquePtr<char> deviceClassChar(gst_device_get_device_class(device.get()));
String deviceClass(String(deviceClassChar.get()));
if (type == CaptureDevice::DeviceType::Microphone && !deviceClass.startsWith("Audio"))
return;
if (type == CaptureDevice::DeviceType::Camera && !deviceClass.startsWith("Video"))
return;
GUniquePtr<char> deviceName(gst_device_get_display_name(device.get()));
String identifier = String::fromUTF8(deviceName.get());
auto gstCaptureDevice = GStreamerCaptureDevice(WTFMove(device), identifier, type, identifier);
gstCaptureDevice.setEnabled(true);
m_gstreamerDevices.append(WTFMove(gstCaptureDevice));
auto captureDevice = CaptureDevice(identifier, type, identifier);
captureDevice.setEnabled(true);
m_devices.append(WTFMove(captureDevice));
}
void GStreamerCaptureDeviceManager::refreshCaptureDevices()
{
if (!m_deviceMonitor) {
m_deviceMonitor = adoptGRef(gst_device_monitor_new());
CaptureDevice::DeviceType type = deviceType();
if (type == CaptureDevice::DeviceType::Camera) {
GRefPtr<GstCaps> caps = adoptGRef(gst_caps_new_empty_simple("video/x-raw"));
gst_device_monitor_add_filter(m_deviceMonitor.get(), "Video/Source", caps.get());
} else if (type == CaptureDevice::DeviceType::Microphone) {
GRefPtr<GstCaps> caps = adoptGRef(gst_caps_new_empty_simple("audio/x-raw"));
gst_device_monitor_add_filter(m_deviceMonitor.get(), "Audio/Source", caps.get());
}
}
if (!gst_device_monitor_start(m_deviceMonitor.get())) {
GST_WARNING_OBJECT(m_deviceMonitor.get(), "Could not start device monitor");
m_deviceMonitor = nullptr;
return;
}
GList* devices = gst_device_monitor_get_devices(m_deviceMonitor.get());
while (devices) {
GRefPtr<GstDevice> device = adoptGRef(GST_DEVICE_CAST(devices->data));
deviceAdded(WTFMove(device));
devices = g_list_delete_link(devices, devices);
}
gst_device_monitor_stop(m_deviceMonitor.get());
}
}
#endif // ENABLE(MEDIA_STREAM) && USE(GSTREAMER)