summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/gstreamer/camerabin/camerabincontrol.cpp56
-rw-r--r--src/plugins/gstreamer/camerabin/camerabincontrol.h4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinfocus.cpp14
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinfocus.h4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp4
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinrecorder.cpp8
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.cpp185
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.h15
8 files changed, 152 insertions, 138 deletions
diff --git a/src/plugins/gstreamer/camerabin/camerabincontrol.cpp b/src/plugins/gstreamer/camerabin/camerabincontrol.cpp
index b46b92b17..cd7e37628 100644
--- a/src/plugins/gstreamer/camerabin/camerabincontrol.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabincontrol.cpp
@@ -51,11 +51,10 @@ CameraBinControl::CameraBinControl(CameraBinSession *session)
:QCameraControl(session),
m_session(session),
m_state(QCamera::UnloadedState),
- m_status(QCamera::UnloadedStatus),
m_reloadPending(false)
{
- connect(m_session, SIGNAL(stateChanged(QCamera::State)),
- this, SLOT(updateStatus()));
+ connect(m_session, SIGNAL(statusChanged(QCamera::Status)),
+ this, SIGNAL(statusChanged(QCamera::Status)));
connect(m_session, SIGNAL(viewfinderChanged()),
SLOT(reloadLater()));
@@ -116,7 +115,7 @@ void CameraBinControl::setState(QCamera::State state)
//special case for stopping the camera while it's busy,
//it should be delayed until the camera is idle
if (state == QCamera::LoadedState &&
- m_session->state() == QCamera::ActiveState &&
+ m_session->status() == QCamera::ActiveStatus &&
m_session->isBusy()) {
#ifdef CAMEABIN_DEBUG
qDebug() << Q_FUNC_INFO << "Camera is busy, QCamera::stop() is delayed";
@@ -165,52 +164,9 @@ QCamera::State CameraBinControl::state() const
return m_state;
}
-void CameraBinControl::updateStatus()
+QCamera::Status CameraBinControl::status() const
{
- QCamera::State sessionState = m_session->state();
- QCamera::Status oldStatus = m_status;
-
- switch (m_state) {
- case QCamera::UnloadedState:
- m_status = QCamera::UnloadedStatus;
- break;
- case QCamera::LoadedState:
- switch (sessionState) {
- case QCamera::UnloadedState:
- m_status = m_resourcePolicy->isResourcesGranted()
- ? QCamera::LoadingStatus
- : QCamera::UnavailableStatus;
- break;
- case QCamera::LoadedState:
- m_status = QCamera::LoadedStatus;
- break;
- case QCamera::ActiveState:
- m_status = QCamera::ActiveStatus;
- break;
- }
- break;
- case QCamera::ActiveState:
- switch (sessionState) {
- case QCamera::UnloadedState:
- m_status = m_resourcePolicy->isResourcesGranted()
- ? QCamera::LoadingStatus
- : QCamera::UnavailableStatus;
- break;
- case QCamera::LoadedState:
- m_status = QCamera::StartingStatus;
- break;
- case QCamera::ActiveState:
- m_status = QCamera::ActiveStatus;
- break;
- }
- }
-
- if (m_status != oldStatus) {
-#ifdef CAMEABIN_DEBUG
- qDebug() << "Camera status changed" << ENUM_NAME(QCamera, "Status", m_status);
-#endif
- emit statusChanged(m_status);
- }
+ return m_session->status();
}
void CameraBinControl::reloadLater()
@@ -254,7 +210,7 @@ void CameraBinControl::handleResourcesGranted()
void CameraBinControl::handleBusyChanged(bool busy)
{
- if (!busy && m_session->state() == QCamera::ActiveState) {
+ if (!busy && m_session->status() == QCamera::ActiveStatus) {
if (m_state == QCamera::LoadedState) {
//handle delayed stop() because of busy camera
m_resourcePolicy->setResourceSet(CamerabinResourcePolicy::LoadedResources);
diff --git a/src/plugins/gstreamer/camerabin/camerabincontrol.h b/src/plugins/gstreamer/camerabin/camerabincontrol.h
index fc0d8b9ca..6a6b47d50 100644
--- a/src/plugins/gstreamer/camerabin/camerabincontrol.h
+++ b/src/plugins/gstreamer/camerabin/camerabincontrol.h
@@ -56,7 +56,7 @@ public:
QCamera::State state() const;
void setState(QCamera::State state);
- QCamera::Status status() const { return m_status; }
+ QCamera::Status status() const;
QCamera::CaptureModes captureMode() const;
void setCaptureMode(QCamera::CaptureModes mode);
@@ -72,7 +72,6 @@ public slots:
void setViewfinderColorSpaceConversion(bool enabled);
private slots:
- void updateStatus();
void delayedReload();
void handleResourcesGranted();
@@ -86,7 +85,6 @@ private:
CameraBinSession *m_session;
QCamera::State m_state;
- QCamera::Status m_status;
CamerabinResourcePolicy *m_resourcePolicy;
bool m_reloadPending;
diff --git a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp b/src/plugins/gstreamer/camerabin/camerabinfocus.cpp
index 2b777e3ff..32b8d9454 100644
--- a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinfocus.cpp
@@ -56,7 +56,7 @@ CameraBinFocus::CameraBinFocus(CameraBinSession *session)
QGstreamerBufferProbe(ProbeBuffers),
#endif
m_session(session),
- m_cameraState(QCamera::UnloadedState),
+ m_cameraStatus(QCamera::UnloadedStatus),
m_focusMode(QCameraFocus::AutoFocus),
m_focusPointMode(QCameraFocus::FocusPointAuto),
m_focusStatus(QCamera::Unlocked),
@@ -68,8 +68,8 @@ CameraBinFocus::CameraBinFocus(CameraBinSession *session)
gst_photography_set_focus_mode(m_session->photography(), GST_PHOTOGRAPHY_FOCUS_MODE_AUTO);
- connect(m_session, SIGNAL(stateChanged(QCamera::State)),
- this, SLOT(_q_handleCameraStateChange(QCamera::State)));
+ connect(m_session, SIGNAL(statusChanged(QCamera::Status)),
+ this, SLOT(_q_handleCameraStatusChange(QCamera::Status)));
}
CameraBinFocus::~CameraBinFocus()
@@ -319,10 +319,10 @@ void CameraBinFocus::_q_setFocusStatus(QCamera::LockStatus status, QCamera::Lock
}
}
-void CameraBinFocus::_q_handleCameraStateChange(QCamera::State state)
+void CameraBinFocus::_q_handleCameraStatusChange(QCamera::Status status)
{
- m_cameraState = state;
- if (state == QCamera::ActiveState) {
+ m_cameraStatus = status;
+ if (status == QCamera::ActiveStatus) {
if (GstPad *pad = gst_element_get_static_pad(m_session->cameraSource(), "vfsrc")) {
if (GstCaps *caps = qt_gst_pad_get_current_caps(pad)) {
if (GstStructure *structure = gst_caps_get_structure(caps, 0)) {
@@ -415,7 +415,7 @@ void CameraBinFocus::updateRegionOfInterest(const QRectF &rectangle)
void CameraBinFocus::updateRegionOfInterest(const QVector<QRect> &rectangles)
{
- if (m_cameraState != QCamera::ActiveState)
+ if (m_cameraStatus != QCamera::ActiveStatus)
return;
GstElement * const cameraSource = m_session->cameraSource();
diff --git a/src/plugins/gstreamer/camerabin/camerabinfocus.h b/src/plugins/gstreamer/camerabin/camerabinfocus.h
index 6c4ad2375..667e6b679 100644
--- a/src/plugins/gstreamer/camerabin/camerabinfocus.h
+++ b/src/plugins/gstreamer/camerabin/camerabinfocus.h
@@ -93,7 +93,7 @@ protected:
private Q_SLOTS:
void _q_setFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason);
- void _q_handleCameraStateChange(QCamera::State state);
+ void _q_handleCameraStatusChange(QCamera::Status status);
#if GST_CHECK_VERSION(1,0,0)
void _q_updateFaces();
@@ -109,7 +109,7 @@ private:
#endif
CameraBinSession *m_session;
- QCamera::State m_cameraState;
+ QCamera::Status m_cameraStatus;
QCameraFocus::FocusModes m_focusMode;
QCameraFocus::FocusPointMode m_focusPointMode;
QCamera::LockStatus m_focusStatus;
diff --git a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp b/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
index ba4291c36..2cf14ea3f 100644
--- a/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
@@ -61,7 +61,7 @@ CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
, m_requestId(0)
, m_ready(false)
{
- connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
+ connect(m_session, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateState()));
connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int)));
connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
connect(m_session->cameraControl()->resourcePolicy(), SIGNAL(canCaptureChanged()), this, SLOT(updateState()));
@@ -100,7 +100,7 @@ void CameraBinImageCapture::cancelCapture()
void CameraBinImageCapture::updateState()
{
- bool ready = m_session->state() == QCamera::ActiveState
+ bool ready = m_session->status() == QCamera::ActiveStatus
&& m_session->cameraControl()->resourcePolicy()->canCapture();
if (m_ready != ready) {
#ifdef DEBUG_CAPTURE
diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
index ae9ec812b..4154e1d65 100644
--- a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
@@ -49,7 +49,7 @@ CameraBinRecorder::CameraBinRecorder(CameraBinSession *session)
m_state(QMediaRecorder::StoppedState),
m_status(QMediaRecorder::UnloadedStatus)
{
- connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus()));
+ connect(m_session, SIGNAL(statusChanged(QCamera::Status)), SLOT(updateStatus()));
connect(m_session, SIGNAL(pendingStateChanged(QCamera::State)), SLOT(updateStatus()));
connect(m_session, SIGNAL(busyChanged(bool)), SLOT(updateStatus()));
@@ -86,12 +86,12 @@ QMediaRecorder::Status CameraBinRecorder::status() const
void CameraBinRecorder::updateStatus()
{
- QCamera::State sessionState = m_session->state();
+ QCamera::Status sessionStatus = m_session->status();
QMediaRecorder::State oldState = m_state;
QMediaRecorder::Status oldStatus = m_status;
- if (sessionState == QCamera::ActiveState &&
+ if (sessionStatus == QCamera::ActiveStatus &&
m_session->captureMode().testFlag(QCamera::CaptureVideo)) {
if (!m_session->cameraControl()->resourcePolicy()->canCapture()) {
@@ -214,7 +214,7 @@ void CameraBinRecorder::setState(QMediaRecorder::State state)
break;
case QMediaRecorder::RecordingState:
- if (m_session->state() != QCamera::ActiveState) {
+ if (m_session->status() != QCamera::ActiveStatus) {
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
} else if (!m_session->cameraControl()->resourcePolicy()->canCapture()) {
emit error(QMediaRecorder::ResourceError, tr("Recording permissions are not available"));
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
index f60ba290b..72d72fdef 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
@@ -106,17 +106,12 @@
#define PREVIEW_CAPS_4_3 \
"video/x-raw-rgb, width = (int) 640, height = (int) 480"
-//using GST_STATE_READY for QCamera::LoadedState
-//may not work reliably at least with some webcams.
-
-//#define USE_READY_STATE_ON_LOADED
-
QT_BEGIN_NAMESPACE
CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *parent)
:QObject(parent),
m_recordingActive(false),
- m_state(QCamera::UnloadedState),
+ m_status(QCamera::UnloadedStatus),
m_pendingState(QCamera::UnloadedState),
m_muted(false),
m_busy(false),
@@ -230,9 +225,6 @@ CameraBinSession::CameraRole CameraBinSession::cameraRole() const
return BackCamera;
}
-/*
- Configure camera during Loaded->Active states stansition.
-*/
bool CameraBinSession::setupCameraBin()
{
if (!buildCameraSource())
@@ -248,7 +240,8 @@ bool CameraBinSession::setupCameraBin()
#endif
m_viewfinderHasChanged = false;
if (!m_viewfinderElement) {
- qWarning() << "Staring camera without viewfinder available";
+ if (m_pendingState == QCamera::ActiveState)
+ qWarning() << "Starting camera without viewfinder available";
m_viewfinderElement = gst_element_factory_make("fakesink", NULL);
}
g_object_set(G_OBJECT(m_viewfinderElement), "sync", FALSE, NULL);
@@ -663,9 +656,20 @@ void CameraBinSession::handleViewfinderChange()
emit viewfinderChanged();
}
-QCamera::State CameraBinSession::state() const
+void CameraBinSession::setStatus(QCamera::Status status)
{
- return m_state;
+ if (m_status == status)
+ return;
+
+ m_status = status;
+ emit statusChanged(m_status);
+
+ setStateHelper(m_pendingState);
+}
+
+QCamera::Status CameraBinSession::status() const
+{
+ return m_status;
}
QCamera::State CameraBinSession::pendingState() const
@@ -685,64 +689,112 @@ void CameraBinSession::setState(QCamera::State newState)
qDebug() << Q_FUNC_INFO << newState;
#endif
- switch (newState) {
- case QCamera::UnloadedState:
- if (m_recordingActive)
- stopVideoRecording();
-
- if (m_viewfinderInterface)
- m_viewfinderInterface->stopRenderer();
-
- gst_element_set_state(m_camerabin, GST_STATE_NULL);
- m_state = newState;
- if (m_busy)
- emit busyChanged(m_busy = false);
+ setStateHelper(newState);
+}
- emit stateChanged(m_state);
+void CameraBinSession::setStateHelper(QCamera::State state)
+{
+ switch (state) {
+ case QCamera::UnloadedState:
+ unload();
break;
case QCamera::LoadedState:
- if (m_recordingActive)
- stopVideoRecording();
-
- if (m_videoInputHasChanged) {
- if (m_viewfinderInterface)
- m_viewfinderInterface->stopRenderer();
-
- gst_element_set_state(m_camerabin, GST_STATE_NULL);
- buildCameraSource();
- }
-#ifdef USE_READY_STATE_ON_LOADED
- gst_element_set_state(m_camerabin, GST_STATE_READY);
-#else
- m_state = QCamera::LoadedState;
- if (m_viewfinderInterface)
- m_viewfinderInterface->stopRenderer();
- gst_element_set_state(m_camerabin, GST_STATE_NULL);
- emit stateChanged(m_state);
-#endif
+ if (m_status == QCamera::ActiveStatus)
+ stop();
+ else if (m_status == QCamera::UnloadedStatus)
+ load();
break;
case QCamera::ActiveState:
- if (setupCameraBin()) {
- GstState binState = GST_STATE_NULL;
- GstState pending = GST_STATE_NULL;
- gst_element_get_state(m_camerabin, &binState, &pending, 0);
+ // If the viewfinder changed while in the loaded state, we need to reload the pipeline
+ if (m_status == QCamera::LoadedStatus && !m_viewfinderHasChanged)
+ start();
+ else if (m_status == QCamera::UnloadedStatus || m_viewfinderHasChanged)
+ load();
+ }
+}
- m_recorderControl->applySettings();
+void CameraBinSession::setError(int err, const QString &errorString)
+{
+ m_pendingState = QCamera::UnloadedState;
+ emit error(err, errorString);
+ setStatus(QCamera::UnloadedStatus);
+}
- GstEncodingContainerProfile *profile = m_recorderControl->videoProfile();
- g_object_set (G_OBJECT(m_camerabin),
- "video-profile",
- profile,
- NULL);
- gst_encoding_profile_unref(profile);
+void CameraBinSession::load()
+{
+ if (m_status != QCamera::UnloadedStatus && !m_viewfinderHasChanged)
+ return;
- setAudioCaptureCaps();
+ setStatus(QCamera::LoadingStatus);
- setupCaptureResolution();
+ gst_element_set_state(m_camerabin, GST_STATE_NULL);
- gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
- }
+ if (!setupCameraBin()) {
+ setError(QCamera::CameraError, QStringLiteral("No camera source available"));
+ return;
}
+
+ gst_element_set_state(m_camerabin, GST_STATE_READY);
+}
+
+void CameraBinSession::unload()
+{
+ if (m_status == QCamera::UnloadedStatus || m_status == QCamera::UnloadingStatus)
+ return;
+
+ setStatus(QCamera::UnloadingStatus);
+
+ if (m_recordingActive)
+ stopVideoRecording();
+
+ if (m_viewfinderInterface)
+ m_viewfinderInterface->stopRenderer();
+
+ gst_element_set_state(m_camerabin, GST_STATE_NULL);
+
+ if (m_busy)
+ emit busyChanged(m_busy = false);
+
+ setStatus(QCamera::UnloadedStatus);
+}
+
+void CameraBinSession::start()
+{
+ if (m_status != QCamera::LoadedStatus)
+ return;
+
+ setStatus(QCamera::StartingStatus);
+
+ m_recorderControl->applySettings();
+
+ GstEncodingContainerProfile *profile = m_recorderControl->videoProfile();
+ g_object_set (G_OBJECT(m_camerabin),
+ "video-profile",
+ profile,
+ NULL);
+ gst_encoding_profile_unref(profile);
+
+ setAudioCaptureCaps();
+
+ setupCaptureResolution();
+
+ gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
+}
+
+void CameraBinSession::stop()
+{
+ if (m_status != QCamera::ActiveStatus)
+ return;
+
+ setStatus(QCamera::StoppingStatus);
+
+ if (m_recordingActive)
+ stopVideoRecording();
+
+ if (m_viewfinderInterface)
+ m_viewfinderInterface->stopRenderer();
+
+ gst_element_set_state(m_camerabin, GST_STATE_READY);
}
bool CameraBinSession::isBusy() const
@@ -889,7 +941,7 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
if (message.isEmpty())
message = tr("Camera error");
- emit error(int(QMediaRecorder::ResourceError), message);
+ setError(int(QMediaRecorder::ResourceError), message);
}
#ifdef CAMERABIN_DEBUG_DUMP_BIN
@@ -955,17 +1007,17 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
switch (newState) {
case GST_STATE_VOID_PENDING:
case GST_STATE_NULL:
- if (m_state != QCamera::UnloadedState)
- emit stateChanged(m_state = QCamera::UnloadedState);
+ setStatus(QCamera::UnloadedStatus);
break;
case GST_STATE_READY:
setMetaData(m_metaData);
- if (m_state != QCamera::LoadedState)
- emit stateChanged(m_state = QCamera::LoadedState);
+ setStatus(QCamera::LoadedStatus);
break;
- case GST_STATE_PAUSED:
case GST_STATE_PLAYING:
- emit stateChanged(m_state = QCamera::ActiveState);
+ setStatus(QCamera::ActiveStatus);
+ break;
+ case GST_STATE_PAUSED:
+ default:
break;
}
}
@@ -973,7 +1025,6 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
default:
break;
}
- //qDebug() << "New session state:" << ENUM_NAME(CameraBinSession,"State",m_state);
}
}
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h
index 723759b6a..d4214a620 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.h
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.h
@@ -148,7 +148,7 @@ public:
void captureImage(int requestId, const QString &fileName);
- QCamera::State state() const;
+ QCamera::Status status() const;
QCamera::State pendingState() const;
bool isBusy() const;
@@ -163,7 +163,7 @@ public:
bool processBusMessage(const QGstreamerMessage &message);
signals:
- void stateChanged(QCamera::State state);
+ void statusChanged(QCamera::Status status);
void pendingStateChanged(QCamera::State state);
void durationChanged(qint64 duration);
void error(int error, const QString &errorString);
@@ -185,6 +185,15 @@ private slots:
void handleViewfinderChange();
private:
+ void load();
+ void unload();
+ void start();
+ void stop();
+
+ void setStatus(QCamera::Status status);
+ void setStateHelper(QCamera::State state);
+ void setError(int error, const QString &errorString);
+
bool setupCameraBin();
void setupCaptureResolution();
void setAudioCaptureCaps();
@@ -197,7 +206,7 @@ private:
QUrl m_actualSink;
bool m_recordingActive;
QString m_captureDevice;
- QCamera::State m_state;
+ QCamera::Status m_status;
QCamera::State m_pendingState;
QString m_inputDevice;
bool m_muted;