diff --git a/src/platform/camera/v4l2.cpp b/src/platform/camera/v4l2.cpp index b7e031c27..7741dd54d 100644 --- a/src/platform/camera/v4l2.cpp +++ b/src/platform/camera/v4l2.cpp @@ -126,8 +126,10 @@ QVector v4l2::getDeviceModes(QString devName) int error = 0; int fd = deviceOpen(devName, &error); - if (fd < 0 || error != 0) + if (fd < 0 || error != 0) { return modes; + } + v4l2_fmtdesc vfd{}; vfd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -156,10 +158,18 @@ QVector v4l2::getDeviceModes(QString devName) QVector rates = getDeviceModeFramerates(fd, mode.width, mode.height, vfd.pixelformat); + + // insert dummy FPS value to have the mode in the list even if we don't know the FPS + // this fixes support for some webcams, see #5082 + if (rates.isEmpty()) { + rates.append(0.0f); + } + for (float rate : rates) { mode.FPS = rate; - if (!modes.contains(mode)) + if (!modes.contains(mode)) { modes.append(std::move(mode)); + } } vfse.index++; } diff --git a/src/video/cameradevice.cpp b/src/video/cameradevice.cpp index 242e4b9cb..79e9061ff 100644 --- a/src/video/cameradevice.cpp +++ b/src/video/cameradevice.cpp @@ -191,8 +191,9 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode) av_dict_set(&options, "video_size", videoSize.c_str(), 0); av_dict_set(&options, "framerate", framerate.c_str(), 0); const std::string pixelFormatStr = v4l2::getPixelFormatString(mode.pixel_format).toStdString(); - const char* pixel_format = pixelFormatStr.c_str(); - if (strncmp(pixel_format, "unknown", 7) != 0) { + // don't try to set a format string that doesn't exist + if (pixelFormatStr != "unknown" && pixelFormatStr != "invalid") { + const char* pixel_format = pixelFormatStr.c_str(); av_dict_set(&options, "pixel_format", pixel_format, 0); } } diff --git a/src/widget/form/settings/avform.cpp b/src/widget/form/settings/avform.cpp index 00f90c4a6..4c8f947a9 100644 --- a/src/widget/form/settings/avform.cpp +++ b/src/widget/form/settings/avform.cpp @@ -222,6 +222,11 @@ void AVForm::on_videoModescomboBox_currentIndexChanged(int index) void AVForm::selectBestModes(QVector& allVideoModes) { + if (allVideoModes.isEmpty()) { + qCritical() << "Trying to select best mode from empty modes list"; + return; + } + // Identify the best resolutions available for the supposed XXXXp resolutions. std::map idealModes; idealModes[120] = VideoMode(160, 120);