use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.
the class MappingTrackSelector method findRenderer.
/**
* Finds the renderer to which the provided {@link TrackGroup} should be associated.
* <p>
* A {@link TrackGroup} is associated to a renderer that reports
* {@link RendererCapabilities#FORMAT_HANDLED} support for one or more of the tracks in the group,
* or {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES} if no such renderer exists, or
* {@link RendererCapabilities#FORMAT_UNSUPPORTED_SUBTYPE} if again no such renderer exists. In
* the case that two or more renderers report the same level of support, the renderer with the
* lowest index is associated.
* <p>
* If all renderers report {@link RendererCapabilities#FORMAT_UNSUPPORTED_TYPE} for all of the
* tracks in the group, then {@code renderers.length} is returned to indicate that no association
* was made.
*
* @param rendererCapabilities The {@link RendererCapabilities} of the renderers.
* @param group The {@link TrackGroup} whose associated renderer is to be found.
* @return The index of the associated renderer, or {@code renderers.length} if no
* association was made.
* @throws ExoPlaybackException If an error occurs finding a renderer.
*/
private static int findRenderer(RendererCapabilities[] rendererCapabilities, TrackGroup group) throws ExoPlaybackException {
int bestRendererIndex = rendererCapabilities.length;
int bestFormatSupportLevel = RendererCapabilities.FORMAT_UNSUPPORTED_TYPE;
for (int rendererIndex = 0; rendererIndex < rendererCapabilities.length; rendererIndex++) {
RendererCapabilities rendererCapability = rendererCapabilities[rendererIndex];
for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
int formatSupportLevel = rendererCapability.supportsFormat(group.getFormat(trackIndex)) & RendererCapabilities.FORMAT_SUPPORT_MASK;
if (formatSupportLevel > bestFormatSupportLevel) {
bestRendererIndex = rendererIndex;
bestFormatSupportLevel = formatSupportLevel;
if (bestFormatSupportLevel == RendererCapabilities.FORMAT_HANDLED) {
// We can't do better.
return bestRendererIndex;
}
}
}
}
return bestRendererIndex;
}
use of com.google.android.exoplayer2.source.TrackGroup in project ExoPlayer by google.
the class HlsMediaPeriod method selectTracks.
@Override
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
// Map each selection and stream onto a child period index.
int[] streamChildIndices = new int[selections.length];
int[] selectionChildIndices = new int[selections.length];
for (int i = 0; i < selections.length; i++) {
streamChildIndices[i] = streams[i] == null ? C.INDEX_UNSET : streamWrapperIndices.get(streams[i]);
selectionChildIndices[i] = C.INDEX_UNSET;
if (selections[i] != null) {
TrackGroup trackGroup = selections[i].getTrackGroup();
for (int j = 0; j < sampleStreamWrappers.length; j++) {
if (sampleStreamWrappers[j].getTrackGroups().indexOf(trackGroup) != C.INDEX_UNSET) {
selectionChildIndices[i] = j;
break;
}
}
}
}
boolean selectedNewTracks = false;
streamWrapperIndices.clear();
// Select tracks for each child, copying the resulting streams back into a new streams array.
SampleStream[] newStreams = new SampleStream[selections.length];
SampleStream[] childStreams = new SampleStream[selections.length];
TrackSelection[] childSelections = new TrackSelection[selections.length];
ArrayList<HlsSampleStreamWrapper> enabledSampleStreamWrapperList = new ArrayList<>(sampleStreamWrappers.length);
for (int i = 0; i < sampleStreamWrappers.length; i++) {
for (int j = 0; j < selections.length; j++) {
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
}
selectedNewTracks |= sampleStreamWrappers[i].selectTracks(childSelections, mayRetainStreamFlags, childStreams, streamResetFlags, !seenFirstTrackSelection);
boolean wrapperEnabled = false;
for (int j = 0; j < selections.length; j++) {
if (selectionChildIndices[j] == i) {
// Assert that the child provided a stream for the selection.
Assertions.checkState(childStreams[j] != null);
newStreams[j] = childStreams[j];
wrapperEnabled = true;
streamWrapperIndices.put(childStreams[j], i);
} else if (streamChildIndices[j] == i) {
// Assert that the child cleared any previous stream.
Assertions.checkState(childStreams[j] == null);
}
}
if (wrapperEnabled) {
enabledSampleStreamWrapperList.add(sampleStreamWrappers[i]);
}
}
// Copy the new streams back into the streams array.
System.arraycopy(newStreams, 0, streams, 0, newStreams.length);
// Update the local state.
enabledSampleStreamWrappers = new HlsSampleStreamWrapper[enabledSampleStreamWrapperList.size()];
enabledSampleStreamWrapperList.toArray(enabledSampleStreamWrappers);
// initialization.
if (enabledSampleStreamWrappers.length > 0) {
enabledSampleStreamWrappers[0].setIsTimestampMaster(true);
for (int i = 1; i < enabledSampleStreamWrappers.length; i++) {
enabledSampleStreamWrappers[i].setIsTimestampMaster(false);
}
}
sequenceableLoader = new CompositeSequenceableLoader(enabledSampleStreamWrappers);
if (seenFirstTrackSelection && selectedNewTracks) {
seekToUs(positionUs);
// We'll need to reset renderers consuming from all streams due to the seek.
for (int i = 0; i < selections.length; i++) {
if (streams[i] != null) {
streamResetFlags[i] = true;
}
}
}
seenFirstTrackSelection = true;
return positionUs;
}
Aggregations