mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Workaround Samsung tablet reboot playing adaptive secure content
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=169256059
This commit is contained in:
parent
9ea8a8a714
commit
e54841436b
1 changed files with 42 additions and 15 deletions
|
|
@ -158,9 +158,26 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
*/
|
*/
|
||||||
private static final int REINITIALIZATION_STATE_WAIT_END_OF_STREAM = 2;
|
private static final int REINITIALIZATION_STATE_WAIT_END_OF_STREAM = 2;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef({ADAPTATION_WORKAROUND_MODE_NEVER, ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION,
|
||||||
|
ADAPTATION_WORKAROUND_MODE_ALWAYS})
|
||||||
|
private @interface AdaptationWorkaroundMode {}
|
||||||
|
/**
|
||||||
|
* The adaptation workaround is never used.
|
||||||
|
*/
|
||||||
|
private static final int ADAPTATION_WORKAROUND_MODE_NEVER = 0;
|
||||||
|
/**
|
||||||
|
* The adaptation workaround is used when adapting between formats of the same resolution only.
|
||||||
|
*/
|
||||||
|
private static final int ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION = 1;
|
||||||
|
/**
|
||||||
|
* The adaptation workaround is always used when adapting between formats.
|
||||||
|
*/
|
||||||
|
private static final int ADAPTATION_WORKAROUND_MODE_ALWAYS = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* H.264/AVC buffer to queue when using the adaptation workaround (see
|
* H.264/AVC buffer to queue when using the adaptation workaround (see
|
||||||
* {@link #codecNeedsAdaptationWorkaround(String)}. Consists of three NAL units with start codes:
|
* {@link #codecAdaptationWorkaroundMode(String)}. Consists of three NAL units with start codes:
|
||||||
* Baseline sequence/picture parameter sets and a 32 * 32 pixel IDR slice. This stream can be
|
* Baseline sequence/picture parameter sets and a 32 * 32 pixel IDR slice. This stream can be
|
||||||
* queued to force a resolution change when adapting to a new format.
|
* queued to force a resolution change when adapting to a new format.
|
||||||
*/
|
*/
|
||||||
|
|
@ -182,9 +199,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
private DrmSession<FrameworkMediaCrypto> pendingDrmSession;
|
private DrmSession<FrameworkMediaCrypto> pendingDrmSession;
|
||||||
private MediaCodec codec;
|
private MediaCodec codec;
|
||||||
private MediaCodecInfo codecInfo;
|
private MediaCodecInfo codecInfo;
|
||||||
|
private @AdaptationWorkaroundMode int codecAdaptationWorkaroundMode;
|
||||||
private boolean codecNeedsDiscardToSpsWorkaround;
|
private boolean codecNeedsDiscardToSpsWorkaround;
|
||||||
private boolean codecNeedsFlushWorkaround;
|
private boolean codecNeedsFlushWorkaround;
|
||||||
private boolean codecNeedsAdaptationWorkaround;
|
|
||||||
private boolean codecNeedsEosPropagationWorkaround;
|
private boolean codecNeedsEosPropagationWorkaround;
|
||||||
private boolean codecNeedsEosFlushWorkaround;
|
private boolean codecNeedsEosFlushWorkaround;
|
||||||
private boolean codecNeedsEosOutputExceptionWorkaround;
|
private boolean codecNeedsEosOutputExceptionWorkaround;
|
||||||
|
|
@ -355,9 +372,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
String codecName = codecInfo.name;
|
String codecName = codecInfo.name;
|
||||||
|
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
|
||||||
codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, format);
|
codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, format);
|
||||||
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
|
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
|
||||||
codecNeedsAdaptationWorkaround = codecNeedsAdaptationWorkaround(codecName);
|
|
||||||
codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(codecName);
|
codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(codecName);
|
||||||
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
|
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
|
||||||
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
|
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
|
||||||
|
|
@ -458,7 +475,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
codecReceivedBuffers = false;
|
codecReceivedBuffers = false;
|
||||||
codecNeedsDiscardToSpsWorkaround = false;
|
codecNeedsDiscardToSpsWorkaround = false;
|
||||||
codecNeedsFlushWorkaround = false;
|
codecNeedsFlushWorkaround = false;
|
||||||
codecNeedsAdaptationWorkaround = false;
|
codecAdaptationWorkaroundMode = ADAPTATION_WORKAROUND_MODE_NEVER;
|
||||||
codecNeedsEosPropagationWorkaround = false;
|
codecNeedsEosPropagationWorkaround = false;
|
||||||
codecNeedsEosFlushWorkaround = false;
|
codecNeedsEosFlushWorkaround = false;
|
||||||
codecNeedsMonoChannelCountWorkaround = false;
|
codecNeedsMonoChannelCountWorkaround = false;
|
||||||
|
|
@ -802,8 +819,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
&& canReconfigureCodec(codec, codecInfo.adaptive, oldFormat, format)) {
|
&& canReconfigureCodec(codec, codecInfo.adaptive, oldFormat, format)) {
|
||||||
codecReconfigured = true;
|
codecReconfigured = true;
|
||||||
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
||||||
codecNeedsAdaptationWorkaroundBuffer = codecNeedsAdaptationWorkaround
|
codecNeedsAdaptationWorkaroundBuffer =
|
||||||
&& format.width == oldFormat.width && format.height == oldFormat.height;
|
codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_ALWAYS
|
||||||
|
|| (codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION
|
||||||
|
&& format.width == oldFormat.width && format.height == oldFormat.height);
|
||||||
} else {
|
} else {
|
||||||
if (codecReceivedBuffers) {
|
if (codecReceivedBuffers) {
|
||||||
// Signal end of stream and wait for any final output buffers before re-initialization.
|
// Signal end of stream and wait for any final output buffers before re-initialization.
|
||||||
|
|
@ -989,7 +1008,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
*/
|
*/
|
||||||
private void processOutputFormat() throws ExoPlaybackException {
|
private void processOutputFormat() throws ExoPlaybackException {
|
||||||
MediaFormat format = codec.getOutputFormat();
|
MediaFormat format = codec.getOutputFormat();
|
||||||
if (codecNeedsAdaptationWorkaround
|
if (codecAdaptationWorkaroundMode != ADAPTATION_WORKAROUND_MODE_NEVER
|
||||||
&& format.getInteger(MediaFormat.KEY_WIDTH) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT
|
&& format.getInteger(MediaFormat.KEY_WIDTH) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT
|
||||||
&& format.getInteger(MediaFormat.KEY_HEIGHT) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT) {
|
&& format.getInteger(MediaFormat.KEY_HEIGHT) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT) {
|
||||||
// We assume this format changed event was caused by the adaptation workaround.
|
// We assume this format changed event was caused by the adaptation workaround.
|
||||||
|
|
@ -1122,22 +1141,30 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the decoder is known to get stuck during some adaptations where the resolution
|
* Returns a mode that specifies when the adaptation workaround should be enabled.
|
||||||
* does not change.
|
|
||||||
* <p>
|
* <p>
|
||||||
* If true is returned, the renderer will work around the issue by queueing and discarding a blank
|
* When enabled, the workaround queues and discards a blank frame with a resolution whose width
|
||||||
* frame at a different resolution, which resets the codec's internal state.
|
* and height both equal {@link #ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT}, to reset the codec's
|
||||||
|
* internal state when a format change occurs.
|
||||||
* <p>
|
* <p>
|
||||||
* See [Internal: b/27807182].
|
* See [Internal: b/27807182].
|
||||||
|
* See <a href="https://github.com/google/ExoPlayer/issues/3257">GitHub issue #3257</a>.
|
||||||
*
|
*
|
||||||
* @param name The name of the decoder.
|
* @param name The name of the decoder.
|
||||||
* @return True if the decoder is known to get stuck during some adaptations.
|
* @return The mode specifying when the adaptation workaround should be enabled.
|
||||||
*/
|
*/
|
||||||
private static boolean codecNeedsAdaptationWorkaround(String name) {
|
private @AdaptationWorkaroundMode int codecAdaptationWorkaroundMode(String name) {
|
||||||
return Util.SDK_INT < 24
|
if (Util.SDK_INT <= 24 && "OMX.Exynos.avc.dec.secure".equals(name)
|
||||||
|
&& Util.MODEL.startsWith("SM-T585")) {
|
||||||
|
return ADAPTATION_WORKAROUND_MODE_ALWAYS;
|
||||||
|
} else if (Util.SDK_INT < 24
|
||||||
&& ("OMX.Nvidia.h264.decode".equals(name) || "OMX.Nvidia.h264.decode.secure".equals(name))
|
&& ("OMX.Nvidia.h264.decode".equals(name) || "OMX.Nvidia.h264.decode.secure".equals(name))
|
||||||
&& ("flounder".equals(Util.DEVICE) || "flounder_lte".equals(Util.DEVICE)
|
&& ("flounder".equals(Util.DEVICE) || "flounder_lte".equals(Util.DEVICE)
|
||||||
|| "grouper".equals(Util.DEVICE) || "tilapia".equals(Util.DEVICE));
|
|| "grouper".equals(Util.DEVICE) || "tilapia".equals(Util.DEVICE))) {
|
||||||
|
return ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION;
|
||||||
|
} else {
|
||||||
|
return ADAPTATION_WORKAROUND_MODE_NEVER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue