Skip to content

Commit

Permalink
AVC level check profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelRUSF authored and nielsvanvelzen committed Aug 25, 2024
1 parent 49bcd6f commit 50ef4a7
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package org.jellyfin.androidtv.util.profile
import org.jellyfin.androidtv.constant.Codec
import org.jellyfin.androidtv.util.profile.ProfileHelper.audioDirectPlayProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.deviceAV1CodecProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.deviceAVCCodecProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.deviceAVCLevelCodecProfiles
import org.jellyfin.androidtv.util.profile.ProfileHelper.deviceHevcCodecProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.deviceHevcLevelCodecProfiles
import org.jellyfin.androidtv.util.profile.ProfileHelper.h264VideoLevelProfileCondition
import org.jellyfin.androidtv.util.profile.ProfileHelper.h264VideoProfileCondition
import org.jellyfin.androidtv.util.profile.ProfileHelper.max1080pProfileConditions
import org.jellyfin.androidtv.util.profile.ProfileHelper.maxAudioChannelsCodecProfile
import org.jellyfin.androidtv.util.profile.ProfileHelper.photoDirectPlayProfile
Expand Down Expand Up @@ -154,15 +154,8 @@ class ExoPlayerProfile(

codecProfiles = buildList {
// H264 profile
add(CodecProfile().apply {
type = CodecType.Video
codec = Codec.Video.H264
conditions = buildList {
add(h264VideoProfileCondition)
add(h264VideoLevelProfileCondition)
if (disable4KVideo) addAll(max1080pProfileConditions)
}.toTypedArray()
})
add(deviceAVCCodecProfile)
addAll(deviceAVCLevelCodecProfiles)
// H264 ref frames profile
add(CodecProfile().apply {
type = CodecType.Video
Expand Down
136 changes: 101 additions & 35 deletions app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.jellyfin.androidtv.util.profile

import org.jellyfin.androidtv.constant.Codec
import org.jellyfin.androidtv.util.DeviceUtils
import org.jellyfin.apiclient.model.dlna.CodecProfile
import org.jellyfin.apiclient.model.dlna.CodecType
import org.jellyfin.apiclient.model.dlna.DirectPlayProfile
Expand All @@ -14,11 +13,6 @@ import org.jellyfin.apiclient.model.dlna.SubtitleProfile
import timber.log.Timber

object ProfileHelper {
// H264 codec levels https://en.wikipedia.org/wiki/Advanced_Video_Coding#Levels
private const val H264_LEVEL_4_1 = "41"
private const val H264_LEVEL_5_1 = "51"
private const val H264_LEVEL_5_2 = "52"

private val MediaTest by lazy { MediaCodecCapabilitiesTest() }

val deviceAV1CodecProfile by lazy {
Expand Down Expand Up @@ -63,6 +57,107 @@ object ProfileHelper {
}
}

val supportsAVC by lazy {
MediaTest.supportsAVC()
}

val supportsAVCHigh10 by lazy {
MediaTest.supportsAVCHigh10()
}

val deviceAVCCodecProfile by lazy {
CodecProfile().apply {
type = CodecType.Video
codec = Codec.Video.H264

conditions = when {
!supportsAVC -> {
// If AVC is not supported, exclude all AVC profiles
Timber.i("*** Does NOT support AVC")
arrayOf(
ProfileCondition(
ProfileConditionType.Equals,
ProfileConditionValue.VideoProfile,
"none"
)
)
}
else -> {
// If AVC is supported, include all relevant profiles
Timber.i("*** Supports AVC")
arrayOf(
ProfileCondition(
ProfileConditionType.EqualsAny,
ProfileConditionValue.VideoProfile,
listOfNotNull(
"High",
"Main",
"Baseline",
"Constrained Baseline",
if (supportsAVCHigh10) "High 10" else null
).joinToString("|")
)
)
}
}
}
}

val deviceAVCLevelCodecProfiles by lazy {
buildList {
if (supportsAVC) {
add(CodecProfile().apply {
type = CodecType.Video
codec = Codec.Video.H264

applyConditions = arrayOf(
ProfileCondition(
ProfileConditionType.EqualsAny,
ProfileConditionValue.VideoProfile,
listOfNotNull(
"High",
"Main",
"Baseline",
"Constrained Baseline"
).joinToString("|")
)
)

conditions = arrayOf(
ProfileCondition(
ProfileConditionType.LessThanEqual,
ProfileConditionValue.VideoLevel,
MediaTest.getAVCMainLevel()
)
)
})

if (supportsAVCHigh10) {
add(CodecProfile().apply {
type = CodecType.Video
codec = Codec.Video.H264

applyConditions = arrayOf(
ProfileCondition(
ProfileConditionType.Equals,
ProfileConditionValue.VideoProfile,
"High 10"
)
)

conditions = arrayOf(
ProfileCondition(
ProfileConditionType.LessThanEqual,
ProfileConditionValue.VideoLevel,
MediaTest.getAVCHigh10Level()
)
)
})
}
}
}
}

val supportsHevc by lazy {
MediaTest.supportsHevc()
}
Expand Down Expand Up @@ -159,35 +254,6 @@ object ProfileHelper {
}
}

val h264VideoLevelProfileCondition by lazy {
ProfileCondition(
ProfileConditionType.LessThanEqual,
ProfileConditionValue.VideoLevel,
when {
// https://developer.amazon.com/docs/fire-tv/device-specifications.html
DeviceUtils.isFireTvStick4k -> H264_LEVEL_5_2
DeviceUtils.isFireTv4k -> H264_LEVEL_5_2
DeviceUtils.isFireTv -> H264_LEVEL_4_1
DeviceUtils.isShieldTv -> H264_LEVEL_5_2
else -> H264_LEVEL_5_1
}
)
}

val h264VideoProfileCondition by lazy {
ProfileCondition(
ProfileConditionType.EqualsAny,
ProfileConditionValue.VideoProfile,
listOfNotNull(
"high",
"main",
"baseline",
"constrained baseline",
if (MediaTest.supportsAVCHigh10()) "high 10" else null
).joinToString("|")
)
}

val max1080pProfileConditions by lazy {
arrayOf(
ProfileCondition(
Expand Down

0 comments on commit 50ef4a7

Please sign in to comment.