summaryrefslogtreecommitdiffstats
path: root/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp')
-rw-r--r--src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp338
1 files changed, 0 insertions, 338 deletions
diff --git a/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp b/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp
deleted file mode 100644
index 4ed208feb..000000000
--- a/src/plugins/winrt/qwinrtcameraimagecapturecontrol.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwinrtcameraimagecapturecontrol.h"
-#include "qwinrtcameracontrol.h"
-#include "qwinrtimageencodercontrol.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-#include <QtCore/QGlobalStatic>
-#include <QtCore/QPointer>
-#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>
-#include <windows.media.mediaproperties.h>
-#include <windows.storage.streams.h>
-#include <windows.graphics.imaging.h>
-#include <robuffer.h>
-
-using namespace Microsoft::WRL;
-using namespace Microsoft::WRL::Wrappers;
-using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::Media::Capture;
-using namespace ABI::Windows::Media::Devices;
-using namespace ABI::Windows::Media::MediaProperties;
-using namespace ABI::Windows::Storage::Streams;
-using namespace ABI::Windows::Graphics::Imaging;
-
-QT_BEGIN_NAMESPACE
-
-#define wchar(str) reinterpret_cast<const wchar_t *>(str.utf16())
-
-struct QWinRTCameraImageCaptureControlGlobal
-{
- QWinRTCameraImageCaptureControlGlobal()
- {
- HRESULT hr;
- hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Media_MediaProperties_ImageEncodingProperties).Get(),
- &encodingPropertiesFactory);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
- &bufferFactory);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(),
- &dataReaderFactory);
- }
-
- ComPtr<IImageEncodingPropertiesStatics2> encodingPropertiesFactory;
- ComPtr<IBufferFactory> bufferFactory;
- ComPtr<IDataReaderFactory> dataReaderFactory;
-};
-Q_GLOBAL_STATIC(QWinRTCameraImageCaptureControlGlobal, g)
-
-struct CaptureRequest
-{
- quint16 id;
- QString fileName;
- ComPtr<IImageEncodingProperties> imageFormat;
- ComPtr<IRandomAccessStream> stream;
- ComPtr<IAsyncAction> op;
-};
-
-// Do not use CoTaskMemFree directly for image cleanup as it leads to crashes in release
-static void freeImageData(void *data)
-{
- CoTaskMemFree(data);
-}
-
-class QWinRTCameraImageCaptureControlPrivate
-{
-public:
- QWinRTCameraImageCaptureControlPrivate()
- : isActive(false)
- {
- }
-
- QPointer<QWinRTCameraControl> cameraControl;
- QHash<IAsyncAction *, CaptureRequest> requests;
- quint16 currentCaptureId;
- QMediaStorageLocation location;
- bool isActive;
-};
-
-QWinRTCameraImageCaptureControl::QWinRTCameraImageCaptureControl(QWinRTCameraControl *parent)
- : QCameraImageCaptureControl(parent), d_ptr(new QWinRTCameraImageCaptureControlPrivate)
-{
- qCDebug(lcMMCamera) << __FUNCTION__ << parent;
- Q_D(QWinRTCameraImageCaptureControl);
-
- d->cameraControl = parent;
- connect(d->cameraControl, &QCameraControl::stateChanged,
- this, &QWinRTCameraImageCaptureControl::onCameraStateChanged);
- d->currentCaptureId = 0;
-}
-
-bool QWinRTCameraImageCaptureControl::isReadyForCapture() const
-{
- Q_D(const QWinRTCameraImageCaptureControl);
- return d->isActive;
-}
-
-QCameraImageCapture::DriveMode QWinRTCameraImageCaptureControl::driveMode() const
-{
- return QCameraImageCapture::SingleImageCapture;
-}
-
-void QWinRTCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode)
-{
- Q_UNUSED(mode);
-}
-
-int QWinRTCameraImageCaptureControl::capture(const QString &fileName)
-{
- qCDebug(lcMMCamera) << __FUNCTION__ << fileName;
- Q_D(QWinRTCameraImageCaptureControl);
-
- ++d->currentCaptureId;
- ComPtr<IMediaCapture> capture = d->cameraControl->handle();
- if (!capture) {
- emit error(d->currentCaptureId, QCameraImageCapture::NotReadyError, tr("Camera not ready"));
- return -1;
- }
-
- CaptureRequest request = {
- d->currentCaptureId,
- d->location.generateFileName(fileName, QMediaStorageLocation::Pictures, QStringLiteral("IMG_"),
- fileName.isEmpty() ? QStringLiteral("jpg") : QFileInfo(fileName).suffix()),
- nullptr, nullptr, nullptr
- };
-
- 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);
-
- const QSize imageSize = static_cast<QWinRTImageEncoderControl*>(d->cameraControl->imageEncoderControl())->imageSettings().resolution();
- hr = request.imageFormat->put_Width(UINT32(imageSize.width()));
- Q_ASSERT_SUCCEEDED(hr);
- hr = request.imageFormat->put_Height(UINT32(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.");
- 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;
- return request.id;
-}
-
-void QWinRTCameraImageCaptureControl::cancelCapture()
-{
- qCDebug(lcMMCamera) << __FUNCTION__;
- Q_D(QWinRTCameraImageCaptureControl);
-
- QHash<IAsyncAction *, CaptureRequest>::iterator it = d->requests.begin();
- while (it != d->requests.end()) {
- ComPtr<IAsyncInfo> info;
- it->op.As(&info);
- info->Cancel();
- it = d->requests.erase(it);
- }
- emit captureQueueChanged(true);
-}
-
-void QWinRTCameraImageCaptureControl::onCameraStateChanged(QCamera::State state)
-{
- Q_D(QWinRTCameraImageCaptureControl);
- const bool newActive = state == QCamera::ActiveState;
- if (d->isActive == newActive)
- return;
-
- d->isActive = newActive;
- emit readyForCaptureChanged(newActive);
-}
-
-HRESULT QWinRTCameraImageCaptureControl::onCaptureCompleted(IAsyncAction *asyncInfo, AsyncStatus status)
-{
- qCDebug(lcMMCamera) << __FUNCTION__;
- Q_D(QWinRTCameraImageCaptureControl);
-
- if (status == Canceled || !d->requests.contains(asyncInfo))
- return S_OK;
-
- CaptureRequest request = d->requests.take(asyncInfo);
- emit captureQueueChanged(d->requests.isEmpty());
- HRESULT hr;
- if (status == Error) {
- hr = asyncInfo->GetResults();
- emit error(request.id, QCameraImageCapture::ResourceError, qt_error_string(hr));
- return S_OK;
- }
-
- quint64 dataLength;
- hr = request.stream->get_Size(&dataLength);
- Q_ASSERT_SUCCEEDED(hr);
- if (dataLength == 0 || dataLength > INT_MAX) {
- emit error(request.id, QCameraImageCapture::FormatError, tr("Invalid photo data length."));
- return S_OK;
- }
-
- ComPtr<IBitmapDecoderStatics> bitmapFactory;
- hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_BitmapDecoder).Get(),
- &bitmapFactory);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IAsyncOperation<BitmapDecoder *>> op;
- hr = bitmapFactory->CreateAsync(request.stream.Get(), &op);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IBitmapDecoder> decoder;
- hr = QWinRTFunctions::await(op, decoder.GetAddressOf());
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IAsyncOperation<BitmapFrame *>> op2;
- hr = decoder->GetFrameAsync(0, &op2);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IBitmapFrame> frame;
- hr = QWinRTFunctions::await(op2, frame.GetAddressOf());
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IBitmapTransform> transform;
- hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_BitmapTransform).Get(),
- &transform);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IAsyncOperation<PixelDataProvider *>> op3;
- hr = frame->GetPixelDataTransformedAsync(BitmapPixelFormat_Rgba8, BitmapAlphaMode_Straight,
- transform.Get(), ExifOrientationMode_IgnoreExifOrientation,
- ColorManagementMode_DoNotColorManage, &op3);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IPixelDataProvider> pixelDataProvider;
- hr = QWinRTFunctions::await(op3, pixelDataProvider.GetAddressOf());
- Q_ASSERT_SUCCEEDED(hr);
-
- UINT32 pixelDataSize;
- BYTE *pixelData;
- hr = pixelDataProvider->DetachPixelData(&pixelDataSize, &pixelData);
-
- UINT32 pixelHeight;
- hr = frame->get_PixelHeight(&pixelHeight);
- Q_ASSERT_SUCCEEDED(hr);
- UINT32 pixelWidth;
- hr = frame->get_PixelWidth(&pixelWidth);
- Q_ASSERT_SUCCEEDED(hr);
- const QImage image(pixelData, int(pixelWidth), int(pixelHeight),
- QImage::Format_RGBA8888,
- reinterpret_cast<QImageCleanupFunction>(&freeImageData), pixelData);
- emit imageCaptured(request.id, image);
-
- QWinRTImageEncoderControl *imageEncoderControl = static_cast<QWinRTImageEncoderControl*>(d->cameraControl->imageEncoderControl());
- int imageQuality = 100;
- switch (imageEncoderControl->imageSettings().quality()) {
- case QMultimedia::VeryLowQuality:
- imageQuality = 20;
- break;
- case QMultimedia::LowQuality:
- imageQuality = 40;
- break;
- case QMultimedia::NormalQuality:
- imageQuality = 60;
- break;
- case QMultimedia::HighQuality:
- imageQuality = 80;
- break;
- case QMultimedia::VeryHighQuality:
- imageQuality = 100;
- break;
- }
-
- if (image.save(request.fileName, imageEncoderControl->imageSettings().codec().toLatin1().data(), imageQuality))
- emit imageSaved(request.id, request.fileName);
- else
- emit error(request.id, QCameraImageCapture::ResourceError, tr("Image saving failed"));
-
- return S_OK;
-}
-
-QT_END_NAMESPACE