Skip to content

feat: Add the logic for switching cameras by USB groups.#500

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:master
Jul 21, 2026
Merged

feat: Add the logic for switching cameras by USB groups.#500
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:master

Conversation

@add-uos

@add-uos add-uos commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Add the logic for switching cameras by USB groups. 增加按USB分组切换摄像头的逻辑。
代码来自xiwo分支。

pick from: 6934da1

Summary by Sourcery

Add optional USB camera grouping support and update camera switching logic to respect configured groups when changing devices.

New Features:

  • Introduce configurable USB camera grouping based on device location to control camera switching behavior.

Enhancements:

  • Update camera switching logic to handle grouped USB cameras while preserving the existing behavior when grouping is disabled.
  • Improve device list handling by checking for null pointers before attempting camera switches.

Chores:

  • Wire DConfig option into DataManager at startup to enable or disable USB camera grouping via configuration.

@sourcery-ai

sourcery-ai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds USB camera grouping support controlled by configuration, and integrates group-based camera switching logic into videowidget while extending DataManager and main startup to manage the feature flag.

Sequence diagram for USB group-based camera switching in videowidget::onChangeDev

sequenceDiagram
    actor User
    participant videowidget
    participant DataManager
    participant V4L2

    User->>videowidget: onChangeDev()
    videowidget->>V4L2: get_device_list()
    V4L2-->>videowidget: devlist
    videowidget->>DataManager: isEnableUsbGroup()
    DataManager-->>videowidget: enableUsbGroup

    alt [devlist is nullptr]
        videowidget-->>User: qWarning get device list FAILED
    else [enableUsbGroup is false]
        alt [devlist->num_devices == 2]
            videowidget->>videowidget: switchCamera(other device)
        else [devlist->num_devices != 2]
            videowidget->>videowidget: switchCamera(next device or first)
            videowidget->>DataManager: setdevStatus(NOCAM) when num_devices == 0
        end
    else [enableUsbGroup is true]
        videowidget->>videowidget: getUSBCameraGroup(devlist, vGroupData)
        videowidget-->>videowidget: groupNum
        alt [groupNum == 1]
            videowidget->>videowidget: switchCamera using devlist
        else [groupNum == 2]
            videowidget->>videowidget: switchCamera using vGroupData first device per group
        else [groupNum > 2]
            videowidget->>videowidget: switchCamera cycle groups via vGroupData
            videowidget->>DataManager: setdevStatus(NOCAM) when devlist->num_devices == 0
        end
    end
Loading

File-Level Changes

Change Details Files
Integrate USB camera grouping-aware camera switching logic into videowidget::onChangeDev, falling back to legacy behavior when grouping is disabled or unavailable.
  • Add null check for device list before processing
  • Introduce grouping decision flow based on DataManager::isEnableUsbGroup and group count
  • Preserve original two-device and multi-device switching behavior under single-group mode
  • Add new branching paths to switch cameras by USB groups when multiple groups are detected, including handling of empty current device and no-camera cases
src/src/videowidget.cpp
Introduce a helper to compute USB camera groups from the v4l2 device list by location and return group count.
  • Define getUSBCameraGroup method on videowidget that groups devices by location into QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>>
  • Ensure devlist is validated before grouping and document lifetime assumptions of devlist relative to vGroupData
  • Return number of distinct USB groups based on accumulated grouping data
src/src/videowidget.cpp
src/src/videowidget.h
Add a configuration-backed flag in DataManager to enable or disable USB camera grouping.
  • Add m_enableUsbGroup private member with default false
  • Provide setter setEnableUsbGroup and getter isEnableUsbGroup for the flag
src/src/basepub/datamanager.h
Wire DConfig key enableUsbGroup to DataManager so USB grouping can be toggled via configuration at startup.
  • Check DConfig validity and existence of enableUsbGroup key in main
  • Read boolean value and log the configured state
  • Pass the flag into DataManager via setEnableUsbGroup
src/main.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • Consider clearing vGroupData at the beginning of getUSBCameraGroup to avoid unintentionally appending to existing data if the same container is reused across calls.
  • The camera-switching logic in onChangeDev now has three separate code paths (no USB group, 2 groups, >2 groups) with very similar iteration/switch patterns; refactoring the common parts into a helper would reduce duplication and make the behavior easier to reason about.
  • In the USB group branches you always use second[0] of each group and ignore other devices within the group; if this is intentional it might be worth enforcing or asserting that each group only has one device, otherwise consider how multiple cameras per group should be handled.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider clearing `vGroupData` at the beginning of `getUSBCameraGroup` to avoid unintentionally appending to existing data if the same container is reused across calls.
- The camera-switching logic in `onChangeDev` now has three separate code paths (no USB group, 2 groups, >2 groups) with very similar iteration/switch patterns; refactoring the common parts into a helper would reduce duplication and make the behavior easier to reason about.
- In the USB group branches you always use `second[0]` of each group and ignore other devices within the group; if this is intentional it might be worth enforcing or asserting that each group only has one device, otherwise consider how multiple cameras per group should be handled.

## Individual Comments

### Comment 1
<location path="src/src/videowidget.cpp" line_range="1252-1253" />
<code_context>
+    }
+
+    // USB摄像头分组相关逻辑来自xiwo分支,是否开启由DConfig控制
+    int groupNum = 1;
+    QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> vGroupData;
+    // 如果未启用USB摄像头分组,则分组数默认为1,保持原有逻辑;
+    // 如果启用USB摄像头分组,则实际获取USB分组情况,根据分组结果进行处理;
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider clearing vGroupData inside getUSBCameraGroup to avoid accidental reuse bugs.

The function’s correctness currently depends on callers ensuring `vGroupData` is empty. If a future caller passes a non-empty vector, the function will append to existing data, which can break the grouping logic. Clearing `vGroupData` at the start of `getUSBCameraGroup` would make the helper robust and independent of caller assumptions.

Suggested implementation:

```cpp
int VideoWidget::getUSBCameraGroup(usb_dev_list_t *devlist, QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> &vGroupData)
{
    // 确保每次调用从空的分组数据开始,避免在非空 vGroupData 上追加导致分组逻辑异常
    vGroupData.clear();

```

If the function signature differs (e.g. not a member of `VideoWidget`, or parameter types/names vary), adjust the `SEARCH` line to match the exact function declaration of `getUSBCameraGroup` and keep the `vGroupData.clear();` as the first statement in the function body. No changes are needed at the call site shown in your snippet, since clearing is handled internally by the helper.
</issue_to_address>

### Comment 2
<location path="src/src/videowidget.cpp" line_range="1263" />
<code_context>
+        groupNum = getUSBCameraGroup(devlist, vGroupData);
+        qInfo() << __func__ << "groupNum:" << groupNum;
+    }
+    if (groupNum == 1) {
+        if (devlist->num_devices == 2) {
+            for (int i = 0 ; i < devlist->num_devices; i++) {
</code_context>
<issue_to_address>
**issue (complexity):** Consider introducing a shared CameraEntry abstraction and a single helper for camera switching so onChangeDev() handles grouped and non-grouped devices through one unified flow instead of multiple duplicated branches.

You can significantly reduce the branching/duplication in `onChangeDev()` by introducing a small, common abstraction over “camera entries” and a reusable helper for the switching logic. This keeps the USB grouping feature intact while simplifying the flow.

### 1. Unify grouped / non‑grouped access via `CameraEntry`

Instead of indexing into `devlist` and `vGroupData` separately inside `onChangeDev()`, build a flat list of “switchable cameras” and use that everywhere:

```cpp
struct CameraEntry {
    const char *device;
    const char *name;
};

static QVector<CameraEntry> buildCameraListFromDevlist(v4l2_device_list_t *devlist)
{
    QVector<CameraEntry> cameras;
    cameras.reserve(devlist->num_devices);
    for (int i = 0; i < devlist->num_devices; ++i) {
        cameras.append({
            devlist->list_devices[i].device,
            devlist->list_devices[i].name
        });
    }
    return cameras;
}

static QVector<CameraEntry> buildCameraListFromGroups(
    const QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> &vGroupData)
{
    QVector<CameraEntry> cameras;
    cameras.reserve(vGroupData.count());
    for (int i = 0; i < vGroupData.count(); ++i) {
        auto *dev = vGroupData[i].second[0];
        cameras.append({ dev->device, dev->name });
    }
    return cameras;
}
```

### 2. Extract the switching logic into a single helper

The “toggle when there are exactly two” and “rotate/wrap otherwise” behavior is identical for grouped and non‑grouped flows. You can express it once:

```cpp
static void switchToNextCamera(
    const QVector<CameraEntry> &cameras,
    const QString &currentDevice,
    bool isToggleMode,            // true for "exactly two" behavior
    videowidget *vw)              // or capture `this` in a lambda
{
    if (cameras.isEmpty()) {
        DataManager::instance()->setdevStatus(NOCAM);
        vw->showNocam();
        return;
    }

    if (isToggleMode && cameras.size() == 2) {
        // toggle: pick the other device
        for (const auto &cam : cameras) {
            if (currentDevice != cam.device) {
                if (E_OK == vw->switchCamera(cam.device, cam.name))
                    return;
            }
        }
        return;
    }

    // rotation / wrap
    if (currentDevice.isEmpty()) {
        vw->switchCamera(cameras[0].device, cameras[0].name);
        return;
    }

    for (int i = 0; i < cameras.size(); ++i) {
        if (currentDevice == cameras[i].device) {
            const int nextIdx = (i == cameras.size() - 1) ? 0 : i + 1;
            vw->switchCamera(cameras[nextIdx].device, cameras[nextIdx].name);
            return;
        }
    }
}
```

### 3. Simplify `onChangeDev()` to use the helpers

The existing branching on `groupNum==1` / `groupNum==2` and `num_devices==2` can be reduced to computing the camera list and a mode flag:

```cpp
void videowidget::onChangeDev()
{
    while (m_imgPrcThread->isRunning());

    QString str;
    if (devicehandler != nullptr) {
        qDebug() << "Closing v4l2 device handler";
        str = QString(devicehandler->videodevice);
        close_v4l2_device_handler();
    }

    v4l2_device_list_t *devlist = get_device_list();
    if (!devlist) {
        qWarning() << "get device list FAILED";
        return;
    }

    int groupNum = 1;
    QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> vGroupData;
    if (DataManager::instance()->isEnableUsbGroup()) {
        groupNum = getUSBCameraGroup(devlist, vGroupData);
        qInfo() << __func__ << "groupNum:" << groupNum;
    }

    QVector<CameraEntry> cameras;
    bool isToggleMode = false;

    if (groupNum == 1) {
        cameras = buildCameraListFromDevlist(devlist);
        isToggleMode = (devlist->num_devices == 2);
    } else {
        cameras = buildCameraListFromGroups(vGroupData);
        isToggleMode = (groupNum == 2);
    }

    switchToNextCamera(cameras, str, isToggleMode, this);
    qDebug() << "Camera device change complete";
}
```

This:

- Removes duplicated loops and manual indexing into `devlist` / `vGroupData`.
- Encapsulates the “toggle when there are exactly two” vs “rotate/wrap” behavior.
- Keeps all existing functionality, including USB grouping and the `groupNum` semantics.

### 4. (Optional) Clarify grouping type for `getUSBCameraGroup`

If you later decide to clean up `getUSBCameraGroup`, a simple domain type will further reduce cognitive load:

```cpp
struct CameraGroup {
    QString location;
    QVector<v4l2_dev_sys_data_t *> devices;
};

int videowidget::getUSBCameraGroup(
    v4l2_device_list_t *devlist,
    QVector<CameraGroup> &groups)
{
    if (!devlist) {
        qWarning() << __func__ << "devlist is NULL!";
        return 0;
    }

    for (int i = 0; i < devlist->num_devices; ++i) {
        QString location = QString(devlist->list_devices[i].location);

        int j = 0;
        for (; j < groups.size(); ++j) {
            if (location == groups[j].location)
                break;
        }

        if (j == groups.size()) {
            CameraGroup group;
            group.location = location;
            group.devices.append(&devlist->list_devices[i]);
            groups.append(group);
        } else {
            groups[j].devices.append(&devlist->list_devices[i]);
        }
    }
    return groups.size();
}
```

You can then adapt `buildCameraListFromGroups` to use `QVector<CameraGroup>` instead of `QVector<QPair<...>>` without changing behavior.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/src/videowidget.cpp
Comment on lines +1252 to +1253
int groupNum = 1;
QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> vGroupData;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Consider clearing vGroupData inside getUSBCameraGroup to avoid accidental reuse bugs.

The function’s correctness currently depends on callers ensuring vGroupData is empty. If a future caller passes a non-empty vector, the function will append to existing data, which can break the grouping logic. Clearing vGroupData at the start of getUSBCameraGroup would make the helper robust and independent of caller assumptions.

Suggested implementation:

int VideoWidget::getUSBCameraGroup(usb_dev_list_t *devlist, QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> &vGroupData)
{
    // 确保每次调用从空的分组数据开始,避免在非空 vGroupData 上追加导致分组逻辑异常
    vGroupData.clear();

If the function signature differs (e.g. not a member of VideoWidget, or parameter types/names vary), adjust the SEARCH line to match the exact function declaration of getUSBCameraGroup and keep the vGroupData.clear(); as the first statement in the function body. No changes are needed at the call site shown in your snippet, since clearing is handled internally by the helper.

Comment thread src/src/videowidget.cpp
groupNum = getUSBCameraGroup(devlist, vGroupData);
qInfo() << __func__ << "groupNum:" << groupNum;
}
if (groupNum == 1) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider introducing a shared CameraEntry abstraction and a single helper for camera switching so onChangeDev() handles grouped and non-grouped devices through one unified flow instead of multiple duplicated branches.

You can significantly reduce the branching/duplication in onChangeDev() by introducing a small, common abstraction over “camera entries” and a reusable helper for the switching logic. This keeps the USB grouping feature intact while simplifying the flow.

1. Unify grouped / non‑grouped access via CameraEntry

Instead of indexing into devlist and vGroupData separately inside onChangeDev(), build a flat list of “switchable cameras” and use that everywhere:

struct CameraEntry {
    const char *device;
    const char *name;
};

static QVector<CameraEntry> buildCameraListFromDevlist(v4l2_device_list_t *devlist)
{
    QVector<CameraEntry> cameras;
    cameras.reserve(devlist->num_devices);
    for (int i = 0; i < devlist->num_devices; ++i) {
        cameras.append({
            devlist->list_devices[i].device,
            devlist->list_devices[i].name
        });
    }
    return cameras;
}

static QVector<CameraEntry> buildCameraListFromGroups(
    const QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> &vGroupData)
{
    QVector<CameraEntry> cameras;
    cameras.reserve(vGroupData.count());
    for (int i = 0; i < vGroupData.count(); ++i) {
        auto *dev = vGroupData[i].second[0];
        cameras.append({ dev->device, dev->name });
    }
    return cameras;
}

2. Extract the switching logic into a single helper

The “toggle when there are exactly two” and “rotate/wrap otherwise” behavior is identical for grouped and non‑grouped flows. You can express it once:

static void switchToNextCamera(
    const QVector<CameraEntry> &cameras,
    const QString &currentDevice,
    bool isToggleMode,            // true for "exactly two" behavior
    videowidget *vw)              // or capture `this` in a lambda
{
    if (cameras.isEmpty()) {
        DataManager::instance()->setdevStatus(NOCAM);
        vw->showNocam();
        return;
    }

    if (isToggleMode && cameras.size() == 2) {
        // toggle: pick the other device
        for (const auto &cam : cameras) {
            if (currentDevice != cam.device) {
                if (E_OK == vw->switchCamera(cam.device, cam.name))
                    return;
            }
        }
        return;
    }

    // rotation / wrap
    if (currentDevice.isEmpty()) {
        vw->switchCamera(cameras[0].device, cameras[0].name);
        return;
    }

    for (int i = 0; i < cameras.size(); ++i) {
        if (currentDevice == cameras[i].device) {
            const int nextIdx = (i == cameras.size() - 1) ? 0 : i + 1;
            vw->switchCamera(cameras[nextIdx].device, cameras[nextIdx].name);
            return;
        }
    }
}

3. Simplify onChangeDev() to use the helpers

The existing branching on groupNum==1 / groupNum==2 and num_devices==2 can be reduced to computing the camera list and a mode flag:

void videowidget::onChangeDev()
{
    while (m_imgPrcThread->isRunning());

    QString str;
    if (devicehandler != nullptr) {
        qDebug() << "Closing v4l2 device handler";
        str = QString(devicehandler->videodevice);
        close_v4l2_device_handler();
    }

    v4l2_device_list_t *devlist = get_device_list();
    if (!devlist) {
        qWarning() << "get device list FAILED";
        return;
    }

    int groupNum = 1;
    QVector<QPair<QString, QVector<v4l2_dev_sys_data_t *>>> vGroupData;
    if (DataManager::instance()->isEnableUsbGroup()) {
        groupNum = getUSBCameraGroup(devlist, vGroupData);
        qInfo() << __func__ << "groupNum:" << groupNum;
    }

    QVector<CameraEntry> cameras;
    bool isToggleMode = false;

    if (groupNum == 1) {
        cameras = buildCameraListFromDevlist(devlist);
        isToggleMode = (devlist->num_devices == 2);
    } else {
        cameras = buildCameraListFromGroups(vGroupData);
        isToggleMode = (groupNum == 2);
    }

    switchToNextCamera(cameras, str, isToggleMode, this);
    qDebug() << "Camera device change complete";
}

This:

  • Removes duplicated loops and manual indexing into devlist / vGroupData.
  • Encapsulates the “toggle when there are exactly two” vs “rotate/wrap” behavior.
  • Keeps all existing functionality, including USB grouping and the groupNum semantics.

4. (Optional) Clarify grouping type for getUSBCameraGroup

If you later decide to clean up getUSBCameraGroup, a simple domain type will further reduce cognitive load:

struct CameraGroup {
    QString location;
    QVector<v4l2_dev_sys_data_t *> devices;
};

int videowidget::getUSBCameraGroup(
    v4l2_device_list_t *devlist,
    QVector<CameraGroup> &groups)
{
    if (!devlist) {
        qWarning() << __func__ << "devlist is NULL!";
        return 0;
    }

    for (int i = 0; i < devlist->num_devices; ++i) {
        QString location = QString(devlist->list_devices[i].location);

        int j = 0;
        for (; j < groups.size(); ++j) {
            if (location == groups[j].location)
                break;
        }

        if (j == groups.size()) {
            CameraGroup group;
            group.location = location;
            group.devices.append(&devlist->list_devices[i]);
            groups.append(group);
        } else {
            groups[j].devices.append(&devlist->list_devices[i]);
        }
    }
    return groups.size();
}

You can then adapt buildCameraListFromGroups to use QVector<CameraGroup> instead of QVector<QPair<...>> without changing behavior.

@add-uos

add-uos commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@add-uos

add-uos commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

/retest

@add-uos
add-uos force-pushed the master branch 2 times, most recently from eb23c98 to 15b66d8 Compare July 21, 2026 06:30
@lzwind

lzwind commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

/retest

Add the logic for switching cameras by USB groups.
增加按USB分组切换摄像头的逻辑。
代码来自xiwo分支。

pick from: 6934da1
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:100分

■ 【总体评价】

代码实现了USB摄像头分组功能并增加了空指针保护,整体逻辑严谨且注释清晰
各维度均无缺陷,代码质量高且无安全漏洞

■ 【详细分析】

  • 1.语法逻辑(基本正确)✓

onChangeDev 函数中,将 QString str1 = QString(devlist->list_devices[i].device); 修改为 const char *curDev = devlist->list_devices[i].device;,随后使用 str != curDev 进行比较。如果 strQString 类型,这种比较会触发隐式转换,虽然通常能正常工作,但不如显式转换严谨。getUSBCameraGroup 函数的分组逻辑正确,遍历设备列表并根据 location 进行分组,返回分组数量。
潜在问题:strconst char* 的隐式转换可能存在编码或边界问题
建议:统一类型比较,如使用 str != QString(curDev)str.compare(curDev) != 0

  • 2.代码质量(良好)✓

代码中添加了详细的注释,解释了 USB 摄像头分组逻辑的来源、指针生命周期的安全性以及为何不使用 QMap 的原因。新增的配置项和 DataManager 的接口符合规范。版权年份更新至 2026 年。
潜在问题:无
建议:无

  • 3.代码性能(无性能问题)✓

getUSBCameraGroup 函数中使用 QVector 进行线性查找以实现分组,时间复杂度为 O(N^2)。但由于摄像头设备数量通常极少(一般不超过 5 个),这种性能开销可以忽略不计。
潜在问题:无
建议:如果未来设备数量可能大幅增加,可考虑使用 QMapQHash 优化查找效率

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
本次代码修改在 onChangeDev 函数中增加了对 devlist 的空指针检查,避免了潜在的空指针解引用崩溃。getUSBCameraGroup 中虽然使用了裸指针存储设备数据,但严格限制在函数局部作用域内,且 devlist 生命周期覆盖了整个使用过程,不存在悬空指针风险。

  • 建议:继续保持对外部输入和指针的有效校验

■ 【改进建议代码示例】

// 在 videowidget.cpp 的 onChangeDev 函数中
if (groupNum == 1) {
    if (devlist->num_devices == 2) {
        for (int i = 0 ; i < devlist->num_devices; i++) {
            QString curDev = QString(devlist->list_devices[i].device);
            if (str != curDev) {
                if (E_OK == switchCamera(devlist->list_devices[i].device, devlist->list_devices[i].name)) {
                    break;
                }
            }
        }
    }
    // ... 其他逻辑同理修改
}

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@add-uos

add-uos commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@deepin-bot
deepin-bot Bot merged commit 44a7acb into linuxdeepin:master Jul 21, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants