[camera] Fix crashes and lockups caused by changing the capture mode during an image capture. Contributes to JB#42936
A camera source may reject changing the mode while it is busy leaving the the camerabin plugin in a state inconsistent with the gstreamer pipeline which can lead to attempts to record video in the image capture mode and ultimately a lockup. Changing any of the source resolutions requires putting the pipeline into the the READY state to apply the changes. If this happened during a capture the state change was deferred and the internal plugin state was restored to active before the capture finished and the state changes were treated as a no-op and the resolution change wasn't applied leading to an attempt to record video with an unsupported resolution set for the image capture mode. So if a change to a lower state is requested and the plugin is unable to process it immediately still defer the change but ensure the pipeline is still dropped to the lowest requested state before being restored to the current requested state so that any changes made on state transitions are applied.
This commit is contained in:
@@ -49,30 +49,10 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
CameraBinControl::CameraBinControl(CameraBinSession *session)
|
CameraBinControl::CameraBinControl(CameraBinSession *session)
|
||||||
:QCameraControl(session),
|
:QCameraControl(session),
|
||||||
m_session(session),
|
m_session(session)
|
||||||
m_state(QCamera::UnloadedState),
|
|
||||||
m_reloadPending(false)
|
|
||||||
{
|
{
|
||||||
connect(m_session, SIGNAL(statusChanged(QCamera::Status)),
|
connect(m_session, SIGNAL(statusChanged(QCamera::Status)),
|
||||||
this, SIGNAL(statusChanged(QCamera::Status)));
|
this, SIGNAL(statusChanged(QCamera::Status)));
|
||||||
|
|
||||||
connect(m_session, SIGNAL(viewfinderChanged()),
|
|
||||||
SLOT(reloadLater()));
|
|
||||||
connect(m_session, SIGNAL(readyChanged(bool)),
|
|
||||||
SLOT(reloadLater()));
|
|
||||||
connect(m_session, SIGNAL(error(int,QString)),
|
|
||||||
SLOT(handleCameraError(int,QString)));
|
|
||||||
|
|
||||||
m_resourcePolicy = new CamerabinResourcePolicy(this);
|
|
||||||
connect(m_resourcePolicy, SIGNAL(resourcesGranted()),
|
|
||||||
SLOT(handleResourcesGranted()));
|
|
||||||
connect(m_resourcePolicy, SIGNAL(resourcesDenied()),
|
|
||||||
SLOT(handleResourcesLost()));
|
|
||||||
connect(m_resourcePolicy, SIGNAL(resourcesLost()),
|
|
||||||
SLOT(handleResourcesLost()));
|
|
||||||
|
|
||||||
connect(m_session, SIGNAL(busyChanged(bool)),
|
|
||||||
SLOT(handleBusyChanged(bool)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraBinControl::~CameraBinControl()
|
CameraBinControl::~CameraBinControl()
|
||||||
@@ -86,17 +66,7 @@ QCamera::CaptureModes CameraBinControl::captureMode() const
|
|||||||
|
|
||||||
void CameraBinControl::setCaptureMode(QCamera::CaptureModes mode)
|
void CameraBinControl::setCaptureMode(QCamera::CaptureModes mode)
|
||||||
{
|
{
|
||||||
if (m_session->captureMode() != mode) {
|
m_session->setCaptureMode(mode);
|
||||||
m_session->setCaptureMode(mode);
|
|
||||||
|
|
||||||
if (m_state == QCamera::ActiveState) {
|
|
||||||
m_resourcePolicy->setResourceSet(
|
|
||||||
captureMode() == QCamera::CaptureStillImage ?
|
|
||||||
CamerabinResourcePolicy::ImageCaptureResources :
|
|
||||||
CamerabinResourcePolicy::VideoCaptureResources);
|
|
||||||
}
|
|
||||||
emit captureModeChanged(mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CameraBinControl::isCaptureModeSupported(QCamera::CaptureModes mode) const
|
bool CameraBinControl::isCaptureModeSupported(QCamera::CaptureModes mode) const
|
||||||
@@ -109,59 +79,12 @@ void CameraBinControl::setState(QCamera::State state)
|
|||||||
#ifdef CAMEABIN_DEBUG
|
#ifdef CAMEABIN_DEBUG
|
||||||
qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", state);
|
qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", state);
|
||||||
#endif
|
#endif
|
||||||
if (m_state != state) {
|
m_session->setState(state);
|
||||||
m_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 || state == QCamera::UnloadedState) &&
|
|
||||||
m_session->status() == QCamera::ActiveStatus &&
|
|
||||||
m_session->isBusy()) {
|
|
||||||
#ifdef CAMEABIN_DEBUG
|
|
||||||
qDebug() << Q_FUNC_INFO << "Camera is busy, QCamera::stop() is delayed";
|
|
||||||
#endif
|
|
||||||
emit stateChanged(m_state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CamerabinResourcePolicy::ResourceSet resourceSet = CamerabinResourcePolicy::NoResources;
|
|
||||||
switch (state) {
|
|
||||||
case QCamera::UnloadedState:
|
|
||||||
resourceSet = CamerabinResourcePolicy::NoResources;
|
|
||||||
break;
|
|
||||||
case QCamera::LoadedState:
|
|
||||||
resourceSet = CamerabinResourcePolicy::LoadedResources;
|
|
||||||
break;
|
|
||||||
case QCamera::ActiveState:
|
|
||||||
resourceSet = captureMode() == QCamera::CaptureStillImage ?
|
|
||||||
CamerabinResourcePolicy::ImageCaptureResources :
|
|
||||||
CamerabinResourcePolicy::VideoCaptureResources;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_resourcePolicy->setResourceSet(resourceSet);
|
|
||||||
|
|
||||||
if (m_resourcePolicy->isResourcesGranted()) {
|
|
||||||
//postpone changing to Active if the session is nor ready yet
|
|
||||||
if (state == QCamera::ActiveState) {
|
|
||||||
if (m_session->isReady()) {
|
|
||||||
m_session->setState(state);
|
|
||||||
} else {
|
|
||||||
#ifdef CAMEABIN_DEBUG
|
|
||||||
qDebug() << "Camera session is not ready yet, postpone activating";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
m_session->setState(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit stateChanged(m_state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QCamera::State CameraBinControl::state() const
|
QCamera::State CameraBinControl::state() const
|
||||||
{
|
{
|
||||||
return m_state;
|
return m_session->requestedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
QCamera::Status CameraBinControl::status() const
|
QCamera::Status CameraBinControl::status() const
|
||||||
@@ -169,81 +92,6 @@ QCamera::Status CameraBinControl::status() const
|
|||||||
return m_session->status();
|
return m_session->status();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinControl::reloadLater()
|
|
||||||
{
|
|
||||||
#ifdef CAMEABIN_DEBUG
|
|
||||||
qDebug() << "CameraBinControl: reload pipeline requested" << ENUM_NAME(QCamera, "State", m_state);
|
|
||||||
#endif
|
|
||||||
if (!m_reloadPending && m_state == QCamera::ActiveState) {
|
|
||||||
m_reloadPending = true;
|
|
||||||
|
|
||||||
if (!m_session->isBusy()) {
|
|
||||||
m_session->setState(QCamera::LoadedState);
|
|
||||||
QMetaObject::invokeMethod(this, "delayedReload", Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraBinControl::handleResourcesLost()
|
|
||||||
{
|
|
||||||
#ifdef CAMEABIN_DEBUG
|
|
||||||
qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", m_state);
|
|
||||||
#endif
|
|
||||||
m_session->setState(QCamera::UnloadedState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraBinControl::handleResourcesGranted()
|
|
||||||
{
|
|
||||||
#ifdef CAMEABIN_DEBUG
|
|
||||||
qDebug() << Q_FUNC_INFO << ENUM_NAME(QCamera, "State", m_state);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//camera will be started soon by delayedReload()
|
|
||||||
if (m_reloadPending && m_state == QCamera::ActiveState)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_state == QCamera::ActiveState && m_session->isReady())
|
|
||||||
m_session->setState(QCamera::ActiveState);
|
|
||||||
else if (m_state == QCamera::LoadedState)
|
|
||||||
m_session->setState(QCamera::LoadedState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraBinControl::handleBusyChanged(bool busy)
|
|
||||||
{
|
|
||||||
if (!busy && m_session->status() == QCamera::ActiveStatus) {
|
|
||||||
if (m_state == QCamera::LoadedState) {
|
|
||||||
//handle delayed stop() because of busy camera
|
|
||||||
m_resourcePolicy->setResourceSet(CamerabinResourcePolicy::LoadedResources);
|
|
||||||
m_session->setState(QCamera::LoadedState);
|
|
||||||
} else if (m_state == QCamera::ActiveState && m_reloadPending) {
|
|
||||||
//handle delayed reload because of busy camera
|
|
||||||
m_session->setState(QCamera::LoadedState);
|
|
||||||
QMetaObject::invokeMethod(this, "delayedReload", Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraBinControl::handleCameraError(int errorCode, const QString &errorString)
|
|
||||||
{
|
|
||||||
emit error(errorCode, errorString);
|
|
||||||
setState(QCamera::UnloadedState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraBinControl::delayedReload()
|
|
||||||
{
|
|
||||||
#ifdef CAMEABIN_DEBUG
|
|
||||||
qDebug() << "CameraBinControl: reload pipeline";
|
|
||||||
#endif
|
|
||||||
if (m_reloadPending) {
|
|
||||||
m_reloadPending = false;
|
|
||||||
if (m_state == QCamera::ActiveState &&
|
|
||||||
m_session->isReady() &&
|
|
||||||
m_resourcePolicy->isResourcesGranted()) {
|
|
||||||
m_session->setState(QCamera::ActiveState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CameraBinControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const
|
bool CameraBinControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(status);
|
Q_UNUSED(status);
|
||||||
|
|||||||
@@ -65,29 +65,13 @@ public:
|
|||||||
bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const;
|
bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const;
|
||||||
bool viewfinderColorSpaceConversion() const;
|
bool viewfinderColorSpaceConversion() const;
|
||||||
|
|
||||||
CamerabinResourcePolicy *resourcePolicy() { return m_resourcePolicy; }
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reloadLater();
|
|
||||||
void setViewfinderColorSpaceConversion(bool enabled);
|
void setViewfinderColorSpaceConversion(bool enabled);
|
||||||
|
|
||||||
private slots:
|
|
||||||
void delayedReload();
|
|
||||||
|
|
||||||
void handleResourcesGranted();
|
|
||||||
void handleResourcesLost();
|
|
||||||
|
|
||||||
void handleBusyChanged(bool);
|
|
||||||
void handleCameraError(int error, const QString &errorString);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateSupportedResolutions(const QString &device);
|
void updateSupportedResolutions(const QString &device);
|
||||||
|
|
||||||
CameraBinSession *m_session;
|
CameraBinSession *m_session;
|
||||||
QCamera::State m_state;
|
|
||||||
CamerabinResourcePolicy *m_resourcePolicy;
|
|
||||||
|
|
||||||
bool m_reloadPending;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
|
|||||||
connect(m_session, SIGNAL(statusChanged(QCamera::Status)), 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(imageExposed(int)), this, SIGNAL(imageExposed(int)));
|
||||||
connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
|
connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage)));
|
||||||
connect(m_session->cameraControl()->resourcePolicy(), SIGNAL(canCaptureChanged()), this, SLOT(updateState()));
|
connect(m_session->resourcePolicy(), SIGNAL(canCaptureChanged()), this, SLOT(updateState()));
|
||||||
connect(m_session, SIGNAL(handleReadyForCaptureChanged(bool)), this, SLOT(updateState()));
|
connect(m_session, SIGNAL(handleReadyForCaptureChanged(bool)), this, SLOT(updateState()));
|
||||||
|
|
||||||
m_session->bus()->installMessageFilter(this);
|
m_session->bus()->installMessageFilter(this);
|
||||||
@@ -102,7 +102,7 @@ void CameraBinImageCapture::cancelCapture()
|
|||||||
void CameraBinImageCapture::updateState()
|
void CameraBinImageCapture::updateState()
|
||||||
{
|
{
|
||||||
bool ready = m_session->status() == QCamera::ActiveStatus
|
bool ready = m_session->status() == QCamera::ActiveStatus
|
||||||
&& m_session->cameraControl()->resourcePolicy()->canCapture()
|
&& m_session->resourcePolicy()->canCapture()
|
||||||
&& m_session->isReadyForCapture();
|
&& m_session->isReadyForCapture();
|
||||||
if (m_ready != ready) {
|
if (m_ready != ready) {
|
||||||
#ifdef DEBUG_CAPTURE
|
#ifdef DEBUG_CAPTURE
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ CameraBinRecorder::CameraBinRecorder(CameraBinSession *session)
|
|||||||
|
|
||||||
connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
|
connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
|
||||||
connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
|
connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
|
||||||
connect(m_session->cameraControl()->resourcePolicy(), SIGNAL(canCaptureChanged()),
|
connect(m_session->resourcePolicy(), SIGNAL(canCaptureChanged()),
|
||||||
this, SLOT(updateStatus()));
|
this, SLOT(updateStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ void CameraBinRecorder::updateStatus()
|
|||||||
if (sessionStatus == QCamera::ActiveStatus &&
|
if (sessionStatus == QCamera::ActiveStatus &&
|
||||||
m_session->captureMode().testFlag(QCamera::CaptureVideo)) {
|
m_session->captureMode().testFlag(QCamera::CaptureVideo)) {
|
||||||
|
|
||||||
if (!m_session->cameraControl()->resourcePolicy()->canCapture()) {
|
if (!m_session->resourcePolicy()->canCapture()) {
|
||||||
m_status = QMediaRecorder::UnavailableStatus;
|
m_status = QMediaRecorder::UnavailableStatus;
|
||||||
m_state = QMediaRecorder::StoppedState;
|
m_state = QMediaRecorder::StoppedState;
|
||||||
m_session->stopVideoRecording();
|
m_session->stopVideoRecording();
|
||||||
@@ -109,7 +109,7 @@ void CameraBinRecorder::updateStatus()
|
|||||||
m_state = QMediaRecorder::StoppedState;
|
m_state = QMediaRecorder::StoppedState;
|
||||||
m_session->stopVideoRecording();
|
m_session->stopVideoRecording();
|
||||||
}
|
}
|
||||||
m_status = m_session->pendingState() == QCamera::ActiveState
|
m_status = m_session->requestedState() == QCamera::ActiveState
|
||||||
&& m_session->captureMode().testFlag(QCamera::CaptureVideo)
|
&& m_session->captureMode().testFlag(QCamera::CaptureVideo)
|
||||||
? QMediaRecorder::LoadingStatus
|
? QMediaRecorder::LoadingStatus
|
||||||
: QMediaRecorder::UnloadedStatus;
|
: QMediaRecorder::UnloadedStatus;
|
||||||
@@ -221,7 +221,7 @@ void CameraBinRecorder::setState(QMediaRecorder::State state)
|
|||||||
|
|
||||||
if (m_session->status() != QCamera::ActiveStatus) {
|
if (m_session->status() != QCamera::ActiveStatus) {
|
||||||
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
|
emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
|
||||||
} else if (!m_session->cameraControl()->resourcePolicy()->canCapture()) {
|
} else if (!m_session->resourcePolicy()->canCapture()) {
|
||||||
emit error(QMediaRecorder::ResourceError, tr("Recording permissions are not available"));
|
emit error(QMediaRecorder::ResourceError, tr("Recording permissions are not available"));
|
||||||
} else {
|
} else {
|
||||||
m_session->recordVideo();
|
m_session->recordVideo();
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
VideoCaptureResources
|
VideoCaptureResources
|
||||||
};
|
};
|
||||||
|
|
||||||
CamerabinResourcePolicy(QObject *parent);
|
CamerabinResourcePolicy(QObject *parent = nullptr);
|
||||||
~CamerabinResourcePolicy();
|
~CamerabinResourcePolicy();
|
||||||
|
|
||||||
ResourceSet resourceSet() const;
|
ResourceSet resourceSet() const;
|
||||||
|
|||||||
@@ -113,11 +113,15 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
|
|||||||
:QObject(parent),
|
:QObject(parent),
|
||||||
m_recordingActive(false),
|
m_recordingActive(false),
|
||||||
m_status(QCamera::UnloadedStatus),
|
m_status(QCamera::UnloadedStatus),
|
||||||
m_pendingState(QCamera::UnloadedState),
|
m_requestedState(QCamera::UnloadedState),
|
||||||
|
m_transientState(QCamera::UnloadedState),
|
||||||
|
m_acceptedState(QCamera::UnloadedState),
|
||||||
m_muted(false),
|
m_muted(false),
|
||||||
m_busy(false),
|
|
||||||
m_readyForCapture(false),
|
m_readyForCapture(false),
|
||||||
m_captureMode(QCamera::CaptureStillImage),
|
m_captureMode(QCamera::CaptureStillImage),
|
||||||
|
m_appliedCaptureMode(QCamera::CaptureStillImage),
|
||||||
|
m_busy(false),
|
||||||
|
m_reportedReadyForCapture(false),
|
||||||
m_audioInputFactory(0),
|
m_audioInputFactory(0),
|
||||||
m_videoInputFactory(0),
|
m_videoInputFactory(0),
|
||||||
m_viewfinder(0),
|
m_viewfinder(0),
|
||||||
@@ -187,6 +191,10 @@ CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *pa
|
|||||||
|
|
||||||
g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL);
|
g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL);
|
||||||
gst_caps_unref(previewCaps);
|
gst_caps_unref(previewCaps);
|
||||||
|
|
||||||
|
connect(&m_resourcePolicy, &CamerabinResourcePolicy::resourcesGranted, this, &CameraBinSession::applyState);
|
||||||
|
connect(&m_resourcePolicy, &CamerabinResourcePolicy::resourcesDenied, this, &CameraBinSession::resourcesLost);
|
||||||
|
connect(&m_resourcePolicy, &CamerabinResourcePolicy::resourcesLost, this, &CameraBinSession::resourcesLost);
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraBinSession::~CameraBinSession()
|
CameraBinSession::~CameraBinSession()
|
||||||
@@ -270,7 +278,7 @@ bool CameraBinSession::setupCameraBin()
|
|||||||
#endif
|
#endif
|
||||||
m_viewfinderHasChanged = false;
|
m_viewfinderHasChanged = false;
|
||||||
if (!m_viewfinderElement) {
|
if (!m_viewfinderElement) {
|
||||||
if (m_pendingState == QCamera::ActiveState)
|
if (m_requestedState == QCamera::ActiveState)
|
||||||
qWarning() << "Starting camera without viewfinder available";
|
qWarning() << "Starting camera without viewfinder available";
|
||||||
m_viewfinderElement = gst_element_factory_make("fakesink", NULL);
|
m_viewfinderElement = gst_element_factory_make("fakesink", NULL);
|
||||||
}
|
}
|
||||||
@@ -561,22 +569,25 @@ void CameraBinSession::captureImage(int requestId, const QString &fileName)
|
|||||||
g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL);
|
g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL);
|
||||||
|
|
||||||
m_imageFileName = actualFileName;
|
m_imageFileName = actualFileName;
|
||||||
|
|
||||||
|
updateCaptureStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraBinSession::updateCaptureStatus()
|
||||||
|
{
|
||||||
|
if (m_reportedReadyForCapture != m_readyForCapture) {
|
||||||
|
m_readyForCapture = m_reportedReadyForCapture;
|
||||||
|
emit handleReadyForCaptureChanged(m_readyForCapture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::setCaptureMode(QCamera::CaptureModes mode)
|
void CameraBinSession::setCaptureMode(QCamera::CaptureModes mode)
|
||||||
{
|
{
|
||||||
m_captureMode = mode;
|
if (m_captureMode != mode) {
|
||||||
|
m_captureMode = mode;
|
||||||
switch (m_captureMode) {
|
emit m_cameraControl->captureModeChanged(m_captureMode);
|
||||||
case QCamera::CaptureStillImage:
|
|
||||||
g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_IMAGE_MODE, NULL);
|
|
||||||
break;
|
|
||||||
case QCamera::CaptureVideo:
|
|
||||||
g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_VIDEO_MODE, NULL);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_recorderControl->updateStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl CameraBinSession::outputLocation() const
|
QUrl CameraBinSession::outputLocation() const
|
||||||
@@ -631,32 +642,29 @@ void CameraBinSession::setViewfinder(QObject *viewfinder)
|
|||||||
viewfinder = 0;
|
viewfinder = 0;
|
||||||
|
|
||||||
if (m_viewfinder != viewfinder) {
|
if (m_viewfinder != viewfinder) {
|
||||||
bool oldReady = isReady();
|
|
||||||
|
|
||||||
if (m_viewfinder) {
|
if (m_viewfinder) {
|
||||||
disconnect(m_viewfinder, SIGNAL(sinkChanged()),
|
disconnect(m_viewfinder, SIGNAL(sinkChanged()),
|
||||||
this, SLOT(handleViewfinderChange()));
|
this, SLOT(handleViewfinderChange()));
|
||||||
disconnect(m_viewfinder, SIGNAL(readyChanged(bool)),
|
disconnect(m_viewfinder, SIGNAL(readyChanged(bool)),
|
||||||
this, SIGNAL(readyChanged(bool)));
|
this, SLOT(applyState()));
|
||||||
|
|
||||||
m_busHelper->removeMessageFilter(m_viewfinder);
|
m_busHelper->removeMessageFilter(m_viewfinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_viewfinder = viewfinder;
|
m_viewfinder = viewfinder;
|
||||||
m_viewfinderHasChanged = true;
|
m_viewfinderHasChanged = true;
|
||||||
|
m_transientState = QCamera::UnloadedState;
|
||||||
|
|
||||||
if (m_viewfinder) {
|
if (m_viewfinder) {
|
||||||
connect(m_viewfinder, SIGNAL(sinkChanged()),
|
connect(m_viewfinder, SIGNAL(sinkChanged()),
|
||||||
this, SLOT(handleViewfinderChange()));
|
this, SLOT(handleViewfinderChange()));
|
||||||
connect(m_viewfinder, SIGNAL(readyChanged(bool)),
|
connect(m_viewfinder, SIGNAL(readyChanged(bool)),
|
||||||
this, SIGNAL(readyChanged(bool)));
|
this, SLOT(applyState()));
|
||||||
|
|
||||||
m_busHelper->installMessageFilter(m_viewfinder);
|
m_busHelper->installMessageFilter(m_viewfinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit viewfinderChanged();
|
applyState();
|
||||||
if (oldReady != isReady())
|
|
||||||
emit readyChanged(isReady());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,7 +695,9 @@ void CameraBinSession::handleViewfinderChange()
|
|||||||
//the viewfinder will be reloaded
|
//the viewfinder will be reloaded
|
||||||
//shortly when the pipeline is started
|
//shortly when the pipeline is started
|
||||||
m_viewfinderHasChanged = true;
|
m_viewfinderHasChanged = true;
|
||||||
emit viewfinderChanged();
|
m_transientState = QCamera::UnloadedState;
|
||||||
|
|
||||||
|
applyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::setStatus(QCamera::Status status)
|
void CameraBinSession::setStatus(QCamera::Status status)
|
||||||
@@ -697,8 +707,6 @@ void CameraBinSession::setStatus(QCamera::Status status)
|
|||||||
|
|
||||||
m_status = status;
|
m_status = status;
|
||||||
emit statusChanged(m_status);
|
emit statusChanged(m_status);
|
||||||
|
|
||||||
setStateHelper(m_pendingState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QCamera::Status CameraBinSession::status() const
|
QCamera::Status CameraBinSession::status() const
|
||||||
@@ -706,60 +714,122 @@ QCamera::Status CameraBinSession::status() const
|
|||||||
return m_status;
|
return m_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
QCamera::State CameraBinSession::pendingState() const
|
QCamera::State CameraBinSession::requestedState() const
|
||||||
{
|
{
|
||||||
return m_pendingState;
|
return m_requestedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::setState(QCamera::State newState)
|
void CameraBinSession::setState(QCamera::State newState)
|
||||||
{
|
{
|
||||||
if (newState == m_pendingState)
|
if (newState == m_requestedState)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_pendingState = newState;
|
if (newState < m_transientState) {
|
||||||
emit pendingStateChanged(m_pendingState);
|
m_transientState = newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_requestedState = newState;
|
||||||
|
emit pendingStateChanged(m_requestedState);
|
||||||
|
m_cameraControl->stateChanged(m_requestedState);
|
||||||
|
|
||||||
#if CAMERABIN_DEBUG
|
#if CAMERABIN_DEBUG
|
||||||
qDebug() << Q_FUNC_INFO << newState;
|
qDebug() << Q_FUNC_INFO << newState;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setStateHelper(newState);
|
applyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::setStateHelper(QCamera::State state)
|
void CameraBinSession::applyState()
|
||||||
{
|
{
|
||||||
switch (state) {
|
CamerabinResourcePolicy::ResourceSet resourceSet = CamerabinResourcePolicy::NoResources;
|
||||||
|
switch (m_requestedState) {
|
||||||
case QCamera::UnloadedState:
|
case QCamera::UnloadedState:
|
||||||
unload();
|
resourceSet = CamerabinResourcePolicy::NoResources;
|
||||||
break;
|
break;
|
||||||
case QCamera::LoadedState:
|
case QCamera::LoadedState:
|
||||||
if (m_status == QCamera::ActiveStatus)
|
resourceSet = CamerabinResourcePolicy::LoadedResources;
|
||||||
stop();
|
|
||||||
else if (m_status == QCamera::UnloadedStatus)
|
|
||||||
load();
|
|
||||||
break;
|
break;
|
||||||
case QCamera::ActiveState:
|
case QCamera::ActiveState:
|
||||||
// If the viewfinder changed while in the loaded state, we need to reload the pipeline
|
resourceSet = m_captureMode == QCamera::CaptureStillImage
|
||||||
if (m_status == QCamera::LoadedStatus && !m_viewfinderHasChanged)
|
? CamerabinResourcePolicy::ImageCaptureResources
|
||||||
start();
|
: CamerabinResourcePolicy::VideoCaptureResources;
|
||||||
else if (m_status == QCamera::UnloadedStatus || m_viewfinderHasChanged)
|
break;
|
||||||
load();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_resourcePolicy.resourceSet() != resourceSet) {
|
||||||
|
m_resourcePolicy.setResourceSet(resourceSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_resourcePolicy.isResourcesGranted()) {
|
||||||
|
m_transientState = QCamera::UnloadedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_transientState < m_acceptedState) {
|
||||||
|
// Ensure that if something tried to unload or stop the pipeline that it happens and
|
||||||
|
// settings changes are applied.
|
||||||
|
switch (m_transientState) {
|
||||||
|
case QCamera::UnloadedState:
|
||||||
|
unload();
|
||||||
|
break;
|
||||||
|
case QCamera::LoadedState:
|
||||||
|
stop();
|
||||||
|
break;
|
||||||
|
case QCamera::ActiveState:
|
||||||
|
// Unreachable
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_requestedState > m_acceptedState
|
||||||
|
&& !m_busy
|
||||||
|
&& isReady()
|
||||||
|
&& m_resourcePolicy.isResourcesGranted()) {
|
||||||
|
m_transientState = m_requestedState;
|
||||||
|
|
||||||
|
switch (m_requestedState) {
|
||||||
|
case QCamera::UnloadedState:
|
||||||
|
// Unreachable.
|
||||||
|
break;
|
||||||
|
case QCamera::LoadedState:
|
||||||
|
load();
|
||||||
|
break;
|
||||||
|
case QCamera::ActiveState:
|
||||||
|
if (m_status == QCamera::UnloadedStatus) {
|
||||||
|
load();
|
||||||
|
} else if (m_status == QCamera::LoadedStatus) {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraBinSession::resourcesLost()
|
||||||
|
{
|
||||||
|
m_transientState = QCamera::UnloadedState;
|
||||||
|
|
||||||
|
applyState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::setError(int err, const QString &errorString)
|
void CameraBinSession::setError(int err, const QString &errorString)
|
||||||
{
|
{
|
||||||
m_pendingState = QCamera::UnloadedState;
|
m_requestedState = QCamera::UnloadedState;
|
||||||
emit error(err, errorString);
|
m_transientState = QCamera::UnloadedState;
|
||||||
setStatus(QCamera::UnloadedStatus);
|
|
||||||
|
emit m_cameraControl->error(err, errorString);
|
||||||
|
|
||||||
|
applyState();
|
||||||
|
|
||||||
|
emit m_cameraControl->stateChanged(m_requestedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::load()
|
void CameraBinSession::load()
|
||||||
{
|
{
|
||||||
if (m_status != QCamera::UnloadedStatus && !m_viewfinderHasChanged)
|
if (m_status != QCamera::UnloadedStatus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setStatus(QCamera::LoadingStatus);
|
m_acceptedState = QCamera::LoadedState;
|
||||||
|
|
||||||
|
m_status = QCamera::LoadingStatus;
|
||||||
|
|
||||||
if (!setupCameraBin()) {
|
if (!setupCameraBin()) {
|
||||||
setError(QCamera::CameraError, QStringLiteral("No camera source available"));
|
setError(QCamera::CameraError, QStringLiteral("No camera source available"));
|
||||||
@@ -780,23 +850,34 @@ void CameraBinSession::load()
|
|||||||
setupCaptureResolution();
|
setupCaptureResolution();
|
||||||
|
|
||||||
gst_element_set_state(m_camerabin, GST_STATE_READY);
|
gst_element_set_state(m_camerabin, GST_STATE_READY);
|
||||||
|
|
||||||
|
emit statusChanged(m_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::unload()
|
void CameraBinSession::unload()
|
||||||
{
|
{
|
||||||
if (m_status == QCamera::UnloadedStatus || m_status == QCamera::UnloadingStatus)
|
if (m_status == QCamera::UnloadedStatus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We save the recording state in case something reacted to setStatus() and
|
bool changed = m_status != QCamera::UnloadingStatus;
|
||||||
// stopped recording.
|
m_status = QCamera::UnloadingStatus;
|
||||||
bool wasRecording = m_recordingActive;
|
|
||||||
|
|
||||||
setStatus(QCamera::UnloadingStatus);
|
|
||||||
|
|
||||||
if (m_recordingActive)
|
if (m_recordingActive)
|
||||||
stopVideoRecording();
|
stopVideoRecording();
|
||||||
else if (!wasRecording)
|
|
||||||
handleBusyChanged(false);
|
if (!m_busy) {
|
||||||
|
m_acceptedState = QCamera::UnloadedState;
|
||||||
|
|
||||||
|
if (m_viewfinderInterface)
|
||||||
|
m_viewfinderInterface->stopRenderer();
|
||||||
|
|
||||||
|
gst_element_set_state(m_camerabin, GST_STATE_NULL);
|
||||||
|
|
||||||
|
m_status = QCamera::UnloadedStatus;
|
||||||
|
emit statusChanged(m_status);
|
||||||
|
} else if (changed) {
|
||||||
|
emit statusChanged(m_status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::start()
|
void CameraBinSession::start()
|
||||||
@@ -804,7 +885,20 @@ void CameraBinSession::start()
|
|||||||
if (m_status != QCamera::LoadedStatus)
|
if (m_status != QCamera::LoadedStatus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setStatus(QCamera::StartingStatus);
|
m_acceptedState = QCamera::ActiveState;
|
||||||
|
|
||||||
|
m_status = QCamera::StartingStatus;
|
||||||
|
|
||||||
|
m_appliedCaptureMode = m_captureMode;
|
||||||
|
|
||||||
|
switch (m_captureMode) {
|
||||||
|
case QCamera::CaptureStillImage:
|
||||||
|
g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_IMAGE_MODE, NULL);
|
||||||
|
break;
|
||||||
|
case QCamera::CaptureVideo:
|
||||||
|
g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_VIDEO_MODE, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_recorderControl->applySettings();
|
m_recorderControl->applySettings();
|
||||||
|
|
||||||
@@ -822,22 +916,30 @@ void CameraBinSession::start()
|
|||||||
setupCaptureResolution();
|
setupCaptureResolution();
|
||||||
|
|
||||||
gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
|
gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
emit statusChanged(m_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::stop()
|
void CameraBinSession::stop()
|
||||||
{
|
{
|
||||||
if (m_status != QCamera::ActiveStatus)
|
if (m_status != QCamera::ActiveStatus && m_status != QCamera::StartingStatus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setStatus(QCamera::StoppingStatus);
|
m_status = QCamera::StoppingStatus;
|
||||||
|
|
||||||
if (m_recordingActive)
|
if (m_recordingActive)
|
||||||
stopVideoRecording();
|
stopVideoRecording();
|
||||||
|
|
||||||
if (m_viewfinderInterface)
|
if (!m_busy) {
|
||||||
m_viewfinderInterface->stopRenderer();
|
m_acceptedState = QCamera::LoadedState;
|
||||||
|
|
||||||
gst_element_set_state(m_camerabin, GST_STATE_READY);
|
if (m_viewfinderInterface)
|
||||||
|
m_viewfinderInterface->stopRenderer();
|
||||||
|
|
||||||
|
gst_element_set_state(m_camerabin, GST_STATE_READY);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit statusChanged(m_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CameraBinSession::isBusy() const
|
bool CameraBinSession::isBusy() const
|
||||||
@@ -859,11 +961,8 @@ void CameraBinSession::updateBusyStatus(GObject *o, GParamSpec *p, gpointer d)
|
|||||||
g_object_get(o, "idle", &idle, NULL);
|
g_object_get(o, "idle", &idle, NULL);
|
||||||
bool busy = !idle;
|
bool busy = !idle;
|
||||||
|
|
||||||
if (session->m_busy != busy) {
|
if (session->m_busy.fetchAndStoreRelaxed(busy) != busy) {
|
||||||
session->m_busy = busy;
|
QMetaObject::invokeMethod(session, "applyState", Qt::QueuedConnection);
|
||||||
QMetaObject::invokeMethod(session, "handleBusyChanged",
|
|
||||||
Qt::QueuedConnection,
|
|
||||||
Q_ARG(bool, busy));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,10 +974,9 @@ void CameraBinSession::updateReadyForCapture(GObject *o, GParamSpec *p, gpointer
|
|||||||
CameraBinSession *session = reinterpret_cast<CameraBinSession *>(d);
|
CameraBinSession *session = reinterpret_cast<CameraBinSession *>(d);
|
||||||
gboolean ready = false;
|
gboolean ready = false;
|
||||||
g_object_get(o, "ready-for-capture", &ready, NULL);
|
g_object_get(o, "ready-for-capture", &ready, NULL);
|
||||||
if (session->m_readyForCapture != ready) {
|
|
||||||
session->m_readyForCapture = ready;
|
if (session->m_reportedReadyForCapture.fetchAndStoreRelaxed(ready) != ready) {
|
||||||
QMetaObject::invokeMethod(session, "handleReadyForCaptureChanged",
|
QMetaObject::invokeMethod(session, "updateCaptureStatus", Qt::QueuedConnection);
|
||||||
Qt::QueuedConnection, Q_ARG(bool, ready));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,6 +1185,9 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update any chained state changes.
|
||||||
|
applyState();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1121,6 +1222,10 @@ QString CameraBinSession::currentContainerFormat() const
|
|||||||
|
|
||||||
void CameraBinSession::recordVideo()
|
void CameraBinSession::recordVideo()
|
||||||
{
|
{
|
||||||
|
if (!m_reportedReadyForCapture || m_appliedCaptureMode != QCamera::CaptureVideo || m_busy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QString format = currentContainerFormat();
|
QString format = currentContainerFormat();
|
||||||
if (format.isEmpty())
|
if (format.isEmpty())
|
||||||
format = m_mediaContainerControl->actualContainerFormat();
|
format = m_mediaContainerControl->actualContainerFormat();
|
||||||
@@ -1531,28 +1636,4 @@ void CameraBinSession::elementRemoved(GstBin *, GstElement *element, CameraBinSe
|
|||||||
session->m_muxer = 0;
|
session->m_muxer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::handleBusyChanged(bool busy)
|
|
||||||
{
|
|
||||||
// don't do anything if we are not unloading.
|
|
||||||
// It could be that the camera is starting again while it is being unloaded
|
|
||||||
if (m_status != QCamera::UnloadingStatus) {
|
|
||||||
if (m_busy != busy)
|
|
||||||
emit busyChanged(m_busy = busy);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we can really stop
|
|
||||||
if (m_viewfinderInterface)
|
|
||||||
m_viewfinderInterface->stopRenderer();
|
|
||||||
|
|
||||||
gst_element_set_state(m_camerabin, GST_STATE_NULL);
|
|
||||||
|
|
||||||
if (m_busy != busy)
|
|
||||||
emit busyChanged(m_busy = busy);
|
|
||||||
|
|
||||||
m_supportedViewfinderSettings.clear();
|
|
||||||
|
|
||||||
setStatus(QCamera::UnloadedStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -49,6 +49,8 @@
|
|||||||
#include <private/qmediastoragelocation_p.h>
|
#include <private/qmediastoragelocation_p.h>
|
||||||
#include "qcamera.h"
|
#include "qcamera.h"
|
||||||
|
|
||||||
|
#include "camerabinresourcepolicy.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QGstreamerMessage;
|
class QGstreamerMessage;
|
||||||
@@ -118,6 +120,7 @@ public:
|
|||||||
CameraBinLocks *cameraLocksControl();
|
CameraBinLocks *cameraLocksControl();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CamerabinResourcePolicy *resourcePolicy() { return &m_resourcePolicy; }
|
||||||
CameraBinZoom *cameraZoomControl() const { return m_cameraZoomControl; }
|
CameraBinZoom *cameraZoomControl() const { return m_cameraZoomControl; }
|
||||||
CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
|
CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
|
||||||
CameraBinCaptureDestination *captureDestinationControl() const { return m_captureDestinationControl; }
|
CameraBinCaptureDestination *captureDestinationControl() const { return m_captureDestinationControl; }
|
||||||
@@ -143,7 +146,7 @@ public:
|
|||||||
void captureImage(int requestId, const QString &fileName);
|
void captureImage(int requestId, const QString &fileName);
|
||||||
|
|
||||||
QCamera::Status status() const;
|
QCamera::Status status() const;
|
||||||
QCamera::State pendingState() const;
|
QCamera::State requestedState() const;
|
||||||
bool isBusy() const;
|
bool isBusy() const;
|
||||||
bool isReadyForCapture() const;
|
bool isReadyForCapture() const;
|
||||||
|
|
||||||
@@ -182,7 +185,8 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void handleViewfinderChange();
|
void handleViewfinderChange();
|
||||||
void setupCaptureResolution();
|
void setupCaptureResolution();
|
||||||
void handleBusyChanged(bool busy);
|
void updateCaptureStatus();
|
||||||
|
void applyState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load();
|
void load();
|
||||||
@@ -191,7 +195,7 @@ private:
|
|||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void setStatus(QCamera::Status status);
|
void setStatus(QCamera::Status status);
|
||||||
void setStateHelper(QCamera::State state);
|
void resourcesLost();
|
||||||
void setError(int error, const QString &errorString);
|
void setError(int error, const QString &errorString);
|
||||||
|
|
||||||
bool setupCameraBin();
|
bool setupCameraBin();
|
||||||
@@ -211,16 +215,21 @@ private:
|
|||||||
bool m_recordingActive;
|
bool m_recordingActive;
|
||||||
QString m_captureDevice;
|
QString m_captureDevice;
|
||||||
QCamera::Status m_status;
|
QCamera::Status m_status;
|
||||||
QCamera::State m_pendingState;
|
QCamera::State m_requestedState; // The desired state, transitioning to this may be blocked resource policy or outstanding actions.
|
||||||
|
QCamera::State m_transientState; // A state that must be passed through. If the pipeline is busy and can't be unloaded immediately it should still go through unloaded when it can to apply settings changes.
|
||||||
|
QCamera::State m_acceptedState; // The current state or the state the pipeline is actively transitioning to.
|
||||||
QString m_inputDevice;
|
QString m_inputDevice;
|
||||||
bool m_muted;
|
bool m_muted;
|
||||||
bool m_busy;
|
|
||||||
bool m_readyForCapture;
|
bool m_readyForCapture;
|
||||||
QMediaStorageLocation m_mediaStorageLocation;
|
QMediaStorageLocation m_mediaStorageLocation;
|
||||||
|
|
||||||
QCamera::CaptureModes m_captureMode;
|
QCamera::CaptureModes m_captureMode;
|
||||||
|
QCamera::CaptureModes m_appliedCaptureMode;
|
||||||
QMap<QByteArray, QVariant> m_metaData;
|
QMap<QByteArray, QVariant> m_metaData;
|
||||||
|
|
||||||
|
QAtomicInteger<bool> m_busy;
|
||||||
|
QAtomicInteger<bool> m_reportedReadyForCapture;
|
||||||
|
|
||||||
QGstreamerElementFactory *m_audioInputFactory;
|
QGstreamerElementFactory *m_audioInputFactory;
|
||||||
QGstreamerElementFactory *m_videoInputFactory;
|
QGstreamerElementFactory *m_videoInputFactory;
|
||||||
QObject *m_viewfinder;
|
QObject *m_viewfinder;
|
||||||
@@ -229,6 +238,7 @@ private:
|
|||||||
QCameraViewfinderSettings m_viewfinderSettings;
|
QCameraViewfinderSettings m_viewfinderSettings;
|
||||||
QCameraViewfinderSettings m_actualViewfinderSettings;
|
QCameraViewfinderSettings m_actualViewfinderSettings;
|
||||||
|
|
||||||
|
CamerabinResourcePolicy m_resourcePolicy;
|
||||||
CameraBinControl *m_cameraControl;
|
CameraBinControl *m_cameraControl;
|
||||||
CameraBinAudioEncoder *m_audioEncodeControl;
|
CameraBinAudioEncoder *m_audioEncodeControl;
|
||||||
CameraBinVideoEncoder *m_videoEncodeControl;
|
CameraBinVideoEncoder *m_videoEncodeControl;
|
||||||
|
|||||||
Reference in New Issue
Block a user