627 lines
25 KiB
Java
627 lines
25 KiB
Java
/*
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package android.media;
|
|
|
|
import android.annotation.NonNull;
|
|
import android.content.ContentResolver;
|
|
import android.net.Uri;
|
|
import android.os.Build;
|
|
import android.os.Bundle;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.util.Log;
|
|
|
|
import com.android.modules.annotation.MinSdk;
|
|
|
|
import org.xmlpull.v1.XmlPullParser;
|
|
import org.xmlpull.v1.XmlPullParserException;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
ApplicationMediaCapabilities is an immutable class that encapsulates an application's capabilities
|
|
for handling newer video codec format and media features.
|
|
|
|
<p>
|
|
Android 12 introduces Compatible media transcoding feature. See
|
|
<a href="https://developer.android.com/about/versions/12/features#compatible_media_transcoding">
|
|
Compatible media transcoding</a>. By default, Android assumes apps can support playback of all
|
|
media formats. Apps that would like to request that media be transcoded into a more compatible
|
|
format should declare their media capabilities in a media_capabilities.xml resource file and add it
|
|
as a property tag in the AndroidManifest.xml file. Here is a example:
|
|
<pre>
|
|
{@code
|
|
<media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
|
|
<format android:name="HEVC" supported="true"/>
|
|
<format android:name="HDR10" supported="false"/>
|
|
<format android:name="HDR10Plus" supported="false"/>
|
|
</media-capabilities>
|
|
}
|
|
</pre>
|
|
The ApplicationMediaCapabilities class is generated from this xml and used by the platform to
|
|
represent an application's media capabilities in order to determine whether modern media files need
|
|
to be transcoded for that application.
|
|
</p>
|
|
|
|
<p>
|
|
ApplicationMediaCapabilities objects can also be built by applications at runtime for use with
|
|
{@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)} to provide more
|
|
control over the transcoding that is built into the platform. ApplicationMediaCapabilities
|
|
provided by applications at runtime like this override the default manifest capabilities for that
|
|
media access.The object could be build either through {@link #createFromXml(XmlPullParser)} or
|
|
through the builder class {@link ApplicationMediaCapabilities.Builder}
|
|
|
|
<h3> Video Codec Support</h3>
|
|
<p>
|
|
Newer video codes include HEVC, VP9 and AV1. Application only needs to indicate their support
|
|
for newer format with this class as they are assumed to support older format like h.264.
|
|
|
|
<h3>Capability of handling HDR(high dynamic range) video</h3>
|
|
<p>
|
|
There are four types of HDR video(Dolby-Vision, HDR10, HDR10+, HLG) supported by the platform,
|
|
application will only need to specify individual types they supported.
|
|
*/
|
|
@MinSdk(Build.VERSION_CODES.S)
|
|
public final class ApplicationMediaCapabilities implements Parcelable {
|
|
private static final String TAG = "ApplicationMediaCapabilities";
|
|
|
|
/** List of supported video codec mime types. */
|
|
private Set<String> mSupportedVideoMimeTypes = new HashSet<>();
|
|
|
|
/** List of unsupported video codec mime types. */
|
|
private Set<String> mUnsupportedVideoMimeTypes = new HashSet<>();
|
|
|
|
/** List of supported hdr types. */
|
|
private Set<String> mSupportedHdrTypes = new HashSet<>();
|
|
|
|
/** List of unsupported hdr types. */
|
|
private Set<String> mUnsupportedHdrTypes = new HashSet<>();
|
|
|
|
private boolean mIsSlowMotionSupported = false;
|
|
|
|
private ApplicationMediaCapabilities(Builder b) {
|
|
mSupportedVideoMimeTypes.addAll(b.getSupportedVideoMimeTypes());
|
|
mUnsupportedVideoMimeTypes.addAll(b.getUnsupportedVideoMimeTypes());
|
|
mSupportedHdrTypes.addAll(b.getSupportedHdrTypes());
|
|
mUnsupportedHdrTypes.addAll(b.getUnsupportedHdrTypes());
|
|
mIsSlowMotionSupported = b.mIsSlowMotionSupported;
|
|
}
|
|
|
|
/**
|
|
* Query if a video codec format is supported by the application.
|
|
* <p>
|
|
* If the application has not specified supporting the format or not, this will return false.
|
|
* Use {@link #isFormatSpecified(String)} to query if a format is specified or not.
|
|
*
|
|
* @param videoMime The mime type of the video codec format. Must be the one used in
|
|
* {@link MediaFormat#KEY_MIME}.
|
|
* @return true if application supports the video codec format, false otherwise.
|
|
*/
|
|
public boolean isVideoMimeTypeSupported(
|
|
@NonNull String videoMime) {
|
|
if (mSupportedVideoMimeTypes.contains(videoMime.toLowerCase())) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Query if a HDR type is supported by the application.
|
|
* <p>
|
|
* If the application has not specified supporting the format or not, this will return false.
|
|
* Use {@link #isFormatSpecified(String)} to query if a format is specified or not.
|
|
*
|
|
* @param hdrType The type of the HDR format.
|
|
* @return true if application supports the HDR format, false otherwise.
|
|
*/
|
|
public boolean isHdrTypeSupported(
|
|
@NonNull @MediaFeature.MediaHdrType String hdrType) {
|
|
if (mSupportedHdrTypes.contains(hdrType)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Query if a format is specified by the application.
|
|
* <p>
|
|
* The format could be either the video format or the hdr format.
|
|
*
|
|
* @param format The name of the format.
|
|
* @return true if application specifies the format, false otherwise.
|
|
*/
|
|
public boolean isFormatSpecified(@NonNull String format) {
|
|
if (mSupportedVideoMimeTypes.contains(format) || mUnsupportedVideoMimeTypes.contains(format)
|
|
|| mSupportedHdrTypes.contains(format) || mUnsupportedHdrTypes.contains(format)) {
|
|
return true;
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
// Write out the supported video mime types.
|
|
dest.writeInt(mSupportedVideoMimeTypes.size());
|
|
for (String cap : mSupportedVideoMimeTypes) {
|
|
dest.writeString(cap);
|
|
}
|
|
// Write out the unsupported video mime types.
|
|
dest.writeInt(mUnsupportedVideoMimeTypes.size());
|
|
for (String cap : mUnsupportedVideoMimeTypes) {
|
|
dest.writeString(cap);
|
|
}
|
|
// Write out the supported hdr types.
|
|
dest.writeInt(mSupportedHdrTypes.size());
|
|
for (String cap : mSupportedHdrTypes) {
|
|
dest.writeString(cap);
|
|
}
|
|
// Write out the unsupported hdr types.
|
|
dest.writeInt(mUnsupportedHdrTypes.size());
|
|
for (String cap : mUnsupportedHdrTypes) {
|
|
dest.writeString(cap);
|
|
}
|
|
// Write out the supported slow motion.
|
|
dest.writeBoolean(mIsSlowMotionSupported);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
String caps = new String(
|
|
"Supported Video MimeTypes: " + mSupportedVideoMimeTypes.toString());
|
|
caps += "Unsupported Video MimeTypes: " + mUnsupportedVideoMimeTypes.toString();
|
|
caps += "Supported HDR types: " + mSupportedHdrTypes.toString();
|
|
caps += "Unsupported HDR types: " + mUnsupportedHdrTypes.toString();
|
|
caps += "Supported slow motion: " + mIsSlowMotionSupported;
|
|
return caps;
|
|
}
|
|
|
|
@NonNull
|
|
public static final Creator<ApplicationMediaCapabilities> CREATOR =
|
|
new Creator<ApplicationMediaCapabilities>() {
|
|
public ApplicationMediaCapabilities createFromParcel(Parcel in) {
|
|
ApplicationMediaCapabilities.Builder builder =
|
|
new ApplicationMediaCapabilities.Builder();
|
|
|
|
// Parse supported video codec mime types.
|
|
int count = in.readInt();
|
|
for (int readCount = 0; readCount < count; ++readCount) {
|
|
builder.addSupportedVideoMimeType(in.readString());
|
|
}
|
|
|
|
// Parse unsupported video codec mime types.
|
|
count = in.readInt();
|
|
for (int readCount = 0; readCount < count; ++readCount) {
|
|
builder.addUnsupportedVideoMimeType(in.readString());
|
|
}
|
|
|
|
// Parse supported hdr types.
|
|
count = in.readInt();
|
|
for (int readCount = 0; readCount < count; ++readCount) {
|
|
builder.addSupportedHdrType(in.readString());
|
|
}
|
|
|
|
// Parse unsupported hdr types.
|
|
count = in.readInt();
|
|
for (int readCount = 0; readCount < count; ++readCount) {
|
|
builder.addUnsupportedHdrType(in.readString());
|
|
}
|
|
|
|
boolean supported = in.readBoolean();
|
|
builder.setSlowMotionSupported(supported);
|
|
|
|
return builder.build();
|
|
}
|
|
|
|
public ApplicationMediaCapabilities[] newArray(int size) {
|
|
return new ApplicationMediaCapabilities[size];
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Query the video codec mime types supported by the application.
|
|
* @return List of supported video codec mime types. The list will be empty if there are none.
|
|
*/
|
|
@NonNull
|
|
public List<String> getSupportedVideoMimeTypes() {
|
|
return new ArrayList<>(mSupportedVideoMimeTypes);
|
|
}
|
|
|
|
/**
|
|
* Query the video codec mime types that are not supported by the application.
|
|
* @return List of unsupported video codec mime types. The list will be empty if there are none.
|
|
*/
|
|
@NonNull
|
|
public List<String> getUnsupportedVideoMimeTypes() {
|
|
return new ArrayList<>(mUnsupportedVideoMimeTypes);
|
|
}
|
|
|
|
/**
|
|
* Query all hdr types that are supported by the application.
|
|
* @return List of supported hdr types. The list will be empty if there are none.
|
|
*/
|
|
@NonNull
|
|
public List<String> getSupportedHdrTypes() {
|
|
return new ArrayList<>(mSupportedHdrTypes);
|
|
}
|
|
|
|
/**
|
|
* Query all hdr types that are not supported by the application.
|
|
* @return List of unsupported hdr types. The list will be empty if there are none.
|
|
*/
|
|
@NonNull
|
|
public List<String> getUnsupportedHdrTypes() {
|
|
return new ArrayList<>(mUnsupportedHdrTypes);
|
|
}
|
|
|
|
/**
|
|
* Whether handling of slow-motion video is supported
|
|
* @hide
|
|
*/
|
|
public boolean isSlowMotionSupported() {
|
|
return mIsSlowMotionSupported;
|
|
}
|
|
|
|
/**
|
|
* Creates {@link ApplicationMediaCapabilities} from an xml.
|
|
*
|
|
* The xml's syntax is the same as the media_capabilities.xml used by the AndroidManifest.xml.
|
|
* <p> Here is an example:
|
|
*
|
|
* <pre>
|
|
* {@code
|
|
* <media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
|
|
* <format android:name="HEVC" supported="true"/>
|
|
* <format android:name="HDR10" supported="false"/>
|
|
* <format android:name="HDR10Plus" supported="false"/>
|
|
* </media-capabilities>
|
|
* }
|
|
* </pre>
|
|
* <p>
|
|
*
|
|
* @param xmlParser The underlying {@link XmlPullParser} that will read the xml.
|
|
* @return An ApplicationMediaCapabilities object.
|
|
* @throws UnsupportedOperationException if the capabilities in xml config are invalid or
|
|
* incompatible.
|
|
*/
|
|
// TODO: Add developer.android.com link for the format of the xml.
|
|
@NonNull
|
|
public static ApplicationMediaCapabilities createFromXml(@NonNull XmlPullParser xmlParser) {
|
|
ApplicationMediaCapabilities.Builder builder = new ApplicationMediaCapabilities.Builder();
|
|
builder.parseXml(xmlParser);
|
|
return builder.build();
|
|
}
|
|
|
|
/**
|
|
* Builder class for {@link ApplicationMediaCapabilities} objects.
|
|
* Use this class to configure and create an ApplicationMediaCapabilities instance. Builder
|
|
* could be created from an existing ApplicationMediaCapabilities object, from a xml file or
|
|
* MediaCodecList.
|
|
* //TODO(hkuang): Add xml parsing support to the builder.
|
|
*/
|
|
public final static class Builder {
|
|
/** List of supported video codec mime types. */
|
|
private Set<String> mSupportedVideoMimeTypes = new HashSet<>();
|
|
|
|
/** List of supported hdr types. */
|
|
private Set<String> mSupportedHdrTypes = new HashSet<>();
|
|
|
|
/** List of unsupported video codec mime types. */
|
|
private Set<String> mUnsupportedVideoMimeTypes = new HashSet<>();
|
|
|
|
/** List of unsupported hdr types. */
|
|
private Set<String> mUnsupportedHdrTypes = new HashSet<>();
|
|
|
|
private boolean mIsSlowMotionSupported = false;
|
|
|
|
/* Map to save the format read from the xml. */
|
|
private Map<String, Boolean> mFormatSupportedMap = new HashMap<String, Boolean>();
|
|
|
|
/**
|
|
* Constructs a new Builder with all the supports default to false.
|
|
*/
|
|
public Builder() {
|
|
}
|
|
|
|
private void parseXml(@NonNull XmlPullParser xmlParser)
|
|
throws UnsupportedOperationException {
|
|
if (xmlParser == null) {
|
|
throw new IllegalArgumentException("XmlParser must not be null");
|
|
}
|
|
|
|
try {
|
|
while (xmlParser.next() != XmlPullParser.START_TAG) {
|
|
continue;
|
|
}
|
|
|
|
// Validates the tag is "media-capabilities".
|
|
if (!xmlParser.getName().equals("media-capabilities")) {
|
|
throw new UnsupportedOperationException("Invalid tag");
|
|
}
|
|
|
|
xmlParser.next();
|
|
while (xmlParser.getEventType() != XmlPullParser.END_TAG) {
|
|
while (xmlParser.getEventType() != XmlPullParser.START_TAG) {
|
|
if (xmlParser.getEventType() == XmlPullParser.END_DOCUMENT) {
|
|
return;
|
|
}
|
|
xmlParser.next();
|
|
}
|
|
|
|
// Validates the tag is "format".
|
|
if (xmlParser.getName().equals("format")) {
|
|
parseFormatTag(xmlParser);
|
|
} else {
|
|
throw new UnsupportedOperationException("Invalid tag");
|
|
}
|
|
while (xmlParser.getEventType() != XmlPullParser.END_TAG) {
|
|
xmlParser.next();
|
|
}
|
|
xmlParser.next();
|
|
}
|
|
} catch (XmlPullParserException xppe) {
|
|
throw new UnsupportedOperationException("Ill-formatted xml file");
|
|
} catch (java.io.IOException ioe) {
|
|
throw new UnsupportedOperationException("Unable to read xml file");
|
|
}
|
|
}
|
|
|
|
private void parseFormatTag(XmlPullParser xmlParser) {
|
|
String name = null;
|
|
String supported = null;
|
|
for (int i = 0; i < xmlParser.getAttributeCount(); i++) {
|
|
String attrName = xmlParser.getAttributeName(i);
|
|
if (attrName.equals("name")) {
|
|
name = xmlParser.getAttributeValue(i);
|
|
} else if (attrName.equals("supported")) {
|
|
supported = xmlParser.getAttributeValue(i);
|
|
} else {
|
|
throw new UnsupportedOperationException("Invalid attribute name " + attrName);
|
|
}
|
|
}
|
|
|
|
if (name != null && supported != null) {
|
|
if (!supported.equals("true") && !supported.equals("false")) {
|
|
throw new UnsupportedOperationException(
|
|
("Supported value must be either true or false"));
|
|
}
|
|
boolean isSupported = Boolean.parseBoolean(supported);
|
|
|
|
// Check if the format is already found before.
|
|
if (mFormatSupportedMap.get(name) != null && mFormatSupportedMap.get(name)
|
|
!= isSupported) {
|
|
throw new UnsupportedOperationException(
|
|
"Format: " + name + " has conflict supported value");
|
|
}
|
|
|
|
switch (name) {
|
|
case "HEVC":
|
|
if (isSupported) {
|
|
mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
|
|
} else {
|
|
mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
|
|
}
|
|
break;
|
|
case "VP9":
|
|
if (isSupported) {
|
|
mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_VP9);
|
|
} else {
|
|
mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_VP9);
|
|
}
|
|
break;
|
|
case "AV1":
|
|
if (isSupported) {
|
|
mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_AV1);
|
|
} else {
|
|
mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_AV1);
|
|
}
|
|
break;
|
|
case "HDR10":
|
|
if (isSupported) {
|
|
mSupportedHdrTypes.add(MediaFeature.HdrType.HDR10);
|
|
} else {
|
|
mUnsupportedHdrTypes.add(MediaFeature.HdrType.HDR10);
|
|
}
|
|
break;
|
|
case "HDR10Plus":
|
|
if (isSupported) {
|
|
mSupportedHdrTypes.add(MediaFeature.HdrType.HDR10_PLUS);
|
|
} else {
|
|
mUnsupportedHdrTypes.add(MediaFeature.HdrType.HDR10_PLUS);
|
|
}
|
|
break;
|
|
case "Dolby-Vision":
|
|
if (isSupported) {
|
|
mSupportedHdrTypes.add(MediaFeature.HdrType.DOLBY_VISION);
|
|
} else {
|
|
mUnsupportedHdrTypes.add(MediaFeature.HdrType.DOLBY_VISION);
|
|
}
|
|
break;
|
|
case "HLG":
|
|
if (isSupported) {
|
|
mSupportedHdrTypes.add(MediaFeature.HdrType.HLG);
|
|
} else {
|
|
mUnsupportedHdrTypes.add(MediaFeature.HdrType.HLG);
|
|
}
|
|
break;
|
|
case "SlowMotion":
|
|
mIsSlowMotionSupported = isSupported;
|
|
break;
|
|
default:
|
|
Log.w(TAG, "Invalid format name " + name);
|
|
}
|
|
// Save the name and isSupported into the map for validate later.
|
|
mFormatSupportedMap.put(name, isSupported);
|
|
} else {
|
|
throw new UnsupportedOperationException(
|
|
"Format name and supported must both be specified");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Builds a {@link ApplicationMediaCapabilities} object.
|
|
*
|
|
* @return a new {@link ApplicationMediaCapabilities} instance successfully initialized
|
|
* with all the parameters set on this <code>Builder</code>.
|
|
* @throws UnsupportedOperationException if the parameters set on the
|
|
* <code>Builder</code> were incompatible, or if they
|
|
* are not supported by the
|
|
* device.
|
|
*/
|
|
@NonNull
|
|
public ApplicationMediaCapabilities build() {
|
|
Log.d(TAG,
|
|
"Building ApplicationMediaCapabilities with: (Supported HDR: "
|
|
+ mSupportedHdrTypes.toString() + " Unsupported HDR: "
|
|
+ mUnsupportedHdrTypes.toString() + ") (Supported Codec: "
|
|
+ " " + mSupportedVideoMimeTypes.toString() + " Unsupported Codec:"
|
|
+ mUnsupportedVideoMimeTypes.toString() + ") "
|
|
+ mIsSlowMotionSupported);
|
|
|
|
// If hdr is supported, application must also support hevc.
|
|
if (!mSupportedHdrTypes.isEmpty() && !mSupportedVideoMimeTypes.contains(
|
|
MediaFormat.MIMETYPE_VIDEO_HEVC)) {
|
|
throw new UnsupportedOperationException("Only support HEVC mime type");
|
|
}
|
|
return new ApplicationMediaCapabilities(this);
|
|
}
|
|
|
|
/**
|
|
* Adds a supported video codec mime type.
|
|
*
|
|
* @param codecMime Supported codec mime types. Must be one of the mime type defined
|
|
* in {@link MediaFormat}.
|
|
* @throws IllegalArgumentException if mime type is not valid.
|
|
*/
|
|
@NonNull
|
|
public Builder addSupportedVideoMimeType(
|
|
@NonNull String codecMime) {
|
|
mSupportedVideoMimeTypes.add(codecMime);
|
|
return this;
|
|
}
|
|
|
|
private List<String> getSupportedVideoMimeTypes() {
|
|
return new ArrayList<>(mSupportedVideoMimeTypes);
|
|
}
|
|
|
|
private boolean isValidVideoCodecMimeType(@NonNull String codecMime) {
|
|
if (!codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)
|
|
&& !codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)
|
|
&& !codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AV1)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Adds an unsupported video codec mime type.
|
|
*
|
|
* @param codecMime Unsupported codec mime type. Must be one of the mime type defined
|
|
* in {@link MediaFormat}.
|
|
* @throws IllegalArgumentException if mime type is not valid.
|
|
*/
|
|
@NonNull
|
|
public Builder addUnsupportedVideoMimeType(
|
|
@NonNull String codecMime) {
|
|
if (!isValidVideoCodecMimeType(codecMime)) {
|
|
throw new IllegalArgumentException("Invalid codec mime type: " + codecMime);
|
|
}
|
|
mUnsupportedVideoMimeTypes.add(codecMime);
|
|
return this;
|
|
}
|
|
|
|
private List<String> getUnsupportedVideoMimeTypes() {
|
|
return new ArrayList<>(mUnsupportedVideoMimeTypes);
|
|
}
|
|
|
|
/**
|
|
* Adds a supported hdr type.
|
|
*
|
|
* @param hdrType Supported hdr type. Must be one of the String defined in
|
|
* {@link MediaFeature.HdrType}.
|
|
* @throws IllegalArgumentException if hdrType is not valid.
|
|
*/
|
|
@NonNull
|
|
public Builder addSupportedHdrType(
|
|
@NonNull @MediaFeature.MediaHdrType String hdrType) {
|
|
if (!isValidVideoCodecHdrType(hdrType)) {
|
|
throw new IllegalArgumentException("Invalid hdr type: " + hdrType);
|
|
}
|
|
mSupportedHdrTypes.add(hdrType);
|
|
return this;
|
|
}
|
|
|
|
private List<String> getSupportedHdrTypes() {
|
|
return new ArrayList<>(mSupportedHdrTypes);
|
|
}
|
|
|
|
private boolean isValidVideoCodecHdrType(@NonNull String hdrType) {
|
|
if (!hdrType.equals(MediaFeature.HdrType.DOLBY_VISION)
|
|
&& !hdrType.equals(MediaFeature.HdrType.HDR10)
|
|
&& !hdrType.equals(MediaFeature.HdrType.HDR10_PLUS)
|
|
&& !hdrType.equals(MediaFeature.HdrType.HLG)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Adds an unsupported hdr type.
|
|
*
|
|
* @param hdrType Unsupported hdr type. Must be one of the String defined in
|
|
* {@link MediaFeature.HdrType}.
|
|
* @throws IllegalArgumentException if hdrType is not valid.
|
|
*/
|
|
@NonNull
|
|
public Builder addUnsupportedHdrType(
|
|
@NonNull @MediaFeature.MediaHdrType String hdrType) {
|
|
if (!isValidVideoCodecHdrType(hdrType)) {
|
|
throw new IllegalArgumentException("Invalid hdr type: " + hdrType);
|
|
}
|
|
mUnsupportedHdrTypes.add(hdrType);
|
|
return this;
|
|
}
|
|
|
|
private List<String> getUnsupportedHdrTypes() {
|
|
return new ArrayList<>(mUnsupportedHdrTypes);
|
|
}
|
|
|
|
/**
|
|
* Sets whether slow-motion video is supported.
|
|
* If an application indicates support for slow-motion, it is application's responsibility
|
|
* to parse the slow-motion videos using their own parser or using support library.
|
|
* @see android.media.MediaFormat#KEY_SLOW_MOTION_MARKERS
|
|
* @hide
|
|
*/
|
|
@NonNull
|
|
public Builder setSlowMotionSupported(boolean slowMotionSupported) {
|
|
mIsSlowMotionSupported = slowMotionSupported;
|
|
return this;
|
|
}
|
|
}
|
|
}
|