Add optional AV1 software decoding via dav1d for ExoPlayer (#721)

## Description
Adds the [`dav1d` decoder
module](https://github.com/androidx/media/tree/release/libraries/decoder_av1)
for ExoPlayer as an option. It can be enabled in advanced settings.

Performance will vary between devices.

### Related issues
Closes #103

### Dev notes

As with the ffmpeg module, this one is not required to build the entire
app so it's easier for developers to get started.

This also introduces a customized `DefaultRenderersFactory` for
ExoPlayer, but its largely copied from the super class's implementation.
This commit is contained in:
Ray 2026-01-18 18:35:41 -05:00 committed by GitHub
parent a0329b2c1d
commit 4dd44b935c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 170 additions and 36 deletions

View file

@ -67,6 +67,7 @@ fun createDeviceProfile(
assDirectPlay: Boolean,
pgsDirectPlay: Boolean,
dolbyVisionELDirectPlay: Boolean,
decodeAv1: Boolean,
jellyfinTenEleven: Boolean,
) = buildDeviceProfile {
val allowedAudioCodecs =
@ -338,6 +339,7 @@ fun createDeviceProfile(
conditions {
when {
decodeAv1 -> ProfileConditionValue.VIDEO_PROFILE notEquals "none"
!supportsAV1 -> ProfileConditionValue.VIDEO_PROFILE equals "none"
!supportsAV1Main10 -> ProfileConditionValue.VIDEO_PROFILE notEquals "main 10"
else -> ProfileConditionValue.VIDEO_PROFILE notEquals "none"
@ -382,13 +384,15 @@ fun createDeviceProfile(
}
// AV1
codecProfile {
type = CodecType.VIDEO
codec = Codec.Video.AV1
if (!decodeAv1) {
codecProfile {
type = CodecType.VIDEO
codec = Codec.Video.AV1
conditions {
ProfileConditionValue.WIDTH lowerThanOrEquals maxResolutionAV1.width
ProfileConditionValue.HEIGHT lowerThanOrEquals maxResolutionAV1.height
conditions {
ProfileConditionValue.WIDTH lowerThanOrEquals maxResolutionAV1.width
ProfileConditionValue.HEIGHT lowerThanOrEquals maxResolutionAV1.height
}
}
}
@ -410,16 +414,18 @@ fun createDeviceProfile(
buildSet {
if (jellyfinTenEleven) add("DOVIInvalid")
if (!supportsAV1DolbyVision) {
add(VideoRangeType.DOVI.serialName)
if (!supportsAV1HDR10) add(VideoRangeType.DOVI_WITH_HDR10.serialName)
if (jellyfinTenEleven && !supportsAV1HDR10Plus) add("DOVIWithHDR10Plus")
}
if (!decodeAv1) {
if (!supportsAV1DolbyVision) {
add(VideoRangeType.DOVI.serialName)
if (!supportsAV1HDR10) add(VideoRangeType.DOVI_WITH_HDR10.serialName)
if (jellyfinTenEleven && !supportsAV1HDR10Plus) add("DOVIWithHDR10Plus")
}
if (!supportsAV1HDR10Plus) {
add(VideoRangeType.HDR10_PLUS.serialName)
if (!supportsAV1HDR10Plus) {
add(VideoRangeType.HDR10_PLUS.serialName)
if (!mediaTest.supportsAV1HDR10()) add(VideoRangeType.HDR10.serialName)
if (!mediaTest.supportsAV1HDR10()) add(VideoRangeType.HDR10.serialName)
}
}
}