Skip to content

Commit 01a5d01

Browse files
MichaelRUSFMichaelR416
MichaelRUSF
authored and
MichaelR416
committed
Add codec panel
1 parent b540f29 commit 01a5d01

File tree

7 files changed

+126
-12
lines changed

7 files changed

+126
-12
lines changed

app/src/main/java/org/jellyfin/androidtv/preference/UserPreferences.kt

+10
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ class UserPreferences(context: Context) : SharedPreferenceStore(
102102
*/
103103
var preferExoPlayerFfmpeg = booleanPreference("exoplayer_prefer_ffmpeg", defaultValue = false)
104104

105+
/**
106+
* User defined AVC levels for main and high 10.
107+
*/
108+
var userAVCLevel = stringPreference("user_avc_level", "auto")
109+
110+
/**
111+
* User defined HEVC levels for main and main 10.
112+
*/
113+
var userHEVCLevel = stringPreference("user_hevc_level", "auto")
114+
105115
/* Playback - Audio related */
106116
/**
107117
* Preferred behavior for audio streaming.

app/src/main/java/org/jellyfin/androidtv/ui/playback/PlaybackController.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,9 @@ private VideoOptions buildExoPlayerOptions(@Nullable Integer forcedSubtitleIndex
514514
DeviceProfile internalProfile = new ExoPlayerProfile(
515515
!internalOptions.getEnableDirectStream(),
516516
userPreferences.getValue().get(UserPreferences.Companion.getAc3Enabled()),
517-
userPreferences.getValue().get(UserPreferences.Companion.getAudioBehaviour()) == AudioBehavior.DOWNMIX_TO_STEREO
517+
userPreferences.getValue().get(UserPreferences.Companion.getAudioBehaviour()) == AudioBehavior.DOWNMIX_TO_STEREO,
518+
userPreferences.getValue().get(UserPreferences.Companion.getUserAVCLevel()),
519+
userPreferences.getValue().get(UserPreferences.Companion.getUserHEVCLevel())
518520
);
519521
internalOptions.setProfile(internalProfile);
520522
return internalOptions;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package org.jellyfin.androidtv.ui.preference.screen
2+
3+
import org.jellyfin.androidtv.R
4+
import org.jellyfin.androidtv.preference.UserPreferences
5+
import org.jellyfin.androidtv.ui.preference.dsl.OptionsFragment
6+
import org.jellyfin.androidtv.ui.preference.dsl.checkbox
7+
import org.jellyfin.androidtv.ui.preference.dsl.list
8+
import org.jellyfin.androidtv.ui.preference.dsl.optionsScreen
9+
import org.koin.android.ext.android.inject
10+
11+
class PlaybackAdvancedCodecPreferencesScreen : OptionsFragment() {
12+
private val userPreferences: UserPreferences by inject()
13+
14+
override val screen by optionsScreen {
15+
setTitle(R.string.codec)
16+
17+
category {
18+
setTitle(R.string.level_warning)
19+
20+
list {
21+
setTitle(R.string.user_avc_level)
22+
entries = mapOf(
23+
// AVC levels as reported by ffprobe are multiplied by 10, e.g. level 4.1 is 41.
24+
"auto" to "Auto",
25+
"62" to "Level 6.2",
26+
"61" to "Level 6.1",
27+
"60" to "Level 6.0",
28+
"52" to "Level 5.2",
29+
"51" to "Level 5.1",
30+
"50" to "Level 5.0",
31+
"42" to "Level 4.2",
32+
"41" to "Level 4.1",
33+
"40" to "Level 4.0"
34+
)
35+
bind(userPreferences, UserPreferences.userAVCLevel)
36+
}
37+
38+
list {
39+
setTitle(R.string.user_hevc_level)
40+
entries = mapOf(
41+
// HEVC levels as reported by ffprobe are multiplied by 30, e.g. level 4.1 is 123.
42+
"auto" to "Auto",
43+
"186" to "Level 6.2",
44+
"183" to "Level 6.1",
45+
"180" to "Level 6.0",
46+
"156" to "Level 5.2",
47+
"153" to "Level 5.1",
48+
"150" to "Level 5.0",
49+
"123" to "Level 4.1",
50+
"120" to "Level 4.0"
51+
)
52+
bind(userPreferences, UserPreferences.userHEVCLevel)
53+
}
54+
}
55+
56+
category {
57+
setTitle(R.string.pref_audio)
58+
59+
checkbox {
60+
setTitle(R.string.lbl_bitstream_ac3)
61+
setContent(R.string.desc_bitstream_ac3)
62+
bind(userPreferences, UserPreferences.ac3Enabled)
63+
}
64+
}
65+
}
66+
}

app/src/main/java/org/jellyfin/androidtv/ui/preference/screen/PlaybackAdvancedPreferencesScreen.kt

-6
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,6 @@ class PlaybackAdvancedPreferencesScreen : OptionsFragment() {
109109
bind(userPreferences, UserPreferences.audioNightMode)
110110
depends { Build.VERSION.SDK_INT >= Build.VERSION_CODES.P }
111111
}
112-
113-
checkbox {
114-
setTitle(R.string.lbl_bitstream_ac3)
115-
setContent(R.string.desc_bitstream_ac3)
116-
bind(userPreferences, UserPreferences.ac3Enabled)
117-
}
118112
}
119113
}
120114
}

app/src/main/java/org/jellyfin/androidtv/ui/preference/screen/PlaybackPreferencesScreen.kt

+6
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,12 @@ class PlaybackPreferencesScreen : OptionsFragment() {
194194
icon = R.drawable.ic_more
195195
withFragment<PlaybackAdvancedPreferencesScreen>()
196196
}
197+
198+
link {
199+
setTitle(R.string.codec_advanced)
200+
icon = R.drawable.ic_more
201+
withFragment<PlaybackAdvancedCodecPreferencesScreen>()
202+
}
197203
}
198204
}
199205
}

app/src/main/java/org/jellyfin/androidtv/util/profile/ExoPlayerProfile.kt

+36-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ import org.jellyfin.apiclient.model.dlna.TranscodingProfile
2626
class ExoPlayerProfile(
2727
disableVideoDirectPlay: Boolean,
2828
isAC3Enabled: Boolean,
29-
downMixAudio: Boolean
29+
downMixAudio: Boolean,
30+
userAVCLevel: String? = "auto",
31+
userHEVCLevel: String? = "auto"
3032
) : DeviceProfile() {
3133
private val downmixSupportedAudioCodecs = arrayOf(
3234
Codec.Audio.AAC,
@@ -153,8 +155,22 @@ class ExoPlayerProfile(
153155

154156
codecProfiles = buildList {
155157
// H264 profile
156-
add(deviceAVCCodecProfile)
157-
addAll(deviceAVCLevelCodecProfiles)
158+
if (userAVCLevel == "auto") {
159+
add(deviceAVCCodecProfile)
160+
addAll(deviceAVCLevelCodecProfiles)
161+
} else {
162+
add(CodecProfile().apply {
163+
type = CodecType.Video
164+
codec = Codec.Video.H264
165+
conditions = arrayOf(
166+
ProfileCondition(
167+
ProfileConditionType.LessThanEqual,
168+
ProfileConditionValue.VideoLevel,
169+
userAVCLevel
170+
)
171+
)
172+
})
173+
}
158174
// H264 ref frames profile
159175
add(CodecProfile().apply {
160176
type = CodecType.Video
@@ -194,8 +210,23 @@ class ExoPlayerProfile(
194210
)
195211
})
196212
// HEVC profiles
197-
add(deviceHevcCodecProfile)
198-
addAll(deviceHevcLevelCodecProfiles)
213+
if (userHEVCLevel == "auto") {
214+
add(deviceHevcCodecProfile)
215+
addAll(deviceHevcLevelCodecProfiles)
216+
} else {
217+
add(CodecProfile().apply {
218+
type = CodecType.Video
219+
codec = Codec.Video.HEVC
220+
conditions = arrayOf(
221+
ProfileCondition(
222+
ProfileConditionType.LessThanEqual,
223+
ProfileConditionValue.VideoLevel,
224+
userHEVCLevel
225+
)
226+
)
227+
})
228+
}
229+
199230
// AV1 profile
200231
add(deviceAV1CodecProfile)
201232
// Limit video resolution support for older devices

app/src/main/res/values/strings.xml

+5
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,11 @@
526526
<string name="segment_type_unknown">Unknown segments</string>
527527
<string name="skip_forward_length">Skip forward length</string>
528528
<string name="preference_enable_trickplay">Enable trickplay in video player</string>
529+
<string name="codec_advanced">Advanced codec preferences</string>
530+
<string name="codec">Codec</string>
531+
<string name="user_avc_level">H.264 Level</string>
532+
<string name="user_hevc_level">H.265 Level</string>
533+
<string name="level_warning">Video\n\nSwitching from \'Auto\' could lead to playback issues</string>
529534
<plurals name="seconds">
530535
<item quantity="one">%1$s second</item>
531536
<item quantity="other">%1$s seconds</item>

0 commit comments

Comments
 (0)