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