From 5f20fcb6297f75e2c81f2e85454ed6c6f7335f6c Mon Sep 17 00:00:00 2001 From: rickysixx <51907568+rickysixx@users.noreply.github.com> Date: Sun, 20 Oct 2024 17:41:46 +0200 Subject: [PATCH 1/2] Add preference to enable DTS audio bitstream Currently there is no reliable way to check if DTS audio is supported by the device or by others it's connected to, therefore DTS playback must be enabled/disabled manually by the user. `false` is the safest default value for the preference, because it allows media to be always played without errors on any device, even though it will trigger a useless transcode for devices that do support DTS. This commit reverts 38589ef0c7124857803cbf5656505c1932a3bb04, but now the preference does have a logic. --- .../org/jellyfin/androidtv/preference/UserPreferences.kt | 5 +++++ .../jellyfin/androidtv/ui/playback/PlaybackController.java | 1 + .../preference/screen/PlaybackAdvancedPreferencesScreen.kt | 6 ++++++ .../org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt | 5 +++-- app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt b/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt index a15ae6ca9c..16d5467439 100644 --- a/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt +++ b/app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt @@ -110,6 +110,11 @@ class UserPreferences(context: Context) : SharedPreferenceStore( */ var audioNightMode = enumPreference("audio_night_mode", false) + /** + * Enable DTS + */ + var dtsEnabled = booleanPreference("pref_bitstream_dts", false) + /** * Enable AC3 */ 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 d4389c6a9c..65504037d7 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 @@ -507,6 +507,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.getDtsEnabled()), userPreferences.getValue().get(UserPreferences.Companion.getAudioBehaviour()) == AudioBehavior.DOWNMIX_TO_STEREO ); internalOptions.setProfile(internalProfile); diff --git a/app/src/main/java/org/jellyfin/androidtv/ui/preference/screen/PlaybackAdvancedPreferencesScreen.kt b/app/src/main/java/org/jellyfin/androidtv/ui/preference/screen/PlaybackAdvancedPreferencesScreen.kt index 9eaddc3baa..25120755bc 100644 --- a/app/src/main/java/org/jellyfin/androidtv/ui/preference/screen/PlaybackAdvancedPreferencesScreen.kt +++ b/app/src/main/java/org/jellyfin/androidtv/ui/preference/screen/PlaybackAdvancedPreferencesScreen.kt @@ -115,6 +115,12 @@ class PlaybackAdvancedPreferencesScreen : OptionsFragment() { setContent(R.string.desc_bitstream_ac3) bind(userPreferences, UserPreferences.ac3Enabled) } + + checkbox { + setTitle(R.string.lbl_bitstream_dts) + setContent(R.string.desc_bitstream_dts) + bind(userPreferences, UserPreferences.dtsEnabled) + } } } } 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 628cc737a4..c80f7aa2f9 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 @@ -27,7 +27,8 @@ import org.jellyfin.apiclient.model.dlna.TranscodingProfile class ExoPlayerProfile( disableVideoDirectPlay: Boolean, isAC3Enabled: Boolean, - downMixAudio: Boolean + isDtsEnabled: Boolean, + downMixAudio: Boolean, ) : DeviceProfile() { private val downmixSupportedAudioCodecs = arrayOf( Codec.Audio.AAC, @@ -46,7 +47,7 @@ class ExoPlayerProfile( if (isAC3Enabled) add(Codec.Audio.AC3) if (isAC3Enabled) add(Codec.Audio.EAC3) add(Codec.Audio.DCA) - add(Codec.Audio.DTS) + if (isDtsEnabled) add(Codec.Audio.DTS) add(Codec.Audio.MLP) add(Codec.Audio.TRUEHD) add(Codec.Audio.PCM_ALAW) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1299959c38..2d46c85511 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -179,6 +179,8 @@ New premieres Bitstream Dolby Digital audio Requires capable hardware + Bitstream DTS audio + Requires capable hardware Levels out audio volume automatically Zoom Auto crop From 9ea2f504ff829bf474c69f014b5846b10045819b Mon Sep 17 00:00:00 2001 From: rickysixx <51907568+rickysixx@users.noreply.github.com> Date: Sun, 20 Oct 2024 17:41:54 +0200 Subject: [PATCH 2/2] refactor: use lower camel case for variable name --- .../androidtv/util/profile/ProfileHelper.kt | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 959c9d774d..0ee435c925 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 @@ -14,7 +14,7 @@ import org.jellyfin.apiclient.model.dlna.SubtitleProfile import timber.log.Timber object ProfileHelper { - private val MediaTest by lazy { MediaCodecCapabilitiesTest() } + private val mediaTest by lazy { MediaCodecCapabilitiesTest() } val deviceAV1CodecProfile by lazy { CodecProfile().apply { @@ -22,7 +22,7 @@ object ProfileHelper { codec = Codec.Video.AV1 conditions = when { - !MediaTest.supportsAV1() -> { + !mediaTest.supportsAV1() -> { // The following condition is a method to exclude all AV1 Timber.i("*** Does NOT support AV1") arrayOf( @@ -33,7 +33,7 @@ object ProfileHelper { ) ) } - !MediaTest.supportsAV1Main10() -> { + !mediaTest.supportsAV1Main10() -> { Timber.i("*** Does NOT support AV1 10 bit") arrayOf( ProfileCondition( @@ -59,11 +59,11 @@ object ProfileHelper { } val supportsAVC by lazy { - MediaTest.supportsAVC() + mediaTest.supportsAVC() } val supportsAVCHigh10 by lazy { - MediaTest.supportsAVCHigh10() + mediaTest.supportsAVCHigh10() } val deviceAVCCodecProfile by lazy { @@ -128,7 +128,7 @@ object ProfileHelper { ProfileCondition( ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoLevel, - MediaTest.getAVCMainLevel() + mediaTest.getAVCMainLevel() ) ) }) @@ -150,7 +150,7 @@ object ProfileHelper { ProfileCondition( ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoLevel, - MediaTest.getAVCHigh10Level() + mediaTest.getAVCHigh10Level() ) ) }) @@ -160,11 +160,11 @@ object ProfileHelper { } val supportsHevc by lazy { - MediaTest.supportsHevc() + mediaTest.supportsHevc() } val supportsHevcMain10 by lazy { - MediaTest.supportsHevcMain10() + mediaTest.supportsHevcMain10() } val deviceHevcCodecProfile by lazy { @@ -221,7 +221,7 @@ object ProfileHelper { ProfileCondition( ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoLevel, - MediaTest.getHevcMainLevel() + mediaTest.getHevcMainLevel() ) ) }) @@ -243,7 +243,7 @@ object ProfileHelper { ProfileCondition( ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoLevel, - MediaTest.getHevcMain10Level() + mediaTest.getHevcMain10Level() ) ) }) @@ -253,7 +253,7 @@ object ProfileHelper { } val maxResolutionCodecProfile by lazy { - val maxResolution = MediaTest.getMaxResolution(MediaFormat.MIMETYPE_VIDEO_AVC) + val maxResolution = mediaTest.getMaxResolution(MediaFormat.MIMETYPE_VIDEO_AVC) CodecProfile().apply { type = CodecType.Video