8#include <qcameradevice.h>
9#include <qmediadevices.h>
11#include <private/qmediastoragelocation_p.h>
13QDebug &operator<<(QDebug &d,
const QQnxCamera::VideoFormat &f)
15 d <<
"VideoFormat - width=" << f.width
16 <<
"height=" << f.height
17 <<
"rotation=" << f.rotation
18 <<
"frameRate=" << f.frameRate
19 <<
"frameType=" << f.frameType;
27 case CAMERA_STATUS_DISCONNECTED:
28 return QStringLiteral(
"No user is connected to the camera");
29 case CAMERA_STATUS_POWERDOWN:
30 return QStringLiteral(
"Power down");
31 case CAMERA_STATUS_VIDEOVF:
32 return QStringLiteral(
"The video viewfinder has started");
33 case CAMERA_STATUS_CAPTURE_ABORTED:
34 return QStringLiteral(
"The capture of a still image failed and was aborted");
35 case CAMERA_STATUS_FILESIZE_WARNING:
36 return QStringLiteral(
"Time-remaining threshold has been exceeded");
37 case CAMERA_STATUS_FOCUS_CHANGE:
38 return QStringLiteral(
"The focus has changed on the camera");
39 case CAMERA_STATUS_RESOURCENOTAVAIL:
40 return QStringLiteral(
"The camera is about to free resources");
41 case CAMERA_STATUS_VIEWFINDER_ERROR:
42 return QStringLiteral(
" An unexpected error was encountered while the "
43 "viewfinder was active");
44 case CAMERA_STATUS_MM_ERROR:
45 return QStringLiteral(
"The recording has stopped due to a memory error or multimedia "
47 case CAMERA_STATUS_FILESIZE_ERROR:
48 return QStringLiteral(
"A file has exceeded the maximum size.");
49 case CAMERA_STATUS_NOSPACE_ERROR:
50 return QStringLiteral(
"Not enough disk space");
51 case CAMERA_STATUS_BUFFER_UNDERFLOW:
52 return QStringLiteral(
"The viewfinder is out of buffers");
62QQnxCamera::QQnxCamera(camera_unit_t unit, QObject *parent)
66 if (!m_handle.open(m_cameraUnit, CAMERA_MODE_RW))
67 qWarning(
"QQnxCamera: Failed to open camera (0x%x)", m_handle.lastError());
69 if (camera_set_vf_mode(m_handle.get(), CAMERA_VFMODE_VIDEO) != CAMERA_EOK) {
70 qWarning(
"QQnxCamera: unable to configure viewfinder mode");
74 if (camera_set_vf_property(m_handle.get(), CAMERA_IMGPROP_CREATEWINDOW, 0,
75 CAMERA_IMGPROP_RENDERTOWINDOW, 0) != CAMERA_EOK) {
76 qWarning(
"QQnxCamera: failed to set camera properties");
81 updateSupportedWhiteBalanceValues();
98 char name[CAMERA_LOCATION_NAMELEN];
100 if (camera_get_location_property(m_cameraUnit,
101 CAMERA_LOCATION_NAME, &name, CAMERA_LOCATION_END) != CAMERA_EOK) {
102 qWarning(
"QQnxCamera: unable to obtain camera name");
106 return QString::fromUtf8(name);
116 return m_handle.isOpen() && m_viewfinderActive;
124 if (camera_start_viewfinder(m_handle.get(), viewfinderCallback,
125 statusCallback,
this) != CAMERA_EOK) {
126 qWarning(
"QQnxCamera: unable to start viewfinder");
130 m_viewfinderActive =
true;
138 if (m_recordingVideo)
141 if (camera_stop_viewfinder(m_handle.get()) != CAMERA_EOK)
142 qWarning(
"QQnxCamera: Failed to stop camera");
144 m_viewfinderActive =
false;
149 if (!m_handle.isOpen())
152 const camera_error_t error = camera_set_vf_property(m_handle.get(),
153 CAMERA_IMGPROP_WIDTH, width,
154 CAMERA_IMGPROP_HEIGHT, height,
155 CAMERA_IMGPROP_FRAMERATE, frameRate);
157 if (error != CAMERA_EOK) {
158 qWarning(
"QQnxCamera: failed to set camera format");
167 return supportedFocusModes().contains(mode);
175 const camera_error_t result = camera_set_focus_mode(m_handle.get(), mode);
177 if (result != CAMERA_EOK) {
178 qWarning(
"QQnxCamera: Unable to set focus mode (0x%x)", result);
182 focusModeChanged(mode);
190 return CAMERA_FOCUSMODE_OFF;
192 camera_focusmode_t mode;
194 const camera_error_t result = camera_get_focus_mode(m_handle.get(), &mode);
196 if (result != CAMERA_EOK) {
197 qWarning(
"QQnxCamera: Unable to set focus mode (0x%x)", result);
198 return CAMERA_FOCUSMODE_OFF;
208 if (camera_get_vf_property(m_handle.get(),
209 CAMERA_IMGPROP_WIDTH, &f.width,
210 CAMERA_IMGPROP_HEIGHT, &f.height,
211 CAMERA_IMGPROP_ROTATION, &f.rotation,
212 CAMERA_IMGPROP_FRAMERATE, &f.frameRate,
213 CAMERA_IMGPROP_FORMAT, &f.frameType) != CAMERA_EOK) {
214 qWarning(
"QQnxCamera: Failed to query video finder frameType");
220void QQnxCamera::setVfFormat(
const VideoFormat &f)
227 if (camera_set_vf_property(m_handle.get(),
228 CAMERA_IMGPROP_WIDTH, f.width,
229 CAMERA_IMGPROP_HEIGHT, f.height,
230 CAMERA_IMGPROP_ROTATION, f.rotation,
231 CAMERA_IMGPROP_FRAMERATE, f.frameRate,
232 CAMERA_IMGPROP_FORMAT, f.frameType) != CAMERA_EOK) {
233 qWarning(
"QQnxCamera: Failed to set video finder frameType");
244 if (camera_get_video_property(m_handle.get(),
245 CAMERA_IMGPROP_WIDTH, &f.width,
246 CAMERA_IMGPROP_HEIGHT, &f.height,
247 CAMERA_IMGPROP_ROTATION, &f.rotation,
248 CAMERA_IMGPROP_FRAMERATE, &f.frameRate,
249 CAMERA_IMGPROP_FORMAT, &f.frameType) != CAMERA_EOK) {
250 qWarning(
"QQnxCamera: Failed to query recording frameType");
256void QQnxCamera::setRecordingFormat(
const VideoFormat &f)
258 if (camera_set_video_property(m_handle.get(),
259 CAMERA_IMGPROP_WIDTH, f.width,
260 CAMERA_IMGPROP_HEIGHT, f.height,
261 CAMERA_IMGPROP_ROTATION, f.rotation,
262 CAMERA_IMGPROP_FRAMERATE, f.frameRate,
263 CAMERA_IMGPROP_FORMAT, f.frameType) != CAMERA_EOK) {
264 qWarning(
"QQnxCamera: Failed to set recording frameType");
270 const QSize vfSize = viewFinderSize();
272 if (vfSize.isEmpty())
275 const auto toUint32 = [](
double value) {
276 return static_cast<uint32_t>(std::max(0.0, value));
280 constexpr int pixelSize = 40;
282 const auto left = toUint32(point.x() * vfSize.width() - pixelSize / 2);
283 const auto top = toUint32(point.y() * vfSize.height() - pixelSize / 2);
285 camera_region_t focusRegion {
293 if (camera_set_focus_regions(m_handle.get(), 1, &focusRegion) != CAMERA_EOK) {
294 qWarning(
"QQnxCamera: Unable to set focus region");
298 if (setFocusMode(focusMode()))
299 customFocusPointChanged(point);
305 qWarning(
"QQnxCamera: Failed to set focus distance - view finder not active");
309 if (!isFocusModeSupported(CAMERA_FOCUSMODE_MANUAL)) {
310 qWarning(
"QQnxCamera: Failed to set focus distance - manual focus mode not supported");
314 if (camera_set_manual_focus_step(m_handle.get(), step) != CAMERA_EOK)
315 qWarning(
"QQnxCamera: Failed to set focus distance");
320 return focusStep().step;
325 return focusStep().maxStep;
330 constexpr FocusStep invalidStep { -1, -1 };
333 qWarning(
"QQnxCamera: Failed to query max focus distance - view finder not active");
337 if (!isFocusModeSupported(CAMERA_FOCUSMODE_MANUAL)) {
338 qWarning(
"QQnxCamera: Failed to query max focus distance - "
339 "manual focus mode not supported");
345 if (camera_get_manual_focus_step(m_handle.get(),
346 &focusStep.maxStep, &focusStep.step) != CAMERA_EOK) {
347 qWarning(
"QQnxCamera: Unable to query camera focus step");
361 if (camera_get_vf_property(m_handle.get(),
362 CAMERA_IMGPROP_WIDTH, width,
363 CAMERA_IMGPROP_HEIGHT, height) != CAMERA_EOK) {
364 qWarning(
"QQnxCamera: failed to query view finder size");
368 return { width, height };
390 if (camera_get_zoom_ratio_from_zoom_level(m_handle.get(), zoomLevel, &ratio) != CAMERA_EOK) {
391 qWarning(
"QQnxCamera: failed to query zoom ratio from zoom level");
400 if (camera_set_vf_property(m_handle.get(), CAMERA_IMGPROP_ZOOMFACTOR, factor) != CAMERA_EOK) {
401 qWarning(
"QQnxCamera: failed to set zoom factor");
413 if (camera_set_ev_offset(m_handle.get(), ev) != CAMERA_EOK)
414 qWarning(
"QQnxCamera: Failed to set up exposure compensation");
424 if (camera_get_manual_iso(m_handle.get(), &isoValue) != CAMERA_EOK) {
425 qWarning(
"QQnxCamera: Failed to query ISO value");
437 if (camera_set_manual_iso(m_handle.get(), value) != CAMERA_EOK)
438 qWarning(
"QQnxCamera: Failed to set ISO value");
446 if (camera_set_manual_shutter_speed(m_handle.get(), seconds) != CAMERA_EOK)
447 qWarning(
"QQnxCamera: Failed to set exposure time");
457 if (camera_get_manual_shutter_speed(m_handle.get(), &shutterSpeed) != CAMERA_EOK) {
458 qWarning(
"QQnxCamera: Failed to get exposure time");
467 return camera_has_feature(m_handle.get(), feature);
475 if (camera_set_whitebalance_mode(m_handle.get(), mode) != CAMERA_EOK)
476 qWarning(
"QQnxCamera: failed to set whitebalance mode");
482 return CAMERA_WHITEBALANCEMODE_OFF;
484 camera_whitebalancemode_t mode;
486 if (camera_get_whitebalance_mode(m_handle.get(), &mode) != CAMERA_EOK) {
487 qWarning(
"QQnxCamera: failed to get white balance mode");
488 return CAMERA_WHITEBALANCEMODE_OFF;
499 if (camera_set_manual_white_balance(m_handle.get(), value) != CAMERA_EOK)
500 qWarning(
"QQnxCamera: failed to set manual white balance");
510 if (camera_get_manual_white_balance(m_handle.get(), &value) != CAMERA_EOK) {
511 qWarning(
"QQnxCamera: failed to get manual white balance");
522 if (hasFeature(CAMERA_FEATURE_PREVIEWISVIDEO)) {
523 VideoFormat newFormat = vfFormat();
525 const QList<camera_frametype_t> recordingTypes = supportedRecordingFrameTypes();
529 if (newFormat.frameType != recordingFormat().frameType
530 && !recordingTypes.contains(newFormat.frameType)) {
534 for (
const camera_frametype_t type : supportedVfFrameTypes()) {
535 if (recordingTypes.contains(type)) {
536 newFormat.frameType = type;
543 m_originalVfFormat = vfFormat();
546 setVfFormat(newFormat);
548 qWarning(
"QQnxCamera: failed to find suitable frame type for recording - aborting");
553 setRecordingFormat(newFormat);
556 if (camera_start_video(m_handle.get(), qPrintable(filename),
557 nullptr,
nullptr,
nullptr) == CAMERA_EOK) {
558 m_recordingVideo =
true;
560 qWarning(
"QQnxCamera: failed to start video encoding");
563 return m_recordingVideo;
568 m_recordingVideo =
false;
570 if (camera_stop_video(m_handle.get()) != CAMERA_EOK)
571 qWarning(
"QQnxCamera: error when stopping video recording");
574 if (m_originalVfFormat) {
575 setVfFormat(*m_originalVfFormat);
576 m_originalVfFormat.reset();
580bool QQnxCamera::isVideoEncodingSupported()
const
585 return camera_has_feature(m_handle.get(), CAMERA_FEATURE_VIDEO);
590 return m_handle.get();
597 if (camera_get_zoom_limits(m_handle.get(), &m_minZoom, &m_maxZoom, &smooth) != CAMERA_EOK) {
598 qWarning(
"QQnxCamera: failed to update zoom limits - using default values");
599 m_minZoom = m_maxZoom = 0;
603void QQnxCamera::updateSupportedWhiteBalanceValues()
605 uint32_t numSupported = 0;
607 const camera_error_t result = camera_get_supported_manual_white_balance_values(
608 m_handle.get(), 0, &numSupported,
nullptr, &m_continuousWhiteBalanceValues);
610 if (result != CAMERA_EOK) {
611 if (result == CAMERA_EOPNOTSUPP)
612 qWarning(
"QQnxCamera: white balance not supported");
614 qWarning(
"QQnxCamera: unable to query manual white balance value count");
616 m_supportedWhiteBalanceValues.clear();
621 m_supportedWhiteBalanceValues.resize(numSupported);
623 if (camera_get_supported_manual_white_balance_values(m_handle.get(),
624 m_supportedWhiteBalanceValues.size(),
626 m_supportedWhiteBalanceValues.data(),
627 &m_continuousWhiteBalanceValues) != CAMERA_EOK) {
628 qWarning(
"QQnxCamera: unable to query manual white balance values");
630 m_supportedWhiteBalanceValues.clear();
636 return queryValues(camera_get_supported_vf_modes);
641 return queryValues(camera_get_supported_vf_resolutions);
646 return queryValues(camera_get_supported_vf_frame_types);
651 return queryValues(camera_get_focus_modes);
655 camera_res_t resolution)
const
657 uint32_t numSupported = 0;
659 if (camera_get_specified_vf_framerates(m_handle.get(), frameType, resolution,
660 0, &numSupported,
nullptr,
nullptr) != CAMERA_EOK) {
661 qWarning(
"QQnxCamera: unable to query specified framerates count");
665 QList<
double> values(numSupported);
667 if (camera_get_specified_vf_framerates(m_handle.get(), frameType, resolution,
668 values.size(), &numSupported, values.data(),
nullptr) != CAMERA_EOK) {
669 qWarning(
"QQnxCamera: unable to query specified framerates values");
678 return queryValues(camera_get_video_frame_types);
683 return m_supportedWhiteBalanceValues;
688 return m_continuousWhiteBalanceValues;
693 unsigned int numSupported = 0;
695 if (camera_get_supported_cameras(0, &numSupported,
nullptr) != CAMERA_EOK) {
696 qWarning(
"QQnxCamera: failed to query supported camera unit count");
700 QList<camera_unit_t> cameraUnits(numSupported);
702 if (camera_get_supported_cameras(cameraUnits.size(), &numSupported,
703 cameraUnits.data()) != CAMERA_EOK) {
704 qWarning(
"QQnxCamera: failed to enumerate supported camera units");
711template <
typename T,
typename U>
712QList<T>
QQnxCamera::queryValues(QueryFuncPtr<T,U> func)
const
714 static_assert(
std::is_integral_v<U>,
"Parameter U must be of integral type");
718 if (func(m_handle.get(), 0, &numSupported,
nullptr) != CAMERA_EOK) {
719 qWarning(
"QQnxCamera: unable to query camera value count");
723 QList<T> values(numSupported);
725 if (func(m_handle.get(), values.size(), &numSupported, values.data()) != CAMERA_EOK) {
726 qWarning(
"QQnxCamera: unable to query camera values");
733void QQnxCamera::handleVfBuffer(camera_buffer_t *buffer)
739 if (m_currentFrameMutex.tryLock()) {
740 m_currentFrame = std::move(frame);
741 m_currentFrameMutex.unlock();
743 Q_EMIT frameAvailable();
747void QQnxCamera::handleVfStatus(camera_devstatus_t status, uint16_t extraData)
749 QMetaObject::invokeMethod(
this,
"handleStatusChange", Qt::QueuedConnection,
750 Q_ARG(camera_devstatus_t, status),
751 Q_ARG(uint16_t, extraData));
754void QQnxCamera::handleStatusChange(camera_devstatus_t status, uint16_t extraData)
759 case CAMERA_STATUS_BUFFER_UNDERFLOW:
760 case CAMERA_STATUS_CAPTURECOMPLETE:
761 case CAMERA_STATUS_CAPTURE_ABORTED:
762 case CAMERA_STATUS_CONNECTED:
763 case CAMERA_STATUS_DISCONNECTED:
764 case CAMERA_STATUS_FILESIZE_ERROR:
765 case CAMERA_STATUS_FILESIZE_LIMIT_WARNING:
766 case CAMERA_STATUS_FILESIZE_WARNING:
767 case CAMERA_STATUS_FLASH_LEVEL_CHANGE:
768 case CAMERA_STATUS_FOCUS_CHANGE:
769 case CAMERA_STATUS_FRAME_DROPPED:
770 case CAMERA_STATUS_LOWLIGHT:
771 case CAMERA_STATUS_MM_ERROR:
772 case CAMERA_STATUS_NOSPACE_ERROR:
773 case CAMERA_STATUS_PHOTOVF:
774 case CAMERA_STATUS_POWERDOWN:
775 case CAMERA_STATUS_POWERUP:
776 case CAMERA_STATUS_RESOURCENOTAVAIL:
777 case CAMERA_STATUS_UNKNOWN:
778 case CAMERA_STATUS_VIDEOLIGHT_CHANGE:
779 case CAMERA_STATUS_VIDEOLIGHT_LEVEL_CHANGE:
780 case CAMERA_STATUS_VIDEOVF:
781 case CAMERA_STATUS_VIDEO_PAUSE:
782 case CAMERA_STATUS_VIDEO_RESUME:
783 case CAMERA_STATUS_VIEWFINDER_ACTIVE:
784 case CAMERA_STATUS_VIEWFINDER_ERROR:
785 case CAMERA_STATUS_VIEWFINDER_FREEZE:
786 case CAMERA_STATUS_VIEWFINDER_SUSPEND:
787 case CAMERA_STATUS_VIEWFINDER_UNFREEZE:
788 case CAMERA_STATUS_VIEWFINDER_UNSUSPEND:
789 qDebug() <<
"QQnxCamera:" << ::statusToString(status);
796 QMutexLocker l(&m_currentFrameMutex);
798 return std::move(m_currentFrame);
801void QQnxCamera::viewfinderCallback(camera_handle_t handle, camera_buffer_t *buffer,
void *arg)
806 camera->handleVfBuffer(buffer);
809void QQnxCamera::statusCallback(camera_handle_t handle, camera_devstatus_t status,
810 uint16_t extraData,
void *arg)
815 camera->handleVfStatus(status, extraData);
820#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)