Skip to content

fix(camera): keep shutter audio stream active - #508

Closed
Resurgamz wants to merge 2 commits into
linuxdeepin:release/eaglefrom
Resurgamz:fix/shutter-sound-keepalive-upstream
Closed

fix(camera): keep shutter audio stream active#508
Resurgamz wants to merge 2 commits into
linuxdeepin:release/eaglefrom
Resurgamz:fix/shutter-sound-keepalive-upstream

Conversation

@Resurgamz

@Resurgamz Resurgamz commented Jul 30, 2026

Copy link
Copy Markdown

Summary

  • Replace Qt 5 QSound shutter playback with QSoundEffect.
  • Keep a muted looping effect active while shutter sound is enabled.
  • Apply shutter sound setting changes immediately and preserve a pending first shutter.

Verification

  • cmake --build obj-x86_64-linux-gnu --target deepin-camera -- -j2

PMS: https://pms.uniontech.com/bug-view-369937.html

Summary by Sourcery

Replace the camera shutter sound implementation with a QSoundEffect-based solution and keep a muted looping audio stream active to ensure reliable shutter playback when enabled.

New Features:

  • Add a dedicated shutter sound enable/disable API on videowidget and wire it to the global settings change signal.
  • Introduce a looping muted QSoundEffect instance to keep the shutter audio stream active and allow pending shutter playback when ready.

Bug Fixes:

  • Ensure shutter sound setting changes take effect immediately and preserve the first shutter request until the audio stream is ready.
  • Prevent shutter sound playback failures by maintaining an active audio stream and handling QSoundEffect error states.

Enhancements:

  • Refine shutter sound lifecycle management, including initialization, playback coordination, and proper cleanup in videowidget.

Replace QSound with QSoundEffect for shutter playback. Keep a muted\nlooping effect active while shutter sound is enabled to prevent the\naudio backend from entering idle suspension.\n\n使用 QSoundEffect 播放快门音。快门音开启时保持静音循环音效运行,\n避免音频后端空闲挂起。\n\nLog: 修复快门音空闲后首次播放音量偏小的问题\nPMS: https://pms.uniontech.com/bug-view-369937.html\nInfluence: 关闭后重新开启或长时间未拍照后,首次快门声音量保持正常。

@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.

Sorry @Resurgamz, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@sourcery-ai

sourcery-ai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Reviewer's Guide

Replaces QSound with QSoundEffect for shutter playback, adds a muted looping keepalive stream to keep the audio path active, introduces state-tracking for shutter sound enablement/pending playback, and wires the shutter sound setting changes through Settings/MainWindow into videowidget so they apply immediately.

Sequence diagram for shutter sound playback with keepalive stream

sequenceDiagram
    actor User
    participant videowidget
    participant QSoundEffect_takePic as QSoundEffect_takePic
    participant QSoundEffect_keepalive as QSoundEffect_keepalive

    User->>videowidget: flash()
    videowidget->>videowidget: get_sound_of_takeing_photo()
    alt shutter_sound_enabled
        alt keepalive_playing && takePic_ready
            videowidget->>QSoundEffect_takePic: play()
        else keepalive_not_ready
            videowidget->>videowidget: m_shutterSoundPending = true
            videowidget->>videowidget: ensureShutterSoundKeepalive()
            videowidget->>QSoundEffect_keepalive: play()
        end
    end

    QSoundEffect_takePic->>videowidget: statusChanged()
    alt takePic_status == Error
        videowidget->>videowidget: m_shutterSoundPending = false
    else takePic_status == Ready
        videowidget->>videowidget: playPendingShutterSound()
        videowidget->>QSoundEffect_takePic: play()
    end

    QSoundEffect_keepalive->>videowidget: statusChanged()
    alt keepalive_status == Error
        videowidget->>videowidget: m_shutterSoundPending = false
    else keepalive_status == Ready
        videowidget->>videowidget: ensureShutterSoundKeepalive()
        videowidget->>QSoundEffect_keepalive: play()
    end

    QSoundEffect_keepalive->>videowidget: playingChanged()
    videowidget->>videowidget: ensureShutterSoundKeepalive()
    videowidget->>videowidget: playPendingShutterSound()
Loading

File-Level Changes

Change Details Files
Switch shutter playback from QSound to QSoundEffect and add a muted looping keepalive effect to keep the audio stream active.
  • Instantiate m_takePicSound as QSoundEffect, configure source, loop count, volume, and connect statusChanged to a new handler.
  • Add m_shutterSoundKeepalive QSoundEffect instance configured as an infinite, muted loop of the shutter audio, with statusChanged and playingChanged handlers.
  • Ensure both sound effects are stopped and deleted in videowidget destructor.
src/src/videowidget.cpp
src/src/videowidget.h
Introduce shutter sound enablement and pending playback logic so setting changes take effect immediately and the first shutter is preserved.
  • Add setShutterSoundEnabled(bool) to update internal flags, call existing set_takeing_photo_sound, and start/stop keepalive playback as appropriate.
  • Implement ensureShutterSoundKeepalive(), playPendingShutterSound(), and Qt slot handlers to manage ready/error states and trigger pending shutter playback when the audio path is ready.
  • Modify flash() to either play the shutter sound immediately when ready or mark it as pending and start/ensure the keepalive loop.
src/src/videowidget.cpp
src/src/videowidget.h
Wire shutter sound configuration changes from Settings into videowidget and emit a dedicated signal when the shutter sound option changes.
  • Connect Settings::shutterSoundEnabledChanged to videowidget::setShutterSoundEnabled in CMainWindow::initUI.
  • Replace direct set_takeing_photo_sound() calls with m_videoPre->setShutterSoundEnabled(soundphoto) in CMainWindow initialization and settings close handling.
  • Emit shutterSoundEnabledChanged(bool) from Settings::onValueChanged when the soundswitchbtn key changes, and declare the corresponding signal in Settings.h.
src/src/mainwindow.cpp
src/src/Settings.cpp
src/src/Settings.h

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

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:95分

■ 【总体评价】

代码通过引入QSoundEffect和keepalive机制有效解决了快门声音播放延迟的问题,逻辑严谨且生命周期管理正确。
机制设计合理,未引入安全风险,仅在功耗方面有轻微业务权衡,整体质量优秀。

■ 【详细分析】

  • 1.语法逻辑 完全正确 ✓

代码将QSound替换为QSoundEffect,在videowidget构造函数中正确初始化了m_takePicSound和m_shutterSoundKeepalive,并绑定了相应的状态改变信号。flash()函数中的条件判断逻辑清晰,pending状态管理正确。析构函数中正确停止并删除了新增的音频对象,避免了内存泄漏。
潜在问题:无
建议:无

  • 2.代码质量 良好 ✓

代码结构清晰,命名规范,如ensureShutterSoundKeepalive和playPendingShutterSound准确表达了函数意图。Settings类中新增的信号传递了设置变更,降低了模块间的耦合。注释和代码风格保持了项目一致性。
潜在问题:keepalive机制虽然解决了延迟,但持续占用音频后端可能对部分环境下的资源调度产生影响。
建议:可考虑在应用失去焦点或长时间未拍照时释放keepalive资源,以进一步优化资源占用。

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

通过静音循环播放QSoundEffect保持音频后端活跃,以极小的资源开销换取了首音播放的及时性,符合业务需求。状态变更回调机制避免了轮询检查,性能表现良好。
潜在问题:持续播放静音音频会增加微小的CPU和音频设备功耗。
建议:在非拍照模式或应用最小化时,可考虑暂停keepalive播放。

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

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
本次代码变更未引入任何安全漏洞,资源生命周期管理规范,无外部输入注入风险。

  • 建议:无需针对安全进行修复。

■ 【改进建议代码示例】

// 建议在应用失去焦点或进入空闲状态时优化keepalive资源占用
void videowidget::onApplicationStateChanged(Qt::ApplicationState state)
{
    if (state != Qt::ApplicationActive) {
        // 应用非活跃时停止keepalive以节省资源
        if (m_shutterSoundKeepalive->isPlaying()) {
            m_shutterSoundKeepalive->stop();
        }
    } else {
        // 应用恢复活跃时重新确保keepalive
        if (m_shutterSoundEnabled) {
            ensureShutterSoundKeepalive();
        }
    }
}

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Resurgamz

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

@Resurgamz

Copy link
Copy Markdown
Author

Closing this PR because the continuous keepalive approach was reverted after power-impact evaluation. A lower-power on-demand warmup design will be proposed separately.

@Resurgamz Resurgamz closed this Jul 30, 2026
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.

2 participants