mirror of
https://github.com/samsonjs/media.git
synced 2026-03-25 09:25:53 +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
|
||||
`DefaultPreloadManager` and `ExoPlayer` instances with consistently
|
||||
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:
|
||||
* Make setting the image duration using
|
||||
`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.util.Assertions;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.NullableType;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
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.DefaultAllocator;
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import com.google.errorprone.annotations.InlineMe;
|
||||
import java.util.HashMap;
|
||||
|
||||
/** The default {@link LoadControl} implementation. */
|
||||
|
|
@ -337,15 +339,12 @@ public class DefaultLoadControl implements LoadControl {
|
|||
|
||||
@Override
|
||||
public void onTracksSelected(
|
||||
PlayerId playerId,
|
||||
Timeline timeline,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
Renderer[] renderers,
|
||||
LoadControl.Parameters parameters,
|
||||
TrackGroupArray trackGroups,
|
||||
ExoTrackSelection[] trackSelections) {
|
||||
checkNotNull(loadingStates.get(playerId)).targetBufferBytes =
|
||||
@NullableType ExoTrackSelection[] trackSelections) {
|
||||
checkNotNull(loadingStates.get(parameters.playerId)).targetBufferBytes =
|
||||
targetBufferBytesOverwrite == C.LENGTH_UNSET
|
||||
? calculateTargetBufferBytes(renderers, trackSelections)
|
||||
? calculateTargetBufferBytes(trackSelections)
|
||||
: targetBufferBytesOverwrite;
|
||||
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
|
||||
* 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.
|
||||
* @return The target buffer size in bytes.
|
||||
*/
|
||||
protected int calculateTargetBufferBytes(
|
||||
Renderer[] renderers, ExoTrackSelection[] trackSelectionArray) {
|
||||
protected int calculateTargetBufferBytes(@NullableType ExoTrackSelection[] trackSelectionArray) {
|
||||
int targetBufferSize = 0;
|
||||
for (int i = 0; i < renderers.length; i++) {
|
||||
if (trackSelectionArray[i] != null) {
|
||||
targetBufferSize += getDefaultBufferSize(renderers[i].getTrackType());
|
||||
for (ExoTrackSelection exoTrackSelection : trackSelectionArray) {
|
||||
if (exoTrackSelection != null) {
|
||||
targetBufferSize += getDefaultBufferSize(exoTrackSelection.getTrackGroup().type);
|
||||
}
|
||||
}
|
||||
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
|
||||
/* package */ int calculateTotalTargetBufferBytes() {
|
||||
int totalTargetBufferBytes = 0;
|
||||
|
|
@ -503,6 +510,7 @@ public class DefaultLoadControl implements LoadControl {
|
|||
case C.TRACK_TYPE_NONE:
|
||||
return 0;
|
||||
case C.TRACK_TYPE_UNKNOWN:
|
||||
return DEFAULT_MIN_BUFFER_SIZE;
|
||||
default:
|
||||
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.
|
||||
long bufferedDurationUs = getTotalBufferedDurationUs(loadingHolder.getBufferedPositionUs());
|
||||
|
||||
return loadControl.shouldStartPlayback(
|
||||
new LoadControl.Parameters(
|
||||
playerId,
|
||||
|
|
@ -2907,11 +2908,29 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
MediaPeriodId mediaPeriodId,
|
||||
TrackGroupArray trackGroups,
|
||||
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(
|
||||
playerId,
|
||||
playbackInfo.timeline,
|
||||
mediaPeriodId,
|
||||
renderers,
|
||||
new LoadControl.Parameters(
|
||||
playerId,
|
||||
playbackInfo.timeline,
|
||||
mediaPeriodId,
|
||||
playbackPositionUs,
|
||||
bufferedDurationUs,
|
||||
mediaClock.getPlaybackParameters().speed,
|
||||
playbackInfo.playWhenReady,
|
||||
isRebuffering,
|
||||
targetLiveOffsetUs),
|
||||
trackGroups,
|
||||
trackSelectorResult.selections);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import androidx.media3.common.Player;
|
|||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.TrackGroup;
|
||||
import androidx.media3.common.util.Log;
|
||||
import androidx.media3.common.util.NullableType;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||
import androidx.media3.exoplayer.source.MediaPeriod;
|
||||
|
|
@ -145,28 +146,40 @@ public interface LoadControl {
|
|||
/**
|
||||
* Called by the player when a track selection occurs.
|
||||
*
|
||||
* @param playerId The {@linkplain PlayerId ID of the player} that selected tracks.
|
||||
* @param timeline The current {@link Timeline} in ExoPlayer.
|
||||
* @param mediaPeriodId Identifies (in the current timeline) the {@link MediaPeriod} for which the
|
||||
* selection was made. Will be {@link #EMPTY_MEDIA_PERIOD_ID} when {@code timeline} is empty.
|
||||
* @param renderers The renderers.
|
||||
* @param parameters containing the {@linkplain PlayerId ID of the player}, the current {@link
|
||||
* Timeline} in ExoPlayer, and the {@link MediaPeriod} for which the selection was made. Will
|
||||
* be {@link #EMPTY_MEDIA_PERIOD_ID} when {@code timeline} is empty.
|
||||
* @param trackGroups The {@link TrackGroup}s from which the selection was 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.
|
||||
@Deprecated
|
||||
default void onTracksSelected(
|
||||
PlayerId playerId,
|
||||
Timeline timeline,
|
||||
MediaPeriodId mediaPeriodId,
|
||||
Renderer[] renderers,
|
||||
TrackGroupArray trackGroups,
|
||||
ExoTrackSelection[] trackSelections) {
|
||||
@NullableType ExoTrackSelection[] trackSelections) {
|
||||
onTracksSelected(timeline, mediaPeriodId, renderers, trackGroups, trackSelections);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Implement {@link #onTracksSelected(PlayerId, Timeline, MediaPeriodId, Renderer[],
|
||||
* TrackGroupArray, ExoTrackSelection[])} instead.
|
||||
* @deprecated Implement {@link #onTracksSelected(Parameters, TrackGroupArray,
|
||||
* ExoTrackSelection[])} instead.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
||||
@Deprecated
|
||||
|
|
@ -175,18 +188,20 @@ public interface LoadControl {
|
|||
MediaPeriodId mediaPeriodId,
|
||||
Renderer[] renderers,
|
||||
TrackGroupArray trackGroups,
|
||||
ExoTrackSelection[] trackSelections) {
|
||||
@NullableType ExoTrackSelection[] trackSelections) {
|
||||
onTracksSelected(renderers, trackGroups, trackSelections);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Implement {@link #onTracksSelected(PlayerId, Timeline, MediaPeriodId, Renderer[],
|
||||
* TrackGroupArray, ExoTrackSelection[])} instead.
|
||||
* @deprecated Implement {@link #onTracksSelected(Parameters, TrackGroupArray,
|
||||
* ExoTrackSelection[])} instead.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // Calling deprecated version of this method.
|
||||
@Deprecated
|
||||
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
|
||||
// implementation to please the compiler only.
|
||||
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.FixedTrackSelection;
|
||||
import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
||||
import androidx.media3.test.utils.FakeRenderer;
|
||||
import androidx.media3.test.utils.FakeTimeline;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import org.junit.Before;
|
||||
|
|
@ -512,10 +511,16 @@ public class DefaultLoadControlTest {
|
|||
loadControl = builder.build();
|
||||
loadControl.onPrepared(playerId);
|
||||
loadControl.onTracksSelected(
|
||||
playerId,
|
||||
timeline,
|
||||
mediaPeriodId,
|
||||
new Renderer[0],
|
||||
new LoadControl.Parameters(
|
||||
playerId,
|
||||
timeline,
|
||||
mediaPeriodId,
|
||||
/* playbackPositionUs= */ 0L,
|
||||
/* bufferedDurationUs= */ 0L,
|
||||
/* playbackSpeed= */ 1f,
|
||||
/* playWhenReady= */ false,
|
||||
/* rebuffering= */ false,
|
||||
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||
TrackGroupArray.EMPTY,
|
||||
new ExoTrackSelection[0]);
|
||||
|
||||
|
|
@ -747,24 +752,34 @@ public class DefaultLoadControlTest {
|
|||
TrackGroup videoTrackGroup =
|
||||
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build());
|
||||
TrackGroupArray videoTrackGroupArray = new TrackGroupArray(videoTrackGroup);
|
||||
Renderer[] videoRenderer = new Renderer[] {new FakeRenderer(C.TRACK_TYPE_VIDEO)};
|
||||
TrackGroup audioTrackGroup =
|
||||
new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build());
|
||||
TrackGroupArray audioTrackGroupArray = new TrackGroupArray(audioTrackGroup);
|
||||
Renderer[] audioRenderer = new Renderer[] {new FakeRenderer(C.TRACK_TYPE_AUDIO)};
|
||||
|
||||
loadControl.onTracksSelected(
|
||||
playerId,
|
||||
timeline,
|
||||
mediaPeriodId,
|
||||
videoRenderer,
|
||||
new LoadControl.Parameters(
|
||||
playerId,
|
||||
timeline,
|
||||
mediaPeriodId,
|
||||
/* playbackPositionUs= */ 0,
|
||||
/* bufferedDurationUs= */ 0,
|
||||
/* playbackSpeed= */ 1.0f,
|
||||
/* playWhenReady= */ false,
|
||||
/* rebuffering= */ false,
|
||||
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||
videoTrackGroupArray,
|
||||
new ExoTrackSelection[] {new FixedTrackSelection(videoTrackGroup, /* track= */ 0)});
|
||||
loadControl.onTracksSelected(
|
||||
playerId2,
|
||||
timeline2,
|
||||
mediaPeriodId2,
|
||||
audioRenderer,
|
||||
new LoadControl.Parameters(
|
||||
playerId2,
|
||||
timeline2,
|
||||
mediaPeriodId2,
|
||||
/* playbackPositionUs= */ 0,
|
||||
/* bufferedDurationUs= */ 0,
|
||||
/* playbackSpeed= */ 1.0f,
|
||||
/* playWhenReady= */ false,
|
||||
/* rebuffering= */ false,
|
||||
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||
audioTrackGroupArray,
|
||||
new ExoTrackSelection[] {new FixedTrackSelection(audioTrackGroup, /* track= */ 0)});
|
||||
|
||||
|
|
@ -796,10 +811,16 @@ public class DefaultLoadControlTest {
|
|||
loadControl = builder.build();
|
||||
loadControl.onPrepared(playerId);
|
||||
loadControl.onTracksSelected(
|
||||
playerId,
|
||||
timeline,
|
||||
mediaPeriodId,
|
||||
new Renderer[0],
|
||||
new LoadControl.Parameters(
|
||||
playerId,
|
||||
timeline,
|
||||
mediaPeriodId,
|
||||
/* playbackPositionUs= */ 0,
|
||||
/* bufferedDurationUs= */ 0,
|
||||
/* playbackSpeed= */ 1.0f,
|
||||
/* playWhenReady= */ false,
|
||||
/* rebuffering= */ false,
|
||||
/* targetLiveOffsetUs= */ C.TIME_UNSET),
|
||||
/* trackGroups= */ null,
|
||||
/* trackSelections= */ null);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue