diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt index c816a60e4..2eb7b994c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerActivity.kt @@ -322,6 +322,8 @@ class PlayerActivity : setMpvConf() val logLevel = if (networkPreferences.verboseLogging().get()) "info" else "warn" player.initialize(applicationContext.filesDir.path, logLevel) + val hwDec = playerPreferences.standardHwDec().get() + MPVLib.setOptionString("hwdec", hwDec) MPVLib.setOptionString("keep-open", "always") MPVLib.setOptionString("ytdl", "no") MPVLib.addLogObserver(this) @@ -1054,8 +1056,23 @@ class PlayerActivity : @Suppress("UNUSED_PARAMETER") fun switchDecoder(view: View) { - player.cycleHwdec() - playerPreferences.playerViewMode().get() + val standardHwDec = playerPreferences.standardHwDec().get() + val currentHwDec = player.hwdecActive + + if (standardHwDec == currentHwDec) { + val hwDecEnabled = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + "mediacodec" + } else { + "mediacodec-copy" + } + val otherHwDec = when (standardHwDec) { + "no" -> hwDecEnabled + else -> "no" + } + MPVLib.setPropertyString("hwdec", otherHwDec) + } else { + MPVLib.setOptionString("hwdec", standardHwDec) + } playerControls.updateDecoderButton() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerControlsView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerControlsView.kt index 6a21681f3..aeaf50b57 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerControlsView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/PlayerControlsView.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.player import android.annotation.SuppressLint import android.content.Context import android.content.ContextWrapper +import android.os.Build import android.os.Handler import android.os.Looper import android.util.AttributeSet @@ -148,6 +149,7 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr // Long click controls binding.cycleSpeedBtn.setOnLongClickListener { pickSpeed(); true } + binding.cycleDecoderBtn.setOnLongClickListener { pickDecoder(); true } binding.playbackSeekbar.setOnSeekBarChangeListener(seekBarChangeListener) @@ -362,6 +364,34 @@ class PlayerControlsView @JvmOverloads constructor(context: Context, attrs: Attr } } + private fun pickDecoder() { + val restore = pauseForDialog() + + val items = mutableListOf( + Pair("HW (mediacodec-copy)", "mediacodec-copy"), + Pair("SW", "no"), + ) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + items.add(0, Pair("HW+ (mediacodec)", "mediacodec")) + } + var hwdecActive = playerPreferences.standardHwDec().get() + val selectedIndex = items.indexOfFirst { it.second == hwdecActive } + with(activity.HideBarsMaterialAlertDialogBuilder(activity)) { + setTitle(R.string.player_hwdec_dialog_title) + setSingleChoiceItems(items.map { it.first }.toTypedArray(), selectedIndex) { _, idx -> + hwdecActive = items[idx].second + } + setPositiveButton(R.string.dialog_ok) { _, _ -> + playerPreferences.standardHwDec().set(hwdecActive) + MPVLib.setPropertyString("hwdec", hwdecActive) + } + setNegativeButton(R.string.dialog_cancel) { dialog, _ -> dialog.cancel() } + setOnDismissListener { restore() } + create() + show() + } + } + private fun speedPickerDialog( picker: PickerDialog, @StringRes titleRes: Int, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/player/setting/PlayerPreferences.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/player/setting/PlayerPreferences.kt index c714c6ee4..05caa8d2b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/player/setting/PlayerPreferences.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/player/setting/PlayerPreferences.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.ui.player.setting +import android.os.Build import eu.kanade.tachiyomi.core.preference.PreferenceStore class PlayerPreferences( @@ -64,4 +65,11 @@ class PlayerPreferences( fun waitingTimeAniSkip() = preferenceStore.getInt("pref_waiting_time_aniskip", 5) fun enableNetflixStyleAniSkip() = preferenceStore.getBoolean("pref_enable_netflixStyle_aniskip", false) + + private val defaultHwDec = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + "mediacodec" + } else { + "mediacodec-copy" + } + fun standardHwDec() = preferenceStore.getString("pref_hwdec", defaultHwDec) } diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index bd4c16de1..929e4b68a 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -1134,6 +1134,7 @@ Don\'t skip Skip in %d seconds %s Skipped + Set default hardware decoding mode See your recently updated library entries