From 706b64573ae882273703ba1e93c1b3a9737bfebc Mon Sep 17 00:00:00 2001 From: MichaelRUSF <78215956+MichaelRUSF@users.noreply.github.com> Date: Sun, 8 Sep 2024 05:33:16 -0400 Subject: [PATCH] Add resolution codec check (#3953) * Add 4k resolution codec check * 4k profile check * Apply review changes * Remove hard-coded resolutions --- .../ui/playback/PlaybackController.java | 4 +-- .../util/profile/ExoPlayerProfile.kt | 12 ++------ .../profile/MediaCodecCapabilitiesTest.kt | 26 ++++++++++++++++ .../androidtv/util/profile/ProfileHelper.kt | 30 +++++++++++-------- 4 files changed, 48 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java index e140a12f7d..2bf081ae8f 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java +++ b/app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java @@ -24,7 +24,6 @@ import org.jellyfin.androidtv.preference.constant.NextUpBehavior; import org.jellyfin.androidtv.preference.constant.RefreshRateSwitchingBehavior; import org.jellyfin.androidtv.ui.livetv.TvManager; -import org.jellyfin.androidtv.util.DeviceUtils; import org.jellyfin.androidtv.util.TimeUtils; import org.jellyfin.androidtv.util.Utils; import org.jellyfin.androidtv.util.apiclient.ReportingHelper; @@ -523,8 +522,7 @@ private VideoOptions buildExoPlayerOptions(@Nullable Integer forcedSubtitleIndex DeviceProfile internalProfile = new ExoPlayerProfile( isLiveTv && !userPreferences.getValue().get(UserPreferences.Companion.getLiveTvDirectPlayEnabled()), userPreferences.getValue().get(UserPreferences.Companion.getAc3Enabled()), - userPreferences.getValue().get(UserPreferences.Companion.getAudioBehaviour()) == AudioBehavior.DOWNMIX_TO_STEREO, - !DeviceUtils.has4kVideoSupport() + userPreferences.getValue().get(UserPreferences.Companion.getAudioBehaviour()) == AudioBehavior.DOWNMIX_TO_STEREO ); internalOptions.setProfile(internalProfile); return internalOptions; diff --git a/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt b/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt index 0ab9ca98dc..191c08e4a1 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt +++ b/app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt @@ -7,7 +7,7 @@ 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.max1080pProfileConditions +import org.jellyfin.androidtv.util.profile.ProfileHelper.maxResolutionCodecProfile import org.jellyfin.androidtv.util.profile.ProfileHelper.maxAudioChannelsCodecProfile import org.jellyfin.androidtv.util.profile.ProfileHelper.photoDirectPlayProfile import org.jellyfin.androidtv.util.profile.ProfileHelper.subtitleProfile @@ -27,8 +27,7 @@ import org.jellyfin.apiclient.model.dlna.TranscodingProfile class ExoPlayerProfile( disableVideoDirectPlay: Boolean, isAC3Enabled: Boolean, - downMixAudio: Boolean, - disable4KVideo: Boolean + downMixAudio: Boolean ) : DeviceProfile() { private val downmixSupportedAudioCodecs = arrayOf( Codec.Audio.AAC, @@ -200,12 +199,7 @@ class ExoPlayerProfile( // AV1 profile add(deviceAV1CodecProfile) // Limit video resolution support for older devices - if (disable4KVideo) { - add(CodecProfile().apply { - type = CodecType.Video - conditions = max1080pProfileConditions - }) - } + add(maxResolutionCodecProfile) // Audio channel profile add(maxAudioChannelsCodecProfile(channels = if (downMixAudio) 2 else 8)) }.toTypedArray() diff --git a/app/src/main/java/org/jellyfin/androidtv/util/profile/MediaCodecCapabilitiesTest.kt b/app/src/main/java/org/jellyfin/androidtv/util/profile/MediaCodecCapabilitiesTest.kt index 58d5227c80..d3ee8c88dc 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/profile/MediaCodecCapabilitiesTest.kt +++ b/app/src/main/java/org/jellyfin/androidtv/util/profile/MediaCodecCapabilitiesTest.kt @@ -4,6 +4,7 @@ import android.media.MediaCodecInfo.CodecProfileLevel import android.media.MediaCodecList import android.media.MediaFormat import android.os.Build +import android.util.Size import timber.log.Timber class MediaCodecCapabilitiesTest { @@ -165,4 +166,29 @@ class MediaCodecCapabilitiesTest { return false } + + fun getMaxResolution(mime: String): Size { + var maxWidth = 0 + var maxHeight = 0 + + for (info in mediaCodecList.codecInfos) { + if (info.isEncoder) continue + + try { + val capabilities = info.getCapabilitiesForType(mime) + val videoCapabilities = capabilities.videoCapabilities ?: continue + val supportedWidth = videoCapabilities.supportedWidths?.upper ?: continue + val supportedHeight = videoCapabilities.supportedHeights?.upper ?: continue + + maxWidth = maxOf(maxWidth, supportedWidth) + maxHeight = maxOf(maxHeight, supportedHeight) + + } catch (e: IllegalArgumentException) { + Timber.d(e, "Codec %s does not support video capabilities", info.name) + } + } + + return Size(maxWidth, maxHeight) + } + } diff --git a/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt b/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt index 87e163a23e..959c9d774d 100644 --- a/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt +++ b/app/src/main/java/org/jellyfin/androidtv/util/profile/ProfileHelper.kt @@ -1,5 +1,6 @@ package org.jellyfin.androidtv.util.profile +import android.media.MediaFormat import org.jellyfin.androidtv.constant.Codec import org.jellyfin.apiclient.model.dlna.CodecProfile import org.jellyfin.apiclient.model.dlna.CodecType @@ -251,19 +252,24 @@ object ProfileHelper { } } - val max1080pProfileConditions by lazy { - arrayOf( - ProfileCondition( - ProfileConditionType.LessThanEqual, - ProfileConditionValue.Width, - "1920" - ), - ProfileCondition( - ProfileConditionType.LessThanEqual, - ProfileConditionValue.Height, - "1080" + val maxResolutionCodecProfile by lazy { + val maxResolution = MediaTest.getMaxResolution(MediaFormat.MIMETYPE_VIDEO_AVC) + + CodecProfile().apply { + type = CodecType.Video + conditions = arrayOf( + ProfileCondition( + ProfileConditionType.LessThanEqual, + ProfileConditionValue.Width, + maxResolution.width.toString() + ), + ProfileCondition( + ProfileConditionType.LessThanEqual, + ProfileConditionValue.Height, + maxResolution.height.toString() + ) ) - ) + } } val photoDirectPlayProfile by lazy {