mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Remove Renderer[] from LoadControl.onTracksSelected
The `DefaultLoadControl` implementation of onTracksSelected only utilizes the `Renderer[]` parameter for use in stream type, of which it can collect from the `ExoTrackSelection[]` parameter. PiperOrigin-RevId: 685677726
This commit is contained in:
parent
17c0ff8ba8
commit
1c4ee06ad6
5 changed files with 119 additions and 48 deletions
|
|
@ -51,6 +51,14 @@
|
||||||
* Add `DefaultPreloadManager.Builder` that builds the
|
* Add `DefaultPreloadManager.Builder` that builds the
|
||||||
`DefaultPreloadManager` and `ExoPlayer` instances with consistently
|
`DefaultPreloadManager` and `ExoPlayer` instances with consistently
|
||||||
shared configurations.
|
shared configurations.
|
||||||
|
* Remove `Renderer[]` parameter from `LoadControl.onTracksSelected()` as
|
||||||
|
`DefaultLoadControl` implementation can retrieve the stream types from
|
||||||
|
`ExoTrackSelection[]`.
|
||||||
|
* Deprecated `DefaultLoadControl.calculateTargetBufferBytes(Renderer[],
|
||||||
|
ExoTrackSelection[])` and marked method as final to prevent overrides.
|
||||||
|
The new
|
||||||
|
`DefaultLoadControl.calculateTargetBufferBytes(ExoTrackSelection[])`
|
||||||
|
should be used instead.
|
||||||
* Transformer:
|
* Transformer:
|
||||||
* Make setting the image duration using
|
* Make setting the image duration using
|
||||||
`MediaItem.Builder.setImageDurationMs` mandatory for image export.
|
`MediaItem.Builder.setImageDurationMs` mandatory for image export.
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Timeline;
|
import androidx.media3.common.Timeline;
|
||||||
import androidx.media3.common.util.Assertions;
|
import androidx.media3.common.util.Assertions;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
|
import androidx.media3.common.util.NullableType;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||||
|
|
@ -35,6 +36,7 @@ import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
||||||
import androidx.media3.exoplayer.upstream.Allocator;
|
import androidx.media3.exoplayer.upstream.Allocator;
|
||||||
import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
|
import com.google.errorprone.annotations.InlineMe;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
/** The default {@link LoadControl} implementation. */
|
/** The default {@link LoadControl} implementation. */
|
||||||
|
|
@ -337,15 +339,12 @@ public class DefaultLoadControl implements LoadControl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTracksSelected(
|
public void onTracksSelected(
|
||||||
PlayerId playerId,
|
LoadControl.Parameters parameters,
|
||||||
Timeline timeline,
|
|
||||||
MediaPeriodId mediaPeriodId,
|
|
||||||
Renderer[] renderers,
|
|
||||||
TrackGroupArray trackGroups,
|
TrackGroupArray trackGroups,
|
||||||
ExoTrackSelection[] trackSelections) {
|
@NullableType ExoTrackSelection[] trackSelections) {
|
||||||
checkNotNull(loadingStates.get(playerId)).targetBufferBytes =
|
checkNotNull(loadingStates.get(parameters.playerId)).targetBufferBytes =
|
||||||
targetBufferBytesOverwrite == C.LENGTH_UNSET
|
targetBufferBytesOverwrite == C.LENGTH_UNSET
|
||||||
? calculateTargetBufferBytes(renderers, trackSelections)
|
? calculateTargetBufferBytes(trackSelections)
|
||||||
: targetBufferBytesOverwrite;
|
: targetBufferBytesOverwrite;
|
||||||
updateAllocator();
|
updateAllocator();
|
||||||
}
|
}
|
||||||
|
|
@ -437,21 +436,29 @@ public class DefaultLoadControl implements LoadControl {
|
||||||
* Calculate target buffer size in bytes based on the selected tracks. The player will try not to
|
* Calculate target buffer size in bytes based on the selected tracks. The player will try not to
|
||||||
* exceed this target buffer. Only used when {@code targetBufferBytes} is {@link C#LENGTH_UNSET}.
|
* exceed this target buffer. Only used when {@code targetBufferBytes} is {@link C#LENGTH_UNSET}.
|
||||||
*
|
*
|
||||||
* @param renderers The renderers for which the track were selected.
|
|
||||||
* @param trackSelectionArray The selected tracks.
|
* @param trackSelectionArray The selected tracks.
|
||||||
* @return The target buffer size in bytes.
|
* @return The target buffer size in bytes.
|
||||||
*/
|
*/
|
||||||
protected int calculateTargetBufferBytes(
|
protected int calculateTargetBufferBytes(@NullableType ExoTrackSelection[] trackSelectionArray) {
|
||||||
Renderer[] renderers, ExoTrackSelection[] trackSelectionArray) {
|
|
||||||
int targetBufferSize = 0;
|
int targetBufferSize = 0;
|
||||||
for (int i = 0; i < renderers.length; i++) {
|
for (ExoTrackSelection exoTrackSelection : trackSelectionArray) {
|
||||||
if (trackSelectionArray[i] != null) {
|
if (exoTrackSelection != null) {
|
||||||
targetBufferSize += getDefaultBufferSize(renderers[i].getTrackType());
|
targetBufferSize += getDefaultBufferSize(exoTrackSelection.getTrackGroup().type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return max(DEFAULT_MIN_BUFFER_SIZE, targetBufferSize);
|
return max(DEFAULT_MIN_BUFFER_SIZE, targetBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #calculateTargetBufferBytes(ExoTrackSelection[])} instead.
|
||||||
|
*/
|
||||||
|
@InlineMe(replacement = "this.calculateTargetBufferBytes(trackSelectionArray)")
|
||||||
|
@Deprecated
|
||||||
|
protected final int calculateTargetBufferBytes(
|
||||||
|
Renderer[] renderers, ExoTrackSelection[] trackSelectionArray) {
|
||||||
|
return calculateTargetBufferBytes(trackSelectionArray);
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
/* package */ int calculateTotalTargetBufferBytes() {
|
/* package */ int calculateTotalTargetBufferBytes() {
|
||||||
int totalTargetBufferBytes = 0;
|
int totalTargetBufferBytes = 0;
|
||||||
|
|
@ -503,6 +510,7 @@ public class DefaultLoadControl implements LoadControl {
|
||||||
case C.TRACK_TYPE_NONE:
|
case C.TRACK_TYPE_NONE:
|
||||||
return 0;
|
return 0;
|
||||||
case C.TRACK_TYPE_UNKNOWN:
|
case C.TRACK_TYPE_UNKNOWN:
|
||||||
|
return DEFAULT_MIN_BUFFER_SIZE;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2008,6 +2008,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
}
|
}
|
||||||
// Get updated buffered duration as it may have changed since the start of the renderer loop.
|
// Get updated buffered duration as it may have changed since the start of the renderer loop.
|
||||||
long bufferedDurationUs = getTotalBufferedDurationUs(loadingHolder.getBufferedPositionUs());
|
long bufferedDurationUs = getTotalBufferedDurationUs(loadingHolder.getBufferedPositionUs());
|
||||||
|
|
||||||
return loadControl.shouldStartPlayback(
|
return loadControl.shouldStartPlayback(
|
||||||
new LoadControl.Parameters(
|
new LoadControl.Parameters(
|
||||||
playerId,
|
playerId,
|
||||||
|
|
@ -2907,11 +2908,29 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
MediaPeriodId mediaPeriodId,
|
MediaPeriodId mediaPeriodId,
|
||||||
TrackGroupArray trackGroups,
|
TrackGroupArray trackGroups,
|
||||||
TrackSelectorResult trackSelectorResult) {
|
TrackSelectorResult trackSelectorResult) {
|
||||||
|
MediaPeriodHolder loadingPeriodHolder = checkNotNull(queue.getLoadingPeriod());
|
||||||
|
long playbackPositionUs =
|
||||||
|
loadingPeriodHolder == queue.getPlayingPeriod()
|
||||||
|
? loadingPeriodHolder.toPeriodTime(rendererPositionUs)
|
||||||
|
: loadingPeriodHolder.toPeriodTime(rendererPositionUs)
|
||||||
|
- loadingPeriodHolder.info.startPositionUs;
|
||||||
|
long bufferedDurationUs =
|
||||||
|
getTotalBufferedDurationUs(loadingPeriodHolder.getBufferedPositionUs());
|
||||||
|
long targetLiveOffsetUs =
|
||||||
|
shouldUseLivePlaybackSpeedControl(playbackInfo.timeline, loadingPeriodHolder.info.id)
|
||||||
|
? livePlaybackSpeedControl.getTargetLiveOffsetUs()
|
||||||
|
: C.TIME_UNSET;
|
||||||
loadControl.onTracksSelected(
|
loadControl.onTracksSelected(
|
||||||
playerId,
|
new LoadControl.Parameters(
|
||||||
playbackInfo.timeline,
|
playerId,
|
||||||
mediaPeriodId,
|
playbackInfo.timeline,
|
||||||
renderers,
|
mediaPeriodId,
|
||||||
|
playbackPositionUs,
|
||||||
|
bufferedDurationUs,
|
||||||
|
mediaClock.getPlaybackParameters().speed,
|
||||||
|
playbackInfo.playWhenReady,
|
||||||
|
isRebuffering,
|
||||||
|
targetLiveOffsetUs),
|
||||||
trackGroups,
|
trackGroups,
|
||||||
trackSelectorResult.selections);
|
trackSelectorResult.selections);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.media3.common.Player;
|
||||||
import androidx.media3.common.Timeline;
|
import androidx.media3.common.Timeline;
|
||||||
import androidx.media3.common.TrackGroup;
|
import androidx.media3.common.TrackGroup;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
|
import androidx.media3.common.util.NullableType;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||||
import androidx.media3.exoplayer.source.MediaPeriod;
|
import androidx.media3.exoplayer.source.MediaPeriod;
|
||||||
|
|
@ -145,28 +146,40 @@ public interface LoadControl {
|
||||||
/**
|
/**
|
||||||
* Called by the player when a track selection occurs.
|
* Called by the player when a track selection occurs.
|
||||||
*
|
*
|
||||||
* @param playerId The {@linkplain PlayerId ID of the player} that selected tracks.
|
* @param parameters containing the {@linkplain PlayerId ID of the player}, the current {@link
|
||||||
* @param timeline The current {@link Timeline} in ExoPlayer.
|
* Timeline} in ExoPlayer, and the {@link MediaPeriod} for which the selection was made. Will
|
||||||
* @param mediaPeriodId Identifies (in the current timeline) the {@link MediaPeriod} for which the
|
* be {@link #EMPTY_MEDIA_PERIOD_ID} when {@code timeline} is empty.
|
||||||
* selection was made. Will be {@link #EMPTY_MEDIA_PERIOD_ID} when {@code timeline} is empty.
|
|
||||||
* @param renderers The renderers.
|
|
||||||
* @param trackGroups The {@link TrackGroup}s from which the selection was made.
|
* @param trackGroups The {@link TrackGroup}s from which the selection was made.
|
||||||
* @param trackSelections The track selections that were made.
|
* @param trackSelections The track selections that were made.
|
||||||
*/
|
*/
|
||||||
|
default void onTracksSelected(
|
||||||
|
Parameters parameters,
|
||||||
|
TrackGroupArray trackGroups,
|
||||||
|
@NullableType ExoTrackSelection[] trackSelections) {
|
||||||
|
// Media3 ExoPlayer will never call this method. This default implementation provides an
|
||||||
|
// implementation to please the compiler only.
|
||||||
|
throw new IllegalStateException("onTracksSelected not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Implement {@link #onTracksSelected(Parameters, TrackGroupArray,
|
||||||
|
* ExoTrackSelection[])} instead.
|
||||||
|
*/
|
||||||
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
||||||
|
@Deprecated
|
||||||
default void onTracksSelected(
|
default void onTracksSelected(
|
||||||
PlayerId playerId,
|
PlayerId playerId,
|
||||||
Timeline timeline,
|
Timeline timeline,
|
||||||
MediaPeriodId mediaPeriodId,
|
MediaPeriodId mediaPeriodId,
|
||||||
Renderer[] renderers,
|
Renderer[] renderers,
|
||||||
TrackGroupArray trackGroups,
|
TrackGroupArray trackGroups,
|
||||||
ExoTrackSelection[] trackSelections) {
|
@NullableType ExoTrackSelection[] trackSelections) {
|
||||||
onTracksSelected(timeline, mediaPeriodId, renderers, trackGroups, trackSelections);
|
onTracksSelected(timeline, mediaPeriodId, renderers, trackGroups, trackSelections);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Implement {@link #onTracksSelected(PlayerId, Timeline, MediaPeriodId, Renderer[],
|
* @deprecated Implement {@link #onTracksSelected(Parameters, TrackGroupArray,
|
||||||
* TrackGroupArray, ExoTrackSelection[])} instead.
|
* ExoTrackSelection[])} instead.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|
@ -175,18 +188,20 @@ public interface LoadControl {
|
||||||
MediaPeriodId mediaPeriodId,
|
MediaPeriodId mediaPeriodId,
|
||||||
Renderer[] renderers,
|
Renderer[] renderers,
|
||||||
TrackGroupArray trackGroups,
|
TrackGroupArray trackGroups,
|
||||||
ExoTrackSelection[] trackSelections) {
|
@NullableType ExoTrackSelection[] trackSelections) {
|
||||||
onTracksSelected(renderers, trackGroups, trackSelections);
|
onTracksSelected(renderers, trackGroups, trackSelections);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Implement {@link #onTracksSelected(PlayerId, Timeline, MediaPeriodId, Renderer[],
|
* @deprecated Implement {@link #onTracksSelected(Parameters, TrackGroupArray,
|
||||||
* TrackGroupArray, ExoTrackSelection[])} instead.
|
* ExoTrackSelection[])} instead.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default void onTracksSelected(
|
default void onTracksSelected(
|
||||||
Renderer[] renderers, TrackGroupArray trackGroups, ExoTrackSelection[] trackSelections) {
|
Renderer[] renderers,
|
||||||
|
TrackGroupArray trackGroups,
|
||||||
|
@NullableType ExoTrackSelection[] trackSelections) {
|
||||||
// Media3 ExoPlayer will never call this method. This default implementation provides an
|
// Media3 ExoPlayer will never call this method. This default implementation provides an
|
||||||
// implementation to please the compiler only.
|
// implementation to please the compiler only.
|
||||||
throw new IllegalStateException("onTracksSelected not implemented");
|
throw new IllegalStateException("onTracksSelected not implemented");
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import androidx.media3.exoplayer.source.TrackGroupArray;
|
||||||
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
||||||
import androidx.media3.exoplayer.trackselection.FixedTrackSelection;
|
import androidx.media3.exoplayer.trackselection.FixedTrackSelection;
|
||||||
import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
||||||
import androidx.media3.test.utils.FakeRenderer;
|
|
||||||
import androidx.media3.test.utils.FakeTimeline;
|
import androidx.media3.test.utils.FakeTimeline;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
@ -512,10 +511,16 @@ public class DefaultLoadControlTest {
|
||||||
loadControl = builder.build();
|
loadControl = builder.build();
|
||||||
loadControl.onPrepared(playerId);
|
loadControl.onPrepared(playerId);
|
||||||
loadControl.onTracksSelected(
|
loadControl.onTracksSelected(
|
||||||
playerId,
|
new LoadControl.Parameters(
|
||||||
timeline,
|
playerId,
|
||||||
mediaPeriodId,
|
timeline,
|
||||||
new Renderer[0],
|
mediaPeriodId,
|
||||||
|
/* playbackPositionUs= */ 0L,
|
||||||
|
/* bufferedDurationUs= */ 0L,
|
||||||
|
/* playbackSpeed= */ 1f,
|
||||||
|
/* playWhenReady= */ false,
|
||||||
|
/* rebuffering= */ false,
|
||||||
|
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||||
TrackGroupArray.EMPTY,
|
TrackGroupArray.EMPTY,
|
||||||
new ExoTrackSelection[0]);
|
new ExoTrackSelection[0]);
|
||||||
|
|
||||||
|
|
@ -747,24 +752,34 @@ public class DefaultLoadControlTest {
|
||||||
TrackGroup videoTrackGroup =
|
TrackGroup videoTrackGroup =
|
||||||
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build());
|
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build());
|
||||||
TrackGroupArray videoTrackGroupArray = new TrackGroupArray(videoTrackGroup);
|
TrackGroupArray videoTrackGroupArray = new TrackGroupArray(videoTrackGroup);
|
||||||
Renderer[] videoRenderer = new Renderer[] {new FakeRenderer(C.TRACK_TYPE_VIDEO)};
|
|
||||||
TrackGroup audioTrackGroup =
|
TrackGroup audioTrackGroup =
|
||||||
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build());
|
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build());
|
||||||
TrackGroupArray audioTrackGroupArray = new TrackGroupArray(audioTrackGroup);
|
TrackGroupArray audioTrackGroupArray = new TrackGroupArray(audioTrackGroup);
|
||||||
Renderer[] audioRenderer = new Renderer[] {new FakeRenderer(C.TRACK_TYPE_AUDIO)};
|
|
||||||
|
|
||||||
loadControl.onTracksSelected(
|
loadControl.onTracksSelected(
|
||||||
playerId,
|
new LoadControl.Parameters(
|
||||||
timeline,
|
playerId,
|
||||||
mediaPeriodId,
|
timeline,
|
||||||
videoRenderer,
|
mediaPeriodId,
|
||||||
|
/* playbackPositionUs= */ 0,
|
||||||
|
/* bufferedDurationUs= */ 0,
|
||||||
|
/* playbackSpeed= */ 1.0f,
|
||||||
|
/* playWhenReady= */ false,
|
||||||
|
/* rebuffering= */ false,
|
||||||
|
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||||
videoTrackGroupArray,
|
videoTrackGroupArray,
|
||||||
new ExoTrackSelection[] {new FixedTrackSelection(videoTrackGroup, /* track= */ 0)});
|
new ExoTrackSelection[] {new FixedTrackSelection(videoTrackGroup, /* track= */ 0)});
|
||||||
loadControl.onTracksSelected(
|
loadControl.onTracksSelected(
|
||||||
playerId2,
|
new LoadControl.Parameters(
|
||||||
timeline2,
|
playerId2,
|
||||||
mediaPeriodId2,
|
timeline2,
|
||||||
audioRenderer,
|
mediaPeriodId2,
|
||||||
|
/* playbackPositionUs= */ 0,
|
||||||
|
/* bufferedDurationUs= */ 0,
|
||||||
|
/* playbackSpeed= */ 1.0f,
|
||||||
|
/* playWhenReady= */ false,
|
||||||
|
/* rebuffering= */ false,
|
||||||
|
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||||
audioTrackGroupArray,
|
audioTrackGroupArray,
|
||||||
new ExoTrackSelection[] {new FixedTrackSelection(audioTrackGroup, /* track= */ 0)});
|
new ExoTrackSelection[] {new FixedTrackSelection(audioTrackGroup, /* track= */ 0)});
|
||||||
|
|
||||||
|
|
@ -796,10 +811,16 @@ public class DefaultLoadControlTest {
|
||||||
loadControl = builder.build();
|
loadControl = builder.build();
|
||||||
loadControl.onPrepared(playerId);
|
loadControl.onPrepared(playerId);
|
||||||
loadControl.onTracksSelected(
|
loadControl.onTracksSelected(
|
||||||
playerId,
|
new LoadControl.Parameters(
|
||||||
timeline,
|
playerId,
|
||||||
mediaPeriodId,
|
timeline,
|
||||||
new Renderer[0],
|
mediaPeriodId,
|
||||||
|
/* playbackPositionUs= */ 0,
|
||||||
|
/* bufferedDurationUs= */ 0,
|
||||||
|
/* playbackSpeed= */ 1.0f,
|
||||||
|
/* playWhenReady= */ false,
|
||||||
|
/* rebuffering= */ false,
|
||||||
|
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||||
/* trackGroups= */ null,
|
/* trackGroups= */ null,
|
||||||
/* trackSelections= */ null);
|
/* trackSelections= */ null);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue