summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Mira <samuel.mira@qt.io>2021-09-24 15:11:27 +0300
committerSamuel Mira <samuel.mira@qt.io>2021-10-07 10:45:39 +0300
commit806325a271bf84a0ac359237d1b9a449c0987e8d (patch)
tree70757052e81ede6062e03364c218cbfa44796870
parent8b039e83346fc86d99ed0c3efd17c2661d6cbb9d (diff)
Fix resolution list to a camera format list
Changed the resolution list (widthxheight) to camera a format list (PixelFormat widthxheight MinFps-MaxFps FPS) Changed the Frames per Second to be a spinbox and a slider so it would give feedback of the selected FPS while being easy to change on a mobile device. This way users can fine tune how many fps they want for the capture (previously was either min or max) Set the selected cameraFormat to the camera in the captureSession since it was needed for saving all the changes and it fixed QTBUG-96739 by coincidence Fixes: QTBUG-96719 Fixes: QTBUG-96739 Pick-to: 6.2 Change-Id: I9eaacfbf860d8a4d03c2044b41de5d84139b3b17 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
-rw-r--r--examples/multimediawidgets/camera/camera.cpp19
-rw-r--r--examples/multimediawidgets/camera/videosettings.cpp95
-rw-r--r--examples/multimediawidgets/camera/videosettings.ui37
-rw-r--r--examples/multimediawidgets/camera/videosettings_mobile.ui54
-rw-r--r--src/multimedia/video/qvideoframeformat.cpp143
-rw-r--r--src/multimedia/video/qvideoframeformat.h2
6 files changed, 209 insertions, 141 deletions
diff --git a/examples/multimediawidgets/camera/camera.cpp b/examples/multimediawidgets/camera/camera.cpp
index a0d3de698..3ddb78597 100644
--- a/examples/multimediawidgets/camera/camera.cpp
+++ b/examples/multimediawidgets/camera/camera.cpp
@@ -131,6 +131,25 @@ void Camera::setCamera(const QCameraDevice &cameraDevice)
readyForCapture(m_imageCapture->isReadyForCapture());
updateCaptureMode();
+
+ if (m_camera->cameraFormat().isNull()) {
+ // Setting default settings.
+ // The biggest resolution and the max framerate
+ auto formats = cameraDevice.videoFormats();
+ auto defaultFormat = formats.first();
+
+ for (const auto &format : formats) {
+
+ bool isFormatBigger = format.resolution().width() > defaultFormat.resolution().width()
+ && format.resolution().height() > defaultFormat.resolution().height();
+
+ defaultFormat = isFormatBigger ? format : defaultFormat;
+ }
+
+ m_camera->setCameraFormat(defaultFormat);
+ m_mediaRecorder->setVideoFrameRate(defaultFormat.maxFrameRate());
+ }
+
m_camera->start();
}
diff --git a/examples/multimediawidgets/camera/videosettings.cpp b/examples/multimediawidgets/camera/videosettings.cpp
index b5b0ba384..e212e9dd8 100644
--- a/examples/multimediawidgets/camera/videosettings.cpp
+++ b/examples/multimediawidgets/camera/videosettings.cpp
@@ -66,6 +66,27 @@
#include <QCamera>
#include <QAudioInput>
+QString toFormattedString(const QCameraFormat &cameraFormat)
+{
+ QString string;
+ const auto &separator = QStringLiteral(" ");
+
+ string.append(QVideoFrameFormat::pixelFormatToString(cameraFormat.pixelFormat()));
+ string.append(separator);
+
+ string.append(QString::number(cameraFormat.resolution().width()));
+ string.append(QStringLiteral("x"));
+ string.append(QString::number(cameraFormat.resolution().height()));
+ string.append(separator);
+
+ string.append(QString::number(cameraFormat.minFrameRate()));
+ string.append(QStringLiteral("-"));
+ string.append(QString::number(cameraFormat.maxFrameRate()));
+ string.append(QStringLiteral("FPS"));
+
+ return string;
+}
+
VideoSettings::VideoSettings(QMediaRecorder *mediaRecorder, QWidget *parent)
: QDialog(parent),
ui(new Ui::VideoSettingsUi),
@@ -94,50 +115,33 @@ VideoSettings::VideoSettings(QMediaRecorder *mediaRecorder, QWidget *parent)
ui->videoCodecBox->addItem(QMediaFormat::videoCodecName(codec) + ": " + description, QVariant::fromValue(codec));
}
- ui->videoResolutionBox->addItem(tr("Default"));
+ // camera format
+ ui->videoFormatBox->addItem(tr("Default camera format"));
const QList<QCameraFormat> videoFormats =
mediaRecorder->captureSession()->camera()->cameraDevice().videoFormats();
for (const QCameraFormat &format : videoFormats) {
- const QSize resolution = format.resolution();
- ui->videoResolutionBox->addItem(QString("%1x%2")
- .arg(resolution.width())
- .arg(resolution.height()),
- QVariant(resolution));
+ ui->videoFormatBox->addItem(toFormattedString(format), QVariant::fromValue(format));
}
- ui->videoFramerateBox->addItem(tr("Default"));
-
- connect(ui->videoResolutionBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
- [this, mediaRecorder](int index) {
-
- // Get the current list of formats
- const QList<QCameraFormat> videoFormats =
- mediaRecorder->captureSession()->camera()->cameraDevice().videoFormats();
-
- QCameraFormat videoFormat;
- const auto resolution = ui->videoResolutionBox->itemData(index).value<QSize>();
- for (const QCameraFormat &format : videoFormats) {
- if (format.resolution() == resolution) {
- videoFormat = format;
- break;
- }
- }
+ connect(ui->videoFormatBox, &QComboBox::currentIndexChanged, [this](int index) {
+ const auto &cameraFormat = boxValue(ui->videoFormatBox).value<QCameraFormat>();
+ ui->fpsSlider->setRange(cameraFormat.minFrameRate(), cameraFormat.maxFrameRate());
+ ui->fpsSpinBox->setRange(cameraFormat.minFrameRate(), cameraFormat.maxFrameRate());
+ });
- ui->videoFramerateBox->clear();
+ auto currentCameraFormat = mediaRecorder->captureSession()->camera()->cameraFormat();
+ ui->fpsSlider->setRange(currentCameraFormat.minFrameRate(), currentCameraFormat.maxFrameRate());
+ ui->fpsSpinBox->setRange(currentCameraFormat.minFrameRate(),
+ currentCameraFormat.maxFrameRate());
- const float minFrameRate = videoFormat.minFrameRate();
- QString rateString = QString("%1").arg(minFrameRate, 0, 'f', 2);
- ui->videoFramerateBox->addItem(rateString, QVariant(minFrameRate));
+ connect(ui->fpsSlider, &QSlider::valueChanged, ui->fpsSpinBox, &QSpinBox::setValue);
+ connect(ui->fpsSpinBox, &QSpinBox::valueChanged, ui->fpsSlider, &QSlider::setValue);
- const float maxFrameRate = videoFormat.maxFrameRate();
- rateString = QString("%1").arg(maxFrameRate, 0, 'f', 2);
- ui->videoFramerateBox->addItem(rateString, QVariant(maxFrameRate));
- });
-
- //containers
- ui->containerFormatBox->addItem(tr("Default container"), QVariant::fromValue(QMediaFormat::UnspecifiedFormat));
+ // containers
+ ui->containerFormatBox->addItem(tr("Default video container"),
+ QVariant::fromValue(QMediaFormat::UnspecifiedFormat));
const auto formats = QMediaFormat().supportedFileFormats(QMediaFormat::Encode);
for (auto format : formats) {
ui->containerFormatBox->addItem(QMediaFormat::fileFormatName(format) + ": " + QMediaFormat::fileFormatDescription(format),
@@ -153,17 +157,12 @@ VideoSettings::VideoSettings(QMediaRecorder *mediaRecorder, QWidget *parent)
ui->qualitySlider->setValue(mediaRecorder->quality());
ui->audioSampleRateBox->setValue(mediaRecorder->audioSampleRate());
- selectComboBoxItem(ui->videoResolutionBox, QVariant(mediaRecorder->videoResolution()));
-
- //special case for frame rate
- for (int i = 0; i < ui->videoFramerateBox->count(); ++i) {
- qreal itemRate = ui->videoFramerateBox->itemData(i).value<qreal>();
- if (qFuzzyCompare(itemRate, mediaRecorder->videoFrameRate())) {
- ui->videoFramerateBox->setCurrentIndex(i);
- break;
- }
- }
+ selectComboBoxItem(
+ ui->videoFormatBox,
+ QVariant::fromValue(mediaRecorder->captureSession()->camera()->cameraFormat()));
+ ui->fpsSlider->setValue(mediaRecorder->videoFrameRate());
+ ui->fpsSpinBox->setValue(mediaRecorder->videoFrameRate());
}
VideoSettings::~VideoSettings()
@@ -193,8 +192,12 @@ void VideoSettings::applySettings()
mediaRecorder->setMediaFormat(format);
mediaRecorder->setQuality(QMediaRecorder::Quality(ui->qualitySlider->value()));
mediaRecorder->setAudioSampleRate(ui->audioSampleRateBox->value());
- mediaRecorder->setVideoResolution(boxValue(ui->videoResolutionBox).toSize());
- mediaRecorder->setVideoFrameRate(boxValue(ui->videoFramerateBox).value<qreal>());
+
+ const auto &cameraFormat = boxValue(ui->videoFormatBox).value<QCameraFormat>();
+ mediaRecorder->setVideoResolution(cameraFormat.resolution());
+ mediaRecorder->setVideoFrameRate(ui->fpsSlider->value());
+
+ mediaRecorder->captureSession()->camera()->setCameraFormat(cameraFormat);
}
QVariant VideoSettings::boxValue(const QComboBox *box) const
diff --git a/examples/multimediawidgets/camera/videosettings.ui b/examples/multimediawidgets/camera/videosettings.ui
index e30e31608..3c1f71f11 100644
--- a/examples/multimediawidgets/camera/videosettings.ui
+++ b/examples/multimediawidgets/camera/videosettings.ui
@@ -30,18 +30,15 @@
<string>Video</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="1" column="0" colspan="2">
- <widget class="QComboBox" name="videoResolutionBox"/>
- </item>
- <item row="4" column="0" colspan="2">
- <widget class="QLabel" name="label_6">
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label_8">
<property name="text">
- <string>Video Codec:</string>
+ <string>Camera Format</string>
</property>
</widget>
</item>
- <item row="3" column="0" colspan="2">
- <widget class="QComboBox" name="videoFramerateBox"/>
+ <item row="5" column="0" colspan="2">
+ <widget class="QComboBox" name="videoCodecBox"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_9">
@@ -50,15 +47,29 @@
</property>
</widget>
</item>
- <item row="0" column="0" colspan="2">
- <widget class="QLabel" name="label_8">
+ <item row="4" column="0" colspan="2">
+ <widget class="QLabel" name="label_6">
<property name="text">
- <string>Resolution:</string>
+ <string>Video Codec:</string>
</property>
</widget>
</item>
- <item row="5" column="0" colspan="2">
- <widget class="QComboBox" name="videoCodecBox"/>
+ <item row="1" column="0" colspan="2">
+ <widget class="QComboBox" name="videoFormatBox"/>
+ </item>
+ <item row="3" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSpinBox" name="fpsSpinBox"/>
+ </item>
+ <item>
+ <widget class="QSlider" name="fpsSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
</widget>
diff --git a/examples/multimediawidgets/camera/videosettings_mobile.ui b/examples/multimediawidgets/camera/videosettings_mobile.ui
index 99819df05..6584f07f9 100644
--- a/examples/multimediawidgets/camera/videosettings_mobile.ui
+++ b/examples/multimediawidgets/camera/videosettings_mobile.ui
@@ -106,37 +106,34 @@
<string>Video</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="1" column="0" colspan="2">
- <widget class="QComboBox" name="videoResolutionBox"/>
- </item>
- <item row="4" column="0" colspan="2">
- <widget class="QLabel" name="label_6">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
<property name="text">
- <string>Video Codec:</string>
+ <string>Frames per second:</string>
</property>
</widget>
</item>
- <item row="2" column="0" colspan="2">
- <widget class="QLabel" name="label_9">
+ <item row="6" column="0" colspan="2">
+ <widget class="QComboBox" name="videoCodecBox"/>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QLabel" name="label_8">
<property name="text">
- <string>Framerate:</string>
+ <string>Camera Format:</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
- <widget class="QComboBox" name="videoCodecBox"/>
- </item>
- <item row="3" column="0" colspan="2">
- <widget class="QComboBox" name="videoFramerateBox"/>
- </item>
- <item row="0" column="0" colspan="2">
- <widget class="QLabel" name="label_8">
+ <widget class="QLabel" name="label_6">
<property name="text">
- <string>Resolution:</string>
+ <string>Video Codec:</string>
</property>
</widget>
</item>
- <item row="6" column="0">
+ <item row="1" column="0" colspan="2">
+ <widget class="QComboBox" name="videoFormatBox"/>
+ </item>
+ <item row="7" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -146,6 +143,27 @@
</property>
</widget>
</item>
+ <item row="3" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSpinBox" name="fpsSpinBox">
+ <property name="minimum">
+ <number>8</number>
+ </property>
+ <property name="maximum">
+ <number>30</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="fpsSlider">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/multimedia/video/qvideoframeformat.cpp b/src/multimedia/video/qvideoframeformat.cpp
index 71165e4da..84130c281 100644
--- a/src/multimedia/video/qvideoframeformat.cpp
+++ b/src/multimedia/video/qvideoframeformat.cpp
@@ -669,6 +669,79 @@ QImage::Format QVideoFrameFormat::imageFormatFromPixelFormat(QVideoFrameFormat::
return QImage::Format_Invalid;
}
+/*!
+ Returns a string representation of the given \a pixelFormat.
+*/
+QString QVideoFrameFormat::pixelFormatToString(QVideoFrameFormat::PixelFormat pixelFormat)
+{
+ switch (pixelFormat) {
+ case QVideoFrameFormat::Format_Invalid:
+ return QStringLiteral("Invalid");
+ case QVideoFrameFormat::Format_ARGB8888:
+ return QStringLiteral("ARGB8888");
+ case QVideoFrameFormat::Format_ARGB8888_Premultiplied:
+ return QStringLiteral("ARGB8888 Premultiplied");
+ case QVideoFrameFormat::Format_XRGB8888:
+ return QStringLiteral("XRGB8888");
+ case QVideoFrameFormat::Format_BGRA8888:
+ return QStringLiteral("BGRA8888");
+ case QVideoFrameFormat::Format_BGRX8888:
+ return QStringLiteral("BGRX8888");
+ case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
+ return QStringLiteral("BGRA8888 Premultiplied");
+ case QVideoFrameFormat::Format_RGBA8888:
+ return QStringLiteral("RGBA8888");
+ case QVideoFrameFormat::Format_RGBX8888:
+ return QStringLiteral("RGBX8888");
+ case QVideoFrameFormat::Format_ABGR8888:
+ return QStringLiteral("ABGR8888");
+ case QVideoFrameFormat::Format_XBGR8888:
+ return QStringLiteral("XBGR8888");
+ case QVideoFrameFormat::Format_AYUV:
+ return QStringLiteral("AYUV");
+ case QVideoFrameFormat::Format_AYUV_Premultiplied:
+ return QStringLiteral("AYUV Premultiplied");
+ case QVideoFrameFormat::Format_YUV420P:
+ return QStringLiteral("YUV420P");
+ case QVideoFrameFormat::Format_YUV422P:
+ return QStringLiteral("YUV422P");
+ case QVideoFrameFormat::Format_YV12:
+ return QStringLiteral("YV12");
+ case QVideoFrameFormat::Format_UYVY:
+ return QStringLiteral("UYVY");
+ case QVideoFrameFormat::Format_YUYV:
+ return QStringLiteral("YUYV");
+ case QVideoFrameFormat::Format_NV12:
+ return QStringLiteral("NV12");
+ case QVideoFrameFormat::Format_NV21:
+ return QStringLiteral("NV21");
+ case QVideoFrameFormat::Format_IMC1:
+ return QStringLiteral("IMC1");
+ case QVideoFrameFormat::Format_IMC2:
+ return QStringLiteral("IMC2");
+ case QVideoFrameFormat::Format_IMC3:
+ return QStringLiteral("IMC3");
+ case QVideoFrameFormat::Format_IMC4:
+ return QStringLiteral("IMC4");
+ case QVideoFrameFormat::Format_Y8:
+ return QStringLiteral("Y8");
+ case QVideoFrameFormat::Format_Y16:
+ return QStringLiteral("Y16");
+ case QVideoFrameFormat::Format_P010:
+ return QStringLiteral("P010");
+ case QVideoFrameFormat::Format_P016:
+ return QStringLiteral("P016");
+ case QVideoFrameFormat::Format_SamplerExternalOES:
+ return QStringLiteral("SamplerExternalOES");
+ case QVideoFrameFormat::Format_Jpeg:
+ return QStringLiteral("Jpeg");
+ case QVideoFrameFormat::Format_SamplerRect:
+ return QStringLiteral("SamplerRect");
+ }
+
+ return QStringLiteral("");
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, QVideoFrameFormat::YCbCrColorSpace cs)
{
@@ -734,70 +807,12 @@ QDebug operator<<(QDebug dbg, QVideoFrameFormat::PixelFormat pf)
{
QDebugStateSaver saver(dbg);
dbg.nospace();
- switch (pf) {
- case QVideoFrameFormat::Format_Invalid:
- return dbg << "Format_Invalid";
- case QVideoFrameFormat::Format_ARGB8888:
- return dbg << "Format_ARGB8888";
- case QVideoFrameFormat::Format_ARGB8888_Premultiplied:
- return dbg << "Format_ARGB8888_Premultiplied";
- case QVideoFrameFormat::Format_XRGB8888:
- return dbg << "Format_XRGB8888";
- case QVideoFrameFormat::Format_BGRA8888:
- return dbg << "Format_BGRA8888";
- case QVideoFrameFormat::Format_BGRX8888:
- return dbg << "Format_BGRX8888";
- case QVideoFrameFormat::Format_BGRA8888_Premultiplied:
- return dbg << "Format_BGRA8888_Premultiplied";
- case QVideoFrameFormat::Format_RGBA8888:
- return dbg << "Format_RGBA8888";
- case QVideoFrameFormat::Format_RGBX8888:
- return dbg << "Format_RGBX8888";
- case QVideoFrameFormat::Format_ABGR8888:
- return dbg << "Format_ABGR8888";
- case QVideoFrameFormat::Format_XBGR8888:
- return dbg << "Format_XBGR8888";
- case QVideoFrameFormat::Format_AYUV:
- return dbg << "Format_AYUV";
- case QVideoFrameFormat::Format_AYUV_Premultiplied:
- return dbg << "Format_AYUV_Premultiplied";
- case QVideoFrameFormat::Format_YUV420P:
- return dbg << "Format_YUV420P";
- case QVideoFrameFormat::Format_YUV422P:
- return dbg << "Format_YUV422P";
- case QVideoFrameFormat::Format_YV12:
- return dbg << "Format_YV12";
- case QVideoFrameFormat::Format_UYVY:
- return dbg << "Format_UYVY";
- case QVideoFrameFormat::Format_YUYV:
- return dbg << "Format_YUYV";
- case QVideoFrameFormat::Format_NV12:
- return dbg << "Format_NV12";
- case QVideoFrameFormat::Format_NV21:
- return dbg << "Format_NV21";
- case QVideoFrameFormat::Format_IMC1:
- return dbg << "Format_IMC1";
- case QVideoFrameFormat::Format_IMC2:
- return dbg << "Format_IMC2";
- case QVideoFrameFormat::Format_IMC3:
- return dbg << "Format_IMC3";
- case QVideoFrameFormat::Format_IMC4:
- return dbg << "Format_IMC4";
- case QVideoFrameFormat::Format_Y8:
- return dbg << "Format_Y8";
- case QVideoFrameFormat::Format_Y16:
- return dbg << "Format_Y16";
- case QVideoFrameFormat::Format_P010:
- return dbg << "Format_P010";
- case QVideoFrameFormat::Format_P016:
- return dbg << "Format_P016";
- case QVideoFrameFormat::Format_SamplerExternalOES:
- return dbg << "Format_SamplerExternalOES";
- case QVideoFrameFormat::Format_Jpeg:
- return dbg << "Format_Jpeg";
- case QVideoFrameFormat::Format_SamplerRect:
- return dbg << "Format_SamplerRect";
- }
+
+ auto format = QVideoFrameFormat::pixelFormatToString(pf);
+ if (format.isEmpty())
+ return dbg;
+
+ dbg << QStringLiteral("Format_") << format;
return dbg;
}
#endif
diff --git a/src/multimedia/video/qvideoframeformat.h b/src/multimedia/video/qvideoframeformat.h
index bd4f9fc15..a60d1eedc 100644
--- a/src/multimedia/video/qvideoframeformat.h
+++ b/src/multimedia/video/qvideoframeformat.h
@@ -171,6 +171,8 @@ public:
static PixelFormat pixelFormatFromImageFormat(QImage::Format format);
static QImage::Format imageFormatFromPixelFormat(PixelFormat format);
+ static QString pixelFormatToString(QVideoFrameFormat::PixelFormat pixelFormat);
+
private:
QExplicitlySharedDataPointer<QVideoFrameFormatPrivate> d;
};