Commit 3f17f5d4 by olly Committed by Oliver Woodman

1) Adds new csi ticks:

exp (ExoPlayer prepare)
ffr (First Frame Rendered)
psr (Player State Ready).

2) Modifies aci/acc vci/vcc to report timing from ExoPlayer Playback thread.

3) Fix to report pvri and pari for every playback.

and other minor bug fixes.

PiperOrigin-RevId: 360228206
parent b5d360c4
...@@ -2020,8 +2020,8 @@ public class SimpleExoPlayer extends BasePlayer ...@@ -2020,8 +2020,8 @@ public class SimpleExoPlayer extends BasePlayer
} }
@Override @Override
public void onRenderedFirstFrame(@Nullable Surface surface) { public void onRenderedFirstFrame(@Nullable Surface surface, long renderTimeMs) {
analyticsCollector.onRenderedFirstFrame(surface); analyticsCollector.onRenderedFirstFrame(surface, renderTimeMs);
if (SimpleExoPlayer.this.surface == surface) { if (SimpleExoPlayer.this.surface == surface) {
for (VideoListener videoListener : videoListeners) { for (VideoListener videoListener : videoListeners) {
videoListener.onRenderedFirstFrame(); videoListener.onRenderedFirstFrame();
......
...@@ -231,6 +231,8 @@ public class AnalyticsCollector ...@@ -231,6 +231,8 @@ public class AnalyticsCollector
AnalyticsListener.EVENT_AUDIO_DECODER_INITIALIZED, AnalyticsListener.EVENT_AUDIO_DECODER_INITIALIZED,
listener -> { listener -> {
listener.onAudioDecoderInitialized(eventTime, decoderName, initializationDurationMs); listener.onAudioDecoderInitialized(eventTime, decoderName, initializationDurationMs);
listener.onAudioDecoderInitialized(
eventTime, decoderName, initializedTimestampMs, initializationDurationMs);
listener.onDecoderInitialized( listener.onDecoderInitialized(
eventTime, C.TRACK_TYPE_AUDIO, decoderName, initializationDurationMs); eventTime, C.TRACK_TYPE_AUDIO, decoderName, initializationDurationMs);
}); });
...@@ -386,6 +388,8 @@ public class AnalyticsCollector ...@@ -386,6 +388,8 @@ public class AnalyticsCollector
AnalyticsListener.EVENT_VIDEO_DECODER_INITIALIZED, AnalyticsListener.EVENT_VIDEO_DECODER_INITIALIZED,
listener -> { listener -> {
listener.onVideoDecoderInitialized(eventTime, decoderName, initializationDurationMs); listener.onVideoDecoderInitialized(eventTime, decoderName, initializationDurationMs);
listener.onVideoDecoderInitialized(
eventTime, decoderName, initializedTimestampMs, initializationDurationMs);
listener.onDecoderInitialized( listener.onDecoderInitialized(
eventTime, C.TRACK_TYPE_VIDEO, decoderName, initializationDurationMs); eventTime, C.TRACK_TYPE_VIDEO, decoderName, initializationDurationMs);
}); });
...@@ -449,13 +453,17 @@ public class AnalyticsCollector ...@@ -449,13 +453,17 @@ public class AnalyticsCollector
eventTime, width, height, unappliedRotationDegrees, pixelWidthHeightRatio)); eventTime, width, height, unappliedRotationDegrees, pixelWidthHeightRatio));
} }
@SuppressWarnings("deprecation") // Calling deprecated listener method.
@Override @Override
public final void onRenderedFirstFrame(@Nullable Surface surface) { public final void onRenderedFirstFrame(@Nullable Surface surface, long renderTimeMs) {
EventTime eventTime = generateReadingMediaPeriodEventTime(); EventTime eventTime = generateReadingMediaPeriodEventTime();
sendEvent( sendEvent(
eventTime, eventTime,
AnalyticsListener.EVENT_RENDERED_FIRST_FRAME, AnalyticsListener.EVENT_RENDERED_FIRST_FRAME,
listener -> listener.onRenderedFirstFrame(eventTime, surface)); listener -> {
listener.onRenderedFirstFrame(eventTime, surface);
listener.onRenderedFirstFrame(eventTime, surface, renderTimeMs);
});
} }
@Override @Override
......
...@@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull; ...@@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.media.MediaCodec.CodecException; import android.media.MediaCodec.CodecException;
import android.os.Looper; import android.os.Looper;
import android.os.SystemClock;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.Surface; import android.view.Surface;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
...@@ -753,9 +754,19 @@ public interface AnalyticsListener { ...@@ -753,9 +754,19 @@ public interface AnalyticsListener {
* *
* @param eventTime The event time. * @param eventTime The event time.
* @param decoderName The decoder that was created. * @param decoderName The decoder that was created.
* @param initializedTimestampMs {@link SystemClock#elapsedRealtime()} when initialization
* finished.
* @param initializationDurationMs The time taken to initialize the decoder in milliseconds. * @param initializationDurationMs The time taken to initialize the decoder in milliseconds.
*/ */
default void onAudioDecoderInitialized( default void onAudioDecoderInitialized(
EventTime eventTime,
String decoderName,
long initializedTimestampMs,
long initializationDurationMs) {}
/** @deprecated Use {@link #onAudioDecoderInitialized(EventTime, String, long, long)}. */
@Deprecated
default void onAudioDecoderInitialized(
EventTime eventTime, String decoderName, long initializationDurationMs) {} EventTime eventTime, String decoderName, long initializationDurationMs) {}
/** /**
...@@ -895,9 +906,19 @@ public interface AnalyticsListener { ...@@ -895,9 +906,19 @@ public interface AnalyticsListener {
* *
* @param eventTime The event time. * @param eventTime The event time.
* @param decoderName The decoder that was created. * @param decoderName The decoder that was created.
* @param initializedTimestampMs {@link SystemClock#elapsedRealtime()} when initialization
* finished.
* @param initializationDurationMs The time taken to initialize the decoder in milliseconds. * @param initializationDurationMs The time taken to initialize the decoder in milliseconds.
*/ */
default void onVideoDecoderInitialized( default void onVideoDecoderInitialized(
EventTime eventTime,
String decoderName,
long initializedTimestampMs,
long initializationDurationMs) {}
/** @deprecated Use {@link #onVideoDecoderInitialized(EventTime, String, long, long)}. */
@Deprecated
default void onVideoDecoderInitialized(
EventTime eventTime, String decoderName, long initializationDurationMs) {} EventTime eventTime, String decoderName, long initializationDurationMs) {}
/** /**
...@@ -988,7 +1009,13 @@ public interface AnalyticsListener { ...@@ -988,7 +1009,13 @@ public interface AnalyticsListener {
* @param eventTime The event time. * @param eventTime The event time.
* @param surface The {@link Surface} to which a frame has been rendered, or {@code null} if the * @param surface The {@link Surface} to which a frame has been rendered, or {@code null} if the
* renderer renders to something that isn't a {@link Surface}. * renderer renders to something that isn't a {@link Surface}.
* @param renderTimeMs {@link SystemClock#elapsedRealtime()} when the first frame was rendered.
*/ */
default void onRenderedFirstFrame(
EventTime eventTime, @Nullable Surface surface, long renderTimeMs) {}
/** @deprecated Use {@link #onRenderedFirstFrame(EventTime, Surface, long)} instead. */
@Deprecated
default void onRenderedFirstFrame(EventTime eventTime, @Nullable Surface surface) {} default void onRenderedFirstFrame(EventTime eventTime, @Nullable Surface surface) {}
/** /**
......
...@@ -130,7 +130,12 @@ public interface VideoRendererEventListener { ...@@ -130,7 +130,12 @@ public interface VideoRendererEventListener {
* *
* @param surface The {@link Surface} to which a first frame has been rendered, or {@code null} if * @param surface The {@link Surface} to which a first frame has been rendered, or {@code null} if
* the renderer renders to something that isn't a {@link Surface}. * the renderer renders to something that isn't a {@link Surface}.
* @param renderTimeMs The {@link SystemClock#elapsedRealtime()} when the frame was rendered.
*/ */
default void onRenderedFirstFrame(@Nullable Surface surface, long renderTimeMs) {}
/** @deprecated Use {@link #onRenderedFirstFrame(Surface, long)}. */
@Deprecated
default void onRenderedFirstFrame(@Nullable Surface surface) {} default void onRenderedFirstFrame(@Nullable Surface surface) {}
/** /**
...@@ -246,10 +251,16 @@ public interface VideoRendererEventListener { ...@@ -246,10 +251,16 @@ public interface VideoRendererEventListener {
} }
} }
/** Invokes {@link VideoRendererEventListener#onRenderedFirstFrame(Surface)}. */ /** Invokes {@link VideoRendererEventListener#onRenderedFirstFrame(Surface, long)}. */
public void renderedFirstFrame(@Nullable Surface surface) { public void renderedFirstFrame(@Nullable Surface surface) {
if (handler != null) { if (handler != null) {
handler.post(() -> castNonNull(listener).onRenderedFirstFrame(surface)); // TODO: Replace this timestamp with the actual frame release time.
long renderTimeMs = SystemClock.elapsedRealtime();
handler.post(
() -> {
castNonNull(listener).onRenderedFirstFrame(surface);
castNonNull(listener).onRenderedFirstFrame(surface, renderTimeMs);
});
} }
} }
......
...@@ -1701,12 +1701,12 @@ public final class AnalyticsCollectorTest { ...@@ -1701,12 +1701,12 @@ public final class AnalyticsCollectorTest {
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce()) verify(listener, atLeastOnce())
.onVideoDecoderInitialized( .onVideoDecoderInitialized(
individualVideoDecoderInitializedEventTimes.capture(), any(), anyLong()); individualVideoDecoderInitializedEventTimes.capture(), any(), anyLong(), anyLong());
ArgumentCaptor<AnalyticsListener.EventTime> individualAudioDecoderInitializedEventTimes = ArgumentCaptor<AnalyticsListener.EventTime> individualAudioDecoderInitializedEventTimes =
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce()) verify(listener, atLeastOnce())
.onAudioDecoderInitialized( .onAudioDecoderInitialized(
individualAudioDecoderInitializedEventTimes.capture(), any(), anyLong()); individualAudioDecoderInitializedEventTimes.capture(), any(), anyLong(), anyLong());
ArgumentCaptor<AnalyticsListener.EventTime> individualVideoDisabledEventTimes = ArgumentCaptor<AnalyticsListener.EventTime> individualVideoDisabledEventTimes =
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce()) verify(listener, atLeastOnce())
...@@ -1718,7 +1718,7 @@ public final class AnalyticsCollectorTest { ...@@ -1718,7 +1718,7 @@ public final class AnalyticsCollectorTest {
ArgumentCaptor<AnalyticsListener.EventTime> individualRenderedFirstFrameEventTimes = ArgumentCaptor<AnalyticsListener.EventTime> individualRenderedFirstFrameEventTimes =
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce()) verify(listener, atLeastOnce())
.onRenderedFirstFrame(individualRenderedFirstFrameEventTimes.capture(), any()); .onRenderedFirstFrame(individualRenderedFirstFrameEventTimes.capture(), any(), anyLong());
ArgumentCaptor<AnalyticsListener.EventTime> individualVideoSizeChangedEventTimes = ArgumentCaptor<AnalyticsListener.EventTime> individualVideoSizeChangedEventTimes =
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class); ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
verify(listener, atLeastOnce()) verify(listener, atLeastOnce())
...@@ -2184,7 +2184,10 @@ public final class AnalyticsCollectorTest { ...@@ -2184,7 +2184,10 @@ public final class AnalyticsCollectorTest {
@Override @Override
public void onAudioDecoderInitialized( public void onAudioDecoderInitialized(
EventTime eventTime, String decoderName, long initializationDurationMs) { EventTime eventTime,
String decoderName,
long initializedTimestampMs,
long initializationDurationMs) {
reportedEvents.add(new ReportedEvent(EVENT_AUDIO_DECODER_INITIALIZED, eventTime)); reportedEvents.add(new ReportedEvent(EVENT_AUDIO_DECODER_INITIALIZED, eventTime));
} }
...@@ -2221,7 +2224,10 @@ public final class AnalyticsCollectorTest { ...@@ -2221,7 +2224,10 @@ public final class AnalyticsCollectorTest {
@Override @Override
public void onVideoDecoderInitialized( public void onVideoDecoderInitialized(
EventTime eventTime, String decoderName, long initializationDurationMs) { EventTime eventTime,
String decoderName,
long initializedTimestampMs,
long initializationDurationMs) {
reportedEvents.add(new ReportedEvent(EVENT_VIDEO_DECODER_INITIALIZED, eventTime)); reportedEvents.add(new ReportedEvent(EVENT_VIDEO_DECODER_INITIALIZED, eventTime));
} }
...@@ -2247,7 +2253,8 @@ public final class AnalyticsCollectorTest { ...@@ -2247,7 +2253,8 @@ public final class AnalyticsCollectorTest {
} }
@Override @Override
public void onRenderedFirstFrame(EventTime eventTime, @Nullable Surface surface) { public void onRenderedFirstFrame(
EventTime eventTime, @Nullable Surface surface, long renderTimeMs) {
reportedEvents.add(new ReportedEvent(EVENT_RENDERED_FIRST_FRAME, eventTime)); reportedEvents.add(new ReportedEvent(EVENT_RENDERED_FIRST_FRAME, eventTime));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment