summaryrefslogtreecommitdiffstats
path: root/src/plugins/winrt/qwinrtcameracontrol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/winrt/qwinrtcameracontrol.cpp')
-rw-r--r--src/plugins/winrt/qwinrtcameracontrol.cpp376
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);
}