winrt: fix camera control after move to xaml thread
Camera control management has to happen inside the xaml thread, otherwise the behavior is undefined. This results in ie. the first capture not working due to synchronization issues. When (de-)activating the videoRenderer we have to switch to the UI thread first. In addition add focus for Windows 10 (Mobile), previously it was compiled for Windows Phone 8.1 only. On desktop this might return no focus mode to be supported, but API-wise this is available. Task-number: QTBUG-47803 Change-Id: I9b345ebc82502fc6e00aede43b9096893cd0ad53 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This commit is contained in:
committed by
Maurice Kalinowski
parent
65c9e24c10
commit
a0a20157ef
@@ -46,8 +46,10 @@
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/qfunctions_winrt.h>
|
||||
#include <QtCore/private/qeventdispatcher_winrt_p.h>
|
||||
#include <QtMultimedia/private/qmediastoragelocation_p.h>
|
||||
|
||||
#include <functional>
|
||||
#include <wrl.h>
|
||||
#include <windows.media.capture.h>
|
||||
#include <windows.media.devices.h>
|
||||
@@ -161,33 +163,37 @@ int QWinRTCameraImageCaptureControl::capture(const QString &fileName)
|
||||
fileName.isEmpty() ? QStringLiteral("jpg") : QFileInfo(fileName).suffix())
|
||||
};
|
||||
|
||||
HRESULT hr;
|
||||
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(),
|
||||
&request.stream);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d, capture, &request]() {
|
||||
HRESULT hr;
|
||||
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(),
|
||||
&request.stream);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
hr = g->encodingPropertiesFactory->CreateBmp(&request.imageFormat);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = g->encodingPropertiesFactory->CreateBmp(&request.imageFormat);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
const QSize imageSize = static_cast<QWinRTImageEncoderControl*>(d->cameraControl->imageEncoderControl())->imageSettings().resolution();
|
||||
hr = request.imageFormat->put_Width(imageSize.width());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = request.imageFormat->put_Height(imageSize.height());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
const QSize imageSize = static_cast<QWinRTImageEncoderControl*>(d->cameraControl->imageEncoderControl())->imageSettings().resolution();
|
||||
hr = request.imageFormat->put_Width(imageSize.width());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = request.imageFormat->put_Height(imageSize.height());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
hr = capture->CapturePhotoToStreamAsync(request.imageFormat.Get(), request.stream.Get(), &request.op);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
if (!request.op) {
|
||||
qErrnoWarning("Camera photo capture failed.");
|
||||
hr = capture->CapturePhotoToStreamAsync(request.imageFormat.Get(), request.stream.Get(), &request.op);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
if (!request.op) {
|
||||
qErrnoWarning("Camera photo capture failed.");
|
||||
return E_FAIL;
|
||||
}
|
||||
emit captureQueueChanged(false);
|
||||
d->requests.insert(request.op.Get(), request);
|
||||
|
||||
hr = request.op->put_Completed(Callback<IAsyncActionCompletedHandler>(
|
||||
this, &QWinRTCameraImageCaptureControl::onCaptureCompleted).Get());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
return hr;
|
||||
});
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
}
|
||||
emit captureQueueChanged(false);
|
||||
d->requests.insert(request.op.Get(), request);
|
||||
|
||||
hr = request.op->put_Completed(Callback<IAsyncActionCompletedHandler>(
|
||||
this, &QWinRTCameraImageCaptureControl::onCaptureCompleted).Get());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
return request.id;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user