diff --git a/libcam/libcam_v4l2core/v4l2_formats.c b/libcam/libcam_v4l2core/v4l2_formats.c index da651e1b..a3d1a8df 100644 --- a/libcam/libcam_v4l2core/v4l2_formats.c +++ b/libcam/libcam_v4l2core/v4l2_formats.c @@ -119,6 +119,9 @@ static uint32_t decoder_supported_formats[] = 0 }; +// 是否开启8K预览 +static int enable_8k_preview = 0; + /* FIXME: doesn't support bigendian formats=> fourcc | (1 << 31) * get pixelformat from fourcc * args: @@ -748,8 +751,45 @@ void free_frame_formats(v4l2_dev_t *vd) int is_valid_resolution(int width, int height) { + // 希沃的8K分辨率是8192x2772,过多限制会导致此分辨率不可用 + if (enable_8k_preview) { + return (width > 0 && height > 0) + && (width % 16 == 0 && height % 4 == 0); + } + // 由于上游guvcview项目在解码3840x2160分辨率以上时会出现异常(出现条纹、崩溃等),所以我们需要限制可用分辨率到3840x2160 return (width > 0 && height > 0) && (width <= MAX_WIDTH_LIMIT && height <= MAX_HEIGHT_LIMIT) && (width % 16 == 0 && height % 8 == 0); } + +/* + * set enable 8k preview + * args: + * enable - enable 8k preview + * + * asserts: + * none + * + * returns: void + */ +void set_enable_8k_preview(int enable) +{ + enable_8k_preview = enable; +} + +/* + * check if 8k preview is enabled + * args: + * none + * + * asserts: + * none + * + * returns: TRUE(1) if enabled + * FALSE(0) if not + */ +int is_enable_8k_preview() +{ + return enable_8k_preview; +} diff --git a/libcam/libcam_v4l2core/v4l2_formats.h b/libcam/libcam_v4l2core/v4l2_formats.h index dafed99c..ab50576c 100644 --- a/libcam/libcam_v4l2core/v4l2_formats.h +++ b/libcam/libcam_v4l2core/v4l2_formats.h @@ -110,4 +110,29 @@ void free_frame_formats(v4l2_dev_t *vd); */ int is_valid_resolution(int width, int height); +/* + * set enable 8k preview + * args: + * enable - enable 8k preview + * + * asserts: + * none + * + * returns: void + */ +void set_enable_8k_preview(int enable); + +/* + * check if 8k preview is enabled + * args: + * none + * + * asserts: + * none + * + * returns: TRUE(1) if enabled + * FALSE(0) if not + */ +int is_enable_8k_preview(); + #endif diff --git a/src/assets/org.deepin.camera.encode.json b/src/assets/org.deepin.camera.encode.json index 90ad17b9..9b30cf0e 100644 --- a/src/assets/org.deepin.camera.encode.json +++ b/src/assets/org.deepin.camera.encode.json @@ -81,6 +81,16 @@ "description": "Enable USB group", "permissions": "readwrite", "visibility": "private" + }, + "enable8kPreview": { + "value": false, + "serial": 0, + "flags": ["global"], + "name": "enable 8k preview", + "name[zh_CN]": "是否启用8K预览", + "description": "Enable 8k preview", + "permissions": "readwrite", + "visibility": "private" } } } diff --git a/src/main.cpp b/src/main.cpp index c40765ad..ce2f1917 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,7 @@ extern "C" { #include "camview.h" +#include "v4l2_formats.h" } #include "mainwindow.h" #include "capplication.h" @@ -188,6 +189,16 @@ int main(int argc, char *argv[]) DataManager::instance()->setEnableUsbGroup(enable); } + // 是否开启8K预览通过DConfig控制,目前要求开启8K预览的厂家是希沃 + // 希沃的8K分辨率是8192x2772,希沃在8K预览的时候表现正常,在录像的时候表现异常,所以在开启8K预览的时候我们会禁用录像功能 + // 8K预览功能默认关闭,因为多个厂家的摄像头在8K预览的时候表现异常 + if (dconfig && dconfig->isValid() && dconfig->keyList().contains("enable8kPreview")) { + bool enable = dconfig->value("enable8kPreview").toBool(); + qInfo() << "enable 8K preview:" << enable; + DataManager::instance()->setEnable8kPreview(enable); + set_enable_8k_preview(enable ? 1 : 0); + } + if (!libVaDriverName.isEmpty()) { qputenv("LIBVA_DRIVER_NAME", libVaDriverName.toLocal8Bit()); } diff --git a/src/src/basepub/datamanager.h b/src/src/basepub/datamanager.h index fafa8068..fd9d1f54 100644 --- a/src/src/basepub/datamanager.h +++ b/src/src/basepub/datamanager.h @@ -175,6 +175,18 @@ class DataManager: public QObject * @return */ bool isEnableUsbGroup() const { return m_enableUsbGroup; }; + + /** + * @brief 设置是否启用8K预览 + * @param enable + */ + void setEnable8kPreview(bool enable) { m_enable8kPreview = enable; }; + + /** + * @brief 获取是否启用8K预览 + * @return + */ + bool isEnable8kPreview() const { return m_enable8kPreview; }; private: DataManager(); static DataManager *m_dataManager; @@ -187,5 +199,6 @@ class DataManager: public QObject bool m_isSupportCameraSwitch = false; // 是否带有摄像头开关 bool m_isPreviewNoDelay = false; // 是否预览无延迟 bool m_enableUsbGroup = false; // 是否启用USB摄像头分组 + bool m_enable8kPreview = false; // 是否启用8K预览 }; #endif // DATAMANAGER_H diff --git a/src/src/mainwindow.cpp b/src/src/mainwindow.cpp index c9fe9b7c..d8aa03bd 100644 --- a/src/src/mainwindow.cpp +++ b/src/src/mainwindow.cpp @@ -1394,6 +1394,7 @@ void CMainWindow::onSwitchCameraSuccess(const QString &cameraName) m_labelCameraName->show(); m_filterName->hide(); m_showCameraNameTimer->start(); + showChildWidget(); } void CMainWindow::onTimeoutLock(const QString &serviceName, QVariantMap key2value, QStringList) @@ -2216,6 +2217,13 @@ void CMainWindow::onSettingsDlgClose() if (bPathChanged) { reflushSnapshotLabel(); } + + // 8k分辨率时不显示录像功能 + bool isResolutionTooHigh = checkResolutionTooHigh(); + if (isResolutionTooHigh) { + m_modeSwitchBox->reset(); + } + showChildWidget(); } void CMainWindow::onEnableSettings(bool bTrue) @@ -2327,9 +2335,12 @@ void CMainWindow::showChildWidget() showWidget(m_photoRecordBtn, true); return; } + + // 8k分辨率时不显示录像功能 + bool isResolutionTooHigh = checkResolutionTooHigh(); showWidget(m_snapshotLabel, true); showWidget(m_cameraSwitchBtn, m_bSwitchCameraShowEnable); - showWidget(m_modeSwitchBox, true); + showWidget(m_modeSwitchBox, !isResolutionTooHigh); showWidget(m_photoRecordBtn, true); showWidget(m_takePhotoSettingArea, true); showWidget(m_filterName, m_bShowFilterName); @@ -2348,6 +2359,21 @@ void CMainWindow::showWidget(DWidget *widget, bool bShow) } } +bool CMainWindow::checkResolutionTooHigh() const +{ + int currentWidth = 0; + int currentHeight = 0; + v4l2_dev_t *fd = get_v4l2_device_handler(); + if (fd) { + currentWidth = v4l2core_get_frame_width(fd); + currentHeight = v4l2core_get_frame_height(fd); + } + bool isTrue = currentWidth > MAX_WIDTH_LIMIT || currentHeight > MAX_HEIGHT_LIMIT; + qInfo() << __func__ << isTrue << currentWidth << "x" << currentHeight; + + return isTrue; +} + CMainWindow::~CMainWindow() { if (m_devnumMonitor) { diff --git a/src/src/mainwindow.h b/src/src/mainwindow.h index d76d46a3..ec7d32c9 100644 --- a/src/src/mainwindow.h +++ b/src/src/mainwindow.h @@ -201,6 +201,11 @@ class CMainWindow : public DMainWindow */ void getMediaFileInfoList(const QString &path, QFileInfoList &fileList); + /** + * @brief 检测分辨率是否太高,8K分辨率不显示录像功能 + */ + bool checkResolutionTooHigh() const; + private slots: /** * @brief setSelBtnHide 设置切换相机按钮隐藏 diff --git a/src/src/rollingbox.cpp b/src/src/rollingbox.cpp index 62107ec3..f29e3dfa 100644 --- a/src/src/rollingbox.cpp +++ b/src/src/rollingbox.cpp @@ -301,3 +301,10 @@ void RollingBox::setDeviation(int n) update(); } +void RollingBox::reset() +{ + m_currentIndex = m_rangeMin; + m_deviation = 0; + emit currentValueChanged(m_currentIndex); + update(); +} diff --git a/src/src/rollingbox.h b/src/src/rollingbox.h index 3e381e95..c323a865 100644 --- a/src/src/rollingbox.h +++ b/src/src/rollingbox.h @@ -36,6 +36,11 @@ class RollingBox : public QWidget */ int getCurrentValue(); + /** + * @brief 重置至初始位置 + */ + void reset(); + protected: /** * @brief 鼠标按下事件