Added enablePreview() and disablePreview() to QtCamMode
[harmattan/cameraplus] / lib / qtcammode.cpp
index 30a8be2..81d5781 100644 (file)
@@ -1,14 +1,32 @@
+/*!
+ * This file is part of CameraPlus.
+ *
+ * Copyright (C) 2012-2013 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 "qtcammode.h"
 #include "qtcammode_p.h"
 #include "qtcamdevice_p.h"
 #include "qtcamdevice.h"
 #include <QDebug>
-#include "qtcamgstreamermessagehandler.h"
 #include "qtcamgstreamermessagelistener.h"
 #include <gst/video/video.h>
 #include <QImage>
-
-#define PREVIEW_CAPS "video/x-raw-rgb, width = (int) %1, height = (int) %2, bpp = (int) 32, depth = (int) 24, red_mask = (int) 65280, green_mask = (int) 16711680, blue_mask = (int) -16777216"
+#include <QFile>
 
 class PreviewImageHandler : public QtCamGStreamerMessageHandler {
 public:
@@ -52,7 +70,7 @@ public:
 
     // We need to copy because GStreamer will free the buffer after we return
     // and since QImage doesn't copythe data by default we will end up with garbage.
-    // TODO: consider a QImage subclass that takes a GstBuffer reference
+    // There is no way to subclass QImage to prevent copying :|
     QImage cp = image.copy();
 
     QString fileName = QString::fromUtf8(file);
@@ -64,35 +82,13 @@ public:
   QtCamMode *mode;
 };
 
-class DoneHandler : public QtCamGStreamerMessageHandler {
-public:
-  DoneHandler(QtCamMode *m, const char *done, QObject *parent = 0) :
-    QtCamGStreamerMessageHandler(done, parent) {
-    mode = m;
-  }
-
-  virtual void handleMessage(GstMessage *message) {
-    const GstStructure *s = gst_message_get_structure(message);
-    if (gst_structure_has_field(s, "filename")) {
-      const char *str = gst_structure_get_string(s, "filename");
-      if (str) {
-       fileName = QString::fromUtf8(str);
-      }
-    }
-
-    QMetaObject::invokeMethod(mode, "saved", Q_ARG(QString, fileName));
-  }
-
-  QString fileName;
-  QtCamMode *mode;
-};
-
-QtCamMode::QtCamMode(QtCamModePrivate *d, const char *mode, const char *done, QObject *parent) :
+QtCamMode::QtCamMode(QtCamModePrivate *d, const char *mode, QObject *parent) :
   QObject(parent), d_ptr(d) {
 
+  d_ptr->q_ptr = this;
   d_ptr->id = d_ptr->modeId(mode);
   d_ptr->previewImageHandler = new PreviewImageHandler(this, this);
-  d_ptr->doneHandler = new DoneHandler(this, done, this);
+  d_ptr->doneHandler = 0;
 }
 
 QtCamMode::~QtCamMode() {
@@ -114,14 +110,13 @@ void QtCamMode::activate() {
 
   d_ptr->dev->active = this;
 
-  // TODO: check that we can actually do it. Perhaps the pipeline is busy.
   g_object_set(d_ptr->dev->cameraBin, "mode", d_ptr->id, NULL);
 
-  // TODO: is that needed ?
-  //  d_ptr->dev->resetCapabilities();
-
   d_ptr->dev->listener->addHandler(d_ptr->previewImageHandler);
-  d_ptr->dev->listener->addHandler(d_ptr->doneHandler);
+
+  // This has to be sync. VideoDoneHandler will lock a mutex that is already
+  // locked from the main thread.
+  d_ptr->dev->listener->addSyncHandler(d_ptr->doneHandler);
 
   start();
 
@@ -138,7 +133,7 @@ void QtCamMode::deactivate() {
   }
 
   d_ptr->dev->listener->removeHandler(d_ptr->previewImageHandler);
-  d_ptr->dev->listener->removeHandler(d_ptr->doneHandler);
+  d_ptr->dev->listener->removeSyncHandler(d_ptr->doneHandler);
 
   d_ptr->previewImageHandler->setParent(this);
   d_ptr->doneHandler->setParent(this);
@@ -153,32 +148,18 @@ void QtCamMode::deactivate() {
 }
 
 bool QtCamMode::canCapture() {
-  return d_ptr->dev->cameraBin && isActive() && d_ptr->dev->q_ptr->isRunning();
+  return d_ptr->dev->cameraBin && isActive() && d_ptr->dev->q_ptr->isRunning() &&
+    !d_ptr->dev->error;
 }
 
 bool QtCamMode::isActive() {
   return d_ptr->dev->active == this;
 }
 
-void QtCamMode::setPreviewSize(const QSize& size) {
-  if (!d_ptr->dev->cameraBin) {
-    return;
-  }
-
-  if (size.width() <= 0 && size.height() <= 0) {
-    g_object_set(d_ptr->dev->cameraBin, "preview-caps", NULL, "post-previews", FALSE, NULL);
-  }
-  else {
-    QString preview = QString(PREVIEW_CAPS).arg(size.width()).arg(size.height());
-
-    GstCaps *caps = gst_caps_from_string(preview.toAscii());
-
-    g_object_set(d_ptr->dev->cameraBin, "preview-caps", caps, "post-previews", TRUE, NULL);
-
-    gst_caps_unref(caps);
-  }
+QtCamDevice *QtCamMode::device() const {
+  return d_ptr->dev->q_ptr;
 }
 
-void QtCamMode::setFileName(const QString& fileName) {
-  d_ptr->doneHandler->fileName = fileName;
+void QtCamMode::disablePreview() {
+  d_ptr->setPreviewSize(QSize());
 }