| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU Lesser General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | 
| 21 | ** packaging of this file. Please review the following information to | 
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | 
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | 
| 24 | ** | 
| 25 | ** GNU General Public License Usage | 
| 26 | ** Alternatively, this file may be used under the terms of the GNU | 
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | 
| 28 | ** Public license version 3 or any later version approved by the KDE Free | 
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | 
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | 
| 31 | ** included in the packaging of this file. Please review the following | 
| 32 | ** information to ensure the GNU General Public License requirements will | 
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | 
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | 
| 35 | ** | 
| 36 | ** $QT_END_LICENSE$ | 
| 37 | ** | 
| 38 | ****************************************************************************/ | 
| 39 | #include <qcameraimagecapture.h> | 
| 40 | #include <qcameraimagecapturecontrol.h> | 
| 41 | #include <qmediaencodersettings.h> | 
| 42 | #include <qcameracapturedestinationcontrol.h> | 
| 43 | #include <qcameracapturebufferformatcontrol.h> | 
| 44 |  | 
| 45 | #include <qimageencodercontrol.h> | 
| 46 | #include "qmediaobject_p.h" | 
| 47 | #include <qmediaservice.h> | 
| 48 | #include <qcamera.h> | 
| 49 | #include <qcameracontrol.h> | 
| 50 | #include <QtCore/qdebug.h> | 
| 51 | #include <QtCore/qurl.h> | 
| 52 | #include <QtCore/qstringlist.h> | 
| 53 | #include <QtCore/qmetaobject.h> | 
| 54 |  | 
| 55 | QT_BEGIN_NAMESPACE | 
| 56 |  | 
| 57 | /*! | 
| 58 |     \class QCameraImageCapture | 
| 59 |     \inmodule QtMultimedia | 
| 60 |     \ingroup multimedia | 
| 61 |     \ingroup multimedia_camera | 
| 62 |  | 
| 63 |  | 
| 64 |     \brief The QCameraImageCapture class is used for the recording of media content. | 
| 65 |  | 
| 66 |     The QCameraImageCapture class is a high level images recording class. | 
| 67 |     It's not intended to be used alone but for accessing the media | 
| 68 |     recording functions of other media objects, like QCamera. | 
| 69 |  | 
| 70 |     \snippet multimedia-snippets/camera.cpp Camera | 
| 71 |  | 
| 72 |     \snippet multimedia-snippets/camera.cpp Camera keys | 
| 73 |  | 
| 74 |     \sa QCamera | 
| 75 | */ | 
| 76 |  | 
| 77 | /*! | 
| 78 |     \enum QCameraImageCapture::CaptureDestination | 
| 79 |  | 
| 80 |     \value CaptureToFile  Capture the image to a file. | 
| 81 |     \value CaptureToBuffer  Capture the image to a buffer for further processing. | 
| 82 | */ | 
| 83 |  | 
| 84 | static void qRegisterCameraImageCaptureMetaTypes() | 
| 85 | { | 
| 86 |     qRegisterMetaType<QCameraImageCapture::Error>(typeName: "QCameraImageCapture::Error" ); | 
| 87 |     qRegisterMetaType<QCameraImageCapture::CaptureDestination>(typeName: "QCameraImageCapture::CaptureDestination" ); | 
| 88 |     qRegisterMetaType<QCameraImageCapture::CaptureDestinations>(typeName: "QCameraImageCapture::CaptureDestinations" ); | 
| 89 | } | 
| 90 |  | 
| 91 | Q_CONSTRUCTOR_FUNCTION(qRegisterCameraImageCaptureMetaTypes) | 
| 92 |  | 
| 93 |  | 
| 94 | class QCameraImageCapturePrivate | 
| 95 | { | 
| 96 |     Q_DECLARE_NON_CONST_PUBLIC(QCameraImageCapture) | 
| 97 | public: | 
| 98 |     QCameraImageCapturePrivate(); | 
| 99 |  | 
| 100 |     QMediaObject *mediaObject; | 
| 101 |  | 
| 102 |     QCameraImageCaptureControl *control; | 
| 103 |     QImageEncoderControl *encoderControl; | 
| 104 |     QCameraCaptureDestinationControl *captureDestinationControl; | 
| 105 |     QCameraCaptureBufferFormatControl *bufferFormatControl; | 
| 106 |  | 
| 107 |     QCameraImageCapture::Error error; | 
| 108 |     QString errorString; | 
| 109 |  | 
| 110 |     void _q_error(int id, int error, const QString &errorString); | 
| 111 |     void _q_readyChanged(bool); | 
| 112 |     void _q_serviceDestroyed(); | 
| 113 |  | 
| 114 |     void unsetError() { error = QCameraImageCapture::NoError; errorString.clear(); } | 
| 115 |  | 
| 116 |     QCameraImageCapture *q_ptr; | 
| 117 | }; | 
| 118 |  | 
| 119 | QCameraImageCapturePrivate::QCameraImageCapturePrivate(): | 
| 120 |      mediaObject(nullptr), | 
| 121 |      control(nullptr), | 
| 122 |      encoderControl(nullptr), | 
| 123 |      captureDestinationControl(nullptr), | 
| 124 |      bufferFormatControl(nullptr), | 
| 125 |      error(QCameraImageCapture::NoError) | 
| 126 | { | 
| 127 | } | 
| 128 |  | 
| 129 | void QCameraImageCapturePrivate::_q_error(int id, int error, const QString &errorString) | 
| 130 | { | 
| 131 |     Q_Q(QCameraImageCapture); | 
| 132 |  | 
| 133 |     this->error = QCameraImageCapture::Error(error); | 
| 134 |     this->errorString = errorString; | 
| 135 |  | 
| 136 |     emit q->error(id, error: this->error, errorString); | 
| 137 | } | 
| 138 |  | 
| 139 | void QCameraImageCapturePrivate::_q_readyChanged(bool ready) | 
| 140 | { | 
| 141 |     Q_Q(QCameraImageCapture); | 
| 142 |     emit q->readyForCaptureChanged(ready); | 
| 143 | } | 
| 144 |  | 
| 145 | void QCameraImageCapturePrivate::_q_serviceDestroyed() | 
| 146 | { | 
| 147 |     mediaObject = nullptr; | 
| 148 |     control = nullptr; | 
| 149 |     encoderControl = nullptr; | 
| 150 |     captureDestinationControl = nullptr; | 
| 151 |     bufferFormatControl = nullptr; | 
| 152 | } | 
| 153 |  | 
| 154 | /*! | 
| 155 |     Constructs a media recorder which records the media produced by \a mediaObject. | 
| 156 |  | 
| 157 |     The \a parent is passed to QMediaObject. | 
| 158 | */ | 
| 159 |  | 
| 160 | QCameraImageCapture::QCameraImageCapture(QMediaObject *mediaObject, QObject *parent): | 
| 161 |     QObject(parent), d_ptr(new QCameraImageCapturePrivate) | 
| 162 | { | 
| 163 |     Q_D(QCameraImageCapture); | 
| 164 |  | 
| 165 |     d->q_ptr = this; | 
| 166 |  | 
| 167 |     if (mediaObject) | 
| 168 |         mediaObject->bind(this); | 
| 169 | } | 
| 170 |  | 
| 171 | /*! | 
| 172 |     Destroys images capture object. | 
| 173 | */ | 
| 174 |  | 
| 175 | QCameraImageCapture::~QCameraImageCapture() | 
| 176 | { | 
| 177 |     Q_D(QCameraImageCapture); | 
| 178 |  | 
| 179 |     if (d->mediaObject) | 
| 180 |         d->mediaObject->unbind(this); | 
| 181 |  | 
| 182 |     delete d_ptr; | 
| 183 | } | 
| 184 |  | 
| 185 | /*! | 
| 186 |   \reimp | 
| 187 | */ | 
| 188 | QMediaObject *QCameraImageCapture::mediaObject() const | 
| 189 | { | 
| 190 |     return d_func()->mediaObject; | 
| 191 | } | 
| 192 |  | 
| 193 | /*! | 
| 194 |   \reimp | 
| 195 | */ | 
| 196 | bool QCameraImageCapture::setMediaObject(QMediaObject *mediaObject) | 
| 197 | { | 
| 198 |     Q_D(QCameraImageCapture); | 
| 199 |  | 
| 200 |     if (d->mediaObject) { | 
| 201 |         if (d->control) { | 
| 202 |             disconnect(sender: d->control, SIGNAL(imageExposed(int)), | 
| 203 |                        receiver: this, SIGNAL(imageExposed(int))); | 
| 204 |             disconnect(sender: d->control, SIGNAL(imageCaptured(int,QImage)), | 
| 205 |                        receiver: this, SIGNAL(imageCaptured(int,QImage))); | 
| 206 |             disconnect(sender: d->control, SIGNAL(imageAvailable(int,QVideoFrame)), | 
| 207 |                        receiver: this, SIGNAL(imageAvailable(int,QVideoFrame))); | 
| 208 |             disconnect(sender: d->control, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), | 
| 209 |                        receiver: this, SIGNAL(imageMetadataAvailable(int,QString,QVariant))); | 
| 210 |             disconnect(sender: d->control, SIGNAL(imageSaved(int,QString)), | 
| 211 |                        receiver: this, SIGNAL(imageSaved(int,QString))); | 
| 212 |             disconnect(sender: d->control, SIGNAL(readyForCaptureChanged(bool)), | 
| 213 |                        receiver: this, SLOT(_q_readyChanged(bool))); | 
| 214 |             disconnect(sender: d->control, SIGNAL(error(int,int,QString)), | 
| 215 |                        receiver: this, SLOT(_q_error(int,int,QString))); | 
| 216 |  | 
| 217 |             if (d->captureDestinationControl) { | 
| 218 |                 disconnect(sender: d->captureDestinationControl, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)), | 
| 219 |                            receiver: this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations))); | 
| 220 |             } | 
| 221 |  | 
| 222 |             if (d->bufferFormatControl) { | 
| 223 |                 disconnect(sender: d->bufferFormatControl, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)), | 
| 224 |                            receiver: this, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat))); | 
| 225 |             } | 
| 226 |  | 
| 227 |             QMediaService *service = d->mediaObject->service(); | 
| 228 |             service->releaseControl(control: d->control); | 
| 229 |             if (d->encoderControl) | 
| 230 |                 service->releaseControl(control: d->encoderControl); | 
| 231 |             if (d->captureDestinationControl) | 
| 232 |                 service->releaseControl(control: d->captureDestinationControl); | 
| 233 |             if (d->bufferFormatControl) | 
| 234 |                 service->releaseControl(control: d->bufferFormatControl); | 
| 235 |  | 
| 236 |             disconnect(sender: service, SIGNAL(destroyed()), receiver: this, SLOT(_q_serviceDestroyed())); | 
| 237 |         } | 
| 238 |     } | 
| 239 |  | 
| 240 |     d->mediaObject = mediaObject; | 
| 241 |  | 
| 242 |     if (d->mediaObject) { | 
| 243 |         QMediaService *service = mediaObject->service(); | 
| 244 |         if (service) { | 
| 245 |             d->control = qobject_cast<QCameraImageCaptureControl*>(object: service->requestControl(QCameraImageCaptureControl_iid)); | 
| 246 |  | 
| 247 |             if (d->control) { | 
| 248 |                 d->encoderControl = qobject_cast<QImageEncoderControl *>(object: service->requestControl(QImageEncoderControl_iid)); | 
| 249 |                 d->captureDestinationControl = qobject_cast<QCameraCaptureDestinationControl *>( | 
| 250 |                     object: service->requestControl(QCameraCaptureDestinationControl_iid)); | 
| 251 |                 d->bufferFormatControl = qobject_cast<QCameraCaptureBufferFormatControl *>( | 
| 252 |                     object: service->requestControl(QCameraCaptureBufferFormatControl_iid)); | 
| 253 |  | 
| 254 |                 connect(sender: d->control, SIGNAL(imageExposed(int)), | 
| 255 |                         receiver: this, SIGNAL(imageExposed(int))); | 
| 256 |                 connect(sender: d->control, SIGNAL(imageCaptured(int,QImage)), | 
| 257 |                         receiver: this, SIGNAL(imageCaptured(int,QImage))); | 
| 258 |                 connect(sender: d->control, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), | 
| 259 |                         receiver: this, SIGNAL(imageMetadataAvailable(int,QString,QVariant))); | 
| 260 |                 connect(sender: d->control, SIGNAL(imageAvailable(int,QVideoFrame)), | 
| 261 |                         receiver: this, SIGNAL(imageAvailable(int,QVideoFrame))); | 
| 262 |                 connect(sender: d->control, SIGNAL(imageSaved(int,QString)), | 
| 263 |                         receiver: this, SIGNAL(imageSaved(int,QString))); | 
| 264 |                 connect(sender: d->control, SIGNAL(readyForCaptureChanged(bool)), | 
| 265 |                         receiver: this, SLOT(_q_readyChanged(bool))); | 
| 266 |                 connect(sender: d->control, SIGNAL(error(int,int,QString)), | 
| 267 |                         receiver: this, SLOT(_q_error(int,int,QString))); | 
| 268 |  | 
| 269 |                 if (d->captureDestinationControl) { | 
| 270 |                     connect(sender: d->captureDestinationControl, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)), | 
| 271 |                             receiver: this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations))); | 
| 272 |                 } | 
| 273 |  | 
| 274 |                 if (d->bufferFormatControl) { | 
| 275 |                     connect(sender: d->bufferFormatControl, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)), | 
| 276 |                             receiver: this, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat))); | 
| 277 |                 } | 
| 278 |  | 
| 279 |                 connect(sender: service, SIGNAL(destroyed()), receiver: this, SLOT(_q_serviceDestroyed())); | 
| 280 |  | 
| 281 |                 return true; | 
| 282 |             } | 
| 283 |         } | 
| 284 |     } | 
| 285 |  | 
| 286 |     // without QCameraImageCaptureControl discard the media object | 
| 287 |     d->mediaObject = nullptr; | 
| 288 |     d->control = nullptr; | 
| 289 |     d->encoderControl = nullptr; | 
| 290 |     d->captureDestinationControl = nullptr; | 
| 291 |     d->bufferFormatControl = nullptr; | 
| 292 |  | 
| 293 |     return false; | 
| 294 | } | 
| 295 |  | 
| 296 | /*! | 
| 297 |     Returns true if the images capture service ready to use. | 
| 298 | */ | 
| 299 | bool QCameraImageCapture::isAvailable() const | 
| 300 | { | 
| 301 |     if (d_func()->control != nullptr) | 
| 302 |         return true; | 
| 303 |     else | 
| 304 |         return false; | 
| 305 | } | 
| 306 |  | 
| 307 | /*! | 
| 308 |     Returns the availability of this functionality. | 
| 309 | */ | 
| 310 | QMultimedia::AvailabilityStatus QCameraImageCapture::availability() const | 
| 311 | { | 
| 312 |     if (d_func()->control != nullptr) | 
| 313 |         return QMultimedia::Available; | 
| 314 |     else | 
| 315 |         return QMultimedia::ServiceMissing; | 
| 316 | } | 
| 317 |  | 
| 318 | /*! | 
| 319 |     Returns the current error state. | 
| 320 |  | 
| 321 |     \sa errorString() | 
| 322 | */ | 
| 323 |  | 
| 324 | QCameraImageCapture::Error QCameraImageCapture::error() const | 
| 325 | { | 
| 326 |     return d_func()->error; | 
| 327 | } | 
| 328 |  | 
| 329 | /*! | 
| 330 |     Returns a string describing the current error state. | 
| 331 |  | 
| 332 |     \sa error() | 
| 333 | */ | 
| 334 |  | 
| 335 | QString QCameraImageCapture::errorString() const | 
| 336 | { | 
| 337 |     return d_func()->errorString; | 
| 338 | } | 
| 339 |  | 
| 340 |  | 
| 341 | /*! | 
| 342 |     Returns a list of supported image codecs. | 
| 343 | */ | 
| 344 | QStringList QCameraImageCapture::supportedImageCodecs() const | 
| 345 | { | 
| 346 |     return d_func()->encoderControl ? | 
| 347 |            d_func()->encoderControl->supportedImageCodecs() : QStringList(); | 
| 348 | } | 
| 349 |  | 
| 350 | /*! | 
| 351 |     Returns a description of an image \a codec. | 
| 352 | */ | 
| 353 | QString QCameraImageCapture::imageCodecDescription(const QString &codec) const | 
| 354 | { | 
| 355 |     return d_func()->encoderControl ? | 
| 356 |            d_func()->encoderControl->imageCodecDescription(codec) : QString(); | 
| 357 | } | 
| 358 |  | 
| 359 | /*! | 
| 360 |     Returns a list of resolutions images can be encoded at. | 
| 361 |  | 
| 362 |     If non null image \a settings parameter is passed, | 
| 363 |     the returned list is reduced to resolution supported with partial settings like image codec or quality applied. | 
| 364 |  | 
| 365 |     If the encoder supports arbitrary resolutions within the supported range, | 
| 366 |     *\a continuous is set to true, otherwise *\a continuous is set to false. | 
| 367 |  | 
| 368 |     \sa QImageEncoderSettings::resolution() | 
| 369 | */ | 
| 370 | QList<QSize> QCameraImageCapture::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const | 
| 371 | { | 
| 372 |     if (continuous) | 
| 373 |         *continuous = false; | 
| 374 |  | 
| 375 |     return d_func()->encoderControl ? | 
| 376 |            d_func()->encoderControl->supportedResolutions(settings, continuous) : QList<QSize>(); | 
| 377 | } | 
| 378 |  | 
| 379 | /*! | 
| 380 |     Returns the image encoder settings being used. | 
| 381 |  | 
| 382 |     \sa setEncodingSettings() | 
| 383 | */ | 
| 384 |  | 
| 385 | QImageEncoderSettings QCameraImageCapture::encodingSettings() const | 
| 386 | { | 
| 387 |     return d_func()->encoderControl ? | 
| 388 |            d_func()->encoderControl->imageSettings() : QImageEncoderSettings(); | 
| 389 | } | 
| 390 |  | 
| 391 | /*! | 
| 392 |     Sets the image encoding \a settings. | 
| 393 |  | 
| 394 |     If some parameters are not specified, or null settings are passed, | 
| 395 |     the encoder choose the default encoding parameters. | 
| 396 |  | 
| 397 |     \sa encodingSettings() | 
| 398 | */ | 
| 399 |  | 
| 400 | void QCameraImageCapture::setEncodingSettings(const QImageEncoderSettings &settings) | 
| 401 | { | 
| 402 |     Q_D(QCameraImageCapture); | 
| 403 |  | 
| 404 |     if (d->encoderControl) { | 
| 405 |         QCamera *camera = qobject_cast<QCamera*>(object: d->mediaObject); | 
| 406 |         if (camera && camera->captureMode() == QCamera::CaptureStillImage) { | 
| 407 |             QMetaObject::invokeMethod(obj: camera, | 
| 408 |                                       member: "_q_preparePropertyChange" , | 
| 409 |                                       type: Qt::DirectConnection, | 
| 410 |                                       Q_ARG(int, QCameraControl::ImageEncodingSettings)); | 
| 411 |         } | 
| 412 |  | 
| 413 |         d->encoderControl->setImageSettings(settings); | 
| 414 |     } | 
| 415 | } | 
| 416 |  | 
| 417 | /*! | 
| 418 |     Returns the list of supported buffer image capture formats. | 
| 419 |  | 
| 420 |     \sa bufferFormat(), setBufferFormat() | 
| 421 | */ | 
| 422 | QList<QVideoFrame::PixelFormat> QCameraImageCapture::supportedBufferFormats() const | 
| 423 | { | 
| 424 |     if (d_func()->bufferFormatControl) | 
| 425 |         return d_func()->bufferFormatControl->supportedBufferFormats(); | 
| 426 |     else | 
| 427 |         return QList<QVideoFrame::PixelFormat>(); | 
| 428 | } | 
| 429 |  | 
| 430 | /*! | 
| 431 |     Returns the buffer image capture format being used. | 
| 432 |  | 
| 433 |     \sa supportedBufferFormats(), setBufferFormat() | 
| 434 | */ | 
| 435 | QVideoFrame::PixelFormat QCameraImageCapture::bufferFormat() const | 
| 436 | { | 
| 437 |     if (d_func()->bufferFormatControl) | 
| 438 |         return d_func()->bufferFormatControl->bufferFormat(); | 
| 439 |     else | 
| 440 |         return QVideoFrame::Format_Invalid; | 
| 441 | } | 
| 442 |  | 
| 443 | /*! | 
| 444 |     Sets the buffer image capture \a format to be used. | 
| 445 |  | 
| 446 |     \sa bufferFormat(), supportedBufferFormats(), captureDestination() | 
| 447 | */ | 
| 448 | void QCameraImageCapture::setBufferFormat(const QVideoFrame::PixelFormat format) | 
| 449 | { | 
| 450 |     if (d_func()->bufferFormatControl) | 
| 451 |         d_func()->bufferFormatControl->setBufferFormat(format); | 
| 452 | } | 
| 453 |  | 
| 454 | /*! | 
| 455 |     Returns true if the image capture \a destination is supported; otherwise returns false. | 
| 456 |  | 
| 457 |     \sa captureDestination(), setCaptureDestination() | 
| 458 | */ | 
| 459 | bool QCameraImageCapture::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const | 
| 460 | { | 
| 461 |     if (d_func()->captureDestinationControl) | 
| 462 |         return d_func()->captureDestinationControl->isCaptureDestinationSupported(destination); | 
| 463 |     else | 
| 464 |         return destination == CaptureToFile; | 
| 465 | } | 
| 466 |  | 
| 467 | /*! | 
| 468 |     Returns the image capture destination being used. | 
| 469 |  | 
| 470 |     \sa isCaptureDestinationSupported(), setCaptureDestination() | 
| 471 | */ | 
| 472 | QCameraImageCapture::CaptureDestinations QCameraImageCapture::captureDestination() const | 
| 473 | { | 
| 474 |     if (d_func()->captureDestinationControl) | 
| 475 |         return d_func()->captureDestinationControl->captureDestination(); | 
| 476 |     else | 
| 477 |         return CaptureToFile; | 
| 478 | } | 
| 479 |  | 
| 480 | /*! | 
| 481 |     Sets the capture \a destination to be used. | 
| 482 |  | 
| 483 |     \sa isCaptureDestinationSupported(), captureDestination() | 
| 484 | */ | 
| 485 | void QCameraImageCapture::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) | 
| 486 | { | 
| 487 |     Q_D(QCameraImageCapture); | 
| 488 |  | 
| 489 |     if (d->captureDestinationControl) | 
| 490 |         d->captureDestinationControl->setCaptureDestination(destination); | 
| 491 | } | 
| 492 |  | 
| 493 | /*! | 
| 494 |   \property QCameraImageCapture::readyForCapture | 
| 495 |   \brief whether the service is ready to capture a an image immediately. | 
| 496 |  | 
| 497 |   Calling capture() while \e readyForCapture is \c false is not permitted and | 
| 498 |   results in an error. | 
| 499 | */ | 
| 500 |  | 
| 501 | bool QCameraImageCapture::isReadyForCapture() const | 
| 502 | { | 
| 503 |     if (d_func()->control) | 
| 504 |         return d_func()->control->isReadyForCapture(); | 
| 505 |     else | 
| 506 |         return false; | 
| 507 | } | 
| 508 |  | 
| 509 | /*! | 
| 510 |     \fn QCameraImageCapture::readyForCaptureChanged(bool ready) | 
| 511 |  | 
| 512 |     Signals that a camera's \a ready for capture state has changed. | 
| 513 | */ | 
| 514 |  | 
| 515 |  | 
| 516 | /*! | 
| 517 |     Capture the image and save it to \a file. | 
| 518 |     This operation is asynchronous in majority of cases, | 
| 519 |     followed by signals QCameraImageCapture::imageExposed(), | 
| 520 |     QCameraImageCapture::imageCaptured(), QCameraImageCapture::imageSaved() | 
| 521 |     or QCameraImageCapture::error(). | 
| 522 |  | 
| 523 |     If an empty \a file is passed, the camera backend choses | 
| 524 |     the default location and naming scheme for photos on the system, | 
| 525 |     if only file name without full path is specified, the image will be saved to | 
| 526 |     the default directory, with a full path reported with imageCaptured() and imageSaved() signals. | 
| 527 |  | 
| 528 |     QCamera saves all the capture parameters like exposure settings or | 
| 529 |     image processing parameters, so changes to camera parameters after | 
| 530 |     capture() is called do not affect previous capture requests. | 
| 531 |  | 
| 532 |     QCameraImageCapture::capture returns the capture Id parameter, used with | 
| 533 |     imageExposed(), imageCaptured() and imageSaved() signals. | 
| 534 |  | 
| 535 |     \sa isReadyForCapture() | 
| 536 | */ | 
| 537 | int QCameraImageCapture::capture(const QString &file) | 
| 538 | { | 
| 539 |     Q_D(QCameraImageCapture); | 
| 540 |  | 
| 541 |     d->unsetError(); | 
| 542 |  | 
| 543 |     if (d->control) { | 
| 544 |         return d->control->capture(fileName: file); | 
| 545 |     } else { | 
| 546 |         d->error = NotSupportedFeatureError; | 
| 547 |         d->errorString = tr(s: "Device does not support images capture." ); | 
| 548 |  | 
| 549 |         emit error(id: -1, error: d->error, errorString: d->errorString); | 
| 550 |     } | 
| 551 |  | 
| 552 |     return -1; | 
| 553 | } | 
| 554 |  | 
| 555 | /*! | 
| 556 |     Cancel incomplete capture requests. | 
| 557 |     Already captured and queused for proicessing images may be discarded. | 
| 558 | */ | 
| 559 | void QCameraImageCapture::cancelCapture() | 
| 560 | { | 
| 561 |     Q_D(QCameraImageCapture); | 
| 562 |  | 
| 563 |     d->unsetError(); | 
| 564 |  | 
| 565 |     if (d->control) { | 
| 566 |         d->control->cancelCapture(); | 
| 567 |     } else { | 
| 568 |         d->error = NotSupportedFeatureError; | 
| 569 |         d->errorString = tr(s: "Device does not support images capture." ); | 
| 570 |  | 
| 571 |         emit error(id: -1, error: d->error, errorString: d->errorString); | 
| 572 |     } | 
| 573 | } | 
| 574 |  | 
| 575 |  | 
| 576 | /*! | 
| 577 |     \enum QCameraImageCapture::Error | 
| 578 |  | 
| 579 |     \value NoError         No Errors. | 
| 580 |     \value NotReadyError   The service is not ready for capture yet. | 
| 581 |     \value ResourceError   Device is not ready or not available. | 
| 582 |     \value OutOfSpaceError No space left on device. | 
| 583 |     \value NotSupportedFeatureError Device does not support stillimages capture. | 
| 584 |     \value FormatError     Current format is not supported. | 
| 585 | */ | 
| 586 |  | 
| 587 | /*! | 
| 588 |     \enum QCameraImageCapture::DriveMode | 
| 589 |  | 
| 590 |     \value SingleImageCapture Drive mode is capturing a single picture. | 
| 591 | */ | 
| 592 |  | 
| 593 | /*! | 
| 594 |     \fn QCameraImageCapture::error(int id, QCameraImageCapture::Error error, const QString &errorString) | 
| 595 |  | 
| 596 |     Signals that the capture request \a id has failed with an \a error | 
| 597 |     and \a errorString description. | 
| 598 | */ | 
| 599 |  | 
| 600 | /*! | 
| 601 |     \fn QCameraImageCapture::bufferFormatChanged(QVideoFrame::PixelFormat format) | 
| 602 |  | 
| 603 |     Signal emitted when the buffer \a format for the buffer image capture has changed. | 
| 604 | */ | 
| 605 |  | 
| 606 | /*! | 
| 607 |     \fn QCameraImageCapture::captureDestinationChanged(CaptureDestinations destination) | 
| 608 |  | 
| 609 |     Signal emitted when the capture \a destination has changed. | 
| 610 | */ | 
| 611 |  | 
| 612 | /*! | 
| 613 |     \fn QCameraImageCapture::imageExposed(int id) | 
| 614 |  | 
| 615 |     Signal emitted when the frame with request \a id was exposed. | 
| 616 | */ | 
| 617 |  | 
| 618 | /*! | 
| 619 |     \fn QCameraImageCapture::imageCaptured(int id, const QImage &preview); | 
| 620 |  | 
| 621 |     Signal emitted when QAbstractVideoSurface is used as a viewfinder and | 
| 622 |     the frame with request \a id was captured, but not processed and saved yet. | 
| 623 |     Frame \a preview can be displayed to user. | 
| 624 | */ | 
| 625 |  | 
| 626 | /*! | 
| 627 |     \fn QCameraImageCapture::imageMetadataAvailable(int id, const QString &key, const QVariant &value) | 
| 628 |  | 
| 629 |     Signals that a metadata for an image with request \a id is available. Also | 
| 630 |     includes the \a key and \a value of the metadata. | 
| 631 |  | 
| 632 |     This signal is emitted between imageExposed and imageSaved signals. | 
| 633 | */ | 
| 634 |  | 
| 635 | /*! | 
| 636 |     \fn QCameraImageCapture::imageAvailable(int id, const QVideoFrame &frame) | 
| 637 |  | 
| 638 |     Signal emitted when QCameraImageCapture::CaptureToBuffer is set and | 
| 639 |     the \a frame with request \a id is available. | 
| 640 | */ | 
| 641 |  | 
| 642 | /*! | 
| 643 |     \fn QCameraImageCapture::imageSaved(int id, const QString &fileName) | 
| 644 |  | 
| 645 |     Signal emitted when QCameraImageCapture::CaptureToFile is set and | 
| 646 |     the frame with request \a id was saved to \a fileName. | 
| 647 | */ | 
| 648 |  | 
| 649 | QT_END_NAMESPACE | 
| 650 |  | 
| 651 | #include "moc_qcameraimagecapture.cpp" | 
| 652 |  |