mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Fixed Device manager: restore gmainloop
The gmainloop is used by gst to detect devices. Fixed bugs on detection of invalid devices.
This commit is contained in:
116
DeviceSource.cpp
116
DeviceSource.cpp
@@ -38,7 +38,7 @@
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define DEVICE_DEBUG
|
||||
//#define GST_DEVICE_DEBUG
|
||||
#define GST_DEVICE_DEBUG
|
||||
#endif
|
||||
|
||||
|
||||
@@ -120,47 +120,20 @@ gboolean
|
||||
Device::callback_device_monitor (GstBus *, GstMessage * message, gpointer )
|
||||
{
|
||||
GstDevice *device;
|
||||
gchar *name;
|
||||
|
||||
switch (GST_MESSAGE_TYPE (message)) {
|
||||
case GST_MESSAGE_DEVICE_ADDED: {
|
||||
case GST_MESSAGE_DEVICE_ADDED:
|
||||
{
|
||||
gst_message_parse_device_added (message, &device);
|
||||
name = gst_device_get_display_name (device);
|
||||
|
||||
// ignore if already in the list
|
||||
if ( std::find(manager().src_name_.begin(), manager().src_name_.end(), name) != manager().src_name_.end())
|
||||
break;
|
||||
|
||||
manager().src_name_.push_back(name);
|
||||
#ifdef GST_DEVICE_DEBUG
|
||||
gchar *stru = gst_structure_to_string( gst_device_get_properties(device) );
|
||||
g_print("\nDevice %s plugged : %s\n", name, stru);
|
||||
g_free (stru);
|
||||
#endif
|
||||
g_free (name);
|
||||
|
||||
std::string p = pipelineForDevice(device, manager().src_description_.size());
|
||||
manager().src_description_.push_back(p);
|
||||
|
||||
DeviceConfigSet confs = getDeviceConfigs(p);
|
||||
manager().src_config_.push_back(confs);
|
||||
|
||||
manager().list_uptodate_ = false;
|
||||
|
||||
manager().add(device);
|
||||
gst_object_unref (device);
|
||||
|
||||
}
|
||||
break;
|
||||
case GST_MESSAGE_DEVICE_REMOVED: {
|
||||
case GST_MESSAGE_DEVICE_REMOVED:
|
||||
{
|
||||
gst_message_parse_device_removed (message, &device);
|
||||
name = gst_device_get_display_name (device);
|
||||
manager().remove(name);
|
||||
#ifdef GST_DEVICE_DEBUG
|
||||
g_print("\nDevice %s unplugged\n", name);
|
||||
#endif
|
||||
g_free (name);
|
||||
|
||||
manager().list_uptodate_ = false;
|
||||
|
||||
manager().remove(device);
|
||||
gst_object_unref (device);
|
||||
}
|
||||
break;
|
||||
@@ -171,18 +144,58 @@ Device::callback_device_monitor (GstBus *, GstMessage * message, gpointer )
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void Device::remove(const char *device)
|
||||
|
||||
void Device::add(GstDevice *device)
|
||||
{
|
||||
if (device==nullptr)
|
||||
return;
|
||||
|
||||
gchar *device_name = gst_device_get_display_name (device);
|
||||
|
||||
if ( std::find(manager().src_name_.begin(), manager().src_name_.end(), device_name) == manager().src_name_.end()) {
|
||||
|
||||
std::string p = pipelineForDevice(device, manager().src_description_.size());
|
||||
DeviceConfigSet confs = getDeviceConfigs(p);
|
||||
|
||||
// add if not in the list and valid
|
||||
if (!p.empty() && !confs.empty()) {
|
||||
src_name_.push_back(device_name);
|
||||
src_description_.push_back(p);
|
||||
src_config_.push_back(confs);
|
||||
#ifdef GST_DEVICE_DEBUG
|
||||
gchar *stru = gst_structure_to_string( gst_device_get_properties(device) );
|
||||
g_print("\nDevice %s plugged : %s\n", device_name, stru);
|
||||
g_free (stru);
|
||||
#endif
|
||||
}
|
||||
list_uptodate_ = false;
|
||||
}
|
||||
g_free (device_name);
|
||||
}
|
||||
|
||||
void Device::remove(GstDevice *device)
|
||||
{
|
||||
if (device==nullptr)
|
||||
return;
|
||||
|
||||
gchar *device_name = gst_device_get_display_name (device);
|
||||
|
||||
std::vector< std::string >::iterator nameit = src_name_.begin();
|
||||
std::vector< std::string >::iterator descit = src_description_.begin();
|
||||
std::vector< DeviceConfigSet >::iterator coit = src_config_.begin();
|
||||
while (nameit != src_name_.end()){
|
||||
|
||||
if ( (*nameit).compare(device) == 0 )
|
||||
if ( (*nameit).compare(device_name) == 0 )
|
||||
{
|
||||
src_name_.erase(nameit);
|
||||
src_description_.erase(descit);
|
||||
src_config_.erase(coit);
|
||||
|
||||
list_uptodate_ = false;
|
||||
|
||||
#ifdef GST_DEVICE_DEBUG
|
||||
g_print("\nDevice %s unplugged\n", device_name);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -190,10 +203,16 @@ void Device::remove(const char *device)
|
||||
++descit;
|
||||
++coit;
|
||||
}
|
||||
g_free (device_name);
|
||||
}
|
||||
|
||||
|
||||
Device::Device()
|
||||
Device::Device(): list_uptodate_(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Device::init()
|
||||
{
|
||||
GstBus *bus;
|
||||
GstCaps *caps;
|
||||
@@ -217,24 +236,9 @@ Device::Device()
|
||||
GList *devices = gst_device_monitor_get_devices(monitor_);
|
||||
GList *tmp;
|
||||
for (tmp = devices; tmp ; tmp = tmp->next ) {
|
||||
|
||||
GstDevice *device = (GstDevice *) tmp->data;
|
||||
|
||||
gchar *name = gst_device_get_display_name (device);
|
||||
src_name_.push_back(name);
|
||||
g_free (name);
|
||||
|
||||
#ifdef GST_DEVICE_DEBUG
|
||||
gchar *stru = gst_structure_to_string( gst_device_get_properties(device) );
|
||||
g_print("\nDevice %s already plugged : %s", name, stru);
|
||||
g_free (stru);
|
||||
#endif
|
||||
|
||||
std::string p = pipelineForDevice(device, src_description_.size());
|
||||
src_description_.push_back(p);
|
||||
|
||||
DeviceConfigSet confs = getDeviceConfigs(p);
|
||||
src_config_.push_back(confs);
|
||||
add(device);
|
||||
gst_object_unref (device);
|
||||
}
|
||||
g_list_free(devices);
|
||||
|
||||
@@ -383,6 +387,7 @@ void DeviceSource::setDevice(const std::string &devicename)
|
||||
Log::Info(" - %s %s %d x %d %.1f fps", (*it).stream.c_str(), (*it).format.c_str(), (*it).width, (*it).height, fps);
|
||||
}
|
||||
#endif
|
||||
if (!confs.empty()) {
|
||||
DeviceConfig best = *confs.rbegin();
|
||||
float fps = static_cast<float>(best.fps_numerator) / static_cast<float>(best.fps_denominator);
|
||||
Log::Info("Device %s selected its optimal config: %s %s %dx%d@%.1ffps", device_.c_str(), best.stream.c_str(), best.format.c_str(), best.width, best.height, fps);
|
||||
@@ -409,6 +414,7 @@ void DeviceSource::setDevice(const std::string &devicename)
|
||||
// open gstreamer
|
||||
stream_->open( pipeline.str(), best.width, best.height);
|
||||
stream_->play(true);
|
||||
}
|
||||
|
||||
// will be ready after init and one frame rendered
|
||||
ready_ = false;
|
||||
|
||||
@@ -100,6 +100,7 @@ public:
|
||||
return _instance;
|
||||
}
|
||||
|
||||
void init();
|
||||
int numDevices () const;
|
||||
std::string name (int index) const;
|
||||
std::string description (int index) const;
|
||||
@@ -116,7 +117,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void remove(const char *device);
|
||||
void remove(GstDevice *device);
|
||||
void add(GstDevice *device);
|
||||
|
||||
std::vector< std::string > src_name_;
|
||||
std::vector< std::string > src_description_;
|
||||
|
||||
@@ -352,10 +352,8 @@ void Rendering::draw()
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
glfwPollEvents();
|
||||
|
||||
#ifndef USE_GST_APPSINK_CALLBACKS
|
||||
// no g_main_loop_run(loop) : update global GMainContext
|
||||
g_main_context_iteration(NULL, FALSE);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
6
main.cpp
6
main.cpp
@@ -30,6 +30,7 @@
|
||||
#include "ControlManager.h"
|
||||
#include "Connection.h"
|
||||
#include "Metronome.h"
|
||||
#include "DeviceSource.h"
|
||||
|
||||
#if defined(APPLE)
|
||||
extern "C"{
|
||||
@@ -120,6 +121,11 @@ int main(int argc, char *argv[])
|
||||
if ( !Rendering::manager().init() )
|
||||
return 1;
|
||||
|
||||
///
|
||||
/// DEVICES INIT
|
||||
///
|
||||
Device::manager().init();
|
||||
|
||||
///
|
||||
/// UI INIT
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user