Migrate SmoothStreaming to Format.Builder
Bitrates in SmoothStreaming manifests are average bitrates, as per the ref'd issue. Issue: #5978 PiperOrigin-RevId: 296467667
This commit is contained in:
parent
bc8fd2ca12
commit
d6650e6514
@ -288,7 +288,8 @@ public final class CodecSpecificDataUtil {
|
||||
* @return The individual NAL units, or null if the input did not consist of NAL start code
|
||||
* delimited units.
|
||||
*/
|
||||
public static @Nullable byte[][] splitNalUnits(byte[] data) {
|
||||
@Nullable
|
||||
public static byte[][] splitNalUnits(byte[] data) {
|
||||
if (!isNalStartCode(data, 0)) {
|
||||
// data does not consist of NAL start code delimited units.
|
||||
return null;
|
||||
|
@ -663,96 +663,65 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
||||
|
||||
@Override
|
||||
public void parseStartTag(XmlPullParser parser) throws ParserException {
|
||||
int type = (Integer) getNormalizedAttribute(KEY_TYPE);
|
||||
String id = parser.getAttributeValue(null, KEY_INDEX);
|
||||
String name = (String) getNormalizedAttribute(KEY_NAME);
|
||||
int bitrate = parseRequiredInt(parser, KEY_BITRATE);
|
||||
String sampleMimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
|
||||
Format.Builder formatBuilder = new Format.Builder();
|
||||
|
||||
@Nullable String sampleMimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
|
||||
int type = (Integer) getNormalizedAttribute(KEY_TYPE);
|
||||
if (type == C.TRACK_TYPE_VIDEO) {
|
||||
int width = parseRequiredInt(parser, KEY_MAX_WIDTH);
|
||||
int height = parseRequiredInt(parser, KEY_MAX_HEIGHT);
|
||||
List<byte[]> codecSpecificData = buildCodecSpecificData(
|
||||
parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA));
|
||||
format =
|
||||
Format.createVideoContainerFormat(
|
||||
id,
|
||||
name,
|
||||
MimeTypes.VIDEO_MP4,
|
||||
sampleMimeType,
|
||||
/* codecs= */ null,
|
||||
/* metadata= */ null,
|
||||
bitrate,
|
||||
width,
|
||||
height,
|
||||
/* frameRate= */ Format.NO_VALUE,
|
||||
codecSpecificData,
|
||||
/* selectionFlags= */ 0,
|
||||
/* roleFlags= */ 0);
|
||||
formatBuilder
|
||||
.setContainerMimeType(MimeTypes.VIDEO_MP4)
|
||||
.setWidth(parseRequiredInt(parser, KEY_MAX_WIDTH))
|
||||
.setHeight(parseRequiredInt(parser, KEY_MAX_HEIGHT))
|
||||
.setInitializationData(codecSpecificData);
|
||||
} else if (type == C.TRACK_TYPE_AUDIO) {
|
||||
sampleMimeType = sampleMimeType == null ? MimeTypes.AUDIO_AAC : sampleMimeType;
|
||||
int channels = parseRequiredInt(parser, KEY_CHANNELS);
|
||||
int samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
|
||||
if (sampleMimeType == null) {
|
||||
// If we don't know the MIME type, assume AAC.
|
||||
sampleMimeType = MimeTypes.AUDIO_AAC;
|
||||
}
|
||||
int channelCount = parseRequiredInt(parser, KEY_CHANNELS);
|
||||
int sampleRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
|
||||
List<byte[]> codecSpecificData = buildCodecSpecificData(
|
||||
parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA));
|
||||
if (codecSpecificData.isEmpty() && MimeTypes.AUDIO_AAC.equals(sampleMimeType)) {
|
||||
codecSpecificData = Collections.singletonList(
|
||||
CodecSpecificDataUtil.buildAacLcAudioSpecificConfig(samplingRate, channels));
|
||||
codecSpecificData =
|
||||
Collections.singletonList(
|
||||
CodecSpecificDataUtil.buildAacLcAudioSpecificConfig(sampleRate, channelCount));
|
||||
}
|
||||
String language = (String) getNormalizedAttribute(KEY_LANGUAGE);
|
||||
format =
|
||||
Format.createAudioContainerFormat(
|
||||
id,
|
||||
name,
|
||||
MimeTypes.AUDIO_MP4,
|
||||
sampleMimeType,
|
||||
/* codecs= */ null,
|
||||
/* metadata= */ null,
|
||||
bitrate,
|
||||
channels,
|
||||
samplingRate,
|
||||
codecSpecificData,
|
||||
/* selectionFlags= */ 0,
|
||||
/* roleFlags= */ 0,
|
||||
language);
|
||||
formatBuilder
|
||||
.setContainerMimeType(MimeTypes.AUDIO_MP4)
|
||||
.setChannelCount(channelCount)
|
||||
.setSampleRate(sampleRate)
|
||||
.setInitializationData(codecSpecificData);
|
||||
} else if (type == C.TRACK_TYPE_TEXT) {
|
||||
String subType = (String) getNormalizedAttribute(KEY_SUB_TYPE);
|
||||
@C.RoleFlags int roleFlags = 0;
|
||||
switch (subType) {
|
||||
case "CAPT":
|
||||
roleFlags = C.ROLE_FLAG_CAPTION;
|
||||
break;
|
||||
case "DESC":
|
||||
roleFlags = C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@Nullable String subType = (String) getNormalizedAttribute(KEY_SUB_TYPE);
|
||||
if (subType != null) {
|
||||
switch (subType) {
|
||||
case "CAPT":
|
||||
roleFlags = C.ROLE_FLAG_CAPTION;
|
||||
break;
|
||||
case "DESC":
|
||||
roleFlags = C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
String language = (String) getNormalizedAttribute(KEY_LANGUAGE);
|
||||
format =
|
||||
Format.createTextContainerFormat(
|
||||
id,
|
||||
name,
|
||||
MimeTypes.APPLICATION_MP4,
|
||||
sampleMimeType,
|
||||
/* codecs= */ null,
|
||||
bitrate,
|
||||
/* selectionFlags= */ 0,
|
||||
roleFlags,
|
||||
language);
|
||||
formatBuilder.setContainerMimeType(MimeTypes.APPLICATION_MP4).setRoleFlags(roleFlags);
|
||||
} else {
|
||||
format =
|
||||
Format.createContainerFormat(
|
||||
id,
|
||||
name,
|
||||
MimeTypes.APPLICATION_MP4,
|
||||
sampleMimeType,
|
||||
/* codecs= */ null,
|
||||
bitrate,
|
||||
/* selectionFlags= */ 0,
|
||||
/* roleFlags= */ 0,
|
||||
/* language= */ null);
|
||||
formatBuilder.setContainerMimeType(MimeTypes.APPLICATION_MP4);
|
||||
}
|
||||
|
||||
format =
|
||||
formatBuilder
|
||||
.setId(parser.getAttributeValue(null, KEY_INDEX))
|
||||
.setLabel((String) getNormalizedAttribute(KEY_NAME))
|
||||
.setSampleMimeType(sampleMimeType)
|
||||
.setAverageBitrate(parseRequiredInt(parser, KEY_BITRATE))
|
||||
.setLanguage((String) getNormalizedAttribute(KEY_LANGUAGE))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -764,7 +733,7 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
||||
ArrayList<byte[]> csd = new ArrayList<>();
|
||||
if (!TextUtils.isEmpty(codecSpecificDataString)) {
|
||||
byte[] codecPrivateData = Util.getBytesFromHexString(codecSpecificDataString);
|
||||
byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
|
||||
@Nullable byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
|
||||
if (split == null) {
|
||||
csd.add(codecPrivateData);
|
||||
} else {
|
||||
@ -774,6 +743,7 @@ public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
|
||||
return csd;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String fourCCToMimeType(String fourCC) {
|
||||
if (fourCC.equalsIgnoreCase("H264") || fourCC.equalsIgnoreCase("X264")
|
||||
|| fourCC.equalsIgnoreCase("AVC1") || fourCC.equalsIgnoreCase("DAVC")) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user