VEX-6365: Improve memory management (#17)

Improve memory management to reduce pressure on low end devices.

JIRA: VEX-6365
This commit is contained in:
Armands Malejev 2022-01-21 14:10:22 +02:00 committed by GitHub
parent aa63361695
commit 2ab029995f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 3 deletions

View File

@ -386,6 +386,8 @@ maxBufferMs | number | The default maximum duration of media that the player wil
bufferForPlaybackMs | number | The default duration of media that must be buffered for playback to start or resume following a user action such as a seek, in milliseconds.
bufferForPlaybackAfterRebufferMs | number | The default duration of media that must be buffered for playback to resume after a rebuffer, in milliseconds. A rebuffer is defined to be caused by buffer depletion rather than a user action.
maxHeapAllocationPercent | number | The percentage of available heap that the video can use to buffer, between 0 and 1
minBackBufferMemoryReservePercent | number | The percentage of available app memory at which during startup the back buffer will be disabled, between 0 and 1
minBufferMemoryReservePercent | number | The percentage of available app memory to keep in reserve that prevents buffer from using it, between 0 and 1
This prop should only be set when you are setting the source, changing it after the media is loaded will cause it to be reloaded.

View File

@ -113,6 +113,8 @@ class ReactExoplayerView extends FrameLayout implements
DrmSessionEventListener {
public static final double DEFAULT_MAX_HEAP_ALLOCATION_PERCENT = 1;
public static final double DEFAULT_MIN_BACK_BUFFER_MEMORY_RESERVE = 0;
public static final double DEFAULT_MIN_BUFFER_MEMORY_RESERVE = 0;
private static final String TAG = "ReactExoplayerView";
@ -161,7 +163,8 @@ class ReactExoplayerView extends FrameLayout implements
private int bufferForPlaybackMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS;
private int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
private double maxHeapAllocationPercent = ReactExoplayerView.DEFAULT_MAX_HEAP_ALLOCATION_PERCENT;
private double minBackBufferMemoryReservePercent = ReactExoplayerView.DEFAULT_MIN_BACK_BUFFER_MEMORY_RESERVE;
private double minBufferMemoryReservePercent = ReactExoplayerView.DEFAULT_MIN_BUFFER_MEMORY_RESERVE;
private Handler mainHandler;
private Timer bufferCheckTimer;
@ -449,6 +452,14 @@ class ReactExoplayerView extends FrameLayout implements
if (isHeapReached) {
return false;
}
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long freeMemory = runtime.maxMemory() - usedMemory;
long reserveMemory = (long)minBufferMemoryReservePercent * runtime.maxMemory();
long bufferedMs = bufferedDurationUs / (long)1000;
if (reserveMemory > freeMemory && bufferedMs > 2000) {
// We don't have enough memory in reserve so we stop buffering to allow other components to use it instead
return false;
}
if (runtime.freeMemory() == 0) {
Log.w("ExoPlayer Warning", "Free memory reached 0, forcing garbage collection");
runtime.gc();
@ -1622,6 +1633,16 @@ class ReactExoplayerView extends FrameLayout implements
}
public void setBackBufferDurationMs(int backBufferDurationMs) {
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long freeMemory = runtime.maxMemory() - usedMemory;
long reserveMemory = (long)minBackBufferMemoryReservePercent * runtime.maxMemory();
if (reserveMemory > freeMemory) {
// We don't have enough memory in reserve so we will
Log.w("ExoPlayer Warning", "Not enough reserve memory, setting back buffer to 0ms to reduce memory pressure!");
this.backBufferDurationMs = 0;
return;
}
this.backBufferDurationMs = backBufferDurationMs;
}
@ -1679,12 +1700,14 @@ class ReactExoplayerView extends FrameLayout implements
exoPlayerView.setHideShutterView(hideShutterView);
}
public void setBufferConfig(int newMinBufferMs, int newMaxBufferMs, int newBufferForPlaybackMs, int newBufferForPlaybackAfterRebufferMs, double newMaxHeapAllocationPercent) {
public void setBufferConfig(int newMinBufferMs, int newMaxBufferMs, int newBufferForPlaybackMs, int newBufferForPlaybackAfterRebufferMs, double newMaxHeapAllocationPercent, double newMinBackBufferMemoryReservePercent, double newMinBufferMemoryReservePercent) {
minBufferMs = newMinBufferMs;
maxBufferMs = newMaxBufferMs;
bufferForPlaybackMs = newBufferForPlaybackMs;
bufferForPlaybackAfterRebufferMs = newBufferForPlaybackAfterRebufferMs;
maxHeapAllocationPercent = newMaxHeapAllocationPercent;
minBackBufferMemoryReservePercent = newMinBackBufferMemoryReservePercent;
minBufferMemoryReservePercent = newMinBufferMemoryReservePercent;
releasePlayer();
initializePlayer();
}

View File

@ -56,6 +56,8 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_MS = "bufferForPlaybackMs";
private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = "bufferForPlaybackAfterRebufferMs";
private static final String PROP_BUFFER_CONFIG_MAX_HEAP_ALLOCATION_PERCENT = "maxHeapAllocationPercent";
private static final String PROP_BUFFER_CONFIG_MIN_BACK_BUFFER_MEMORY_RESERVE_PERCENT = "minBackBufferMemoryReservePercent";
private static final String PROP_BUFFER_CONFIG_MIN_BUFFER_MEMORY_RESERVE_PERCENT = "minBufferMemoryReservePercent";
private static final String PROP_PREVENTS_DISPLAY_SLEEP_DURING_VIDEO_PLAYBACK = "preventsDisplaySleepDuringVideoPlayback";
private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
private static final String PROP_REPORT_BANDWIDTH = "reportBandwidth";
@ -346,6 +348,9 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
int bufferForPlaybackMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS;
int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
double maxHeapAllocationPercent = ReactExoplayerView.DEFAULT_MAX_HEAP_ALLOCATION_PERCENT;
double minBackBufferMemoryReservePercent = ReactExoplayerView.DEFAULT_MIN_BACK_BUFFER_MEMORY_RESERVE;
double minBufferMemoryReservePercent = ReactExoplayerView.DEFAULT_MIN_BUFFER_MEMORY_RESERVE;
if (bufferConfig != null) {
minBufferMs = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MIN_BUFFER_MS)
? bufferConfig.getInt(PROP_BUFFER_CONFIG_MIN_BUFFER_MS) : minBufferMs;
@ -357,7 +362,11 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
? bufferConfig.getInt(PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS) : bufferForPlaybackAfterRebufferMs;
maxHeapAllocationPercent = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MAX_HEAP_ALLOCATION_PERCENT)
? bufferConfig.getDouble(PROP_BUFFER_CONFIG_MAX_HEAP_ALLOCATION_PERCENT) : maxHeapAllocationPercent;
videoView.setBufferConfig(minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, maxHeapAllocationPercent);
minBackBufferMemoryReservePercent = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MIN_BACK_BUFFER_MEMORY_RESERVE_PERCENT)
? bufferConfig.getDouble(PROP_BUFFER_CONFIG_MIN_BACK_BUFFER_MEMORY_RESERVE_PERCENT) : minBackBufferMemoryReservePercent;
minBufferMemoryReservePercent = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MIN_BUFFER_MEMORY_RESERVE_PERCENT)
? bufferConfig.getDouble(PROP_BUFFER_CONFIG_MIN_BUFFER_MEMORY_RESERVE_PERCENT) : minBufferMemoryReservePercent;
videoView.setBufferConfig(minBufferMs, maxBufferMs, bufferForPlaybackMs, bufferForPlaybackAfterRebufferMs, maxHeapAllocationPercent, minBackBufferMemoryReservePercent, minBufferMemoryReservePercent);
}
}