Improve logging II
- Show renderers with no tracks in EventLogger track logging - Log renderer names in EventLogger track logging - Add useful message to ExoPlaybackException instances (including renderer name for renderer errors) PiperOrigin-RevId: 302421616
This commit is contained in:
parent
adae53c787
commit
dc33c0bdfb
@ -34,6 +34,7 @@ import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
|||||||
/** Decodes and renders video using libgav1 decoder. */
|
/** Decodes and renders video using libgav1 decoder. */
|
||||||
public class Libgav1VideoRenderer extends DecoderVideoRenderer {
|
public class Libgav1VideoRenderer extends DecoderVideoRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "Libgav1VideoRenderer";
|
||||||
private static final int DEFAULT_NUM_OF_INPUT_BUFFERS = 4;
|
private static final int DEFAULT_NUM_OF_INPUT_BUFFERS = 4;
|
||||||
private static final int DEFAULT_NUM_OF_OUTPUT_BUFFERS = 4;
|
private static final int DEFAULT_NUM_OF_OUTPUT_BUFFERS = 4;
|
||||||
/* Default size based on 720p resolution video compressed by a factor of two. */
|
/* Default size based on 720p resolution video compressed by a factor of two. */
|
||||||
@ -106,6 +107,11 @@ public class Libgav1VideoRenderer extends DecoderVideoRenderer {
|
|||||||
this.numOutputBuffers = numOutputBuffers;
|
this.numOutputBuffers = numOutputBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
public final int supportsFormat(Format format) {
|
public final int supportsFormat(Format format) {
|
||||||
|
@ -32,6 +32,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
/** Decodes and renders audio using FFmpeg. */
|
/** Decodes and renders audio using FFmpeg. */
|
||||||
public final class FfmpegAudioRenderer extends DecoderAudioRenderer {
|
public final class FfmpegAudioRenderer extends DecoderAudioRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "FfmpegAudioRenderer";
|
||||||
|
|
||||||
/** The number of input and output buffers. */
|
/** The number of input and output buffers. */
|
||||||
private static final int NUM_BUFFERS = 16;
|
private static final int NUM_BUFFERS = 16;
|
||||||
/** The default input buffer size. */
|
/** The default input buffer size. */
|
||||||
@ -88,6 +90,11 @@ public final class FfmpegAudioRenderer extends DecoderAudioRenderer {
|
|||||||
this.enableFloatOutput = enableFloatOutput;
|
this.enableFloatOutput = enableFloatOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@FormatSupport
|
@FormatSupport
|
||||||
protected int supportsFormatInternal(Format format) {
|
protected int supportsFormatInternal(Format format) {
|
||||||
|
@ -36,6 +36,8 @@ import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
|||||||
*/
|
*/
|
||||||
public final class FfmpegVideoRenderer extends DecoderVideoRenderer {
|
public final class FfmpegVideoRenderer extends DecoderVideoRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "FfmpegAudioRenderer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*
|
*
|
||||||
@ -56,6 +58,11 @@ public final class FfmpegVideoRenderer extends DecoderVideoRenderer {
|
|||||||
// TODO: Implement.
|
// TODO: Implement.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@RendererCapabilities.Capabilities
|
@RendererCapabilities.Capabilities
|
||||||
public final int supportsFormat(Format format) {
|
public final int supportsFormat(Format format) {
|
||||||
|
@ -34,6 +34,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
/** Decodes and renders audio using the native Flac decoder. */
|
/** Decodes and renders audio using the native Flac decoder. */
|
||||||
public final class LibflacAudioRenderer extends DecoderAudioRenderer {
|
public final class LibflacAudioRenderer extends DecoderAudioRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "LibflacAudioRenderer";
|
||||||
private static final int NUM_BUFFERS = 16;
|
private static final int NUM_BUFFERS = 16;
|
||||||
|
|
||||||
private @MonotonicNonNull FlacStreamMetadata streamMetadata;
|
private @MonotonicNonNull FlacStreamMetadata streamMetadata;
|
||||||
@ -71,6 +72,11 @@ public final class LibflacAudioRenderer extends DecoderAudioRenderer {
|
|||||||
audioSink);
|
audioSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@FormatSupport
|
@FormatSupport
|
||||||
protected int supportsFormatInternal(Format format) {
|
protected int supportsFormatInternal(Format format) {
|
||||||
|
@ -28,6 +28,7 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
|||||||
/** Decodes and renders audio using the native Opus decoder. */
|
/** Decodes and renders audio using the native Opus decoder. */
|
||||||
public class LibopusAudioRenderer extends DecoderAudioRenderer {
|
public class LibopusAudioRenderer extends DecoderAudioRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "LibopusAudioRenderer";
|
||||||
/** The number of input and output buffers. */
|
/** The number of input and output buffers. */
|
||||||
private static final int NUM_BUFFERS = 16;
|
private static final int NUM_BUFFERS = 16;
|
||||||
/** The default input buffer size. */
|
/** The default input buffer size. */
|
||||||
@ -53,6 +54,11 @@ public class LibopusAudioRenderer extends DecoderAudioRenderer {
|
|||||||
super(eventHandler, eventListener, audioProcessors);
|
super(eventHandler, eventListener, audioProcessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@FormatSupport
|
@FormatSupport
|
||||||
protected int supportsFormatInternal(Format format) {
|
protected int supportsFormatInternal(Format format) {
|
||||||
|
@ -33,6 +33,8 @@ import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
|||||||
/** Decodes and renders video using the native VP9 decoder. */
|
/** Decodes and renders video using the native VP9 decoder. */
|
||||||
public class LibvpxVideoRenderer extends DecoderVideoRenderer {
|
public class LibvpxVideoRenderer extends DecoderVideoRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "LibvpxVideoRenderer";
|
||||||
|
|
||||||
/** The number of input buffers. */
|
/** The number of input buffers. */
|
||||||
private final int numInputBuffers;
|
private final int numInputBuffers;
|
||||||
/**
|
/**
|
||||||
@ -115,6 +117,11 @@ public class LibvpxVideoRenderer extends DecoderVideoRenderer {
|
|||||||
this.numOutputBuffers = numOutputBuffers;
|
this.numOutputBuffers = numOutputBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
public final int supportsFormat(Format format) {
|
public final int supportsFormat(Format format) {
|
||||||
|
@ -330,7 +330,8 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||||||
throwRendererExceptionIsExecuting = false;
|
throwRendererExceptionIsExecuting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ExoPlaybackException.createForRenderer(cause, getIndex(), format, formatSupport);
|
return ExoPlaybackException.createForRenderer(
|
||||||
|
cause, getName(), getIndex(), format, formatSupport);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer2;
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.text.TextUtils;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.RendererCapabilities.FormatSupport;
|
import com.google.android.exoplayer2.RendererCapabilities.FormatSupport;
|
||||||
@ -70,9 +71,10 @@ public final class ExoPlaybackException extends Exception {
|
|||||||
/** The {@link Type} of the playback failure. */
|
/** The {@link Type} of the playback failure. */
|
||||||
@Type public final int type;
|
@Type public final int type;
|
||||||
|
|
||||||
/**
|
/** If {@link #type} is {@link #TYPE_RENDERER}, this is the name of the renderer. */
|
||||||
* If {@link #type} is {@link #TYPE_RENDERER}, this is the index of the renderer.
|
@Nullable public final String rendererName;
|
||||||
*/
|
|
||||||
|
/** If {@link #type} is {@link #TYPE_RENDERER}, this is the index of the renderer. */
|
||||||
public final int rendererIndex;
|
public final int rendererIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,12 +118,15 @@ public final class ExoPlaybackException extends Exception {
|
|||||||
*/
|
*/
|
||||||
public static ExoPlaybackException createForRenderer(
|
public static ExoPlaybackException createForRenderer(
|
||||||
Exception cause,
|
Exception cause,
|
||||||
|
String rendererName,
|
||||||
int rendererIndex,
|
int rendererIndex,
|
||||||
@Nullable Format rendererFormat,
|
@Nullable Format rendererFormat,
|
||||||
@FormatSupport int rendererFormatSupport) {
|
@FormatSupport int rendererFormatSupport) {
|
||||||
return new ExoPlaybackException(
|
return new ExoPlaybackException(
|
||||||
TYPE_RENDERER,
|
TYPE_RENDERER,
|
||||||
cause,
|
cause,
|
||||||
|
/* customMessage= */ null,
|
||||||
|
rendererName,
|
||||||
rendererIndex,
|
rendererIndex,
|
||||||
rendererFormat,
|
rendererFormat,
|
||||||
rendererFormat == null ? RendererCapabilities.FORMAT_HANDLED : rendererFormatSupport);
|
rendererFormat == null ? RendererCapabilities.FORMAT_HANDLED : rendererFormatSupport);
|
||||||
@ -161,6 +166,19 @@ public final class ExoPlaybackException extends Exception {
|
|||||||
this(
|
this(
|
||||||
type,
|
type,
|
||||||
cause,
|
cause,
|
||||||
|
/* customMessage= */ null,
|
||||||
|
/* rendererName= */ null,
|
||||||
|
/* rendererIndex= */ C.INDEX_UNSET,
|
||||||
|
/* rendererFormat= */ null,
|
||||||
|
/* rendererFormatSupport= */ RendererCapabilities.FORMAT_HANDLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExoPlaybackException(@Type int type, String message) {
|
||||||
|
this(
|
||||||
|
type,
|
||||||
|
/* cause= */ null,
|
||||||
|
/* customMessage= */ message,
|
||||||
|
/* rendererName= */ null,
|
||||||
/* rendererIndex= */ C.INDEX_UNSET,
|
/* rendererIndex= */ C.INDEX_UNSET,
|
||||||
/* rendererFormat= */ null,
|
/* rendererFormat= */ null,
|
||||||
/* rendererFormatSupport= */ RendererCapabilities.FORMAT_HANDLED);
|
/* rendererFormatSupport= */ RendererCapabilities.FORMAT_HANDLED);
|
||||||
@ -168,29 +186,30 @@ public final class ExoPlaybackException extends Exception {
|
|||||||
|
|
||||||
private ExoPlaybackException(
|
private ExoPlaybackException(
|
||||||
@Type int type,
|
@Type int type,
|
||||||
Throwable cause,
|
@Nullable Throwable cause,
|
||||||
|
@Nullable String customMessage,
|
||||||
|
@Nullable String rendererName,
|
||||||
int rendererIndex,
|
int rendererIndex,
|
||||||
@Nullable Format rendererFormat,
|
@Nullable Format rendererFormat,
|
||||||
@FormatSupport int rendererFormatSupport) {
|
@FormatSupport int rendererFormatSupport) {
|
||||||
super(cause);
|
super(
|
||||||
|
deriveMessage(
|
||||||
|
type,
|
||||||
|
customMessage,
|
||||||
|
rendererName,
|
||||||
|
rendererIndex,
|
||||||
|
rendererFormat,
|
||||||
|
rendererFormatSupport),
|
||||||
|
cause);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.cause = cause;
|
this.cause = cause;
|
||||||
|
this.rendererName = rendererName;
|
||||||
this.rendererIndex = rendererIndex;
|
this.rendererIndex = rendererIndex;
|
||||||
this.rendererFormat = rendererFormat;
|
this.rendererFormat = rendererFormat;
|
||||||
this.rendererFormatSupport = rendererFormatSupport;
|
this.rendererFormatSupport = rendererFormatSupport;
|
||||||
timestampMs = SystemClock.elapsedRealtime();
|
timestampMs = SystemClock.elapsedRealtime();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExoPlaybackException(@Type int type, String message) {
|
|
||||||
super(message);
|
|
||||||
this.type = type;
|
|
||||||
rendererIndex = C.INDEX_UNSET;
|
|
||||||
rendererFormat = null;
|
|
||||||
rendererFormatSupport = RendererCapabilities.FORMAT_UNSUPPORTED_TYPE;
|
|
||||||
cause = null;
|
|
||||||
timestampMs = SystemClock.elapsedRealtime();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the underlying error when {@link #type} is {@link #TYPE_SOURCE}.
|
* Retrieves the underlying error when {@link #type} is {@link #TYPE_SOURCE}.
|
||||||
*
|
*
|
||||||
@ -230,4 +249,45 @@ public final class ExoPlaybackException extends Exception {
|
|||||||
Assertions.checkState(type == TYPE_OUT_OF_MEMORY);
|
Assertions.checkState(type == TYPE_OUT_OF_MEMORY);
|
||||||
return (OutOfMemoryError) Assertions.checkNotNull(cause);
|
return (OutOfMemoryError) Assertions.checkNotNull(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static String deriveMessage(
|
||||||
|
@Type int type,
|
||||||
|
@Nullable String customMessage,
|
||||||
|
@Nullable String rendererName,
|
||||||
|
int rendererIndex,
|
||||||
|
@Nullable Format rendererFormat,
|
||||||
|
@FormatSupport int rendererFormatSupport) {
|
||||||
|
@Nullable String message;
|
||||||
|
switch (type) {
|
||||||
|
case TYPE_SOURCE:
|
||||||
|
message = "Source error";
|
||||||
|
break;
|
||||||
|
case TYPE_RENDERER:
|
||||||
|
message =
|
||||||
|
rendererName
|
||||||
|
+ " error"
|
||||||
|
+ ", index="
|
||||||
|
+ rendererIndex
|
||||||
|
+ ", format="
|
||||||
|
+ rendererFormat
|
||||||
|
+ ", format_supported="
|
||||||
|
+ RendererCapabilities.getFormatSupportString(rendererFormatSupport);
|
||||||
|
break;
|
||||||
|
case TYPE_REMOTE:
|
||||||
|
message = "Remote error";
|
||||||
|
break;
|
||||||
|
case TYPE_OUT_OF_MEMORY:
|
||||||
|
message = "Out of memory error";
|
||||||
|
break;
|
||||||
|
case TYPE_UNEXPECTED:
|
||||||
|
default:
|
||||||
|
message = "Unexpected runtime error";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(customMessage)) {
|
||||||
|
message += ": " + customMessage;
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
// Handler.Callback implementation.
|
// Handler.Callback implementation.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public boolean handleMessage(Message msg) {
|
public boolean handleMessage(Message msg) {
|
||||||
try {
|
try {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
@ -469,7 +468,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
}
|
}
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
} catch (ExoPlaybackException e) {
|
} catch (ExoPlaybackException e) {
|
||||||
Log.e(TAG, getExoPlaybackExceptionMessage(e), e);
|
Log.e(TAG, "Playback error", e);
|
||||||
stopInternal(
|
stopInternal(
|
||||||
/* forceResetRenderers= */ true,
|
/* forceResetRenderers= */ true,
|
||||||
/* resetPositionAndState= */ false,
|
/* resetPositionAndState= */ false,
|
||||||
@ -477,19 +476,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
playbackInfo = playbackInfo.copyWithPlaybackError(e);
|
playbackInfo = playbackInfo.copyWithPlaybackError(e);
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Source error", e);
|
ExoPlaybackException error = ExoPlaybackException.createForSource(e);
|
||||||
|
Log.e(TAG, "Playback error", error);
|
||||||
stopInternal(
|
stopInternal(
|
||||||
/* forceResetRenderers= */ false,
|
/* forceResetRenderers= */ false,
|
||||||
/* resetPositionAndState= */ false,
|
/* resetPositionAndState= */ false,
|
||||||
/* acknowledgeStop= */ false);
|
/* acknowledgeStop= */ false);
|
||||||
playbackInfo = playbackInfo.copyWithPlaybackError(ExoPlaybackException.createForSource(e));
|
playbackInfo = playbackInfo.copyWithPlaybackError(error);
|
||||||
maybeNotifyPlaybackInfoChanged();
|
maybeNotifyPlaybackInfoChanged();
|
||||||
} catch (RuntimeException | OutOfMemoryError e) {
|
} catch (RuntimeException | OutOfMemoryError e) {
|
||||||
Log.e(TAG, "Internal runtime error", e);
|
|
||||||
ExoPlaybackException error =
|
ExoPlaybackException error =
|
||||||
e instanceof OutOfMemoryError
|
e instanceof OutOfMemoryError
|
||||||
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
|
? ExoPlaybackException.createForOutOfMemoryError((OutOfMemoryError) e)
|
||||||
: ExoPlaybackException.createForUnexpected((RuntimeException) e);
|
: ExoPlaybackException.createForUnexpected((RuntimeException) e);
|
||||||
|
Log.e(TAG, "Playback error", error);
|
||||||
stopInternal(
|
stopInternal(
|
||||||
/* forceResetRenderers= */ true,
|
/* forceResetRenderers= */ true,
|
||||||
/* resetPositionAndState= */ false,
|
/* resetPositionAndState= */ false,
|
||||||
@ -502,20 +502,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
// Private methods.
|
// Private methods.
|
||||||
|
|
||||||
private String getExoPlaybackExceptionMessage(ExoPlaybackException e) {
|
|
||||||
if (e.type != ExoPlaybackException.TYPE_RENDERER) {
|
|
||||||
return "Playback error.";
|
|
||||||
}
|
|
||||||
return "Renderer error: index="
|
|
||||||
+ e.rendererIndex
|
|
||||||
+ ", type="
|
|
||||||
+ Util.getTrackTypeString(renderers[e.rendererIndex].getTrackType())
|
|
||||||
+ ", format="
|
|
||||||
+ e.rendererFormat
|
|
||||||
+ ", rendererSupport="
|
|
||||||
+ RendererCapabilities.getFormatSupportString(e.rendererFormatSupport);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blocks the current thread until {@link #releaseInternal()} is executed on the playback Thread.
|
* Blocks the current thread until {@link #releaseInternal()} is executed on the playback Thread.
|
||||||
*
|
*
|
||||||
|
@ -189,6 +189,14 @@ public interface Renderer extends PlayerMessage.Target {
|
|||||||
*/
|
*/
|
||||||
int STATE_STARTED = 2;
|
int STATE_STARTED = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this renderer, for logging and debugging purposes. Should typically be the
|
||||||
|
* renderer's (un-obfuscated) class name.
|
||||||
|
*
|
||||||
|
* @return The name of this renderer.
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the track type that the renderer handles. For example, a video renderer will return
|
* Returns the track type that the renderer handles. For example, a video renderer will return
|
||||||
* {@link C#TRACK_TYPE_VIDEO}, an audio renderer will return {@link C#TRACK_TYPE_AUDIO}, a text
|
* {@link C#TRACK_TYPE_VIDEO}, an audio renderer will return {@link C#TRACK_TYPE_AUDIO}, a text
|
||||||
|
@ -260,6 +260,9 @@ public interface RendererCapabilities {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the name of the {@link Renderer}. */
|
||||||
|
String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the track type that the {@link Renderer} handles. For example, a video renderer will
|
* Returns the track type that the {@link Renderer} handles. For example, a video renderer will
|
||||||
* return {@link C#TRACK_TYPE_VIDEO}, an audio renderer will return {@link C#TRACK_TYPE_AUDIO}, a
|
* return {@link C#TRACK_TYPE_VIDEO}, an audio renderer will return {@link C#TRACK_TYPE_AUDIO}, a
|
||||||
|
@ -201,11 +201,14 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||||||
audioSink.setListener(new AudioSinkListener());
|
audioSink.setListener(new AudioSinkListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
protected int supportsFormat(
|
protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format)
|
||||||
MediaCodecSelector mediaCodecSelector,
|
|
||||||
Format format)
|
|
||||||
throws DecoderQueryException {
|
throws DecoderQueryException {
|
||||||
String mimeType = format.sampleMimeType;
|
String mimeType = format.sampleMimeType;
|
||||||
if (!MimeTypes.isAudio(mimeType)) {
|
if (!MimeTypes.isAudio(mimeType)) {
|
||||||
|
@ -40,6 +40,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
*/
|
*/
|
||||||
public final class MetadataRenderer extends BaseRenderer implements Callback {
|
public final class MetadataRenderer extends BaseRenderer implements Callback {
|
||||||
|
|
||||||
|
private static final String TAG = "MetadataRenderer";
|
||||||
private static final int MSG_INVOKE_RENDERER = 0;
|
private static final int MSG_INVOKE_RENDERER = 0;
|
||||||
// TODO: Holding multiple pending metadata objects is temporary mitigation against
|
// TODO: Holding multiple pending metadata objects is temporary mitigation against
|
||||||
// https://github.com/google/ExoPlayer/issues/1874. It should be removed once this issue has been
|
// https://github.com/google/ExoPlayer/issues/1874. It should be removed once this issue has been
|
||||||
@ -92,6 +93,11 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||||||
pendingMetadataTimestamps = new long[MAX_PENDING_METADATA_COUNT];
|
pendingMetadataTimestamps = new long[MAX_PENDING_METADATA_COUNT];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
public int supportsFormat(Format format) {
|
public int supportsFormat(Format format) {
|
||||||
|
@ -121,6 +121,11 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
|||||||
formatHolder = new FormatHolder();
|
formatHolder = new FormatHolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
public int supportsFormat(Format format) {
|
public int supportsFormat(Format format) {
|
||||||
|
@ -92,6 +92,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||||||
@Deprecated public final int length;
|
@Deprecated public final int length;
|
||||||
|
|
||||||
private final int rendererCount;
|
private final int rendererCount;
|
||||||
|
private final String[] rendererNames;
|
||||||
private final int[] rendererTrackTypes;
|
private final int[] rendererTrackTypes;
|
||||||
private final TrackGroupArray[] rendererTrackGroups;
|
private final TrackGroupArray[] rendererTrackGroups;
|
||||||
@AdaptiveSupport private final int[] rendererMixedMimeTypeAdaptiveSupports;
|
@AdaptiveSupport private final int[] rendererMixedMimeTypeAdaptiveSupports;
|
||||||
@ -99,6 +100,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||||||
private final TrackGroupArray unmappedTrackGroups;
|
private final TrackGroupArray unmappedTrackGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param rendererNames The name of each renderer.
|
||||||
* @param rendererTrackTypes The track type handled by each renderer.
|
* @param rendererTrackTypes The track type handled by each renderer.
|
||||||
* @param rendererTrackGroups The {@link TrackGroup}s mapped to each renderer.
|
* @param rendererTrackGroups The {@link TrackGroup}s mapped to each renderer.
|
||||||
* @param rendererMixedMimeTypeAdaptiveSupports The {@link AdaptiveSupport} for mixed MIME type
|
* @param rendererMixedMimeTypeAdaptiveSupports The {@link AdaptiveSupport} for mixed MIME type
|
||||||
@ -109,11 +111,13 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
/* package */ MappedTrackInfo(
|
/* package */ MappedTrackInfo(
|
||||||
|
String[] rendererNames,
|
||||||
int[] rendererTrackTypes,
|
int[] rendererTrackTypes,
|
||||||
TrackGroupArray[] rendererTrackGroups,
|
TrackGroupArray[] rendererTrackGroups,
|
||||||
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptiveSupports,
|
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptiveSupports,
|
||||||
@Capabilities int[][][] rendererFormatSupports,
|
@Capabilities int[][][] rendererFormatSupports,
|
||||||
TrackGroupArray unmappedTrackGroups) {
|
TrackGroupArray unmappedTrackGroups) {
|
||||||
|
this.rendererNames = rendererNames;
|
||||||
this.rendererTrackTypes = rendererTrackTypes;
|
this.rendererTrackTypes = rendererTrackTypes;
|
||||||
this.rendererTrackGroups = rendererTrackGroups;
|
this.rendererTrackGroups = rendererTrackGroups;
|
||||||
this.rendererFormatSupports = rendererFormatSupports;
|
this.rendererFormatSupports = rendererFormatSupports;
|
||||||
@ -128,6 +132,17 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||||||
return rendererCount;
|
return rendererCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the renderer at a given index.
|
||||||
|
*
|
||||||
|
* @see Renderer#getName()
|
||||||
|
* @param rendererIndex The renderer index.
|
||||||
|
* @return The name of the renderer.
|
||||||
|
*/
|
||||||
|
public String getRendererName(int rendererIndex) {
|
||||||
|
return rendererNames[rendererIndex];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the track type that the renderer at a given index handles.
|
* Returns the track type that the renderer at a given index handles.
|
||||||
*
|
*
|
||||||
@ -380,6 +395,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||||||
|
|
||||||
// Create a track group array for each renderer, and trim each rendererFormatSupports entry.
|
// Create a track group array for each renderer, and trim each rendererFormatSupports entry.
|
||||||
TrackGroupArray[] rendererTrackGroupArrays = new TrackGroupArray[rendererCapabilities.length];
|
TrackGroupArray[] rendererTrackGroupArrays = new TrackGroupArray[rendererCapabilities.length];
|
||||||
|
String[] rendererNames = new String[rendererCapabilities.length];
|
||||||
int[] rendererTrackTypes = new int[rendererCapabilities.length];
|
int[] rendererTrackTypes = new int[rendererCapabilities.length];
|
||||||
for (int i = 0; i < rendererCapabilities.length; i++) {
|
for (int i = 0; i < rendererCapabilities.length; i++) {
|
||||||
int rendererTrackGroupCount = rendererTrackGroupCounts[i];
|
int rendererTrackGroupCount = rendererTrackGroupCounts[i];
|
||||||
@ -388,6 +404,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||||||
Util.nullSafeArrayCopy(rendererTrackGroups[i], rendererTrackGroupCount));
|
Util.nullSafeArrayCopy(rendererTrackGroups[i], rendererTrackGroupCount));
|
||||||
rendererFormatSupports[i] =
|
rendererFormatSupports[i] =
|
||||||
Util.nullSafeArrayCopy(rendererFormatSupports[i], rendererTrackGroupCount);
|
Util.nullSafeArrayCopy(rendererFormatSupports[i], rendererTrackGroupCount);
|
||||||
|
rendererNames[i] = rendererCapabilities[i].getName();
|
||||||
rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
|
rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,6 +418,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
|
|||||||
// Package up the track information and selections.
|
// Package up the track information and selections.
|
||||||
MappedTrackInfo mappedTrackInfo =
|
MappedTrackInfo mappedTrackInfo =
|
||||||
new MappedTrackInfo(
|
new MappedTrackInfo(
|
||||||
|
rendererNames,
|
||||||
rendererTrackTypes,
|
rendererTrackTypes,
|
||||||
rendererTrackGroupArrays,
|
rendererTrackGroupArrays,
|
||||||
rendererMixedMimeTypeAdaptationSupports,
|
rendererMixedMimeTypeAdaptationSupports,
|
||||||
|
@ -216,8 +216,10 @@ public class EventLogger implements AnalyticsListener {
|
|||||||
for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) {
|
for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) {
|
||||||
TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
|
TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex);
|
||||||
TrackSelection trackSelection = trackSelections.get(rendererIndex);
|
TrackSelection trackSelection = trackSelections.get(rendererIndex);
|
||||||
if (rendererTrackGroups.length > 0) {
|
if (rendererTrackGroups.length == 0) {
|
||||||
logd(" Renderer:" + rendererIndex + " [");
|
logd(" " + mappedTrackInfo.getRendererName(rendererIndex) + " []");
|
||||||
|
} else {
|
||||||
|
logd(" " + mappedTrackInfo.getRendererName(rendererIndex) + " [");
|
||||||
for (int groupIndex = 0; groupIndex < rendererTrackGroups.length; groupIndex++) {
|
for (int groupIndex = 0; groupIndex < rendererTrackGroups.length; groupIndex++) {
|
||||||
TrackGroup trackGroup = rendererTrackGroups.get(groupIndex);
|
TrackGroup trackGroup = rendererTrackGroups.get(groupIndex);
|
||||||
String adaptiveSupport =
|
String adaptiveSupport =
|
||||||
@ -261,7 +263,7 @@ public class EventLogger implements AnalyticsListener {
|
|||||||
// Log tracks not associated with a renderer.
|
// Log tracks not associated with a renderer.
|
||||||
TrackGroupArray unassociatedTrackGroups = mappedTrackInfo.getUnmappedTrackGroups();
|
TrackGroupArray unassociatedTrackGroups = mappedTrackInfo.getUnmappedTrackGroups();
|
||||||
if (unassociatedTrackGroups.length > 0) {
|
if (unassociatedTrackGroups.length > 0) {
|
||||||
logd(" Renderer:None [");
|
logd(" Unmapped [");
|
||||||
for (int groupIndex = 0; groupIndex < unassociatedTrackGroups.length; groupIndex++) {
|
for (int groupIndex = 0; groupIndex < unassociatedTrackGroups.length; groupIndex++) {
|
||||||
logd(" Group:" + groupIndex + " [");
|
logd(" Group:" + groupIndex + " [");
|
||||||
TrackGroup trackGroup = unassociatedTrackGroups.get(groupIndex);
|
TrackGroup trackGroup = unassociatedTrackGroups.get(groupIndex);
|
||||||
|
@ -240,11 +240,14 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
clearReportedVideoSize();
|
clearReportedVideoSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
protected int supportsFormat(
|
protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format)
|
||||||
MediaCodecSelector mediaCodecSelector,
|
|
||||||
Format format)
|
|
||||||
throws DecoderQueryException {
|
throws DecoderQueryException {
|
||||||
String mimeType = format.sampleMimeType;
|
String mimeType = format.sampleMimeType;
|
||||||
if (!MimeTypes.isVideo(mimeType)) {
|
if (!MimeTypes.isVideo(mimeType)) {
|
||||||
|
@ -33,6 +33,7 @@ import java.nio.ByteBuffer;
|
|||||||
/** A {@link Renderer} that parses the camera motion track. */
|
/** A {@link Renderer} that parses the camera motion track. */
|
||||||
public class CameraMotionRenderer extends BaseRenderer {
|
public class CameraMotionRenderer extends BaseRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "CameraMotionRenderer";
|
||||||
// The amount of time to read samples ahead of the current time.
|
// The amount of time to read samples ahead of the current time.
|
||||||
private static final int SAMPLE_WINDOW_DURATION_US = 100000;
|
private static final int SAMPLE_WINDOW_DURATION_US = 100000;
|
||||||
|
|
||||||
@ -49,6 +50,11 @@ public class CameraMotionRenderer extends BaseRenderer {
|
|||||||
scratch = new ParsableByteArray();
|
scratch = new ParsableByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
public int supportsFormat(Format format) {
|
public int supportsFormat(Format format) {
|
||||||
|
@ -58,6 +58,11 @@ public class DecoderAudioRendererTest {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
audioRenderer =
|
audioRenderer =
|
||||||
new DecoderAudioRenderer(null, null, mockAudioSink) {
|
new DecoderAudioRenderer(null, null, mockAudioSink) {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "TestAudioRenderer";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@FormatSupport
|
@FormatSupport
|
||||||
protected int supportsFormatInternal(Format format) {
|
protected int supportsFormatInternal(Format format) {
|
||||||
|
@ -49,6 +49,7 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Selecti
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationListener;
|
import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationListener;
|
||||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -1546,6 +1547,11 @@ public final class DefaultTrackSelectorTest {
|
|||||||
this.supportValue = supportValue;
|
this.supportValue = supportValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "FakeRenderer(" + Util.getTrackTypeString(trackType) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTrackType() {
|
public int getTrackType() {
|
||||||
return trackType;
|
return trackType;
|
||||||
@ -1590,6 +1596,11 @@ public final class DefaultTrackSelectorTest {
|
|||||||
this.formatToCapability = new HashMap<>(formatToCapability);
|
this.formatToCapability = new HashMap<>(formatToCapability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "FakeRenderer(" + Util.getTrackTypeString(trackType) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTrackType() {
|
public int getTrackType() {
|
||||||
return trackType;
|
return trackType;
|
||||||
|
@ -32,6 +32,7 @@ import com.google.android.exoplayer2.source.TrackGroup;
|
|||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@ -169,6 +170,11 @@ public final class MappingTrackSelectorTest {
|
|||||||
this.trackType = trackType;
|
this.trackType = trackType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "FakeRenderer(" + Util.getTrackTypeString(trackType) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTrackType() {
|
public int getTrackType() {
|
||||||
return trackType;
|
return trackType;
|
||||||
|
@ -80,6 +80,11 @@ public final class DecoderVideoRendererTest {
|
|||||||
|
|
||||||
@C.VideoOutputMode private int outputMode;
|
@C.VideoOutputMode private int outputMode;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "TestVideoRenderer";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Capabilities
|
@Capabilities
|
||||||
public int supportsFormat(Format format) {
|
public int supportsFormat(Format format) {
|
||||||
|
@ -72,6 +72,7 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
private static class DebugMediaCodecVideoRenderer extends MediaCodecVideoRenderer {
|
private static class DebugMediaCodecVideoRenderer extends MediaCodecVideoRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "DebugMediaCodecVideoRenderer";
|
||||||
private static final int ARRAY_SIZE = 1000;
|
private static final int ARRAY_SIZE = 1000;
|
||||||
|
|
||||||
private final long[] timestampsList = new long[ARRAY_SIZE];
|
private final long[] timestampsList = new long[ARRAY_SIZE];
|
||||||
@ -98,6 +99,11 @@ import java.util.ArrayList;
|
|||||||
maxDroppedFrameCountToNotify);
|
maxDroppedFrameCountToNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configureCodec(
|
protected void configureCodec(
|
||||||
MediaCodecInfo codecInfo,
|
MediaCodecInfo codecInfo,
|
||||||
|
@ -39,6 +39,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class FakeRenderer extends BaseRenderer {
|
public class FakeRenderer extends BaseRenderer {
|
||||||
|
|
||||||
|
private static final String TAG = "FakeRenderer";
|
||||||
/**
|
/**
|
||||||
* The amount of time ahead of the current playback position that the renderer reads from the
|
* The amount of time ahead of the current playback position that the renderer reads from the
|
||||||
* source. A real renderer will typically read ahead by a small amount due to pipelining through
|
* source. A real renderer will typically read ahead by a small amount due to pipelining through
|
||||||
@ -64,6 +65,11 @@ public class FakeRenderer extends BaseRenderer {
|
|||||||
formatsRead = new ArrayList<>();
|
formatsRead = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
|
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
|
||||||
playbackPositionUs = positionUs;
|
playbackPositionUs = positionUs;
|
||||||
@ -93,6 +99,7 @@ public class FakeRenderer extends BaseRenderer {
|
|||||||
Util.formatInvariant(
|
Util.formatInvariant(
|
||||||
"Format track type (%s) doesn't match renderer track type (%s).",
|
"Format track type (%s) doesn't match renderer track type (%s).",
|
||||||
MimeTypes.getTrackType(format.sampleMimeType), getTrackType())),
|
MimeTypes.getTrackType(format.sampleMimeType), getTrackType())),
|
||||||
|
getName(),
|
||||||
getIndex(),
|
getIndex(),
|
||||||
format,
|
format,
|
||||||
FORMAT_UNSUPPORTED_TYPE);
|
FORMAT_UNSUPPORTED_TYPE);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user