diff --git a/src/dbus/metatypes.h b/src/dbus/metatypes.h index 01d22f500905d07110f7e3741089970de2bf4d13..ba3c85fb10453cfa2237a46238ebbbfaf224a784 100644 --- a/src/dbus/metatypes.h +++ b/src/dbus/metatypes.h @@ -30,18 +30,27 @@ typedef QMap<QString, QString> MapStringString; typedef QMap<QString, int> MapStringInt; typedef QVector<int> VectorInt; typedef QVector< QMap<QString, QString> > VectorMapStringString; +typedef QVector< QString > VectorString; +typedef QMap< QString, QMap< QString, QVector<QString> > > MapStringMapStringVectorString; +typedef QMap< QString, QVector<QString> > MapStringVectorString; Q_DECLARE_METATYPE(MapStringString) Q_DECLARE_METATYPE(MapStringInt) Q_DECLARE_METATYPE(VectorMapStringString) +Q_DECLARE_METATYPE(MapStringMapStringVectorString) Q_DECLARE_METATYPE(VectorInt) +Q_DECLARE_METATYPE(VectorString) +Q_DECLARE_METATYPE(MapStringVectorString) static bool dbus_metaTypeInit = false; inline void registerCommTypes() { qDBusRegisterMetaType<MapStringString>(); qDBusRegisterMetaType<MapStringInt>(); qDBusRegisterMetaType<VectorMapStringString>(); - qDBusRegisterMetaType<VectorInt>(); + qDBusRegisterMetaType<MapStringMapStringVectorString>(); + qDBusRegisterMetaType<VectorInt>(); + qDBusRegisterMetaType<VectorString>(); + qDBusRegisterMetaType<MapStringVectorString>(); dbus_metaTypeInit = true; } #pragma GCC diagnostic pop diff --git a/src/dbus/videomanager-introspec.xml b/src/dbus/videomanager-introspec.xml index 7feb2cfd6eae8dc0ab1fcb4361f8ff44ba73e063..4dc4f890a991e4b98b48481cb84e4e75575c7d31 100644 --- a/src/dbus/videomanager-introspec.xml +++ b/src/dbus/videomanager-introspec.xml @@ -5,14 +5,14 @@ <method name="getDeviceList" tp:name-for-bindings="getDeviceList"> <tp:docstring>Returns a list of the detected v4l2 devices</tp:docstring> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> </arg> </method> <method name="getDeviceChannelList" tp:name-for-bindings="getDeviceChannelList"> <tp:docstring>Returns a list of the channels available for a given v4l2 device</tp:docstring> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="s" name="device" direction="in"> </arg> <arg type="as" name="list" direction="out"> @@ -21,7 +21,7 @@ <method name="getDeviceSizeList" tp:name-for-bindings="getDeviceSizeList"> <tp:docstring>Returns a list of the resolutions available for a given channel of a given v4l2 device</tp:docstring> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="s" name="device" direction="in"> </arg> <arg type="s" name="channel" direction="in"> @@ -32,7 +32,7 @@ <method name="getDeviceRateList" tp:name-for-bindings="getDeviceRateList"> <tp:docstring>Returns a list of the framerates available for a given resolution of a given channel of a given v4l2 device</tp:docstring> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="s" name="device" direction="in"> </arg> <arg type="s" name="channel" direction="in"> @@ -43,9 +43,18 @@ </arg> </method> + <method name="getCapabilities" tp:name-for-bindings="getCapabilities"> + <tp:docstring>Returns a map of map of array of strings, containing the capabilities (channel, size, rate) of a device</tp:docstring> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringMapStringVectorString"/> + <arg type="s" name="name" direction="in"> + </arg> + <arg type="a{sa{sas}}" name="cap" direction="out"> + </arg> + </method> + <method name="getSettingsFor" tp:name-for-bindings="getSettingsFor"> <tp:docstring>Returns a map of settings for the given device name</tp:docstring> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <arg type="s" name="device" direction="in"> </arg> <arg type="a{ss}" name="map" direction="out"> @@ -54,7 +63,7 @@ <method name="getPreferences" tp:name-for-bindings="getPreferences"> <tp:docstring>Returns a map of user preferences for the given device name</tp:docstring> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="MapStringString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <arg type="s" name="name" direction="in"> </arg> <arg type="a{ss}" name="map" direction="out"> @@ -65,7 +74,7 @@ <tp:docstring>Set the preferences of a given device name</tp:docstring> <arg type="s" name="name" direction="in"> </arg> - <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="MapStringString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="MapStringString"/> <arg type="a{ss}" name="pref" direction="in"> </arg> </method> @@ -75,18 +84,48 @@ </arg> </method> + <method name="getActiveDeviceChannel" tp:name-for-bindings="getActiveDeviceChannel"> + <arg type="s" name="channel" direction="out"> + </arg> + </method> + + <method name="getActiveDeviceSize" tp:name-for-bindings="getActiveDeviceSize"> + <arg type="s" name="size" direction="out"> + </arg> + </method> + + <method name="getActiveDeviceRate" tp:name-for-bindings="getActiveDeviceRate"> + <arg type="s" name="rate" direction="out"> + </arg> + </method> + <method name="setActiveDevice" tp:name-for-bindings="setActiveDevice"> <arg type="s" name="device" direction="in"> </arg> </method> + <method name="setActiveDeviceChannel" tp:name-for-bindings="setActiveDeviceChannel"> + <arg type="s" name="channel" direction="in"> + </arg> + </method> + + <method name="setActiveDeviceSize" tp:name-for-bindings="setActiveDeviceSize"> + <arg type="s" name="size" direction="in"> + </arg> + </method> + + <method name="setActiveDeviceRate" tp:name-for-bindings="setActiveDeviceRate"> + <arg type="s" name="rate" direction="in"> + </arg> + </method> + <!-- Video Codec related methods --> <method name="getCodecs" tp:name-for-bindings="getCodecs"> <tp:docstring>Gets the hashtable describing all the codecs and their parameters for a given account</tp:docstring> <arg type="s" name="accountID" direction="in"> </arg> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/> <arg type="aa{ss}" name="details" direction="out"> </arg> </method> @@ -95,7 +134,7 @@ <tp:docstring>Sets a vector of hashtables describing codecs and their parameters for a given account, one hashtable per codec</tp:docstring> <arg type="s" name="accountID" direction="in"> </arg> - <annotation name="org.qtproject.QtDBus.QtTypeName.In1" value="VectorMapStringString"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="VectorMapStringString"/> <arg type="aa{ss}" name="details" direction="in"> </arg> </method> @@ -125,7 +164,7 @@ </method> <method name="hasCameraStarted" tp:name-for-bindings="hasCameraStarted"> - <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="Bool"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="Bool"/> <arg type="b" name="started" direction="out"> <tp:docstring>Returns true if the camera has already started, false otherwise</tp:docstring> </arg> diff --git a/src/typedefs.h b/src/typedefs.h index d3fb6b1888f75d304fe3278c7263a2a5509b9ad9..ff77e33ce2a59664a67118776e5e84b005858195 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -28,6 +28,7 @@ typedef QMap<QString, QString> MapStringString; typedef QVector< QMap<QString, QString> > VectorMapStringString; +typedef QMap< QString, QMap< QString, QVector<QString> > > MapStringMapStringVectorString; typedef QMap<QString, int> MapStringInt; template<class T, class E> diff --git a/src/videodevice.cpp b/src/videodevice.cpp index fcaf69c6ccb406155ce1cff557dde11e3d8130b0..6ef8faf6c134a3afbbb65b5de9092b44c646e677 100644 --- a/src/videodevice.cpp +++ b/src/videodevice.cpp @@ -19,15 +19,17 @@ #include "dbus/videomanager.h" -Resolution::Resolution(uint _width, uint _height):QSize(_width,_height) +Resolution::Resolution(uint _width, uint _height):QSize(_width,_height), +m_pCurrentRate(nullptr),m_pChannel(nullptr) { } -Resolution::Resolution() : QSize() +Resolution::Resolution() : QSize(),m_pCurrentRate(nullptr),m_pChannel(nullptr) { } -Resolution::Resolution(const QString& size) +Resolution::Resolution(const QString& size, VideoChannel* chan) +: m_pCurrentRate(nullptr),m_pChannel(chan) { if (size.split('x').size() == 2) { setWidth(size.split('x')[0].toInt()); @@ -35,24 +37,50 @@ Resolution::Resolution(const QString& size) } } -Resolution::Resolution(const Resolution& res):QSize(res.width(),res.height()) +Resolution::Resolution(const Resolution& res):QSize(res.width(),res.height()), +m_pCurrentRate(nullptr),m_pChannel(nullptr) { } -Resolution::Resolution(const QSize& size):QSize(size) +Resolution::Resolution(const QSize& size):QSize(size), +m_pCurrentRate(nullptr),m_pChannel(nullptr) { } -const QString Resolution::toString() const +const QString Resolution::name() const { return QString::number(width())+'x'+QString::number(height()); } ///Constructor -VideoDevice::VideoDevice(const QString &id) : QObject(nullptr), m_DeviceId(id),m_Resolution("0x0") +VideoDevice::VideoDevice(const QString &id) : QObject(nullptr), m_DeviceId(id), +m_pCurrentChannel(nullptr) { - + VideoManagerInterface& interface = DBus::VideoManager::instance(); + MapStringMapStringVectorString cap = interface.getCapabilities(id); + QMapIterator<QString, MapStringVectorString> channels(cap); + qDebug() << "\n\n\n\nCAP" << id << cap.size(); + while (channels.hasNext()) { + channels.next(); + + VideoChannel* chan = new VideoChannel(this,channels.key()); + m_lChannels << chan; + + QMapIterator<QString, VectorString> resolutions(channels.value()); + while (resolutions.hasNext()) { + resolutions.next(); + + Resolution* res = new Resolution(resolutions.key(),chan); + chan->m_lValidResolutions << res; + + foreach(const QString& rate, resolutions.value()) { + VideoRate* r = new VideoRate(res,rate); + res->m_lValidRates << r; + } + } + } + Q_UNUSED(cap) } ///Destructor @@ -60,104 +88,145 @@ VideoDevice::~VideoDevice() { } -///Get the valid rates for this device -const QStringList VideoDevice::rateList(const VideoChannel& channel, const Resolution& resolution) -{ - VideoManagerInterface& interface = DBus::VideoManager::instance(); - return interface.getDeviceRateList(m_DeviceId,channel,resolution.toString()); -} - ///Get the valid channel list -const QList<VideoChannel> VideoDevice::channelList() +QList<VideoChannel*> VideoDevice::channelList() const { - VideoManagerInterface& interface = DBus::VideoManager::instance(); - return interface.getDeviceChannelList(m_DeviceId); + return m_lChannels; } -///Set the current device rate -void VideoDevice::setRate(const VideoRate& rate) +///Save the current settings +void VideoDevice::save() { - m_Rate = rate; + //In case new (unsupported) fields are added, merge with existing VideoManagerInterface& interface = DBus::VideoManager::instance(); MapStringString pref = interface.getPreferences(m_DeviceId); - pref[PreferenceNames::RATE] = rate; + pref[VideoDevice::PreferenceNames::CHANNEL] = activeChannel()->name(); + pref[VideoDevice::PreferenceNames::SIZE ] = activeChannel()->activeResolution()->name(); + pref[VideoDevice::PreferenceNames::RATE ] = activeChannel()->activeResolution()->activeRate()->name(); interface.setPreferences(m_DeviceId,pref); } -///Set the current resolution -void VideoDevice::setResolution(const Resolution& resolution) //??? No device +///Get the device id +const QString VideoDevice::id() const { - m_Resolution = resolution; - VideoManagerInterface& interface = DBus::VideoManager::instance(); - MapStringString pref = interface.getPreferences(m_DeviceId); - pref[PreferenceNames::SIZE] = resolution.toString(); - interface.setPreferences(m_DeviceId,pref); + return m_DeviceId; } -///Set the current device channel -void VideoDevice::setChannel(const VideoChannel& channel) //??? No device +///Get the device name +const QString VideoDevice::name() const { - m_Channel = channel; VideoManagerInterface& interface = DBus::VideoManager::instance(); - MapStringString pref = interface.getPreferences(m_DeviceId); - pref[PreferenceNames::CHANNEL] = channel; - interface.setPreferences(m_DeviceId,pref); + return QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::NAME];; } -///Get the current resolution -const Resolution VideoDevice::resolution() +///Is this device the default one +bool VideoDevice::isActive() const { - VideoManagerInterface& interface = DBus::VideoManager::instance(); - if ((!m_Resolution.isValid()) || m_Resolution == QSize(0,0)) - m_Resolution = Resolution(QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::SIZE]); - return m_Resolution; + return QString(DBus::VideoManager::instance().getActiveDevice()) == m_DeviceId; } -///Get the current channel -const VideoChannel VideoDevice::channel() //??? No device +Resolution* VideoChannel::activeResolution() { - VideoManagerInterface& interface = DBus::VideoManager::instance(); - if (m_Channel.isEmpty()) - m_Channel = QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::CHANNEL]; - return m_Channel; + //If it is the current device, then there is "current" resolution + if ((!m_pCurrentResolution) && m_pDevice->isActive()) { + VideoManagerInterface& interface = DBus::VideoManager::instance(); + const QString res = QMap<QString,QString>(interface.getPreferences(m_pDevice->id()))[VideoDevice::PreferenceNames::SIZE]; + foreach(Resolution* r, validResolutions()) { + if (r->name() == res) { + m_pCurrentResolution = r; + break; + } + } + } + //If it isn't the current _or_ the current res is invalid, pick the first valid one + if (!m_pCurrentResolution && validResolutions().size()) { + m_pCurrentResolution = validResolutions()[0]; + } + + return m_pCurrentResolution; } -///Get the current rate -const VideoRate VideoDevice::rate() -{ - VideoManagerInterface& interface = DBus::VideoManager::instance(); - if (m_Rate.isEmpty()) - m_Rate = QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::RATE]; - return m_Rate; +bool VideoChannel::setActiveResolution(Resolution* res) { + if ((!res) || m_lValidResolutions.indexOf(res) == -1 || res->name().isEmpty()) { + qWarning() << "Invalid active resolution" << (res?res->name():"NULL"); + return false; + } + m_pCurrentResolution = res; + m_pDevice->save(); + return true; } -///Get a list of valid resolution -const QList<Resolution> VideoDevice::resolutionList(const VideoChannel& channel) +VideoRate* Resolution::activeRate() { - QList<Resolution> toReturn; - VideoManagerInterface& interface = DBus::VideoManager::instance(); - const QStringList list = interface.getDeviceSizeList(m_DeviceId,channel); - foreach(const QString& res,list) { - toReturn << Resolution(res); + if (!m_pChannel) { + qWarning() << "Trying to get the active rate of an unattached resolution"; + return nullptr; + } + if (!m_pCurrentRate && m_pChannel && m_pChannel->device()->isActive()) { + VideoManagerInterface& interface = DBus::VideoManager::instance(); + const QString rate = QMap<QString,QString>( + interface.getPreferences(m_pChannel->device()->id()))[VideoDevice::PreferenceNames::RATE]; + foreach(VideoRate* r, m_lValidRates) { + if (r->name() == rate) { + m_pCurrentRate = r; + break; + } + } } - return toReturn; + if ((!m_pCurrentRate) && m_lValidRates.size()) + m_pCurrentRate = m_lValidRates[0]; + + return m_pCurrentRate; } -///Get the device id -const QString VideoDevice::id() const +int Resolution::index() const { - return m_DeviceId; + return m_pChannel?m_pChannel->validResolutions().indexOf(const_cast<Resolution*>(this)):-1; } -///Get the device name -const QString VideoDevice::name() +int VideoChannel::index() { + return m_pDevice->channelList().indexOf(this); +} + +int VideoRate::index() { + return m_pResolution->validRates().indexOf(this); +} + +bool VideoDevice::setActiveChannel(VideoChannel* chan) { - VideoManagerInterface& interface = DBus::VideoManager::instance(); - return QMap<QString,QString>(interface.getPreferences(m_DeviceId))[PreferenceNames::NAME];; + if (!chan || !m_lChannels.indexOf(chan)) { + qWarning() << "Trying to set an invalid channel" << (chan?chan->name():"NULL") << "for" << id(); + return false; + } + m_pCurrentChannel = chan; + save(); + return true; } -///Is this device the default one -bool VideoDevice::isActive() +VideoChannel::VideoChannel(VideoDevice* dev,const QString& name) : + m_Name(name),m_pCurrentResolution(nullptr),m_pDevice(dev) { - return QString(DBus::VideoManager::instance().getActiveDevice()) == m_DeviceId; + m_pCurrentResolution = nullptr; + m_pCurrentResolution = nullptr; + m_pCurrentResolution = nullptr; + m_pCurrentResolution = nullptr; + m_pCurrentResolution = nullptr; } + +VideoChannel* VideoDevice::activeChannel() const +{ + if (!m_pCurrentChannel) { + VideoManagerInterface& interface = DBus::VideoManager::instance(); + const QString chan = QMap<QString,QString>(interface.getPreferences(m_DeviceId))[VideoDevice::PreferenceNames::CHANNEL]; + foreach(VideoChannel* c, m_lChannels) { + if (c->name() == chan) { + const_cast<VideoDevice*>(this)->m_pCurrentChannel = c; + break; + } + } + } + if (!m_pCurrentChannel && m_lChannels.size()) { + const_cast<VideoDevice*>(this)->m_pCurrentChannel = m_lChannels[0]; + } + return m_pCurrentChannel; +} \ No newline at end of file diff --git a/src/videodevice.h b/src/videodevice.h index 35a2d74268441509f9ace17c0032e956c3b77ab4..34e8a8d423d95ca4a9b983680d9a71dee7a97058 100644 --- a/src/videodevice.h +++ b/src/videodevice.h @@ -26,25 +26,90 @@ //SFLPhone class VideoRenderer; +class Resolution; +class VideoRate; +class VideoChannel; +class VideoDevice; ///@typedef VideoChannel A channel available in a Device -typedef QString VideoChannel; +class LIB_EXPORT VideoChannel +{ + //Only VideoDevice can add resolutions + friend class VideoDevice; +public: + QString name() const { + return m_Name; + } + Resolution* activeResolution(); + QList<Resolution*> validResolutions() const { + return m_lValidResolutions; + } + VideoDevice* device() const { + return m_pDevice; + } + int index(); + + bool setActiveResolution(Resolution* res); + +private: + VideoChannel(VideoDevice* dev,const QString& name); + virtual ~VideoChannel() {} + QString m_Name; + QList<Resolution*> m_lValidResolutions; + Resolution* m_pCurrentResolution; + VideoDevice* m_pDevice; +}; ///@typedef VideoRate The rate for a device -typedef QString VideoRate; +class LIB_EXPORT VideoRate +{ + //Can only be created by VideoDevice + friend class VideoDevice; + +public: + virtual ~VideoRate() {} + QString name() const { + return m_Name; + } + int index(); +private: + VideoRate(const Resolution* res,const QString& name) : + m_Name(name),m_pResolution(res) {} + QString m_Name; + const Resolution* m_pResolution; +}; ///@struct Resolution Equivalent of "640x480" class LIB_EXPORT Resolution : public QSize { + //Only VideoDevice can add validated rates + friend class VideoDevice; public: //Constructor Resolution(uint _width, uint _height); - Resolution(const QString& size = QString()); + Resolution(const QString& size = QString(), VideoChannel* chan = nullptr); Resolution(const Resolution& res); Resolution(const QSize& size); explicit Resolution(); //Getter - const QString toString() const; - + const QString name() const; + const QList<VideoRate*> validRates() const { + return m_lValidRates; + } + int index() const; + VideoRate* activeRate(); + bool setActiveRate(VideoRate* rate) { + if (!rate || (m_lValidRates.indexOf(rate) != -1)) { + qWarning() << "Trying to set an invalid rate"; + return false; + } + return true; + } +private: + + //Attributes + QList<VideoRate*> m_lValidRates; + VideoRate* m_pCurrentRate; + VideoChannel* m_pChannel; }; class VideoModel; @@ -54,27 +119,25 @@ class LIB_EXPORT VideoDevice : public QObject { Q_OBJECT friend class VideoModel; friend class VideoDeviceModel; + + //Need to access the PreferenceNames table + friend class VideoChannel; + friend class Resolution; public: //Constants constexpr static const char* NONE = ""; //Getter - const QStringList rateList(const VideoChannel& channel, const Resolution& resolution); - const QList<Resolution> resolutionList(const VideoChannel& channel); - const QList<VideoChannel> channelList (); - const Resolution resolution (); - const VideoChannel channel (); - const VideoRate rate (); - const QString id () const; - const QString name (); - bool isActive (); + QList<VideoChannel*> channelList () const; + VideoChannel* activeChannel () const; + const QString id () const; + const QString name () const; + bool isActive () const; //Static getter //Setter - void setRate ( const VideoRate& rate ); - void setResolution ( const Resolution& resolution ); - void setChannel ( const VideoChannel& channel ); + bool setActiveChannel(VideoChannel* chan); private: //Constructor @@ -82,10 +145,12 @@ class LIB_EXPORT VideoDevice : public QObject { ~VideoDevice(); //Attributes - QString m_DeviceId; - QString m_Rate; - QString m_Channel; - Resolution m_Resolution; + QString m_DeviceId ; + VideoChannel* m_pCurrentChannel ; + QList<VideoChannel*> m_lChannels ; + + //Helper + void save(); class PreferenceNames { public: @@ -95,7 +160,7 @@ class LIB_EXPORT VideoDevice : public QObject { constexpr static const char* SIZE = "size" ; }; - signals: + Q_SIGNALS: void renderingStarted(VideoRenderer*); void renderingStopped(VideoRenderer*); void renderStateChanged(bool state); diff --git a/src/videodevicemodel.cpp b/src/videodevicemodel.cpp index 71d1febdebe87895eb357be68455c7de7f6e9b4b..07bd35ea29d721b641248adffcdf64eb56bf3a4e 100644 --- a/src/videodevicemodel.cpp +++ b/src/videodevicemodel.cpp @@ -193,7 +193,7 @@ VideoDeviceResolutionModel* VideoDeviceModel::resolutionModel() const QVariant VideoDeviceResolutionModel::data( const QModelIndex& idx, int role) const { if(idx.column() == 0 && role == Qt::DisplayRole) - return QVariant(m_lResolutions[idx.row()]->toString()); + return QVariant(VideoDeviceModel::instance()->activeDevice()->activeChannel()->validResolutions()[idx.row()]->name()); return QVariant(); } @@ -201,7 +201,7 @@ QVariant VideoDeviceResolutionModel::data( const QModelIndex& idx, int role) con int VideoDeviceResolutionModel::rowCount( const QModelIndex& par ) const { Q_UNUSED(par) - return m_lResolutions.size(); + return VideoDeviceModel::instance()->activeDevice()->activeChannel()->validResolutions().size(); } ///Items flag @@ -233,19 +233,20 @@ VideoDeviceResolutionModel::~VideoDeviceResolutionModel() } -Resolution VideoDeviceResolutionModel::activeResolution() const +Resolution* VideoDeviceResolutionModel::activeResolution() const { - return VideoDeviceModel::instance()->activeDevice()->resolution(); + return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution(); } ///Save the current model over dbus void VideoDeviceResolutionModel::setActive(const QModelIndex& idx) { if (idx.isValid()) { - QSize s1(*m_lResolutions[idx.row()]),s2(VideoDeviceModel::instance()->activeDevice()->resolution()); + Resolution* r = VideoDeviceModel::instance()->activeDevice()->activeChannel()->validResolutions()[idx.row()]; + QSize s1(*r),s2(*VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()); if (s1 == s2) return; - VideoDeviceModel::instance()->activeDevice()->setResolution(m_lResolutions[idx.row()]->toString()); + VideoDeviceModel::instance()->activeDevice()->activeChannel()->setActiveResolution(r); emit changed(); emit currentIndexChanged(idx.row()); } @@ -262,32 +263,15 @@ void VideoDeviceResolutionModel::setActive(const int idx) void VideoDeviceResolutionModel::reload() { QHash<QString,Resolution*> devicesHash; - VideoManagerInterface& interface = DBus::VideoManager::instance(); VideoDevice* active = VideoDeviceModel::instance()->activeDevice(); if (active) { - const QStringList deviceList = interface.getDeviceSizeList(active->id(), - VideoDeviceModel::instance()->rateModel()->activeRate()); - if (deviceList.size() == m_hResolutions.size()) { - m_lResolutions = m_hResolutions.values(); - } - foreach(const QString& deviceName,deviceList) { - if (!m_hResolutions.contains(deviceName)) { - devicesHash[deviceName] = new Resolution(deviceName); - } - else { - devicesHash[deviceName] = m_hResolutions[deviceName]; - } - } - m_hResolutions.clear(); - m_hResolutions = devicesHash; - m_lResolutions = m_hResolutions.values(); emit layoutChanged(); VideoDeviceModel::instance()->rateModel()->reload(); emit changed(); - emit currentIndexChanged(m_lResolutions.indexOf(m_hResolutions[activeResolution().toString()])); + emit currentIndexChanged(activeResolution()->index()); } else { m_hResolutions.clear(); @@ -298,15 +282,7 @@ void VideoDeviceResolutionModel::reload() int VideoDeviceResolutionModel::currentIndex() const { - const Resolution& res = activeResolution(); - for (int i=0;i<m_lResolutions.size();i++) { - Resolution* availableRes = m_lResolutions[i]; - if (res.width() == availableRes->width() && res.height() == availableRes->height()) { - return i; - } - } - qWarning() << "Invalid resolution"; - return -1; + return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->index(); } @@ -324,16 +300,16 @@ VideoDeviceChannelModel* VideoDeviceModel::channelModel() const } -QString VideoDeviceChannelModel::activeChannel() const +VideoChannel* VideoDeviceChannelModel::activeChannel() const { - return VideoDeviceModel::instance()->activeDevice()->channel(); + return VideoDeviceModel::instance()->activeDevice()->activeChannel(); } ///Get data from the model QVariant VideoDeviceChannelModel::data( const QModelIndex& idx, int role) const { if(idx.column() == 0 && role == Qt::DisplayRole) - return QVariant(m_lChannels[idx.row()]); + return QVariant(activeChannel()->name()); return QVariant(); } @@ -341,7 +317,7 @@ QVariant VideoDeviceChannelModel::data( const QModelIndex& idx, int role) const int VideoDeviceChannelModel::rowCount( const QModelIndex& par ) const { Q_UNUSED(par) - return m_lChannels.size(); + return VideoDeviceModel::instance()->activeDevice()->channelList().size(); } ///Items flag @@ -375,7 +351,8 @@ VideoDeviceChannelModel::~VideoDeviceChannelModel() void VideoDeviceChannelModel::setActive(const QModelIndex& idx) { if (idx.isValid()) { - VideoDeviceModel::instance()->activeDevice()->setChannel(m_lChannels[idx.row()]); + VideoChannel* c = VideoDeviceModel::instance()->activeDevice()->channelList()[idx.row()]; + VideoDeviceModel::instance()->activeDevice()->setActiveChannel(c); emit changed(); emit currentIndexChanged(idx.row()); } @@ -389,29 +366,23 @@ void VideoDeviceChannelModel::setActive(const int idx) void VideoDeviceChannelModel::reload() { - QHash<QString,QString> devicesHash; - VideoManagerInterface& interface = DBus::VideoManager::instance(); VideoDevice* active = VideoDeviceModel::instance()->activeDevice(); if (active) { - const QStringList deviceList = interface.getDeviceChannelList(active->id()); - m_lChannels = deviceList; emit layoutChanged(); VideoDeviceModel::instance()->resolutionModel()->reload(); - setActive(m_lChannels.indexOf(activeChannel())); + setActive(activeChannel()->index()); } else { - //There is no channel when there is no devices - m_lChannels.clear(); emit layoutChanged(); } } int VideoDeviceChannelModel::currentIndex() const { - return m_lChannels.indexOf(activeChannel()); + return activeChannel()->index(); } @@ -427,16 +398,16 @@ VideoDeviceRateModel* VideoDeviceModel::rateModel() const return m_pRateModel; } -QString VideoDeviceRateModel::activeRate() const +VideoRate* VideoDeviceRateModel::activeRate() const { - return VideoDeviceModel::instance()->activeDevice()->rate(); + return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->activeRate(); } ///Get data from the model QVariant VideoDeviceRateModel::data( const QModelIndex& idx, int role) const { - if(idx.isValid() && idx.column() == 0 && role == Qt::DisplayRole && idx.row() < m_lRates.size()) - return QVariant(m_lRates[idx.row()]); + if(idx.isValid() && idx.column() == 0 && role == Qt::DisplayRole) + return QVariant(VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->validRates()[idx.row()]->name()); return QVariant(); } @@ -444,7 +415,7 @@ QVariant VideoDeviceRateModel::data( const QModelIndex& idx, int role) const int VideoDeviceRateModel::rowCount( const QModelIndex& par ) const { Q_UNUSED(par) - return m_lRates.size(); + return VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->validRates().size(); } ///Items flag @@ -478,7 +449,8 @@ VideoDeviceRateModel::~VideoDeviceRateModel() void VideoDeviceRateModel::setActive(const QModelIndex& idx) { if (idx.isValid()) { - VideoDeviceModel::instance()->activeDevice()->setRate(m_lRates[idx.row()]); + VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->setActiveRate( + VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->validRates()[idx.row()]); emit changed(); emit currentIndexChanged(idx.row()); } @@ -495,27 +467,19 @@ void VideoDeviceRateModel::setActive(const int idx) void VideoDeviceRateModel::reload() { QHash<QString,VideoDevice*> devicesHash; - VideoManagerInterface& interface = DBus::VideoManager::instance(); VideoDevice* active = VideoDeviceModel::instance()->activeDevice(); if (active) { - const QStringList deviceList = interface.getDeviceRateList(active->id (), - VideoDeviceModel::instance()->channelModel()->activeChannel (), - VideoDeviceModel::instance()->resolutionModel()->activeResolution().toString() - ); - m_lRates = deviceList; emit layoutChanged(); - const int currentRate = m_lRates.indexOf(activeRate()); - setActive(currentRate==-1?0:currentRate); + setActive(activeRate()->index()); } else { - m_lRates.clear(); emit layoutChanged(); } } int VideoDeviceRateModel::currentIndex() const { - return m_lRates.indexOf(activeRate()); + return activeRate()->index(); } @@ -542,19 +506,19 @@ QVariant ExtendedVideoDeviceModel::data( const QModelIndex& index, int role ) co case ExtendedDeviceList::NONE: switch(role) { case Qt::DisplayRole: - return "NONE"; + return tr("NONE"); }; break; case ExtendedDeviceList::SCREEN: switch(role) { case Qt::DisplayRole: - return "SCREEN"; + return tr("SCREEN"); }; break; case ExtendedDeviceList::FILE: switch(role) { case Qt::DisplayRole: - return "FILE"; + return tr("FILE"); }; break; default: @@ -600,16 +564,18 @@ void ExtendedVideoDeviceModel::switchTo(const int idx) { switch (idx) { case ExtendedDeviceList::NONE: - DBus::VideoManager::instance().switchInput(""); + DBus::VideoManager::instance().switchInput(ProtocolPrefix::NONE); break; case ExtendedDeviceList::SCREEN: - DBus::VideoManager::instance().switchInput("display://0:100x100"); + DBus::VideoManager::instance().switchInput( QString(ProtocolPrefix::DISPLAY)+"0:100x100"); break; case ExtendedDeviceList::FILE: - DBus::VideoManager::instance().switchInput(!m_CurrentFile.isEmpty()?"file://"+m_CurrentFile.path():""); + DBus::VideoManager::instance().switchInput( + !m_CurrentFile.isEmpty()?+ProtocolPrefix::FILE+m_CurrentFile.path():ProtocolPrefix::NONE + ); break; default: - DBus::VideoManager::instance().switchInput("v4l2://"+ + DBus::VideoManager::instance().switchInput(ProtocolPrefix::V4L2 + VideoDeviceModel::instance()->index(idx-ExtendedDeviceList::__COUNT,0).data(Qt::DisplayRole).toString()); break; }; diff --git a/src/videodevicemodel.h b/src/videodevicemodel.h index 2308ccfb4bec5bc2531082477fcfdcedc9404b10..cbd0359c4817c76d83ec24b4987ee359b44d7682 100644 --- a/src/videodevicemodel.h +++ b/src/videodevicemodel.h @@ -29,6 +29,7 @@ //SFLPhone class VideoDevice; +//DEPRECATED ///Abstract model for managing account video codec list class LIB_EXPORT VideoDeviceResolutionModel : public QAbstractListModel { #pragma GCC diagnostic push @@ -47,13 +48,14 @@ public: Qt::ItemFlags flags ( const QModelIndex& index ) const; virtual bool setData ( const QModelIndex& index, const QVariant &value, int role) ; - Resolution activeResolution() const; + Resolution* activeResolution() const; int currentIndex() const; private: + //Attrbutes QHash<QString,Resolution*> m_hResolutions ; - QList<Resolution*> m_lResolutions; +// QList<Resolution*> m_lResolutions; static VideoDeviceResolutionModel* m_spInstance; public Q_SLOTS: @@ -67,6 +69,7 @@ Q_SIGNALS: }; Q_DECLARE_METATYPE(VideoDeviceResolutionModel*) +//DEPRECATED ///Abstract model for managing account video codec list class LIB_EXPORT VideoDeviceChannelModel : public QAbstractListModel { #pragma GCC diagnostic push @@ -87,12 +90,12 @@ public: static VideoDeviceChannelModel* instance(); - QString activeChannel() const; + VideoChannel* activeChannel() const; int currentIndex() const; private: //Attrbutes - QList<QString> m_lChannels; +// QList<QString> m_lChannels; public Q_SLOTS: @@ -126,6 +129,15 @@ public: //Singleton static ExtendedVideoDeviceModel* instance(); private: + //Constants + class ProtocolPrefix { + public: + constexpr static const char* NONE = "" ; + constexpr static const char* DISPLAY = "display://"; + constexpr static const char* FILE = "file://" ; + constexpr static const char* V4L2 = "v4l2://" ; + }; + struct Display { Display() : res("0x0"),point(0,0),index(0){} Resolution res ; /* Resolution 0x0 for native */ @@ -144,6 +156,7 @@ public Q_SLOTS: void setDisplay(int index, Resolution res = Resolution("0x0"), QPoint point = QPoint(0,0)); }; +//DEPRECATED ///Abstract model for managing account video codec list class LIB_EXPORT VideoDeviceRateModel : public QAbstractListModel { #pragma GCC diagnostic push @@ -162,12 +175,12 @@ public: Qt::ItemFlags flags ( const QModelIndex& index ) const; virtual bool setData ( const QModelIndex& index, const QVariant &value, int role) ; - QString activeRate() const; + VideoRate* activeRate() const; int currentIndex() const; private: //Attrbutes - QList<QString> m_lRates; +// QList<QString> m_lRates; public Q_SLOTS: void setActive(const QModelIndex& idx); diff --git a/src/videomodel.cpp b/src/videomodel.cpp index c97986d2c6d6f2195cf5821c1968b7b8d42bb5e2..f33915b3bd7d552f2ee64eb0e94496ab9b51be1f 100644 --- a/src/videomodel.cpp +++ b/src/videomodel.cpp @@ -32,7 +32,8 @@ VideoModel* VideoModel::m_spInstance = nullptr; ///Constructor -VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new QMutex()) +VideoModel::VideoModel():QThread(),m_BufferSize(0),m_ShmKey(0),m_SemKey(0),m_PreviewState(false),m_SSMutex(new QMutex()), +m_pActiveDevice(nullptr) { VideoManagerInterface& interface = DBus::VideoManager::instance(); connect( &interface , SIGNAL(deviceEvent()) , this, SLOT(deviceEvent()) ); @@ -69,7 +70,8 @@ VideoRenderer* VideoModel::getRenderer(const Call* call) const VideoRenderer* VideoModel::previewRenderer() { if (!m_lRenderers["local"]) { - m_lRenderers["local"] = new VideoRenderer("local","", VideoDeviceModel::instance()->activeDevice()->resolution()); + m_lRenderers["local"] = new VideoRenderer("local","", + VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()); } return m_lRenderers["local"]; } @@ -109,13 +111,41 @@ void VideoModel::deviceEvent() } +VideoDevice* VideoModel::activeDevice() const +{ + if (!m_pActiveDevice) { + VideoManagerInterface& interface = DBus::VideoManager::instance(); + const QString activeDeviceId = interface.getActiveDevice(); + foreach(VideoDevice* dev, m_hDevices) { + if (dev->id() == activeDeviceId) { + const_cast<VideoModel*>(this)->m_pActiveDevice = dev; + break; + } + } + } + if (!m_pActiveDevice) { + qWarning() << "No active devices"; + } + return m_pActiveDevice; +} + ///A video is not being rendered void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int width, int height) { Q_UNUSED(id) + Resolution* res; + if (VideoDeviceModel::instance()->activeDevice() + && VideoDeviceModel::instance()->activeDevice()->activeChannel()->activeResolution()->width() == width) { + //FIXME flawed logic + res = VideoModel::activeDevice()->activeChannel()->activeResolution(); + } + else { + res = new Resolution(width,height); //FIXME leak + } + if (m_lRenderers[id] == nullptr ) { - m_lRenderers[id] = new VideoRenderer(id,shmPath,Resolution(width,height)); + m_lRenderers[id] = new VideoRenderer(id,shmPath,res); m_lRenderers[id]->moveToThread(this); if (!isRunning()) start(); @@ -123,7 +153,7 @@ void VideoModel::startedDecoding(const QString& id, const QString& shmPath, int else { VideoRenderer* renderer = m_lRenderers[id]; renderer->setShmPath(shmPath); - renderer->setResolution(QSize(width,height)); + renderer->setResolution(res); } m_lRenderers[id]->startRendering(); diff --git a/src/videomodel.h b/src/videomodel.h index f89787ba16bbe820de56f8fc0ff4ba7ff35a7ca0..69997a69c3650eacc0411182d1e3aebdb5f87818 100644 --- a/src/videomodel.h +++ b/src/videomodel.h @@ -46,13 +46,13 @@ public: VideoRenderer* getRenderer(const Call* call) const; VideoRenderer* previewRenderer(); QList<VideoDevice*> devices(); -// VideoDevice* activeDevice() const; + VideoDevice* activeDevice() const; VideoDevice* device(const QString &id); QMutex* startStopMutex() const; //Setters void setBufferSize(uint size); -// void setActiveDevice(const VideoDevice* device); + void setActiveDevice(const VideoDevice* device); void switchDevice(const VideoDevice* device) const; protected: @@ -74,6 +74,7 @@ private: QMutex* m_SSMutex ; QHash<QString,VideoRenderer*> m_lRenderers; QHash<QString,VideoDevice*> m_hDevices ; + VideoDevice* m_pActiveDevice; public Q_SLOTS: void stopPreview (); diff --git a/src/videorenderer.cpp b/src/videorenderer.cpp index 3e052ac202750ac4e7fa9a6fac36998ac3157ef2..1dc75a3f26d2b7052a05aad38de8954a596a7c0c 100644 --- a/src/videorenderer.cpp +++ b/src/videorenderer.cpp @@ -55,10 +55,10 @@ struct SHMHeader{ }; ///Constructor -VideoRenderer::VideoRenderer(const QString& id, const QString& shmPath, Resolution res): QObject(nullptr), - m_Width(res.width()), m_Height(res.height()), m_ShmPath(shmPath), fd(-1), +VideoRenderer::VideoRenderer(const QString& id, const QString& shmPath, const Resolution* res): QObject(nullptr), + m_Width(res->width()), m_Height(res->height()), m_ShmPath(shmPath), fd(-1), m_pShmArea((SHMHeader*)MAP_FAILED), m_ShmAreaLen(0), m_BufferGen(0), - m_isRendering(false),m_pTimer(nullptr),m_Res(res),m_pMutex(new QMutex()), + m_isRendering(false),m_pTimer(nullptr),m_pRes(const_cast<Resolution*>(res)),m_pMutex(new QMutex()), m_Id(id),m_FrameIdx(false),m_pSSMutex(new QMutex()) { setObjectName("VideoRenderer:"+id); @@ -330,9 +330,9 @@ const QByteArray& VideoRenderer::currentFrame() } ///Return the current resolution -Resolution VideoRenderer::activeResolution() +const Resolution* VideoRenderer::activeResolution() { - return m_Res; + return m_pRes; } ///Get mutex, in case renderer and views are not in the same thread @@ -354,11 +354,11 @@ int VideoRenderer::fps() const * * ****************************************************************************/ -void VideoRenderer::setResolution(QSize size) +void VideoRenderer::setResolution(Resolution* res) { - m_Res = size; - m_Width = size.width(); - m_Height = size.height(); + m_pRes = res; + m_Width = res->width(); + m_Height = res->height(); } void VideoRenderer::setShmPath(const QString& path) diff --git a/src/videorenderer.h b/src/videorenderer.h index a27494abc1ef02e6d60484720bc873976f63b846..d2abb62e1eb5479360d1ce2a7e7f3db98f24133f 100644 --- a/src/videorenderer.h +++ b/src/videorenderer.h @@ -41,7 +41,7 @@ class LIB_EXPORT VideoRenderer : public QObject { public: //Constructor - VideoRenderer (const QString& id, const QString& shmPath, const Resolution res); + VideoRenderer (const QString& id, const QString& shmPath, const Resolution* res); ~VideoRenderer(); //Mutators @@ -50,37 +50,37 @@ class LIB_EXPORT VideoRenderer : public QObject { bool startShm (); //Getters - const char* rawData () ; - bool isRendering () ; + const char* rawData () ; + bool isRendering () ; const QByteArray& currentFrame () ; - Resolution activeResolution() ; - QMutex* mutex () ; - int fps () const; + const Resolution* activeResolution() ; + QMutex* mutex () ; + int fps () const; //Setters - void setResolution(QSize size); + void setResolution(Resolution* res); void setShmPath (const QString& path); private: //Attributes - uint m_Width ; - uint m_Height ; - QString m_ShmPath ; - int fd ; - SHMHeader* m_pShmArea ; - signed int m_ShmAreaLen ; - uint m_BufferGen ; - bool m_isRendering; - QTimer* m_pTimer ; - QByteArray m_Frame[2] ; - bool m_FrameIdx ; - Resolution m_Res ; - QMutex* m_pMutex ; - QMutex* m_pSSMutex ; - QString m_Id ; - int m_fpsC ; - int m_Fps ; - QTime m_CurrentTime; + uint m_Width ; + uint m_Height ; + QString m_ShmPath ; + int fd ; + SHMHeader * m_pShmArea ; + signed int m_ShmAreaLen ; + uint m_BufferGen ; + bool m_isRendering; + QTimer* m_pTimer ; + QByteArray m_Frame[2] ; + bool m_FrameIdx ; + Resolution* m_pRes ; + QMutex* m_pMutex ; + QMutex* m_pSSMutex ; + QString m_Id ; + int m_fpsC ; + int m_Fps ; + QTime m_CurrentTime; //Constants static const int TIMEOUT_SEC = 1; // 1 second