transcoding: Unhide ApplicationMediaCapabilities

CTS-Coverage-Bug:172074159

Bug: 169849854
Test: Unit test
Change-Id: Ib043bf8e52c6868cd1dfeff5552755d394c4c851
This commit is contained in:
hkuang
2020-10-30 12:17:44 -07:00
parent e81f13321b
commit 10acecb23b
5 changed files with 307 additions and 60 deletions

View File

@@ -24184,6 +24184,25 @@ package android.location {
package android.media {
public final class ApplicationMediaCapabilities implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List<java.lang.String> getSupportedHdrTypes();
method @NonNull public java.util.List<java.lang.String> getSupportedVideoMimeTypes();
method public boolean isHdrTypeSupported(@NonNull String);
method public boolean isSlowMotionSupported();
method public boolean isVideoMimeTypeSupported(@NonNull String);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.media.ApplicationMediaCapabilities> CREATOR;
}
public static final class ApplicationMediaCapabilities.Builder {
ctor public ApplicationMediaCapabilities.Builder();
method @NonNull public android.media.ApplicationMediaCapabilities.Builder addSupportedHdrType(@NonNull String);
method @NonNull public android.media.ApplicationMediaCapabilities.Builder addSupportedVideoMimeType(@NonNull String);
method @NonNull public android.media.ApplicationMediaCapabilities build();
method @NonNull public android.media.ApplicationMediaCapabilities.Builder setSlowMotionSupported(boolean);
}
public class AsyncPlayer {
ctor public AsyncPlayer(String);
method @Deprecated public void play(android.content.Context, android.net.Uri, boolean, int);
@@ -26303,6 +26322,17 @@ package android.media {
field public static final String TRACKS = "android.media.mediaextractor.ntrk";
}
public final class MediaFeature {
ctor public MediaFeature();
}
public static final class MediaFeature.HdrType {
field public static final String DOLBY_VISION = "android.media.feature.hdr.dolby_vision";
field public static final String HDR10 = "android.media.feature.hdr.hdr10";
field public static final String HDR10_PLUS = "android.media.feature.hdr.hdr10_plus";
field public static final String HLG = "android.media.feature.hdr.hlg";
}
public final class MediaFormat {
ctor public MediaFormat();
ctor public MediaFormat(@NonNull android.media.MediaFormat);

View File

@@ -24166,6 +24166,25 @@ package android.location {
package android.media {
public final class ApplicationMediaCapabilities implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List<java.lang.String> getSupportedHdrTypes();
method @NonNull public java.util.List<java.lang.String> getSupportedVideoMimeTypes();
method public boolean isHdrTypeSupported(@NonNull String);
method public boolean isSlowMotionSupported();
method public boolean isVideoMimeTypeSupported(@NonNull String);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.media.ApplicationMediaCapabilities> CREATOR;
}
public static final class ApplicationMediaCapabilities.Builder {
ctor public ApplicationMediaCapabilities.Builder();
method @NonNull public android.media.ApplicationMediaCapabilities.Builder addSupportedHdrType(@NonNull String);
method @NonNull public android.media.ApplicationMediaCapabilities.Builder addSupportedVideoMimeType(@NonNull String);
method @NonNull public android.media.ApplicationMediaCapabilities build();
method @NonNull public android.media.ApplicationMediaCapabilities.Builder setSlowMotionSupported(boolean);
}
public class AsyncPlayer {
ctor public AsyncPlayer(String);
method @Deprecated public void play(android.content.Context, android.net.Uri, boolean, int);
@@ -26261,6 +26280,17 @@ package android.media {
field public static final String TRACKS = "android.media.mediaextractor.ntrk";
}
public final class MediaFeature {
ctor public MediaFeature();
}
public static final class MediaFeature.HdrType {
field public static final String DOLBY_VISION = "android.media.feature.hdr.dolby_vision";
field public static final String HDR10 = "android.media.feature.hdr.hdr10";
field public static final String HDR10_PLUS = "android.media.feature.hdr.hdr10_plus";
field public static final String HLG = "android.media.feature.hdr.hlg";
}
public final class MediaFormat {
ctor public MediaFormat();
ctor public MediaFormat(@NonNull android.media.MediaFormat);

View File

@@ -23,11 +23,16 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* ApplicationMediaCapabilities is an immutable class that encapsulates an application's
* capabilities of handling advanced media formats.
* capabilities for handling newer video codec format and media features.
*
* The ApplicationMediaCapabilities class is used by the platform to to represent an application's
* The ApplicationMediaCapabilities class is used by the platform to represent an application's
* media capabilities as defined in their manifest(TODO: Add link) in order to determine
* whether modern media files need to be transcoded for that application (TODO: Add link).
*
@@ -37,43 +42,55 @@ import android.os.Parcelable;
* provided by applications at runtime like this override the default manifest capabilities for that
* media access.
*
* TODO(huang): Correct openTypedAssetFileDescriptor with the new API after it is added.
* TODO(hkuang): Add a link to seamless transcoding detail when it is published
* TODO(hkuang): Add code sample on how to build a capability object with MediaCodecList
* <h3> Video Codec Support</h3>
* 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.
*
* @hide
* <h4>Capability of handling HDR(high dynamic range) video</h4>
* 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.
*
* <h4>Capability of handling Slow Motion video</h4>
* There is no standard format for slow motion yet. 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.
*/
// TODO(huang): Correct openTypedAssetFileDescriptor with the new API after it is added.
// TODO(hkuang): Add a link to seamless transcoding detail when it is published
// TODO(hkuang): Add code sample on how to build a capability object with MediaCodecList
// TODO(hkuang): Add the support library page on parsing slow motion video.
public final class ApplicationMediaCapabilities implements Parcelable {
private static final String TAG = "ApplicationMediaCapabilities";
/** Whether handling of HEVC video is supported. */
private final boolean mIsHevcSupported;
/** List of supported video codec mime types. */
// TODO: init it with avc and mpeg4 as application is assuming to support them.
private Set<String> mSupportedVideoMimeTypes = new HashSet<>();
/** Whether handling of slow-motion video is supported. */
private final boolean mIsSlowMotionSupported;
/** List of supported hdr types. */
private Set<String> mSupportedHdrTypes = new HashSet<>();
/** Whether handling of high dynamic range video is supported. */
private final boolean mIsHdrSupported;
private boolean mIsSlowMotionSupported = false;
private ApplicationMediaCapabilities(Builder b) {
mIsHevcSupported = b.mIsHevcSupported;
mIsHdrSupported = b.mIsHdrSupported;
mSupportedVideoMimeTypes.addAll(b.getSupportedVideoMimeTypes());
mSupportedHdrTypes.addAll(b.getSupportedHdrTypes());
mIsSlowMotionSupported = b.mIsSlowMotionSupported;
}
/** Whether handling of HEVC video is supported. */
public boolean isHevcSupported() {
return mIsHevcSupported;
/**
* Query if an video codec is supported by the application.
*/
public boolean isVideoMimeTypeSupported(
@NonNull String videoMime) {
return mSupportedVideoMimeTypes.contains(videoMime);
}
/** Whether handling of slow-motion video is supported. */
public boolean isSlowMotionSupported() {
return mIsSlowMotionSupported;
}
/** Whether handling of high dynamic range video is supported. */
public boolean isHdrSupported() {
return mIsHdrSupported;
/**
* Query if a hdr type is supported by the application.
*/
public boolean isHdrTypeSupported(
@NonNull @MediaFeature.MediaHdrType String hdrType) {
return mSupportedHdrTypes.contains(hdrType);
}
@Override
@@ -82,12 +99,86 @@ public final class ApplicationMediaCapabilities implements Parcelable {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeBoolean(mIsHevcSupported);
dest.writeBoolean(mIsHdrSupported);
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 supported hdr types.
dest.writeInt(mSupportedHdrTypes.size());
for (String cap : mSupportedHdrTypes) {
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 += "Supported HDR types: " + mSupportedHdrTypes.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 supported hdr types.
count = in.readInt();
for (int readCount = 0; readCount < count; ++readCount) {
builder.addSupportedHdrType(in.readString());
}
boolean supported = in.readBoolean();
builder.setSlowMotionSupported(supported);
return builder.build();
}
public ApplicationMediaCapabilities[] newArray(int size) {
return new ApplicationMediaCapabilities[size];
}
};
/*
* Returns a list that contains all the video codec mime types supported by the application.
* The list will be empty if no codecs are supported by the application.
* @return List of supported video codec mime types.
*/
@NonNull
public List<String> getSupportedVideoMimeTypes() {
return new ArrayList<>(mSupportedVideoMimeTypes);
}
/*
* Returns a list that contains all hdr types supported by the application.
* The list will be empty if no hdr types are supported by the application.
* @return List of supported hdr types.
*/
@NonNull
public List<String> getSupportedHdrTypes() {
return new ArrayList<>(mSupportedHdrTypes);
}
/*
* Whether handling of slow-motion video is supported
*/
public boolean isSlowMotionSupported() {
return mIsSlowMotionSupported;
}
/**
* Builder class for {@link ApplicationMediaCapabilities} objects.
* Use this class to configure and create an ApplicationMediaCapabilities instance. Builder
@@ -96,8 +187,12 @@ public final class ApplicationMediaCapabilities implements Parcelable {
* //TODO(hkuang): Add xml parsing support to the builder.
*/
public final static class Builder {
private boolean mIsHevcSupported = false;
private boolean mIsHdrSupported = false;
/** List of supported video codec mime types. */
private Set<String> mSupportedVideoMimeTypes = new HashSet<>();
/** List of supported hdr types. */
private Set<String> mSupportedHdrTypes = new HashSet<>();
private boolean mIsSlowMotionSupported = false;
/**
@@ -112,37 +207,62 @@ public final class ApplicationMediaCapabilities implements Parcelable {
* @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.
* <code>Builder</code> were incompatible, or if they
* are not supported by the
* device.
*/
@NonNull
public ApplicationMediaCapabilities build() {
if (mIsHdrSupported && !mIsHevcSupported) {
throw new UnsupportedOperationException("Must also support HEVC if support HDR.");
// 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);
}
/**
* Sets whether supports HEVC encoded video.
* 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 UnsupportedOperationException if the codec mime type is not supported.
* @throws IllegalArgumentException if mime type is not valid.
*/
@NonNull
public Builder setHevcSupported(boolean hevcSupported) {
mIsHevcSupported = hevcSupported;
public Builder addSupportedVideoMimeType(
@NonNull String codecMime) {
mSupportedVideoMimeTypes.add(codecMime);
return this;
}
/**
* Sets whether supports high dynamic range video.
*/
@NonNull
public Builder setHdrSupported(boolean hdrSupported) {
mIsHdrSupported = hdrSupported;
return this;
private List<String> getSupportedVideoMimeTypes() {
return new ArrayList<>(mSupportedVideoMimeTypes);
}
/**
* Sets whether supports slow-motion video.
* Adds a supported hdr type.
*
* @param hdrType Supported hdr types. 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) {
mSupportedHdrTypes.add(hdrType);
return this;
}
private List<String> getSupportedHdrTypes() {
return new ArrayList<>(mSupportedHdrTypes);
}
/**
* 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
*/
@NonNull
public Builder setSlowMotionSupported(boolean slowMotionSupported) {

View File

@@ -0,0 +1,63 @@
/*
* 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.StringDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* MediaFeature defines various media features, e.g. hdr type.
*/
public final class MediaFeature {
/**
* Defines tye type of HDR(high dynamic range) video.
*/
public static final class HdrType {
private HdrType() {
}
/**
* HDR type for dolby-vision.
*/
public static final String DOLBY_VISION = "android.media.feature.hdr.dolby_vision";
/**
* HDR type for hdr10.
*/
public static final String HDR10 = "android.media.feature.hdr.hdr10";
/**
* HDR type for hdr10+.
*/
public static final String HDR10_PLUS = "android.media.feature.hdr.hdr10_plus";
/**
* HDR type for hlg.
*/
public static final String HLG = "android.media.feature.hdr.hlg";
}
/** @hide */
@StringDef({
HdrType.DOLBY_VISION,
HdrType.HDR10,
HdrType.HDR10_PLUS,
HdrType.HLG,
})
@Retention(RetentionPolicy.SOURCE)
public @interface MediaHdrType {
}
}

View File

@@ -34,6 +34,8 @@ package com.android.mediatranscodingtest;
import static org.testng.Assert.assertThrows;
import android.media.ApplicationMediaCapabilities;
import android.media.MediaFeature;
import android.media.MediaFormat;
import android.test.ActivityInstrumentationTestCase2;
import org.junit.Test;
@@ -49,37 +51,39 @@ public class ApplicationMediaCapabilitiesTest extends
@Test
public void testSetSupportHevc() throws Exception {
ApplicationMediaCapabilities capability =
new ApplicationMediaCapabilities.Builder().setHevcSupported(true).build();
assertTrue(capability.isHevcSupported());
new ApplicationMediaCapabilities.Builder().addSupportedVideoMimeType(
MediaFormat.MIMETYPE_VIDEO_HEVC).build();
assertTrue(capability.isVideoMimeTypeSupported(MediaFormat.MIMETYPE_VIDEO_HEVC));
ApplicationMediaCapabilities capability2 =
new ApplicationMediaCapabilities.Builder().setHevcSupported(false).build();
assertFalse(capability2.isHevcSupported());
new ApplicationMediaCapabilities.Builder().build();
assertFalse(capability2.isVideoMimeTypeSupported(MediaFormat.MIMETYPE_VIDEO_HEVC));
}
@Test
public void testSetSupportHdr() throws Exception {
ApplicationMediaCapabilities capability =
new ApplicationMediaCapabilities.Builder().setHdrSupported(true).setHevcSupported(
true).build();
assertEquals(true, capability.isHdrSupported());
new ApplicationMediaCapabilities.Builder().addSupportedHdrType(
MediaFeature.HdrType.HDR10_PLUS).addSupportedVideoMimeType(
MediaFormat.MIMETYPE_VIDEO_HEVC).build();
assertEquals(true, capability.isHdrTypeSupported(MediaFeature.HdrType.HDR10_PLUS));
}
@Test
public void testSetSupportSlowMotion() throws Exception {
ApplicationMediaCapabilities capability =
new ApplicationMediaCapabilities.Builder().setSlowMotionSupported(
true).build();
new ApplicationMediaCapabilities.Builder().setSlowMotionSupported(true).build();
assertTrue(capability.isSlowMotionSupported());
}
@Test
public void testBuilder() throws Exception {
ApplicationMediaCapabilities capability =
new ApplicationMediaCapabilities.Builder().setHdrSupported(
true).setHevcSupported(true).setSlowMotionSupported(true).build();
assertTrue(capability.isHdrSupported());
assertTrue(capability.isSlowMotionSupported());
new ApplicationMediaCapabilities.Builder().addSupportedVideoMimeType(
MediaFormat.MIMETYPE_VIDEO_HEVC).addSupportedHdrType(
MediaFeature.HdrType.HDR10_PLUS).setSlowMotionSupported(true).build();
assertTrue(capability.isVideoMimeTypeSupported(MediaFormat.MIMETYPE_VIDEO_HEVC));
assertTrue(capability.isHdrTypeSupported(MediaFeature.HdrType.HDR10_PLUS));
assertTrue(capability.isSlowMotionSupported());
}
@@ -87,8 +91,8 @@ public class ApplicationMediaCapabilitiesTest extends
public void testSupportHdrWithoutSupportHevc() throws Exception {
assertThrows(UnsupportedOperationException.class, () -> {
ApplicationMediaCapabilities capability =
new ApplicationMediaCapabilities.Builder().setHdrSupported(
true).setHevcSupported(false).build();
new ApplicationMediaCapabilities.Builder().addSupportedHdrType(
MediaFeature.HdrType.HDR10_PLUS).build();
});
}
}