From 51950c94179c2a53e131ff1f787001452c19c2df Mon Sep 17 00:00:00 2001 From: Mohammed Sameer Date: Sun, 23 Dec 2012 15:51:36 +0200 Subject: [PATCH] Reworked QtCamAnalysisBin 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 | 106 +++++++++++++++++++++++++++++++++++++-- lib/qtcamanalysisbin.h | 21 +++++++- lib/qtcamdevice.cpp | 16 +++++- lib/qtcamdevice_p.h | 37 +------------- 4 files changed, 137 insertions(+), 43 deletions(-) diff --git a/lib/qtcamanalysisbin.cpp b/lib/qtcamanalysisbin.cpp index ef81a2c..f38e2c2 100644 --- a/lib/qtcamanalysisbin.cpp +++ b/lib/qtcamanalysisbin.cpp @@ -19,11 +19,105 @@ */ #include "qtcamanalysisbin.h" +#include #include #define FACTORY_NAME(x) gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(gst_element_get_factory(x))) -GstElement *qt_cam_analysis_bin_create(QList& children, const char *name) { +static GstElement *qt_cam_analysis_bin_create(QList& 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 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& children, + const char *name, GstPad **queuePad) { GstElement *bin = 0; QList added; @@ -33,10 +127,10 @@ GstElement *qt_cam_analysis_bin_create(QList& 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& 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& 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: diff --git a/lib/qtcamanalysisbin.h b/lib/qtcamanalysisbin.h index 8a797a1..8fb29fd 100644 --- a/lib/qtcamanalysisbin.h +++ b/lib/qtcamanalysisbin.h @@ -26,7 +26,24 @@ #include #include -GstElement *qt_cam_analysis_bin_create(QList& 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 */ diff --git a/lib/qtcamdevice.cpp b/lib/qtcamdevice.cpp index 6b9574f..20c3d78 100644 --- a/lib/qtcamdevice.cpp +++ b/lib/qtcamdevice.cpp @@ -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); } diff --git a/lib/qtcamdevice_p.h b/lib/qtcamdevice_p.h index 717057e..d532ab5 100644 --- a/lib/qtcamdevice_p.h +++ b/lib/qtcamdevice_p.h @@ -29,13 +29,13 @@ #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 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 */ -- 2.25.1