com.google.android.exoplayer2.source.TrackGroup Java Examples

The following examples show how to use com.google.android.exoplayer2.source.TrackGroup. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AdaptiveTrackSelection.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
public AdaptiveTrackSelection createTrackSelection(
    TrackGroup group, BandwidthMeter bandwidthMeter, int... tracks) {
  if (this.bandwidthMeter != null) {
    bandwidthMeter = this.bandwidthMeter;
  }
  return new AdaptiveTrackSelection(
      group,
      tracks,
      bandwidthMeter,
      minDurationForQualityIncreaseMs,
      maxDurationForQualityDecreaseMs,
      minDurationToRetainAfterDiscardMs,
      bandwidthFraction,
      bufferedFractionToLiveEdgeForQualityIncrease,
      minTimeBetweenBufferReevaluationMs,
      clock);
}
 
Example #2
Source File: BaseTrackSelection.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * @param group The {@link TrackGroup}. Must not be null.
 * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
 *     null or empty. May be in any order.
 */
public BaseTrackSelection(TrackGroup group, int... tracks) {
  Assertions.checkState(tracks.length > 0);
  this.group = Assertions.checkNotNull(group);
  this.length = tracks.length;
  // Set the formats, sorted in order of decreasing bandwidth.
  formats = new Format[length];
  for (int i = 0; i < tracks.length; i++) {
    formats[i] = group.getFormat(tracks[i]);
  }
  Arrays.sort(formats, new DecreasingBandwidthComparator());
  // Set the format indices in the same order.
  this.tracks = new int[length];
  for (int i = 0; i < length; i++) {
    this.tracks[i] = group.indexOf(formats[i]);
  }
  blacklistUntilTimes = new long[length];
}
 
Example #3
Source File: AdaptiveTrackSelection.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * @param group The {@link TrackGroup}.
 * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
 *     empty. May be in any order.
 * @param bandwidthMeter Provides an estimate of the currently available bandwidth.
 */
public AdaptiveTrackSelection(TrackGroup group, int[] tracks,
    BandwidthMeter bandwidthMeter) {
  this(
      group,
      tracks,
      bandwidthMeter,
      /* reservedBandwidth= */ 0,
      DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
      DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
      DEFAULT_MIN_DURATION_TO_RETAIN_AFTER_DISCARD_MS,
      DEFAULT_BANDWIDTH_FRACTION,
      DEFAULT_BUFFERED_FRACTION_TO_LIVE_EDGE_FOR_QUALITY_INCREASE,
      DEFAULT_MIN_TIME_BETWEEN_BUFFER_REEVALUTATION_MS,
      Clock.DEFAULT);
}
 
Example #4
Source File: BaseTrackSelection.java    From Telegram with GNU General Public License v2.0 6 votes vote down vote up
/**
 * @param group The {@link TrackGroup}. Must not be null.
 * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
 *     null or empty. May be in any order.
 */
public BaseTrackSelection(TrackGroup group, int... tracks) {
  Assertions.checkState(tracks.length > 0);
  this.group = Assertions.checkNotNull(group);
  this.length = tracks.length;
  // Set the formats, sorted in order of decreasing bandwidth.
  formats = new Format[length];
  for (int i = 0; i < tracks.length; i++) {
    formats[i] = group.getFormat(tracks[i]);
  }
  Arrays.sort(formats, new DecreasingBandwidthComparator());
  // Set the format indices in the same order.
  this.tracks = new int[length];
  for (int i = 0; i < length; i++) {
    this.tracks[i] = group.indexOf(formats[i]);
  }
  blacklistUntilTimes = new long[length];
}
 
Example #5
Source File: DefaultTrackSelector.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
private static void filterAdaptiveVideoTrackCountForMimeType(
    TrackGroup group,
    int[] formatSupport,
    int requiredAdaptiveSupport,
    @Nullable String mimeType,
    int maxVideoWidth,
    int maxVideoHeight,
    int maxVideoFrameRate,
    int maxVideoBitrate,
    List<Integer> selectedTrackIndices) {
  for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) {
    int trackIndex = selectedTrackIndices.get(i);
    if (!isSupportedAdaptiveVideoTrack(
        group.getFormat(trackIndex),
        mimeType,
        formatSupport[trackIndex],
        requiredAdaptiveSupport,
        maxVideoWidth,
        maxVideoHeight,
        maxVideoFrameRate,
        maxVideoBitrate)) {
      selectedTrackIndices.remove(i);
    }
  }
}
 
Example #6
Source File: BaseTrackSelection.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * @param group The {@link TrackGroup}. Must not be null.
 * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
 *     null or empty. May be in any order.
 */
public BaseTrackSelection(TrackGroup group, int... tracks) {
  Assertions.checkState(tracks.length > 0);
  this.group = Assertions.checkNotNull(group);
  this.length = tracks.length;
  // Set the formats, sorted in order of decreasing bandwidth.
  formats = new Format[length];
  for (int i = 0; i < tracks.length; i++) {
    formats[i] = group.getFormat(tracks[i]);
  }
  Arrays.sort(formats, new DecreasingBandwidthComparator());
  // Set the format indices in the same order.
  this.tracks = new int[length];
  for (int i = 0; i < length; i++) {
    this.tracks[i] = group.indexOf(formats[i]);
  }
  blacklistUntilTimes = new long[length];
}
 
Example #7
Source File: SsMediaPeriod.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
private static TrackGroupArray buildTrackGroups(
    SsManifest manifest, DrmSessionManager<?> drmSessionManager) {
  TrackGroup[] trackGroups = new TrackGroup[manifest.streamElements.length];
  for (int i = 0; i < manifest.streamElements.length; i++) {
    Format[] manifestFormats = manifest.streamElements[i].formats;
    Format[] exposedFormats = new Format[manifestFormats.length];
    for (int j = 0; j < manifestFormats.length; j++) {
      Format manifestFormat = manifestFormats[j];
      exposedFormats[j] =
          manifestFormat.drmInitData != null
              ? manifestFormat.copyWithExoMediaCryptoType(
                  drmSessionManager.getExoMediaCryptoType(manifestFormat.drmInitData))
              : manifestFormat;
    }
    trackGroups[i] = new TrackGroup(exposedFormats);
  }
  return new TrackGroupArray(trackGroups);
}
 
Example #8
Source File: MappingTrackSelector.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Finds the renderer to which the provided {@link TrackGroup} should be mapped.
 * <p>
 * A {@link TrackGroup} is mapped to the renderer that reports the highest of (listed in
 * decreasing order of support) {@link RendererCapabilities#FORMAT_HANDLED},
 * {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES},
 * {@link RendererCapabilities#FORMAT_UNSUPPORTED_DRM} and
 * {@link RendererCapabilities#FORMAT_UNSUPPORTED_SUBTYPE}. 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 the group was
 * not mapped to any renderer.
 *
 * @param rendererCapabilities The {@link RendererCapabilities} of the renderers.
 * @param group The track group to map to a renderer.
 * @return The index of the renderer to which the track group was mapped, or
 *     {@code renderers.length} if it was not mapped to any renderer.
 * @throws ExoPlaybackException If an error occurs finding a renderer.
 */
private static int findRenderer(RendererCapabilities[] rendererCapabilities, TrackGroup group)
    throws ExoPlaybackException {
  int bestRendererIndex = rendererCapabilities.length;
  @FormatSupport 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++) {
      @FormatSupport
      int formatSupportLevel =
          RendererCapabilities.getFormatSupport(
              rendererCapability.supportsFormat(group.getFormat(trackIndex)));
      if (formatSupportLevel > bestFormatSupportLevel) {
        bestRendererIndex = rendererIndex;
        bestFormatSupportLevel = formatSupportLevel;
        if (bestFormatSupportLevel == RendererCapabilities.FORMAT_HANDLED) {
          // We can't do better.
          return bestRendererIndex;
        }
      }
    }
  }
  return bestRendererIndex;
}
 
Example #9
Source File: HlsDownloadHelper.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
public TrackGroupArray getTrackGroups(int periodIndex) {
  Assertions.checkNotNull(playlist);
  if (playlist instanceof HlsMediaPlaylist) {
    renditionGroups = new int[0];
    return TrackGroupArray.EMPTY;
  }
  // TODO: Generate track groups as in playback. Reverse the mapping in getDownloadAction.
  HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist;
  TrackGroup[] trackGroups = new TrackGroup[3];
  renditionGroups = new int[3];
  int trackGroupIndex = 0;
  if (!masterPlaylist.variants.isEmpty()) {
    renditionGroups[trackGroupIndex] = HlsMasterPlaylist.GROUP_INDEX_VARIANT;
    trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.variants));
  }
  if (!masterPlaylist.audios.isEmpty()) {
    renditionGroups[trackGroupIndex] = HlsMasterPlaylist.GROUP_INDEX_AUDIO;
    trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.audios));
  }
  if (!masterPlaylist.subtitles.isEmpty()) {
    renditionGroups[trackGroupIndex] = HlsMasterPlaylist.GROUP_INDEX_SUBTITLE;
    trackGroups[trackGroupIndex++] = new TrackGroup(toFormats(masterPlaylist.subtitles));
  }
  return new TrackGroupArray(Arrays.copyOf(trackGroups, trackGroupIndex));
}
 
Example #10
Source File: MappingTrackSelector.java    From Telegram-FOSS with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Finds the renderer to which the provided {@link TrackGroup} should be mapped.
 * <p>
 * A {@link TrackGroup} is mapped to the renderer that reports the highest of (listed in
 * decreasing order of support) {@link RendererCapabilities#FORMAT_HANDLED},
 * {@link RendererCapabilities#FORMAT_EXCEEDS_CAPABILITIES},
 * {@link RendererCapabilities#FORMAT_UNSUPPORTED_DRM} and
 * {@link RendererCapabilities#FORMAT_UNSUPPORTED_SUBTYPE}. 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 the group was
 * not mapped to any renderer.
 *
 * @param rendererCapabilities The {@link RendererCapabilities} of the renderers.
 * @param group The track group to map to a renderer.
 * @return The index of the renderer to which the track group was mapped, or
 *     {@code renderers.length} if it was not mapped to any renderer.
 * @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;
}
 
Example #11
Source File: MappingTrackSelector.java    From K-Sonic with MIT License 6 votes vote down vote up
/**
 * 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;
}
 
Example #12
Source File: DefaultTrackSelector.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
private static int getAdaptiveVideoTrackCountForMimeType(
    TrackGroup group,
    int[] formatSupport,
    int requiredAdaptiveSupport,
    @Nullable String mimeType,
    int maxVideoWidth,
    int maxVideoHeight,
    int maxVideoBitrate,
    List<Integer> selectedTrackIndices) {
  int adaptiveTrackCount = 0;
  for (int i = 0; i < selectedTrackIndices.size(); i++) {
    int trackIndex = selectedTrackIndices.get(i);
    if (isSupportedAdaptiveVideoTrack(group.getFormat(trackIndex), mimeType,
        formatSupport[trackIndex], requiredAdaptiveSupport, maxVideoWidth, maxVideoHeight,
        maxVideoBitrate)) {
      adaptiveTrackCount++;
    }
  }
  return adaptiveTrackCount;
}
 
Example #13
Source File: BaseTrackSelection.java    From K-Sonic with MIT License 6 votes vote down vote up
/**
 * @param group The {@link TrackGroup}. Must not be null.
 * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
 *     null or empty. May be in any order.
 */
public BaseTrackSelection(TrackGroup group, int... tracks) {
  Assertions.checkState(tracks.length > 0);
  this.group = Assertions.checkNotNull(group);
  this.length = tracks.length;
  // Set the formats, sorted in order of decreasing bandwidth.
  formats = new Format[length];
  for (int i = 0; i < tracks.length; i++) {
    formats[i] = group.getFormat(tracks[i]);
  }
  Arrays.sort(formats, new DecreasingBandwidthComparator());
  // Set the format indices in the same order.
  this.tracks = new int[length];
  for (int i = 0; i < length; i++) {
    this.tracks[i] = group.indexOf(formats[i]);
  }
  blacklistUntilTimes = new long[length];
}
 
Example #14
Source File: DefaultTrackSelector.java    From K-Sonic with MIT License 5 votes vote down vote up
protected TrackSelection selectOtherTrack(int trackType, TrackGroupArray groups,
    int[][] formatSupport, 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;
        int trackScore = isDefault ? 2 : 1;
        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);
}
 
Example #15
Source File: HlsChunkSource.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @param extractorFactory An {@link HlsExtractorFactory} from which to obtain the extractors for
 *     media chunks.
 * @param playlistTracker The {@link HlsPlaylistTracker} from which to obtain media playlists.
 * @param playlistUrls The {@link Uri}s of the media playlists that can be adapted between by this
 *     chunk source.
 * @param playlistFormats The {@link Format Formats} corresponding to the media playlists.
 * @param dataSourceFactory An {@link HlsDataSourceFactory} to create {@link DataSource}s for the
 *     chunks.
 * @param mediaTransferListener The transfer listener which should be informed of any media data
 *     transfers. May be null if no listener is available.
 * @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If multiple
 *     {@link HlsChunkSource}s are used for a single playback, they should all share the same
 *     provider.
 * @param muxedCaptionFormats List of muxed caption {@link Format}s. Null if no closed caption
 *     information is available in the master playlist.
 */
public HlsChunkSource(
    HlsExtractorFactory extractorFactory,
    HlsPlaylistTracker playlistTracker,
    Uri[] playlistUrls,
    Format[] playlistFormats,
    HlsDataSourceFactory dataSourceFactory,
    @Nullable TransferListener mediaTransferListener,
    TimestampAdjusterProvider timestampAdjusterProvider,
    List<Format> muxedCaptionFormats) {
  this.extractorFactory = extractorFactory;
  this.playlistTracker = playlistTracker;
  this.playlistUrls = playlistUrls;
  this.playlistFormats = playlistFormats;
  this.timestampAdjusterProvider = timestampAdjusterProvider;
  this.muxedCaptionFormats = muxedCaptionFormats;
  keyCache = new FullSegmentEncryptionKeyCache();
  liveEdgeInPeriodTimeUs = C.TIME_UNSET;
  mediaDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_MEDIA);
  if (mediaTransferListener != null) {
    mediaDataSource.addTransferListener(mediaTransferListener);
  }
  encryptionDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_DRM);
  trackGroup = new TrackGroup(playlistFormats);
  int[] initialTrackSelection = new int[playlistUrls.length];
  for (int i = 0; i < playlistUrls.length; i++) {
    initialTrackSelection[i] = i;
  }
  trackSelection = new InitializationTrackSelection(trackGroup, initialTrackSelection);
}
 
Example #16
Source File: BufferSizeAdaptationBuilder.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
private BufferSizeAdaptiveTrackSelection(
    TrackGroup trackGroup,
    int[] tracks,
    BandwidthMeter bandwidthMeter,
    int minBufferMs,
    int maxBufferMs,
    int hysteresisBufferMs,
    float startUpBandwidthFraction,
    int startUpMinBufferForQualityIncreaseMs,
    DynamicFormatFilter dynamicFormatFilter,
    Clock clock) {
  super(trackGroup, tracks);
  this.bandwidthMeter = bandwidthMeter;
  this.minBufferUs = C.msToUs(minBufferMs);
  this.maxBufferUs = C.msToUs(maxBufferMs);
  this.hysteresisBufferUs = C.msToUs(hysteresisBufferMs);
  this.startUpBandwidthFraction = startUpBandwidthFraction;
  this.startUpMinBufferForQualityIncreaseUs = C.msToUs(startUpMinBufferForQualityIncreaseMs);
  this.dynamicFormatFilter = dynamicFormatFilter;
  this.clock = clock;

  formatBitrates = new int[length];
  maxBitrate = getFormat(/* index= */ 0).bitrate;
  minBitrate = getFormat(/* index= */ length - 1).bitrate;
  selectionReason = C.SELECTION_REASON_UNKNOWN;
  playbackSpeed = 1.0f;

  // We use a log-linear function to map from bitrate to buffer size:
  // buffer = slope * ln(bitrate) + intercept,
  // with buffer(minBitrate) = minBuffer and buffer(maxBitrate) = maxBuffer - hysteresisBuffer.
  bitrateToBufferFunctionSlope =
      (maxBufferUs - hysteresisBufferUs - minBufferUs)
          / Math.log((double) maxBitrate / minBitrate);
  bitrateToBufferFunctionIntercept =
      minBufferUs - bitrateToBufferFunctionSlope * Math.log(minBitrate);
}
 
Example #17
Source File: SsMediaPeriod.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static TrackGroupArray buildTrackGroups(SsManifest manifest) {
  TrackGroup[] trackGroups = new TrackGroup[manifest.streamElements.length];
  for (int i = 0; i < manifest.streamElements.length; i++) {
    trackGroups[i] = new TrackGroup(manifest.streamElements[i].formats);
  }
  return new TrackGroupArray(trackGroups);
}
 
Example #18
Source File: DefaultTrackSelector.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static int[] getAdaptiveAudioTracks(TrackGroup group, int[] formatSupport,
    boolean allowMixedMimeTypes) {
  int selectedConfigurationTrackCount = 0;
  AudioConfigurationTuple selectedConfiguration = null;
  HashSet<AudioConfigurationTuple> seenConfigurationTuples = new HashSet<>();
  for (int i = 0; i < group.length; i++) {
    Format format = group.getFormat(i);
    AudioConfigurationTuple configuration = new AudioConfigurationTuple(
        format.channelCount, format.sampleRate,
        allowMixedMimeTypes ? null : format.sampleMimeType);
    if (seenConfigurationTuples.add(configuration)) {
      int configurationCount = getAdaptiveAudioTrackCount(group, formatSupport, configuration);
      if (configurationCount > selectedConfigurationTrackCount) {
        selectedConfiguration = configuration;
        selectedConfigurationTrackCount = configurationCount;
      }
    }
  }

  if (selectedConfigurationTrackCount > 1) {
    int[] adaptiveIndices = new int[selectedConfigurationTrackCount];
    int index = 0;
    for (int i = 0; i < group.length; i++) {
      if (isSupportedAdaptiveAudioTrack(
          group.getFormat(i), formatSupport[i], Assertions.checkNotNull(selectedConfiguration))) {
        adaptiveIndices[index++] = i;
      }
    }
    return adaptiveIndices;
  }
  return NO_TRACKS;
}
 
Example #19
Source File: AdaptiveTrackSelection.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private AdaptiveTrackSelection(
    TrackGroup group,
    int[] tracks,
    BandwidthProvider bandwidthProvider,
    long minDurationForQualityIncreaseMs,
    long maxDurationForQualityDecreaseMs,
    long minDurationToRetainAfterDiscardMs,
    float bufferedFractionToLiveEdgeForQualityIncrease,
    long minTimeBetweenBufferReevaluationMs,
    Clock clock) {
  super(group, tracks);
  this.bandwidthProvider = bandwidthProvider;
  this.minDurationForQualityIncreaseUs = minDurationForQualityIncreaseMs * 1000L;
  this.maxDurationForQualityDecreaseUs = maxDurationForQualityDecreaseMs * 1000L;
  this.minDurationToRetainAfterDiscardUs = minDurationToRetainAfterDiscardMs * 1000L;
  this.bufferedFractionToLiveEdgeForQualityIncrease =
      bufferedFractionToLiveEdgeForQualityIncrease;
  this.minTimeBetweenBufferReevaluationMs = minTimeBetweenBufferReevaluationMs;
  this.clock = clock;
  playbackSpeed = 1f;
  reason = C.SELECTION_REASON_UNKNOWN;
  lastBufferEvaluationMs = C.TIME_UNSET;
  trackBitrateEstimator = TrackBitrateEstimator.DEFAULT;
  formats = new Format[length];
  formatBitrates = new int[length];
  trackBitrates = new int[length];
  for (int i = 0; i < length; i++) {
    @SuppressWarnings("nullness:method.invocation.invalid")
    Format format = getFormat(i);
    formats[i] = format;
    formatBitrates[i] = formats[i].bitrate;
  }
}
 
Example #20
Source File: DashMediaPeriod.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
private static Pair<TrackGroupArray, TrackGroupInfo[]> buildTrackGroups(
    List<AdaptationSet> adaptationSets, List<EventStream> eventStreams) {
  int[][] groupedAdaptationSetIndices = getGroupedAdaptationSetIndices(adaptationSets);

  int primaryGroupCount = groupedAdaptationSetIndices.length;
  boolean[] primaryGroupHasEventMessageTrackFlags = new boolean[primaryGroupCount];
  Format[][] primaryGroupCea608TrackFormats = new Format[primaryGroupCount][];
  int totalEmbeddedTrackGroupCount =
      identifyEmbeddedTracks(
          primaryGroupCount,
          adaptationSets,
          groupedAdaptationSetIndices,
          primaryGroupHasEventMessageTrackFlags,
          primaryGroupCea608TrackFormats);

  int totalGroupCount = primaryGroupCount + totalEmbeddedTrackGroupCount + eventStreams.size();
  TrackGroup[] trackGroups = new TrackGroup[totalGroupCount];
  TrackGroupInfo[] trackGroupInfos = new TrackGroupInfo[totalGroupCount];

  int trackGroupCount =
      buildPrimaryAndEmbeddedTrackGroupInfos(
          adaptationSets,
          groupedAdaptationSetIndices,
          primaryGroupCount,
          primaryGroupHasEventMessageTrackFlags,
          primaryGroupCea608TrackFormats,
          trackGroups,
          trackGroupInfos);

  buildManifestEventTrackGroupInfos(eventStreams, trackGroups, trackGroupInfos, trackGroupCount);

  return Pair.create(new TrackGroupArray(trackGroups), trackGroupInfos);
}
 
Example #21
Source File: TrackSelection.java    From Telegram with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @param group The {@link TrackGroup}. Must not be null.
 * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
 * @param reason The track selection reason. One of the {@link C} SELECTION_REASON_ constants.
 * @param data Optional data associated with this selection of tracks.
 */
public Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data) {
  this.group = group;
  this.tracks = tracks;
  this.reason = reason;
  this.data = data;
}
 
Example #22
Source File: HlsChunkSource.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @param extractorFactory An {@link HlsExtractorFactory} from which to obtain the extractors for
 *     media chunks.
 * @param playlistTracker The {@link HlsPlaylistTracker} from which to obtain media playlists.
 * @param variants The available variants.
 * @param dataSourceFactory An {@link HlsDataSourceFactory} to create {@link DataSource}s for the
 *     chunks.
 * @param mediaTransferListener The transfer listener which should be informed of any media data
 *     transfers. May be null if no listener is available.
 * @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If multiple
 *     {@link HlsChunkSource}s are used for a single playback, they should all share the same
 *     provider.
 * @param muxedCaptionFormats List of muxed caption {@link Format}s. Null if no closed caption
 *     information is available in the master playlist.
 */
public HlsChunkSource(
    HlsExtractorFactory extractorFactory,
    HlsPlaylistTracker playlistTracker,
    HlsUrl[] variants,
    HlsDataSourceFactory dataSourceFactory,
    @Nullable TransferListener mediaTransferListener,
    TimestampAdjusterProvider timestampAdjusterProvider,
    List<Format> muxedCaptionFormats) {
  this.extractorFactory = extractorFactory;
  this.playlistTracker = playlistTracker;
  this.variants = variants;
  this.timestampAdjusterProvider = timestampAdjusterProvider;
  this.muxedCaptionFormats = muxedCaptionFormats;
  liveEdgeInPeriodTimeUs = C.TIME_UNSET;
  Format[] variantFormats = new Format[variants.length];
  int[] initialTrackSelection = new int[variants.length];
  for (int i = 0; i < variants.length; i++) {
    variantFormats[i] = variants[i].format;
    initialTrackSelection[i] = i;
  }
  mediaDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_MEDIA);
  if (mediaTransferListener != null) {
    mediaDataSource.addTransferListener(mediaTransferListener);
  }
  encryptionDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_DRM);
  trackGroup = new TrackGroup(variantFormats);
  trackSelection = new InitializationTrackSelection(trackGroup, initialTrackSelection);
}
 
Example #23
Source File: TrackSelection.java    From Telegram-FOSS with GNU General Public License v2.0 5 votes vote down vote up
/**
 * @param group The {@link TrackGroup}. Must not be null.
 * @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
 * @param reason The track selection reason. One of the {@link C} SELECTION_REASON_ constants.
 * @param data Optional data associated with this selection of tracks.
 */
public Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data) {
  this.group = group;
  this.tracks = tracks;
  this.reason = reason;
  this.data = data;
}
 
Example #24
Source File: DashMediaPeriod.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static void buildManifestEventTrackGroupInfos(List<EventStream> eventStreams,
    TrackGroup[] trackGroups, TrackGroupInfo[] trackGroupInfos, int existingTrackGroupCount) {
  for (int i = 0; i < eventStreams.size(); i++) {
    EventStream eventStream = eventStreams.get(i);
    Format format = Format.createSampleFormat(eventStream.id(), MimeTypes.APPLICATION_EMSG, null,
        Format.NO_VALUE, null);
    trackGroups[existingTrackGroupCount] = new TrackGroup(format);
    trackGroupInfos[existingTrackGroupCount++] = TrackGroupInfo.mpdEventTrack(i);
  }
}
 
Example #25
Source File: ReactExoplayerView.java    From react-native-video with MIT License 5 votes vote down vote up
private WritableArray getVideoTrackInfo() {
    WritableArray videoTracks = Arguments.createArray();

    MappingTrackSelector.MappedTrackInfo info = trackSelector.getCurrentMappedTrackInfo();
    int index = getTrackRendererIndex(C.TRACK_TYPE_VIDEO);
    if (info == null || index == C.INDEX_UNSET) {
        return videoTracks;
    }

    TrackGroupArray groups = info.getTrackGroups(index);
    for (int i = 0; i < groups.length; ++i) {
        TrackGroup group = groups.get(i);

        for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
            Format format = group.getFormat(trackIndex);
            WritableMap videoTrack = Arguments.createMap();
            videoTrack.putInt("width", format.width == Format.NO_VALUE ? 0 : format.width);
            videoTrack.putInt("height",format.height == Format.NO_VALUE ? 0 : format.height);
            videoTrack.putInt("bitrate", format.bitrate == Format.NO_VALUE ? 0 : format.bitrate);
            videoTrack.putString("codecs", format.codecs != null ? format.codecs : "");
            videoTrack.putString("trackId",
                    format.id == null ? String.valueOf(trackIndex) : format.id);
            videoTracks.pushMap(videoTrack);
        }
    }
    return videoTracks;
}
 
Example #26
Source File: DashMediaPeriod.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private static Pair<TrackGroupArray, TrackGroupInfo[]> buildTrackGroups(
    DrmSessionManager<?> drmSessionManager,
    List<AdaptationSet> adaptationSets,
    List<EventStream> eventStreams) {
  int[][] groupedAdaptationSetIndices = getGroupedAdaptationSetIndices(adaptationSets);

  int primaryGroupCount = groupedAdaptationSetIndices.length;
  boolean[] primaryGroupHasEventMessageTrackFlags = new boolean[primaryGroupCount];
  Format[][] primaryGroupCea608TrackFormats = new Format[primaryGroupCount][];
  int totalEmbeddedTrackGroupCount =
      identifyEmbeddedTracks(
          primaryGroupCount,
          adaptationSets,
          groupedAdaptationSetIndices,
          primaryGroupHasEventMessageTrackFlags,
          primaryGroupCea608TrackFormats);

  int totalGroupCount = primaryGroupCount + totalEmbeddedTrackGroupCount + eventStreams.size();
  TrackGroup[] trackGroups = new TrackGroup[totalGroupCount];
  TrackGroupInfo[] trackGroupInfos = new TrackGroupInfo[totalGroupCount];

  int trackGroupCount =
      buildPrimaryAndEmbeddedTrackGroupInfos(
          drmSessionManager,
          adaptationSets,
          groupedAdaptationSetIndices,
          primaryGroupCount,
          primaryGroupHasEventMessageTrackFlags,
          primaryGroupCea608TrackFormats,
          trackGroups,
          trackGroupInfos);

  buildManifestEventTrackGroupInfos(eventStreams, trackGroups, trackGroupInfos, trackGroupCount);

  return Pair.create(new TrackGroupArray(trackGroups), trackGroupInfos);
}
 
Example #27
Source File: DefaultTrackSelector.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
 * {@link TrackSelection} for a renderer whose type is neither video, audio or text.
 *
 * @param trackType The type of the renderer.
 * @param groups The {@link TrackGroupArray} mapped to the renderer.
 * @param formatSupport The result of {@link RendererCapabilities#supportsFormat} for each mapped
 *     track, indexed by track group index and track index (in that order).
 * @param params The selector's current constraint parameters.
 * @return The {@link TrackSelection} for the renderer, or null if no selection was made.
 * @throws ExoPlaybackException If an error occurs while selecting the tracks.
 */
protected @Nullable TrackSelection selectOtherTrack(
    int trackType, TrackGroupArray groups, int[][] formatSupport, Parameters params)
    throws ExoPlaybackException {
  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],
          params.exceedRendererCapabilitiesIfNecessary)) {
        Format format = trackGroup.getFormat(trackIndex);
        boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
        int trackScore = isDefault ? 2 : 1;
        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);
}
 
Example #28
Source File: SsMediaPeriod.java    From K-Sonic with MIT License 5 votes vote down vote up
private static TrackGroupArray buildTrackGroups(SsManifest manifest) {
  TrackGroup[] trackGroups = new TrackGroup[manifest.streamElements.length];
  for (int i = 0; i < manifest.streamElements.length; i++) {
    trackGroups[i] = new TrackGroup(manifest.streamElements[i].formats);
  }
  return new TrackGroupArray(trackGroups);
}
 
Example #29
Source File: DefaultTrackSelector.java    From K-Sonic with MIT License 5 votes vote down vote up
private static int[] getAdaptiveTracksForGroup(TrackGroup group, int[] formatSupport,
    boolean allowMixedMimeTypes, int requiredAdaptiveSupport, int maxVideoWidth,
    int maxVideoHeight, int maxVideoBitrate, int viewportWidth, int viewportHeight,
    boolean orientationMayChange) {
  if (group.length < 2) {
    return NO_TRACKS;
  }

  List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(group, viewportWidth,
      viewportHeight, orientationMayChange);
  if (selectedTrackIndices.size() < 2) {
    return NO_TRACKS;
  }

  String selectedMimeType = null;
  if (!allowMixedMimeTypes) {
    // Select the mime type for which we have the most adaptive tracks.
    HashSet<String> seenMimeTypes = new HashSet<>();
    int selectedMimeTypeTrackCount = 0;
    for (int i = 0; i < selectedTrackIndices.size(); i++) {
      int trackIndex = selectedTrackIndices.get(i);
      String sampleMimeType = group.getFormat(trackIndex).sampleMimeType;
      if (seenMimeTypes.add(sampleMimeType)) {
        int countForMimeType = getAdaptiveTrackCountForMimeType(group, formatSupport,
            requiredAdaptiveSupport, sampleMimeType, maxVideoWidth, maxVideoHeight,
            maxVideoBitrate, selectedTrackIndices);
        if (countForMimeType > selectedMimeTypeTrackCount) {
          selectedMimeType = sampleMimeType;
          selectedMimeTypeTrackCount = countForMimeType;
        }
      }
    }
  }

  // Filter by the selected mime type.
  filterAdaptiveTrackCountForMimeType(group, formatSupport, requiredAdaptiveSupport,
      selectedMimeType, maxVideoWidth, maxVideoHeight, maxVideoBitrate, selectedTrackIndices);

  return selectedTrackIndices.size() < 2 ? NO_TRACKS : Util.toArray(selectedTrackIndices);
}
 
Example #30
Source File: DefaultTrackSelector.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static int getAdaptiveAudioTrackCount(TrackGroup group, int[] formatSupport,
    AudioConfigurationTuple configuration) {
  int count = 0;
  for (int i = 0; i < group.length; i++) {
    if (isSupportedAdaptiveAudioTrack(group.getFormat(i), formatSupport[i], configuration)) {
      count++;
    }
  }
  return count;
}