5#include "capture/qqnxmediacapturesession_p.h"
7#include <qcameradevice.h>
8#include <qmediadevices.h>
10#include <private/qmediastoragelocation_p.h>
12QDebug &operator<<(QDebug &d,
const QQnxCamera::VideoFormat &f)
14 d <<
"VideoFormat - width=" << f.width
15 <<
"height=" << f.height
16 <<
"rotation=" << f.rotation
17 <<
"frameRate=" << f.frameRate
18 <<
"frameType=" << f.frameType;
26 case CAMERA_STATUS_DISCONNECTED:
27 return QStringLiteral(
"No user is connected to the camera");
28 case CAMERA_STATUS_POWERDOWN:
29 return QStringLiteral(
"Power down");
30 case CAMERA_STATUS_VIDEOVF:
31 return QStringLiteral(
"The video viewfinder has started");
32 case CAMERA_STATUS_CAPTURE_ABORTED:
33 return QStringLiteral(
"The capture of a still image failed and was aborted");
34 case CAMERA_STATUS_FILESIZE_WARNING:
35 return QStringLiteral(
"Time-remaining threshold has been exceeded");
36 case CAMERA_STATUS_FOCUS_CHANGE:
37 return QStringLiteral(
"The focus has changed on the camera");
38 case CAMERA_STATUS_RESOURCENOTAVAIL:
39 return QStringLiteral(
"The camera is about to free resources");
40 case CAMERA_STATUS_VIEWFINDER_ERROR:
41 return QStringLiteral(
" An unexpected error was encountered while the "
42 "viewfinder was active");
43 case CAMERA_STATUS_MM_ERROR:
44 return QStringLiteral(
"The recording has stopped due to a memory error or multimedia "
46 case CAMERA_STATUS_FILESIZE_ERROR:
47 return QStringLiteral(
"A file has exceeded the maximum size.");
48 case CAMERA_STATUS_NOSPACE_ERROR:
49 return QStringLiteral(
"Not enough disk space");
50 case CAMERA_STATUS_BUFFER_UNDERFLOW:
51 return QStringLiteral(
"The viewfinder is out of buffers");
61QQnxCamera::QQnxCamera(camera_unit_t unit, QObject *parent)
65 if (!m_handle.open(m_cameraUnit, CAMERA_MODE_RW))
66 qWarning(
"QQnxCamera: Failed to open camera (0x%x)", m_handle.lastError());
68 if (camera_set_vf_mode(m_handle.get(), CAMERA_VFMODE_VIDEO) != CAMERA_EOK) {
69 qWarning(
"QQnxCamera: unable to configure viewfinder mode");
73 if (camera_set_vf_property(m_handle.get(), CAMERA_IMGPROP_CREATEWINDOW, 0,
74 CAMERA_IMGPROP_RENDERTOWINDOW, 0) != CAMERA_EOK) {
75 qWarning(
"QQnxCamera: failed to set camera properties");
80 updateSupportedWhiteBalanceValues();
97 char name[CAMERA_LOCATION_NAMELEN];
99 if (camera_get_location_property(m_cameraUnit,
100 CAMERA_LOCATION_NAME, &name, CAMERA_LOCATION_END) != CAMERA_EOK) {
101 qWarning(
"QQnxCamera: unable to obtain camera name");
105 return QString::fromUtf8(name);
115 return m_handle.isOpen() && m_viewfinderActive;
123 if (camera_start_viewfinder(m_handle.get(), viewfinderCallback,
124 statusCallback,
this) != CAMERA_EOK) {
125 qWarning(
"QQnxCamera: unable to start viewfinder");
129 m_viewfinderActive =
true;
137 if (m_recordingVideo)
140 if (camera_stop_viewfinder(m_handle.get()) != CAMERA_EOK)
141 qWarning(
"QQnxCamera: Failed to stop camera");
143 m_viewfinderActive =
false;
148 if (!m_handle.isOpen())
151 const camera_error_t error = camera_set_vf_property(m_handle.get(),
152 CAMERA_IMGPROP_WIDTH, width,
153 CAMERA_IMGPROP_HEIGHT, height,
154 CAMERA_IMGPROP_FRAMERATE, frameRate);
156 if (error != CAMERA_EOK) {
157 qWarning(
"QQnxCamera: failed to set camera format");
166 return supportedFocusModes().contains(mode);
174 const camera_error_t result = camera_set_focus_mode(m_handle.get(), mode);
176 if (result != CAMERA_EOK) {
177 qWarning(
"QQnxCamera: Unable to set focus mode (0x%x)", result);
181 focusModeChanged(mode);
189 return CAMERA_FOCUSMODE_OFF;
191 camera_focusmode_t mode;
193 const camera_error_t result = camera_get_focus_mode(m_handle.get(), &mode);
195 if (result != CAMERA_EOK) {
196 qWarning(
"QQnxCamera: Unable to set focus mode (0x%x)", result);
197 return CAMERA_FOCUSMODE_OFF;
207 if (camera_get_vf_property(m_handle.get(),
208 CAMERA_IMGPROP_WIDTH, &f.width,
209 CAMERA_IMGPROP_HEIGHT, &f.height,
210 CAMERA_IMGPROP_ROTATION, &f.rotation,
211 CAMERA_IMGPROP_FRAMERATE, &f.frameRate,
212 CAMERA_IMGPROP_FORMAT, &f.frameType) != CAMERA_EOK) {
213 qWarning(
"QQnxCamera: Failed to query video finder frameType");
219void QQnxCamera::setVfFormat(
const VideoFormat &f)
226 if (camera_set_vf_property(m_handle.get(),
227 CAMERA_IMGPROP_WIDTH, f.width,
228 CAMERA_IMGPROP_HEIGHT, f.height,
229 CAMERA_IMGPROP_ROTATION, f.rotation,
230 CAMERA_IMGPROP_FRAMERATE, f.frameRate,
231 CAMERA_IMGPROP_FORMAT, f.frameType) != CAMERA_EOK) {
232 qWarning(
"QQnxCamera: Failed to set video finder frameType");
243 if (camera_get_video_property(m_handle.get(),
244 CAMERA_IMGPROP_WIDTH, &f.width,
245 CAMERA_IMGPROP_HEIGHT, &f.height,
246 CAMERA_IMGPROP_ROTATION, &f.rotation,
247 CAMERA_IMGPROP_FRAMERATE, &f.frameRate,
248 CAMERA_IMGPROP_FORMAT, &f.frameType) != CAMERA_EOK) {
249 qWarning(
"QQnxCamera: Failed to query recording frameType");
255void QQnxCamera::setRecordingFormat(
const VideoFormat &f)
257 if (camera_set_video_property(m_handle.get(),
258 CAMERA_IMGPROP_WIDTH, f.width,
259 CAMERA_IMGPROP_HEIGHT, f.height,
260 CAMERA_IMGPROP_ROTATION, f.rotation,
261 CAMERA_IMGPROP_FRAMERATE, f.frameRate,
262 CAMERA_IMGPROP_FORMAT, f.frameType) != CAMERA_EOK) {
263 qWarning(
"QQnxCamera: Failed to set recording frameType");
269 const QSize vfSize = viewFinderSize();
271 if (vfSize.isEmpty())
274 const auto toUint32 = [](
double value) {
275 return static_cast<uint32_t>(std::max(0.0, value));
279 constexpr int pixelSize = 40;
281 const auto left = toUint32(point.x() * vfSize.width() - pixelSize / 2);
282 const auto top = toUint32(point.y() * vfSize.height() - pixelSize / 2);
284 camera_region_t focusRegion {
292 if (camera_set_focus_regions(m_handle.get(), 1, &focusRegion) != CAMERA_EOK) {
293 qWarning(
"QQnxCamera: Unable to set focus region");
297 if (setFocusMode(focusMode()))
298 customFocusPointChanged(point);
304 qWarning(
"QQnxCamera: Failed to set focus distance - view finder not active");
308 if (!isFocusModeSupported(CAMERA_FOCUSMODE_MANUAL)) {
309 qWarning(
"QQnxCamera: Failed to set focus distance - manual focus mode not supported");
313 if (camera_set_manual_focus_step(m_handle.get(), step) != CAMERA_EOK)
314 qWarning(
"QQnxCamera: Failed to set focus distance");
319 return focusStep().step;
324 return focusStep().maxStep;
329 constexpr FocusStep invalidStep { -1, -1 };
332 qWarning(
"QQnxCamera: Failed to query max focus distance - view finder not active");
336 if (!isFocusModeSupported(CAMERA_FOCUSMODE_MANUAL)) {
337 qWarning(
"QQnxCamera: Failed to query max focus distance - "
338 "manual focus mode not supported");
344 if (camera_get_manual_focus_step(m_handle.get(),
345 &focusStep.maxStep, &focusStep.step) != CAMERA_EOK) {
346 qWarning(
"QQnxCamera: Unable to query camera focus step");
360 if (camera_get_vf_property(m_handle.get(),
361 CAMERA_IMGPROP_WIDTH, width,
362 CAMERA_IMGPROP_HEIGHT, height) != CAMERA_EOK) {
363 qWarning(
"QQnxCamera: failed to query view finder size");
367 return { width, height };
389 if (camera_get_zoom_ratio_from_zoom_level(m_handle.get(), zoomLevel, &ratio) != CAMERA_EOK) {
390 qWarning(
"QQnxCamera: failed to query zoom ratio from zoom level");
399 if (camera_set_vf_property(m_handle.get(), CAMERA_IMGPROP_ZOOMFACTOR, factor) != CAMERA_EOK) {
400 qWarning(
"QQnxCamera: failed to set zoom factor");
412 if (camera_set_ev_offset(m_handle.get(), ev) != CAMERA_EOK)
413 qWarning(
"QQnxCamera: Failed to set up exposure compensation");
423 if (camera_get_manual_iso(m_handle.get(), &isoValue) != CAMERA_EOK) {
424 qWarning(
"QQnxCamera: Failed to query ISO value");
436 if (camera_set_manual_iso(m_handle.get(), value) != CAMERA_EOK)
437 qWarning(
"QQnxCamera: Failed to set ISO value");
445 if (camera_set_manual_shutter_speed(m_handle.get(), seconds) != CAMERA_EOK)
446 qWarning(
"QQnxCamera: Failed to set exposure time");
456 if (camera_get_manual_shutter_speed(m_handle.get(), &shutterSpeed) != CAMERA_EOK) {
457 qWarning(
"QQnxCamera: Failed to get exposure time");
466 return camera_has_feature(m_handle.get(), feature);
474 if (camera_set_whitebalance_mode(m_handle.get(), mode) != CAMERA_EOK)
475 qWarning(
"QQnxCamera: failed to set whitebalance mode");
481 return CAMERA_WHITEBALANCEMODE_OFF;
483 camera_whitebalancemode_t mode;
485 if (camera_get_whitebalance_mode(m_handle.get(), &mode) != CAMERA_EOK) {
486 qWarning(
"QQnxCamera: failed to get white balance mode");
487 return CAMERA_WHITEBALANCEMODE_OFF;
498 if (camera_set_manual_white_balance(m_handle.get(), value) != CAMERA_EOK)
499 qWarning(
"QQnxCamera: failed to set manual white balance");
509 if (camera_get_manual_white_balance(m_handle.get(), &value) != CAMERA_EOK) {
510 qWarning(
"QQnxCamera: failed to get manual white balance");
521 if (hasFeature(CAMERA_FEATURE_PREVIEWISVIDEO)) {
522 VideoFormat newFormat = vfFormat();
524 const QList<camera_frametype_t> recordingTypes = supportedRecordingFrameTypes();
528 if (newFormat.frameType != recordingFormat().frameType
529 && !recordingTypes.contains(newFormat.frameType)) {
533 for (
const camera_frametype_t type : supportedVfFrameTypes()) {
534 if (recordingTypes.contains(type)) {
535 newFormat.frameType = type;
542 m_originalVfFormat = vfFormat();
545 setVfFormat(newFormat);
547 qWarning(
"QQnxCamera: failed to find suitable frame type for recording - aborting");
552 setRecordingFormat(newFormat);
555 if (camera_start_video(m_handle.get(), qPrintable(filename),
556 nullptr,
nullptr,
nullptr) == CAMERA_EOK) {
557 m_recordingVideo =
true;
559 qWarning(
"QQnxCamera: failed to start video encoding");
562 return m_recordingVideo;
567 m_recordingVideo =
false;
569 if (camera_stop_video(m_handle.get()) != CAMERA_EOK)
570 qWarning(
"QQnxCamera: error when stopping video recording");
573 if (m_originalVfFormat) {
574 setVfFormat(*m_originalVfFormat);
575 m_originalVfFormat.reset();
579bool QQnxCamera::isVideoEncodingSupported()
const
584 return camera_has_feature(m_handle.get(), CAMERA_FEATURE_VIDEO);
589 return m_handle.get();
596 if (camera_get_zoom_limits(m_handle.get(), &m_minZoom, &m_maxZoom, &smooth) != CAMERA_EOK) {
597 qWarning(
"QQnxCamera: failed to update zoom limits - using default values");
598 m_minZoom = m_maxZoom = 0;
602void QQnxCamera::updateSupportedWhiteBalanceValues()
604 uint32_t numSupported = 0;
606 const camera_error_t result = camera_get_supported_manual_white_balance_values(
607 m_handle.get(), 0, &numSupported,
nullptr, &m_continuousWhiteBalanceValues);
609 if (result != CAMERA_EOK) {
610 if (result == CAMERA_EOPNOTSUPP)
611 qWarning(
"QQnxCamera: white balance not supported");
613 qWarning(
"QQnxCamera: unable to query manual white balance value count");
615 m_supportedWhiteBalanceValues.clear();
620 m_supportedWhiteBalanceValues.resize(numSupported);
622 if (camera_get_supported_manual_white_balance_values(m_handle.get(),
623 m_supportedWhiteBalanceValues.size(),
625 m_supportedWhiteBalanceValues.data(),
626 &m_continuousWhiteBalanceValues) != CAMERA_EOK) {
627 qWarning(
"QQnxCamera: unable to query manual white balance values");
629 m_supportedWhiteBalanceValues.clear();
635 return queryValues(camera_get_supported_vf_modes);
640 return queryValues(camera_get_supported_vf_resolutions);
645 return queryValues(camera_get_supported_vf_frame_types);
650 return queryValues(camera_get_focus_modes);
654 camera_res_t resolution)
const
656 uint32_t numSupported = 0;
658 if (camera_get_specified_vf_framerates(m_handle.get(), frameType, resolution,
659 0, &numSupported,
nullptr,
nullptr) != CAMERA_EOK) {
660 qWarning(
"QQnxCamera: unable to query specified framerates count");
664 QList<
double> values(numSupported);
666 if (camera_get_specified_vf_framerates(m_handle.get(), frameType, resolution,
667 values.size(), &numSupported, values.data(),
nullptr) != CAMERA_EOK) {
668 qWarning(
"QQnxCamera: unable to query specified framerates values");
677 return queryValues(camera_get_video_frame_types);
682 return m_supportedWhiteBalanceValues;
687 return m_continuousWhiteBalanceValues;
692 unsigned int numSupported = 0;
694 if (camera_get_supported_cameras(0, &numSupported,
nullptr) != CAMERA_EOK) {
695 qWarning(
"QQnxCamera: failed to query supported camera unit count");
699 QList<camera_unit_t> cameraUnits(numSupported);
701 if (camera_get_supported_cameras(cameraUnits.size(), &numSupported,
702 cameraUnits.data()) != CAMERA_EOK) {
703 qWarning(
"QQnxCamera: failed to enumerate supported camera units");
710template <
typename T,
typename U>
711QList<T>
QQnxCamera::queryValues(QueryFuncPtr<T,U> func)
const
713 static_assert(
std::is_integral_v<U>,
"Parameter U must be of integral type");
717 if (func(m_handle.get(), 0, &numSupported,
nullptr) != CAMERA_EOK) {
718 qWarning(
"QQnxCamera: unable to query camera value count");
722 QList<T> values(numSupported);
724 if (func(m_handle.get(), values.size(), &numSupported, values.data()) != CAMERA_EOK) {
725 qWarning(
"QQnxCamera: unable to query camera values");
732void QQnxCamera::handleVfBuffer(camera_buffer_t *buffer)
738 if (m_currentFrameMutex.tryLock()) {
739 m_currentFrame = std::move(frame);
740 m_currentFrameMutex.unlock();
742 Q_EMIT frameAvailable();
746void QQnxCamera::handleVfStatus(camera_devstatus_t status, uint16_t extraData)
748 QMetaObject::invokeMethod(
this,
"handleStatusChange", Qt::QueuedConnection,
749 Q_ARG(camera_devstatus_t, status),
750 Q_ARG(uint16_t, extraData));
753void QQnxCamera::handleStatusChange(camera_devstatus_t status, uint16_t extraData)
758 case CAMERA_STATUS_BUFFER_UNDERFLOW:
759#if _NTO_VERSION < 800
760 case CAMERA_STATUS_CAPTURECOMPLETE:
761 case CAMERA_STATUS_FLASH_LEVEL_CHANGE:
762 case CAMERA_STATUS_LOWLIGHT:
763 case CAMERA_STATUS_PHOTOVF:
764 case CAMERA_STATUS_VIDEOLIGHT_CHANGE:
765 case CAMERA_STATUS_VIDEOLIGHT_LEVEL_CHANGE:
766 case CAMERA_STATUS_VIEWFINDER_FREEZE:
767 case CAMERA_STATUS_VIEWFINDER_SUSPEND:
768 case CAMERA_STATUS_VIEWFINDER_UNFREEZE:
769 case CAMERA_STATUS_VIEWFINDER_UNSUSPEND:
771 case CAMERA_STATUS_CAPTURE_ABORTED:
772 case CAMERA_STATUS_CONNECTED:
773 case CAMERA_STATUS_DISCONNECTED:
774 case CAMERA_STATUS_FILESIZE_ERROR:
775 case CAMERA_STATUS_FILESIZE_LIMIT_WARNING:
776 case CAMERA_STATUS_FILESIZE_WARNING:
777 case CAMERA_STATUS_FOCUS_CHANGE:
778 case CAMERA_STATUS_FRAME_DROPPED:
779 case CAMERA_STATUS_MM_ERROR:
780 case CAMERA_STATUS_NOSPACE_ERROR:
781 case CAMERA_STATUS_POWERDOWN:
782 case CAMERA_STATUS_POWERUP:
783 case CAMERA_STATUS_RESOURCENOTAVAIL:
784 case CAMERA_STATUS_UNKNOWN:
785 case CAMERA_STATUS_VIDEOVF:
786 case CAMERA_STATUS_VIDEO_PAUSE:
787 case CAMERA_STATUS_VIDEO_RESUME:
788 case CAMERA_STATUS_VIEWFINDER_ACTIVE:
789 case CAMERA_STATUS_VIEWFINDER_ERROR:
790 qDebug() <<
"QQnxCamera:" << ::statusToString(status);
799 QMutexLocker l(&m_currentFrameMutex);
801 return std::move(m_currentFrame);
804void QQnxCamera::viewfinderCallback(camera_handle_t handle, camera_buffer_t *buffer,
void *arg)
809 camera->handleVfBuffer(buffer);
812void QQnxCamera::statusCallback(camera_handle_t handle, camera_devstatus_t status,
813 uint16_t extraData,
void *arg)
818 camera->handleVfStatus(status, extraData);
823#include "moc_qqnxcamera_p.cpp"
QList< camera_vfmode_t > supportedVfModes() const
void setManualIsoSensitivity(uint32_t value)
void setCustomFocusPoint(const QPointF &point)
bool setCameraFormat(uint32_t width, uint32_t height, double frameRate)
camera_whitebalancemode_t whiteBalanceMode() const
void setEvOffset(float ev)
std::unique_ptr< QQnxCameraFrameBuffer > takeCurrentFrame()
camera_handle_t handle() const
QList< camera_frametype_t > supportedRecordingFrameTypes() const
QList< uint32_t > supportedWhiteBalanceValues() const
double zoomRatio(uint32_t zoomLevel) const
bool setZoomFactor(uint32_t factor)
bool isFocusModeSupported(camera_focusmode_t mode) const
void stopVideoRecording()
uint32_t manualIsoSensitivity() const
double manualExposureTime() const
QList< camera_focusmode_t > supportedFocusModes() const
uint32_t maximumZoomLevel() const
QList< double > specifiedVfFrameRates(camera_frametype_t frameType, camera_res_t resolution) const
bool startVideoRecording(const QString &filename)
bool hasFeature(camera_feature_t feature) const
QList< camera_frametype_t > supportedVfFrameTypes() const
void setManualFocusStep(int step)
QSize viewFinderSize() const
bool isSmoothZoom() const
void setWhiteBalanceMode(camera_whitebalancemode_t mode)
QList< camera_res_t > supportedVfResolutions() const
uint32_t minimumZoomLevel() const
bool hasContinuousWhiteBalanceValues() const
camera_focusmode_t focusMode() const
void setManualWhiteBalance(uint32_t value)
uint32_t manualWhiteBalance() const
void setManualExposureTime(double seconds)
bool setFocusMode(camera_focusmode_t mode)
int manualFocusStep() const
camera_unit_t unit() const
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
static QString statusToString(camera_devstatus_t status)