Reworked QtCamAnalysisBin
authorMohammed Sameer <msameer@foolab.org>
Sun, 23 Dec 2012 13:51:36 +0000 (15:51 +0200)
committerMohammed Sameer <msameer@foolab.org>
Sun, 23 Dec 2012 13:51:36 +0000 (15:51 +0200)
QtCamAnalysisBin is now a class that creates the bin internally and has methods
to obtain the GstBin and block and unblock data flow.

lib/qtcamanalysisbin.cpp
lib/qtcamanalysisbin.h
lib/qtcamdevice.cpp
lib/qtcamdevice_p.h

index ef81a2c..f38e2c2 100644 (file)
  */
 
 #include "qtcamanalysisbin.h"
+#include <QStringList>
 #include <QDebug>
 
 #define FACTORY_NAME(x) gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(gst_element_get_factory(x)))
 
-GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children, const char *name) {
+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);
+
+class QtCamAnalysisBinPrivate {
+public:
+  QtCamAnalysisBinPrivate() :
+    bin(0),
+    probe(0),
+    queuePad(0) {
+
+  }
+
+  static gboolean block_buffers(GstPad *pad, GstMiniObject *o) {
+    Q_UNUSED(pad);
+    Q_UNUSED(o);
+
+    // Drop data
+    return FALSE;
+  }
+
+  GstElement *bin;
+  gulong probe;
+  GstPad *queuePad;
+};
+
+QtCamAnalysisBin::QtCamAnalysisBin(QtCamAnalysisBinPrivate *d) :
+  d_ptr(d) {
+  gst_object_ref(d_ptr->bin);
+}
+
+QtCamAnalysisBin::~QtCamAnalysisBin() {
+  setBlocked(false);
+  gst_object_unref(GST_OBJECT(d_ptr->queuePad));
+  gst_object_unref(d_ptr->bin);
+  delete d_ptr; d_ptr = 0;
+}
+
+void QtCamAnalysisBin::setBlocked(bool blocked) {
+  if (blocked == isBlocked()) {
+    return;
+  }
+
+  if (blocked) {
+    d_ptr->probe = gst_pad_add_buffer_probe(d_ptr->queuePad,
+                                           G_CALLBACK(QtCamAnalysisBinPrivate::block_buffers),
+                                           d_ptr);
+  }
+  else {
+    gst_pad_remove_data_probe(d_ptr->queuePad, d_ptr->probe);
+    d_ptr->probe = 0;
+  }
+}
+
+bool QtCamAnalysisBin::isBlocked() const {
+  return d_ptr->probe != 0;
+}
+
+GstElement *QtCamAnalysisBin::bin() {
+  return d_ptr->bin;
+}
+
+QtCamAnalysisBin *QtCamAnalysisBin::create(const QStringList& factories, const char *name) {
+  QList<GstElement *> elements;
+  if (factories.isEmpty()) {
+    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) {
+    return 0;
+  }
+
+  QtCamAnalysisBinPrivate *d = new QtCamAnalysisBinPrivate;
+  d->bin = bin;
+  d->queuePad = pad;
+
+  return new QtCamAnalysisBin(d);
+}
+
+GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children,
+                                      const char *name, GstPad **queuePad) {
   GstElement *bin = 0;
 
   QList<GstElement *> added;
@@ -33,10 +127,10 @@ GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children, const char
   }
 
   if (children.size() == 1) {
-    return qt_cam_analysis_bin_create(children.takeFirst(), name);
+    return qt_cam_analysis_bin_create(children.takeFirst(), name, queuePad);
   }
 
-  bin = gst_bin_new("analysis_bin_bin");
+  bin = gst_bin_new("analysis-bin-bin");
 
   while (!children.isEmpty()) {
     GstElement *elem = children.takeFirst();
@@ -67,7 +161,7 @@ GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children, const char
   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);
+  return qt_cam_analysis_bin_create(bin, name, queuePad);
 }
 
 /*
@@ -75,7 +169,7 @@ GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children, const char
  * tee -
  *       -- queue -- copy -- filters -- fakesink
  */
-GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name) {
+GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name, GstPad **queuePad) {
   GstPad *pad = 0;
 
   GstElement *bin = gst_bin_new(name);
@@ -116,6 +210,8 @@ GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name) {
   g_object_set(tee, "alloc-pad", pad, NULL);
   gst_object_unref(GST_OBJECT(pad));
 
+  *queuePad = gst_element_get_static_pad(queue, "src");
+
   return bin;
 
  free_and_out:
index 8a797a1..8fb29fd 100644 (file)
 #include <gst/gst.h>
 #include <QList>
 
-GstElement *qt_cam_analysis_bin_create(QList<GstElement *>& children, const char *name);
-GstElement *qt_cam_analysis_bin_create(GstElement *child, const char *name);
+class QtCamAnalysisBinPrivate;
+class QStringList;
+
+class QtCamAnalysisBin {
+public:
+  ~QtCamAnalysisBin();
+
+  static QtCamAnalysisBin *create(const QStringList& factories, const char *name);
+
+  void setBlocked(bool blocked);
+  bool isBlocked() const;
+
+  GstElement *bin();
+
+private:
+  QtCamAnalysisBin(QtCamAnalysisBinPrivate *d);
+
+  QtCamAnalysisBinPrivate *d_ptr;
+};
 
 #endif /* QT_CAM_ANALYSIS_BIN_H */
index 6b9574f..20c3d78 100644 (file)
@@ -31,6 +31,7 @@
 #include "qtcamnotifications.h"
 #include "gst/gstcopy.h"
 #include "qtcampropertysetter.h"
+#include "qtcamanalysisbin.h"
 
 QtCamDevice::QtCamDevice(QtCamConfig *config, const QString& name,
                         const QVariant& id, QObject *parent) :
@@ -73,7 +74,18 @@ QtCamDevice::QtCamDevice(QtCamConfig *config, const QString& name,
   g_object_set(d_ptr->cameraBin, "flags", flags, NULL);
 
   d_ptr->setAudioCaptureCaps();
-  d_ptr->addViewfinderFilters();
+
+  QStringList viewfinderFilters = d_ptr->conf->viewfinderFilters();
+  if (!viewfinderFilters.isEmpty()) {
+    d_ptr->viewfinderFilters =
+      QtCamAnalysisBin::create(viewfinderFilters, "QtCamViewfinderFilters");
+
+    if (!d_ptr->viewfinderFilters) {
+      qWarning() << "Failed to create viewfinder filters";
+    }
+  }
+
+  g_object_set(d_ptr->cameraBin, "viewfinder-filter", d_ptr->viewfinderFilters->bin(), NULL);
 
   d_ptr->listener = new QtCamGStreamerMessageListener(gst_element_get_bus(d_ptr->cameraBin),
                                                      d_ptr, this);
@@ -107,6 +119,8 @@ QtCamDevice::~QtCamDevice() {
 
   delete d_ptr->propertySetter;
 
+  delete d_ptr->viewfinderFilters;
+
   if (d_ptr->cameraBin) {
     gst_object_unref(d_ptr->cameraBin);
   }
index 717057e..d532ab5 100644 (file)
 #include "qtcamviewfinder.h"
 #include "qtcamdevice.h"
 #include "qtcammode.h"
-#include "qtcamanalysisbin.h"
 
 class QtCamGStreamerMessageListener;
 class QtCamMode;
 class QtCamImageMode;
 class QtCamVideoMode;
 class QtCamPropertySetter;
+class QtCamAnalysisBin;
 
 class QtCamDevicePrivate {
 public:
@@ -166,10 +166,6 @@ public:
     }
   }
 
-  void addViewfinderFilters() {
-    addElements("viewfinder-filter", conf->viewfinderFilters());
-  }
-
   bool isWrapperReady() {
     if (!wrapperVideoSource) {
       return false;
@@ -201,36 +197,6 @@ public:
                              Q_ARG(bool, d->q_ptr->isIdle()));
   }
 
-  void addElements(const char *prop, const QStringList& elements) {
-    QList<GstElement *> list;
-
-    if (elements.isEmpty()) {
-      return;
-    }
-
-    foreach (const QString& element, elements) {
-      GstElement *elem = gst_element_factory_make(element.toUtf8().constData(), NULL);
-      if (!elem) {
-       qWarning() << "Failed to create element" << element;
-      }
-      else {
-       list << elem;
-      }
-    }
-
-    if (list.isEmpty()) {
-      return;
-    }
-
-    GstElement *bin = qt_cam_analysis_bin_create(list, prop);
-    if (!bin) {
-      qWarning() << "Failed to create bin for" << prop;
-      return;
-    }
-
-    g_object_set(cameraBin, prop, bin, NULL);
-  }
-
   QString name;
   QVariant id;
 
@@ -250,6 +216,7 @@ public:
   bool error;
   QtCamNotifications *notifications;
   QtCamPropertySetter *propertySetter;
+  QtCamAnalysisBin *viewfinderFilters;
 };
 
 #endif /* QT_CAM_DEVICE_P_H */