Allow the user to specify the viewfinder resolution instead of guessing
Guessing badly prevents the camerabin pipeline from loading at all and the fallbacks used are not representive of the capabilities of most cameras. So either stay out of the process and let gstreamer negotiate a resolution if it can, or use a resolution supplied through the viewfinder settings control by someone hopefully better informed. Task-number: QTBUG-30842 Change-Id: Iec2dcc2476f38822f9e0d02301e46a1f49b7c6da Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
30078eeee1
commit
ff2cac464c
@@ -55,6 +55,7 @@
|
||||
#endif
|
||||
|
||||
#include "camerabinimageprocessing.h"
|
||||
#include "camerabinviewfindersettings.h"
|
||||
|
||||
#include "camerabincapturedestination.h"
|
||||
#include "camerabincapturebufferformat.h"
|
||||
@@ -91,6 +92,7 @@
|
||||
#define AUDIO_SOURCE_PROPERTY "audio-source"
|
||||
#define SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-supported-caps"
|
||||
#define SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-supported-caps"
|
||||
#define SUPPORTED_VIEWFINDER_CAPS_PROPERTY "viewfinder-supported-caps"
|
||||
#define IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-caps"
|
||||
#define VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-caps"
|
||||
#define VIEWFINDER_CAPS_PROPERTY "viewfinder-caps"
|
||||
@@ -110,10 +112,6 @@
|
||||
#define PREVIEW_CAPS_4_3 \
|
||||
"video/x-raw-rgb, width = (int) 640, height = (int) 480"
|
||||
|
||||
#define VIEWFINDER_RESOLUTION_4x3 QSize(640, 480)
|
||||
#define VIEWFINDER_RESOLUTION_3x2 QSize(720, 480)
|
||||
#define VIEWFINDER_RESOLUTION_16x9 QSize(800, 450)
|
||||
|
||||
//using GST_STATE_READY for QCamera::LoadedState
|
||||
//may not work reliably at least with some webcams.
|
||||
|
||||
@@ -170,6 +168,7 @@ CameraBinSession::CameraBinSession(QObject *parent)
|
||||
m_imageProcessingControl = new CameraBinImageProcessing(this);
|
||||
m_captureDestinationControl = new CameraBinCaptureDestination(this);
|
||||
m_captureBufferFormatControl = new CameraBinCaptureBufferFormat(this);
|
||||
m_viewfinderSettingsControl = new CameraBinViewfinderSettings(this);
|
||||
|
||||
QByteArray envFlags = qgetenv("QT_GSTREAMER_CAMERABIN_FLAGS");
|
||||
if (!envFlags.isEmpty())
|
||||
@@ -246,8 +245,7 @@ bool CameraBinSession::setupCameraBin()
|
||||
return true;
|
||||
}
|
||||
|
||||
static GstCaps *resolutionToCaps(const QSize &resolution,
|
||||
const QPair<int, int> &rate = qMakePair<int,int>(0,0))
|
||||
static GstCaps *resolutionToCaps(const QSize &resolution, const QPair<int, int> &rate = qMakePair<int,int>(0,0))
|
||||
{
|
||||
if (resolution.isEmpty())
|
||||
return gst_caps_new_any();
|
||||
@@ -263,7 +261,23 @@ static GstCaps *resolutionToCaps(const QSize &resolution,
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
"framerate", GST_TYPE_FRACTION, rate.first, rate.second,
|
||||
NULL), NULL);
|
||||
NULL),
|
||||
gst_structure_new("video/x-raw-data",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
"framerate", GST_TYPE_FRACTION, rate.first, rate.second,
|
||||
NULL),
|
||||
gst_structure_new("video/x-android-buffer",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
"framerate", GST_TYPE_FRACTION, rate.first, rate.second,
|
||||
NULL),
|
||||
gst_structure_new("image/jpeg",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
"framerate", GST_TYPE_FRACTION, rate.first, rate.second,
|
||||
NULL),
|
||||
NULL);
|
||||
} else {
|
||||
caps = gst_caps_new_full (gst_structure_new ("video/x-raw-yuv",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
@@ -271,85 +285,63 @@ static GstCaps *resolutionToCaps(const QSize &resolution,
|
||||
NULL),
|
||||
gst_structure_new ("video/x-raw-rgb",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(), NULL), NULL);
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
NULL),
|
||||
gst_structure_new("video/x-raw-data",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
NULL),
|
||||
gst_structure_new ("video/x-android-buffer",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
NULL),
|
||||
gst_structure_new ("image/jpeg",
|
||||
"width", G_TYPE_INT, resolution.width(),
|
||||
"height", G_TYPE_INT, resolution.height(),
|
||||
NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
void CameraBinSession::setupCaptureResolution()
|
||||
{
|
||||
if (m_captureMode == QCamera::CaptureStillImage) {
|
||||
QSize resolution = m_imageEncodeControl->imageSettings().resolution();
|
||||
|
||||
//by default select the maximum supported resolution
|
||||
if (resolution.isEmpty()) {
|
||||
bool continuous = false;
|
||||
QList<QSize> resolutions = supportedResolutions(qMakePair<int,int>(0,0),
|
||||
&continuous,
|
||||
QCamera::CaptureStillImage);
|
||||
if (!resolutions.isEmpty())
|
||||
resolution = resolutions.last();
|
||||
}
|
||||
|
||||
QSize viewfinderResolution = VIEWFINDER_RESOLUTION_4x3;
|
||||
|
||||
if (!resolution.isEmpty()) {
|
||||
GstCaps *caps = resolutionToCaps(resolution);
|
||||
QSize resolution = m_imageEncodeControl->imageSettings().resolution();
|
||||
if (!resolution.isEmpty()) {
|
||||
GstCaps *caps = resolutionToCaps(resolution);
|
||||
#if CAMERABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << gst_caps_to_string(caps);
|
||||
qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << gst_caps_to_string(caps);
|
||||
#endif
|
||||
g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, caps, NULL);
|
||||
gst_caps_unref(caps);
|
||||
|
||||
if (!resolution.isEmpty()) {
|
||||
qreal aspectRatio = qreal(resolution.width()) / resolution.height();
|
||||
if (aspectRatio < 1.4)
|
||||
viewfinderResolution = VIEWFINDER_RESOLUTION_4x3;
|
||||
else if (aspectRatio > 1.7)
|
||||
viewfinderResolution = VIEWFINDER_RESOLUTION_16x9;
|
||||
else
|
||||
viewfinderResolution = VIEWFINDER_RESOLUTION_3x2;
|
||||
}
|
||||
} else {
|
||||
g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, GST_CAPS_ANY, NULL);
|
||||
}
|
||||
|
||||
//on low res cameras the viewfinder resolution should not be bigger
|
||||
//then capture resolution
|
||||
if (viewfinderResolution.width() > resolution.width() && !resolution.isEmpty())
|
||||
viewfinderResolution = resolution;
|
||||
|
||||
GstCaps *viewfinderCaps = resolutionToCaps(viewfinderResolution);
|
||||
#if CAMERABIN_DEBUG
|
||||
qDebug() << "Set viewfinder resolution" << viewfinderResolution <<gst_caps_to_string(viewfinderCaps);
|
||||
#endif
|
||||
g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, viewfinderCaps, NULL);
|
||||
gst_caps_unref(viewfinderCaps);
|
||||
g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, caps, NULL);
|
||||
gst_caps_unref(caps);
|
||||
} else {
|
||||
g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, NULL, NULL);
|
||||
}
|
||||
|
||||
if (m_captureMode == QCamera::CaptureVideo) {
|
||||
QSize resolution = m_videoEncodeControl->actualVideoSettings().resolution();
|
||||
//qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
|
||||
|
||||
if (resolution.isEmpty()) {
|
||||
//select the hightest supported resolution
|
||||
bool continuous = false;
|
||||
QList<QSize> resolutions = supportedResolutions(qMakePair<int,int>(0,0),
|
||||
&continuous,
|
||||
QCamera::CaptureVideo);
|
||||
if (!resolutions.isEmpty())
|
||||
resolution = resolutions.last();
|
||||
}
|
||||
|
||||
resolution = m_videoEncodeControl->actualVideoSettings().resolution();
|
||||
//qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
|
||||
if (!resolution.isEmpty()) {
|
||||
GstCaps *caps = resolutionToCaps(resolution /*, framerate*/); //convert to rational
|
||||
#if CAMERABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << gst_caps_to_string(caps);
|
||||
#endif
|
||||
|
||||
//Use the same resolution for viewfinder and video capture
|
||||
g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, caps, NULL);
|
||||
gst_caps_unref(caps);
|
||||
} else {
|
||||
g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, NULL, NULL);
|
||||
}
|
||||
|
||||
resolution = m_viewfinderSettingsControl->resolution();
|
||||
if (!resolution.isEmpty()) {
|
||||
GstCaps *caps = resolutionToCaps(resolution);
|
||||
#if CAMERABIN_DEBUG
|
||||
qDebug() << Q_FUNC_INFO << "set viewfinder resolution" << resolution << gst_caps_to_string(caps);
|
||||
#endif
|
||||
g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, caps, NULL);
|
||||
gst_caps_unref(caps);
|
||||
} else {
|
||||
g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user