X-Git-Url: http://cgit.sxemacs.org/?p=harmattan%2Fcameraplus;a=blobdiff_plain;f=lib%2Fqtcamvideomode.cpp;h=762c108de0d6e125814b36d170d508fd0b7cc19c;hp=85b9721d6c295280eb78f0696e19f90d807c1af5;hb=f15b7b41a0fd2cade6cd0bb3771c2c0da14db3c8;hpb=ef824f43b2c961c284ea36d7e671ae132996b871 diff --git a/lib/qtcamvideomode.cpp b/lib/qtcamvideomode.cpp index 85b9721..762c108 100644 --- a/lib/qtcamvideomode.cpp +++ b/lib/qtcamvideomode.cpp @@ -1,27 +1,106 @@ +/*! + * This file is part of CameraPlus. + * + * Copyright (C) 2012-2013 Mohammed Sameer + * + * 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 "qtcamvideomode.h" #include "qtcammode_p.h" #include #include "qtcamdevice_p.h" #include "qtcamdevice.h" #include "qtcamvideosettings.h" +#include "qtcamnotifications.h" +#include +#include class QtCamVideoModePrivate : public QtCamModePrivate { public: QtCamVideoModePrivate(QtCamDevicePrivate *dev) : QtCamModePrivate(dev), - settings(dev->conf->defaultVideoSettings()) { + settings(dev->conf->videoSettings(dev->id)), + resolution(settings->defaultResolution()) { + + } + + ~QtCamVideoModePrivate() { + delete settings; + } + + void _d_idleStateChanged(bool isIdle) { + if (isIdle && dev->active == dev->video) { + QMetaObject::invokeMethod(dev->video, "recordingStateChanged"); + QMetaObject::invokeMethod(dev->video, "canCaptureChanged"); + } + } + + QtCamVideoSettings *settings; + QtCamVideoResolution resolution; +}; + +class VideoDoneHandler : public DoneHandler { +public: + VideoDoneHandler(QtCamModePrivate *d, QObject *parent = 0) : + DoneHandler(d, "video-done", parent), m_done(false) {} + + virtual void handleMessage(GstMessage *message) { + DoneHandler::handleMessage(message); + wake(); + } + + void lock() { + m_mutex.lock(); + } + void unlock() { + m_mutex.unlock(); } - ~QtCamVideoModePrivate() {} + void wait() { + m_cond.wait(&m_mutex); + } - QtCamVideoSettings settings; + void reset() { + m_done = false; + } + + bool isDone() { + return m_done; + } + +private: + void wake() { + lock(); + m_done = true; + m_cond.wakeOne(); + unlock(); + } + + bool m_done; + QMutex m_mutex; + QWaitCondition m_cond; }; -QtCamVideoMode::QtCamVideoMode(QtCamDevicePrivate *d, QObject *parent) : - QtCamMode(new QtCamVideoModePrivate(d), "mode-video", "video-done", parent) { +QtCamVideoMode::QtCamVideoMode(QtCamDevicePrivate *dev, QObject *parent) : + QtCamMode(new QtCamVideoModePrivate(dev), "mode-video", parent) { - d_ptr = (QtCamVideoModePrivate *)QtCamMode::d_ptr; + d_ptr->init(new VideoDoneHandler(d_ptr, this)); + + d = (QtCamVideoModePrivate *)QtCamMode::d_ptr; QString name = d_ptr->dev->conf->videoEncodingProfileName(); QString path = d_ptr->dev->conf->videoEncodingProfilePath(); @@ -32,33 +111,41 @@ QtCamVideoMode::QtCamVideoMode(QtCamDevicePrivate *d, QObject *parent) : setProfile(profile); } } + + QObject::connect(d_ptr->dev->q_ptr, SIGNAL(idleStateChanged(bool)), + this, SLOT(_d_idleStateChanged(bool))); } QtCamVideoMode::~QtCamVideoMode() { - + d = 0; } bool QtCamVideoMode::canCapture() { - return d_ptr->dev->q_ptr->isIdle(); + return QtCamMode::canCapture() && d_ptr->dev->q_ptr->isIdle(); } void QtCamVideoMode::applySettings() { - setCaps("viewfinder-caps", d_ptr->settings.captureResolution(), - d_ptr->settings.frameRate()); + bool night = d_ptr->inNightMode(); - setCaps("video-capture-caps", d_ptr->settings.captureResolution(), - d_ptr->settings.frameRate()); + int fps = night ? d->resolution.nightFrameRate() : d->resolution.frameRate(); - setPreviewSize(d_ptr->settings.previewResolution()); + d_ptr->setCaps("viewfinder-caps", d->resolution.captureResolution(), fps); + + d_ptr->setCaps("video-capture-caps", d->resolution.captureResolution(), fps); + + d_ptr->setPreviewSize(d->resolution.previewResolution()); + + // Not sure this is needed but just in case. + d_ptr->resetCaps("image-capture-caps"); } void QtCamVideoMode::start() { - // Nothing + d_ptr->disableViewfinderFilters(); } void QtCamVideoMode::stop() { if (isRecording()) { - stopRecording(); + stopRecording(true); } } @@ -66,29 +153,65 @@ bool QtCamVideoMode::isRecording() { return !d_ptr->dev->q_ptr->isIdle(); } -bool QtCamVideoMode::startRecording(const QString& fileName) { +bool QtCamVideoMode::startRecording(const QString& fileName, const QString& tmpFileName) { if (!canCapture() || isRecording()) { return false; } - setFileName(fileName); + if (fileName.isEmpty()) { + return false; + } + + d_ptr->setFileName(fileName); + d_ptr->setTempFileName(tmpFileName); + + QString file = tmpFileName.isEmpty() ? fileName : tmpFileName; - g_object_set(d_ptr->dev->cameraBin, "location", fileName.toUtf8().data(), NULL); + QMetaObject::invokeMethod(d_ptr->dev->notifications, "videoRecordingStarted"); + + g_object_set(d_ptr->dev->cameraBin, "location", file.toUtf8().data(), NULL); g_signal_emit_by_name(d_ptr->dev->cameraBin, "start-capture", NULL); + VideoDoneHandler *handler = dynamic_cast(d_ptr->doneHandler); + handler->reset(); + + emit recordingStateChanged(); + + emit canCaptureChanged(); + return true; } -bool QtCamVideoMode::stopRecording() { +void QtCamVideoMode::stopRecording(bool sync) { if (isRecording()) { + VideoDoneHandler *handler = dynamic_cast(d_ptr->doneHandler); + if (sync) { + handler->lock(); + + if (handler->isDone()) { + handler->unlock(); + return; + } + } + g_signal_emit_by_name(d_ptr->dev->cameraBin, "stop-capture", NULL); - } - return true; + if (sync) { + handler->wait(); + handler->unlock(); + } + } } -bool QtCamVideoMode::setSettings(const QtCamVideoSettings& settings) { - d_ptr->settings = settings; +bool QtCamVideoMode::setResolution(const QtCamVideoResolution& resolution) { + d->resolution = resolution; + + if (!d_ptr->dev->q_ptr->isRunning()) { + // We will return true here because setting the resolution on a non-running pipeline + // doesn't make much sense (Probably the only use case is as a kind of optimization only). + // We will set it anyway when the pipeline gets started. + return true; + } if (isRecording()) { return false; @@ -99,7 +222,6 @@ bool QtCamVideoMode::setSettings(const QtCamVideoSettings& settings) { return true; } - void QtCamVideoMode::setProfile(GstEncodingProfile *profile) { if (!d_ptr->dev->cameraBin) { gst_encoding_profile_unref(profile); @@ -108,3 +230,13 @@ void QtCamVideoMode::setProfile(GstEncodingProfile *profile) { g_object_set(d_ptr->dev->cameraBin, "video-profile", profile, NULL); } + +QtCamVideoSettings *QtCamVideoMode::settings() { + return d->settings; +} + +QtCamVideoResolution QtCamVideoMode::currentResolution() { + return d->resolution; +} + +#include "moc_qtcamvideomode.cpp"