diff --git a/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java b/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java index 2847dda685..cf86be8c46 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/util/MimeTypes.java @@ -17,6 +17,7 @@ package com.google.android.exoplayer2.util; import android.text.TextUtils; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.audio.AacUtil; import java.util.ArrayList; @@ -28,19 +29,6 @@ import java.util.regex.Pattern; */ public final class MimeTypes { - /** An mp4a Object Type Indication (OTI) and its optional audio OTI is defined by RFC 6381. */ - public static final class Mp4aObjectType { - /** The Object Type Indication of the mp4a codec. */ - public final int objectTypeIndication; - /** The Audio Object Type Indication of the mp4a codec, or 0 if it is absent. */ - @AacUtil.AacAudioObjectType public final int audioObjectTypeIndication; - - private Mp4aObjectType(int objectTypeIndication, int audioObjectTypeIndication) { - this.objectTypeIndication = objectTypeIndication; - this.audioObjectTypeIndication = audioObjectTypeIndication; - } - } - public static final String BASE_TYPE_VIDEO = "video"; public static final String BASE_TYPE_AUDIO = "audio"; public static final String BASE_TYPE_TEXT = "text"; @@ -135,7 +123,7 @@ public final class MimeTypes { * via this method. If this method is used, it must be called before creating any player(s). * * @param mimeType The custom MIME type to register. - * @param codecPrefix The RFC 6381-style codec string prefix associated with the MIME type. + * @param codecPrefix The RFC 6381 codec string prefix associated with the MIME type. * @param trackType The {@link C}{@code .TRACK_TYPE_*} constant associated with the MIME type. * This value is ignored if the top-level type of {@code mimeType} is audio, video or text. */ @@ -181,13 +169,13 @@ public final class MimeTypes { } /** - * Returns true if it is known that all samples in a stream of the given sample MIME type are - * guaranteed to be sync samples (i.e., {@link C#BUFFER_FLAG_KEY_FRAME} is guaranteed to be set on - * every sample). + * Returns true if it is known that all samples in a stream of the given MIME type are guaranteed + * to be sync samples (i.e., {@link C#BUFFER_FLAG_KEY_FRAME} is guaranteed to be set on every + * sample). * - * @param mimeType The sample MIME type. - * @return True if it is known that all samples in a stream of the given sample MIME type are - * guaranteed to be sync samples. False otherwise, including if {@code null} is passed. + * @param mimeType A MIME type. + * @return True if it is known that all samples in a stream of the given MIME type are guaranteed + * to be sync samples. False otherwise, including if {@code null} is passed. */ public static boolean allSamplesAreSyncSamples(@Nullable String mimeType) { if (mimeType == null) { @@ -216,10 +204,10 @@ public final class MimeTypes { } /** - * Derives a video sample mimeType from a codecs attribute. + * Returns the first video MIME type derived from an RFC 6381 codecs string. * - * @param codecs The codecs attribute. - * @return The derived video mimeType, or null if it could not be derived. + * @param codecs An RFC 6381 codecs string. + * @return The first derived video MIME type, or {@code null}. */ @Nullable public static String getVideoMediaMimeType(@Nullable String codecs) { @@ -237,10 +225,10 @@ public final class MimeTypes { } /** - * Derives a audio sample mimeType from a codecs attribute. + * Returns the first audio MIME type derived from an RFC 6381 codecs string. * - * @param codecs The codecs attribute. - * @return The derived audio mimeType, or null if it could not be derived. + * @param codecs An RFC 6381 codecs string. + * @return The first derived audio MIME type, or {@code null}. */ @Nullable public static String getAudioMediaMimeType(@Nullable String codecs) { @@ -258,10 +246,10 @@ public final class MimeTypes { } /** - * Derives a text sample mimeType from a codecs attribute. + * Returns the first text MIME type derived from an RFC 6381 codecs string. * - * @param codecs The codecs attribute. - * @return The derived text mimeType, or null if it could not be derived. + * @param codecs An RFC 6381 codecs string. + * @return The first derived text MIME type, or {@code null}. */ @Nullable public static String getTextMediaMimeType(@Nullable String codecs) { @@ -279,10 +267,11 @@ public final class MimeTypes { } /** - * Derives a mimeType from a codec identifier, as defined in RFC 6381. + * Returns the MIME type corresponding to an RFC 6381 codec string, or {@code null} if it could + * not be determined. * - * @param codec The codec identifier to derive. - * @return The mimeType, or null if it could not be derived. + * @param codec An RFC 6381 codec string. + * @return The corresponding MIME type, or {@code null} if it could not be determined. */ @Nullable public static String getMediaMimeType(@Nullable String codec) { @@ -346,11 +335,11 @@ public final class MimeTypes { } /** - * Derives a mimeType from MP4 object type identifier, as defined in RFC 6381 and - * https://mp4ra.org/#/object_types. + * Returns the MIME type corresponding to an MP4 object type identifier, as defined in RFC 6381 + * and https://mp4ra.org/#/object_types. * - * @param objectType The objectType identifier to derive. - * @return The mimeType, or null if it could not be derived. + * @param objectType An MP4 object type identifier. + * @return The corresponding MIME type, or {@code null} if it could not be determined. */ @Nullable public static String getMimeTypeFromMp4ObjectType(int objectType) { @@ -402,12 +391,12 @@ public final class MimeTypes { } /** - * Returns the {@link C}{@code .TRACK_TYPE_*} constant that corresponds to a specified MIME type. - * {@link C#TRACK_TYPE_UNKNOWN} if the MIME type is not known or the mapping cannot be - * established. + * Returns the {@link C}{@code .TRACK_TYPE_*} constant corresponding to a specified MIME type, or + * {@link C#TRACK_TYPE_UNKNOWN} if it could not be determined. * - * @param mimeType The MIME type. - * @return The {@link C}{@code .TRACK_TYPE_*} constant that corresponds to a specified MIME type. + * @param mimeType A MIME type. + * @return The corresponding {@link C}{@code .TRACK_TYPE_*}, or {@link C#TRACK_TYPE_UNKNOWN} if it + * could not be determined. */ public static int getTrackType(@Nullable String mimeType) { if (TextUtils.isEmpty(mimeType)) { @@ -430,25 +419,24 @@ public final class MimeTypes { } /** - * Returns the {@link C}{@code .ENCODING_*} constant that corresponds to specified MIME type, if - * it is an encoded (non-PCM) audio format, or {@link C#ENCODING_INVALID} otherwise. + * Returns the {@link C.Encoding} constant corresponding to the specified audio MIME type and RFC + * 6381 codec string, or {@link C#ENCODING_INVALID} if the corresponding {@link C.Encoding} cannot + * be determined. * - * @param mimeType The MIME type. - * @param codecs Codecs of the format as described in RFC 6381, or null if unknown or not - * applicable. - * @return One of {@link C.Encoding} constants that corresponds to a specified MIME type, or - * {@link C#ENCODING_INVALID}. + * @param mimeType A MIME type. + * @param codec An RFC 6381 codec string, or {@code null} if unknown or not applicable. + * @return The corresponding {@link C.Encoding}, or {@link C#ENCODING_INVALID}. */ @C.Encoding - public static int getEncoding(String mimeType, @Nullable String codecs) { + public static int getEncoding(String mimeType, @Nullable String codec) { switch (mimeType) { case MimeTypes.AUDIO_MPEG: return C.ENCODING_MP3; case MimeTypes.AUDIO_AAC: - if (codecs == null) { + if (codec == null) { return C.ENCODING_INVALID; } - @Nullable Mp4aObjectType objectType = getObjectTypeFromMp4aRFC6381CodecString(codecs); + @Nullable Mp4aObjectType objectType = getObjectTypeFromMp4aRFC6381CodecString(codec); if (objectType == null) { return C.ENCODING_INVALID; } @@ -475,57 +463,19 @@ public final class MimeTypes { /** * Equivalent to {@code getTrackType(getMediaMimeType(codec))}. * - * @param codec The codec. - * @return The {@link C}{@code .TRACK_TYPE_*} constant that corresponds to a specified codec. + * @param codec An RFC 6381 codec string. + * @return The corresponding {@link C}{@code .TRACK_TYPE_*}, or {@link C#TRACK_TYPE_UNKNOWN} if it + * could not be determined. */ public static int getTrackTypeOfCodec(String codec) { return getTrackType(getMediaMimeType(codec)); } - /** - * Retrieves the object type of an mp4 audio codec from its string as defined in RFC 6381. - * - *
Per https://mp4ra.org/#/object_types and https://tools.ietf.org/html/rfc6381#section-3.3, an - * mp4 codec string has the form: - * - *
- * ~~~~~~~~~~~~~~ Object Type Indication (OTI) byte in hex
- * mp4a.[a-zA-Z0-9]{2}(.[0-9]{1,2})?
- * ~~~~~~~~~~ audio OTI, decimal. Only for certain OTI.
- *
- *
- * For example: mp4a.40.2, has an OTI of 0x40 and an audio OTI of 2.
- *
- * @param codec The string as defined in RFC 6381 describing an mp4 audio codec.
- * @return The {@link Mp4aObjectType} or {@code null} if the input is invalid.
- */
- @Nullable
- public static Mp4aObjectType getObjectTypeFromMp4aRFC6381CodecString(String codec) {
- Matcher matcher = MP4A_RFC_6381_CODEC_PATTERN.matcher(codec);
- if (!matcher.matches()) {
- return null;
- }
- String objectTypeIndicationHex = Assertions.checkNotNull(matcher.group(1));
- @Nullable String audioObjectTypeIndicationDec = matcher.group(2);
- int objectTypeIndication;
- int audioObjectTypeIndication = 0;
- try {
- objectTypeIndication = Integer.parseInt(objectTypeIndicationHex, 16);
- if (audioObjectTypeIndicationDec != null) {
- audioObjectTypeIndication = Integer.parseInt(audioObjectTypeIndicationDec);
- }
- } catch (NumberFormatException e) {
- return null;
- }
- return new Mp4aObjectType(objectTypeIndication, audioObjectTypeIndication);
- }
-
/**
* Normalizes the MIME type provided so that equivalent MIME types are uniquely represented.
*
- * @param mimeType The MIME type to normalize. The MIME type provided is returned if its
- * normalized form is unknown.
- * @return The normalized MIME type.
+ * @param mimeType A MIME type to normalize.
+ * @return The normalized MIME type, or the argument MIME type if its normalized form is unknown.
*/
public static String normalizeMimeType(String mimeType) {
switch (mimeType) {
@@ -596,6 +546,59 @@ public final class MimeTypes {
// Prevent instantiation.
}
+ /**
+ * Returns the {@link Mp4aObjectType} of an RFC 6381 MP4 audio codec string.
+ *
+ * Per https://mp4ra.org/#/object_types and https://tools.ietf.org/html/rfc6381#section-3.3, an + * MP4 codec string has the form: + * + *
+ * ~~~~~~~~~~~~~~ Object Type Indication (OTI) byte in hex
+ * mp4a.[a-zA-Z0-9]{2}(.[0-9]{1,2})?
+ * ~~~~~~~~~~ audio OTI, decimal. Only for certain OTI.
+ *
+ *
+ * For example, mp4a.40.2 has an OTI of 0x40 and an audio OTI of 2.
+ *
+ * @param codec An RFC 6381 MP4 audio codec string.
+ * @return The {@link Mp4aObjectType}, or {@code null} if the input was invalid.
+ */
+ @VisibleForTesting
+ @Nullable
+ /* package */ static Mp4aObjectType getObjectTypeFromMp4aRFC6381CodecString(String codec) {
+ Matcher matcher = MP4A_RFC_6381_CODEC_PATTERN.matcher(codec);
+ if (!matcher.matches()) {
+ return null;
+ }
+ String objectTypeIndicationHex = Assertions.checkNotNull(matcher.group(1));
+ @Nullable String audioObjectTypeIndicationDec = matcher.group(2);
+ int objectTypeIndication;
+ int audioObjectTypeIndication = 0;
+ try {
+ objectTypeIndication = Integer.parseInt(objectTypeIndicationHex, 16);
+ if (audioObjectTypeIndicationDec != null) {
+ audioObjectTypeIndication = Integer.parseInt(audioObjectTypeIndicationDec);
+ }
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ return new Mp4aObjectType(objectTypeIndication, audioObjectTypeIndication);
+ }
+
+ /** An MP4A Object Type Indication (OTI) and its optional audio OTI is defined by RFC 6381. */
+ @VisibleForTesting
+ /* package */ static final class Mp4aObjectType {
+ /** The Object Type Indication of the MP4A codec. */
+ public final int objectTypeIndication;
+ /** The Audio Object Type Indication of the MP4A codec, or 0 if it is absent. */
+ @AacUtil.AacAudioObjectType public final int audioObjectTypeIndication;
+
+ public Mp4aObjectType(int objectTypeIndication, int audioObjectTypeIndication) {
+ this.objectTypeIndication = objectTypeIndication;
+ this.audioObjectTypeIndication = audioObjectTypeIndication;
+ }
+ }
+
private static final class CustomMimeType {
public final String mimeType;
public final String codecPrefix;