Experimental HEVC encoding support for videos.

This commit is contained in:
Nicholas Tinsley
2024-08-23 10:09:22 -04:00
parent 5f66e2eb15
commit 0f7f866562
14 changed files with 124 additions and 34 deletions

View File

@@ -383,6 +383,19 @@ class InternalSettingsFragment : DSLSettingsFragment(R.string.preferences__inter
dividerPref()
sectionHeaderPref(DSLSettingsText.from("Media"))
switchPref(
title = DSLSettingsText.from("Enable HEVC Encoding for HD Videos"),
summary = DSLSettingsText.from("Videos sent in \"HD\" quality will be encoded in HEVC on compatible devices."),
isChecked = state.hevcEncoding,
onClick = {
viewModel.setHevcEncoding(!state.hevcEncoding)
}
)
dividerPref()
sectionHeaderPref(DSLSettingsText.from("Conversations and Shortcuts"))
clickPref(

View File

@@ -23,5 +23,6 @@ data class InternalSettingsState(
val canClearOnboardingState: Boolean,
val pnpInitialized: Boolean,
val useConversationItemV2ForMedia: Boolean,
val hasPendingOneTimeDonation: Boolean
val hasPendingOneTimeDonation: Boolean,
val hevcEncoding: Boolean
)

View File

@@ -119,6 +119,11 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito
refresh()
}
fun setHevcEncoding(enabled: Boolean) {
SignalStore.internal.hevcEncoding = enabled
refresh()
}
fun addSampleReleaseNote() {
repository.addSampleReleaseNote()
}
@@ -159,7 +164,8 @@ class InternalSettingsViewModel(private val repository: InternalSettingsReposito
canClearOnboardingState = SignalStore.story.hasDownloadedOnboardingStory && Stories.isFeatureEnabled(),
pnpInitialized = SignalStore.misc.hasPniInitializedDevices,
useConversationItemV2ForMedia = SignalStore.internal.useConversationItemV2Media(),
hasPendingOneTimeDonation = SignalStore.inAppPayments.getPendingOneTimeDonation() != null
hasPendingOneTimeDonation = SignalStore.inAppPayments.getPendingOneTimeDonation() != null,
hevcEncoding = SignalStore.internal.hevcEncoding
)
fun onClearOnboardingState() {

View File

@@ -32,6 +32,7 @@ public final class InternalValues extends SignalStoreValues {
public static final String CONVERSATION_ITEM_V2_MEDIA = "internal.conversation_item_v2_media";
public static final String FORCE_ENTER_RESTORE_V2_FLOW = "internal.force_enter_restore_v2_flow";
public static final String WEB_SOCKET_SHADOWING_STATS = "internal.web_socket_shadowing_stats";
public static final String ENCODE_HEVC = "internal.hevc_encoding";
InternalValues(KeyValueStore store) {
super(store);
@@ -183,6 +184,14 @@ public final class InternalValues extends SignalStoreValues {
}
}
public void setHevcEncoding(boolean enabled) {
putBoolean(ENCODE_HEVC, enabled);
}
public boolean getHevcEncoding() {
return getBoolean(ENCODE_HEVC, false);
}
public void setLastScrollPosition(int position) {
putInteger(LAST_SCROLL_POSITION, position);
}

View File

@@ -41,10 +41,6 @@ public abstract class MediaConstraints {
return TranscodingPreset.LEVEL_1;
}
public boolean isHighQuality() {
return false;
}
/**
* Provide a list of dimensions that should be attempted during compression. We will keep moving
* down the list until the image can be scaled to fit under {@link #getImageMaxSize(Context)}.

View File

@@ -7,10 +7,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.RemoteConfig;
import org.thoughtcrime.securesms.util.LocaleRemoteConfig;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.video.TranscodingPreset;
import org.thoughtcrime.securesms.video.videoconverter.utils.DeviceCapabilities;
import java.util.Arrays;
@@ -25,11 +27,6 @@ public class PushMediaConstraints extends MediaConstraints {
currentConfig = getCurrentConfig(AppDependencies.getApplication(), sentMediaQuality);
}
@Override
public boolean isHighQuality() {
return currentConfig == MediaConfig.LEVEL_3;
}
@Override
public int getImageMaxWidth(Context context) {
return currentConfig.imageSizeTargets[0];
@@ -102,7 +99,11 @@ public class PushMediaConstraints extends MediaConstraints {
}
if (sentMediaQuality == SentMediaQuality.HIGH) {
return MediaConfig.LEVEL_3;
if (DeviceCapabilities.canEncodeHevc() && (RemoteConfig.useHevcEncoder() || SignalStore.internal().getHevcEncoding())) {
return MediaConfig.LEVEL_4;
} else {
return MediaConfig.LEVEL_3;
}
}
return LocaleRemoteConfig.getMediaQualityLevel().orElse(MediaConfig.getDefault(context));
}
@@ -112,7 +113,8 @@ public class PushMediaConstraints extends MediaConstraints {
LEVEL_1(false, 1, MB, new int[] { 1600, 1024, 768, 512 }, 70, TranscodingPreset.LEVEL_1),
LEVEL_2(false, 2, (int) (1.5 * MB), new int[] { 2048, 1600, 1024, 768, 512 }, 75, TranscodingPreset.LEVEL_2),
LEVEL_3(false, 3, (int) (3 * MB), new int[] { 4096, 3072, 2048, 1600, 1024, 768, 512 }, 75, TranscodingPreset.LEVEL_3);
LEVEL_3(false, 3, (int) (3 * MB), new int[] { 4096, 3072, 2048, 1600, 1024, 768, 512 }, 75, TranscodingPreset.LEVEL_3),
LEVEL_4(false, 4, 3 * MB, new int[] { 4096, 3072, 2048, 1600, 1024, 768, 512 }, 75, TranscodingPreset.LEVEL_4);
private final boolean isLowMemory;
private final int level;

View File

@@ -1110,5 +1110,13 @@ object RemoteConfig {
hotSwappable = false
)
@JvmStatic
@get:JvmName("useHevcEncoder")
val useHevcEncoder: Boolean by remoteBoolean(
key = "android.useHevcEncoder",
defaultValue = false,
hotSwappable = false
)
// endregion
}