Added ROI an face detection
authorMohammed Sameer <msameer@foolab.org>
Tue, 29 Jan 2013 19:14:01 +0000 (21:14 +0200)
committerMohammed Sameer <msameer@foolab.org>
Tue, 29 Jan 2013 19:14:01 +0000 (21:14 +0200)
28 files changed:
data/n9/properties.ini
data/n9/qtcamera.ini
declarative/autofocus.cpp
declarative/autofocus.h
declarative/camera.cpp
declarative/camera.h
declarative/declarative.pro
declarative/plugin.cpp
declarative/roi.cpp [new file with mode: 0644]
declarative/roi.h [new file with mode: 0644]
lib/lib.pro
lib/qtcamanalysisbin.cpp
lib/qtcamanalysisbin.h
lib/qtcamautofocus.cpp
lib/qtcamautofocus.h
lib/qtcamautofocus_p.h
lib/qtcamconfig.cpp
lib/qtcamconfig.h
lib/qtcamdevice.h
lib/qtcampropertysetter.cpp
lib/qtcamroi.cpp [new file with mode: 0644]
lib/qtcamroi.h [new file with mode: 0644]
lib/qtcamroi_p.h [new file with mode: 0644]
qml/FocusReticle.qml
qml/ImagePage.qml
qml/ImageSettingsDialog.qml
src/settings.cpp
src/settings.h

index e3804cd..48f5f8d 100644 (file)
@@ -3,7 +3,7 @@ queue-size=6
 
 [motiondetect]
 use-local-buffer=false
 
 [motiondetect]
 use-local-buffer=false
-ratio=1, 2
+ratio=1,2
 
 [facetracking]
 use-local-buffer=false
 
 [facetracking]
 use-local-buffer=false
@@ -12,6 +12,7 @@ max-face-size=456
 max-num-faces=5
 tracking-interval=0
 draw-box=false
 max-num-faces=5
 tracking-interval=0
 draw-box=false
+event=false
 
 [mp4mux]
 dts-method=0
 
 [mp4mux]
 dts-method=0
index 77bec94..454d4ee 100644 (file)
@@ -176,3 +176,8 @@ autoFocusAcquired = /usr/share/sounds/ui-tones//snd_camera_af.wav
 
 [viewfinder-filters]
 elements = facetracking, motiondetect
 
 [viewfinder-filters]
 elements = facetracking, motiondetect
+
+[roi]
+element=facetracking
+enable=message
+message=regions-of-interest
index 2bfb6ea..ed08771 100644 (file)
@@ -52,7 +52,3 @@ bool AutoFocus::stopAutoFocus() {
 bool AutoFocus::canFocus(int sceneMode) {
   return m_af->canFocus((QtCamScene::SceneMode)sceneMode);
 }
 bool AutoFocus::canFocus(int sceneMode) {
   return m_af->canFocus((QtCamScene::SceneMode)sceneMode);
 }
-
-void AutoFocus::setRegionOfInterest(const QRectF& roi) {
-  return m_af->setRegionOfInterest(roi);
-}
index 0aecb79..14b20f7 100644 (file)
@@ -52,9 +52,6 @@ public:
   Status status();
   Status cafStatus();
 
   Status status();
   Status cafStatus();
 
-public slots:
-  void setRegionOfInterest(const QRectF& roi);
-
 signals:
   void valueChanged();
   void cafValueChanged();
 signals:
   void valueChanged();
   void cafValueChanged();
index 518f2f6..a20f9ac 100644 (file)
@@ -44,6 +44,7 @@
 #include "flickerreduction.h"
 #include "focus.h"
 #include "autofocus.h"
 #include "flickerreduction.h"
 #include "focus.h"
 #include "autofocus.h"
+#include "roi.h"
 
 #include "videomute.h"
 #include "videotorch.h"
 
 #include "videomute.h"
 #include "videotorch.h"
@@ -68,6 +69,7 @@ Camera::Camera(QDeclarativeItem *parent) :
   m_flickerReduction(0),
   m_focus(0),
   m_autoFocus(0),
   m_flickerReduction(0),
   m_focus(0),
   m_autoFocus(0),
+  m_roi(0),
   m_videoMute(0),
   m_videoTorch(0) {
 
   m_videoMute(0),
   m_videoTorch(0) {
 
@@ -100,6 +102,7 @@ Camera::~Camera() {
   delete m_flickerReduction;
   delete m_focus;
   delete m_autoFocus;
   delete m_flickerReduction;
   delete m_focus;
   delete m_autoFocus;
+  delete m_roi;
   delete m_videoMute;
   delete m_videoTorch;
 }
   delete m_videoMute;
   delete m_videoTorch;
 }
@@ -350,6 +353,10 @@ void Camera::resetCapabilities() {
   m_autoFocus = new AutoFocus(dev, this);
   emit autoFocusChanged();
 
   m_autoFocus = new AutoFocus(dev, this);
   emit autoFocusChanged();
 
+  delete m_roi;
+  m_roi = new Roi(dev, this);
+  emit roiChanged();
+
   delete m_videoMute;
   m_videoMute = new VideoMute(dev, this);
   emit videoMuteChanged();
   delete m_videoMute;
   m_videoMute = new VideoMute(dev, this);
   emit videoMuteChanged();
@@ -411,6 +418,10 @@ AutoFocus *Camera::autoFocus() const {
   return m_autoFocus;
 }
 
   return m_autoFocus;
 }
 
+Roi *Camera::roi() const {
+  return m_roi;
+}
+
 VideoMute *Camera::videoMute() const {
   return m_videoMute;
 }
 VideoMute *Camera::videoMute() const {
   return m_videoMute;
 }
index d34b7ed..232ad9e 100644 (file)
@@ -45,6 +45,7 @@ class NoiseReduction;
 class FlickerReduction;
 class Focus;
 class AutoFocus;
 class FlickerReduction;
 class Focus;
 class AutoFocus;
+class Roi;
 class VideoMute;
 class VideoTorch;
 
 class VideoMute;
 class VideoTorch;
 
@@ -76,6 +77,7 @@ class Camera : public QDeclarativeItem {
   Q_PROPERTY(FlickerReduction *flickerReduction READ flickerReduction NOTIFY flickerReductionChanged);
   Q_PROPERTY(Focus *focus READ focus NOTIFY focusChanged);
   Q_PROPERTY(AutoFocus *autoFocus READ autoFocus NOTIFY autoFocusChanged);
   Q_PROPERTY(FlickerReduction *flickerReduction READ flickerReduction NOTIFY flickerReductionChanged);
   Q_PROPERTY(Focus *focus READ focus NOTIFY focusChanged);
   Q_PROPERTY(AutoFocus *autoFocus READ autoFocus NOTIFY autoFocusChanged);
+  Q_PROPERTY(Roi *roi READ roi NOTIFY roiChanged);
 
   Q_PROPERTY(VideoMute *videoMute READ videoMute NOTIFY videoMuteChanged);
   Q_PROPERTY(VideoTorch *videoTorch READ videoTorch NOTIFY videoTorchChanged);
 
   Q_PROPERTY(VideoMute *videoMute READ videoMute NOTIFY videoMuteChanged);
   Q_PROPERTY(VideoTorch *videoTorch READ videoTorch NOTIFY videoTorchChanged);
@@ -133,6 +135,7 @@ public:
   FlickerReduction *flickerReduction() const;
   Focus *focus() const;
   AutoFocus *autoFocus() const;
   FlickerReduction *flickerReduction() const;
   Focus *focus() const;
   AutoFocus *autoFocus() const;
+  Roi *roi() const;
 
   VideoMute *videoMute() const;
   VideoTorch *videoTorch() const;
 
   VideoMute *videoMute() const;
   VideoTorch *videoTorch() const;
@@ -168,6 +171,7 @@ signals:
   void flickerReductionChanged();
   void focusChanged();
   void autoFocusChanged();
   void flickerReductionChanged();
   void focusChanged();
   void autoFocusChanged();
+  void roiChanged();
 
   void videoMuteChanged();
   void videoTorchChanged();
 
   void videoMuteChanged();
   void videoTorchChanged();
@@ -203,6 +207,7 @@ private:
   FlickerReduction *m_flickerReduction;
   Focus *m_focus;
   AutoFocus *m_autoFocus;
   FlickerReduction *m_flickerReduction;
   Focus *m_focus;
   AutoFocus *m_autoFocus;
+  Roi *m_roi;
 
   VideoMute *m_videoMute;
   VideoTorch *m_videoTorch;
 
   VideoMute *m_videoMute;
   VideoTorch *m_videoTorch;
index 91b21ba..6b25cca 100644 (file)
@@ -15,11 +15,13 @@ HEADERS += plugin.h previewprovider.h camera.h mode.h imagemode.h videomode.h \
            colortone.h exposure.h aperture.h iso.h noisereduction.h \
            flickerreduction.h videomute.h metadata.h imagesettings.h \
            imageresolutionmodel.h videosettings.h videoresolutionmodel.h \
            colortone.h exposure.h aperture.h iso.h noisereduction.h \
            flickerreduction.h videomute.h metadata.h imagesettings.h \
            imageresolutionmodel.h videosettings.h videoresolutionmodel.h \
-           notifications.h notificationscontainer.h sounds.h focus.h autofocus.h
+           notifications.h notificationscontainer.h sounds.h focus.h autofocus.h \
+           roi.h
 
 SOURCES += plugin.cpp previewprovider.cpp camera.cpp mode.cpp imagemode.cpp videomode.cpp \
            zoom.cpp flash.cpp scene.cpp evcomp.cpp videotorch.cpp whitebalance.cpp \
            colortone.cpp exposure.cpp aperture.cpp iso.cpp noisereduction.cpp \
            flickerreduction.cpp videomute.cpp metadata.cpp imagesettings.cpp \
            imageresolutionmodel.cpp videosettings.cpp videoresolutionmodel.cpp \
 
 SOURCES += plugin.cpp previewprovider.cpp camera.cpp mode.cpp imagemode.cpp videomode.cpp \
            zoom.cpp flash.cpp scene.cpp evcomp.cpp videotorch.cpp whitebalance.cpp \
            colortone.cpp exposure.cpp aperture.cpp iso.cpp noisereduction.cpp \
            flickerreduction.cpp videomute.cpp metadata.cpp imagesettings.cpp \
            imageresolutionmodel.cpp videosettings.cpp videoresolutionmodel.cpp \
-           notifications.cpp notificationscontainer.cpp sounds.cpp focus.cpp autofocus.cpp
+           notifications.cpp notificationscontainer.cpp sounds.cpp focus.cpp autofocus.cpp \
+           roi.cpp
index 08ef8df..5000a63 100644 (file)
@@ -37,6 +37,7 @@
 #include "flickerreduction.h"
 #include "focus.h"
 #include "autofocus.h"
 #include "flickerreduction.h"
 #include "focus.h"
 #include "autofocus.h"
+#include "roi.h"
 #include "videomute.h"
 #include "metadata.h"
 #include "imagesettings.h"
 #include "videomute.h"
 #include "metadata.h"
 #include "imagesettings.h"
@@ -70,6 +71,7 @@ void Plugin::registerTypes(QDeclarativeEngine *engine) {
   qmlRegisterUncreatableType<FlickerReduction>(URI, MAJOR, MINOR, "FlickerReduction", QObject::tr("Cannot create separate instance of FlickerReduction"));
   qmlRegisterUncreatableType<Focus>(URI, MAJOR, MINOR, "Focus", QObject::tr("Cannot create separate instance of Focus"));
   qmlRegisterUncreatableType<AutoFocus>(URI, MAJOR, MINOR, "AutoFocus", QObject::tr("Cannot create separate instance of AutoFocus"));
   qmlRegisterUncreatableType<FlickerReduction>(URI, MAJOR, MINOR, "FlickerReduction", QObject::tr("Cannot create separate instance of FlickerReduction"));
   qmlRegisterUncreatableType<Focus>(URI, MAJOR, MINOR, "Focus", QObject::tr("Cannot create separate instance of Focus"));
   qmlRegisterUncreatableType<AutoFocus>(URI, MAJOR, MINOR, "AutoFocus", QObject::tr("Cannot create separate instance of AutoFocus"));
+  qmlRegisterUncreatableType<Roi>(URI, MAJOR, MINOR, "Roi", QObject::tr("Cannot create separate instance of Roi"));
 
   qmlRegisterUncreatableType<VideoMute>(URI, MAJOR, MINOR, "VideoMute", QObject::tr("Cannot create separate instance of VideoMute"));
   qmlRegisterUncreatableType<VideoTorch>(URI, MAJOR, MINOR, "VideoTorch", QObject::tr("Cannot create separate instance of VideoTorch"));
 
   qmlRegisterUncreatableType<VideoMute>(URI, MAJOR, MINOR, "VideoMute", QObject::tr("Cannot create separate instance of VideoMute"));
   qmlRegisterUncreatableType<VideoTorch>(URI, MAJOR, MINOR, "VideoTorch", QObject::tr("Cannot create separate instance of VideoTorch"));
diff --git a/declarative/roi.cpp b/declarative/roi.cpp
new file mode 100644 (file)
index 0000000..65a9643
--- /dev/null
@@ -0,0 +1,76 @@
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "roi.h"
+#include "qtcamroi.h"
+
+Roi::Roi(QtCamDevice *device, QObject *parent) :
+  QObject(parent),
+  m_roi(new QtCamRoi(device)) {
+
+  QObject::connect(m_roi,
+                  SIGNAL(regionsOfInterestUpdated(const QList<QRectF>&, const QRectF&, const QList<QRectF>&)),
+                  this,
+                  SLOT(handleRegionsChanged(const QList<QRectF>&, const QRectF&, const QList<QRectF>&)));
+}
+
+Roi::~Roi() {
+  delete m_roi; m_roi = 0;
+}
+
+
+void Roi::setEnabled(bool enabled) {
+  if (Roi::isEnabled() != enabled) {
+    m_roi->setEnabled(enabled);
+    emit enabledChanged();
+  }
+}
+
+bool Roi::isEnabled() {
+  return m_roi->isEnabled();
+}
+
+void Roi::setRegionOfInterest(const QRectF& region) {
+  m_roi->setRegionOfInterest(region);
+}
+
+void Roi::resetRegionOfInterest() {
+  m_roi->resetRegionOfInterest();
+}
+
+void Roi::handleRegionsChanged(const QList<QRectF>& regions, const QRectF& primary,
+                              const QList<QRectF>& rest) {
+
+  QVariantList regionsList = variantList(regions);
+  QVariantList restList = variantList(rest);
+  QVariant primaryRect = QVariant::fromValue(primary);
+
+  emit regionsChanged(regionsList, primaryRect, restList);
+}
+
+QVariantList Roi::variantList(const QList<QRectF>& rects) {
+  QVariantList list;
+
+  foreach(const QRectF& rect, rects) {
+    list.append(QVariant::fromValue(rect));
+  }
+
+  return list;
+}
diff --git a/declarative/roi.h b/declarative/roi.h
new file mode 100644 (file)
index 0000000..c019d2a
--- /dev/null
@@ -0,0 +1,66 @@
+// -*- c++ -*-
+
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef ROI_H
+#define ROI_H
+
+#include <QObject>
+#include <QRectF>
+#include <QVariantList>
+
+class QtCamDevice;
+class QtCamRoi;
+
+class Roi : public QObject {
+  Q_OBJECT
+
+  Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged);
+
+public:
+  Roi(QtCamDevice *device, QObject *parent = 0);
+  ~Roi();
+
+  void setEnabled(bool enabled);
+  bool isEnabled();
+
+  QList<QRectF> regions();
+
+public slots:
+  void setRegionOfInterest(const QRectF& region);
+  void resetRegionOfInterest();
+
+signals:
+  void enabledChanged();
+  void regionsChanged(const QVariantList& regions, const QVariant& primary,
+                     const QVariantList& rest);
+
+private slots:
+  void handleRegionsChanged(const QList<QRectF>& regions, const QRectF& primary,
+                           const QList<QRectF>& rest);
+
+private:
+  QVariantList variantList(const QList<QRectF>& rects);
+
+  QtCamRoi *m_roi;
+};
+
+#endif /* ROI_H */
index 38c797c..4cdee5b 100644 (file)
@@ -19,7 +19,7 @@ HEADERS += qtcamconfig.h qtcamera.h qtcamscanner.h qtcamdevice.h qtcamviewfinder
            qtcamwhitebalance.h qtcamcolortone.h qtcamflickerreduction.h \
            qtcamnoisereduction.h qtcamiso.h qtcamaperture.h qtcamexposure.h \
            qtcamvideomute.h qtcamnotifications.h qtcamfocus.h qtcamautofocus.h \
            qtcamwhitebalance.h qtcamcolortone.h qtcamflickerreduction.h \
            qtcamnoisereduction.h qtcamiso.h qtcamaperture.h qtcamexposure.h \
            qtcamvideomute.h qtcamnotifications.h qtcamfocus.h qtcamautofocus.h \
-           qtcamanalysisbin.h qtcampropertysetter.h
+           qtcamanalysisbin.h qtcampropertysetter.h qtcamroi.h
 
 SOURCES += qtcamconfig.cpp qtcamera.cpp qtcamscanner.cpp qtcamdevice.cpp qtcamviewfinder.cpp \
            qtcammode.cpp qtcamgstreamermessagehandler.cpp qtcamgstreamermessagelistener.cpp \
 
 SOURCES += qtcamconfig.cpp qtcamera.cpp qtcamscanner.cpp qtcamdevice.cpp qtcamviewfinder.cpp \
            qtcammode.cpp qtcamgstreamermessagehandler.cpp qtcamgstreamermessagelistener.cpp \
@@ -30,10 +30,10 @@ SOURCES += qtcamconfig.cpp qtcamera.cpp qtcamscanner.cpp qtcamdevice.cpp qtcamvi
            qtcamwhitebalance.cpp qtcamcolortone.cpp qtcamflickerreduction.cpp \
            qtcamnoisereduction.cpp qtcamiso.cpp qtcamaperture.cpp qtcamexposure.cpp \
            qtcamvideomute.cpp qtcamnotifications.cpp qtcamfocus.cpp qtcamautofocus.cpp \
            qtcamwhitebalance.cpp qtcamcolortone.cpp qtcamflickerreduction.cpp \
            qtcamnoisereduction.cpp qtcamiso.cpp qtcamaperture.cpp qtcamexposure.cpp \
            qtcamvideomute.cpp qtcamnotifications.cpp qtcamfocus.cpp qtcamautofocus.cpp \
-           qtcamanalysisbin.cpp qtcampropertysetter.cpp
+           qtcamanalysisbin.cpp qtcampropertysetter.cpp qtcamroi.cpp
 
 HEADERS += qtcammode_p.h qtcamdevice_p.h qtcamcapability_p.h qtcamautofocus_p.h \
 
 HEADERS += qtcammode_p.h qtcamdevice_p.h qtcamcapability_p.h qtcamautofocus_p.h \
-           qtcamnotifications_p.h qtcamflash_p.h
+           qtcamnotifications_p.h qtcamflash_p.h qtcamroi_p.h
 
 LIBS += -lgstphotography-0.10
 
 
 LIBS += -lgstphotography-0.10
 
index f38e2c2..5c093a8 100644 (file)
 #include "qtcamanalysisbin.h"
 #include <QStringList>
 #include <QDebug>
 #include "qtcamanalysisbin.h"
 #include <QStringList>
 #include <QDebug>
+#include <QHash>
 
 #define FACTORY_NAME(x) gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(gst_element_get_factory(x)))
 
 
 #define FACTORY_NAME(x) gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(gst_element_get_factory(x)))
 
-static GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children,
-                                             const char *name, GstPad **queuePad);
-static GstElement *qt_cam_analysis_bin_create(GstElement *child,
-                                             const char *name, GstPad **queuePad);
+static QtCamAnalysisBinPrivate *qt_cam_analysis_bin_create(const QStringList& factories,
+                                                          const char *name);
+static QtCamAnalysisBinPrivate *qt_cam_analysis_bin_create(GstElement *child,
+                                                          const char *name);
 
 class QtCamAnalysisBinPrivate {
 public:
 
 class QtCamAnalysisBinPrivate {
 public:
@@ -49,6 +50,7 @@ public:
   GstElement *bin;
   gulong probe;
   GstPad *queuePad;
   GstElement *bin;
   gulong probe;
   GstPad *queuePad;
+  QMultiHash<QString, GstElement *> elements;
 };
 
 QtCamAnalysisBin::QtCamAnalysisBin(QtCamAnalysisBinPrivate *d) :
 };
 
 QtCamAnalysisBin::QtCamAnalysisBin(QtCamAnalysisBinPrivate *d) :
@@ -57,6 +59,8 @@ QtCamAnalysisBin::QtCamAnalysisBin(QtCamAnalysisBinPrivate *d) :
 }
 
 QtCamAnalysisBin::~QtCamAnalysisBin() {
 }
 
 QtCamAnalysisBin::~QtCamAnalysisBin() {
+  d_ptr->elements.clear();
+
   setBlocked(false);
   gst_object_unref(GST_OBJECT(d_ptr->queuePad));
   gst_object_unref(d_ptr->bin);
   setBlocked(false);
   gst_object_unref(GST_OBJECT(d_ptr->queuePad));
   gst_object_unref(d_ptr->bin);
@@ -93,63 +97,51 @@ QtCamAnalysisBin *QtCamAnalysisBin::create(const QStringList& factories, const c
     return 0;
   }
 
     return 0;
   }
 
-  foreach (const QString& factory, factories) {
-    GstElement *element = gst_element_factory_make(factory.toUtf8().constData(), NULL);
-    if (!element) {
-      qWarning() << "Failed to create element" << factory;
-      continue;
-    }
-
-    elements << element;
-  }
-
-  GstPad *pad = 0;
-  GstElement *bin = qt_cam_analysis_bin_create(elements, name, &pad);
-  if (!bin) {
+  QtCamAnalysisBinPrivate *d = qt_cam_analysis_bin_create(factories, name);
+  if (!d) {
     return 0;
   }
 
     return 0;
   }
 
-  QtCamAnalysisBinPrivate *d = new QtCamAnalysisBinPrivate;
-  d->bin = bin;
-  d->queuePad = pad;
-
   return new QtCamAnalysisBin(d);
 }
 
   return new QtCamAnalysisBin(d);
 }
 
-GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children,
-                                      const char *name, GstPad **queuePad) {
-  GstElement *bin = 0;
+QtCamAnalysisBinPrivate *qt_cam_analysis_bin_create(const QStringList& factories,
+                                                   const char *name) {
 
 
-  QList<GstElement *> added;
-
-  if (children.isEmpty()) {
+  if (factories.isEmpty()) {
     return 0;
   }
 
     return 0;
   }
 
-  if (children.size() == 1) {
-    return qt_cam_analysis_bin_create(children.takeFirst(), name, queuePad);
-  }
+  GstElement *bin = 0;
+  QHash<QString, GstElement *> elements;
+  QList<GstElement *> added;
 
   bin = gst_bin_new("analysis-bin-bin");
 
 
   bin = gst_bin_new("analysis-bin-bin");
 
-  while (!children.isEmpty()) {
-    GstElement *elem = children.takeFirst();
-
-    if (!gst_bin_add(GST_BIN(bin), elem)) {
-      qWarning() << "Failed to add element" << FACTORY_NAME(elem) << "to bin";
-      gst_object_unref(elem);
+  foreach (const QString& factory, factories) {
+    GstElement *element = gst_element_factory_make(factory.toUtf8().constData(), NULL);
+    if (!element) {
+      qWarning() << "Failed to create element" << factory;
+      continue;
     }
     }
-    else {
-      added << elem;
+
+    if (!gst_bin_add(GST_BIN(bin), element)) {
+      qWarning() << "Failed to add element" << factory << "to bin";
+      gst_object_unref(element);
     }
     }
+
+    elements.insert(factory, element);
+    added << element;
   }
 
   }
 
-  for (int x = 1; x < added.count(); x++) {
-    GstElement *elem = added[x];
-    GstElement *prev = added[x - 1];
+  if (added.size() > 1) {
+    for (int x = 1; x < added.count(); x++) {
+      GstElement *elem = added[x];
+      GstElement *prev = added[x - 1];
 
 
-    if (!gst_element_link(prev, elem)) {
-      qWarning() << "Failed to link" << FACTORY_NAME(prev) << "and" << FACTORY_NAME(elem);
+      if (!gst_element_link(prev, elem)) {
+       qWarning() << "Failed to link" << FACTORY_NAME(prev) << "and" << FACTORY_NAME(elem);
+      }
     }
   }
 
     }
   }
 
@@ -161,7 +153,14 @@ GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children,
   gst_element_add_pad(bin, gst_ghost_pad_new("src", pad));
   gst_object_unref(GST_OBJECT(pad));
 
   gst_element_add_pad(bin, gst_ghost_pad_new("src", pad));
   gst_object_unref(GST_OBJECT(pad));
 
-  return qt_cam_analysis_bin_create(bin, name, queuePad);
+  QtCamAnalysisBinPrivate *d = qt_cam_analysis_bin_create(bin, name);
+  if (!d) {
+    return 0;
+  }
+
+  d->elements = elements;
+
+  return d;
 }
 
 /*
 }
 
 /*
@@ -169,8 +168,10 @@ GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children,
  * tee -
  *       -- queue -- copy -- filters -- fakesink
  */
  * tee -
  *       -- queue -- copy -- filters -- fakesink
  */
-GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name, GstPad **queuePad) {
+QtCamAnalysisBinPrivate *qt_cam_analysis_bin_create(GstElement *child, const char *name) {
   GstPad *pad = 0;
   GstPad *pad = 0;
+  GstPad *queuePad = 0;
+  QtCamAnalysisBinPrivate *d = 0;
 
   GstElement *bin = gst_bin_new(name);
 
 
   GstElement *bin = gst_bin_new(name);
 
@@ -210,9 +211,12 @@ GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name, GstP
   g_object_set(tee, "alloc-pad", pad, NULL);
   gst_object_unref(GST_OBJECT(pad));
 
   g_object_set(tee, "alloc-pad", pad, NULL);
   gst_object_unref(GST_OBJECT(pad));
 
-  *queuePad = gst_element_get_static_pad(queue, "src");
+  queuePad = gst_element_get_static_pad(queue, "src");
 
 
-  return bin;
+  d = new QtCamAnalysisBinPrivate;
+  d->queuePad = queuePad;
+  d->bin = bin;
+  return d;
 
  free_and_out:
   if (bin) {
 
  free_and_out:
   if (bin) {
@@ -244,3 +248,11 @@ GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name, GstP
 
   return 0;
 }
 
   return 0;
 }
+
+QList<GstElement *> QtCamAnalysisBin::lookup(const QString& factory) {
+  if (d_ptr->elements.contains(factory)) {
+    return d_ptr->elements.values(factory);
+  }
+
+  return QList<GstElement *>();
+}
index 8fb29fd..8de3877 100644 (file)
@@ -28,6 +28,7 @@
 
 class QtCamAnalysisBinPrivate;
 class QStringList;
 
 class QtCamAnalysisBinPrivate;
 class QStringList;
+class QString;
 
 class QtCamAnalysisBin {
 public:
 
 class QtCamAnalysisBin {
 public:
@@ -40,6 +41,8 @@ public:
 
   GstElement *bin();
 
 
   GstElement *bin();
 
+  QList<GstElement *> lookup(const QString& factory);
+
 private:
   QtCamAnalysisBin(QtCamAnalysisBinPrivate *d);
 
 private:
   QtCamAnalysisBin(QtCamAnalysisBinPrivate *d);
 
index 96a4073..5dd6354 100644 (file)
 
 #include "qtcamautofocus.h"
 #include "qtcamautofocus_p.h"
 
 #include "qtcamautofocus.h"
 #include "qtcamautofocus_p.h"
-#include <QRectF>
-
-#ifndef G_VALUE_INIT
-#define G_VALUE_INIT  { 0, { { 0 } } }
-#endif /* G_VALUE_INIT */
 
 QtCamAutoFocus::QtCamAutoFocus(QtCamDevice *dev, QObject *parent) :
   QObject(parent),
 
 QtCamAutoFocus::QtCamAutoFocus(QtCamDevice *dev, QObject *parent) :
   QObject(parent),
@@ -59,57 +54,3 @@ bool QtCamAutoFocus::canFocus(const QtCamScene::SceneMode& mode) {
 
   return true;
 }
 
   return true;
 }
-
-void QtCamAutoFocus::setRegionOfInterest(const QRectF& roi) {
-  if (!d_ptr->dev || !d_ptr->dev->viewfinder()) {
-    return;
-  }
-
-  QSizeF vf = d_ptr->dev->viewfinder()->videoResolution();
-  if (vf.isEmpty()) {
-    return;
-  }
-
-  int frameWidth = vf.width();
-  int frameHeight = vf.height();
-  int x = roi.x() * frameWidth;
-  int y = roi.y() * frameHeight;
-  int width = roi.width() * frameWidth;
-  int height = roi.height() * frameHeight;
-
-  // if we have an empty roi then we reset:
-  int priority = roi.isEmpty() ? 0 : 1;
-
-  GstStructure *region = gst_structure_new("region0",
-                                          "region-x", G_TYPE_UINT, x,
-                                          "region-y", G_TYPE_UINT, y,
-                                          "region-w", G_TYPE_UINT, width,
-                                          "region-h", G_TYPE_UINT, height,
-                                          "region-priority", G_TYPE_UINT, priority,
-                                          "region-id", G_TYPE_UINT, 0,
-                                          NULL);
-
-  GValue regionValue = G_VALUE_INIT;
-  GValue regionList = G_VALUE_INIT;
-
-  g_value_init(&regionValue, GST_TYPE_STRUCTURE);
-  g_value_init(&regionList, GST_TYPE_LIST);
-
-  gst_value_set_structure(&regionValue, region);
-  gst_value_list_append_value(&regionList, &regionValue);
-
-  GstStructure *s = gst_structure_new("regions-of-interest",
-                                     "frame-width", G_TYPE_UINT, frameWidth,
-                                     "frame-height", G_TYPE_UINT, frameHeight,
-                                     NULL);
-  gst_structure_set_value(s, "regions", &regionList);
-
-  GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_UPSTREAM, s);
-  gst_structure_free(region);
-  g_value_unset(&regionValue);
-  g_value_unset(&regionList);
-
-  if (!d_ptr->sendEventToSource(event)) {
-    qWarning() << "Failed to send ROI event";
-  }
-}
index 7459508..11c5759 100644 (file)
@@ -28,7 +28,6 @@
 
 class QtCamDevice;
 class QtCamAutoFocusPrivate;
 
 class QtCamDevice;
 class QtCamAutoFocusPrivate;
-class QRectF;
 
 class QtCamAutoFocus : public QObject {
   Q_OBJECT
 
 class QtCamAutoFocus : public QObject {
   Q_OBJECT
@@ -57,8 +56,6 @@ public:
 
   bool canFocus(const QtCamScene::SceneMode& mode);
 
 
   bool canFocus(const QtCamScene::SceneMode& mode);
 
-  void setRegionOfInterest(const QRectF& roi);
-
 signals:
   void statusChanged();
   void cafStatusChanged();
 signals:
   void statusChanged();
   void cafStatusChanged();
index a1ea0c5..efe6a2c 100644 (file)
@@ -113,16 +113,6 @@ public:
     return false;
   }
 
     return false;
   }
 
-  bool sendEventToSource(GstEvent *event) {
-    if (!dev->d_ptr->videoSource) {
-      qWarning() << "No video source";
-      gst_event_unref(event);
-      return false;
-    }
-
-    return gst_element_send_event(dev->d_ptr->videoSource, event) == TRUE ? true : false;
-  }
-
 public slots:
   void handleMessage(GstMessage *message) {
     if (setStatus(&status, message)) {
 public slots:
   void handleMessage(GstMessage *message) {
     if (setStatus(&status, message)) {
index b056078..4598cf6 100644 (file)
@@ -219,3 +219,19 @@ QString QtCamConfig::autoFocusAcquiredSound() const {
 QStringList QtCamConfig::viewfinderFilters() const {
   return d_ptr->conf->value("viewfinder-filters/elements").toStringList();
 }
 QStringList QtCamConfig::viewfinderFilters() const {
   return d_ptr->conf->value("viewfinder-filters/elements").toStringList();
 }
+
+QString QtCamConfig::roiElement() const {
+  return d_ptr->conf->value("roi/element").toString();
+}
+
+QString QtCamConfig::roiMessageName() const {
+  return d_ptr->conf->value("roi/message").toString();
+}
+
+QString QtCamConfig::roiEnableProperty() const {
+  return d_ptr->conf->value("roi/enable").toString();
+}
+
+QString QtCamConfig::roiMessage() const {
+  return d_ptr->conf->value("roi/message").toString();
+}
index a60e923..25a0a86 100644 (file)
@@ -84,6 +84,11 @@ public:
 
   QStringList viewfinderFilters() const;
 
 
   QStringList viewfinderFilters() const;
 
+  QString roiElement() const;
+  QString roiMessageName() const;
+  QString roiEnableProperty() const;
+  QString roiMessage() const;
+
 private:
   QtCamConfigPrivate *d_ptr;
 };
 private:
   QtCamConfigPrivate *d_ptr;
 };
index 34f72e8..d67aa4e 100644 (file)
@@ -85,6 +85,7 @@ private:
   friend class QtCamVideoTorch;
   friend class QtCamVideoMute;
   friend class QtCamAutoFocusPrivate;
   friend class QtCamVideoTorch;
   friend class QtCamVideoMute;
   friend class QtCamAutoFocusPrivate;
+  friend class QtCamRoiPrivate;
 
   QtCamDevicePrivate *d_ptr;
 };
 
   QtCamDevicePrivate *d_ptr;
 };
index 4f10833..28fceb9 100644 (file)
@@ -54,14 +54,14 @@ public:
 
        gst_object_unref(elem);
        break;
 
        gst_object_unref(elem);
        break;
+
       case GST_ITERATOR_RESYNC:
        gst_iterator_resync(iter);
        break;
       case GST_ITERATOR_RESYNC:
        gst_iterator_resync(iter);
        break;
+
       case GST_ITERATOR_ERROR:
       case GST_ITERATOR_ERROR:
-       done = TRUE;
-       break;
       case GST_ITERATOR_DONE:
       case GST_ITERATOR_DONE:
-       done = TRUE;
+       done = true;
        break;
       }
     }
        break;
       }
     }
diff --git a/lib/qtcamroi.cpp b/lib/qtcamroi.cpp
new file mode 100644 (file)
index 0000000..fc7e3b7
--- /dev/null
@@ -0,0 +1,124 @@
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "qtcamroi.h"
+#include "qtcamroi_p.h"
+
+#ifndef G_VALUE_INIT
+#define G_VALUE_INIT  { 0, { { 0 } } }
+#endif /* G_VALUE_INIT */
+
+QtCamRoi::QtCamRoi(QtCamDevice *dev, QObject *parent) :
+  QObject(parent),
+  d_ptr(new QtCamRoiPrivate(dev, this, this)) {
+
+  d_ptr->init();
+  d_ptr->installHandler();
+}
+
+QtCamRoi::~QtCamRoi() {
+  delete d_ptr; d_ptr = 0;
+}
+
+void QtCamRoi::setRegionOfInterest(const QRectF& roi) {
+  if (!d_ptr->dev || !d_ptr->dev->viewfinder()) {
+    return;
+  }
+
+  QSizeF vf = d_ptr->dev->viewfinder()->videoResolution();
+  if (vf.isEmpty()) {
+    return;
+  }
+
+  int frameWidth = vf.width();
+  int frameHeight = vf.height();
+  int x = roi.x() * frameWidth;
+  int y = roi.y() * frameHeight;
+  int width = roi.width() * frameWidth;
+  int height = roi.height() * frameHeight;
+
+  // if we have an empty roi then we reset:
+  int priority = roi.isEmpty() ? 0 : 1;
+
+  GstStructure *region = gst_structure_new("region0",
+                                          "region-x", G_TYPE_UINT, x,
+                                          "region-y", G_TYPE_UINT, y,
+                                          "region-w", G_TYPE_UINT, width,
+                                          "region-h", G_TYPE_UINT, height,
+                                          "region-priority", G_TYPE_UINT, priority,
+                                          "region-id", G_TYPE_UINT, 0,
+                                          NULL);
+
+  GValue regionValue = G_VALUE_INIT;
+  GValue regionList = G_VALUE_INIT;
+
+  g_value_init(&regionValue, GST_TYPE_STRUCTURE);
+  g_value_init(&regionList, GST_TYPE_LIST);
+
+  gst_value_set_structure(&regionValue, region);
+  gst_value_list_append_value(&regionList, &regionValue);
+
+  GstStructure *s = gst_structure_new("regions-of-interest",
+                                     "frame-width", G_TYPE_UINT, frameWidth,
+                                     "frame-height", G_TYPE_UINT, frameHeight,
+                                     NULL);
+  gst_structure_set_value(s, "regions", &regionList);
+
+  GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_UPSTREAM, s);
+  gst_structure_free(region);
+  g_value_unset(&regionValue);
+  g_value_unset(&regionList);
+
+  if (!d_ptr->sendEventToSource(event)) {
+    qWarning() << "Failed to send ROI event";
+  }
+}
+
+void QtCamRoi::resetRegionOfInterest() {
+  setRegionOfInterest(QRectF());
+}
+
+void QtCamRoi::setEnabled(bool enabled) {
+  if (enabled == isEnabled()) {
+    return;
+  }
+
+  if (!d_ptr->roi) {
+    return;
+  }
+
+  gboolean val = enabled ? TRUE : FALSE;
+
+  g_object_set(d_ptr->roi, d_ptr->dev->config()->roiEnableProperty().toUtf8().constData(),
+              val, NULL);
+}
+
+bool QtCamRoi::isEnabled() {
+  if (!d_ptr->roi) {
+    return false;
+  }
+
+  gboolean val = FALSE;
+
+  g_object_get(d_ptr->roi, d_ptr->dev->config()->roiEnableProperty().toUtf8().constData(),
+              &val, NULL);
+
+  return val == TRUE;
+}
diff --git a/lib/qtcamroi.h b/lib/qtcamroi.h
new file mode 100644 (file)
index 0000000..90e8d9c
--- /dev/null
@@ -0,0 +1,56 @@
+// -*- c++ -*-
+
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef QT_CAM_ROI_H
+#define QT_CAM_ROI_H
+
+#include <QObject>
+
+class QtCamDevice;
+class QtCamRoiPrivate;
+class QRectF;
+
+class QtCamRoi : public QObject {
+  Q_OBJECT
+  friend class QtCamRoiPrivate;
+
+public:
+  QtCamRoi(QtCamDevice *dev, QObject *parent = 0);
+  ~QtCamRoi();
+
+  void setRegionOfInterest(const QRectF& roi);
+  void resetRegionOfInterest();
+
+  void setEnabled(bool enabled);
+
+  bool isEnabled();
+
+signals:
+  void regionsOfInterestUpdated(const QList<QRectF>& regions,
+                               const QRectF& primary,
+                               const QList<QRectF>& rest);
+
+private:
+  QtCamRoiPrivate *d_ptr;
+};
+
+#endif /* QT_CAM_ROI_H */
diff --git a/lib/qtcamroi_p.h b/lib/qtcamroi_p.h
new file mode 100644 (file)
index 0000000..6118da0
--- /dev/null
@@ -0,0 +1,199 @@
+// -*- c++ -*-
+
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef QT_CAM_ROI_P_H
+#define QT_CAM_ROI_P_H
+
+#include "qtcamdevice.h"
+#include "qtcamdevice_p.h"
+#include "qtcamanalysisbin.h"
+#include "qtcamgstreamermessagehandler.h"
+#include "qtcamgstreamermessagelistener.h"
+#include "qtcamroi.h"
+#include <QDebug>
+#include <QPointer>
+#include <cmath>
+
+class QtCamRoiPrivate : public QObject {
+  Q_OBJECT
+
+public:
+  QtCamRoiPrivate(QtCamDevice *device, QtCamRoi *q, QObject *parent = 0) :
+    QObject(parent),
+    q_ptr(q),
+    dev(device),
+    roi(0),
+    msg(0) {
+
+  }
+
+  ~QtCamRoiPrivate() {
+    if (roi) {
+      gst_object_unref(roi);
+    }
+
+    if (handler) {
+      dev->listener()->removeSyncHandler(handler);
+
+      delete handler.data();
+    }
+
+    GstMessage *message = msg.fetchAndStoreOrdered(0);
+    if (message) {
+      gst_message_unref(message);
+      message = 0;
+    }
+  }
+
+  bool sendEventToSource(GstEvent *event) {
+    if (!dev->d_ptr->videoSource) {
+      qWarning() << "No video source";
+      gst_event_unref(event);
+      return false;
+    }
+
+    return gst_element_send_event(dev->d_ptr->videoSource, event) == TRUE ? true : false;
+  }
+
+  void init() {
+    if (!dev->d_ptr->viewfinderFilters) {
+      return;
+    }
+
+    QList<GstElement *> elements =
+      dev->d_ptr->viewfinderFilters->lookup(dev->config()->roiElement());
+    if (elements.isEmpty()) {
+      qWarning() << "Cannot find element" << dev->config()->roiElement();
+    }
+    else if (elements.size() > 1) {
+      qWarning() << "Found multiple element of" << dev->config()->roiElement();
+    }
+    else {
+      roi = GST_ELEMENT(gst_object_ref(elements.at(0)));
+    }
+  }
+
+  void installHandler() {
+
+    if (dev->listener()) {
+      handler = new QtCamGStreamerMessageHandler(dev->config()->roiMessage(), this);
+      dev->listener()->addSyncHandler(handler);
+      QObject::connect(handler, SIGNAL(messageSent(GstMessage *)),
+                      this, SLOT(handleMessage(GstMessage *)), Qt::DirectConnection);
+    }
+  }
+
+  int primaryRegion(const QRectF& area, const QList<QRectF>& rects) {
+    int index = -1;
+    qreal distance = 0.0;
+    QPointF center = area.center();
+
+    for (int x = 0; x < rects.size(); x++) {
+      const QRectF& rect = rects.at(x);
+
+      QPointF val = rect.center() - center;
+
+      qreal newDistance = sqrt(pow(val.x(), 2) + pow(val.y(), 2));
+      if (index == -1 || newDistance < distance) {
+       index = x;
+       distance = newDistance;
+      }
+    }
+
+    return -1;
+  }
+
+public slots:
+  void handleMessage(GstMessage *message) {
+    gst_message_ref(message);
+
+    GstMessage *oldMessage = msg.fetchAndStoreOrdered(message);
+
+    if (oldMessage) {
+      gst_message_unref(oldMessage);
+    }
+
+    QMetaObject::invokeMethod(this, "processMessage", Qt::QueuedConnection);
+  }
+
+private slots:
+  void processMessage() {
+    GstMessage *message = msg.fetchAndStoreOrdered(0);
+    if (!message) {
+      return;
+    }
+
+    QList<QRectF> rects;
+    unsigned width = 0, height = 0;
+
+    const GstStructure *s = gst_message_get_structure(message);
+    if (!gst_structure_get_uint(s, "frame-width", &width) ||
+       !gst_structure_get_uint(s, "frame-height", &height)) {
+
+      qWarning() << "Failed to obtain frame dimensions for ROI message";
+      gst_message_unref(message);
+      return;
+    }
+
+    const GValue *regions = gst_structure_get_value(s, "regions");
+    if (!regions) {
+      qWarning() << "No regions in ROI message";
+      gst_message_unref(message);
+      return;
+    }
+
+    guint size = gst_value_list_get_size(regions);
+    for (unsigned i = 0; i < size; i++) {
+      const GValue *region = gst_value_list_get_value(regions, i);
+      const GstStructure *structure = gst_value_get_structure(region);
+
+      unsigned x = 0, y = 0, w = 0, h = 0;
+
+      gst_structure_get_uint(structure, "region-x", &x);
+      gst_structure_get_uint(structure, "region-y", &y);
+      gst_structure_get_uint(structure, "region-w", &w);
+      gst_structure_get_uint(structure, "region-h", &h);
+
+      QRectF rect((qreal)x/width, (qreal)y/height, (qreal)w/width, (qreal)h/height);
+
+      rects << rect;
+    }
+
+    int index = primaryRegion(QRectF(0, 0, width, height), rects);
+
+    QList<QRectF> rest(rects);
+    QRectF primary = index == -1 ? QRectF() : rest.takeAt(index);
+
+    emit q_ptr->regionsOfInterestUpdated(rects, primary, rest);
+
+    gst_message_unref(message);
+  }
+
+public:
+  QtCamRoi *q_ptr;
+  QtCamDevice *dev;
+  GstElement *roi;
+  QPointer<QtCamGStreamerMessageHandler> handler;
+  QAtomicPointer<GstMessage> msg;
+};
+
+#endif /* QT_CAM_ROI_P_H */
index 34d0329..bb6b0be 100644 (file)
@@ -49,7 +49,7 @@ MouseArea {
                 // thus we do it here
                 onModeChanged: {
                         moveToCenter();
                 // thus we do it here
                 onModeChanged: {
                         moveToCenter();
-                        cam.autoFocus.setRegionOfInterest(Qt.rect(0, 0, 0, 0));
+                        cam.roi.resetRegionOfInterest();
                 }
         }
 
                 }
         }
 
@@ -140,7 +140,7 @@ MouseArea {
         function setRegionOfInterest() {
                 if (!reticle.touchMode) {
 //                        console.log("resetting ROI");
         function setRegionOfInterest() {
                 if (!reticle.touchMode) {
 //                        console.log("resetting ROI");
-                        cam.autoFocus.setRegionOfInterest(Qt.rect(0, 0, 0, 0));
+                        cam.roi.resetRegionOfInterest();
                         return;
                 }
 
                         return;
                 }
 
@@ -164,7 +164,7 @@ MouseArea {
                 height = height / cam.videoResolution.height;
 
 //                console.log("Setting ROI to: " + x + " " + y);
                 height = height / cam.videoResolution.height;
 
 //                console.log("Setting ROI to: " + x + " " + y);
-                cam.autoFocus.setRegionOfInterest(Qt.rect(x, y, width, height));
+                cam.roi.setRegionOfInterest(Qt.rect(x, y, width, height));
         }
 
         onReleased: {
         }
 
         onReleased: {
index cd6ba72..53c012b 100644 (file)
@@ -169,6 +169,13 @@ CameraPage {
                                         alwaysRunToEnd: true
                                 }
                         }
                                         alwaysRunToEnd: true
                                 }
                         }
+
+                        Indicator {
+                                id: faceDetectionIndicator
+                                visible: settings.faceDetectionEnabled
+                                source: "image://theme/icon-m-camera-face-detection-screen"
+                        }
+
                 }
         }
 
                 }
         }
 
index 1b7fe97..5a64acf 100644 (file)
@@ -125,6 +125,26 @@ Dialog {
                                         }
                                 }
 
                                         }
                                 }
 
+                                Item {
+                                        width: parent.width
+                                        height: Math.max(enableFaceDetectionLabel.height, enableFaceDetection.height);
+
+                                        Label {
+                                                id: enableFaceDetectionLabel
+                                                anchors.left: parent.left
+                                                text: qsTr("Enable face detection");
+                                        }
+
+                                        Switch {
+                                                id: enableFaceDetection
+                                                anchors.right: parent.right
+                                                // We have to do it that way because QML complains about a binding
+                                                // loop for checked if we bind the checked property to the settings value.
+                                                Component.onCompleted: checked = settings.faceDetectionEnabled;
+                                                onCheckedChanged: settings.faceDetectionEnabled = checked;
+                                        }
+                                }
+
                                 CameraSettings {
                                         anchors.horizontalCenter: parent.horizontalCenter
                                 }
                                 CameraSettings {
                                         anchors.horizontalCenter: parent.horizontalCenter
                                 }
index 8d16faa..f3e6738 100644 (file)
 
 #define PATH QString("%1%2.config%2/cameraplus.conf").arg(QDir::homePath()).arg(QDir::separator())
 
 
 #define PATH QString("%1%2.config%2/cameraplus.conf").arg(QDir::homePath()).arg(QDir::separator())
 
-#define DEFAULT_MODE               1
-#define DEFAULT_SCENE_MODE         6 // Auto
-#define DEFAULT_USE_GPS            true
-#define DEFAULT_USE_GEOTAGS        true
-#define DEFAULT_COLOR_FILTER       0
-#define DEFAULT_WHITE_BALANCE      0
-#define DEFAULT_EV_COMP            0.0
-#define DEFAULT_FLASH_MODE         0
-#define DEFAULT_IMAGE_ISO          0
-#define DEFAULT_IMAGE_RESOLUTION   "high"
-#define DEFAULT_IMAGE_ASPECT_RATIO "16:9"
-#define DEFAULT_VIDEO_RESOLUTION   "high"
-#define DEFAULT_SOUND_ENABLED      true
-#define DEFAULT_VIDEO_TORCH_ON     false
-#define DEFAULT_SHOW_TOOL_BAR      false
-#define DEFAULT_VIDEO_MUTE         false
-#define DEFAULT_GRID_ENABLED       false
+#define DEFAULT_MODE                    1
+#define DEFAULT_SCENE_MODE              6 // Auto
+#define DEFAULT_USE_GPS                 true
+#define DEFAULT_USE_GEOTAGS             true
+#define DEFAULT_COLOR_FILTER            0
+#define DEFAULT_WHITE_BALANCE           0
+#define DEFAULT_EV_COMP                 0.0
+#define DEFAULT_FLASH_MODE              0
+#define DEFAULT_IMAGE_ISO               0
+#define DEFAULT_IMAGE_RESOLUTION        "high"
+#define DEFAULT_IMAGE_ASPECT_RATIO      "16:9"
+#define DEFAULT_VIDEO_RESOLUTION        "high"
+#define DEFAULT_SOUND_ENABLED           true
+#define DEFAULT_VIDEO_TORCH_ON          false
+#define DEFAULT_SHOW_TOOL_BAR           false
+#define DEFAULT_VIDEO_MUTE              false
+#define DEFAULT_GRID_ENABLED            false
+#define DEFAULT_FACE_DETECTION_ENABLED  true
 
 Settings::Settings(QObject *parent) :
   QObject(parent),
 
 Settings::Settings(QObject *parent) :
   QObject(parent),
@@ -320,3 +321,14 @@ void Settings::setGridEnabled(bool enabled) {
     emit gridEnabledChanged();
   }
 }
     emit gridEnabledChanged();
   }
 }
+
+bool Settings::isFaceDetectionEnabled() const {
+  return m_settings->value("image/faceDetectionEnabled", DEFAULT_FACE_DETECTION_ENABLED).toBool();
+}
+
+void Settings::setFaceDetectionEnabled(bool enabled) {
+  if (isFaceDetectionEnabled() != enabled) {
+    m_settings->setValue("image/faceDetectionEnabled", enabled);
+    emit faceDetectionEnabledChanged();
+  }
+}
index 6c7cf53..e98bdf9 100644 (file)
@@ -61,6 +61,8 @@ class Settings : public QObject {
 
   Q_PROPERTY(bool gridEnabled READ isGridEnabled WRITE setGridEnabled NOTIFY gridEnabledChanged);
 
 
   Q_PROPERTY(bool gridEnabled READ isGridEnabled WRITE setGridEnabled NOTIFY gridEnabledChanged);
 
+  Q_PROPERTY(bool faceDetectionEnabled READ isFaceDetectionEnabled WRITE setFaceDetectionEnabled NOTIFY faceDetectionEnabledChanged);
+
 public:
   Settings(QObject *parent = 0);
   ~Settings();
 public:
   Settings(QObject *parent = 0);
   ~Settings();
@@ -134,6 +136,9 @@ public:
   bool isGridEnabled() const;
   void setGridEnabled(bool enabled);
 
   bool isGridEnabled() const;
   void setGridEnabled(bool enabled);
 
+  bool isFaceDetectionEnabled() const;
+  void setFaceDetectionEnabled(bool enabled);
+
 signals:
   void modeChanged();
   void creatorNameChanged();
 signals:
   void modeChanged();
   void creatorNameChanged();
@@ -158,6 +163,7 @@ signals:
   void toolBarShownChanged();
   void videoMutedChanged();
   void gridEnabledChanged();
   void toolBarShownChanged();
   void videoMutedChanged();
   void gridEnabledChanged();
+  void faceDetectionEnabledChanged();
 
 private:
   QSettings *m_settings;
 
 private:
   QSettings *m_settings;