mirror of
https://github.com/samsonjs/media.git
synced 2026-03-29 10:05:48 +00:00
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
This commit is contained in:
parent
b5d360c4cd
commit
3f17f5d441
5 changed files with 65 additions and 12 deletions
|
|
@ -2020,8 +2020,8 @@ public class SimpleExoPlayer extends BasePlayer
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onRenderedFirstFrame(@Nullable Surface surface) {
|
||||
analyticsCollector.onRenderedFirstFrame(surface);
|
||||
public void onRenderedFirstFrame(@Nullable Surface surface, long renderTimeMs) {
|
||||
analyticsCollector.onRenderedFirstFrame(surface, renderTimeMs);
|
||||
if (SimpleExoPlayer.this.surface == surface) {
|
||||
for (VideoListener videoListener : videoListeners) {
|
||||
videoListener.onRenderedFirstFrame();
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ public class AnalyticsCollector
|
|||
AnalyticsListener.EVENT_AUDIO_DECODER_INITIALIZED,
|
||||
listener -> {
|
||||
listener.onAudioDecoderInitialized(eventTime, decoderName, initializationDurationMs);
|
||||
listener.onAudioDecoderInitialized(
|
||||
eventTime, decoderName, initializedTimestampMs, initializationDurationMs);
|
||||
listener.onDecoderInitialized(
|
||||
eventTime, C.TRACK_TYPE_AUDIO, decoderName, initializationDurationMs);
|
||||
});
|
||||
|
|
@ -386,6 +388,8 @@ public class AnalyticsCollector
|
|||
AnalyticsListener.EVENT_VIDEO_DECODER_INITIALIZED,
|
||||
listener -> {
|
||||
listener.onVideoDecoderInitialized(eventTime, decoderName, initializationDurationMs);
|
||||
listener.onVideoDecoderInitialized(
|
||||
eventTime, decoderName, initializedTimestampMs, initializationDurationMs);
|
||||
listener.onDecoderInitialized(
|
||||
eventTime, C.TRACK_TYPE_VIDEO, decoderName, initializationDurationMs);
|
||||
});
|
||||
|
|
@ -449,13 +453,17 @@ public class AnalyticsCollector
|
|||
eventTime, width, height, unappliedRotationDegrees, pixelWidthHeightRatio));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Calling deprecated listener method.
|
||||
@Override
|
||||
public final void onRenderedFirstFrame(@Nullable Surface surface) {
|
||||
public final void onRenderedFirstFrame(@Nullable Surface surface, long renderTimeMs) {
|
||||
EventTime eventTime = generateReadingMediaPeriodEventTime();
|
||||
sendEvent(
|
||||
eventTime,
|
||||
AnalyticsListener.EVENT_RENDERED_FIRST_FRAME,
|
||||
listener -> listener.onRenderedFirstFrame(eventTime, surface));
|
||||
listener -> {
|
||||
listener.onRenderedFirstFrame(eventTime, surface);
|
||||
listener.onRenderedFirstFrame(eventTime, surface, renderTimeMs);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
|||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodec.CodecException;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.IntDef;
|
||||
|
|
@ -753,8 +754,18 @@ public interface AnalyticsListener {
|
|||
*
|
||||
* @param eventTime The event time.
|
||||
* @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.
|
||||
*/
|
||||
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) {}
|
||||
|
||||
|
|
@ -895,8 +906,18 @@ public interface AnalyticsListener {
|
|||
*
|
||||
* @param eventTime The event time.
|
||||
* @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.
|
||||
*/
|
||||
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) {}
|
||||
|
||||
|
|
@ -988,7 +1009,13 @@ public interface AnalyticsListener {
|
|||
* @param eventTime The event time.
|
||||
* @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}.
|
||||
* @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) {}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -130,7 +130,12 @@ public interface VideoRendererEventListener {
|
|||
*
|
||||
* @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}.
|
||||
* @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) {}
|
||||
|
||||
/**
|
||||
|
|
@ -246,10 +251,16 @@ public interface VideoRendererEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
/** Invokes {@link VideoRendererEventListener#onRenderedFirstFrame(Surface)}. */
|
||||
/** Invokes {@link VideoRendererEventListener#onRenderedFirstFrame(Surface, long)}. */
|
||||
public void renderedFirstFrame(@Nullable Surface surface) {
|
||||
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 {
|
|||
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
|
||||
verify(listener, atLeastOnce())
|
||||
.onVideoDecoderInitialized(
|
||||
individualVideoDecoderInitializedEventTimes.capture(), any(), anyLong());
|
||||
individualVideoDecoderInitializedEventTimes.capture(), any(), anyLong(), anyLong());
|
||||
ArgumentCaptor<AnalyticsListener.EventTime> individualAudioDecoderInitializedEventTimes =
|
||||
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
|
||||
verify(listener, atLeastOnce())
|
||||
.onAudioDecoderInitialized(
|
||||
individualAudioDecoderInitializedEventTimes.capture(), any(), anyLong());
|
||||
individualAudioDecoderInitializedEventTimes.capture(), any(), anyLong(), anyLong());
|
||||
ArgumentCaptor<AnalyticsListener.EventTime> individualVideoDisabledEventTimes =
|
||||
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
|
||||
verify(listener, atLeastOnce())
|
||||
|
|
@ -1718,7 +1718,7 @@ public final class AnalyticsCollectorTest {
|
|||
ArgumentCaptor<AnalyticsListener.EventTime> individualRenderedFirstFrameEventTimes =
|
||||
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
|
||||
verify(listener, atLeastOnce())
|
||||
.onRenderedFirstFrame(individualRenderedFirstFrameEventTimes.capture(), any());
|
||||
.onRenderedFirstFrame(individualRenderedFirstFrameEventTimes.capture(), any(), anyLong());
|
||||
ArgumentCaptor<AnalyticsListener.EventTime> individualVideoSizeChangedEventTimes =
|
||||
ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
|
||||
verify(listener, atLeastOnce())
|
||||
|
|
@ -2184,7 +2184,10 @@ public final class AnalyticsCollectorTest {
|
|||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -2221,7 +2224,10 @@ public final class AnalyticsCollectorTest {
|
|||
|
||||
@Override
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
@ -2247,7 +2253,8 @@ public final class AnalyticsCollectorTest {
|
|||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue