fix(player): render Dolby Vision via gpu-next on the Android mpv backend
Dolby Vision Profile 5 files play with pink and purple colors on Android devices without DV support (#1902): vo=gpu cannot apply DV RPU reshaping, so the raw IPTPQc2 base layer reaches the screen. The shipped libmpv AAR builds mpv 0.41 with libplacebo, where gpu-next is the upstream default VO and reshapes DV correctly. Prefer vo=gpu-next with an explicit vo=gpu fallback on both the primary mpv backend and the ExoPlayer failure-fallback path, drop the vd-lavc-film-grain=cpu override so film grain applies on the GPU under gpu-next, and report current-vo in player stats. Verified on a Pixel 7 (no DV display or decoder): gpu-next initializes on Mali-G710/GLES 3.2, SDR hardware decode is unchanged, and a 4K DV stream decodes to dolbyvision/bt.2020/pq with correct colors under software decode. Reshaping still needs software decode: FFmpeg 8.0's mediacodec wrapper exports no DOVI side data, so hardware-decoded DV keeps playing the base layer untouched.
This commit is contained in:
@@ -1313,7 +1313,7 @@ class ExoPlayerPlugin :
|
||||
val bufferSize = configuredBufferSizeBytes
|
||||
|
||||
core.setProperty("hwdec", "mediacodec,mediacodec-copy")
|
||||
core.setProperty("vo", "gpu")
|
||||
core.setProperty("vo", "gpu-next,gpu")
|
||||
core.setProperty("ao", "audiotrack")
|
||||
|
||||
if (bufferSize != null && bufferSize > 0) {
|
||||
|
||||
@@ -293,10 +293,17 @@ class MpvPlayerCore private constructor(
|
||||
setOption("audio-display", "no")
|
||||
setOption("gapless-audio", "weak")
|
||||
} else {
|
||||
setOption("vo", "gpu")
|
||||
// gpu-next (libplacebo) is mpv 0.41's default VO and the only
|
||||
// Android path that applies Dolby Vision RPU reshaping — vo=gpu
|
||||
// renders the raw base layer, which for DV Profile 5 means
|
||||
// pink/purple IPTPQc2 output (#1902). Keep the explicit chain so
|
||||
// a device where gpu-next cannot initialize still gets the
|
||||
// legacy renderer instead of no video output. Film grain is left
|
||||
// on its `auto` default: applied by the VO under gpu-next, by
|
||||
// the decoder on the fallback path.
|
||||
setOption("vo", "gpu-next,gpu")
|
||||
setOption("gpu-context", "android")
|
||||
setOption("opengl-es", "yes")
|
||||
setOption("vd-lavc-film-grain", "cpu")
|
||||
if (displayFpsOverride != null) {
|
||||
setOption("display-fps-override", displayFpsOverride)
|
||||
}
|
||||
@@ -1038,6 +1045,7 @@ class MpvPlayerCore private constructor(
|
||||
"estimated-vf-fps" to getProperty("estimated-vf-fps"),
|
||||
"video-bitrate" to getProperty("video-bitrate"),
|
||||
"hwdec-current" to getProperty("hwdec-current"),
|
||||
"current-vo" to getProperty("current-vo"),
|
||||
"audio-codec-name" to getProperty("audio-codec-name"),
|
||||
"audio-params/samplerate" to getProperty("audio-params/samplerate"),
|
||||
"audio-params/hr-channels" to getProperty("audio-params/hr-channels"),
|
||||
|
||||
Reference in New Issue
Block a user