mirror of
https://github.com/Pinball3D/Rabbit-R1.git
synced 2024-12-26 17:12:31 -06:00
1606 lines
75 KiB
Java
1606 lines
75 KiB
Java
package androidx.media3.exoplayer.video;
|
|
|
|
import android.content.Context;
|
|
import android.graphics.Point;
|
|
import android.hardware.display.DisplayManager;
|
|
import android.media.MediaCrypto;
|
|
import android.media.MediaFormat;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.os.Message;
|
|
import android.os.SystemClock;
|
|
import android.util.Pair;
|
|
import android.view.Display;
|
|
import android.view.Surface;
|
|
import androidx.media3.common.ColorInfo;
|
|
import androidx.media3.common.DebugViewProvider;
|
|
import androidx.media3.common.Effect;
|
|
import androidx.media3.common.Format;
|
|
import androidx.media3.common.FrameInfo;
|
|
import androidx.media3.common.MimeTypes;
|
|
import androidx.media3.common.PlaybackException;
|
|
import androidx.media3.common.SurfaceInfo;
|
|
import androidx.media3.common.VideoFrameProcessingException;
|
|
import androidx.media3.common.VideoFrameProcessor;
|
|
import androidx.media3.common.VideoSize;
|
|
import androidx.media3.common.util.Assertions;
|
|
import androidx.media3.common.util.Log;
|
|
import androidx.media3.common.util.MediaFormatUtil;
|
|
import androidx.media3.common.util.Size;
|
|
import androidx.media3.common.util.TraceUtil;
|
|
import androidx.media3.common.util.Util;
|
|
import androidx.media3.decoder.DecoderInputBuffer;
|
|
import androidx.media3.exoplayer.DecoderReuseEvaluation;
|
|
import androidx.media3.exoplayer.ExoPlaybackException;
|
|
import androidx.media3.exoplayer.FormatHolder;
|
|
import androidx.media3.exoplayer.RendererCapabilities;
|
|
import androidx.media3.exoplayer.mediacodec.MediaCodecAdapter;
|
|
import androidx.media3.exoplayer.mediacodec.MediaCodecDecoderException;
|
|
import androidx.media3.exoplayer.mediacodec.MediaCodecInfo;
|
|
import androidx.media3.exoplayer.mediacodec.MediaCodecRenderer;
|
|
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
|
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
|
import androidx.media3.exoplayer.video.VideoRendererEventListener;
|
|
import androidx.work.WorkRequest;
|
|
import com.google.common.collect.ImmutableList;
|
|
import io.flutter.plugin.platform.PlatformPlugin;
|
|
import io.sentry.protocol.OperatingSystem;
|
|
import io.sentry.protocol.SentryThread;
|
|
import io.sentry.protocol.ViewHierarchyNode;
|
|
import java.lang.reflect.Constructor;
|
|
import java.lang.reflect.Method;
|
|
import java.nio.ByteBuffer;
|
|
import java.util.ArrayDeque;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
|
import java.util.concurrent.Executor;
|
|
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
|
|
|
/* loaded from: classes2.dex */
|
|
public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|
private static final int HEVC_MAX_INPUT_SIZE_THRESHOLD = 2097152;
|
|
private static final float INITIAL_FORMAT_MAX_INPUT_SIZE_SCALE_FACTOR = 1.5f;
|
|
private static final String KEY_CROP_BOTTOM = "crop-bottom";
|
|
private static final String KEY_CROP_LEFT = "crop-left";
|
|
private static final String KEY_CROP_RIGHT = "crop-right";
|
|
private static final String KEY_CROP_TOP = "crop-top";
|
|
private static final int[] STANDARD_LONG_EDGE_VIDEO_PX = {1920, 1600, 1440, PlatformPlugin.DEFAULT_SYSTEM_UI, 960, 854, 640, 540, 480};
|
|
private static final String TAG = "MediaCodecVideoRenderer";
|
|
private static final long TUNNELING_EOS_PRESENTATION_TIME_US = Long.MAX_VALUE;
|
|
private static boolean deviceNeedsSetOutputSurfaceWorkaround;
|
|
private static boolean evaluatedDeviceNeedsSetOutputSurfaceWorkaround;
|
|
private final long allowedJoiningTimeMs;
|
|
private int buffersInCodecCount;
|
|
private boolean codecHandlesHdr10PlusOutOfBandMetadata;
|
|
private CodecMaxValues codecMaxValues;
|
|
private boolean codecNeedsSetOutputSurfaceWorkaround;
|
|
private int consecutiveDroppedFrameCount;
|
|
private final Context context;
|
|
private VideoSize decodedVideoSize;
|
|
private final boolean deviceNeedsNoPostProcessWorkaround;
|
|
private Surface displaySurface;
|
|
private long droppedFrameAccumulationStartTimeMs;
|
|
private int droppedFrames;
|
|
private final VideoRendererEventListener.EventDispatcher eventDispatcher;
|
|
private VideoFrameMetadataListener frameMetadataListener;
|
|
private final VideoFrameReleaseHelper frameReleaseHelper;
|
|
private boolean haveReportedFirstFrameRenderedForCurrentSurface;
|
|
private long initialPositionUs;
|
|
private long joiningDeadlineMs;
|
|
private long lastBufferPresentationTimeUs;
|
|
private long lastFrameReleaseTimeNs;
|
|
private long lastRenderRealtimeUs;
|
|
private final int maxDroppedFramesToNotify;
|
|
private boolean mayRenderFirstFrameAfterEnableIfNotStarted;
|
|
private PlaceholderSurface placeholderSurface;
|
|
private boolean renderedFirstFrameAfterEnable;
|
|
private boolean renderedFirstFrameAfterReset;
|
|
private VideoSize reportedVideoSize;
|
|
private int scalingMode;
|
|
private long totalVideoFrameProcessingOffsetUs;
|
|
private boolean tunneling;
|
|
private int tunnelingAudioSessionId;
|
|
OnFrameRenderedListenerV23 tunnelingOnFrameRenderedListener;
|
|
private int videoFrameProcessingOffsetCount;
|
|
private final VideoFrameProcessorManager videoFrameProcessorManager;
|
|
|
|
private void clearReportedVideoSize() {
|
|
this.reportedVideoSize = null;
|
|
}
|
|
|
|
private static boolean isBufferLate(long j) {
|
|
return j < -30000;
|
|
}
|
|
|
|
private static boolean isBufferVeryLate(long j) {
|
|
return j < -500000;
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.Renderer, androidx.media3.exoplayer.RendererCapabilities
|
|
public String getName() {
|
|
return TAG;
|
|
}
|
|
|
|
protected Surface getSurface() {
|
|
return this.displaySurface;
|
|
}
|
|
|
|
static /* synthetic */ boolean access$000() {
|
|
return codecAppliesRotation();
|
|
}
|
|
|
|
public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector) {
|
|
this(context, mediaCodecSelector, 0L);
|
|
}
|
|
|
|
public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, long j) {
|
|
this(context, mediaCodecSelector, j, null, null, 0);
|
|
}
|
|
|
|
public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, long j, Handler handler, VideoRendererEventListener videoRendererEventListener, int i) {
|
|
this(context, MediaCodecAdapter.Factory.DEFAULT, mediaCodecSelector, j, false, handler, videoRendererEventListener, i, 30.0f);
|
|
}
|
|
|
|
public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector, long j, boolean z, Handler handler, VideoRendererEventListener videoRendererEventListener, int i) {
|
|
this(context, MediaCodecAdapter.Factory.DEFAULT, mediaCodecSelector, j, z, handler, videoRendererEventListener, i, 30.0f);
|
|
}
|
|
|
|
public MediaCodecVideoRenderer(Context context, MediaCodecAdapter.Factory factory, MediaCodecSelector mediaCodecSelector, long j, boolean z, Handler handler, VideoRendererEventListener videoRendererEventListener, int i) {
|
|
this(context, factory, mediaCodecSelector, j, z, handler, videoRendererEventListener, i, 30.0f);
|
|
}
|
|
|
|
public MediaCodecVideoRenderer(Context context, MediaCodecAdapter.Factory factory, MediaCodecSelector mediaCodecSelector, long j, boolean z, Handler handler, VideoRendererEventListener videoRendererEventListener, int i, float f) {
|
|
super(2, factory, mediaCodecSelector, z, f);
|
|
this.allowedJoiningTimeMs = j;
|
|
this.maxDroppedFramesToNotify = i;
|
|
Context applicationContext = context.getApplicationContext();
|
|
this.context = applicationContext;
|
|
VideoFrameReleaseHelper videoFrameReleaseHelper = new VideoFrameReleaseHelper(applicationContext);
|
|
this.frameReleaseHelper = videoFrameReleaseHelper;
|
|
this.eventDispatcher = new VideoRendererEventListener.EventDispatcher(handler, videoRendererEventListener);
|
|
this.videoFrameProcessorManager = new VideoFrameProcessorManager(videoFrameReleaseHelper, this);
|
|
this.deviceNeedsNoPostProcessWorkaround = deviceNeedsNoPostProcessWorkaround();
|
|
this.joiningDeadlineMs = -9223372036854775807L;
|
|
this.scalingMode = 1;
|
|
this.decodedVideoSize = VideoSize.UNKNOWN;
|
|
this.tunnelingAudioSessionId = 0;
|
|
clearReportedVideoSize();
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format) throws MediaCodecUtil.DecoderQueryException {
|
|
boolean z;
|
|
int i = 0;
|
|
if (!MimeTypes.isVideo(format.sampleMimeType)) {
|
|
return RendererCapabilities.create(0);
|
|
}
|
|
boolean z2 = format.drmInitData != null;
|
|
List<MediaCodecInfo> decoderInfos = getDecoderInfos(this.context, mediaCodecSelector, format, z2, false);
|
|
if (z2 && decoderInfos.isEmpty()) {
|
|
decoderInfos = getDecoderInfos(this.context, mediaCodecSelector, format, false, false);
|
|
}
|
|
if (decoderInfos.isEmpty()) {
|
|
return RendererCapabilities.create(1);
|
|
}
|
|
if (!supportsFormatDrm(format)) {
|
|
return RendererCapabilities.create(2);
|
|
}
|
|
MediaCodecInfo mediaCodecInfo = decoderInfos.get(0);
|
|
boolean isFormatSupported = mediaCodecInfo.isFormatSupported(format);
|
|
if (!isFormatSupported) {
|
|
for (int i2 = 1; i2 < decoderInfos.size(); i2++) {
|
|
MediaCodecInfo mediaCodecInfo2 = decoderInfos.get(i2);
|
|
if (mediaCodecInfo2.isFormatSupported(format)) {
|
|
z = false;
|
|
isFormatSupported = true;
|
|
mediaCodecInfo = mediaCodecInfo2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
z = true;
|
|
int i3 = isFormatSupported ? 4 : 3;
|
|
int i4 = mediaCodecInfo.isSeamlessAdaptationSupported(format) ? 16 : 8;
|
|
int i5 = mediaCodecInfo.hardwareAccelerated ? 64 : 0;
|
|
int i6 = z ? 128 : 0;
|
|
if (Util.SDK_INT >= 26 && "video/dolby-vision".equals(format.sampleMimeType) && !Api26.doesDisplaySupportDolbyVision(this.context)) {
|
|
i6 = 256;
|
|
}
|
|
if (isFormatSupported) {
|
|
List<MediaCodecInfo> decoderInfos2 = getDecoderInfos(this.context, mediaCodecSelector, format, z2, true);
|
|
if (!decoderInfos2.isEmpty()) {
|
|
MediaCodecInfo mediaCodecInfo3 = MediaCodecUtil.getDecoderInfosSortedByFormatSupport(decoderInfos2, format).get(0);
|
|
if (mediaCodecInfo3.isFormatSupported(format) && mediaCodecInfo3.isSeamlessAdaptationSupported(format)) {
|
|
i = 32;
|
|
}
|
|
}
|
|
}
|
|
return RendererCapabilities.create(i3, i4, i, i5, i6);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected List<MediaCodecInfo> getDecoderInfos(MediaCodecSelector mediaCodecSelector, Format format, boolean z) throws MediaCodecUtil.DecoderQueryException {
|
|
return MediaCodecUtil.getDecoderInfosSortedByFormatSupport(getDecoderInfos(this.context, mediaCodecSelector, format, z, this.tunneling), format);
|
|
}
|
|
|
|
private static List<MediaCodecInfo> getDecoderInfos(Context context, MediaCodecSelector mediaCodecSelector, Format format, boolean z, boolean z2) throws MediaCodecUtil.DecoderQueryException {
|
|
if (format.sampleMimeType == null) {
|
|
return ImmutableList.of();
|
|
}
|
|
if (Util.SDK_INT >= 26 && "video/dolby-vision".equals(format.sampleMimeType) && !Api26.doesDisplaySupportDolbyVision(context)) {
|
|
List<MediaCodecInfo> alternativeDecoderInfos = MediaCodecUtil.getAlternativeDecoderInfos(mediaCodecSelector, format, z, z2);
|
|
if (!alternativeDecoderInfos.isEmpty()) {
|
|
return alternativeDecoderInfos;
|
|
}
|
|
}
|
|
return MediaCodecUtil.getDecoderInfosSoftMatch(mediaCodecSelector, format, z, z2);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes2.dex */
|
|
public static final class Api26 {
|
|
private Api26() {
|
|
}
|
|
|
|
public static boolean doesDisplaySupportDolbyVision(Context context) {
|
|
DisplayManager displayManager = (DisplayManager) context.getSystemService("display");
|
|
Display display = displayManager != null ? displayManager.getDisplay(0) : null;
|
|
if (display == null || !display.isHdr()) {
|
|
return false;
|
|
}
|
|
for (int i : display.getHdrCapabilities().getSupportedHdrTypes()) {
|
|
if (i == 1) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.BaseRenderer
|
|
public void onEnabled(boolean z, boolean z2) throws ExoPlaybackException {
|
|
super.onEnabled(z, z2);
|
|
boolean z3 = getConfiguration().tunneling;
|
|
Assertions.checkState((z3 && this.tunnelingAudioSessionId == 0) ? false : true);
|
|
if (this.tunneling != z3) {
|
|
this.tunneling = z3;
|
|
releaseCodec();
|
|
}
|
|
this.eventDispatcher.enabled(this.decoderCounters);
|
|
this.mayRenderFirstFrameAfterEnableIfNotStarted = z2;
|
|
this.renderedFirstFrameAfterEnable = false;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.BaseRenderer
|
|
public void onPositionReset(long j, boolean z) throws ExoPlaybackException {
|
|
super.onPositionReset(j, z);
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.flush();
|
|
}
|
|
clearRenderedFirstFrame();
|
|
this.frameReleaseHelper.onPositionReset();
|
|
this.lastBufferPresentationTimeUs = -9223372036854775807L;
|
|
this.initialPositionUs = -9223372036854775807L;
|
|
this.consecutiveDroppedFrameCount = 0;
|
|
if (z) {
|
|
setJoiningDeadlineMs();
|
|
} else {
|
|
this.joiningDeadlineMs = -9223372036854775807L;
|
|
}
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.Renderer
|
|
public boolean isEnded() {
|
|
boolean isEnded = super.isEnded();
|
|
return this.videoFrameProcessorManager.isEnabled() ? isEnded & this.videoFrameProcessorManager.releasedLastFrame() : isEnded;
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.Renderer
|
|
public boolean isReady() {
|
|
PlaceholderSurface placeholderSurface;
|
|
if (super.isReady() && ((!this.videoFrameProcessorManager.isEnabled() || this.videoFrameProcessorManager.isReady()) && (this.renderedFirstFrameAfterReset || (((placeholderSurface = this.placeholderSurface) != null && this.displaySurface == placeholderSurface) || getCodec() == null || this.tunneling)))) {
|
|
this.joiningDeadlineMs = -9223372036854775807L;
|
|
return true;
|
|
}
|
|
if (this.joiningDeadlineMs == -9223372036854775807L) {
|
|
return false;
|
|
}
|
|
if (SystemClock.elapsedRealtime() < this.joiningDeadlineMs) {
|
|
return true;
|
|
}
|
|
this.joiningDeadlineMs = -9223372036854775807L;
|
|
return false;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.BaseRenderer
|
|
public void onStarted() {
|
|
super.onStarted();
|
|
this.droppedFrames = 0;
|
|
this.droppedFrameAccumulationStartTimeMs = SystemClock.elapsedRealtime();
|
|
this.lastRenderRealtimeUs = SystemClock.elapsedRealtime() * 1000;
|
|
this.totalVideoFrameProcessingOffsetUs = 0L;
|
|
this.videoFrameProcessingOffsetCount = 0;
|
|
this.frameReleaseHelper.onStarted();
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.BaseRenderer
|
|
public void onStopped() {
|
|
this.joiningDeadlineMs = -9223372036854775807L;
|
|
maybeNotifyDroppedFrames();
|
|
maybeNotifyVideoFrameProcessingOffset();
|
|
this.frameReleaseHelper.onStopped();
|
|
super.onStopped();
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.BaseRenderer
|
|
public void onDisabled() {
|
|
clearReportedVideoSize();
|
|
clearRenderedFirstFrame();
|
|
this.haveReportedFirstFrameRenderedForCurrentSurface = false;
|
|
this.tunnelingOnFrameRenderedListener = null;
|
|
try {
|
|
super.onDisabled();
|
|
} finally {
|
|
this.eventDispatcher.disabled(this.decoderCounters);
|
|
this.eventDispatcher.videoSizeChanged(VideoSize.UNKNOWN);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.BaseRenderer
|
|
public void onReset() {
|
|
try {
|
|
super.onReset();
|
|
} finally {
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.reset();
|
|
}
|
|
if (this.placeholderSurface != null) {
|
|
releasePlaceholderSurface();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.BaseRenderer, androidx.media3.exoplayer.PlayerMessage.Target
|
|
public void handleMessage(int i, Object obj) throws ExoPlaybackException {
|
|
Surface surface;
|
|
if (i == 1) {
|
|
setOutput(obj);
|
|
return;
|
|
}
|
|
if (i == 7) {
|
|
this.frameMetadataListener = (VideoFrameMetadataListener) obj;
|
|
return;
|
|
}
|
|
if (i == 10) {
|
|
int intValue = ((Integer) obj).intValue();
|
|
if (this.tunnelingAudioSessionId != intValue) {
|
|
this.tunnelingAudioSessionId = intValue;
|
|
if (this.tunneling) {
|
|
releaseCodec();
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
if (i == 4) {
|
|
this.scalingMode = ((Integer) obj).intValue();
|
|
MediaCodecAdapter codec = getCodec();
|
|
if (codec != null) {
|
|
codec.setVideoScalingMode(this.scalingMode);
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
if (i == 5) {
|
|
this.frameReleaseHelper.setChangeFrameRateStrategy(((Integer) obj).intValue());
|
|
return;
|
|
}
|
|
if (i == 13) {
|
|
this.videoFrameProcessorManager.setVideoEffects((List) Assertions.checkNotNull(obj));
|
|
return;
|
|
}
|
|
if (i == 14) {
|
|
Size size = (Size) Assertions.checkNotNull(obj);
|
|
if (size.getWidth() == 0 || size.getHeight() == 0 || (surface = this.displaySurface) == null) {
|
|
return;
|
|
}
|
|
this.videoFrameProcessorManager.setOutputSurfaceInfo(surface, size);
|
|
return;
|
|
}
|
|
super.handleMessage(i, obj);
|
|
}
|
|
|
|
/* JADX WARN: Multi-variable type inference failed */
|
|
/* JADX WARN: Type inference failed for: r4v0, types: [androidx.media3.exoplayer.video.MediaCodecVideoRenderer] */
|
|
/* JADX WARN: Type inference failed for: r5v9, types: [android.view.Surface] */
|
|
private void setOutput(Object obj) throws ExoPlaybackException {
|
|
PlaceholderSurface placeholderSurface = obj instanceof Surface ? (Surface) obj : null;
|
|
if (placeholderSurface == null) {
|
|
PlaceholderSurface placeholderSurface2 = this.placeholderSurface;
|
|
if (placeholderSurface2 != null) {
|
|
placeholderSurface = placeholderSurface2;
|
|
} else {
|
|
MediaCodecInfo codecInfo = getCodecInfo();
|
|
if (codecInfo != null && shouldUsePlaceholderSurface(codecInfo)) {
|
|
placeholderSurface = PlaceholderSurface.newInstanceV17(this.context, codecInfo.secure);
|
|
this.placeholderSurface = placeholderSurface;
|
|
}
|
|
}
|
|
}
|
|
if (this.displaySurface == placeholderSurface) {
|
|
if (placeholderSurface == null || placeholderSurface == this.placeholderSurface) {
|
|
return;
|
|
}
|
|
maybeRenotifyVideoSizeChanged();
|
|
maybeRenotifyRenderedFirstFrame();
|
|
return;
|
|
}
|
|
this.displaySurface = placeholderSurface;
|
|
this.frameReleaseHelper.onSurfaceChanged(placeholderSurface);
|
|
this.haveReportedFirstFrameRenderedForCurrentSurface = false;
|
|
int state = getState();
|
|
MediaCodecAdapter codec = getCodec();
|
|
if (codec != null && !this.videoFrameProcessorManager.isEnabled()) {
|
|
if (Util.SDK_INT >= 23 && placeholderSurface != null && !this.codecNeedsSetOutputSurfaceWorkaround) {
|
|
setOutputSurfaceV23(codec, placeholderSurface);
|
|
} else {
|
|
releaseCodec();
|
|
maybeInitCodecOrBypass();
|
|
}
|
|
}
|
|
if (placeholderSurface != null && placeholderSurface != this.placeholderSurface) {
|
|
maybeRenotifyVideoSizeChanged();
|
|
clearRenderedFirstFrame();
|
|
if (state == 2) {
|
|
setJoiningDeadlineMs();
|
|
}
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.setOutputSurfaceInfo(placeholderSurface, Size.UNKNOWN);
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
clearReportedVideoSize();
|
|
clearRenderedFirstFrame();
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.clearOutputSurfaceInfo();
|
|
}
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected boolean shouldInitCodec(MediaCodecInfo mediaCodecInfo) {
|
|
return this.displaySurface != null || shouldUsePlaceholderSurface(mediaCodecInfo);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected boolean getCodecNeedsEosPropagation() {
|
|
return this.tunneling && Util.SDK_INT < 23;
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected MediaCodecAdapter.Configuration getMediaCodecConfiguration(MediaCodecInfo mediaCodecInfo, Format format, MediaCrypto mediaCrypto, float f) {
|
|
PlaceholderSurface placeholderSurface = this.placeholderSurface;
|
|
if (placeholderSurface != null && placeholderSurface.secure != mediaCodecInfo.secure) {
|
|
releasePlaceholderSurface();
|
|
}
|
|
String str = mediaCodecInfo.codecMimeType;
|
|
CodecMaxValues codecMaxValues = getCodecMaxValues(mediaCodecInfo, format, getStreamFormats());
|
|
this.codecMaxValues = codecMaxValues;
|
|
MediaFormat mediaFormat = getMediaFormat(format, str, codecMaxValues, f, this.deviceNeedsNoPostProcessWorkaround, this.tunneling ? this.tunnelingAudioSessionId : 0);
|
|
if (this.displaySurface == null) {
|
|
if (!shouldUsePlaceholderSurface(mediaCodecInfo)) {
|
|
throw new IllegalStateException();
|
|
}
|
|
if (this.placeholderSurface == null) {
|
|
this.placeholderSurface = PlaceholderSurface.newInstanceV17(this.context, mediaCodecInfo.secure);
|
|
}
|
|
this.displaySurface = this.placeholderSurface;
|
|
}
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
mediaFormat = this.videoFrameProcessorManager.amendMediaFormatKeys(mediaFormat);
|
|
}
|
|
return MediaCodecAdapter.Configuration.createForVideoDecoding(mediaCodecInfo, mediaFormat, format, this.videoFrameProcessorManager.isEnabled() ? this.videoFrameProcessorManager.getInputSurface() : this.displaySurface, mediaCrypto);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected DecoderReuseEvaluation canReuseCodec(MediaCodecInfo mediaCodecInfo, Format format, Format format2) {
|
|
DecoderReuseEvaluation canReuseCodec = mediaCodecInfo.canReuseCodec(format, format2);
|
|
int i = canReuseCodec.discardReasons;
|
|
if (format2.width > this.codecMaxValues.width || format2.height > this.codecMaxValues.height) {
|
|
i |= 256;
|
|
}
|
|
if (getMaxInputSize(mediaCodecInfo, format2) > this.codecMaxValues.inputSize) {
|
|
i |= 64;
|
|
}
|
|
int i2 = i;
|
|
return new DecoderReuseEvaluation(mediaCodecInfo.name, format, format2, i2 != 0 ? 0 : canReuseCodec.result, i2);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.Renderer
|
|
public void render(long j, long j2) throws ExoPlaybackException {
|
|
super.render(j, j2);
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.releaseProcessedFrames(j, j2);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
public void resetCodecStateForFlush() {
|
|
super.resetCodecStateForFlush();
|
|
this.buffersInCodecCount = 0;
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer, androidx.media3.exoplayer.Renderer
|
|
public void setPlaybackSpeed(float f, float f2) throws ExoPlaybackException {
|
|
super.setPlaybackSpeed(f, f2);
|
|
this.frameReleaseHelper.onPlaybackSpeed(f);
|
|
}
|
|
|
|
/* JADX WARN: Can't fix incorrect switch cases order, some code will duplicate */
|
|
/* JADX WARN: Code restructure failed: missing block: B:55:0x007a, code lost:
|
|
|
|
if (r3.equals("video/av01") == false) goto L18;
|
|
*/
|
|
/*
|
|
Code decompiled incorrectly, please refer to instructions dump.
|
|
To view partially-correct add '--show-bad-code' argument
|
|
*/
|
|
public static int getCodecMaxInputSize(androidx.media3.exoplayer.mediacodec.MediaCodecInfo r9, androidx.media3.common.Format r10) {
|
|
/*
|
|
Method dump skipped, instructions count: 276
|
|
To view this dump add '--comments-level debug' option
|
|
*/
|
|
throw new UnsupportedOperationException("Method not decompiled: androidx.media3.exoplayer.video.MediaCodecVideoRenderer.getCodecMaxInputSize(androidx.media3.exoplayer.mediacodec.MediaCodecInfo, androidx.media3.common.Format):int");
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected float getCodecOperatingRateV23(float f, Format format, Format[] formatArr) {
|
|
float f2 = -1.0f;
|
|
for (Format format2 : formatArr) {
|
|
float f3 = format2.frameRate;
|
|
if (f3 != -1.0f) {
|
|
f2 = Math.max(f2, f3);
|
|
}
|
|
}
|
|
if (f2 == -1.0f) {
|
|
return -1.0f;
|
|
}
|
|
return f2 * f;
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected void onReadyToInitializeCodec(Format format) throws ExoPlaybackException {
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
return;
|
|
}
|
|
this.videoFrameProcessorManager.maybeEnable(format, getOutputStreamOffsetUs());
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected void onCodecInitialized(String str, MediaCodecAdapter.Configuration configuration, long j, long j2) {
|
|
this.eventDispatcher.decoderInitialized(str, j, j2);
|
|
this.codecNeedsSetOutputSurfaceWorkaround = codecNeedsSetOutputSurfaceWorkaround(str);
|
|
this.codecHandlesHdr10PlusOutOfBandMetadata = ((MediaCodecInfo) Assertions.checkNotNull(getCodecInfo())).isHdr10PlusOutOfBandMetadataSupported();
|
|
if (Util.SDK_INT >= 23 && this.tunneling) {
|
|
this.tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23((MediaCodecAdapter) Assertions.checkNotNull(getCodec()));
|
|
}
|
|
this.videoFrameProcessorManager.onCodecInitialized(str);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected void onCodecReleased(String str) {
|
|
this.eventDispatcher.decoderReleased(str);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected void onCodecError(Exception exc) {
|
|
Log.e(TAG, "Video codec error", exc);
|
|
this.eventDispatcher.videoCodecError(exc);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
public DecoderReuseEvaluation onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackException {
|
|
DecoderReuseEvaluation onInputFormatChanged = super.onInputFormatChanged(formatHolder);
|
|
this.eventDispatcher.inputFormatChanged(formatHolder.format, onInputFormatChanged);
|
|
return onInputFormatChanged;
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected void onQueueInputBuffer(DecoderInputBuffer decoderInputBuffer) throws ExoPlaybackException {
|
|
if (!this.tunneling) {
|
|
this.buffersInCodecCount++;
|
|
}
|
|
if (Util.SDK_INT >= 23 || !this.tunneling) {
|
|
return;
|
|
}
|
|
onProcessedTunneledBuffer(decoderInputBuffer.timeUs);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected void onOutputFormatChanged(Format format, MediaFormat mediaFormat) {
|
|
int integer;
|
|
int integer2;
|
|
int i;
|
|
int i2;
|
|
MediaCodecAdapter codec = getCodec();
|
|
if (codec != null) {
|
|
codec.setVideoScalingMode(this.scalingMode);
|
|
}
|
|
int i3 = 0;
|
|
if (this.tunneling) {
|
|
i2 = format.width;
|
|
i = format.height;
|
|
} else {
|
|
Assertions.checkNotNull(mediaFormat);
|
|
boolean z = mediaFormat.containsKey(KEY_CROP_RIGHT) && mediaFormat.containsKey(KEY_CROP_LEFT) && mediaFormat.containsKey(KEY_CROP_BOTTOM) && mediaFormat.containsKey(KEY_CROP_TOP);
|
|
if (z) {
|
|
integer = (mediaFormat.getInteger(KEY_CROP_RIGHT) - mediaFormat.getInteger(KEY_CROP_LEFT)) + 1;
|
|
} else {
|
|
integer = mediaFormat.getInteger(ViewHierarchyNode.JsonKeys.WIDTH);
|
|
}
|
|
if (z) {
|
|
integer2 = (mediaFormat.getInteger(KEY_CROP_BOTTOM) - mediaFormat.getInteger(KEY_CROP_TOP)) + 1;
|
|
} else {
|
|
integer2 = mediaFormat.getInteger(ViewHierarchyNode.JsonKeys.HEIGHT);
|
|
}
|
|
int i4 = integer;
|
|
i = integer2;
|
|
i2 = i4;
|
|
}
|
|
float f = format.pixelWidthHeightRatio;
|
|
if (codecAppliesRotation()) {
|
|
if (format.rotationDegrees == 90 || format.rotationDegrees == 270) {
|
|
f = 1.0f / f;
|
|
int i5 = i;
|
|
i = i2;
|
|
i2 = i5;
|
|
}
|
|
} else if (!this.videoFrameProcessorManager.isEnabled()) {
|
|
i3 = format.rotationDegrees;
|
|
}
|
|
this.decodedVideoSize = new VideoSize(i2, i, i3, f);
|
|
this.frameReleaseHelper.onFormatChanged(format.frameRate);
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.setInputFormat(format.buildUpon().setWidth(i2).setHeight(i).setRotationDegrees(i3).setPixelWidthHeightRatio(f).build());
|
|
}
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected void handleInputBufferSupplementalData(DecoderInputBuffer decoderInputBuffer) throws ExoPlaybackException {
|
|
if (this.codecHandlesHdr10PlusOutOfBandMetadata) {
|
|
ByteBuffer byteBuffer = (ByteBuffer) Assertions.checkNotNull(decoderInputBuffer.supplementalData);
|
|
if (byteBuffer.remaining() >= 7) {
|
|
byte b = byteBuffer.get();
|
|
short s = byteBuffer.getShort();
|
|
short s2 = byteBuffer.getShort();
|
|
byte b2 = byteBuffer.get();
|
|
byte b3 = byteBuffer.get();
|
|
byteBuffer.position(0);
|
|
if (b == -75 && s == 60 && s2 == 1 && b2 == 4) {
|
|
if (b3 == 0 || b3 == 1) {
|
|
byte[] bArr = new byte[byteBuffer.remaining()];
|
|
byteBuffer.get(bArr);
|
|
byteBuffer.position(0);
|
|
setHdr10PlusInfoV29(getCodec(), bArr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected boolean processOutputBuffer(long j, long j2, MediaCodecAdapter mediaCodecAdapter, ByteBuffer byteBuffer, int i, int i2, int i3, long j3, boolean z, boolean z2, Format format) throws ExoPlaybackException {
|
|
Assertions.checkNotNull(mediaCodecAdapter);
|
|
if (this.initialPositionUs == -9223372036854775807L) {
|
|
this.initialPositionUs = j;
|
|
}
|
|
if (j3 != this.lastBufferPresentationTimeUs) {
|
|
if (!this.videoFrameProcessorManager.isEnabled()) {
|
|
this.frameReleaseHelper.onNextFrame(j3);
|
|
}
|
|
this.lastBufferPresentationTimeUs = j3;
|
|
}
|
|
long outputStreamOffsetUs = j3 - getOutputStreamOffsetUs();
|
|
if (z && !z2) {
|
|
skipOutputBuffer(mediaCodecAdapter, i, outputStreamOffsetUs);
|
|
return true;
|
|
}
|
|
boolean z3 = false;
|
|
boolean z4 = getState() == 2;
|
|
long calculateEarlyTimeUs = calculateEarlyTimeUs(j, j2, SystemClock.elapsedRealtime() * 1000, j3, z4);
|
|
if (this.displaySurface == this.placeholderSurface) {
|
|
if (!isBufferLate(calculateEarlyTimeUs)) {
|
|
return false;
|
|
}
|
|
skipOutputBuffer(mediaCodecAdapter, i, outputStreamOffsetUs);
|
|
updateVideoFrameProcessingOffsetCounters(calculateEarlyTimeUs);
|
|
return true;
|
|
}
|
|
if (shouldForceRender(j, calculateEarlyTimeUs)) {
|
|
if (!this.videoFrameProcessorManager.isEnabled()) {
|
|
z3 = true;
|
|
} else if (!this.videoFrameProcessorManager.maybeRegisterFrame(format, outputStreamOffsetUs, z2)) {
|
|
return false;
|
|
}
|
|
renderOutputBufferNow(mediaCodecAdapter, format, i, outputStreamOffsetUs, z3);
|
|
updateVideoFrameProcessingOffsetCounters(calculateEarlyTimeUs);
|
|
return true;
|
|
}
|
|
if (z4 && j != this.initialPositionUs) {
|
|
long nanoTime = System.nanoTime();
|
|
long adjustReleaseTime = this.frameReleaseHelper.adjustReleaseTime((calculateEarlyTimeUs * 1000) + nanoTime);
|
|
if (!this.videoFrameProcessorManager.isEnabled()) {
|
|
calculateEarlyTimeUs = (adjustReleaseTime - nanoTime) / 1000;
|
|
}
|
|
boolean z5 = this.joiningDeadlineMs != -9223372036854775807L;
|
|
if (shouldDropBuffersToKeyframe(calculateEarlyTimeUs, j2, z2) && maybeDropBuffersToKeyframe(j, z5)) {
|
|
return false;
|
|
}
|
|
if (shouldDropOutputBuffer(calculateEarlyTimeUs, j2, z2)) {
|
|
if (z5) {
|
|
skipOutputBuffer(mediaCodecAdapter, i, outputStreamOffsetUs);
|
|
} else {
|
|
dropOutputBuffer(mediaCodecAdapter, i, outputStreamOffsetUs);
|
|
}
|
|
updateVideoFrameProcessingOffsetCounters(calculateEarlyTimeUs);
|
|
return true;
|
|
}
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.releaseProcessedFrames(j, j2);
|
|
if (!this.videoFrameProcessorManager.maybeRegisterFrame(format, outputStreamOffsetUs, z2)) {
|
|
return false;
|
|
}
|
|
renderOutputBufferNow(mediaCodecAdapter, format, i, outputStreamOffsetUs, false);
|
|
return true;
|
|
}
|
|
if (Util.SDK_INT >= 21) {
|
|
if (calculateEarlyTimeUs < 50000) {
|
|
if (adjustReleaseTime == this.lastFrameReleaseTimeNs) {
|
|
skipOutputBuffer(mediaCodecAdapter, i, outputStreamOffsetUs);
|
|
} else {
|
|
notifyFrameMetadataListener(outputStreamOffsetUs, adjustReleaseTime, format);
|
|
renderOutputBufferV21(mediaCodecAdapter, i, outputStreamOffsetUs, adjustReleaseTime);
|
|
}
|
|
updateVideoFrameProcessingOffsetCounters(calculateEarlyTimeUs);
|
|
this.lastFrameReleaseTimeNs = adjustReleaseTime;
|
|
return true;
|
|
}
|
|
} else if (calculateEarlyTimeUs < 30000) {
|
|
if (calculateEarlyTimeUs > 11000) {
|
|
try {
|
|
Thread.sleep((calculateEarlyTimeUs - WorkRequest.MIN_BACKOFF_MILLIS) / 1000);
|
|
} catch (InterruptedException unused) {
|
|
Thread.currentThread().interrupt();
|
|
return false;
|
|
}
|
|
}
|
|
notifyFrameMetadataListener(outputStreamOffsetUs, adjustReleaseTime, format);
|
|
renderOutputBuffer(mediaCodecAdapter, i, outputStreamOffsetUs);
|
|
updateVideoFrameProcessingOffsetCounters(calculateEarlyTimeUs);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public boolean shouldForceRender(long j, long j2) {
|
|
boolean z = getState() == 2;
|
|
boolean z2 = this.renderedFirstFrameAfterEnable ? !this.renderedFirstFrameAfterReset : z || this.mayRenderFirstFrameAfterEnableIfNotStarted;
|
|
long elapsedRealtime = (SystemClock.elapsedRealtime() * 1000) - this.lastRenderRealtimeUs;
|
|
if (this.joiningDeadlineMs == -9223372036854775807L && j >= getOutputStreamOffsetUs()) {
|
|
if (z2) {
|
|
return true;
|
|
}
|
|
if (z && shouldForceRenderOutputBuffer(j2, elapsedRealtime)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public long calculateEarlyTimeUs(long j, long j2, long j3, long j4, boolean z) {
|
|
long playbackSpeed = (long) ((j4 - j) / getPlaybackSpeed());
|
|
return z ? playbackSpeed - (j3 - j2) : playbackSpeed;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void notifyFrameMetadataListener(long j, long j2, Format format) {
|
|
VideoFrameMetadataListener videoFrameMetadataListener = this.frameMetadataListener;
|
|
if (videoFrameMetadataListener != null) {
|
|
videoFrameMetadataListener.onVideoFrameAboutToBeRendered(j, j2, format, getCodecOutputMediaFormat());
|
|
}
|
|
}
|
|
|
|
protected void onProcessedTunneledBuffer(long j) throws ExoPlaybackException {
|
|
updateOutputFormatForTime(j);
|
|
maybeNotifyVideoSizeChanged(this.decodedVideoSize);
|
|
this.decoderCounters.renderedOutputBufferCount++;
|
|
maybeNotifyRenderedFirstFrame();
|
|
onProcessedOutputBuffer(j);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void onProcessedTunneledEndOfStream() {
|
|
setPendingOutputEndOfStream();
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
public void onProcessedOutputBuffer(long j) {
|
|
super.onProcessedOutputBuffer(j);
|
|
if (this.tunneling) {
|
|
return;
|
|
}
|
|
this.buffersInCodecCount--;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
public void onProcessedStreamChange() {
|
|
super.onProcessedStreamChange();
|
|
clearRenderedFirstFrame();
|
|
}
|
|
|
|
protected boolean shouldDropOutputBuffer(long j, long j2, boolean z) {
|
|
return isBufferLate(j) && !z;
|
|
}
|
|
|
|
protected boolean shouldDropBuffersToKeyframe(long j, long j2, boolean z) {
|
|
return isBufferVeryLate(j) && !z;
|
|
}
|
|
|
|
protected boolean shouldForceRenderOutputBuffer(long j, long j2) {
|
|
return isBufferLate(j) && j2 > 100000;
|
|
}
|
|
|
|
protected void skipOutputBuffer(MediaCodecAdapter mediaCodecAdapter, int i, long j) {
|
|
TraceUtil.beginSection("skipVideoBuffer");
|
|
mediaCodecAdapter.releaseOutputBuffer(i, false);
|
|
TraceUtil.endSection();
|
|
this.decoderCounters.skippedOutputBufferCount++;
|
|
}
|
|
|
|
protected void dropOutputBuffer(MediaCodecAdapter mediaCodecAdapter, int i, long j) {
|
|
TraceUtil.beginSection("dropVideoBuffer");
|
|
mediaCodecAdapter.releaseOutputBuffer(i, false);
|
|
TraceUtil.endSection();
|
|
updateDroppedBufferCounters(0, 1);
|
|
}
|
|
|
|
protected boolean maybeDropBuffersToKeyframe(long j, boolean z) throws ExoPlaybackException {
|
|
int skipSource = skipSource(j);
|
|
if (skipSource == 0) {
|
|
return false;
|
|
}
|
|
if (z) {
|
|
this.decoderCounters.skippedInputBufferCount += skipSource;
|
|
this.decoderCounters.skippedOutputBufferCount += this.buffersInCodecCount;
|
|
} else {
|
|
this.decoderCounters.droppedToKeyframeCount++;
|
|
updateDroppedBufferCounters(skipSource, this.buffersInCodecCount);
|
|
}
|
|
flushOrReinitializeCodec();
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
this.videoFrameProcessorManager.flush();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
protected void updateDroppedBufferCounters(int i, int i2) {
|
|
this.decoderCounters.droppedInputBufferCount += i;
|
|
int i3 = i + i2;
|
|
this.decoderCounters.droppedBufferCount += i3;
|
|
this.droppedFrames += i3;
|
|
this.consecutiveDroppedFrameCount += i3;
|
|
this.decoderCounters.maxConsecutiveDroppedBufferCount = Math.max(this.consecutiveDroppedFrameCount, this.decoderCounters.maxConsecutiveDroppedBufferCount);
|
|
int i4 = this.maxDroppedFramesToNotify;
|
|
if (i4 <= 0 || this.droppedFrames < i4) {
|
|
return;
|
|
}
|
|
maybeNotifyDroppedFrames();
|
|
}
|
|
|
|
protected void updateVideoFrameProcessingOffsetCounters(long j) {
|
|
this.decoderCounters.addVideoFrameProcessingOffset(j);
|
|
this.totalVideoFrameProcessingOffsetUs += j;
|
|
this.videoFrameProcessingOffsetCount++;
|
|
}
|
|
|
|
protected Pair<ColorInfo, ColorInfo> experimentalGetVideoFrameProcessorColorConfiguration(ColorInfo colorInfo) {
|
|
if (!ColorInfo.isTransferHdr(colorInfo)) {
|
|
return Pair.create(ColorInfo.SDR_BT709_LIMITED, ColorInfo.SDR_BT709_LIMITED);
|
|
}
|
|
if (colorInfo.colorTransfer == 7) {
|
|
return Pair.create(colorInfo, colorInfo.buildUpon().setColorTransfer(6).build());
|
|
}
|
|
return Pair.create(colorInfo, colorInfo);
|
|
}
|
|
|
|
private void renderOutputBufferNow(MediaCodecAdapter mediaCodecAdapter, Format format, int i, long j, boolean z) {
|
|
long nanoTime;
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
nanoTime = this.videoFrameProcessorManager.getCorrectedFramePresentationTimeUs(j, getOutputStreamOffsetUs()) * 1000;
|
|
} else {
|
|
nanoTime = System.nanoTime();
|
|
}
|
|
if (z) {
|
|
notifyFrameMetadataListener(j, nanoTime, format);
|
|
}
|
|
if (Util.SDK_INT >= 21) {
|
|
renderOutputBufferV21(mediaCodecAdapter, i, j, nanoTime);
|
|
} else {
|
|
renderOutputBuffer(mediaCodecAdapter, i, j);
|
|
}
|
|
}
|
|
|
|
protected void renderOutputBuffer(MediaCodecAdapter mediaCodecAdapter, int i, long j) {
|
|
TraceUtil.beginSection("releaseOutputBuffer");
|
|
mediaCodecAdapter.releaseOutputBuffer(i, true);
|
|
TraceUtil.endSection();
|
|
this.decoderCounters.renderedOutputBufferCount++;
|
|
this.consecutiveDroppedFrameCount = 0;
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
return;
|
|
}
|
|
this.lastRenderRealtimeUs = SystemClock.elapsedRealtime() * 1000;
|
|
maybeNotifyVideoSizeChanged(this.decodedVideoSize);
|
|
maybeNotifyRenderedFirstFrame();
|
|
}
|
|
|
|
protected void renderOutputBufferV21(MediaCodecAdapter mediaCodecAdapter, int i, long j, long j2) {
|
|
TraceUtil.beginSection("releaseOutputBuffer");
|
|
mediaCodecAdapter.releaseOutputBuffer(i, j2);
|
|
TraceUtil.endSection();
|
|
this.decoderCounters.renderedOutputBufferCount++;
|
|
this.consecutiveDroppedFrameCount = 0;
|
|
if (this.videoFrameProcessorManager.isEnabled()) {
|
|
return;
|
|
}
|
|
this.lastRenderRealtimeUs = SystemClock.elapsedRealtime() * 1000;
|
|
maybeNotifyVideoSizeChanged(this.decodedVideoSize);
|
|
maybeNotifyRenderedFirstFrame();
|
|
}
|
|
|
|
private boolean shouldUsePlaceholderSurface(MediaCodecInfo mediaCodecInfo) {
|
|
return Util.SDK_INT >= 23 && !this.tunneling && !codecNeedsSetOutputSurfaceWorkaround(mediaCodecInfo.name) && (!mediaCodecInfo.secure || PlaceholderSurface.isSecureSupported(this.context));
|
|
}
|
|
|
|
private void releasePlaceholderSurface() {
|
|
Surface surface = this.displaySurface;
|
|
PlaceholderSurface placeholderSurface = this.placeholderSurface;
|
|
if (surface == placeholderSurface) {
|
|
this.displaySurface = null;
|
|
}
|
|
placeholderSurface.release();
|
|
this.placeholderSurface = null;
|
|
}
|
|
|
|
private void setJoiningDeadlineMs() {
|
|
this.joiningDeadlineMs = this.allowedJoiningTimeMs > 0 ? SystemClock.elapsedRealtime() + this.allowedJoiningTimeMs : -9223372036854775807L;
|
|
}
|
|
|
|
private void clearRenderedFirstFrame() {
|
|
MediaCodecAdapter codec;
|
|
this.renderedFirstFrameAfterReset = false;
|
|
if (Util.SDK_INT < 23 || !this.tunneling || (codec = getCodec()) == null) {
|
|
return;
|
|
}
|
|
this.tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
|
|
}
|
|
|
|
void maybeNotifyRenderedFirstFrame() {
|
|
this.renderedFirstFrameAfterEnable = true;
|
|
if (this.renderedFirstFrameAfterReset) {
|
|
return;
|
|
}
|
|
this.renderedFirstFrameAfterReset = true;
|
|
this.eventDispatcher.renderedFirstFrame(this.displaySurface);
|
|
this.haveReportedFirstFrameRenderedForCurrentSurface = true;
|
|
}
|
|
|
|
private void maybeRenotifyRenderedFirstFrame() {
|
|
if (this.haveReportedFirstFrameRenderedForCurrentSurface) {
|
|
this.eventDispatcher.renderedFirstFrame(this.displaySurface);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void maybeNotifyVideoSizeChanged(VideoSize videoSize) {
|
|
if (videoSize.equals(VideoSize.UNKNOWN) || videoSize.equals(this.reportedVideoSize)) {
|
|
return;
|
|
}
|
|
this.reportedVideoSize = videoSize;
|
|
this.eventDispatcher.videoSizeChanged(videoSize);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
private void maybeNotifyVideoFrameProcessingOffset() {
|
|
int i = this.videoFrameProcessingOffsetCount;
|
|
if (i != 0) {
|
|
this.eventDispatcher.reportVideoFrameProcessingOffset(this.totalVideoFrameProcessingOffsetUs, i);
|
|
this.totalVideoFrameProcessingOffsetUs = 0L;
|
|
this.videoFrameProcessingOffsetCount = 0;
|
|
}
|
|
}
|
|
|
|
private static void setHdr10PlusInfoV29(MediaCodecAdapter mediaCodecAdapter, byte[] bArr) {
|
|
Bundle bundle = new Bundle();
|
|
bundle.putByteArray("hdr10-plus-info", bArr);
|
|
mediaCodecAdapter.setParameters(bundle);
|
|
}
|
|
|
|
protected void setOutputSurfaceV23(MediaCodecAdapter mediaCodecAdapter, Surface surface) {
|
|
mediaCodecAdapter.setOutputSurface(surface);
|
|
}
|
|
|
|
private static void configureTunnelingV21(MediaFormat mediaFormat, int i) {
|
|
mediaFormat.setFeatureEnabled("tunneled-playback", true);
|
|
mediaFormat.setInteger("audio-session-id", i);
|
|
}
|
|
|
|
protected MediaFormat getMediaFormat(Format format, String str, CodecMaxValues codecMaxValues, float f, boolean z, int i) {
|
|
Pair<Integer, Integer> codecProfileAndLevel;
|
|
MediaFormat mediaFormat = new MediaFormat();
|
|
mediaFormat.setString("mime", str);
|
|
mediaFormat.setInteger(ViewHierarchyNode.JsonKeys.WIDTH, format.width);
|
|
mediaFormat.setInteger(ViewHierarchyNode.JsonKeys.HEIGHT, format.height);
|
|
MediaFormatUtil.setCsdBuffers(mediaFormat, format.initializationData);
|
|
MediaFormatUtil.maybeSetFloat(mediaFormat, "frame-rate", format.frameRate);
|
|
MediaFormatUtil.maybeSetInteger(mediaFormat, "rotation-degrees", format.rotationDegrees);
|
|
MediaFormatUtil.maybeSetColorInfo(mediaFormat, format.colorInfo);
|
|
if ("video/dolby-vision".equals(format.sampleMimeType) && (codecProfileAndLevel = MediaCodecUtil.getCodecProfileAndLevel(format)) != null) {
|
|
MediaFormatUtil.maybeSetInteger(mediaFormat, "profile", ((Integer) codecProfileAndLevel.first).intValue());
|
|
}
|
|
mediaFormat.setInteger("max-width", codecMaxValues.width);
|
|
mediaFormat.setInteger("max-height", codecMaxValues.height);
|
|
MediaFormatUtil.maybeSetInteger(mediaFormat, "max-input-size", codecMaxValues.inputSize);
|
|
if (Util.SDK_INT >= 23) {
|
|
mediaFormat.setInteger(SentryThread.JsonKeys.PRIORITY, 0);
|
|
if (f != -1.0f) {
|
|
mediaFormat.setFloat("operating-rate", f);
|
|
}
|
|
}
|
|
if (z) {
|
|
mediaFormat.setInteger("no-post-process", 1);
|
|
mediaFormat.setInteger("auto-frc", 0);
|
|
}
|
|
if (i != 0) {
|
|
configureTunnelingV21(mediaFormat, i);
|
|
}
|
|
return mediaFormat;
|
|
}
|
|
|
|
protected CodecMaxValues getCodecMaxValues(MediaCodecInfo mediaCodecInfo, Format format, Format[] formatArr) {
|
|
int codecMaxInputSize;
|
|
int i = format.width;
|
|
int i2 = format.height;
|
|
int maxInputSize = getMaxInputSize(mediaCodecInfo, format);
|
|
if (formatArr.length == 1) {
|
|
if (maxInputSize != -1 && (codecMaxInputSize = getCodecMaxInputSize(mediaCodecInfo, format)) != -1) {
|
|
maxInputSize = Math.min((int) (maxInputSize * INITIAL_FORMAT_MAX_INPUT_SIZE_SCALE_FACTOR), codecMaxInputSize);
|
|
}
|
|
return new CodecMaxValues(i, i2, maxInputSize);
|
|
}
|
|
int length = formatArr.length;
|
|
boolean z = false;
|
|
for (int i3 = 0; i3 < length; i3++) {
|
|
Format format2 = formatArr[i3];
|
|
if (format.colorInfo != null && format2.colorInfo == null) {
|
|
format2 = format2.buildUpon().setColorInfo(format.colorInfo).build();
|
|
}
|
|
if (mediaCodecInfo.canReuseCodec(format, format2).result != 0) {
|
|
z |= format2.width == -1 || format2.height == -1;
|
|
i = Math.max(i, format2.width);
|
|
i2 = Math.max(i2, format2.height);
|
|
maxInputSize = Math.max(maxInputSize, getMaxInputSize(mediaCodecInfo, format2));
|
|
}
|
|
}
|
|
if (z) {
|
|
Log.w(TAG, "Resolutions unknown. Codec max resolution: " + i + ViewHierarchyNode.JsonKeys.X + i2);
|
|
Point codecMaxSize = getCodecMaxSize(mediaCodecInfo, format);
|
|
if (codecMaxSize != null) {
|
|
i = Math.max(i, codecMaxSize.x);
|
|
i2 = Math.max(i2, codecMaxSize.y);
|
|
maxInputSize = Math.max(maxInputSize, getCodecMaxInputSize(mediaCodecInfo, format.buildUpon().setWidth(i).setHeight(i2).build()));
|
|
Log.w(TAG, "Codec max resolution adjusted to: " + i + ViewHierarchyNode.JsonKeys.X + i2);
|
|
}
|
|
}
|
|
return new CodecMaxValues(i, i2, maxInputSize);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecRenderer
|
|
protected MediaCodecDecoderException createDecoderException(Throwable th, MediaCodecInfo mediaCodecInfo) {
|
|
return new MediaCodecVideoDecoderException(th, mediaCodecInfo, this.displaySurface);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes2.dex */
|
|
public static final class VideoFrameProcessorManager {
|
|
private static final long EARLY_THRESHOLD_US = 50000;
|
|
private Pair<Long, Format> currentFrameFormat;
|
|
private Pair<Surface, Size> currentSurfaceAndSize;
|
|
private final VideoFrameReleaseHelper frameReleaseHelper;
|
|
private Handler handler;
|
|
private Format inputFormat;
|
|
private boolean pendingOutputSizeChange;
|
|
private boolean processedLastFrame;
|
|
private boolean registeredLastFrame;
|
|
private boolean releasedLastFrame;
|
|
private final MediaCodecVideoRenderer renderer;
|
|
private CopyOnWriteArrayList<Effect> videoEffects;
|
|
private VideoFrameProcessor videoFrameProcessor;
|
|
private final ArrayDeque<Long> processedFramesTimestampsUs = new ArrayDeque<>();
|
|
private final ArrayDeque<Pair<Long, Format>> pendingFrameFormats = new ArrayDeque<>();
|
|
private int videoFrameProcessorMaxPendingFrameCount = -1;
|
|
private boolean canEnableFrameProcessing = true;
|
|
private long lastCodecBufferPresentationTimestampUs = -9223372036854775807L;
|
|
private VideoSize processedFrameSize = VideoSize.UNKNOWN;
|
|
private long pendingOutputSizeChangeNotificationTimeUs = -9223372036854775807L;
|
|
private long initialStreamOffsetUs = -9223372036854775807L;
|
|
|
|
public boolean isEnabled() {
|
|
return this.videoFrameProcessor != null;
|
|
}
|
|
|
|
public boolean releasedLastFrame() {
|
|
return this.releasedLastFrame;
|
|
}
|
|
|
|
public VideoFrameProcessorManager(VideoFrameReleaseHelper videoFrameReleaseHelper, MediaCodecVideoRenderer mediaCodecVideoRenderer) {
|
|
this.frameReleaseHelper = videoFrameReleaseHelper;
|
|
this.renderer = mediaCodecVideoRenderer;
|
|
}
|
|
|
|
public void setVideoEffects(List<Effect> list) {
|
|
CopyOnWriteArrayList<Effect> copyOnWriteArrayList = this.videoEffects;
|
|
if (copyOnWriteArrayList == null) {
|
|
this.videoEffects = new CopyOnWriteArrayList<>(list);
|
|
} else {
|
|
copyOnWriteArrayList.clear();
|
|
this.videoEffects.addAll(list);
|
|
}
|
|
}
|
|
|
|
public boolean isReady() {
|
|
Pair<Surface, Size> pair = this.currentSurfaceAndSize;
|
|
return pair == null || !((Size) pair.second).equals(Size.UNKNOWN);
|
|
}
|
|
|
|
public void flush() {
|
|
Assertions.checkStateNotNull(this.videoFrameProcessor);
|
|
this.videoFrameProcessor.flush();
|
|
this.processedFramesTimestampsUs.clear();
|
|
this.handler.removeCallbacksAndMessages(null);
|
|
if (this.registeredLastFrame) {
|
|
this.registeredLastFrame = false;
|
|
this.processedLastFrame = false;
|
|
this.releasedLastFrame = false;
|
|
}
|
|
}
|
|
|
|
public boolean maybeEnable(final Format format, long j) throws ExoPlaybackException {
|
|
Assertions.checkState(!isEnabled());
|
|
if (!this.canEnableFrameProcessing) {
|
|
return false;
|
|
}
|
|
if (this.videoEffects == null) {
|
|
this.canEnableFrameProcessing = false;
|
|
return false;
|
|
}
|
|
this.handler = Util.createHandlerForCurrentLooper();
|
|
Pair<ColorInfo, ColorInfo> experimentalGetVideoFrameProcessorColorConfiguration = this.renderer.experimentalGetVideoFrameProcessorColorConfiguration(format.colorInfo);
|
|
try {
|
|
if (!MediaCodecVideoRenderer.access$000() && format.rotationDegrees != 0) {
|
|
this.videoEffects.add(0, VideoFrameProcessorAccessor.createRotationEffect(format.rotationDegrees));
|
|
}
|
|
VideoFrameProcessor.Factory frameProcessorFactory = VideoFrameProcessorAccessor.getFrameProcessorFactory();
|
|
Context context = this.renderer.context;
|
|
List<Effect> list = (List) Assertions.checkNotNull(this.videoEffects);
|
|
DebugViewProvider debugViewProvider = DebugViewProvider.NONE;
|
|
ColorInfo colorInfo = (ColorInfo) experimentalGetVideoFrameProcessorColorConfiguration.first;
|
|
ColorInfo colorInfo2 = (ColorInfo) experimentalGetVideoFrameProcessorColorConfiguration.second;
|
|
final Handler handler = this.handler;
|
|
Objects.requireNonNull(handler);
|
|
VideoFrameProcessor create = frameProcessorFactory.create(context, list, debugViewProvider, colorInfo, colorInfo2, false, new Executor() { // from class: androidx.media3.exoplayer.video.MediaCodecVideoRenderer$VideoFrameProcessorManager$$ExternalSyntheticLambda0
|
|
@Override // java.util.concurrent.Executor
|
|
public final void execute(Runnable runnable) {
|
|
handler.post(runnable);
|
|
}
|
|
}, new VideoFrameProcessor.Listener() { // from class: androidx.media3.exoplayer.video.MediaCodecVideoRenderer.VideoFrameProcessorManager.1
|
|
@Override // androidx.media3.common.VideoFrameProcessor.Listener
|
|
public void onOutputSizeChanged(int i, int i2) {
|
|
Assertions.checkStateNotNull(VideoFrameProcessorManager.this.inputFormat);
|
|
VideoFrameProcessorManager.this.processedFrameSize = new VideoSize(i, i2, 0, 1.0f);
|
|
VideoFrameProcessorManager.this.pendingOutputSizeChange = true;
|
|
}
|
|
|
|
@Override // androidx.media3.common.VideoFrameProcessor.Listener
|
|
public void onOutputFrameAvailableForRendering(long j2) {
|
|
if (VideoFrameProcessorManager.this.registeredLastFrame) {
|
|
Assertions.checkState(VideoFrameProcessorManager.this.lastCodecBufferPresentationTimestampUs != -9223372036854775807L);
|
|
}
|
|
VideoFrameProcessorManager.this.processedFramesTimestampsUs.add(Long.valueOf(j2));
|
|
if (VideoFrameProcessorManager.this.registeredLastFrame && j2 >= VideoFrameProcessorManager.this.lastCodecBufferPresentationTimestampUs) {
|
|
VideoFrameProcessorManager.this.processedLastFrame = true;
|
|
}
|
|
if (VideoFrameProcessorManager.this.pendingOutputSizeChange) {
|
|
VideoFrameProcessorManager.this.pendingOutputSizeChange = false;
|
|
VideoFrameProcessorManager.this.pendingOutputSizeChangeNotificationTimeUs = j2;
|
|
}
|
|
}
|
|
|
|
@Override // androidx.media3.common.VideoFrameProcessor.Listener
|
|
public void onError(VideoFrameProcessingException videoFrameProcessingException) {
|
|
VideoFrameProcessorManager.this.renderer.setPendingPlaybackException(VideoFrameProcessorManager.this.renderer.createRendererException(videoFrameProcessingException, format, PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED));
|
|
}
|
|
|
|
@Override // androidx.media3.common.VideoFrameProcessor.Listener
|
|
public void onEnded() {
|
|
throw new IllegalStateException();
|
|
}
|
|
});
|
|
this.videoFrameProcessor = create;
|
|
create.registerInputStream(1);
|
|
this.initialStreamOffsetUs = j;
|
|
Pair<Surface, Size> pair = this.currentSurfaceAndSize;
|
|
if (pair != null) {
|
|
Size size = (Size) pair.second;
|
|
this.videoFrameProcessor.setOutputSurfaceInfo(new SurfaceInfo((Surface) this.currentSurfaceAndSize.first, size.getWidth(), size.getHeight()));
|
|
}
|
|
setInputFormat(format);
|
|
return true;
|
|
} catch (Exception e) {
|
|
throw this.renderer.createRendererException(e, format, 7000);
|
|
}
|
|
}
|
|
|
|
public long getCorrectedFramePresentationTimeUs(long j, long j2) {
|
|
Assertions.checkState(this.initialStreamOffsetUs != -9223372036854775807L);
|
|
return (j + j2) - this.initialStreamOffsetUs;
|
|
}
|
|
|
|
public Surface getInputSurface() {
|
|
return ((VideoFrameProcessor) Assertions.checkNotNull(this.videoFrameProcessor)).getInputSurface();
|
|
}
|
|
|
|
public void setOutputSurfaceInfo(Surface surface, Size size) {
|
|
Pair<Surface, Size> pair = this.currentSurfaceAndSize;
|
|
if (pair != null && ((Surface) pair.first).equals(surface) && ((Size) this.currentSurfaceAndSize.second).equals(size)) {
|
|
return;
|
|
}
|
|
this.currentSurfaceAndSize = Pair.create(surface, size);
|
|
if (isEnabled()) {
|
|
((VideoFrameProcessor) Assertions.checkNotNull(this.videoFrameProcessor)).setOutputSurfaceInfo(new SurfaceInfo(surface, size.getWidth(), size.getHeight()));
|
|
}
|
|
}
|
|
|
|
public void clearOutputSurfaceInfo() {
|
|
((VideoFrameProcessor) Assertions.checkNotNull(this.videoFrameProcessor)).setOutputSurfaceInfo(null);
|
|
this.currentSurfaceAndSize = null;
|
|
}
|
|
|
|
public void setInputFormat(Format format) {
|
|
((VideoFrameProcessor) Assertions.checkNotNull(this.videoFrameProcessor)).setInputFrameInfo(new FrameInfo.Builder(format.width, format.height).setPixelWidthHeightRatio(format.pixelWidthHeightRatio).build());
|
|
this.inputFormat = format;
|
|
if (this.registeredLastFrame) {
|
|
this.registeredLastFrame = false;
|
|
this.processedLastFrame = false;
|
|
this.releasedLastFrame = false;
|
|
}
|
|
}
|
|
|
|
public MediaFormat amendMediaFormatKeys(MediaFormat mediaFormat) {
|
|
if (Util.SDK_INT >= 29 && this.renderer.context.getApplicationContext().getApplicationInfo().targetSdkVersion >= 29) {
|
|
mediaFormat.setInteger("allow-frame-drop", 0);
|
|
}
|
|
return mediaFormat;
|
|
}
|
|
|
|
public void onCodecInitialized(String str) {
|
|
this.videoFrameProcessorMaxPendingFrameCount = Util.getMaxPendingFramesCountForMediaCodecDecoders(this.renderer.context, str, false);
|
|
}
|
|
|
|
public boolean maybeRegisterFrame(Format format, long j, boolean z) {
|
|
Assertions.checkStateNotNull(this.videoFrameProcessor);
|
|
Assertions.checkState(this.videoFrameProcessorMaxPendingFrameCount != -1);
|
|
if (this.videoFrameProcessor.getPendingInputFrameCount() >= this.videoFrameProcessorMaxPendingFrameCount) {
|
|
return false;
|
|
}
|
|
this.videoFrameProcessor.registerInputFrame();
|
|
Pair<Long, Format> pair = this.currentFrameFormat;
|
|
if (pair == null) {
|
|
this.currentFrameFormat = Pair.create(Long.valueOf(j), format);
|
|
} else if (!Util.areEqual(format, pair.second)) {
|
|
this.pendingFrameFormats.add(Pair.create(Long.valueOf(j), format));
|
|
}
|
|
if (z) {
|
|
this.registeredLastFrame = true;
|
|
this.lastCodecBufferPresentationTimestampUs = j;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void releaseProcessedFrames(long j, long j2) {
|
|
Assertions.checkStateNotNull(this.videoFrameProcessor);
|
|
while (!this.processedFramesTimestampsUs.isEmpty()) {
|
|
boolean z = false;
|
|
boolean z2 = this.renderer.getState() == 2;
|
|
long longValue = ((Long) Assertions.checkNotNull(this.processedFramesTimestampsUs.peek())).longValue();
|
|
long j3 = longValue + this.initialStreamOffsetUs;
|
|
long calculateEarlyTimeUs = this.renderer.calculateEarlyTimeUs(j, j2, SystemClock.elapsedRealtime() * 1000, j3, z2);
|
|
if (this.processedLastFrame && this.processedFramesTimestampsUs.size() == 1) {
|
|
z = true;
|
|
}
|
|
if (this.renderer.shouldForceRender(j, calculateEarlyTimeUs)) {
|
|
releaseProcessedFrameInternal(-1L, z);
|
|
return;
|
|
}
|
|
if (!z2 || j == this.renderer.initialPositionUs || calculateEarlyTimeUs > EARLY_THRESHOLD_US) {
|
|
return;
|
|
}
|
|
this.frameReleaseHelper.onNextFrame(j3);
|
|
long adjustReleaseTime = this.frameReleaseHelper.adjustReleaseTime(System.nanoTime() + (calculateEarlyTimeUs * 1000));
|
|
if (this.renderer.shouldDropOutputBuffer((adjustReleaseTime - System.nanoTime()) / 1000, j2, z)) {
|
|
releaseProcessedFrameInternal(-2L, z);
|
|
} else {
|
|
if (!this.pendingFrameFormats.isEmpty() && j3 > ((Long) this.pendingFrameFormats.peek().first).longValue()) {
|
|
this.currentFrameFormat = this.pendingFrameFormats.remove();
|
|
}
|
|
this.renderer.notifyFrameMetadataListener(longValue, adjustReleaseTime, (Format) this.currentFrameFormat.second);
|
|
if (this.pendingOutputSizeChangeNotificationTimeUs >= j3) {
|
|
this.pendingOutputSizeChangeNotificationTimeUs = -9223372036854775807L;
|
|
this.renderer.maybeNotifyVideoSizeChanged(this.processedFrameSize);
|
|
}
|
|
releaseProcessedFrameInternal(adjustReleaseTime, z);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void reset() {
|
|
((VideoFrameProcessor) Assertions.checkNotNull(this.videoFrameProcessor)).release();
|
|
this.videoFrameProcessor = null;
|
|
Handler handler = this.handler;
|
|
if (handler != null) {
|
|
handler.removeCallbacksAndMessages(null);
|
|
}
|
|
CopyOnWriteArrayList<Effect> copyOnWriteArrayList = this.videoEffects;
|
|
if (copyOnWriteArrayList != null) {
|
|
copyOnWriteArrayList.clear();
|
|
}
|
|
this.processedFramesTimestampsUs.clear();
|
|
this.canEnableFrameProcessing = true;
|
|
}
|
|
|
|
private void releaseProcessedFrameInternal(long j, boolean z) {
|
|
Assertions.checkStateNotNull(this.videoFrameProcessor);
|
|
this.videoFrameProcessor.renderOutputFrame(j);
|
|
this.processedFramesTimestampsUs.remove();
|
|
this.renderer.lastRenderRealtimeUs = SystemClock.elapsedRealtime() * 1000;
|
|
if (j != -2) {
|
|
this.renderer.maybeNotifyRenderedFirstFrame();
|
|
}
|
|
if (z) {
|
|
this.releasedLastFrame = true;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes2.dex */
|
|
public static final class VideoFrameProcessorAccessor {
|
|
private static Method buildScaleAndRotateTransformationMethod;
|
|
private static Method buildVideoFrameProcessorFactoryMethod;
|
|
private static Constructor<?> scaleAndRotateTransformationBuilderConstructor;
|
|
private static Method setRotationMethod;
|
|
private static Constructor<?> videoFrameProcessorFactoryBuilderConstructor;
|
|
|
|
private VideoFrameProcessorAccessor() {
|
|
}
|
|
|
|
public static Effect createRotationEffect(float f) throws Exception {
|
|
prepare();
|
|
Object newInstance = scaleAndRotateTransformationBuilderConstructor.newInstance(new Object[0]);
|
|
setRotationMethod.invoke(newInstance, Float.valueOf(f));
|
|
return (Effect) Assertions.checkNotNull(buildScaleAndRotateTransformationMethod.invoke(newInstance, new Object[0]));
|
|
}
|
|
|
|
public static VideoFrameProcessor.Factory getFrameProcessorFactory() throws Exception {
|
|
prepare();
|
|
return (VideoFrameProcessor.Factory) Assertions.checkNotNull(buildVideoFrameProcessorFactoryMethod.invoke(videoFrameProcessorFactoryBuilderConstructor.newInstance(new Object[0]), new Object[0]));
|
|
}
|
|
|
|
@EnsuresNonNull({"scaleAndRotateTransformationBuilderConstructor", "setRotationMethod", "buildScaleAndRotateTransformationMethod", "videoFrameProcessorFactoryBuilderConstructor", "buildVideoFrameProcessorFactoryMethod"})
|
|
private static void prepare() throws Exception {
|
|
if (scaleAndRotateTransformationBuilderConstructor == null || setRotationMethod == null || buildScaleAndRotateTransformationMethod == null) {
|
|
Class<?> cls = Class.forName("androidx.media3.effect.ScaleAndRotateTransformation$Builder");
|
|
scaleAndRotateTransformationBuilderConstructor = cls.getConstructor(new Class[0]);
|
|
setRotationMethod = cls.getMethod("setRotationDegrees", Float.TYPE);
|
|
buildScaleAndRotateTransformationMethod = cls.getMethod(OperatingSystem.JsonKeys.BUILD, new Class[0]);
|
|
}
|
|
if (videoFrameProcessorFactoryBuilderConstructor == null || buildVideoFrameProcessorFactoryMethod == null) {
|
|
Class<?> cls2 = Class.forName("androidx.media3.effect.DefaultVideoFrameProcessor$Factory$Builder");
|
|
videoFrameProcessorFactoryBuilderConstructor = cls2.getConstructor(new Class[0]);
|
|
buildVideoFrameProcessorFactoryMethod = cls2.getMethod(OperatingSystem.JsonKeys.BUILD, new Class[0]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static Point getCodecMaxSize(MediaCodecInfo mediaCodecInfo, Format format) {
|
|
boolean z = format.height > format.width;
|
|
int i = z ? format.height : format.width;
|
|
int i2 = z ? format.width : format.height;
|
|
float f = i2 / i;
|
|
for (int i3 : STANDARD_LONG_EDGE_VIDEO_PX) {
|
|
int i4 = (int) (i3 * f);
|
|
if (i3 <= i || i4 <= i2) {
|
|
break;
|
|
}
|
|
if (Util.SDK_INT >= 21) {
|
|
int i5 = z ? i4 : i3;
|
|
if (!z) {
|
|
i3 = i4;
|
|
}
|
|
Point alignVideoSizeV21 = mediaCodecInfo.alignVideoSizeV21(i5, i3);
|
|
if (mediaCodecInfo.isVideoSizeAndRateSupportedV21(alignVideoSizeV21.x, alignVideoSizeV21.y, format.frameRate)) {
|
|
return alignVideoSizeV21;
|
|
}
|
|
} else {
|
|
try {
|
|
int ceilDivide = Util.ceilDivide(i3, 16) * 16;
|
|
int ceilDivide2 = Util.ceilDivide(i4, 16) * 16;
|
|
if (ceilDivide * ceilDivide2 <= MediaCodecUtil.maxH264DecodableFrameSize()) {
|
|
int i6 = z ? ceilDivide2 : ceilDivide;
|
|
if (!z) {
|
|
ceilDivide = ceilDivide2;
|
|
}
|
|
return new Point(i6, ceilDivide);
|
|
}
|
|
} catch (MediaCodecUtil.DecoderQueryException unused) {
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
protected static int getMaxInputSize(MediaCodecInfo mediaCodecInfo, Format format) {
|
|
if (format.maxInputSize != -1) {
|
|
int size = format.initializationData.size();
|
|
int i = 0;
|
|
for (int i2 = 0; i2 < size; i2++) {
|
|
i += format.initializationData.get(i2).length;
|
|
}
|
|
return format.maxInputSize + i;
|
|
}
|
|
return getCodecMaxInputSize(mediaCodecInfo, format);
|
|
}
|
|
|
|
private static boolean codecAppliesRotation() {
|
|
return Util.SDK_INT >= 21;
|
|
}
|
|
|
|
private static boolean deviceNeedsNoPostProcessWorkaround() {
|
|
return "NVIDIA".equals(Util.MANUFACTURER);
|
|
}
|
|
|
|
protected boolean codecNeedsSetOutputSurfaceWorkaround(String str) {
|
|
if (str.startsWith("OMX.google")) {
|
|
return false;
|
|
}
|
|
synchronized (MediaCodecVideoRenderer.class) {
|
|
if (!evaluatedDeviceNeedsSetOutputSurfaceWorkaround) {
|
|
deviceNeedsSetOutputSurfaceWorkaround = evaluateDeviceNeedsSetOutputSurfaceWorkaround();
|
|
evaluatedDeviceNeedsSetOutputSurfaceWorkaround = true;
|
|
}
|
|
}
|
|
return deviceNeedsSetOutputSurfaceWorkaround;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: protected */
|
|
/* loaded from: classes2.dex */
|
|
public static final class CodecMaxValues {
|
|
public final int height;
|
|
public final int inputSize;
|
|
public final int width;
|
|
|
|
public CodecMaxValues(int i, int i2, int i3) {
|
|
this.width = i;
|
|
this.height = i2;
|
|
this.inputSize = i3;
|
|
}
|
|
}
|
|
|
|
private static int getMaxSampleSize(int i, int i2) {
|
|
return (i * 3) / (i2 * 2);
|
|
}
|
|
|
|
/* JADX WARN: Can't fix incorrect switch cases order, some code will duplicate */
|
|
/* JADX WARN: Code restructure failed: missing block: B:448:0x0848, code lost:
|
|
|
|
if (r0.equals("PGN528") == false) goto L91;
|
|
*/
|
|
/* JADX WARN: Failed to find 'out' block for switch in B:47:0x089f. Please report as an issue. */
|
|
/*
|
|
Code decompiled incorrectly, please refer to instructions dump.
|
|
To view partially-correct add '--show-bad-code' argument
|
|
*/
|
|
private static boolean evaluateDeviceNeedsSetOutputSurfaceWorkaround() {
|
|
/*
|
|
Method dump skipped, instructions count: 3188
|
|
To view this dump add '--comments-level debug' option
|
|
*/
|
|
throw new UnsupportedOperationException("Method not decompiled: androidx.media3.exoplayer.video.MediaCodecVideoRenderer.evaluateDeviceNeedsSetOutputSurfaceWorkaround():boolean");
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* loaded from: classes2.dex */
|
|
public final class OnFrameRenderedListenerV23 implements MediaCodecAdapter.OnFrameRenderedListener, Handler.Callback {
|
|
private static final int HANDLE_FRAME_RENDERED = 0;
|
|
private final Handler handler;
|
|
|
|
public OnFrameRenderedListenerV23(MediaCodecAdapter mediaCodecAdapter) {
|
|
Handler createHandlerForCurrentLooper = Util.createHandlerForCurrentLooper(this);
|
|
this.handler = createHandlerForCurrentLooper;
|
|
mediaCodecAdapter.setOnFrameRenderedListener(this, createHandlerForCurrentLooper);
|
|
}
|
|
|
|
@Override // androidx.media3.exoplayer.mediacodec.MediaCodecAdapter.OnFrameRenderedListener
|
|
public void onFrameRendered(MediaCodecAdapter mediaCodecAdapter, long j, long j2) {
|
|
if (Util.SDK_INT < 30) {
|
|
this.handler.sendMessageAtFrontOfQueue(Message.obtain(this.handler, 0, (int) (j >> 32), (int) j));
|
|
} else {
|
|
handleFrameRendered(j);
|
|
}
|
|
}
|
|
|
|
@Override // android.os.Handler.Callback
|
|
public boolean handleMessage(Message message) {
|
|
if (message.what != 0) {
|
|
return false;
|
|
}
|
|
handleFrameRendered(Util.toLong(message.arg1, message.arg2));
|
|
return true;
|
|
}
|
|
|
|
private void handleFrameRendered(long j) {
|
|
if (this != MediaCodecVideoRenderer.this.tunnelingOnFrameRenderedListener || MediaCodecVideoRenderer.this.getCodec() == null) {
|
|
return;
|
|
}
|
|
if (j == Long.MAX_VALUE) {
|
|
MediaCodecVideoRenderer.this.onProcessedTunneledEndOfStream();
|
|
return;
|
|
}
|
|
try {
|
|
MediaCodecVideoRenderer.this.onProcessedTunneledBuffer(j);
|
|
} catch (ExoPlaybackException e) {
|
|
MediaCodecVideoRenderer.this.setPendingPlaybackException(e);
|
|
}
|
|
}
|
|
}
|
|
}
|