From 485cb9cec54ee3b9466e730037e7480296e2ecd0 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Tue, 14 Nov 2017 13:47:09 +0100 Subject: DirectShow: Emit an error if QCamera::start() fails If a camera is not started successfully, then an error() should be emitted. After an error the camera's state will be QCamera::UnloadedState and status will be QCamera::UnloadedStatus. The error signal is handled when the camera is unable to set following states: QCamera::UnloadedState, QCamera::LoadedState or QCamera::LoadingState. Thus additionally to QCamera::start() an error can be emitted even when QCamera::load(), QCamera::unload(), or QCamera::stop() is called. Task-number: QTBUG-51825 Change-Id: Ib5ea08ed7983ea49a7bf8c0321cc5266a68d9144 Reviewed-by: Christian Stromme --- src/plugins/directshow/camera/dscameracontrol.cpp | 2 ++ src/plugins/directshow/camera/dscamerasession.cpp | 38 +++++++++++++++-------- src/plugins/directshow/camera/dscamerasession.h | 2 ++ 3 files changed, 29 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/plugins/directshow/camera/dscameracontrol.cpp b/src/plugins/directshow/camera/dscameracontrol.cpp index a6824976d..8d923da9f 100644 --- a/src/plugins/directshow/camera/dscameracontrol.cpp +++ b/src/plugins/directshow/camera/dscameracontrol.cpp @@ -53,6 +53,8 @@ DSCameraControl::DSCameraControl(QObject *parent) m_session = qobject_cast(parent); connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SIGNAL(statusChanged(QCamera::Status))); + connect(m_session, &DSCameraSession::cameraError, + this, &DSCameraControl::error); } DSCameraControl::~DSCameraControl() diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 9b642872a..ca3c47cb8 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -441,30 +441,33 @@ bool DSCameraSession::startPreview() setStatus(QCamera::StartingStatus); + QString errorString; HRESULT hr = S_OK; IMediaControl* pControl = 0; if (!configurePreviewFormat()) { - qWarning() << "Failed to configure preview format"; + errorString = tr("Failed to configure preview format"); goto failed; } - if (!connectGraph()) + if (!connectGraph()) { + errorString = tr("Failed to connect graph"); goto failed; + } if (m_surface) m_surface->start(m_previewSurfaceFormat); hr = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); if (FAILED(hr)) { - qWarning() << "failed to get stream control"; + errorString = tr("Failed to get stream control"); goto failed; } hr = pControl->Run(); pControl->Release(); if (FAILED(hr)) { - qWarning() << "failed to start"; + errorString = tr("Failed to start"); goto failed; } @@ -477,7 +480,7 @@ failed: if (m_surface && m_surface->isActive()) m_surface->stop(); disconnectGraph(); - setStatus(QCamera::LoadedStatus); + setError(QCamera::CameraError, errorString); return false; } @@ -491,17 +494,18 @@ bool DSCameraSession::stopPreview() if (m_previewSampleGrabber) m_previewSampleGrabber->stop(); + QString errorString; IMediaControl* pControl = 0; HRESULT hr = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); if (FAILED(hr)) { - qWarning() << "failed to get stream control"; + errorString = tr("Failed to get stream control"); goto failed; } hr = pControl->Stop(); pControl->Release(); if (FAILED(hr)) { - qWarning() << "failed to stop"; + errorString = tr("Failed to stop"); goto failed; } @@ -514,10 +518,16 @@ bool DSCameraSession::stopPreview() return true; failed: - setStatus(QCamera::ActiveStatus); + setError(QCamera::CameraError, errorString); return false; } +void DSCameraSession::setError(int error, const QString &errorString) +{ + emit cameraError(error, errorString); + setStatus(QCamera::UnloadedStatus); +} + void DSCameraSession::setStatus(QCamera::Status status) { if (m_status == status) @@ -668,6 +678,7 @@ bool DSCameraSession::createFilterGraph() // Previously containered in . static const CLSID cLSID_NullRenderer = { 0xC1F400A4, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; + QString errorString; HRESULT hr; IMoniker* pMoniker = NULL; ICreateDevEnum* pDevEnum = NULL; @@ -677,7 +688,7 @@ bool DSCameraSession::createFilterGraph() hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_filterGraph); if (FAILED(hr)) { - qWarning() << "failed to create filter graph"; + errorString = tr("Failed to create filter graph"); goto failed; } @@ -685,14 +696,14 @@ bool DSCameraSession::createFilterGraph() hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&m_graphBuilder); if (FAILED(hr)) { - qWarning() << "failed to create graph builder"; + errorString = tr("Failed to create graph builder"); goto failed; } // Attach the filter graph to the capture graph hr = m_graphBuilder->SetFiltergraph(m_filterGraph); if (FAILED(hr)) { - qWarning() << "failed to connect capture graph and filter graph"; + errorString = tr("Failed to connect capture graph and filter graph"); goto failed; } @@ -762,7 +773,7 @@ bool DSCameraSession::createFilterGraph() } if (!m_sourceFilter) { - qWarning() << "No capture device found"; + errorString = tr("No capture device found"); goto failed; } @@ -779,7 +790,7 @@ bool DSCameraSession::createFilterGraph() hr = CoCreateInstance(cLSID_NullRenderer, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&m_nullRendererFilter); if (FAILED(hr)) { - qWarning() << "failed to create null renderer"; + errorString = tr("Failed to create null renderer"); goto failed; } @@ -793,6 +804,7 @@ failed: SAFE_RELEASE(m_nullRendererFilter); SAFE_RELEASE(m_filterGraph); SAFE_RELEASE(m_graphBuilder); + setError(QCamera::CameraError, errorString); return false; } diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index e28015534..07c3d9ef9 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -138,6 +138,7 @@ Q_SIGNALS: void readyForCaptureChanged(bool); void captureError(int id, int error, const QString &errorString); void captureDestinationChanged(QCameraImageCapture::CaptureDestinations); + void cameraError(int error, const QString &errorString); private Q_SLOTS: void presentFrame(); @@ -176,6 +177,7 @@ private: void updateSourceCapabilities(); bool configurePreviewFormat(); void updateImageProcessingParametersInfos(); + void setError(int error, const QString &errorString); // These static functions are used for scaling of adjustable parameters, // which have the ranges from -1.0 to +1.0 in the QCameraImageProcessing API. -- cgit v1.2.3