Skip to content

feat(mpv): prioritize gpuinfo VO recommendation in AUTO decode mode#841

Merged
wyu71 merged 1 commit intolinuxdeepin:masterfrom
wyu71:master
Apr 9, 2026
Merged

feat(mpv): prioritize gpuinfo VO recommendation in AUTO decode mode#841
wyu71 merged 1 commit intolinuxdeepin:masterfrom
wyu71:master

Conversation

@wyu71
Copy link
Copy Markdown
Contributor

@wyu71 wyu71 commented Apr 9, 2026

Use gpuinfo_get_vo() from libgpuinfo to get recommended video output for current GPU, overriding heuristic result in AUTO decode mode.

在自动解码模式下,优先使用gpuinfo提供的VO配置,覆盖硬件启发式判断。

Log: 自动解码模式优先使用gpuinfo的VO配置
PMS: BUG-356131
Influence: 当gpuinfo数据库中配置了GPU的推荐VO时,自动解码模式将优先使用该配置,提升特定GPU的兼容性。

Summary by Sourcery

Prioritize libgpuinfo's recommended video output (VO) in mpv's AUTO decode mode when available.

New Features:

  • Use gpuinfo_get_vo from libgpuinfo to set the initial VO in AUTO decode mode when a recommendation exists.

Enhancements:

  • Initialize and manage a new gpuinfo VO function pointer alongside existing GPU info integration to support VO recommendations.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 9, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Integrates a new gpuinfo_get_vo function pointer into MpvProxy so that in AUTO decode mode, mpv prioritizes the VO (video output) recommended by libgpuinfo over the existing heuristic, while ensuring proper initialization and null-handling of the new function pointer.

Sequence diagram for AUTO decode VO selection with gpuinfo_get_vo

sequenceDiagram
    actor User
    participant Application
    participant MpvProxy
    participant LibGpuInfo as libgpuinfo_so
    participant MpvCore as mpv_core

    User ->> Application: Start playback
    Application ->> MpvProxy: mpv_init()
    activate MpvProxy

    MpvProxy ->> MpvProxy: initGpuInfoFuns()
    alt libgpuinfo.so exists
        MpvProxy ->> LibGpuInfo: resolve vdp_Iter_decoderInfo
        MpvProxy ->> LibGpuInfo: resolve gpuinfo_get_vo
        MpvProxy ->> MpvProxy: store m_gpuInfo and m_gpuInfoVo
    else libgpuinfo.so missing
        MpvProxy ->> MpvProxy: set m_gpuInfo = NULL
        MpvProxy ->> MpvProxy: set m_gpuInfoVo = NULL
    end

    MpvProxy ->> MpvCore: create mpv_handle

    MpvProxy ->> MpvProxy: check m_decodeMode
    alt DecodeMode AUTO
        MpvProxy ->> MpvCore: my_set_property(vo, heuristic_vo)
        MpvProxy ->> MpvProxy: m_sInitVo = heuristic_vo
        alt m_gpuInfoVo is not NULL
            MpvProxy ->> LibGpuInfo: gpuinfo_get_vo()
            LibGpuInfo -->> MpvProxy: vo
            alt vo is non empty
                MpvProxy ->> MpvCore: my_set_property(vo, vo)
                MpvProxy ->> MpvProxy: m_sInitVo = vo
            end
        end
    else DecodeMode HARDWARE or SOFTWARE
        MpvProxy ->> MpvCore: set vo based on other logic
    end

    MpvProxy -->> Application: return initialized mpv_handle
    deactivate MpvProxy
    Application ->> MpvCore: start playback
Loading

Class diagram for MpvProxy updates with gpuinfo_get_vo integration

classDiagram
    class MpvProxy {
        // Members
        void* m_gpuInfo
        void* m_gpuInfoVo
        MpvHandle m_handle
        QString m_sInitVo
        DecodeMode m_decodeMode

        // Methods
        void initGpuInfoFuns()
        mpv_handle* mpv_init()
        void initMember()
        void play()
    }

    class LibGpuInfo {
        <<library>>
        const char* vdp_Iter_decoderInfo()
        const char* gpuinfo_get_vo()
    }

    class MpvCore {
        <<library>>
        void my_set_property(mpv_handle* handle, const char* name, const char* value)
    }

    MpvProxy ..> LibGpuInfo : dynamic_link
    MpvProxy ..> MpvCore : uses

    class DecodeMode {
        <<enum>>
        AUTO
        HARDWARE
        SOFTWARE
    }

    MpvProxy --> DecodeMode
Loading

Flow diagram for AUTO decode VO selection priority

flowchart TD
    A["Start mpv_init in AUTO decode mode"] --> B["Set VO using existing heuristic"]
    B --> C{"Is m_gpuInfoVo non NULL?"}

    C -- "No" --> F["Keep heuristic VO"]

    C -- "Yes" --> D["Call gpuinfo_get_vo() to get vo"]
    D --> E{"Is vo non empty?"}

    E -- "No" --> F
    E -- "Yes" --> G["Set VO to gpuinfo recommended vo"]

    F --> H["m_sInitVo reflects final VO"]
    G --> H
    H --> I["Return initialized mpv_handle"]
Loading

File-Level Changes

Change Details Files
Wire up gpuinfo_get_vo from libgpuinfo and store it in MpvProxy for later use.
  • Extend initGpuInfoFuns to resolve the gpuinfo_get_vo symbol from libgpuinfo.so via QLibrary.
  • Ensure both m_gpuInfo and the new VO function pointer are null-initialized when libgpuinfo.so is missing.
  • Add a new void* member in MpvProxy to hold the gpuinfo_get_vo function pointer.
src/backends/mpv/mpv_proxy.cpp
src/backends/mpv/mpv_proxy.h
Apply gpuinfo-provided VO recommendation in AUTO decode mode, overriding heuristic VO selection when available.
  • In mpv_init, after the existing AUTO-mode heuristic VO selection, call the gpuinfo_get_vo function if available.
  • If gpuinfo_get_vo returns a non-empty string, log the recommended VO and set mpv's 'vo' property and m_sInitVo to that value, overriding any prior AUTO-mode choice.
  • Limit the gpuinfo VO override logic strictly to AUTO decode mode, leaving HARDWARE mode behavior unchanged.
src/backends/mpv/mpv_proxy.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

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

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:

  • Storing function pointers from a QLibrary that is created as a local variable in initGpuInfoFuns() is risky because the library may be unloaded when the QLibrary object goes out of scope; consider making the QLibrary a member (or disabling auto-unload) so m_gpuInfo/m_gpuInfoVo remain valid when used later in mpv_init().
  • Since the gpuinfo VO is only meaningful in AUTO decode mode, it may be safer to guard the m_gpuInfoVo call with an explicit decode-mode check (and/or log when gpuinfo is available but not used) to make the behavior clearer and avoid accidental use under other modes in future refactors.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Storing function pointers from a QLibrary that is created as a local variable in `initGpuInfoFuns()` is risky because the library may be unloaded when the QLibrary object goes out of scope; consider making the QLibrary a member (or disabling auto-unload) so `m_gpuInfo`/`m_gpuInfoVo` remain valid when used later in `mpv_init()`.
- Since the gpuinfo VO is only meaningful in AUTO decode mode, it may be safer to guard the `m_gpuInfoVo` call with an explicit decode-mode check (and/or log when gpuinfo is available but not used) to make the behavior clearer and avoid accidental use under other modes in future refactors.

## Individual Comments

### Comment 1
<location path="src/backends/mpv/mpv_proxy.cpp" line_range="218" />
<code_context>
     }
     QLibrary mpvLibrary(SysUtils::libPath("libgpuinfo.so"));
     m_gpuInfo = reinterpret_cast<void *>(mpvLibrary.resolve("vdp_Iter_decoderInfo"));
+    m_gpuInfoVo = reinterpret_cast<void *>(mpvLibrary.resolve("gpuinfo_get_vo"));
     qInfo() << "GPU info functions initialized successfully";
 }
</code_context>
<issue_to_address>
**issue (bug_risk):** QLibrary lifetime may invalidate stored function pointers after `initGpuInfoFuns` returns.

Because `QLibrary mpvLibrary` is local to `initGpuInfoFuns`, the library may be unloaded when the function returns, leaving `m_gpuInfo` and `m_gpuInfoVo` as dangling function pointers. This issue already existed for `m_gpuInfo`, and extending it to `m_gpuInfoVo` increases the risk. Please keep a `QLibrary` instance alive (e.g., as a member) for as long as these function pointers are used so they remain valid.
</issue_to_address>

### Comment 2
<location path="src/backends/mpv/mpv_proxy.h" line_range="453" />
<code_context>
     mpvinitialize m_initialize;
     mpv_freeNode_contents m_freeNodecontents;
     void *m_gpuInfo; //解码探测函数指针
+    void *m_gpuInfoVo; //gpuinfo_get_vo函数指针


</code_context>
<issue_to_address>
**suggestion:** Use a typed function pointer instead of `void*` for `m_gpuInfoVo` to avoid repeated unsafe casts.

Because `m_gpuInfoVo` is always used as `const char* (*)(void)`, declare it with that function pointer type instead of `void*`. This removes the need for `reinterpret_cast` at the call site and makes the interface safer and harder to misuse.

Suggested implementation:

```c
    mpvinitialize m_initialize;
    mpv_freeNode_contents m_freeNodecontents;
    void *m_gpuInfo; //解码探测函数指针
    const char* (*m_gpuInfoVo)(void); //gpuinfo_get_vo函数指针

```

1. Wherever `m_gpuInfoVo` is assigned (likely from `mpv_get_wakeup_client`-style APIs or dlsym-like lookups), ensure the right-hand side is cast to `const char* (*)(void)` instead of `void*`, e.g.:
   - Before: `m_gpuInfoVo = reinterpret_cast<void*>(gpuinfo_get_vo);`
   - After: `m_gpuInfoVo = reinterpret_cast<const char* (*)(void)>(gpuinfo_get_vo);` (or preferably no cast if the symbol already has that type).
2. Wherever `m_gpuInfoVo` is used, remove any `reinterpret_cast<const char* (*)(void)>(m_gpuInfoVo)` and call it directly:
   - Before: `auto vo = reinterpret_cast<const char* (*)(void)>(m_gpuInfoVo)();`
   - After: `auto vo = m_gpuInfoVo();`
3. If there are null checks, they remain valid (`if (m_gpuInfoVo) { ... }`) because function pointers are nullable.
</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.

}
QLibrary mpvLibrary(SysUtils::libPath("libgpuinfo.so"));
m_gpuInfo = reinterpret_cast<void *>(mpvLibrary.resolve("vdp_Iter_decoderInfo"));
m_gpuInfoVo = reinterpret_cast<void *>(mpvLibrary.resolve("gpuinfo_get_vo"));
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 (bug_risk): QLibrary lifetime may invalidate stored function pointers after initGpuInfoFuns returns.

Because QLibrary mpvLibrary is local to initGpuInfoFuns, the library may be unloaded when the function returns, leaving m_gpuInfo and m_gpuInfoVo as dangling function pointers. This issue already existed for m_gpuInfo, and extending it to m_gpuInfoVo increases the risk. Please keep a QLibrary instance alive (e.g., as a member) for as long as these function pointers are used so they remain valid.

Use gpuinfo_get_vo() from libgpuinfo to get recommended video output
for current GPU, overriding heuristic result in AUTO decode mode.

在自动解码模式下,优先使用gpuinfo提供的VO配置,覆盖硬件启发式判断。

Log: 自动解码模式优先使用gpuinfo的VO配置
PMS: BUG-356131
Influence: 当gpuinfo数据库中配置了GPU的推荐VO时,自动解码模式将优先使用该配置,提升特定GPU的兼容性。
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, wyu71

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

@wyu71 wyu71 merged commit 2c2fd8a into linuxdeepin:master Apr 9, 2026
17 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.

3 participants