use of androidx.media3.exoplayer.dash.manifest.AdaptationSet in project media by androidx.
the class DashMediaPeriod method getGroupedAdaptationSetIndices.
/**
* Groups adaptation sets. Two adaptations sets belong to the same group if either:
*
* <ul>
* <li>One is a trick-play adaptation set and uses a {@code
* http://dashif.org/guidelines/trickmode} essential or supplemental property to indicate
* that the other is the main adaptation set to which it corresponds.
* <li>The two adaptation sets are marked as safe for switching using {@code
* urn:mpeg:dash:adaptation-set-switching:2016} supplemental properties.
* </ul>
*
* @param adaptationSets The adaptation sets to merge.
* @return An array of groups, where each group is an array of adaptation set indices.
*/
private static int[][] getGroupedAdaptationSetIndices(List<AdaptationSet> adaptationSets) {
int adaptationSetCount = adaptationSets.size();
SparseIntArray adaptationSetIdToIndex = new SparseIntArray(adaptationSetCount);
List<List<Integer>> adaptationSetGroupedIndices = new ArrayList<>(adaptationSetCount);
SparseArray<List<Integer>> adaptationSetIndexToGroupedIndices = new SparseArray<>(adaptationSetCount);
// adaptationSetIdToIndex map.
for (int i = 0; i < adaptationSetCount; i++) {
adaptationSetIdToIndex.put(adaptationSets.get(i).id, i);
List<Integer> initialGroup = new ArrayList<>();
initialGroup.add(i);
adaptationSetGroupedIndices.add(initialGroup);
adaptationSetIndexToGroupedIndices.put(i, initialGroup);
}
// Merge adaptation set groups.
for (int i = 0; i < adaptationSetCount; i++) {
int mergedGroupIndex = i;
AdaptationSet adaptationSet = adaptationSets.get(i);
// Trick-play adaptation sets are merged with their corresponding main adaptation sets.
@Nullable Descriptor trickPlayProperty = findTrickPlayProperty(adaptationSet.essentialProperties);
if (trickPlayProperty == null) {
// Trick-play can also be specified using a supplemental property.
trickPlayProperty = findTrickPlayProperty(adaptationSet.supplementalProperties);
}
if (trickPlayProperty != null) {
int mainAdaptationSetId = Integer.parseInt(trickPlayProperty.value);
int mainAdaptationSetIndex = adaptationSetIdToIndex.get(mainAdaptationSetId, /* valueIfKeyNotFound= */
-1);
if (mainAdaptationSetIndex != -1) {
mergedGroupIndex = mainAdaptationSetIndex;
}
}
// merged group.
if (mergedGroupIndex == i) {
@Nullable Descriptor adaptationSetSwitchingProperty = findAdaptationSetSwitchingProperty(adaptationSet.supplementalProperties);
if (adaptationSetSwitchingProperty != null) {
String[] otherAdaptationSetIds = Util.split(adaptationSetSwitchingProperty.value, ",");
for (String adaptationSetId : otherAdaptationSetIds) {
int otherAdaptationSetId = adaptationSetIdToIndex.get(Integer.parseInt(adaptationSetId), /* valueIfKeyNotFound= */
-1);
if (otherAdaptationSetId != -1) {
mergedGroupIndex = min(mergedGroupIndex, otherAdaptationSetId);
}
}
}
}
// Merge the groups if necessary.
if (mergedGroupIndex != i) {
List<Integer> thisGroup = adaptationSetIndexToGroupedIndices.get(i);
List<Integer> mergedGroup = adaptationSetIndexToGroupedIndices.get(mergedGroupIndex);
mergedGroup.addAll(thisGroup);
adaptationSetIndexToGroupedIndices.put(i, mergedGroup);
adaptationSetGroupedIndices.remove(thisGroup);
}
}
int[][] groupedAdaptationSetIndices = new int[adaptationSetGroupedIndices.size()][];
for (int i = 0; i < groupedAdaptationSetIndices.length; i++) {
groupedAdaptationSetIndices[i] = Ints.toArray(adaptationSetGroupedIndices.get(i));
// Restore the original adaptation set order within each group.
Arrays.sort(groupedAdaptationSetIndices[i]);
}
return groupedAdaptationSetIndices;
}
use of androidx.media3.exoplayer.dash.manifest.AdaptationSet in project media by androidx.
the class DashMediaPeriod method getClosedCaptionTrackFormats.
private static Format[] getClosedCaptionTrackFormats(List<AdaptationSet> adaptationSets, int[] adaptationSetIndices) {
for (int i : adaptationSetIndices) {
AdaptationSet adaptationSet = adaptationSets.get(i);
List<Descriptor> descriptors = adaptationSets.get(i).accessibilityDescriptors;
for (int j = 0; j < descriptors.size(); j++) {
Descriptor descriptor = descriptors.get(j);
if ("urn:scte:dash:cc:cea-608:2015".equals(descriptor.schemeIdUri)) {
Format cea608Format = new Format.Builder().setSampleMimeType(MimeTypes.APPLICATION_CEA608).setId(adaptationSet.id + ":cea608").build();
return parseClosedCaptionDescriptor(descriptor, CEA608_SERVICE_DESCRIPTOR_REGEX, cea608Format);
} else if ("urn:scte:dash:cc:cea-708:2015".equals(descriptor.schemeIdUri)) {
Format cea708Format = new Format.Builder().setSampleMimeType(MimeTypes.APPLICATION_CEA708).setId(adaptationSet.id + ":cea708").build();
return parseClosedCaptionDescriptor(descriptor, CEA708_SERVICE_DESCRIPTOR_REGEX, cea708Format);
}
}
}
return new Format[0];
}
use of androidx.media3.exoplayer.dash.manifest.AdaptationSet in project media by androidx.
the class DashMediaSource method getAvailableStartTimeInManifestUs.
private static long getAvailableStartTimeInManifestUs(Period period, long periodDurationUs, long nowUnixTimeUs) {
long periodStartTimeInManifestUs = Util.msToUs(period.startMs);
long availableStartTimeInManifestUs = periodStartTimeInManifestUs;
boolean haveAudioVideoAdaptationSets = hasVideoOrAudioAdaptationSets(period);
for (int i = 0; i < period.adaptationSets.size(); i++) {
AdaptationSet adaptationSet = period.adaptationSets.get(i);
List<Representation> representations = adaptationSet.representations;
// or video adaptation set. See: https://github.com/google/ExoPlayer/issues/4029
if ((haveAudioVideoAdaptationSets && adaptationSet.type == C.TRACK_TYPE_TEXT) || representations.isEmpty()) {
continue;
}
@Nullable DashSegmentIndex index = representations.get(0).getIndex();
if (index == null) {
return periodStartTimeInManifestUs;
}
long availableSegmentCount = index.getAvailableSegmentCount(periodDurationUs, nowUnixTimeUs);
if (availableSegmentCount == 0) {
return periodStartTimeInManifestUs;
}
long firstAvailableSegmentNum = index.getFirstAvailableSegmentNum(periodDurationUs, nowUnixTimeUs);
long adaptationSetAvailableStartTimeInManifestUs = periodStartTimeInManifestUs + index.getTimeUs(firstAvailableSegmentNum);
availableStartTimeInManifestUs = max(availableStartTimeInManifestUs, adaptationSetAvailableStartTimeInManifestUs);
}
return availableStartTimeInManifestUs;
}
use of androidx.media3.exoplayer.dash.manifest.AdaptationSet in project media by androidx.
the class DashMediaPeriodTest method trickPlayProperty_mergesTrackGroups.
@Test
public void trickPlayProperty_mergesTrackGroups() throws IOException {
DashManifest manifest = parseManifest("media/mpd/sample_mpd_trick_play_property");
DashMediaPeriod dashMediaPeriod = createDashMediaPeriod(manifest, 0);
List<AdaptationSet> adaptationSets = manifest.getPeriod(0).adaptationSets;
// We expect the trick play adaptation sets to be merged with the ones to which they refer,
// retaining representations in their original order.
TrackGroupArray expectedTrackGroups = new TrackGroupArray(new TrackGroup(/* id= */
"0", adaptationSets.get(0).representations.get(0).format, adaptationSets.get(0).representations.get(1).format, adaptationSets.get(1).representations.get(0).format), new TrackGroup(/* id= */
"2", adaptationSets.get(2).representations.get(0).format, adaptationSets.get(2).representations.get(1).format, adaptationSets.get(3).representations.get(0).format));
MediaPeriodAsserts.assertTrackGroups(dashMediaPeriod, expectedTrackGroups);
}
use of androidx.media3.exoplayer.dash.manifest.AdaptationSet in project media by androidx.
the class DashMediaPeriodTest method cea708AccessibilityDescriptor_createsCea708TrackGroup.
@Test
public void cea708AccessibilityDescriptor_createsCea708TrackGroup() throws IOException {
DashManifest manifest = parseManifest("media/mpd/sample_mpd_cea_708_accessibility");
DashMediaPeriod dashMediaPeriod = createDashMediaPeriod(manifest, 0);
List<AdaptationSet> adaptationSets = manifest.getPeriod(0).adaptationSets;
// We expect two adaptation sets. The first containing the video representations, and the second
// containing the embedded CEA-708 tracks.
Format.Builder cea608FormatBuilder = new Format.Builder().setSampleMimeType(MimeTypes.APPLICATION_CEA708);
TrackGroupArray expectedTrackGroups = new TrackGroupArray(new TrackGroup(/* id= */
"123", adaptationSets.get(0).representations.get(0).format, adaptationSets.get(0).representations.get(1).format), new TrackGroup(/* id= */
"123:cc", cea608FormatBuilder.setId("123:cea708:1").setLanguage("eng").setAccessibilityChannel(1).build(), cea608FormatBuilder.setId("123:cea708:2").setLanguage("deu").setAccessibilityChannel(2).build()));
MediaPeriodAsserts.assertTrackGroups(dashMediaPeriod, expectedTrackGroups);
}
Aggregations