diff options
author | Liang Qi <liang.qi@qt.io> | 2016-05-10 19:26:21 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-05-10 19:26:21 +0200 |
commit | 08e13bfcdb23eabfbc47bca7499b0b8aadce0ac7 (patch) | |
tree | 406ffa7e3ae0a346a14175ccccb8ac7e596d8f8f /src/plugins/winrt/qwinrtcameracontrol.cpp | |
parent | fa9fe9ff8c3aba25fbae4f8f32588dd6477d6df8 (diff) | |
parent | f0e0d5d901d4e28fff9f29caf86ada84906b3db4 (diff) | |
download | qtmultimedia-08e13bfcdb23eabfbc47bca7499b0b8aadce0ac7.tar.gz |
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts:
src/plugins/winrt/qwinrtcameracontrol.cpp
Change-Id: I45d3042adf19577a72794610fa1c310cb22e26c4
Diffstat (limited to 'src/plugins/winrt/qwinrtcameracontrol.cpp')
-rw-r--r-- | src/plugins/winrt/qwinrtcameracontrol.cpp | 376 |
1 files changed, 210 insertions, 166 deletions
diff --git a/src/plugins/winrt/qwinrtcameracontrol.cpp b/src/plugins/winrt/qwinrtcameracontrol.cpp index d209d9394..40946270a 100644 --- a/src/plugins/winrt/qwinrtcameracontrol.cpp +++ b/src/plugins/winrt/qwinrtcameracontrol.cpp @@ -45,7 +45,9 @@ #include <QtCore/qfunctions_winrt.h> #include <QtCore/QPointer> #include <QtGui/QGuiApplication> +#include <private/qeventdispatcher_winrt_p.h> +#include <functional> #include <mfapi.h> #include <mferror.h> #include <mfidl.h> @@ -81,6 +83,8 @@ QT_BEGIN_NAMESPACE #define FOCUS_RECT_POSITION_MAX 0.995f // FOCUS_RECT_BOUNDARY - FOCUS_RECT_HALF_SIZE #define ASPECTRATIO_EPSILON 0.01f +Q_LOGGING_CATEGORY(lcMMCamera, "qt.mm.camera") + HRESULT getMediaStreamResolutions(IMediaDeviceController *device, MediaStreamType type, IVectorView<IMediaEncodingProperties *> **propertiesList, @@ -444,7 +448,7 @@ public: HRESULT __stdcall Shutdown() Q_DECL_OVERRIDE { m_stream->Flush(); - m_videoRenderer->setActive(false); + scheduleSetActive(false); return m_presentationClock ? m_presentationClock->Stop() : S_OK; } @@ -453,7 +457,7 @@ public: Q_UNUSED(systemTime); Q_UNUSED(clockStartOffset); - m_videoRenderer->setActive(true); + scheduleSetActive(true); return S_OK; } @@ -462,7 +466,7 @@ public: { Q_UNUSED(systemTime); - m_videoRenderer->setActive(false); + scheduleSetActive(false); return m_stream->QueueEvent(MEStreamSinkStopped, GUID_NULL, S_OK, Q_NULLPTR); } @@ -471,7 +475,7 @@ public: { Q_UNUSED(systemTime); - m_videoRenderer->setActive(false); + scheduleSetActive(false); return m_stream->QueueEvent(MEStreamSinkPaused, GUID_NULL, S_OK, Q_NULLPTR); } @@ -480,7 +484,7 @@ public: { Q_UNUSED(systemTime); - m_videoRenderer->setActive(true); + scheduleSetActive(true); return m_stream->QueueEvent(MEStreamSinkStarted, GUID_NULL, S_OK, Q_NULLPTR); } @@ -493,6 +497,12 @@ public: } private: + + inline void scheduleSetActive(bool active) + { + QMetaObject::invokeMethod(m_videoRenderer, "setActive", Qt::QueuedConnection, Q_ARG(bool, active)); + } + ComPtr<MediaStream> m_stream; ComPtr<IMFPresentationClock> m_presentationClock; @@ -532,6 +542,7 @@ public: QWinRTCameraControl::QWinRTCameraControl(QObject *parent) : QCameraControl(parent), d_ptr(new QWinRTCameraControlPrivate) { + qCDebug(lcMMCamera) << __FUNCTION__ << parent; Q_D(QWinRTCameraControl); d->delayClose = nullptr; @@ -568,6 +579,7 @@ QCamera::State QWinRTCameraControl::state() const void QWinRTCameraControl::setState(QCamera::State state) { + qCDebug(lcMMCamera) << __FUNCTION__ << state; Q_D(QWinRTCameraControl); if (d->state == state) @@ -583,16 +595,21 @@ void QWinRTCameraControl::setState(QCamera::State state) } Q_ASSERT(d->state == QCamera::LoadedState); - d->mediaSink = Make<MediaSink>(d->encodingProfile.Get(), d->videoRenderer); ComPtr<IAsyncAction> op; - hr = d->capturePreview->StartPreviewToCustomSinkAsync(d->encodingProfile.Get(), d->mediaSink.Get(), &op); - RETURN_VOID_AND_EMIT_ERROR("Failed to initiate capture"); + hr = QEventDispatcherWinRT::runOnXamlThread([d, &op]() { + d->mediaSink = Make<MediaSink>(d->encodingProfile.Get(), d->videoRenderer); + HRESULT hr = d->capturePreview->StartPreviewToCustomSinkAsync(d->encodingProfile.Get(), d->mediaSink.Get(), &op); + return hr; + }); + RETURN_VOID_AND_EMIT_ERROR("Failed to initiate capture."); if (d->status != QCamera::StartingStatus) { d->status = QCamera::StartingStatus; emit statusChanged(d->status); } - hr = QWinRTFunctions::await(op); + hr = QEventDispatcherWinRT::runOnXamlThread([&op]() { + return QWinRTFunctions::await(op); + }); if (FAILED(hr)) { emit error(QCamera::CameraError, qt_error_string(hr)); setState(QCamera::UnloadedState); // Unload everything, as initialize() will need be called again @@ -607,7 +624,7 @@ void QWinRTCameraControl::setState(QCamera::State state) emit stateChanged(d->state); d->status = QCamera::ActiveStatus; emit statusChanged(d->status); - d->mediaSink->RequestSample(); + QEventDispatcherWinRT::runOnXamlThread([d]() { d->mediaSink->RequestSample(); return S_OK;}); break; } case QCamera::LoadedState: { @@ -635,20 +652,28 @@ void QWinRTCameraControl::setState(QCamera::State state) } ComPtr<IAsyncAction> op; - hr = d->capturePreview->StopPreviewAsync(&op); + hr = QEventDispatcherWinRT::runOnXamlThread([d, &op]() { + HRESULT hr = d->capturePreview->StopPreviewAsync(&op); + return hr; + }); RETURN_VOID_AND_EMIT_ERROR("Failed to stop camera preview"); if (d->status != QCamera::StoppingStatus) { d->status = QCamera::StoppingStatus; emit statusChanged(d->status); } Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(op); // Synchronize unloading + hr = QEventDispatcherWinRT::runOnXamlThread([&op]() { + return QWinRTFunctions::await(op); // Synchronize unloading + }); if (FAILED(hr)) emit error(QCamera::InvalidRequestError, qt_error_string(hr)); if (d->mediaSink) { + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { d->mediaSink->Shutdown(); d->mediaSink.Reset(); + return S_OK; + }); } d->state = QCamera::LoadedState; @@ -667,22 +692,27 @@ void QWinRTCameraControl::setState(QCamera::State state) emit statusChanged(d->status); } - if (d->capture && d->captureFailedCookie.value) { - hr = d->capture->remove_Failed(d->captureFailedCookie); + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + HRESULT hr; + if (d->capture && d->captureFailedCookie.value) { + hr = d->capture->remove_Failed(d->captureFailedCookie); + Q_ASSERT_SUCCEEDED(hr); + d->captureFailedCookie.value = 0; + } + if (d->capture && d->recordLimitationCookie.value) { + d->capture->remove_RecordLimitationExceeded(d->recordLimitationCookie); + Q_ASSERT_SUCCEEDED(hr); + d->recordLimitationCookie.value = 0; + } + ComPtr<IClosable> capture; + hr = d->capture.As(&capture); Q_ASSERT_SUCCEEDED(hr); - d->captureFailedCookie.value = 0; - } - if (d->capture && d->recordLimitationCookie.value) { - d->capture->remove_RecordLimitationExceeded(d->recordLimitationCookie); - Q_ASSERT_SUCCEEDED(hr); - d->recordLimitationCookie.value = 0; - } - ComPtr<IClosable> capture; - hr = d->capture.As(&capture); - Q_ASSERT_SUCCEEDED(hr); - hr = capture->Close(); + hr = capture->Close(); + RETURN_HR_IF_FAILED(""); + d->capture.Reset(); + return hr; + }); RETURN_VOID_AND_EMIT_ERROR("Failed to close the capture manger"); - d->capture.Reset(); if (d->state != QCamera::UnloadedState) { d->state = QCamera::UnloadedState; emit stateChanged(d->state); @@ -713,6 +743,7 @@ QCamera::CaptureModes QWinRTCameraControl::captureMode() const void QWinRTCameraControl::setCaptureMode(QCamera::CaptureModes mode) { + qCDebug(lcMMCamera) << __FUNCTION__ << mode; Q_D(QWinRTCameraControl); if (d->captureMode == mode) @@ -775,10 +806,10 @@ QCameraLocksControl *QWinRTCameraControl::cameraLocksControl() const return d->cameraLocksControl; } -IMediaCapture *QWinRTCameraControl::handle() const +Microsoft::WRL::ComPtr<ABI::Windows::Media::Capture::IMediaCapture> QWinRTCameraControl::handle() const { Q_D(const QWinRTCameraControl); - return d->capture.Get(); + return d->capture; } void QWinRTCameraControl::onBufferRequested() @@ -791,6 +822,10 @@ void QWinRTCameraControl::onBufferRequested() void QWinRTCameraControl::onApplicationStateChanged(Qt::ApplicationState state) { + qCDebug(lcMMCamera) << __FUNCTION__ << state; +#ifdef _DEBUG + return; +#else // !_DEBUG Q_D(QWinRTCameraControl); static QCamera::State savedState = d->state; switch (state) { @@ -806,10 +841,12 @@ void QWinRTCameraControl::onApplicationStateChanged(Qt::ApplicationState state) default: break; } +#endif // _DEBUG } HRESULT QWinRTCameraControl::initialize() { + qCDebug(lcMMCamera) << __FUNCTION__; Q_D(QWinRTCameraControl); if (d->status != QCamera::LoadingStatus) { @@ -817,154 +854,158 @@ HRESULT QWinRTCameraControl::initialize() emit statusChanged(d->status); } - HRESULT hr; - ComPtr<IInspectable> capture; - hr = RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCapture).Get(), - &capture); - Q_ASSERT_SUCCEEDED(hr); - hr = capture.As(&d->capture); - Q_ASSERT_SUCCEEDED(hr); - hr = d->capture.As(&d->capturePreview); - Q_ASSERT_SUCCEEDED(hr); - hr = d->capture->add_Failed(Callback<IMediaCaptureFailedEventHandler>(this, &QWinRTCameraControl::onCaptureFailed).Get(), - &d->captureFailedCookie); - Q_ASSERT_SUCCEEDED(hr); - hr = d->capture->add_RecordLimitationExceeded(Callback<IRecordLimitationExceededEventHandler>(this, &QWinRTCameraControl::onRecordLimitationExceeded).Get(), - &d->recordLimitationCookie); - Q_ASSERT_SUCCEEDED(hr); - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(), - IID_PPV_ARGS(&d->encodingProfileFactory)); - Q_ASSERT_SUCCEEDED(hr); + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() { + HRESULT hr; + ComPtr<IInspectable> capture; + hr = RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCapture).Get(), + &capture); + Q_ASSERT_SUCCEEDED(hr); + hr = capture.As(&d->capture); + Q_ASSERT_SUCCEEDED(hr); + hr = d->capture.As(&d->capturePreview); + Q_ASSERT_SUCCEEDED(hr); + hr = d->capture->add_Failed(Callback<IMediaCaptureFailedEventHandler>(this, &QWinRTCameraControl::onCaptureFailed).Get(), + &d->captureFailedCookie); + Q_ASSERT_SUCCEEDED(hr); + hr = d->capture->add_RecordLimitationExceeded(Callback<IRecordLimitationExceededEventHandler>(this, &QWinRTCameraControl::onRecordLimitationExceeded).Get(), + &d->recordLimitationCookie); + Q_ASSERT_SUCCEEDED(hr); + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(), + IID_PPV_ARGS(&d->encodingProfileFactory)); + Q_ASSERT_SUCCEEDED(hr); - int deviceIndex = d->videoDeviceSelector->selectedDevice(); - if (deviceIndex < 0) - deviceIndex = d->videoDeviceSelector->defaultDevice(); + int deviceIndex = d->videoDeviceSelector->selectedDevice(); + if (deviceIndex < 0) + deviceIndex = d->videoDeviceSelector->defaultDevice(); - const QString deviceName = d->videoDeviceSelector->deviceName(deviceIndex); - if (deviceName.isEmpty()) { - qWarning("No video device available or selected."); - return E_FAIL; - } + const QString deviceName = d->videoDeviceSelector->deviceName(deviceIndex); + if (deviceName.isEmpty()) { + qWarning("No video device available or selected."); + return E_FAIL; + } - const QCamera::Position position = d->videoDeviceSelector->cameraPosition(deviceName); - d->videoRenderer->setScanLineDirection(position == QCamera::BackFace ? QVideoSurfaceFormat::TopToBottom - : QVideoSurfaceFormat::BottomToTop); - ComPtr<IMediaCaptureInitializationSettings> settings; - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings).Get(), - &settings); - Q_ASSERT_SUCCEEDED(hr); - HStringReference deviceId(reinterpret_cast<LPCWSTR>(deviceName.utf16()), deviceName.length()); - hr = settings->put_VideoDeviceId(deviceId.Get()); - Q_ASSERT_SUCCEEDED(hr); + const QCamera::Position position = d->videoDeviceSelector->cameraPosition(deviceName); + d->videoRenderer->setScanLineDirection(position == QCamera::BackFace ? QVideoSurfaceFormat::TopToBottom + : QVideoSurfaceFormat::BottomToTop); + ComPtr<IMediaCaptureInitializationSettings> settings; + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings).Get(), + &settings); + Q_ASSERT_SUCCEEDED(hr); + HStringReference deviceId(reinterpret_cast<LPCWSTR>(deviceName.utf16()), deviceName.length()); + hr = settings->put_VideoDeviceId(deviceId.Get()); + Q_ASSERT_SUCCEEDED(hr); - hr = settings->put_StreamingCaptureMode(StreamingCaptureMode_Video); - Q_ASSERT_SUCCEEDED(hr); + hr = settings->put_StreamingCaptureMode(StreamingCaptureMode_Video); + Q_ASSERT_SUCCEEDED(hr); - hr = settings->put_PhotoCaptureSource(PhotoCaptureSource_Auto); - Q_ASSERT_SUCCEEDED(hr); + hr = settings->put_PhotoCaptureSource(PhotoCaptureSource_Auto); + Q_ASSERT_SUCCEEDED(hr); - ComPtr<IAsyncAction> op; - hr = d->capture->InitializeWithSettingsAsync(settings.Get(), &op); - RETURN_HR_IF_FAILED("Failed to begin initialization of media capture manager"); - hr = QWinRTFunctions::await(op, QWinRTFunctions::ProcessThreadEvents); - if (hr == E_ACCESSDENIED) { - qWarning("Access denied when initializing the media capture manager. " - "Check your manifest settings for microphone and webcam access."); - } - RETURN_HR_IF_FAILED("Failed to initialize media capture manager"); - - ComPtr<IVideoDeviceController> videoDeviceController; - hr = d->capture->get_VideoDeviceController(&videoDeviceController); - ComPtr<IAdvancedVideoCaptureDeviceController2> advancedVideoDeviceController; - hr = videoDeviceController.As(&advancedVideoDeviceController); - Q_ASSERT_SUCCEEDED(hr); - hr = advancedVideoDeviceController->get_FocusControl(&d->focusControl); - Q_ASSERT_SUCCEEDED(hr); + ComPtr<IAsyncAction> op; + hr = d->capture->InitializeWithSettingsAsync(settings.Get(), &op); + RETURN_HR_IF_FAILED("Failed to begin initialization of media capture manager"); + hr = QWinRTFunctions::await(op, QWinRTFunctions::ProcessThreadEvents); + if (hr == E_ACCESSDENIED) { + qWarning("Access denied when initializing the media capture manager. " + "Check your manifest settings for microphone and webcam access."); + } + RETURN_HR_IF_FAILED("Failed to initialize media capture manager"); - boolean isFocusSupported; - hr = d->focusControl->get_Supported(&isFocusSupported); - Q_ASSERT_SUCCEEDED(hr); - if (isFocusSupported) { - hr = advancedVideoDeviceController->get_RegionsOfInterestControl(&d->regionsOfInterestControl); + ComPtr<IVideoDeviceController> videoDeviceController; + hr = d->capture->get_VideoDeviceController(&videoDeviceController); + ComPtr<IAdvancedVideoCaptureDeviceController2> advancedVideoDeviceController; + hr = videoDeviceController.As(&advancedVideoDeviceController); Q_ASSERT_SUCCEEDED(hr); - hr = initializeFocus(); + hr = advancedVideoDeviceController->get_FocusControl(&d->focusControl); Q_ASSERT_SUCCEEDED(hr); - } else { - d->cameraFocusControl->setSupportedFocusMode(0); - d->cameraFocusControl->setSupportedFocusPointMode(QSet<QCameraFocus::FocusPointMode>()); - } - d->cameraLocksControl->initialize(); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IMediaDeviceController> deviceController; - hr = videoDeviceController.As(&deviceController); - Q_ASSERT_SUCCEEDED(hr); + boolean isFocusSupported; + hr = d->focusControl->get_Supported(&isFocusSupported); + Q_ASSERT_SUCCEEDED(hr); + if (isFocusSupported) { + hr = advancedVideoDeviceController->get_RegionsOfInterestControl(&d->regionsOfInterestControl); + Q_ASSERT_SUCCEEDED(hr); + hr = initializeFocus(); + Q_ASSERT_SUCCEEDED(hr); + } else { + d->cameraFocusControl->setSupportedFocusMode(0); + d->cameraFocusControl->setSupportedFocusPointMode(QSet<QCameraFocus::FocusPointMode>()); + } + d->cameraLocksControl->initialize(); - // Get preview stream properties. - ComPtr<IVectorView<IMediaEncodingProperties *>> previewPropertiesList; - QVector<QSize> previewResolutions; - hr = getMediaStreamResolutions(deviceController.Get(), - MediaStreamType_VideoPreview, - &previewPropertiesList, - &previewResolutions); - RETURN_HR_IF_FAILED("Failed to find a suitable video format"); - - MediaStreamType mediaStreamType = - d->captureMode == QCamera::CaptureVideo ? MediaStreamType_VideoRecord : MediaStreamType_Photo; - - // Get capture stream properties. - ComPtr<IVectorView<IMediaEncodingProperties *>> capturePropertiesList; - QVector<QSize> captureResolutions; - hr = getMediaStreamResolutions(deviceController.Get(), - mediaStreamType, - &capturePropertiesList, - &captureResolutions); - RETURN_HR_IF_FAILED("Failed to find a suitable video format"); - - // Set capture resolutions. - d->imageEncoderControl->setSupportedResolutionsList(captureResolutions.toList()); - const QSize captureResolution = d->imageEncoderControl->imageSettings().resolution(); - const quint32 captureResolutionIndex = captureResolutions.indexOf(captureResolution); - ComPtr<IMediaEncodingProperties> captureProperties; - hr = capturePropertiesList->GetAt(captureResolutionIndex, &captureProperties); - Q_ASSERT_SUCCEEDED(hr); - hr = deviceController->SetMediaStreamPropertiesAsync(mediaStreamType, captureProperties.Get(), &op); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(op); - Q_ASSERT_SUCCEEDED(hr); + Q_ASSERT_SUCCEEDED(hr); + ComPtr<IMediaDeviceController> deviceController; + hr = videoDeviceController.As(&deviceController); + Q_ASSERT_SUCCEEDED(hr); - // Set preview resolution. - QVector<QSize> filtered; - const float captureAspectRatio = float(captureResolution.width()) / captureResolution.height(); - for (const QSize &resolution : qAsConst(previewResolutions)) { - const float aspectRatio = float(resolution.width()) / resolution.height(); - if (qAbs(aspectRatio - captureAspectRatio) <= ASPECTRATIO_EPSILON) - filtered.append(resolution); - } - qSort(filtered.begin(), - filtered.end(), - [](QSize size1, QSize size2) { return size1.width() * size1.height() < size2.width() * size2.height(); }); - - const QSize &viewfinderResolution = filtered.first(); - const quint32 viewfinderResolutionIndex = previewResolutions.indexOf(viewfinderResolution); - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(), - &d->encodingProfile); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IMediaEncodingProperties> previewProperties; - hr = previewPropertiesList->GetAt(viewfinderResolutionIndex, &previewProperties); - Q_ASSERT_SUCCEEDED(hr); - hr = deviceController->SetMediaStreamPropertiesAsync(MediaStreamType_VideoPreview, previewProperties.Get(), &op); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(op); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<IVideoEncodingProperties> videoPreviewProperties; - hr = previewProperties.As(&videoPreviewProperties); - Q_ASSERT_SUCCEEDED(hr); - hr = d->encodingProfile->put_Video(videoPreviewProperties.Get()); - Q_ASSERT_SUCCEEDED(hr); + // Get preview stream properties. + ComPtr<IVectorView<IMediaEncodingProperties *>> previewPropertiesList; + QVector<QSize> previewResolutions; + hr = getMediaStreamResolutions(deviceController.Get(), + MediaStreamType_VideoPreview, + &previewPropertiesList, + &previewResolutions); + RETURN_HR_IF_FAILED("Failed to find a suitable video format"); + + MediaStreamType mediaStreamType = + d->captureMode == QCamera::CaptureVideo ? MediaStreamType_VideoRecord : MediaStreamType_Photo; + + // Get capture stream properties. + ComPtr<IVectorView<IMediaEncodingProperties *>> capturePropertiesList; + QVector<QSize> captureResolutions; + hr = getMediaStreamResolutions(deviceController.Get(), + mediaStreamType, + &capturePropertiesList, + &captureResolutions); + RETURN_HR_IF_FAILED("Failed to find a suitable video format"); + + // Set capture resolutions. + d->imageEncoderControl->setSupportedResolutionsList(captureResolutions.toList()); + const QSize captureResolution = d->imageEncoderControl->imageSettings().resolution(); + const quint32 captureResolutionIndex = captureResolutions.indexOf(captureResolution); + ComPtr<IMediaEncodingProperties> captureProperties; + hr = capturePropertiesList->GetAt(captureResolutionIndex, &captureProperties); + Q_ASSERT_SUCCEEDED(hr); + hr = deviceController->SetMediaStreamPropertiesAsync(mediaStreamType, captureProperties.Get(), &op); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(op); + Q_ASSERT_SUCCEEDED(hr); - if (d->videoRenderer) - d->videoRenderer->setSize(viewfinderResolution); + // Set preview resolution. + QVector<QSize> filtered; + const float captureAspectRatio = float(captureResolution.width()) / captureResolution.height(); + for (const QSize &resolution : qAsConst(previewResolutions)) { + const float aspectRatio = float(resolution.width()) / resolution.height(); + if (qAbs(aspectRatio - captureAspectRatio) <= ASPECTRATIO_EPSILON) + filtered.append(resolution); + } + qSort(filtered.begin(), + filtered.end(), + [](QSize size1, QSize size2) { return size1.width() * size1.height() < size2.width() * size2.height(); }); + + const QSize &viewfinderResolution = filtered.first(); + const quint32 viewfinderResolutionIndex = previewResolutions.indexOf(viewfinderResolution); + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_MediaEncodingProfile).Get(), + &d->encodingProfile); + Q_ASSERT_SUCCEEDED(hr); + ComPtr<IMediaEncodingProperties> previewProperties; + hr = previewPropertiesList->GetAt(viewfinderResolutionIndex, &previewProperties); + Q_ASSERT_SUCCEEDED(hr); + hr = deviceController->SetMediaStreamPropertiesAsync(MediaStreamType_VideoPreview, previewProperties.Get(), &op); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(op); + Q_ASSERT_SUCCEEDED(hr); + ComPtr<IVideoEncodingProperties> videoPreviewProperties; + hr = previewProperties.As(&videoPreviewProperties); + Q_ASSERT_SUCCEEDED(hr); + hr = d->encodingProfile->put_Video(videoPreviewProperties.Get()); + Q_ASSERT_SUCCEEDED(hr); + + if (d->videoRenderer) + d->videoRenderer->setSize(viewfinderResolution); + + return S_OK; + }); if (SUCCEEDED(hr) && d->state != QCamera::LoadedState) { d->state = QCamera::LoadedState; @@ -977,7 +1018,7 @@ HRESULT QWinRTCameraControl::initialize() return hr; } -#ifdef Q_OS_WINPHONE +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) HRESULT QWinRTCameraControl::initializeFocus() { @@ -1224,7 +1265,7 @@ bool QWinRTCameraControl::unlockFocus() return QWinRTFunctions::await(op) == S_OK; } -#else // Q_OS_WINPHONE +#else // !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) HRESULT QWinRTCameraControl::initializeFocus() { @@ -1265,7 +1306,7 @@ bool QWinRTCameraControl::unlockFocus() return false; } -#endif // !Q_OS_WINPHONE +#endif // !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) void QWinRTCameraControl::frameMapped() { @@ -1284,6 +1325,7 @@ void QWinRTCameraControl::frameUnmapped() HRESULT QWinRTCameraControl::onCaptureFailed(IMediaCapture *, IMediaCaptureFailedEventArgs *args) { + qCDebug(lcMMCamera) << __FUNCTION__ << args; HRESULT hr; UINT32 code; hr = args->get_Code(&code); @@ -1300,6 +1342,7 @@ HRESULT QWinRTCameraControl::onCaptureFailed(IMediaCapture *, IMediaCaptureFaile HRESULT QWinRTCameraControl::onRecordLimitationExceeded(IMediaCapture *) { + qCDebug(lcMMCamera) << __FUNCTION__; emit error(QCamera::CameraError, QStringLiteral("Recording limit exceeded.")); setState(QCamera::LoadedState); return S_OK; @@ -1307,6 +1350,7 @@ HRESULT QWinRTCameraControl::onRecordLimitationExceeded(IMediaCapture *) void QWinRTCameraControl::emitError(int errorCode, const QString &errorString) { + qCDebug(lcMMCamera) << __FUNCTION__ << errorString << errorCode; emit error(errorCode, errorString); } |