mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-06 16:00:00 +01:00
Cleanup DeviceSource and PatternSource (no feature change)
This commit is contained in:
125
DeviceSource.cpp
125
DeviceSource.cpp
@@ -29,17 +29,20 @@ Device::callback_device_monitor (GstBus * bus, GstMessage * message, gpointer us
|
||||
case GST_MESSAGE_DEVICE_ADDED: {
|
||||
gst_message_parse_device_added (message, &device);
|
||||
name = gst_device_get_display_name (device);
|
||||
manager().names_.push_back(name);
|
||||
manager().src_name_.push_back(name);
|
||||
g_free (name);
|
||||
|
||||
std::ostringstream pipe;
|
||||
pipe << gst_structure_get_string(gst_device_get_properties(device), "device.api");
|
||||
pipe << "src name=devsrc device=";
|
||||
pipe << gst_structure_get_string(gst_device_get_properties(device), "device.path");
|
||||
manager().pipelines_.push_back(pipe.str());
|
||||
manager().src_description_.push_back(pipe.str());
|
||||
|
||||
stru = gst_structure_to_string( gst_device_get_properties(device) );
|
||||
g_print("New device %s \n", stru);
|
||||
DeviceConfigSet confs = getDeviceConfigs(pipe.str());
|
||||
manager().src_config_.push_back(confs);
|
||||
|
||||
// stru = gst_structure_to_string( gst_device_get_properties(device) );
|
||||
// g_print("New device %s \n", stru);
|
||||
|
||||
gst_object_unref (device);
|
||||
}
|
||||
@@ -48,7 +51,7 @@ Device::callback_device_monitor (GstBus * bus, GstMessage * message, gpointer us
|
||||
gst_message_parse_device_removed (message, &device);
|
||||
name = gst_device_get_display_name (device);
|
||||
manager().remove(name);
|
||||
g_print("Device removed: %s\n", name);
|
||||
// g_print("Device removed: %s\n", name);
|
||||
g_free (name);
|
||||
|
||||
gst_object_unref (device);
|
||||
@@ -63,19 +66,22 @@ Device::callback_device_monitor (GstBus * bus, GstMessage * message, gpointer us
|
||||
|
||||
void Device::remove(const char *device)
|
||||
{
|
||||
std::vector< std::string >::iterator nameit = names_.begin();
|
||||
std::vector< std::string >::iterator pipeit = pipelines_.begin();
|
||||
while (nameit != names_.end()){
|
||||
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 )
|
||||
{
|
||||
names_.erase(nameit);
|
||||
pipelines_.erase(pipeit);
|
||||
src_name_.erase(nameit);
|
||||
src_description_.erase(descit);
|
||||
src_config_.erase(coit);
|
||||
break;
|
||||
}
|
||||
|
||||
nameit++;
|
||||
pipeit++;
|
||||
descit++;
|
||||
coit++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,15 +113,17 @@ Device::Device()
|
||||
GstDevice *device = (GstDevice *) tmp->data;
|
||||
|
||||
gchar *name = gst_device_get_display_name (device);
|
||||
names_.push_back(name);
|
||||
src_name_.push_back(name);
|
||||
g_free (name);
|
||||
|
||||
std::ostringstream pipe;
|
||||
pipe << gst_structure_get_string(gst_device_get_properties(device), "device.api");
|
||||
pipe << "src name=devsrc device=";
|
||||
pipe << gst_structure_get_string(gst_device_get_properties(device), "device.path");
|
||||
pipelines_.push_back(pipe.str());
|
||||
src_description_.push_back(pipe.str());
|
||||
|
||||
DeviceConfigSet confs = getDeviceConfigs(pipe.str());
|
||||
src_config_.push_back(confs);
|
||||
}
|
||||
g_list_free(devices);
|
||||
|
||||
@@ -124,41 +132,47 @@ Device::Device()
|
||||
|
||||
int Device::numDevices() const
|
||||
{
|
||||
return names_.size();
|
||||
return src_name_.size();
|
||||
}
|
||||
|
||||
bool Device::exists(const std::string &device) const
|
||||
{
|
||||
std::vector< std::string >::const_iterator d = std::find(names_.begin(), names_.end(), device);
|
||||
return d != names_.end();
|
||||
std::vector< std::string >::const_iterator d = std::find(src_name_.begin(), src_name_.end(), device);
|
||||
return d != src_name_.end();
|
||||
}
|
||||
|
||||
std::string Device::name(int index) const
|
||||
{
|
||||
if (index > -1 && index < names_.size())
|
||||
return names_[index];
|
||||
if (index > -1 && index < src_name_.size())
|
||||
return src_name_[index];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Device::pipeline(int index) const
|
||||
std::string Device::description(int index) const
|
||||
{
|
||||
if (index > -1 && index < pipelines_.size())
|
||||
return pipelines_[index];
|
||||
if (index > -1 && index < src_description_.size())
|
||||
return src_description_[index];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Device::pipeline(const std::string &device) const
|
||||
DeviceConfigSet Device::config(int index) const
|
||||
{
|
||||
std::string pip = "";
|
||||
std::vector< std::string >::const_iterator p = std::find(names_.begin(), names_.end(), device);
|
||||
if (p != names_.end())
|
||||
{
|
||||
int index = std::distance(names_.begin(), p);
|
||||
pip = pipelines_[index];
|
||||
}
|
||||
return pip;
|
||||
if (index > -1 && index < src_config_.size())
|
||||
return src_config_[index];
|
||||
else
|
||||
return DeviceConfigSet();
|
||||
}
|
||||
|
||||
int Device::index(const std::string &device) const
|
||||
{
|
||||
int i = -1;
|
||||
std::vector< std::string >::const_iterator p = std::find(src_name_.begin(), src_name_.end(), device);
|
||||
if (p != src_name_.end())
|
||||
i = std::distance(src_name_.begin(), p);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@@ -187,28 +201,35 @@ void DeviceSource::setDevice(const std::string &devicename)
|
||||
device_ = devicename;
|
||||
Log::Notify("Creating Source with device '%s'", device_.c_str());
|
||||
|
||||
std::ostringstream pipeline;
|
||||
pipeline << Device::manager().pipeline(device_);
|
||||
int index = Device::manager().index(device_);
|
||||
if (index > -1) {
|
||||
|
||||
DeviceInfoSet confs = getDeviceConfigs(pipeline.str());
|
||||
DeviceInfoSet::reverse_iterator best = confs.rbegin();
|
||||
// start filling in the gstreamer pipeline
|
||||
std::ostringstream pipeline;
|
||||
pipeline << Device::manager().description(index);
|
||||
|
||||
pipeline << " ! " << (*best).format;
|
||||
pipeline << ",framerate=" << (*best).fps_numerator << "/" << (*best).fps_denominator;
|
||||
pipeline << ",width=" << (*best).width;
|
||||
pipeline << ",height=" << (*best).height;
|
||||
// test the device and get config
|
||||
DeviceConfigSet confs = Device::manager().config(index);
|
||||
// for( DeviceInfoSet::iterator it = confs.begin(); it != confs.end(); it++ ){
|
||||
// Log::Info("config possible : %s %dx%d @ %d fps", (*it).format.c_str(), (*it).width, (*it).height, (*it).fps_numerator);
|
||||
// }
|
||||
DeviceConfigSet::reverse_iterator best = confs.rbegin();
|
||||
|
||||
if ( (*best).format.find("jpeg") != std::string::npos )
|
||||
pipeline << " ! jpegdec";
|
||||
pipeline << " ! " << (*best).format;
|
||||
pipeline << ",framerate=" << (*best).fps_numerator << "/" << (*best).fps_denominator;
|
||||
pipeline << ",width=" << (*best).width;
|
||||
pipeline << ",height=" << (*best).height;
|
||||
|
||||
// for( DeviceInfoSet::iterator it = confs.begin(); it != confs.end(); it++ ){
|
||||
// Log::Info("config possible : %s %dx%d @ %d fps", (*it).format.c_str(), (*it).width, (*it).height, (*it).fps_numerator);
|
||||
// }
|
||||
if ( (*best).format.find("jpeg") != std::string::npos )
|
||||
pipeline << " ! jpegdec";
|
||||
|
||||
pipeline << " ! videoconvert";
|
||||
pipeline << " ! videoconvert";
|
||||
|
||||
stream_->open( pipeline.str(), (*best).width, (*best).height);
|
||||
stream_->play(true);
|
||||
stream_->open( pipeline.str(), (*best).width, (*best).height);
|
||||
stream_->play(true);
|
||||
}
|
||||
else
|
||||
Log::Warning("No such device '%s'", device_.c_str());
|
||||
}
|
||||
|
||||
void DeviceSource::accept(Visitor& v)
|
||||
@@ -223,12 +244,12 @@ bool DeviceSource::failed() const
|
||||
}
|
||||
|
||||
|
||||
DeviceInfoSet DeviceSource::getDeviceConfigs(const std::string &pipeline)
|
||||
DeviceConfigSet Device::getDeviceConfigs(const std::string &src_description)
|
||||
{
|
||||
DeviceInfoSet configs;
|
||||
DeviceConfigSet configs;
|
||||
|
||||
// create dummy pipeline to be tested
|
||||
std::string description = pipeline;
|
||||
std::string description = src_description;
|
||||
description += " ! fakesink name=sink";
|
||||
|
||||
// parse pipeline descriptor
|
||||
@@ -261,7 +282,7 @@ DeviceInfoSet DeviceSource::getDeviceConfigs(const std::string &pipeline)
|
||||
int C = gst_caps_get_size(device_caps);
|
||||
for (int c = 0; c < C; ++c) {
|
||||
GstStructure *decice_cap_struct = gst_caps_get_structure (device_caps, c);
|
||||
DeviceInfo config;
|
||||
DeviceConfig config;
|
||||
|
||||
// NAME : typically video/x-raw or image/jpeg
|
||||
config.format = gst_structure_get_name (decice_cap_struct);
|
||||
@@ -299,6 +320,8 @@ DeviceInfoSet DeviceSource::getDeviceConfigs(const std::string &pipeline)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WIDTH and HEIGHT
|
||||
if ( gst_structure_has_field (decice_cap_struct, "width"))
|
||||
gst_structure_get_int (decice_cap_struct, "width", &config.width);
|
||||
if ( gst_structure_has_field (decice_cap_struct, "height"))
|
||||
@@ -307,6 +330,8 @@ DeviceInfoSet DeviceSource::getDeviceConfigs(const std::string &pipeline)
|
||||
// gchar *capstext = gst_structure_to_string (decice_cap_struct);
|
||||
// Log::Info("DeviceSource found cap struct %s", capstext);
|
||||
// g_free(capstext);
|
||||
|
||||
// add this config
|
||||
configs.insert(config);
|
||||
}
|
||||
|
||||
|
||||
101
DeviceSource.h
101
DeviceSource.h
@@ -7,6 +7,50 @@
|
||||
#include "GstToolkit.h"
|
||||
#include "StreamSource.h"
|
||||
|
||||
struct DeviceConfig {
|
||||
gint width;
|
||||
gint height;
|
||||
gint fps_numerator;
|
||||
gint fps_denominator;
|
||||
std::string format;
|
||||
|
||||
DeviceConfig() {
|
||||
width = 0;
|
||||
height = 0;
|
||||
fps_numerator = 1;
|
||||
fps_denominator = 1;
|
||||
format = "";
|
||||
}
|
||||
|
||||
inline DeviceConfig& operator = (const DeviceConfig& b)
|
||||
{
|
||||
if (this != &b) {
|
||||
this->width = b.width;
|
||||
this->height = b.height;
|
||||
this->fps_numerator = b.fps_numerator;
|
||||
this->fps_denominator = b.fps_denominator;
|
||||
this->format = b.format;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator < (const DeviceConfig b) const
|
||||
{
|
||||
return ( this->fps_numerator * this->height < b.fps_numerator * b.height );
|
||||
}
|
||||
};
|
||||
|
||||
struct better_device_comparator
|
||||
{
|
||||
inline bool operator () (const DeviceConfig a, const DeviceConfig b) const
|
||||
{
|
||||
return (a < b);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<DeviceConfig, better_device_comparator> DeviceConfigSet;
|
||||
|
||||
|
||||
class Device
|
||||
{
|
||||
Device();
|
||||
@@ -24,65 +68,27 @@ public:
|
||||
|
||||
int numDevices () const;
|
||||
std::string name (int index) const;
|
||||
std::string pipeline (int index) const;
|
||||
std::string description (int index) const;
|
||||
DeviceConfigSet config (int index) const;
|
||||
|
||||
bool exists (const std::string &device) const;
|
||||
std::string pipeline (const std::string &device) const;
|
||||
int index (const std::string &device) const;
|
||||
|
||||
static gboolean callback_device_monitor (GstBus *, GstMessage *, gpointer);
|
||||
|
||||
private:
|
||||
|
||||
void remove(const char *device);
|
||||
std::vector< std::string > names_;
|
||||
std::vector< std::string > pipelines_;
|
||||
std::vector< std::string > src_name_;
|
||||
std::vector< std::string > src_description_;
|
||||
|
||||
std::vector< DeviceConfigSet > src_config_;
|
||||
static DeviceConfigSet getDeviceConfigs(const std::string &src_description);
|
||||
|
||||
GstDeviceMonitor *monitor_;
|
||||
};
|
||||
|
||||
|
||||
struct DeviceInfo {
|
||||
gint width;
|
||||
gint height;
|
||||
gint fps_numerator;
|
||||
gint fps_denominator;
|
||||
std::string format;
|
||||
|
||||
DeviceInfo() {
|
||||
width = 0;
|
||||
height = 0;
|
||||
fps_numerator = 1;
|
||||
fps_denominator = 1;
|
||||
format = "";
|
||||
}
|
||||
|
||||
inline DeviceInfo& operator = (const DeviceInfo& b)
|
||||
{
|
||||
if (this != &b) {
|
||||
this->width = b.width;
|
||||
this->height = b.height;
|
||||
this->fps_numerator = b.fps_numerator;
|
||||
this->fps_denominator = b.fps_denominator;
|
||||
this->format = b.format;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator < (const DeviceInfo b) const
|
||||
{
|
||||
return ( this->fps_numerator * this->height < b.fps_numerator * b.height );
|
||||
}
|
||||
};
|
||||
|
||||
struct better_device_comparator
|
||||
{
|
||||
inline bool operator () (const DeviceInfo a, const DeviceInfo b) const
|
||||
{
|
||||
return (a < b);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<DeviceInfo, better_device_comparator> DeviceInfoSet;
|
||||
|
||||
class DeviceSource : public StreamSource
|
||||
{
|
||||
public:
|
||||
@@ -102,7 +108,6 @@ public:
|
||||
private:
|
||||
std::string device_;
|
||||
|
||||
DeviceInfoSet getDeviceConfigs(const std::string &pipeline);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ void ImGuiVisitor::visit (PatternSource& s)
|
||||
{
|
||||
for (int p = 0; p < Pattern::pattern_types.size(); ++p){
|
||||
if (ImGui::Selectable( Pattern::pattern_types[p].c_str() )) {
|
||||
s.setPattern(p);
|
||||
s.setPattern(p, s.pattern()->resolution());
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
|
||||
@@ -282,8 +282,8 @@ Source * Mixer::createSourceStream(const std::string &gstreamerpipeline)
|
||||
Source * Mixer::createSourcePattern(int pattern, glm::ivec2 res)
|
||||
{
|
||||
// ready to create a source
|
||||
PatternSource *s = new PatternSource(res);
|
||||
s->setPattern(pattern);
|
||||
PatternSource *s = new PatternSource;
|
||||
s->setPattern(pattern, res);
|
||||
|
||||
// propose a new name based on pattern name
|
||||
renameSource(s, Pattern::pattern_types[pattern]);
|
||||
|
||||
@@ -90,11 +90,9 @@ std::vector<std::string> Pattern::pattern_types = { "100% Black",
|
||||
"Clock"
|
||||
};
|
||||
|
||||
Pattern::Pattern(glm::ivec2 res) : Stream()
|
||||
Pattern::Pattern() : Stream()
|
||||
{
|
||||
|
||||
width_ = res.x;
|
||||
height_ = res.y;
|
||||
}
|
||||
|
||||
glm::ivec2 Pattern::resolution()
|
||||
@@ -103,7 +101,7 @@ glm::ivec2 Pattern::resolution()
|
||||
}
|
||||
|
||||
|
||||
void Pattern::open( uint pattern )
|
||||
void Pattern::open( uint pattern, glm::ivec2 res )
|
||||
{
|
||||
type_ = CLAMP(pattern, 0, 25);
|
||||
std::string gstreamer_pattern = pattern_internal_[type_];
|
||||
@@ -127,24 +125,24 @@ void Pattern::open( uint pattern )
|
||||
single_frame_ = type_ < 15;
|
||||
|
||||
// (private) open stream
|
||||
Stream::open(gstreamer_pattern);
|
||||
Stream::open(gstreamer_pattern, res.x, res.y);
|
||||
}
|
||||
|
||||
PatternSource::PatternSource(glm::ivec2 resolution) : StreamSource()
|
||||
PatternSource::PatternSource() : StreamSource()
|
||||
{
|
||||
// create stream
|
||||
stream_ = (Stream *) new Pattern(resolution);
|
||||
stream_ = (Stream *) new Pattern;
|
||||
|
||||
// set icons
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
}
|
||||
|
||||
void PatternSource::setPattern(int id)
|
||||
void PatternSource::setPattern(int type, glm::ivec2 resolution)
|
||||
{
|
||||
Log::Notify("Creating Source with pattern '%s'", Pattern::pattern_types[id].c_str());
|
||||
Log::Notify("Creating Source with pattern '%s'", Pattern::pattern_types[type].c_str());
|
||||
|
||||
pattern()->open( (uint) id );
|
||||
pattern()->open( (uint) type, resolution );
|
||||
stream_->play(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ class Pattern : public Stream
|
||||
public:
|
||||
static std::vector<std::string> pattern_types;
|
||||
|
||||
Pattern(glm::ivec2 res);
|
||||
void open( uint pattern );
|
||||
Pattern();
|
||||
void open( uint pattern, glm::ivec2 res);
|
||||
|
||||
glm::ivec2 resolution();
|
||||
inline uint type() const { return type_; }
|
||||
@@ -23,7 +23,7 @@ private:
|
||||
class PatternSource : public StreamSource
|
||||
{
|
||||
public:
|
||||
PatternSource(glm::ivec2 resolution);
|
||||
PatternSource();
|
||||
|
||||
// Source interface
|
||||
void accept (Visitor& v) override;
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
|
||||
// specific interface
|
||||
Pattern *pattern() const;
|
||||
void setPattern(int id);
|
||||
void setPattern(int type, glm::ivec2 resolution);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -99,12 +99,12 @@ void SessionCreator::loadSession(XMLElement *sessionNode)
|
||||
if (!pType)
|
||||
continue;
|
||||
if ( std::string(pType) == "MediaSource") {
|
||||
MediaSource *new_media_source = new MediaSource();
|
||||
MediaSource *new_media_source = new MediaSource;
|
||||
new_media_source->accept(*this);
|
||||
session_->addSource(new_media_source);
|
||||
}
|
||||
else if ( std::string(pType) == "SessionSource") {
|
||||
SessionSource *new_session_source = new SessionSource();
|
||||
SessionSource *new_session_source = new SessionSource;
|
||||
new_session_source->accept(*this);
|
||||
session_->addSource(new_session_source);
|
||||
}
|
||||
@@ -114,13 +114,7 @@ void SessionCreator::loadSession(XMLElement *sessionNode)
|
||||
session_->addSource(new_render_source);
|
||||
}
|
||||
else if ( std::string(pType) == "PatternSource") {
|
||||
|
||||
glm::ivec2 resolution(800, 600);
|
||||
XMLElement* res = xmlCurrent_->FirstChildElement("resolution");
|
||||
if (res)
|
||||
tinyxml2::XMLElementToGLM( res->FirstChildElement("ivec2"), resolution);
|
||||
|
||||
PatternSource *new_pattern_source = new PatternSource(resolution);
|
||||
PatternSource *new_pattern_source = new PatternSource;
|
||||
new_pattern_source->accept(*this);
|
||||
session_->addSource(new_pattern_source);
|
||||
}
|
||||
@@ -345,7 +339,13 @@ void SessionCreator::visit (SessionSource& s)
|
||||
void SessionCreator::visit (PatternSource& s)
|
||||
{
|
||||
uint p = xmlCurrent_->UnsignedAttribute("pattern");
|
||||
s.setPattern(p);
|
||||
|
||||
glm::ivec2 resolution(800, 600);
|
||||
XMLElement* res = xmlCurrent_->FirstChildElement("resolution");
|
||||
if (res)
|
||||
tinyxml2::XMLElementToGLM( res->FirstChildElement("ivec2"), resolution);
|
||||
|
||||
s.setPattern(p, resolution);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user