use of io.atlasmap.v2.Format in project ExoPlayer by google.
the class DefaultTrackSelector method selectTextTrack.
// Text track selection implementation.
protected TrackSelection selectTextTrack(TrackGroupArray groups, int[][] formatSupport, String preferredTextLanguage, String preferredAudioLanguage, boolean exceedRendererCapabilitiesIfNecessary) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
int selectedTrackScore = 0;
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
TrackGroup trackGroup = groups.get(groupIndex);
int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex);
boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
boolean isForced = (format.selectionFlags & C.SELECTION_FLAG_FORCED) != 0;
int trackScore;
if (formatHasLanguage(format, preferredTextLanguage)) {
if (isDefault) {
trackScore = 6;
} else if (!isForced) {
// Prefer non-forced to forced if a preferred text language has been specified. Where
// both are provided the non-forced track will usually contain the forced subtitles as
// a subset.
trackScore = 5;
} else {
trackScore = 4;
}
} else if (isDefault) {
trackScore = 3;
} else if (isForced) {
if (formatHasLanguage(format, preferredAudioLanguage)) {
trackScore = 2;
} else {
trackScore = 1;
}
} else {
// Track should not be selected.
continue;
}
if (isSupported(trackFormatSupport[trackIndex], false)) {
trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
}
if (trackScore > selectedTrackScore) {
selectedGroup = trackGroup;
selectedTrackIndex = trackIndex;
selectedTrackScore = trackScore;
}
}
}
}
return selectedGroup == null ? null : new FixedTrackSelection(selectedGroup, selectedTrackIndex);
}
use of io.atlasmap.v2.Format in project ExoPlayer by google.
the class DefaultTrackSelector method selectFixedVideoTrack.
private static TrackSelection selectFixedVideoTrack(TrackGroupArray groups, int[][] formatSupport, int maxVideoWidth, int maxVideoHeight, int maxVideoBitrate, int viewportWidth, int viewportHeight, boolean orientationMayChange, boolean exceedConstraintsIfNecessary, boolean exceedRendererCapabilitiesIfNecessary) {
TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
int selectedTrackScore = 0;
int selectedBitrate = Format.NO_VALUE;
int selectedPixelCount = Format.NO_VALUE;
for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
TrackGroup trackGroup = groups.get(groupIndex);
List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(trackGroup, viewportWidth, viewportHeight, orientationMayChange);
int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex);
boolean isWithinConstraints = selectedTrackIndices.contains(trackIndex) && (format.width == Format.NO_VALUE || format.width <= maxVideoWidth) && (format.height == Format.NO_VALUE || format.height <= maxVideoHeight) && (format.bitrate == Format.NO_VALUE || format.bitrate <= maxVideoBitrate);
if (!isWithinConstraints && !exceedConstraintsIfNecessary) {
// Track should not be selected.
continue;
}
int trackScore = isWithinConstraints ? 2 : 1;
if (isSupported(trackFormatSupport[trackIndex], false)) {
trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
}
boolean selectTrack = trackScore > selectedTrackScore;
if (trackScore == selectedTrackScore) {
// Use the pixel count as a tie breaker (or bitrate if pixel counts are tied). If we're
// within constraints prefer a higher pixel count (or bitrate), else prefer a lower
// count (or bitrate). If still tied then prefer the first track (i.e. the one that's
// already selected).
int comparisonResult;
int formatPixelCount = format.getPixelCount();
if (formatPixelCount != selectedPixelCount) {
comparisonResult = compareFormatValues(format.getPixelCount(), selectedPixelCount);
} else {
comparisonResult = compareFormatValues(format.bitrate, selectedBitrate);
}
selectTrack = isWithinConstraints ? comparisonResult > 0 : comparisonResult < 0;
}
if (selectTrack) {
selectedGroup = trackGroup;
selectedTrackIndex = trackIndex;
selectedTrackScore = trackScore;
selectedBitrate = format.bitrate;
selectedPixelCount = format.getPixelCount();
}
}
}
}
return selectedGroup == null ? null : new FixedTrackSelection(selectedGroup, selectedTrackIndex);
}
use of io.atlasmap.v2.Format in project ExoPlayer by google.
the class DefaultTrackSelector method getViewportFilteredTrackIndices.
// Viewport size util methods.
private static List<Integer> getViewportFilteredTrackIndices(TrackGroup group, int viewportWidth, int viewportHeight, boolean orientationMayChange) {
// Initially include all indices.
ArrayList<Integer> selectedTrackIndices = new ArrayList<>(group.length);
for (int i = 0; i < group.length; i++) {
selectedTrackIndices.add(i);
}
if (viewportWidth == Integer.MAX_VALUE || viewportHeight == Integer.MAX_VALUE) {
// Viewport dimensions not set. Return the full set of indices.
return selectedTrackIndices;
}
int maxVideoPixelsToRetain = Integer.MAX_VALUE;
for (int i = 0; i < group.length; i++) {
Format format = group.getFormat(i);
// We'll discard formats of higher resolution.
if (format.width > 0 && format.height > 0) {
Point maxVideoSizeInViewport = getMaxVideoSizeInViewport(orientationMayChange, viewportWidth, viewportHeight, format.width, format.height);
int videoPixels = format.width * format.height;
if (format.width >= (int) (maxVideoSizeInViewport.x * FRACTION_TO_CONSIDER_FULLSCREEN) && format.height >= (int) (maxVideoSizeInViewport.y * FRACTION_TO_CONSIDER_FULLSCREEN) && videoPixels < maxVideoPixelsToRetain) {
maxVideoPixelsToRetain = videoPixels;
}
}
}
// filter out formats with unknown dimensions, since we have some whose dimensions are known.
if (maxVideoPixelsToRetain != Integer.MAX_VALUE) {
for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) {
Format format = group.getFormat(selectedTrackIndices.get(i));
int pixelCount = format.getPixelCount();
if (pixelCount == Format.NO_VALUE || pixelCount > maxVideoPixelsToRetain) {
selectedTrackIndices.remove(i);
}
}
}
return selectedTrackIndices;
}
use of io.atlasmap.v2.Format in project ExoPlayer by google.
the class WavExtractor method read.
@Override
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException {
if (wavHeader == null) {
wavHeader = WavHeaderReader.peek(input);
if (wavHeader == null) {
// Should only happen if the media wasn't sniffed.
throw new ParserException("Unsupported or unrecognized wav header.");
}
Format format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_RAW, null, wavHeader.getBitrate(), MAX_INPUT_SIZE, wavHeader.getNumChannels(), wavHeader.getSampleRateHz(), wavHeader.getEncoding(), null, null, 0, null);
trackOutput.format(format);
bytesPerFrame = wavHeader.getBytesPerFrame();
}
if (!wavHeader.hasDataBounds()) {
WavHeaderReader.skipToData(input, wavHeader);
extractorOutput.seekMap(this);
}
int bytesAppended = trackOutput.sampleData(input, MAX_INPUT_SIZE - pendingBytes, true);
if (bytesAppended != RESULT_END_OF_INPUT) {
pendingBytes += bytesAppended;
}
// Samples must consist of a whole number of frames.
int pendingFrames = pendingBytes / bytesPerFrame;
if (pendingFrames > 0) {
long timeUs = wavHeader.getTimeUs(input.getPosition() - pendingBytes);
int size = pendingFrames * bytesPerFrame;
pendingBytes -= size;
trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, size, pendingBytes, null);
}
return bytesAppended == RESULT_END_OF_INPUT ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
}
use of io.atlasmap.v2.Format in project ExoPlayer by google.
the class HlsSampleStreamWrapper method readData.
/* package */
int readData(int group, FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) {
if (isPendingReset()) {
return C.RESULT_NOTHING_READ;
}
while (mediaChunks.size() > 1 && finishedReadingChunk(mediaChunks.getFirst())) {
mediaChunks.removeFirst();
}
HlsMediaChunk currentChunk = mediaChunks.getFirst();
Format trackFormat = currentChunk.trackFormat;
if (!trackFormat.equals(downstreamTrackFormat)) {
eventDispatcher.downstreamFormatChanged(trackType, trackFormat, currentChunk.trackSelectionReason, currentChunk.trackSelectionData, currentChunk.startTimeUs);
}
downstreamTrackFormat = trackFormat;
return sampleQueues.valueAt(group).readData(formatHolder, buffer, requireFormat, loadingFinished, lastSeekPositionUs);
}
Aggregations