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);
if (eventMessageTrackGroupIndex != C.INDEX_UNSET) {
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);
trackGroupInfos[eventMessageTrackGroupIndex] =
TrackGroupInfo.embeddedEmsgTrack(adaptationSetIndices, primaryTrackGroupIndex);
@ -660,7 +663,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
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);
Format format =
new Format.Builder()
.setId(eventStream.id())
.setSampleMimeType(MimeTypes.APPLICATION_EMSG)
.build();
trackGroups[existingTrackGroupCount] = new TrackGroup(format);
trackGroupInfos[existingTrackGroupCount++] = TrackGroupInfo.mpdEventTrack(i);
}
@ -804,16 +811,16 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
private static Format buildCea608TrackFormat(
int adaptationSetId, @Nullable String language, int accessibilityChannel) {
return Format.createTextSampleFormat(
String id =
adaptationSetId
+ ":cea608"
+ (accessibilityChannel != Format.NO_VALUE ? ":" + accessibilityChannel : ""),
MimeTypes.APPLICATION_CEA608,
/* selectionFlags= */ 0,
language,
accessibilityChannel,
Format.OFFSET_SAMPLE_RELATIVE,
/* initializationData= */ null);
+ (accessibilityChannel != Format.NO_VALUE ? ":" + accessibilityChannel : "");
return new Format.Builder()
.setId(id)
.setSampleMimeType(MimeTypes.APPLICATION_CEA608)
.setLanguage(language)
.setAccessibilityChannel(accessibilityChannel)
.build();
}
// 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,
@Nullable String codecs,
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.RoleFlags int roleFlags = parseRoleFlagsFromRoleDescriptors(roleDescriptors);
roleFlags |= parseRoleFlagsFromAccessibilityDescriptors(accessibilityDescriptors);
if (sampleMimeType != null) {
if (MimeTypes.AUDIO_E_AC3.equals(sampleMimeType)) {
sampleMimeType = parseEac3SupplementalProperties(supplementalProperties);
}
if (MimeTypes.isVideo(sampleMimeType)) {
return Format.createVideoContainerFormat(
id,
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
/* metadata= */ null,
bitrate,
width,
height,
frameRate,
/* initializationData= */ null,
selectionFlags,
roleFlags);
} else if (MimeTypes.isAudio(sampleMimeType)) {
return Format.createAudioContainerFormat(
id,
/* 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);
Format.Builder formatBuilder =
new Format.Builder()
.setId(id)
.setContainerMimeType(containerMimeType)
.setSampleMimeType(sampleMimeType)
.setCodecs(codecs)
.setPeakBitrate(bitrate)
.setSelectionFlags(selectionFlags)
.setRoleFlags(roleFlags)
.setLanguage(language);
if (MimeTypes.isVideo(sampleMimeType)) {
formatBuilder.setWidth(width).setHeight(height).setFrameRate(frameRate);
} else if (MimeTypes.isAudio(sampleMimeType)) {
formatBuilder.setChannelCount(audioChannels).setSampleRate(audioSamplingRate);
} else if (mimeTypeIsRawText(sampleMimeType)) {
int accessibilityChannel = Format.NO_VALUE;
if (MimeTypes.APPLICATION_CEA608.equals(sampleMimeType)) {
accessibilityChannel = parseCea608AccessibilityChannel(accessibilityDescriptors);
} else if (MimeTypes.APPLICATION_CEA708.equals(sampleMimeType)) {
accessibilityChannel = parseCea708AccessibilityChannel(accessibilityDescriptors);
}
formatBuilder.setAccessibilityChannel(accessibilityChannel);
}
return Format.createContainerFormat(
id,
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
bitrate,
selectionFlags,
roleFlags,
language);
return formatBuilder.build();
}
protected Representation buildRepresentation(
@ -667,24 +631,25 @@ public class DashManifestParser extends DefaultHandler
@Nullable String extraDrmSchemeType,
ArrayList<SchemeData> extraDrmSchemeDatas,
ArrayList<Descriptor> extraInbandEventStreams) {
Format format = representationInfo.format;
Format.Builder formatBuilder = representationInfo.format.buildUpon();
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;
drmSchemeDatas.addAll(extraDrmSchemeDatas);
if (!drmSchemeDatas.isEmpty()) {
filterRedundantIncompleteSchemeDatas(drmSchemeDatas);
DrmInitData drmInitData = new DrmInitData(drmSchemeType, drmSchemeDatas);
format = format.copyWithDrmInitData(drmInitData);
formatBuilder.setDrmInitData(new DrmInitData(drmSchemeType, drmSchemeDatas));
}
ArrayList<Descriptor> inbandEventStreams = representationInfo.inbandEventStreams;
inbandEventStreams.addAll(extraInbandEventStreams);
return Representation.newInstance(
representationInfo.revisionId,
format,
formatBuilder.build(),
representationInfo.baseUrl,
representationInfo.segmentBase,
inbandEventStreams);
@ -709,7 +674,7 @@ public class DashManifestParser extends DefaultHandler
indexLength = Long.parseLong(indexRange[1]) - indexStart + 1;
}
RangedUri initialization = parent != null ? parent.initialization : null;
@Nullable RangedUri initialization = parent != null ? parent.initialization : null;
do {
xpp.next();
if (XmlPullParserUtil.isStartTag(xpp, "Initialization")) {

View File

@ -186,50 +186,33 @@ public final class DashMediaPeriodTest {
}
private static Format createVideoFormat(int bitrate) {
return Format.createContainerFormat(
/* id= */ null,
/* label= */ null,
MimeTypes.VIDEO_MP4,
MimeTypes.VIDEO_H264,
/* codecs= */ null,
bitrate,
/* selectionFlags= */ 0,
/* roleFlags= */ 0,
/* language= */ null);
return new Format.Builder()
.setContainerMimeType(MimeTypes.VIDEO_MP4)
.setSampleMimeType(MimeTypes.VIDEO_H264)
.setPeakBitrate(bitrate)
.build();
}
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(
/* revisionId= */ 0,
Format.createContainerFormat(
/* id= */ null,
/* label= */ null,
MimeTypes.AUDIO_MP4,
MimeTypes.AUDIO_AAC,
/* codecs= */ null,
bitrate,
/* selectionFlags= */ 0,
/* roleFlags= */ 0,
/* language= */ null),
/* baseUrl= */ "",
new SingleSegmentBase());
/* revisionId= */ 0, format, /* baseUrl= */ "", new SingleSegmentBase());
}
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(
/* revisionId= */ 0,
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());
/* revisionId= */ 0, format, /* baseUrl= */ "", new SingleSegmentBase());
}
private static Descriptor createSwitchDescriptor(int... ids) {

View File

@ -38,21 +38,21 @@ public final class DashUtilTest {
@Test
public void testLoadDrmInitDataFromManifest() throws Exception {
Period period = newPeriod(newAdaptationSets(newRepresentations(newDrmInitData())));
Period period = newPeriod(newAdaptationSet(newRepresentation(newDrmInitData())));
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
assertThat(drmInitData).isEqualTo(newDrmInitData());
}
@Test
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);
assertThat(drmInitData).isNull();
}
@Test
public void testLoadDrmInitDataNoRepresentations() throws Exception {
Period period = newPeriod(newAdaptationSets(/* no representation */ ));
Period period = newPeriod(newAdaptationSet(/* no representation */ ));
DrmInitData drmInitData = DashUtil.loadDrmInitData(DummyDataSource.INSTANCE, period);
assertThat(drmInitData).isNull();
}
@ -68,26 +68,16 @@ public final class DashUtilTest {
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);
}
private static Representation newRepresentations(DrmInitData drmInitData) {
private static Representation newRepresentation(DrmInitData drmInitData) {
Format format =
Format.createVideoContainerFormat(
"id",
"label",
MimeTypes.VIDEO_MP4,
MimeTypes.VIDEO_H264,
/* codecs= */ "",
/* metadata= */ null,
Format.NO_VALUE,
/* width= */ 1024,
/* height= */ 768,
Format.NO_VALUE,
/* initializationData= */ null,
/* selectionFlags= */ 0,
/* roleFlags= */ 0);
new Format.Builder()
.setContainerMimeType(MimeTypes.VIDEO_MP4)
.setSampleMimeType(MimeTypes.VIDEO_H264)
.build();
if (drmInitData != null) {
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 VALUE = "123";
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 long DURATION_MS = 3000;
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 SingleSegmentBase DUMMY_SEGMENT_BASE = new SingleSegmentBase();
private static final Format DUMMY_FORMAT =
Format.createSampleFormat(/* id= */ "", /* sampleMimeType= */ "");
private static final Format DUMMY_FORMAT = new Format.Builder().build();
@Test
public void testCopy() {