Skip to content

Automatic version selection ignores Dolby Vision: DV-capable TV auto-picks HDR10 among equal-resolution files #239

Description

@Quick104

Summary

Automatic version selection ranks candidates by resolution only, so among two same-resolution files — e.g. a 2160p Dolby Vision file and a 2160p HDR10 file — the winner is decided by list order rather than by which the display can best present. A Dolby-Vision-capable Android TV can auto-play the plain HDR10 file, and because the last-played file is then persisted as the version memory, the mis-pick reinforces itself on the next launch.

This is the Android counterpart of the Apple fix in Silo-Server/silo-apple (fix(player): automatic version selection prefers Dolby Vision on a capable, DV-enabled display, commit 741f15a), filed for parity per the client-alignment policy.

Where

  • shared/src/commonMain/kotlin/org/siloserver/silo/playback/PlaybackVersionSelector.ktselectPlaybackVersion / bestAvailable sort by playbackResolutionRank only; no dynamic-range term and no deterministic tiebreak (equal ranks fall to sortedWith input order).
  • androidTvApp/.../detail/TvDetailVersionSelection.kt (selectTvDetailDisplayVersion) and the phone ItemDetailViewModel selector delegate to the same shared ranker, so the detail label and the play-time pick share the gap.

Reproduction

"How to Train Your Dragon: The Hidden World" (movie-tmdb-166428) has three files: 1080p AVC, 2160p HEVC HDR10 (63058), 2160p x265 Dolby Vision / HDR10+ (74032). With Version = Automatic on a DV-capable TV, selection returns the HDR10 file (63058) rather than the DV file.

Proposed fix (mirror the Apple change)

Add a dynamic-range tiebreak to the shared selector, applied only among equal-resolution candidates so it never overrides resolution or the user's quality cap:

  • + (highest) when the file is Dolby Vision AND the display advertises DV (Display.HdrCapabilities.getSupportedHdrTypes() contains HDR_TYPE_DOLBY_VISION) AND the user's Dolby Vision setting is on;
  • + (middle) for any HDR presentation the display supports (including a DV file's HDR10 base layer when DV itself is unusable);
  • 0 for SDR;
  • break exact ties deterministically by fileId so the result never depends on input order.

The magnitude must stay below one resolution step and below the quality-preference terms (as on Apple) so it is strictly a tiebreak. Feed display capability + the DV setting into selectPlaybackVersion as an explicit context so it stays unit-testable without a real display.

Apple reference

silo-apple iosApp/iosApp/Screens/Player/VersionDynamicRangePreference.swift (the shared rule) and its use in DetailVersionSelection + PlaybackSessionBridge.selectVersion, with tests in DetailVersionSelectionTests (DV wins when supported+enabled; does not win when the display can't present it or the setting is off; never beats a higher resolution; both selectors agree).

Not in scope

Server-side last_file_id persistence works correctly (the client posts progress to /api/v1/playback/{id}/progress, which writes the version hints). This is purely the client's dynamic-range-blind ranking.


🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions