diff options
author | Andrew den Exter <andrew.den.exter@jollamobile.com> | 2014-02-10 13:25:39 +1000 |
---|---|---|
committer | Andrew den Exter <andrew.den.exter@qinetic.com.au> | 2014-07-10 01:39:22 +0200 |
commit | 4ba4f1a51db14c1df20b27cc375255077f051819 (patch) | |
tree | ad14f07c9c6028f320928bd46672eb94639eab31 /src/plugins/gstreamer | |
parent | 63476053415a8bacef83afb651bf7c6f98d60f5e (diff) |
Implement customFocusPoint in camerabin backend.
Send a regions-of-interest event containing a rectangle surrounding the
focus point to the camera source when the camera's focusPointMode
is QCameraFocus::CustomFocusPoint. Reset the regions-of-interest if the
focusPointMode changes to any other value.
[ChangeLog][GStreamer] Implement customFocusPoint in camerabin backend.
Change-Id: If75405733b18d476dff5467abae3f08271caf06a
Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Diffstat (limited to 'src/plugins/gstreamer')
4 files changed, 141 insertions, 7 deletions
diff --git a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp b/src/plugins/gstreamer/camerabin/camerabinfocus.cpp index ed5b483c2..50bc8a44d 100644 --- a/src/plugins/gstreamer/camerabin/camerabinfocus.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinfocus.cpp @@ -54,10 +54,16 @@ QT_BEGIN_NAMESPACE CameraBinFocus::CameraBinFocus(CameraBinSession *session) :QCameraFocusControl(session), m_session(session), + m_cameraState(QCamera::UnloadedState), m_focusMode(QCameraFocus::AutoFocus), + m_focusPointMode(QCameraFocus::FocusPointAuto), m_focusStatus(QCamera::Unlocked), - m_focusZoneStatus(QCameraFocusZone::Selected) + m_focusZoneStatus(QCameraFocusZone::Selected), + m_focusPoint(0.5, 0.5), + m_focusRect(0, 0, 0.3, 0.3) { + m_focusRect.moveCenter(m_focusPoint); + gst_photography_set_focus_mode(m_session->photography(), GST_PHOTOGRAPHY_FOCUS_MODE_AUTO); connect(m_session, SIGNAL(stateChanged(QCamera::State)), @@ -122,32 +128,61 @@ bool CameraBinFocus::isFocusModeSupported(QCameraFocus::FocusModes mode) const QCameraFocus::FocusPointMode CameraBinFocus::focusPointMode() const { - return QCameraFocus::FocusPointAuto; + return m_focusPointMode; } void CameraBinFocus::setFocusPointMode(QCameraFocus::FocusPointMode mode) { Q_UNUSED(mode); + if (m_focusPointMode != mode + && (mode == QCameraFocus::FocusPointAuto || mode == QCameraFocus::FocusPointCustom)) { + m_focusPointMode = mode; + + if (m_focusPointMode == QCameraFocus::FocusPointAuto) + resetFocusPoint(); + + emit focusPointModeChanged(m_focusPointMode); + + } } bool CameraBinFocus::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const { - return mode == QCameraFocus::FocusPointAuto; + return mode == QCameraFocus::FocusPointAuto || mode == QCameraFocus::FocusPointCustom; } QPointF CameraBinFocus::customFocusPoint() const { - return QPointF(0.5, 0.5); + return m_focusPoint; } void CameraBinFocus::setCustomFocusPoint(const QPointF &point) { - Q_UNUSED(point); + if (m_focusPoint != point) { + m_focusPoint = point; + + // Bound the focus point so the focus rect remains entirely within the unit square. + m_focusPoint.setX(qBound(m_focusRect.width() / 2, m_focusPoint.x(), 1 - m_focusRect.width() / 2)); + m_focusPoint.setY(qBound(m_focusRect.height() / 2, m_focusPoint.y(), 1 - m_focusRect.height() / 2)); + + if (m_focusPointMode == QCameraFocus::FocusPointCustom) { + const QRectF focusRect = m_focusRect; + m_focusRect.moveCenter(m_focusPoint); + + updateRegionOfInterest(m_focusRect, 1); + + if (focusRect != m_focusRect) { + emit focusZonesChanged(); + } + } + + emit customFocusPointChanged(m_focusPoint); + } } QCameraFocusZoneList CameraBinFocus::focusZones() const { - return QCameraFocusZoneList() << QCameraFocusZone(QRectF(0.35, 0.35, 0.3, 0.3), m_focusZoneStatus); + return QCameraFocusZoneList() << QCameraFocusZone(m_focusRect, m_focusZoneStatus); } @@ -213,8 +248,29 @@ void CameraBinFocus::_q_setFocusStatus(QCamera::LockStatus status, QCamera::Lock void CameraBinFocus::_q_handleCameraStateChange(QCamera::State state) { - if (state != QCamera::ActiveState) + m_cameraState = state; + if (state == QCamera::ActiveState) { + if (GstPad *pad = gst_element_get_static_pad(m_session->cameraSource(), "vfsrc")) { + if (GstCaps *caps = gst_pad_get_negotiated_caps(pad)) { + if (GstStructure *structure = gst_caps_get_structure(caps, 0)) { + int width = 0; + int height = 0; + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + setViewfinderResolution(QSize(width, height)); + } + gst_caps_unref(caps); + } + gst_object_unref(GST_OBJECT(pad)); + } + if (m_focusPointMode == QCameraFocus::FocusPointCustom) { + updateRegionOfInterest(m_focusRect, 1); + } + } else { _q_setFocusStatus(QCamera::Unlocked, QCamera::LockLost); + + resetFocusPoint(); + } } void CameraBinFocus::_q_startFocusing() @@ -229,4 +285,70 @@ void CameraBinFocus::_q_stopFocusing() _q_setFocusStatus(QCamera::Unlocked, QCamera::UserRequest); } +void CameraBinFocus::setViewfinderResolution(const QSize &resolution) +{ + if (resolution != m_viewfinderResolution) { + m_viewfinderResolution = resolution; + if (!resolution.isEmpty()) { + const QPointF center = m_focusRect.center(); + m_focusRect.setWidth(m_focusRect.height() * resolution.height() / resolution.width()); + m_focusRect.moveCenter(center); + } + } +} + +void CameraBinFocus::resetFocusPoint() +{ + const QRectF focusRect = m_focusRect; + m_focusPoint = QPointF(0.5, 0.5); + m_focusRect.moveCenter(m_focusPoint); + + updateRegionOfInterest(QRectF(0, 0, 0, 0), 0); + + if (focusRect != m_focusRect) { + emit customFocusPointChanged(m_focusPoint); + emit focusZonesChanged(); + } +} + +void CameraBinFocus::updateRegionOfInterest(const QRectF &focusRect, int priority) +{ + if (m_cameraState != QCamera::ActiveState) + return; + + GstElement * const cameraSource = m_session->cameraSource(); + if (!cameraSource) + return; + + GstStructure *region = gst_structure_new( + "region", + "region-x" , G_TYPE_UINT , uint(m_viewfinderResolution.width() * focusRect.x()), + "region-y" , G_TYPE_UINT, uint(m_viewfinderResolution.height() * focusRect.y()), + "region-w" , G_TYPE_UINT , uint(m_viewfinderResolution.width() * focusRect.width()), + "region-h" , G_TYPE_UINT, uint(m_viewfinderResolution.height() * focusRect.height()), + "region-priority" , G_TYPE_UINT, priority, + NULL); + + GValue regionValue = G_VALUE_INIT; + g_value_init(®ionValue, GST_TYPE_STRUCTURE); + gst_value_set_structure(®ionValue, region); + gst_structure_free(region); + + GValue regions = G_VALUE_INIT; + g_value_init(®ions, GST_TYPE_LIST); + gst_value_list_append_value(®ions, ®ionValue); + g_value_unset(®ionValue); + + GstStructure *regionsOfInterest = gst_structure_new( + "regions-of-interest", + "frame-width" , G_TYPE_UINT , m_viewfinderResolution.width(), + "frame-height" , G_TYPE_UINT, m_viewfinderResolution.height(), + NULL); + gst_structure_set_value(regionsOfInterest, "regions", ®ions); + g_value_unset(®ions); + + GstEvent *event = gst_event_new_custom(GST_EVENT_CUSTOM_UPSTREAM, regionsOfInterest); + gst_element_send_event(cameraSource, event); +} + QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinfocus.h b/src/plugins/gstreamer/camerabin/camerabinfocus.h index e1f4dcd36..45ca7fcc8 100644 --- a/src/plugins/gstreamer/camerabin/camerabinfocus.h +++ b/src/plugins/gstreamer/camerabin/camerabinfocus.h @@ -82,15 +82,25 @@ public Q_SLOTS: void _q_startFocusing(); void _q_stopFocusing(); + void setViewfinderResolution(const QSize &resolution); + private Q_SLOTS: void _q_setFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); void _q_handleCameraStateChange(QCamera::State state); private: + void resetFocusPoint(); + void updateRegionOfInterest(const QRectF &focusRect, int priority); + CameraBinSession *m_session; + QCamera::State m_cameraState; QCameraFocus::FocusModes m_focusMode; + QCameraFocus::FocusPointMode m_focusPointMode; QCamera::LockStatus m_focusStatus; QCameraFocusZone::FocusZoneStatus m_focusZoneStatus; + QPointF m_focusPoint; + QRectF m_focusRect; + QSize m_viewfinderResolution; }; QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h index d77217906..54800e9ed 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.h +++ b/src/plugins/gstreamer/camerabin/camerabinsession.h @@ -103,6 +103,7 @@ public: GstPhotography *photography(); #endif GstElement *cameraBin() { return m_camerabin; } + GstElement *cameraSource() { return m_videoSrc; } QGstreamerBusHelper *bus() { return m_busHelper; } CameraRole cameraRole() const; diff --git a/src/plugins/gstreamer/camerabin/camerabinviewfindersettings.cpp b/src/plugins/gstreamer/camerabin/camerabinviewfindersettings.cpp index 373dbee77..b61a506dc 100644 --- a/src/plugins/gstreamer/camerabin/camerabinviewfindersettings.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinviewfindersettings.cpp @@ -89,6 +89,7 @@ void CameraBinViewfinderSettings::setViewfinderParameter(ViewfinderParameter par switch (parameter) { case Resolution: m_resolution = value.toSize(); + break; case PixelAspectRatio: case MinimumFrameRate: case MaximumFrameRate: |