VEX-6365: Improve memory management (#17)
Improve memory management to reduce pressure on low end devices. JIRA: VEX-6365
This commit is contained in:
parent
aa63361695
commit
2ab029995f
@ -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.
|
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.
|
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
|
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.
|
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.
|
||||||
|
|
||||||
|
@ -113,6 +113,8 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
DrmSessionEventListener {
|
DrmSessionEventListener {
|
||||||
|
|
||||||
public static final double DEFAULT_MAX_HEAP_ALLOCATION_PERCENT = 1;
|
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";
|
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 bufferForPlaybackMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS;
|
||||||
private int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
private int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
||||||
private double maxHeapAllocationPercent = ReactExoplayerView.DEFAULT_MAX_HEAP_ALLOCATION_PERCENT;
|
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 Handler mainHandler;
|
||||||
private Timer bufferCheckTimer;
|
private Timer bufferCheckTimer;
|
||||||
|
|
||||||
@ -449,6 +452,14 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
if (isHeapReached) {
|
if (isHeapReached) {
|
||||||
return false;
|
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) {
|
if (runtime.freeMemory() == 0) {
|
||||||
Log.w("ExoPlayer Warning", "Free memory reached 0, forcing garbage collection");
|
Log.w("ExoPlayer Warning", "Free memory reached 0, forcing garbage collection");
|
||||||
runtime.gc();
|
runtime.gc();
|
||||||
@ -1622,6 +1633,16 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setBackBufferDurationMs(int backBufferDurationMs) {
|
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;
|
this.backBufferDurationMs = backBufferDurationMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1679,12 +1700,14 @@ class ReactExoplayerView extends FrameLayout implements
|
|||||||
exoPlayerView.setHideShutterView(hideShutterView);
|
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;
|
minBufferMs = newMinBufferMs;
|
||||||
maxBufferMs = newMaxBufferMs;
|
maxBufferMs = newMaxBufferMs;
|
||||||
bufferForPlaybackMs = newBufferForPlaybackMs;
|
bufferForPlaybackMs = newBufferForPlaybackMs;
|
||||||
bufferForPlaybackAfterRebufferMs = newBufferForPlaybackAfterRebufferMs;
|
bufferForPlaybackAfterRebufferMs = newBufferForPlaybackAfterRebufferMs;
|
||||||
maxHeapAllocationPercent = newMaxHeapAllocationPercent;
|
maxHeapAllocationPercent = newMaxHeapAllocationPercent;
|
||||||
|
minBackBufferMemoryReservePercent = newMinBackBufferMemoryReservePercent;
|
||||||
|
minBufferMemoryReservePercent = newMinBufferMemoryReservePercent;
|
||||||
releasePlayer();
|
releasePlayer();
|
||||||
initializePlayer();
|
initializePlayer();
|
||||||
}
|
}
|
||||||
|
@ -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_MS = "bufferForPlaybackMs";
|
||||||
private static final String PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS = "bufferForPlaybackAfterRebufferMs";
|
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_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_PREVENTS_DISPLAY_SLEEP_DURING_VIDEO_PLAYBACK = "preventsDisplaySleepDuringVideoPlayback";
|
||||||
private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
|
private static final String PROP_PROGRESS_UPDATE_INTERVAL = "progressUpdateInterval";
|
||||||
private static final String PROP_REPORT_BANDWIDTH = "reportBandwidth";
|
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 bufferForPlaybackMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS;
|
||||||
int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
int bufferForPlaybackAfterRebufferMs = DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS;
|
||||||
double maxHeapAllocationPercent = ReactExoplayerView.DEFAULT_MAX_HEAP_ALLOCATION_PERCENT;
|
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) {
|
if (bufferConfig != null) {
|
||||||
minBufferMs = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MIN_BUFFER_MS)
|
minBufferMs = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MIN_BUFFER_MS)
|
||||||
? bufferConfig.getInt(PROP_BUFFER_CONFIG_MIN_BUFFER_MS) : minBufferMs;
|
? 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;
|
? bufferConfig.getInt(PROP_BUFFER_CONFIG_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS) : bufferForPlaybackAfterRebufferMs;
|
||||||
maxHeapAllocationPercent = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MAX_HEAP_ALLOCATION_PERCENT)
|
maxHeapAllocationPercent = bufferConfig.hasKey(PROP_BUFFER_CONFIG_MAX_HEAP_ALLOCATION_PERCENT)
|
||||||
? bufferConfig.getDouble(PROP_BUFFER_CONFIG_MAX_HEAP_ALLOCATION_PERCENT) : maxHeapAllocationPercent;
|
? 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user