Bug 1517252 - p2: convert out-of-memory error to playback error to avoid crash. r=jya

Differential Revision: https://phabricator.services.mozilla.com/D16710

--HG--
extra : moz-landing-system : lando
This commit is contained in:
John Lin 2019-01-18 01:51:53 +00:00
parent e4a543d886
commit 8143268e96
3 changed files with 25 additions and 13 deletions

View File

@ -13,6 +13,7 @@ import android.util.Log;
import org.mozilla.geckoview.BuildConfig;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
@ -102,7 +103,7 @@ public class GeckoHlsAudioRenderer extends GeckoHlsRendererBase {
}
@Override
protected void handleFormatRead(DecoderInputBuffer bufferForRead) {
protected void handleFormatRead(DecoderInputBuffer bufferForRead) throws ExoPlaybackException {
onInputFormatChanged(mFormatHolder.format);
}

View File

@ -11,6 +11,7 @@ import org.mozilla.geckoview.BuildConfig;
import com.google.android.exoplayer2.BaseRenderer;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder;
@ -41,9 +42,9 @@ public abstract class GeckoHlsRendererBase extends BaseRenderer {
protected boolean mInputStreamEnded = false;
protected long mFirstSampleStartTime = Long.MIN_VALUE;
protected abstract void createInputBuffer();
protected abstract void createInputBuffer() throws ExoPlaybackException;
protected abstract void handleReconfiguration(DecoderInputBuffer bufferForRead);
protected abstract void handleFormatRead(DecoderInputBuffer bufferForRead);
protected abstract void handleFormatRead(DecoderInputBuffer bufferForRead) throws ExoPlaybackException;
protected abstract void handleEndOfStream(DecoderInputBuffer bufferForRead);
protected abstract void handleSamplePreparation(DecoderInputBuffer bufferForRead);
protected abstract void resetRenderer();
@ -145,7 +146,7 @@ public abstract class GeckoHlsRendererBase extends BaseRenderer {
// do nothing.
}
protected void onInputFormatChanged(Format newFormat) {
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
Format oldFormat;
try {
oldFormat = mFormats.get(mFormats.size() - 1);
@ -170,13 +171,17 @@ public abstract class GeckoHlsRendererBase extends BaseRenderer {
notifyPlayerInputFormatChanged(newFormat);
}
protected void maybeInitRenderer() {
protected void maybeInitRenderer() throws ExoPlaybackException {
if (mInitialized || mFormats.size() == 0) {
return;
}
if (DEBUG) { Log.d(LOGTAG, "Initializing ... "); }
createInputBuffer();
mInitialized = true;
try {
createInputBuffer();
mInitialized = true;
} catch (OutOfMemoryError e) {
throw ExoPlaybackException.createForRenderer(new RuntimeException(e), getIndex());
}
}
/*
@ -189,7 +194,7 @@ public abstract class GeckoHlsRendererBase extends BaseRenderer {
* situation 1) not initialized 2) input stream is ended 3) queue is full.
* 4) format changed. 5) exception happened.
*/
protected synchronized boolean feedInputBuffersQueue() {
protected synchronized boolean feedInputBuffersQueue() throws ExoPlaybackException {
if (!mInitialized || mInputStreamEnded || isQueuedEnoughData()) {
// Need to reinitialize the renderer or the input stream has ended
// or we just reached the maximum queue size.
@ -244,7 +249,7 @@ public abstract class GeckoHlsRendererBase extends BaseRenderer {
}
}
private void readFormat() {
private void readFormat() throws ExoPlaybackException {
mflagsOnlyBuffer.clear();
int result = readSource(mFormatHolder, mflagsOnlyBuffer, true);
if (result == C.RESULT_FORMAT_READ) {
@ -288,7 +293,7 @@ public abstract class GeckoHlsRendererBase extends BaseRenderer {
* calls renderer.render by passing its wall clock time.
*/
@Override
public void render(long positionUs, long elapsedRealtimeUs) {
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
if (BuildConfig.DEBUG_BUILD) {
Log.d(LOGTAG, "positionUs = " + positionUs +
", mInputStreamEnded = " + mInputStreamEnded);

View File

@ -13,6 +13,7 @@ import android.util.Log;
import org.mozilla.geckoview.BuildConfig;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.mediacodec.MediaCodecInfo;
@ -134,7 +135,7 @@ public class GeckoHlsVideoRenderer extends GeckoHlsRendererBase {
}
@Override
protected final void createInputBuffer() {
protected final void createInputBuffer() throws ExoPlaybackException {
assertTrue(mFormats.size() > 0);
// Calculate maximum size which might be used for target format.
Format currentFormat = mFormats.get(mFormats.size() - 1);
@ -144,7 +145,12 @@ public class GeckoHlsVideoRenderer extends GeckoHlsRendererBase {
// creating DecoderInputBuffer with specific BufferReplacementMode, we
// still allocate a calculated max size buffer for it at first to reduce
// runtime overhead.
mInputBuffer = ByteBuffer.wrap(new byte[mCodecMaxValues.inputSize]);
try {
mInputBuffer = ByteBuffer.wrap(new byte[mCodecMaxValues.inputSize]);
} catch (OutOfMemoryError e) {
Log.e(LOGTAG, "cannot allocate input buffer of size " + mCodecMaxValues.inputSize, e);
throw ExoPlaybackException.createForRenderer(new Exception(e), getIndex());
}
}
@Override
@ -181,7 +187,7 @@ public class GeckoHlsVideoRenderer extends GeckoHlsRendererBase {
}
@Override
protected void handleFormatRead(DecoderInputBuffer bufferForRead) {
protected void handleFormatRead(DecoderInputBuffer bufferForRead) throws ExoPlaybackException {
if (mRendererReconfigurationState == RECONFIGURATION_STATE.QUEUE_PENDING) {
if (DEBUG) { Log.d(LOGTAG, "[feedInput][QUEUE_PENDING] 2 formats in a row."); }
// We received two formats in a row. Clear the current buffer of any reconfiguration data