CrackMe.apk
Download file
package com.google.android.exoplayer2.video;
import android.media.MediaFormat;
import android.os.Handler;
import android.os.SystemClock;
import android.view.Surface;
import com.google.android.exoplayer2.BaseRenderer;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.decoder.CryptoConfig;
import com.google.android.exoplayer2.decoder.Decoder;
import com.google.android.exoplayer2.decoder.DecoderCounters;
import com.google.android.exoplayer2.decoder.DecoderException;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.decoder.DecoderReuseEvaluation;
import com.google.android.exoplayer2.decoder.VideoDecoderOutputBuffer;
import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.TimedValueQueue;
import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
public abstract class DecoderVideoRenderer extends BaseRenderer {
private static final int REINITIALIZATION_STATE_NONE = 0;
private static final int REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM = 1;
private static final int REINITIALIZATION_STATE_WAIT_END_OF_STREAM = 2;
private static final String TAG = "DecoderVideoRenderer";
private final long allowedJoiningTimeMs;
private int buffersInCodecCount;
private int consecutiveDroppedFrameCount;
private Decoder<DecoderInputBuffer, ? extends VideoDecoderOutputBuffer, ? extends DecoderException> decoder;
protected DecoderCounters decoderCounters;
private DrmSession decoderDrmSession;
private boolean decoderReceivedBuffers;
private int decoderReinitializationState;
private long droppedFrameAccumulationStartTimeMs;
private int droppedFrames;
private final VideoRendererEventListener.EventDispatcher eventDispatcher;
private final DecoderInputBuffer flagsOnlyBuffer;
private final TimedValueQueue<Format> formatQueue;
private VideoFrameMetadataListener frameMetadataListener;
private long initialPositionUs;
private DecoderInputBuffer inputBuffer;
private Format inputFormat;
private boolean inputStreamEnded;
private long joiningDeadlineMs = C.TIME_UNSET;
private long lastRenderTimeUs;
private final int maxDroppedFramesToNotify;
private boolean mayRenderFirstFrameAfterEnableIfNotStarted;
private Object output;
private VideoDecoderOutputBuffer outputBuffer;
private VideoDecoderOutputBufferRenderer outputBufferRenderer;
private Format outputFormat;
private int outputMode;
private boolean outputStreamEnded;
private long outputStreamOffsetUs;
private Surface outputSurface;
private boolean renderedFirstFrameAfterEnable;
private boolean renderedFirstFrameAfterReset;
private VideoSize reportedVideoSize;
private DrmSession sourceDrmSession;
private boolean waitingForFirstSampleInFormat;
private static boolean isBufferLate(long j) {
return j < -30000;
}
private static boolean isBufferVeryLate(long j) {
return j < -500000;
}
/* access modifiers changed from: protected */
public abstract Decoder<DecoderInputBuffer, ? extends VideoDecoderOutputBuffer, ? extends DecoderException> createDecoder(Format format, CryptoConfig cryptoConfig) throws DecoderException;
/* access modifiers changed from: protected */
public void onQueueInputBuffer(DecoderInputBuffer decoderInputBuffer) {
}
/* access modifiers changed from: protected */
public abstract void renderOutputBufferToSurface(VideoDecoderOutputBuffer videoDecoderOutputBuffer, Surface surface) throws DecoderException;
/* access modifiers changed from: protected */
public abstract void setDecoderOutputMode(int i);
protected DecoderVideoRenderer(long j, Handler handler, VideoRendererEventListener videoRendererEventListener, int i) {
super(2);
this.allowedJoiningTimeMs = j;
this.maxDroppedFramesToNotify = i;
clearReportedVideoSize();
this.formatQueue = new TimedValueQueue<>();
this.flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance();
this.eventDispatcher = new VideoRendererEventListener.EventDispatcher(handler, videoRendererEventListener);
this.decoderReinitializationState = 0;
this.outputMode = -1;
}
public void render(long j, long j2) throws ExoPlaybackException {
if (!this.outputStreamEnded) {
if (this.inputFormat == null) {
FormatHolder formatHolder = getFormatHolder();
this.flagsOnlyBuffer.clear();
int readSource = readSource(formatHolder, this.flagsOnlyBuffer, 2);
if (readSource == -5) {
onInputFormatChanged(formatHolder);
} else if (readSource == -4) {
Assertions.checkState(this.flagsOnlyBuffer.isEndOfStream());
this.inputStreamEnded = true;
this.outputStreamEnded = true;
return;
} else {
return;
}
}
maybeInitDecoder();
if (this.decoder != null) {
try {
TraceUtil.beginSection("drainAndFeed");
while (drainOutputBuffer(j, j2)) {
}
while (feedInputBuffer()) {
}
TraceUtil.endSection();
this.decoderCounters.ensureUpdated();
} catch (DecoderException e) {
Log.e(TAG, "Video codec error", e);
this.eventDispatcher.videoCodecError(e);
throw createRendererException(e, this.inputFormat, PlaybackException.ERROR_CODE_DECODING_FAILED);
}
}
}
}
public boolean isEnded() {
return this.outputStreamEnded;
}
public boolean isReady() {
if (this.inputFormat != null && ((isSourceReady() || this.outputBuffer != null) && (this.renderedFirstFrameAfterReset || !hasOutput()))) {
this.joiningDeadlineMs = C.TIME_UNSET;
return true;
} else if (this.joiningDeadlineMs == C.TIME_UNSET) {
return false;
} else {
if (SystemClock.elapsedRealtime() < this.joiningDeadlineMs) {
return true;
}
this.joiningDeadlineMs = C.TIME_UNSET;
return false;
}
}
public void handleMessage(int i, Object obj) throws ExoPlaybackException {
if (i == 1) {
setOutput(obj);
} else if (i == 7) {
this.frameMetadataListener = (VideoFrameMetadataListener) obj;
} else {
super.handleMessage(i, obj);
}
}
/* access modifiers changed from: protected */
public void onEnabled(boolean z, boolean z2) throws ExoPlaybackException {
DecoderCounters decoderCounters2 = new DecoderCounters();
this.decoderCounters = decoderCounters2;
this.eventDispatcher.enabled(decoderCounters2);
this.mayRenderFirstFrameAfterEnableIfNotStarted = z2;
this.renderedFirstFrameAfterEnable = false;
}
/* access modifiers changed from: protected */
public void onPositionReset(long j, boolean z) throws ExoPlaybackException {
this.inputStreamEnded = false;
this.outputStreamEnded = false;
clearRenderedFirstFrame();
this.initialPositionUs = C.TIME_UNSET;
this.consecutiveDroppedFrameCount = 0;
if (this.decoder != null) {
flushDecoder();
}
if (z) {
setJoiningDeadlineMs();
} else {
this.joiningDeadlineMs = C.TIME_UNSET;
}
this.formatQueue.clear();
}
/* access modifiers changed from: protected */
public void onStarted() {
this.droppedFrames = 0;
this.droppedFrameAccumulationStartTimeMs = SystemClock.elapsedRealtime();
this.lastRenderTimeUs = SystemClock.elapsedRealtime() * 1000;
}
/* access modifiers changed from: protected */
public void onStopped() {
this.joiningDeadlineMs = C.TIME_UNSET;
maybeNotifyDroppedFrames();
}
/* access modifiers changed from: protected */
public void onDisabled() {
this.inputFormat = null;
clearReportedVideoSize();
clearRenderedFirstFrame();
try {
setSourceDrmSession((DrmSession) null);
releaseDecoder();
} finally {
this.eventDispatcher.disabled(this.decoderCounters);
}
}
/* access modifiers changed from: protected */
public void onStreamChanged(Format[] formatArr, long j, long j2) throws ExoPlaybackException {
this.outputStreamOffsetUs = j2;
super.onStreamChanged(formatArr, j, j2);
}
/* access modifiers changed from: protected */
public void flushDecoder() throws ExoPlaybackException {
this.buffersInCodecCount = 0;
if (this.decoderReinitializationState != 0) {
releaseDecoder();
maybeInitDecoder();
return;
}
this.inputBuffer = null;
VideoDecoderOutputBuffer videoDecoderOutputBuffer = this.outputBuffer;
if (videoDecoderOutputBuffer != null) {
videoDecoderOutputBuffer.release();
this.outputBuffer = null;
}
this.decoder.flush();
this.decoderReceivedBuffers = false;
}
/* access modifiers changed from: protected */
public void releaseDecoder() {
this.inputBuffer = null;
this.outputBuffer = null;
this.decoderReinitializationState = 0;
this.decoderReceivedBuffers = false;
this.buffersInCodecCount = 0;
if (this.decoder != null) {
this.decoderCounters.decoderReleaseCount++;
this.decoder.release();
this.eventDispatcher.decoderReleased(this.decoder.getName());
this.decoder = null;
}
setDecoderDrmSession((DrmSession) null);
}
/* access modifiers changed from: protected */
public void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException {
DecoderReuseEvaluation decoderReuseEvaluation;
this.waitingForFirstSampleInFormat = true;
Format format = (Format) Assertions.checkNotNull(formatHolder.format);
setSourceDrmSession(formatHolder.drmSession);
Format format2 = this.inputFormat;
this.inputFormat = format;
Decoder<DecoderInputBuffer, ? extends VideoDecoderOutputBuffer, ? extends DecoderException> decoder2 = this.decoder;
if (decoder2 == null) {
maybeInitDecoder();
this.eventDispatcher.inputFormatChanged(this.inputFormat, (DecoderReuseEvaluation) null);
return;
}
if (this.sourceDrmSession != this.decoderDrmSession) {
decoderReuseEvaluation = new DecoderReuseEvaluation(decoder2.getName(), format2, format, 0, 128);
} else {
decoderReuseEvaluation = canReuseDecoder(decoder2.getName(), format2, format);
}
if (decoderReuseEvaluation.result == 0) {
if (this.decoderReceivedBuffers) {
this.decoderReinitializationState = 1;
} else {
releaseDecoder();
maybeInitDecoder();
}
}
this.eventDispatcher.inputFormatChanged(this.inputFormat, decoderReuseEvaluation);
}
/* access modifiers changed from: protected */
public void onProcessedOutputBuffer(long j) {
this.buffersInCodecCount--;
}
/* access modifiers changed from: protected */
public boolean shouldDropOutputBuffer(long j, long j2) {
return isBufferLate(j);
}
/* access modifiers changed from: protected */
public boolean shouldDropBuffersToKeyframe(long j, long j2) {
return isBufferVeryLate(j);
}
/* access modifiers changed from: protected */
public boolean shouldForceRenderOutputBuffer(long j, long j2) {
return isBufferLate(j) && j2 > 100000;
}
/* access modifiers changed from: protected */
public void skipOutputBuffer(VideoDecoderOutputBuffer videoDecoderOutputBuffer) {
this.decoderCounters.skippedOutputBufferCount++;
videoDecoderOutputBuffer.release();
}
/* access modifiers changed from: protected */
public void dropOutputBuffer(VideoDecoderOutputBuffer videoDecoderOutputBuffer) {
updateDroppedBufferCounters(0, 1);
videoDecoderOutputBuffer.release();
}
/* access modifiers changed from: protected */
public boolean maybeDropBuffersToKeyframe(long j) throws ExoPlaybackException {
int skipSource = skipSource(j);
if (skipSource == 0) {
return false;
}
this.decoderCounters.droppedToKeyframeCount++;
updateDroppedBufferCounters(skipSource, this.buffersInCodecCount);
flushDecoder();
return true;
}
/* access modifiers changed from: protected */
public void updateDroppedBufferCounters(int i, int i2) {
this.decoderCounters.droppedInputBufferCount += i;
int i3 = i + i2;
this.decoderCounters.droppedBufferCount += i3;
this.droppedFrames += i3;
int i4 = this.consecutiveDroppedFrameCount + i3;
this.consecutiveDroppedFrameCount = i4;
DecoderCounters decoderCounters2 = this.decoderCounters;
decoderCounters2.maxConsecutiveDroppedBufferCount = Math.max(i4, decoderCounters2.maxConsecutiveDroppedBufferCount);
int i5 = this.maxDroppedFramesToNotify;
if (i5 > 0 && this.droppedFrames >= i5) {
maybeNotifyDroppedFrames();
}
}
/* access modifiers changed from: protected */
public void renderOutputBuffer(VideoDecoderOutputBuffer videoDecoderOutputBuffer, long j, Format format) throws DecoderException {
VideoFrameMetadataListener videoFrameMetadataListener = this.frameMetadataListener;
if (videoFrameMetadataListener != null) {
videoFrameMetadataListener.onVideoFrameAboutToBeRendered(j, System.nanoTime(), format, (MediaFormat) null);
}
this.lastRenderTimeUs = Util.msToUs(SystemClock.elapsedRealtime() * 1000);
int i = videoDecoderOutputBuffer.mode;
boolean z = i == 1 && this.outputSurface != null;
boolean z2 = i == 0 && this.outputBufferRenderer != null;
if (z2 || z) {
maybeNotifyVideoSizeChanged(videoDecoderOutputBuffer.width, videoDecoderOutputBuffer.height);
if (z2) {
this.outputBufferRenderer.setOutputBuffer(videoDecoderOutputBuffer);
} else {
renderOutputBufferToSurface(videoDecoderOutputBuffer, this.outputSurface);
}
this.consecutiveDroppedFrameCount = 0;
this.decoderCounters.renderedOutputBufferCount++;
maybeNotifyRenderedFirstFrame();
return;
}
dropOutputBuffer(videoDecoderOutputBuffer);
}
/* access modifiers changed from: protected */
public final void setOutput(Object obj) {
if (obj instanceof Surface) {
this.outputSurface = (Surface) obj;
this.outputBufferRenderer = null;
this.outputMode = 1;
} else if (obj instanceof VideoDecoderOutputBufferRenderer) {
this.outputSurface = null;
this.outputBufferRenderer = (VideoDecoderOutputBufferRenderer) obj;
this.outputMode = 0;
} else {
this.outputSurface = null;
this.outputBufferRenderer = null;
this.outputMode = -1;
obj = null;
}
if (this.output != obj) {
this.output = obj;
if (obj != null) {
if (this.decoder != null) {
setDecoderOutputMode(this.outputMode);
}
onOutputChanged();
return;
}
onOutputRemoved();
} else if (obj != null) {
onOutputReset();
}
}
/* access modifiers changed from: protected */
public DecoderReuseEvaluation canReuseDecoder(String str, Format format, Format format2) {
return new DecoderReuseEvaluation(str, format, format2, 0, 1);
}
private void setSourceDrmSession(DrmSession drmSession) {
DrmSession.CC.replaceSession(this.sourceDrmSession, drmSession);
this.sourceDrmSession = drmSession;
}
private void setDecoderDrmSession(DrmSession drmSession) {
DrmSession.CC.replaceSession(this.decoderDrmSession, drmSession);
this.decoderDrmSession = drmSession;
}
private void maybeInitDecoder() throws ExoPlaybackException {
if (this.decoder == null) {
setDecoderDrmSession(this.sourceDrmSession);
CryptoConfig cryptoConfig = null;
DrmSession drmSession = this.decoderDrmSession;
if (drmSession == null || (cryptoConfig = drmSession.getCryptoConfig()) != null || this.decoderDrmSession.getError() != null) {
try {
long elapsedRealtime = SystemClock.elapsedRealtime();
this.decoder = createDecoder(this.inputFormat, cryptoConfig);
setDecoderOutputMode(this.outputMode);
long elapsedRealtime2 = SystemClock.elapsedRealtime();
this.eventDispatcher.decoderInitialized(this.decoder.getName(), elapsedRealtime2, elapsedRealtime2 - elapsedRealtime);
this.decoderCounters.decoderInitCount++;
} catch (DecoderException e) {
Log.e(TAG, "Video codec error", e);
this.eventDispatcher.videoCodecError(e);
throw createRendererException(e, this.inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
} catch (OutOfMemoryError e2) {
throw createRendererException(e2, this.inputFormat, PlaybackException.ERROR_CODE_DECODER_INIT_FAILED);
}
}
}
}
private boolean feedInputBuffer() throws DecoderException, ExoPlaybackException {
Decoder<DecoderInputBuffer, ? extends VideoDecoderOutputBuffer, ? extends DecoderException> decoder2 = this.decoder;
if (decoder2 == null || this.decoderReinitializationState == 2 || this.inputStreamEnded) {
return false;
}
if (this.inputBuffer == null) {
DecoderInputBuffer dequeueInputBuffer = decoder2.dequeueInputBuffer();
this.inputBuffer = dequeueInputBuffer;
if (dequeueInputBuffer == null) {
return false;
}
}
if (this.decoderReinitializationState == 1) {
this.inputBuffer.setFlags(4);
this.decoder.queueInputBuffer(this.inputBuffer);
this.inputBuffer = null;
this.decoderReinitializationState = 2;
return false;
}
FormatHolder formatHolder = getFormatHolder();
int readSource = readSource(formatHolder, this.inputBuffer, 0);
if (readSource == -5) {
onInputFormatChanged(formatHolder);
return true;
} else if (readSource != -4) {
if (readSource == -3) {
return false;
}
throw new IllegalStateException();
} else if (this.inputBuffer.isEndOfStream()) {
this.inputStreamEnded = true;
this.decoder.queueInputBuffer(this.inputBuffer);
this.inputBuffer = null;
return false;
} else {
if (this.waitingForFirstSampleInFormat) {
this.formatQueue.add(this.inputBuffer.timeUs, this.inputFormat);
this.waitingForFirstSampleInFormat = false;
}
this.inputBuffer.flip();
this.inputBuffer.format = this.inputFormat;
onQueueInputBuffer(this.inputBuffer);
this.decoder.queueInputBuffer(this.inputBuffer);
this.buffersInCodecCount++;
this.decoderReceivedBuffers = true;
this.decoderCounters.queuedInputBufferCount++;
this.inputBuffer = null;
return true;
}
}
private boolean drainOutputBuffer(long j, long j2) throws ExoPlaybackException, DecoderException {
if (this.outputBuffer == null) {
VideoDecoderOutputBuffer videoDecoderOutputBuffer = (VideoDecoderOutputBuffer) this.decoder.dequeueOutputBuffer();
this.outputBuffer = videoDecoderOutputBuffer;
if (videoDecoderOutputBuffer == null) {
return false;
}
this.decoderCounters.skippedOutputBufferCount += this.outputBuffer.skippedOutputBufferCount;
this.buffersInCodecCount -= this.outputBuffer.skippedOutputBufferCount;
}
if (this.outputBuffer.isEndOfStream()) {
if (this.decoderReinitializationState == 2) {
releaseDecoder();
maybeInitDecoder();
} else {
this.outputBuffer.release();
this.outputBuffer = null;
this.outputStreamEnded = true;
}
return false;
}
boolean processOutputBuffer = processOutputBuffer(j, j2);
if (processOutputBuffer) {
onProcessedOutputBuffer(this.outputBuffer.timeUs);
this.outputBuffer = null;
}
return processOutputBuffer;
}
private boolean processOutputBuffer(long j, long j2) throws ExoPlaybackException, DecoderException {
if (this.initialPositionUs == C.TIME_UNSET) {
this.initialPositionUs = j;
}
long j3 = this.outputBuffer.timeUs - j;
if (hasOutput()) {
long j4 = this.outputBuffer.timeUs - this.outputStreamOffsetUs;
Format pollFloor = this.formatQueue.pollFloor(j4);
if (pollFloor != null) {
this.outputFormat = pollFloor;
}
long elapsedRealtime = (SystemClock.elapsedRealtime() * 1000) - this.lastRenderTimeUs;
boolean z = getState() == 2;
if ((this.renderedFirstFrameAfterEnable ? !this.renderedFirstFrameAfterReset : !(!z && !this.mayRenderFirstFrameAfterEnableIfNotStarted)) || (z && shouldForceRenderOutputBuffer(j3, elapsedRealtime))) {
renderOutputBuffer(this.outputBuffer, j4, this.outputFormat);
return true;
} else if (!z || j == this.initialPositionUs || (shouldDropBuffersToKeyframe(j3, j2) && maybeDropBuffersToKeyframe(j))) {
return false;
} else {
if (shouldDropOutputBuffer(j3, j2)) {
dropOutputBuffer(this.outputBuffer);
return true;
}
if (j3 < 30000) {
renderOutputBuffer(this.outputBuffer, j4, this.outputFormat);
return true;
}
return false;
}
} else if (!isBufferLate(j3)) {
return false;
} else {
skipOutputBuffer(this.outputBuffer);
return true;
}
}
private boolean hasOutput() {
return this.outputMode != -1;
}
private void onOutputChanged() {
maybeRenotifyVideoSizeChanged();
clearRenderedFirstFrame();
if (getState() == 2) {
setJoiningDeadlineMs();
}
}
private void onOutputRemoved() {
clearReportedVideoSize();
clearRenderedFirstFrame();
}
private void onOutputReset() {
maybeRenotifyVideoSizeChanged();
maybeRenotifyRenderedFirstFrame();
}
private void setJoiningDeadlineMs() {
this.joiningDeadlineMs = this.allowedJoiningTimeMs > 0 ? SystemClock.elapsedRealtime() + this.allowedJoiningTimeMs : C.TIME_UNSET;
}
private void clearRenderedFirstFrame() {
this.renderedFirstFrameAfterReset = false;
}
private void maybeNotifyRenderedFirstFrame() {
this.renderedFirstFrameAfterEnable = true;
if (!this.renderedFirstFrameAfterReset) {
this.renderedFirstFrameAfterReset = true;
this.eventDispatcher.renderedFirstFrame(this.output);
}
}
private void maybeRenotifyRenderedFirstFrame() {
if (this.renderedFirstFrameAfterReset) {
this.eventDispatcher.renderedFirstFrame(this.output);
}
}
private void clearReportedVideoSize() {
this.reportedVideoSize = null;
}
private void maybeNotifyVideoSizeChanged(int i, int i2) {
VideoSize videoSize = this.reportedVideoSize;
if (videoSize == null || videoSize.width != i || this.reportedVideoSize.height != i2) {
VideoSize videoSize2 = new VideoSize(i, i2);
this.reportedVideoSize = videoSize2;
this.eventDispatcher.videoSizeChanged(videoSize2);
}
}
private void maybeRenotifyVideoSizeChanged() {
VideoSize videoSize = this.reportedVideoSize;
if (videoSize != null) {
this.eventDispatcher.videoSizeChanged(videoSize);
}
}
private void maybeNotifyDroppedFrames() {
if (this.droppedFrames > 0) {
long elapsedRealtime = SystemClock.elapsedRealtime();
this.eventDispatcher.droppedFrames(this.droppedFrames, elapsedRealtime - this.droppedFrameAccumulationStartTimeMs);
this.droppedFrames = 0;
this.droppedFrameAccumulationStartTimeMs = elapsedRealtime;
}
}
}
Download file