return m_dev->start();
}
-void Camera::stop() {
+bool Camera::stop() {
if (m_dev) {
- m_dev->stop();
+ return m_dev->stop();
}
+
+ return true;
}
bool Camera::isIdle() {
QtCamDevice *device() const;
Q_INVOKABLE bool start();
+ Q_INVOKABLE bool stop();
bool isIdle();
bool isRunning();
QString imageSuffix() const;
QString videoSuffix() const;
-public slots:
- void stop();
-
signals:
void deviceCountChanged();
void deviceIdChanged();
return false;
}
+ d_ptr->viewfinder->stop();
+
// First we go to ready:
GstStateChangeReturn st = gst_element_set_state(d_ptr->cameraBin, GST_STATE_READY);
if (st != GST_STATE_CHANGE_FAILURE) {
void QtCamGraphicsViewfinder::updateRequested() {
update();
}
+
+void QtCamGraphicsViewfinder::stop() {
+ d_ptr->resetBackend();
+}
virtual GstElement *sinkElement();
virtual bool setDevice(QtCamDevice *device);
+ virtual void stop();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget = 0);
virtual GstElement *sinkElement() = 0;
virtual bool setDevice(QtCamDevice *device) = 0;
+ virtual void stop() = 0;
};
#endif /* QT_CAM_VIEWFINDER_H */
}
void QtCamViewfinderRendererMeeGo::reset() {
- // Nothing.
+ QMutexLocker locker(&m_frameMutex);
+ m_frame = -1;
}
GstElement *QtCamViewfinderRendererMeeGo::sinkElement() {
import QtQuick 1.1
import com.nokia.meego 1.1
import QtCamera 1.0
+import CameraPlus 1.0
Page {
+ id: page
property alias standbyWidget: standby
+ property bool needsPipeline: true
+ property int policyMode: CameraResources.None
+
+ Component.onCompleted: {
+ if (platformWindow.active && needsPipeline) {
+ resourcePolicy.acquire(page.policyMode);
+ }
+ }
+
+ onStatusChanged: {
+ if (platformWindow.active && status == PageStatus.Activating) {
+ resourcePolicy.acquire(page.policyMode);
+ }
+ }
+/*
+ onStatusChanged: {
+ if (status == PageStatus.Active && !page.needsPipeline) {
+ cam.stop();
+ }
+ }
+*/
+
+ onPolicyModeChanged: {
+ if (platformWindow.active) {
+ resourcePolicy.acquire(page.policyMode);
+ }
+ }
+
+ function handlePipeline() {
+ if (!platformWindow.active) {
+ // TODO: force if we lost resources ?
+ cam.stop();
+ }
+ else if (resourcePolicy.acquired && page.needsPipeline && !cam.running) {
+ // TODO: error
+ cam.start();
+ }
+ else if (!resourcePolicy.acquired) {
+ // TODO: force
+ cam.stop();
+ }
+ }
+
+ Connections {
+ target: resourcePolicy
+ onAcquiredChanged: handlePipeline();
+ }
+
+ Connections {
+ target: platformWindow
+ onActiveChanged: {
+ if (!platformWindow.active) {
+ // This is a noop if camera is not
+ // idle so calling it will not hurt
+ if (cam.stop()) {
+ resourcePolicy.acquire(CameraResources.None);
+ }
+ }
+ else if (page.needsPipeline) {
+ resourcePolicy.acquire(page.policyMode);
+ }
+ }
+ }
+
+ Connections {
+ target: cam
+ onIdleChanged: {
+ if (cam.idle && !platformWindow.active) {
+ cam.stop();
+ resourcePolicy.acquire(CameraResources.None);
+ }
+/*
+ else if (cam.idle && !page.needsPipeline) {
+ cam.stop();
+ }
+*/
+ }
+ }
+
Rectangle {
// TODO: color
// TODO: fade out transition
id: standby
color: "black"
anchors.fill: parent
- visible: !platformWindow.active
+ visible: !platformWindow.active || !cam.running || !resourcePolicy.acquired
Image {
source: "image://theme/icon-l-camera-standby"
anchors.centerIn: parent
anchors.right: parent.right
anchors.rightMargin: 20
anchors.bottomMargin: 20
+ visible: controlsVisible
}
PreviewImage {
import QtQuick 1.1
import com.nokia.meego 1.1
import QtCamera 1.0
+import CameraPlus 1.0
import "data.js" as Data
-Page {
+CameraPage {
id: page
- property Camera cam: null
+
+ controlsVisible: false
+ policyMode: CameraResources.Image
+ needsPipeline: true
Rectangle {
color: "black"
import QtQuick 1.1
import com.nokia.meego 1.1
import QtCamera 1.0
+import CameraPlus 1.0
CameraPage {
id: page
+ policyMode: CameraResources.Image
controlsVisible: capture.visible && cam.running && !standbyWidget.visible
Button {
import QtQuick 1.1
import com.nokia.meego 1.1
import QtCamera 1.0
+import CameraPlus 1.0
import "data.js" as Data
-Page {
+CameraPage {
id: page
- property Camera cam: null
+ controlsVisible: false
+ policyMode: CameraResources.Image
+ needsPipeline: false
Rectangle {
color: "black"
import QtQuick 1.1
import com.nokia.meego 1.1
import QtCamera 1.0
+import CameraPlus 1.0
import "data.js" as Data
-Page {
+CameraPage {
id: page
- property Camera cam: null
+
+ controlsVisible: false
+ policyMode: CameraResources.Image
+ needsPipeline: true
Rectangle {
color: "black"
// TODO: this is really basic.
-Page {
+CameraPage {
id: page
- property Camera cam: null
+
+ controlsVisible: false
+ policyMode: CameraResources.PostCapture
+ needsPipeline: true
+
+ onStatusChanged: {
+ if (status == PageStatus.Active) {
+ cam.stop();
+ }
+ }
+
+ Connections {
+ // Unlikely that we need this.
+ target: cam
+ onIdleChanged: {
+ if (cam.idle && page.status == PageStatus.Active) {
+ cam.stop();
+ }
+ }
+ }
Rectangle {
color: "black"
onStatusChanged: checkStatus(status)
function checkStatus(status) {
- if (status == SparqlConnection.Error)
- console.log("Error = "+connection.errorString());
+ if (status == SparqlConnection.Error) {
+ console.log("Error = "+connection.errorString());
+ }
}
}
}
+ // TODO: tap post capture and then immediately back and you can see the error
+ // and the standby widget underneath it.
delegate: Item {
width: view.width
height: view.height
anchors.bottom: parent.bottom
tools: ToolBarLayout {
id: layout
- ToolIcon { iconId: "icon-m-toolbar-back"; onClicked: pageStack.pop(); }
+ ToolIcon { iconId: "icon-m-toolbar-back"; onClicked: { cam.start(); pageStack.pop(); } }
}
}
}
CameraPage {
id: page
+ policyMode: CameraResources.Video
+
controlsVisible: recording.visible && cam.running && !standbyWidget.visible
orientationLock: PageOrientation.LockLandscape
width: 75
height: 75
opacity: 0.5
+
onClicked: {
- if (!videoMode.recording) {
- if (!fileSystem.available) {
- showError(qsTr("Camera cannot record videos in mass storage mode."));
- }
- else if (!videoMode.startRecording(fileNaming.videoFileName())) {
- showError(qsTr("Failed to record video. Please restart the camera."));
- }
+ if (!fileSystem.available) {
+ showError(qsTr("Camera cannot record videos in mass storage mode."));
+ return;
}
- else {
+
+ // We only toggle the mode to video recording so
+ // policy can acquire the needed resources
+
+ if (policyMode == CameraResources.Video) {
+ policyMode = CameraResources.Recording;
+ }
+ else if (videoMode.recording) {
+ // We just ask to stop video.
videoMode.stopRecording();
}
}
+ Connections {
+ target: videoMode
+ onRecordingChanged: {
+ if (!videoMode.recording) {
+ policyMode = CameraResources.Video;
+ }
+ }
+ }
+
+ Connections {
+ target: resourcePolicy
+ onAcquiredChanged: {
+ if (resourcePolicy.acquired && policyMode == CameraResources.Recording) {
+ if (!videoMode.startRecording(fileNaming.videoFileName())) {
+ showError(qsTr("Failed to record video. Please restart the camera."));
+ policyMode = CameraResources.Video
+}
+ }
+ }
+ }
+
visible: (videoMode.recording || videoMode.canCapture) && !cameraMode.animationRunning && !previewAnimationRunning && !standbyWidget.visible
}
error.show();
}
+ CameraResources {
+ id: resourcePolicy
+ onAcquiredChanged: {
+ if (resourcePolicy.acquired) {
+ // TODO:
+ }
+ else {
+ // TODO: We need a way to force a stop.
+ }
+ }
+ }
+
DeviceInfo {
id: deviceInfo
}
background: " "
}
- Connections {
- target: platformWindow
- onActiveChanged: {
- if (platformWindow.active) {
- if (!cam.start()) {
- showError("Camera failed to start. Please restart the camera.");
- }
- }
- else {
- // This is a noop if camera is not idle so calling it will not hurt
- cam.stop();
- }
- }
- }
-
Camera {
- onIdleChanged: {
- if (idle && !platformWindow.active) {
- stop();
- }
- }
-
+/*
onDeviceIdChanged: {
// TODO: is this needed ?
if (platformWindow.active) {
cam.start();
}
}
-
+*/
id: cam
anchors.fill: parent
--- /dev/null
+#include "cameraresources.h"
+#include <QDebug>
+
+using namespace ResourcePolicy;
+
+CameraResources::CameraResources(QObject *parent) :
+ QObject(parent),
+ m_set(new ResourceSet("camera", this, true, true)),
+ m_mode(None), m_acquired(false) {
+
+ QObject::connect(m_set, SIGNAL(resourcesReleased()), this, SLOT(resourcesReleased()));
+ QObject::connect(m_set, SIGNAL(lostResources()), this, SLOT(lostResources()));
+ QObject::connect(m_set, SIGNAL(resourcesGranted(const QList<ResourcePolicy::ResourceType>&)),
+ this, SLOT(resourcesGranted(const QList<ResourcePolicy::ResourceType>&)));
+ QObject::connect(m_set, SIGNAL(updateOK()), this, SLOT(updateOK()));
+
+ if (!m_set->initAndConnect()) {
+ qCritical() << "Failed to connect to resource policy engine";
+ }
+}
+
+CameraResources::~CameraResources() {
+ acquire(None);
+}
+
+void CameraResources::acquire(const CameraResources::Mode& mode) {
+ if (mode == m_mode) {
+ // We need to emit this because the UI migh be waiting
+ emit acquiredChanged();
+ return;
+ }
+
+ m_mode = mode;
+
+ switch (m_mode) {
+ case None:
+ m_set->release();
+ break;
+
+ case Image:
+ updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::VideoRecorderType
+ << ResourcePolicy::ScaleButtonType
+ << ResourcePolicy::SnapButtonType);
+ break;
+
+ case Video:
+ updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::VideoRecorderType
+ << ResourcePolicy::ScaleButtonType
+ << ResourcePolicy::SnapButtonType);
+ break;
+
+ case Recording:
+ updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::VideoRecorderType
+ << ResourcePolicy::ScaleButtonType
+ << ResourcePolicy::SnapButtonType
+ << ResourcePolicy::AudioRecorderType,
+ QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::AudioPlaybackType);
+ break;
+
+ case PostCapture:
+ updateSet(QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::VideoPlaybackType
+ << ResourcePolicy::ScaleButtonType,
+ QList<ResourcePolicy::ResourceType>()
+ << ResourcePolicy::AudioPlaybackType);
+
+ break;
+
+ default:
+ qWarning() << "Unknown mode" << mode;
+
+ break;
+ }
+}
+
+bool CameraResources::acquired() const {
+ return m_acquired;
+}
+
+void CameraResources::resourcesReleased() {
+ m_mode = None;
+ m_acquired = false;
+ emit acquiredChanged();
+}
+
+void CameraResources::lostResources() {
+ m_mode = None;
+ m_acquired = false;
+ emit acquiredChanged();
+}
+
+void CameraResources::resourcesGranted(const QList<ResourcePolicy::ResourceType>& optional) {
+ Q_UNUSED(optional);
+
+ m_acquired = true;
+ emit acquiredChanged();
+}
+
+void CameraResources::updateOK() {
+ m_acquired = true;
+ emit acquiredChanged();
+}
+
+QList<ResourcePolicy::ResourceType> CameraResources::listSet() {
+ QList<Resource *> resources = m_set->resources();
+ QList<ResourcePolicy::ResourceType> set;
+
+ foreach (Resource *r, resources) {
+ set << r->type();
+ }
+
+ return set;
+}
+
+void CameraResources::updateSet(const QList<ResourcePolicy::ResourceType>& required,
+ const QList<ResourcePolicy::ResourceType>& optional) {
+
+ QList<ResourcePolicy::ResourceType> set = listSet();
+
+ foreach (ResourceType r, set) {
+ // Check for acquired resources that should be dropped.
+ if (required.indexOf(r) == -1) {
+ m_set->deleteResource(r);
+ }
+ }
+
+ foreach (ResourceType r, required) {
+ // TODO: AudioPlayback needs special handling
+ m_set->addResource(r);
+ }
+
+ // TODO: optional resources
+
+ m_set->update();
+}
--- /dev/null
+// -*- c++ -*-
+
+#ifndef CAMERA_RESOURCES_H
+#define CAMERA_RESOURCES_H
+
+#include <QObject>
+#include <policy/resource-set.h>
+
+class CameraResources : public QObject {
+ Q_OBJECT
+
+ Q_PROPERTY(bool acquired READ acquired NOTIFY acquiredChanged);
+
+ Q_ENUMS(Mode);
+
+public:
+ typedef enum {
+ None,
+ Image,
+ Video,
+ Recording,
+ PostCapture,
+ } Mode;
+
+ CameraResources(QObject *parent = 0);
+ ~CameraResources();
+
+ bool acquired() const;
+
+public slots:
+ void acquire(const Mode& mode);
+
+signals:
+ void acquiredChanged();
+
+private slots:
+ void resourcesReleased();
+ void lostResources();
+ void resourcesGranted(const QList<ResourcePolicy::ResourceType>& optional);
+ void updateOK();
+
+private:
+ void updateSet(const QList<ResourcePolicy::ResourceType>& required,
+ const QList<ResourcePolicy::ResourceType>& optional =
+ QList<ResourcePolicy::ResourceType>());
+
+ QList<ResourcePolicy::ResourceType> listSet();
+
+ ResourcePolicy::ResourceSet *m_set;
+ Mode m_mode;
+ bool m_acquired;
+};
+
+#endif /* CAMERA_RESOURCES_H */
#include "quillitem.h"
#include "displaystate.h"
#include "fsmonitor.h"
+#include "cameraresources.h"
Q_DECL_EXPORT int main(int argc, char *argv[]) {
QApplication::setAttribute(Qt::AA_X11InitThreads, true);
qmlRegisterType<QuillItem>("CameraPlus", 1, 0, "QuillItem");
qmlRegisterType<DisplayState>("CameraPlus", 1, 0, "DisplayState");
qmlRegisterType<FSMonitor>("CameraPlus", 1, 0, "FSMonitor");
+ qmlRegisterType<CameraResources>("CameraPlus", 1, 0, "CameraResources");
QUrl sourceUrl = QUrl::fromLocalFile(QDir::currentPath() + "/main.qml");
view.setSource(sourceUrl);
CONFIG += link_pkgconfig debug static
PKGCONFIG = gstreamer-0.10 gstreamer-interfaces-0.10 gstreamer-video-0.10 gstreamer-tag-0.10 \
- gstreamer-pbutils-0.10 meego-gstreamer-interfaces-0.10 quill qmsystem2
+ gstreamer-pbutils-0.10 meego-gstreamer-interfaces-0.10 quill qmsystem2 libresourceqt1
+
LIBS += -L../imports/ -limports -L../lib/ -lqtcamera
-SOURCES += main.cpp settings.cpp filenaming.cpp quillitem.cpp displaystate.cpp fsmonitor.cpp
-HEADERS += settings.h filenaming.h quillitem.h displaystate.h fsmonitor.h
+SOURCES += main.cpp settings.cpp filenaming.cpp quillitem.cpp displaystate.cpp fsmonitor.cpp \
+ cameraresources.cpp
+
+HEADERS += settings.h filenaming.h quillitem.h displaystate.h fsmonitor.h \
+ cameraresources.h