diff options
author | Samuel Mira <samuel.mira@qt.io> | 2021-09-24 15:11:27 +0300 |
---|---|---|
committer | Samuel Mira <samuel.mira@qt.io> | 2021-10-07 10:45:39 +0300 |
commit | 806325a271bf84a0ac359237d1b9a449c0987e8d (patch) | |
tree | 70757052e81ede6062e03364c218cbfa44796870 | |
parent | 8b039e83346fc86d99ed0c3efd17c2661d6cbb9d (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.cpp | 19 | ||||
-rw-r--r-- | examples/multimediawidgets/camera/videosettings.cpp | 95 | ||||
-rw-r--r-- | examples/multimediawidgets/camera/videosettings.ui | 37 | ||||
-rw-r--r-- | examples/multimediawidgets/camera/videosettings_mobile.ui | 54 | ||||
-rw-r--r-- | src/multimedia/video/qvideoframeformat.cpp | 143 | ||||
-rw-r--r-- | src/multimedia/video/qvideoframeformat.h | 2 |
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; }; |