Migrate DASH to Format.Builder

Bitrates in the DASH manifest are peak bitrates, as per the ref'd issue.

Issue: #5978
PiperOrigin-RevId: 296478812
This commit is contained in:
olly 2020-02-21 19:41:31 +00:00 committed by Oliver Woodman
parent d6650e6514
commit f342df2047
6 changed files with 88 additions and 141 deletions

View File

@ -642,7 +642,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
cea608TrackGroupIndex); cea608TrackGroupIndex);
if (eventMessageTrackGroupIndex != C.INDEX_UNSET) { if (eventMessageTrackGroupIndex != C.INDEX_UNSET) {
Format format = Format format =
Format.createSampleFormat(firstAdaptationSet.id + ":emsg", MimeTypes.APPLICATION_EMSG); new Format.Builder()
.setId(firstAdaptationSet.id + ":emsg")
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
.build();
trackGroups[eventMessageTrackGroupIndex] = new TrackGroup(format); trackGroups[eventMessageTrackGroupIndex] = new TrackGroup(format);
trackGroupInfos[eventMessageTrackGroupIndex] = trackGroupInfos[eventMessageTrackGroupIndex] =
TrackGroupInfo.embeddedEmsgTrack(adaptationSetIndices, primaryTrackGroupIndex); TrackGroupInfo.embeddedEmsgTrack(adaptationSetIndices, primaryTrackGroupIndex);
@ -660,7 +663,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
TrackGroup[] trackGroups, TrackGroupInfo[] trackGroupInfos, int existingTrackGroupCount) { TrackGroup[] trackGroups, TrackGroupInfo[] trackGroupInfos, int existingTrackGroupCount) {
for (int i = 0; i < eventStreams.size(); i++) { for (int i = 0; i < eventStreams.size(); i++) {
EventStream eventStream = eventStreams.get(i); EventStream eventStream = eventStreams.get(i);
Format format = Format.createSampleFormat(eventStream.id(), MimeTypes.APPLICATION_EMSG); Format format =
new Format.Builder()
.setId(eventStream.id())
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
.build();
trackGroups[existingTrackGroupCount] = new TrackGroup(format); trackGroups[existingTrackGroupCount] = new TrackGroup(format);
trackGroupInfos[existingTrackGroupCount++] = TrackGroupInfo.mpdEventTrack(i); trackGroupInfos[existingTrackGroupCount++] = TrackGroupInfo.mpdEventTrack(i);
} }
@ -804,16 +811,16 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
private static Format buildCea608TrackFormat( private static Format buildCea608TrackFormat(
int adaptationSetId, @Nullable String language, int accessibilityChannel) { int adaptationSetId, @Nullable String language, int accessibilityChannel) {
return Format.createTextSampleFormat( String id =
adaptationSetId adaptationSetId
+ ":cea608" + ":cea608"
+ (accessibilityChannel != Format.NO_VALUE ? ":" + accessibilityChannel : ""), + (accessibilityChannel != Format.NO_VALUE ? ":" + accessibilityChannel : "");
MimeTypes.APPLICATION_CEA608, return new Format.Builder()
/* selectionFlags= */ 0, .setId(id)
language, .setSampleMimeType(MimeTypes.APPLICATION_CEA608)
accessibilityChannel, .setLanguage(language)
Format.OFFSET_SAMPLE_RELATIVE, .setAccessibilityChannel(accessibilityChannel)
/* initializationData= */ null); .build();
} }
// We won't assign the array to a variable that erases the generic type, and then write into it. // We won't assign the array to a variable that erases the generic type, and then write into it.

View File

@ -589,76 +589,40 @@ public class DashManifestParser extends DefaultHandler
List<Descriptor> accessibilityDescriptors, List<Descriptor> accessibilityDescriptors,
@Nullable String codecs, @Nullable String codecs,
List<Descriptor> supplementalProperties) { List<Descriptor> supplementalProperties) {
String sampleMimeType = getSampleMimeType(containerMimeType, codecs); @Nullable String sampleMimeType = getSampleMimeType(containerMimeType, codecs);
if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) {
sampleMimeType = parseEac3SupplementalProperties(supplementalProperties);
}
@C.SelectionFlags int selectionFlags = parseSelectionFlagsFromRoleDescriptors(roleDescriptors); @C.SelectionFlags int selectionFlags = parseSelectionFlagsFromRoleDescriptors(roleDescriptors);
@C.RoleFlags int roleFlags = parseRoleFlagsFromRoleDescriptors(roleDescriptors); @C.RoleFlags int roleFlags = parseRoleFlagsFromRoleDescriptors(roleDescriptors);
roleFlags |= parseRoleFlagsFromAccessibilityDescriptors(accessibilityDescriptors); roleFlags |= parseRoleFlagsFromAccessibilityDescriptors(accessibilityDescriptors);
if (sampleMimeType != null) {
if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) { Format.Builder formatBuilder =
sampleMimeType = parseEac3SupplementalProperties(supplementalProperties); new Format.Builder()
} .setId(id)
if (MimeTypes.isVideo(sampleMimeType)) { .setContainerMimeType(containerMimeType)
return Format.createVideoContainerFormat( .setSampleMimeType(sampleMimeType)
id, .setCodecs(codecs)
/* label= */ null, .setPeakBitrate(bitrate)
containerMimeType, .setSelectionFlags(selectionFlags)
sampleMimeType, .setRoleFlags(roleFlags)
codecs, .setLanguage(language);
/* metadata= */ null,
bitrate, if (MimeTypes.isVideo(sampleMimeType)) {
width, formatBuilder.setWidth(width).setHeight(height).setFrameRate(frameRate);
height, } else if (MimeTypes.isAudio(sampleMimeType)) {
frameRate, formatBuilder.setChannelCount(audioChannels).setSampleRate(audioSamplingRate);
/* initializationData= */ null, } else if (mimeTypeIsRawText(sampleMimeType)) {
selectionFlags, int accessibilityChannel = Format.NO_VALUE;
roleFlags); if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) {
} else if (MimeTypes.isAudio(sampleMimeType)) { accessibilityChannel = parseCea608AccessibilityChannel(accessibilityDescriptors);
return Format.createAudioContainerFormat( } else if (MimeTypes.APPLICATION_CEA708.equals(sampleMimeType)) {
id, accessibilityChannel = parseCea708AccessibilityChannel(accessibilityDescriptors);
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
/* metadata= */ null,
bitrate,
audioChannels,
audioSamplingRate,
/* initializationData= */ null,
selectionFlags,
roleFlags,
language);
} else if (mimeTypeIsRawText(sampleMimeType)) {
int accessibilityChannel;
if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) {
accessibilityChannel = parseCea608AccessibilityChannel(accessibilityDescriptors);
} else if (MimeTypes.APPLICATION_CEA708.equals(sampleMimeType)) {
accessibilityChannel = parseCea708AccessibilityChannel(accessibilityDescriptors);
} else {
accessibilityChannel = Format.NO_VALUE;
}
return Format.createTextContainerFormat(
id,
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
bitrate,
selectionFlags,
roleFlags,
language,
accessibilityChannel);
} }
formatBuilder.setAccessibilityChannel(accessibilityChannel);
} }
return Format.createContainerFormat(
id, return formatBuilder.build();
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
bitrate,
selectionFlags,
roleFlags,
language);
} }
protected Representation buildRepresentation( protected Representation buildRepresentation(
@ -667,24 +631,25 @@ public class DashManifestParser extends DefaultHandler
@Nullable String extraDrmSchemeType, @Nullable String extraDrmSchemeType,
ArrayList<SchemeData> extraDrmSchemeDatas, ArrayList<SchemeData> extraDrmSchemeDatas,
ArrayList<Descriptor> extraInbandEventStreams) { ArrayList<Descriptor> extraInbandEventStreams) {
Format format = representationInfo.format; Format.Builder formatBuilder = representationInfo.format.buildUpon();
if (label != null) { if (label != null) {
format = format.copyWithLabel(label); formatBuilder.setLabel(label);
}
@Nullable String drmSchemeType = representationInfo.drmSchemeType;
if (drmSchemeType == null) {
drmSchemeType = extraDrmSchemeType;
} }
String drmSchemeType = representationInfo.drmSchemeType != null
? representationInfo.drmSchemeType : extraDrmSchemeType;
ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas; ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
drmSchemeDatas.addAll(extraDrmSchemeDatas); drmSchemeDatas.addAll(extraDrmSchemeDatas);
if (!drmSchemeDatas.isEmpty()) { if (!drmSchemeDatas.isEmpty()) {
filterRedundantIncompleteSchemeDatas(drmSchemeDatas); filterRedundantIncompleteSchemeDatas(drmSchemeDatas);
DrmInitData drmInitData = new DrmInitData(drmSchemeType, drmSchemeDatas); formatBuilder.setDrmInitData(new DrmInitData(drmSchemeType, drmSchemeDatas));
format = format.copyWithDrmInitData(drmInitData);
} }
ArrayList<Descriptor> inbandEventStreams = representationInfo.inbandEventStreams; ArrayList<Descriptor> inbandEventStreams = representationInfo.inbandEventStreams;
inbandEventStreams.addAll(extraInbandEventStreams); inbandEventStreams.addAll(extraInbandEventStreams);
return Representation.newInstance( return Representation.newInstance(
representationInfo.revisionId, representationInfo.revisionId,
format, formatBuilder.build(),
representationInfo.baseUrl, representationInfo.baseUrl,
representationInfo.segmentBase, representationInfo.segmentBase,
inbandEventStreams); inbandEventStreams);
@ -709,7 +674,7 @@ public class DashManifestParser extends DefaultHandler
indexLength = Long.parseLong(indexRange[1]) - indexStart + 1; indexLength = Long.parseLong(indexRange[1]) - indexStart + 1;
} }
RangedUri initialization = parent != null ? parent.initialization : null; @Nullable RangedUri initialization = parent != null ? parent.initialization : null;
do { do {
xpp.next(); xpp.next();
if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) { if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) {

View File

@ -186,50 +186,33 @@ public final class DashMediaPeriodTest {
} }
private static Format createVideoFormat(int bitrate) { private static Format createVideoFormat(int bitrate) {
return Format.createContainerFormat( return new Format.Builder()
/* id= */ null, .setContainerMimeType(MimeTypes.VIDEO_MP4)
/* label= */ null, .setSampleMimeType(MimeTypes.VIDEO_H264)
MimeTypes.VIDEO_MP4, .setPeakBitrate(bitrate)
MimeTypes.VIDEO_H264, .build();
/* codecs= */ null,
bitrate,
/* selectionFlags= */ 0,
/* roleFlags= */ 0,
/* language= */ null);
} }
private static Representation createAudioRepresentation(int bitrate) { private static Representation createAudioRepresentation(int bitrate) {
Format format =
new Format.Builder()
.setContainerMimeType(MimeTypes.AUDIO_MP4)
.setSampleMimeType(MimeTypes.AUDIO_AAC)
.setPeakBitrate(bitrate)
.build();
return Representation.newInstance( return Representation.newInstance(
/* revisionId= */ 0, /* revisionId= */ 0, format, /* baseUrl= */ "", new SingleSegmentBase());
Format.createContainerFormat(
/* id= */ null,
/* label= */ null,
MimeTypes.AUDIO_MP4,
MimeTypes.AUDIO_AAC,
/* codecs= */ null,
bitrate,
/* selectionFlags= */ 0,
/* roleFlags= */ 0,
/* language= */ null),
/* baseUrl= */ "",
new SingleSegmentBase());
} }
private static Representation createTextRepresentation(String language) { private static Representation createTextRepresentation(String language) {
Format format =
new Format.Builder()
.setContainerMimeType(MimeTypes.APPLICATION_MP4)
.setSampleMimeType(MimeTypes.TEXT_VTT)
.setLanguage(language)
.build();
return Representation.newInstance( return Representation.newInstance(
/* revisionId= */ 0, /* revisionId= */ 0, format, /* baseUrl= */ "", new SingleSegmentBase());
Format.createContainerFormat(
/* id= */ null,
/* label= */ null,
MimeTypes.APPLICATION_MP4,
MimeTypes.TEXT_VTT,
/* codecs= */ null,
/* bitrate= */ Format.NO_VALUE,
/* selectionFlags= */ 0,
/* roleFlags= */ 0,
language),
/* baseUrl= */ "",
new SingleSegmentBase());
} }
private static Descriptor createSwitchDescriptor(int... ids) { private static Descriptor createSwitchDescriptor(int... ids) {

View File

@ -38,21 +38,21 @@ public final class DashUtilTest {
@Test @Test
public void testLoadDrmInitDataFromManifest() throws Exception { public void testLoadDrmInitDataFromManifest() throws Exception {
Period period = newPeriod(newAdaptationSets(newRepresentations(newDrmInitData()))); Period period = newPeriod(newAdaptationSet(newRepresentation(newDrmInitData())));
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period); DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
assertThat(drmInitData).isEqualTo(newDrmInitData()); assertThat(drmInitData).isEqualTo(newDrmInitData());
} }
@Test @Test
public void testLoadDrmInitDataMissing() throws Exception { public void testLoadDrmInitDataMissing() throws Exception {
Period period = newPeriod(newAdaptationSets(newRepresentations(null /* no init data */))); Period period = newPeriod(newAdaptationSet(newRepresentation(null /* no init data */)));
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period); DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
assertThat(drmInitData).isNull(); assertThat(drmInitData).isNull();
} }
@Test @Test
public void testLoadDrmInitDataNoRepresentations() throws Exception { public void testLoadDrmInitDataNoRepresentations() throws Exception {
Period period = newPeriod(newAdaptationSets(/* no representation */ )); Period period = newPeriod(newAdaptationSet(/* no representation */ ));
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period); DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
assertThat(drmInitData).isNull(); assertThat(drmInitData).isNull();
} }
@ -68,26 +68,16 @@ public final class DashUtilTest {
return new Period("", 0, Arrays.asList(adaptationSets)); return new Period("", 0, Arrays.asList(adaptationSets));
} }
private static AdaptationSet newAdaptationSets(Representation... representations) { private static AdaptationSet newAdaptationSet(Representation... representations) {
return new AdaptationSet(0, C.TRACK_TYPE_VIDEO, Arrays.asList(representations), null, null); return new AdaptationSet(0, C.TRACK_TYPE_VIDEO, Arrays.asList(representations), null, null);
} }
private static Representation newRepresentations(DrmInitData drmInitData) { private static Representation newRepresentation(DrmInitData drmInitData) {
Format format = Format format =
Format.createVideoContainerFormat( new Format.Builder()
"id", .setContainerMimeType(MimeTypes.VIDEO_MP4)
"label", .setSampleMimeType(MimeTypes.VIDEO_H264)
MimeTypes.VIDEO_MP4, .build();
MimeTypes.VIDEO_H264,
/* codecs= */ "",
/* metadata= */ null,
Format.NO_VALUE,
/* width= */ 1024,
/* height= */ 768,
Format.NO_VALUE,
/* initializationData= */ null,
/* selectionFlags= */ 0,
/* roleFlags= */ 0);
if (drmInitData != null) { if (drmInitData != null) {
format = format.copyWithDrmInitData(drmInitData); format = format.copyWithDrmInitData(drmInitData);
} }

View File

@ -38,7 +38,10 @@ public final class EventSampleStreamTest {
private static final String SCHEME_ID = "urn:test"; private static final String SCHEME_ID = "urn:test";
private static final String VALUE = "123"; private static final String VALUE = "123";
private static final Format FORMAT = private static final Format FORMAT =
Format.createSampleFormat("urn:test/123", MimeTypes.APPLICATION_EMSG); new Format.Builder()
.setId("urn:test/123")
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
.build();
private static final byte[] MESSAGE_DATA = new byte[] {1, 2, 3, 4}; private static final byte[] MESSAGE_DATA = new byte[] {1, 2, 3, 4};
private static final long DURATION_MS = 3000; private static final long DURATION_MS = 3000;
private static final long TIME_SCALE = 1000; private static final long TIME_SCALE = 1000;

View File

@ -35,8 +35,7 @@ public class DashManifestTest {
private static final UtcTimingElement DUMMY_UTC_TIMING = new UtcTimingElement("", ""); private static final UtcTimingElement DUMMY_UTC_TIMING = new UtcTimingElement("", "");
private static final SingleSegmentBase DUMMY_SEGMENT_BASE = new SingleSegmentBase(); private static final SingleSegmentBase DUMMY_SEGMENT_BASE = new SingleSegmentBase();
private static final Format DUMMY_FORMAT = private static final Format DUMMY_FORMAT = new Format.Builder().build();
Format.createSampleFormat(/* id= */ "", /* sampleMimeType= */ "");
@Test @Test
public void testCopy() { public void testCopy() {