Loading api/current.txt +14 −0 Original line number Diff line number Diff line Loading @@ -22927,6 +22927,8 @@ package android.media { method public java.util.Map<java.util.Locale, java.lang.String> getLabels(); method public java.util.Locale getLocale(); method public int getMasteringIndication(); method public int getPresentationId(); method public int getProgramId(); method public boolean hasAudioDescription(); method public boolean hasDialogueEnhancement(); method public boolean hasSpokenSubtitles(); Loading @@ -22937,6 +22939,18 @@ package android.media { field public static final int MASTERING_NOT_INDICATED = 0; // 0x0 } public static class AudioPresentation.Builder { ctor public AudioPresentation.Builder(int); method public android.media.AudioPresentation build(); method public android.media.AudioPresentation.Builder setHasAudioDescription(boolean); method public android.media.AudioPresentation.Builder setHasDialogueEnhancement(boolean); method public android.media.AudioPresentation.Builder setHasSpokenSubtitles(boolean); method public android.media.AudioPresentation.Builder setLabels(java.util.Map<android.icu.util.ULocale, java.lang.String>); method public android.media.AudioPresentation.Builder setLocale(android.icu.util.ULocale); method public android.media.AudioPresentation.Builder setMasteringIndication(int); method public android.media.AudioPresentation.Builder setProgramId(int); } public class AudioRecord implements android.media.AudioRouting { ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler); api/test-current.txt +0 −6 Original line number Diff line number Diff line Loading @@ -578,12 +578,6 @@ package android.media { method public static boolean isEncodingLinearPcm(int); } public final class AudioPresentation { ctor public AudioPresentation(int, int, java.util.Map<java.lang.String, java.lang.String>, java.lang.String, int, boolean, boolean, boolean); method public int getPresentationId(); method public int getProgramId(); } public final class BufferingParams implements android.os.Parcelable { method public int describeContents(); method public int getInitialMarkMs(); Loading media/java/android/media/AudioPresentation.java +215 −39 Original line number Diff line number Diff line Loading @@ -19,13 +19,14 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; import android.icu.util.ULocale; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Objects; /** Loading @@ -34,7 +35,7 @@ import java.util.Map; * * Used by {@link MediaExtractor} {@link MediaExtractor#getAudioPresentations(int)} and * {@link AudioTrack} {@link AudioTrack#setPresentation(AudioPresentation)} to query available * presentations and to select one. * presentations and to select one, respectively. * * A list of available audio presentations in a media source can be queried using * {@link MediaExtractor#getAudioPresentations(int)}. This list can be presented to a user for Loading @@ -49,8 +50,7 @@ import java.util.Map; public final class AudioPresentation { private final int mPresentationId; private final int mProgramId; private final Map<String, String> mLabels; private final String mLanguage; private final ULocale mLanguage; /** @hide */ @IntDef( Loading @@ -63,72 +63,98 @@ public final class AudioPresentation { }) @Retention(RetentionPolicy.SOURCE) public @interface MasteringIndicationType {} private final @MasteringIndicationType int mMasteringIndication; private final boolean mAudioDescriptionAvailable; private final boolean mSpokenSubtitlesAvailable; private final boolean mDialogueEnhancementAvailable; private final Map<ULocale, String> mLabels; /** * No preferred reproduction channel layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERING_NOT_INDICATED = 0; /** * Stereo speaker layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_STEREO = 1; /** * Two-dimensional (e.g. 5.1) speaker layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_SURROUND = 2; /** * Three-dimensional (e.g. 5.1.2) speaker layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_3D = 3; /** * Prerendered for headphone playback. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_HEADPHONE = 4; /** * @hide * This ID is reserved. No items can be explicitly assigned this ID. */ @TestApi public AudioPresentation(int presentationId, private static final int UNKNOWN_ID = -1; /** * This allows an application developer to construct an AudioPresentation object with all the * parameters. * The IDs are all that is required for an * {@link AudioTrack#setPresentation(AudioPresentation)} to be successful. * The rest of the metadata is informative only so as to distinguish features * of different presentations. * @param presentationId Presentation ID to be decoded by a next generation audio decoder. * @param programId Program ID to be decoded by a next generation audio decoder. * @param language Locale corresponding to ISO 639-1/639-2 language code. * @param masteringIndication One of {@link AudioPresentation#MASTERING_NOT_INDICATED}, * {@link AudioPresentation#MASTERED_FOR_STEREO}, * {@link AudioPresentation#MASTERED_FOR_SURROUND}, * {@link AudioPresentation#MASTERED_FOR_3D}, * {@link AudioPresentation#MASTERED_FOR_HEADPHONE}. * @param audioDescriptionAvailable Audio description for the visually impaired. * @param spokenSubtitlesAvailable Spoken subtitles for the visually impaired. * @param dialogueEnhancementAvailable Dialogue enhancement. * @param labels Text label indexed by its locale corresponding to the language code. */ private AudioPresentation(int presentationId, int programId, @NonNull Map<String, String> labels, @NonNull String language, @NonNull ULocale language, @MasteringIndicationType int masteringIndication, boolean audioDescriptionAvailable, boolean spokenSubtitlesAvailable, boolean dialogueEnhancementAvailable) { this.mPresentationId = presentationId; this.mProgramId = programId; this.mLanguage = language; this.mMasteringIndication = masteringIndication; this.mAudioDescriptionAvailable = audioDescriptionAvailable; this.mSpokenSubtitlesAvailable = spokenSubtitlesAvailable; this.mDialogueEnhancementAvailable = dialogueEnhancementAvailable; this.mLabels = new HashMap<String, String>(labels); boolean dialogueEnhancementAvailable, @NonNull Map<ULocale, String> labels) { mPresentationId = presentationId; mProgramId = programId; mLanguage = language; mMasteringIndication = masteringIndication; mAudioDescriptionAvailable = audioDescriptionAvailable; mSpokenSubtitlesAvailable = spokenSubtitlesAvailable; mDialogueEnhancementAvailable = dialogueEnhancementAvailable; mLabels = new HashMap<ULocale, String>(labels); } /** * The framework uses this presentation id to select an audio presentation rendered by a * decoder. Presentation id is typically sequential, but does not have to be. * @hide * Returns presentation ID used by the framework to select an audio presentation rendered by a * decoder. Presentation ID is typically sequential, but does not have to be. */ @TestApi public int getPresentationId() { return mPresentationId; } /** * The framework uses this program id to select an audio presentation rendered by a decoder. * Program id can be used to further uniquely identify the presentation to a decoder. * @hide * Returns program ID used by the framework to select an audio presentation rendered by a * decoder. Program ID can be used to further uniquely identify the presentation to a decoder. */ @TestApi public int getProgramId() { return mProgramId; } Loading @@ -139,9 +165,9 @@ public final class AudioPresentation { * or ISO 639-2/T could be used. */ public Map<Locale, String> getLabels() { Map<Locale, String> localeLabels = new HashMap<>(); for (Map.Entry<String, String> entry : mLabels.entrySet()) { localeLabels.put(new Locale(entry.getKey()), entry.getValue()); Map<Locale, String> localeLabels = new HashMap<Locale, String>(); for (Map.Entry<ULocale, String> entry : mLabels.entrySet()) { localeLabels.put(entry.getKey().toLocale(), entry.getValue()); } return localeLabels; } Loading @@ -150,13 +176,20 @@ public final class AudioPresentation { * @return the locale corresponding to audio presentation's ISO 639-1/639-2 language code. */ public Locale getLocale() { return new Locale(mLanguage); return mLanguage.toLocale(); } private ULocale getULocale() { return mLanguage; } /** * @return the mastering indication of the audio presentation. * See {@link #MASTERING_NOT_INDICATED}, {@link #MASTERED_FOR_STEREO}, * {@link #MASTERED_FOR_SURROUND}, {@link #MASTERED_FOR_3D}, {@link #MASTERED_FOR_HEADPHONE} * See {@link AudioPresentation#MASTERING_NOT_INDICATED}, * {@link AudioPresentation#MASTERED_FOR_STEREO}, * {@link AudioPresentation#MASTERED_FOR_SURROUND}, * {@link AudioPresentation#MASTERED_FOR_3D}, * {@link AudioPresentation#MASTERED_FOR_HEADPHONE} */ @MasteringIndicationType public int getMasteringIndication() { Loading Loading @@ -186,4 +219,147 @@ public final class AudioPresentation { public boolean hasDialogueEnhancement() { return mDialogueEnhancementAvailable; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof AudioPresentation)) { return false; } AudioPresentation obj = (AudioPresentation) o; return mPresentationId == obj.getPresentationId() && mProgramId == obj.getProgramId() && mLanguage == obj.getULocale() && mMasteringIndication == obj.getMasteringIndication() && mAudioDescriptionAvailable == obj.hasAudioDescription() && mSpokenSubtitlesAvailable == obj.hasSpokenSubtitles() && mDialogueEnhancementAvailable == obj.hasDialogueEnhancement() && mLabels.equals(obj.getLabels()); } @Override public int hashCode() { return Objects.hashCode(mPresentationId); } /** * A builder class for creating {@link AudioPresentation} objects. */ public static class Builder { private final int mPresentationId; private int mProgramId = UNKNOWN_ID; private ULocale mLanguage = new ULocale(""); private int mMasteringIndication = MASTERING_NOT_INDICATED; private boolean mAudioDescriptionAvailable = false; private boolean mSpokenSubtitlesAvailable = false; private boolean mDialogueEnhancementAvailable = false; private Map<ULocale, String> mLabels = new HashMap<ULocale, String>(); /** * Create a {@link Builder}. Any field that should be included in the * {@link AudioPresentation} must be added. * * @param presentationId the presentation ID of this audio presentation */ public Builder(int presentationId) { mPresentationId = presentationId; } /** * Sets the ProgramId to which this audio presentation refers. * * @param programId */ public @NonNull Builder setProgramId(int programId) { mProgramId = programId; return this; } /** * Sets the language information of the audio presentation. * * @param language code */ public @NonNull Builder setLocale(ULocale language) { mLanguage = language; return this; } /** * Sets the mastering indication. * * @param masteringIndication Input to set mastering indication. * @throws IllegalArgumentException if the mastering indication is not any of * {@link AudioPresentation#MASTERING_NOT_INDICATED}, * {@link AudioPresentation#MASTERED_FOR_STEREO}, * {@link AudioPresentation#MASTERED_FOR_SURROUND}, * {@link AudioPresentation#MASTERED_FOR_3D}, * and {@link AudioPresentation#MASTERED_FOR_HEADPHONE} */ public @NonNull Builder setMasteringIndication( @MasteringIndicationType int masteringIndication) { if (masteringIndication != MASTERING_NOT_INDICATED && masteringIndication != MASTERED_FOR_STEREO && masteringIndication != MASTERED_FOR_SURROUND && masteringIndication != MASTERED_FOR_3D && masteringIndication != MASTERED_FOR_HEADPHONE) { throw new IllegalArgumentException("Unknown mastering indication: " + masteringIndication); } mMasteringIndication = masteringIndication; return this; } /** * Sets locale / text label pairs describing the presentation. * * @param labels */ public @NonNull Builder setLabels(@NonNull Map<ULocale, String> labels) { mLabels = new HashMap<ULocale, String>(labels); return this; } /** * Indicate whether the presentation contains audio description for the visually impaired. * * @param audioDescriptionAvailable */ public @NonNull Builder setHasAudioDescription(boolean audioDescriptionAvailable) { mAudioDescriptionAvailable = audioDescriptionAvailable; return this; } /** * Indicate whether the presentation contains spoken subtitles for the visually impaired. * * @param spokenSubtitlesAvailable */ public @NonNull Builder setHasSpokenSubtitles(boolean spokenSubtitlesAvailable) { mSpokenSubtitlesAvailable = spokenSubtitlesAvailable; return this; } /** * Indicate whether the presentation supports dialogue enhancement. * * @param dialogueEnhancementAvailable */ public @NonNull Builder setHasDialogueEnhancement(boolean dialogueEnhancementAvailable) { mDialogueEnhancementAvailable = dialogueEnhancementAvailable; return this; } /** * Creates a {@link AudioPresentation} instance with the specified fields. * * @return The new {@link AudioPresentation} instance */ public @NonNull AudioPresentation build() { return new AudioPresentation(mPresentationId, mProgramId, mLanguage, mMasteringIndication, mAudioDescriptionAvailable, mSpokenSubtitlesAvailable, mDialogueEnhancementAvailable, mLabels); } } } media/jni/android_media_AudioPresentation.h +30 −15 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ struct JAudioPresentationInfo { } constructID = env->GetMethodID(clazz, "<init>", "(IILjava/util/Map;Ljava/lang/String;IZZZ)V"); "(IILandroid/icu/util/ULocale;IZZZLjava/util/Map;)V"); env->DeleteLocalRef(lclazz); // list objects Loading Loading @@ -104,21 +104,26 @@ struct JAudioPresentationInfo { // don't expose private keys (starting with android._) continue; } jobject valueObj = NULL; AString val; CHECK(msg->findString(key, &val)); valueObj = env->NewStringUTF(val.c_str()); if (valueObj != NULL) { jstring keyObj = env->NewStringUTF(key); env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj); env->DeleteLocalRef(keyObj); keyObj = NULL; ScopedLocalRef<jclass> localeClazz(env, env->FindClass("android/icu/util/ULocale")); if (localeClazz.get() == NULL) { return -EINVAL; } jmethodID localeConstructID = env->GetMethodID(localeClazz.get(), "<init>", "(Ljava/lang/String;)V"); if (localeConstructID == NULL) { return -EINVAL; } jstring jLanguage = env->NewStringUTF(key); jobject jLocale = env->NewObject(localeClazz.get(), localeConstructID, jLanguage); env->CallObjectMethod(hashMap, hashMapPutID, jLocale, valueObj); env->DeleteLocalRef(jLocale); jLocale = NULL; env->DeleteLocalRef(valueObj); valueObj = NULL; env->DeleteLocalRef(jLanguage); jLanguage = NULL; } } Loading @@ -142,26 +147,36 @@ struct JAudioPresentationInfo { if (ConvertMessageToMap(env, labelMessage, &jLabelObject) != OK) { return NULL; } jstring jLanguage = env->NewStringUTF(ap->mLanguage.string()); ScopedLocalRef<jclass> localeClazz(env, env->FindClass("android/icu/util/ULocale")); if (localeClazz.get() == NULL) { return NULL; } jmethodID localeConstructID = env->GetMethodID(localeClazz.get(), "<init>", "(Ljava/lang/String;)V"); if (localeConstructID == NULL) { return NULL; } jstring jLanguage = env->NewStringUTF(ap->mLanguage.c_str()); jobject jLocale = env->NewObject(localeClazz.get(), localeConstructID, jLanguage); jobject jValueObj = env->NewObject(fields.clazz, fields.constructID, static_cast<jint>(ap->mPresentationId), static_cast<jint>(ap->mProgramId), jLabelObject, jLanguage, jLocale, static_cast<jint>(ap->mMasteringIndication), static_cast<jboolean>((ap->mAudioDescriptionAvailable == 1) ? 1 : 0), static_cast<jboolean>((ap->mSpokenSubtitlesAvailable == 1) ? 1 : 0), static_cast<jboolean>((ap->mDialogueEnhancementAvailable == 1) ? 1 : 0)); 1 : 0), jLabelObject); if (jValueObj == NULL) { env->DeleteLocalRef(jLanguage); jLanguage = NULL; return NULL; } env->CallBooleanMethod(list, fields.listAddId, jValueObj); env->DeleteLocalRef(jLocale); jLocale = NULL; env->DeleteLocalRef(jValueObj); jValueObj = NULL; env->DeleteLocalRef(jLanguage); jLanguage = NULL; } Loading Loading
api/current.txt +14 −0 Original line number Diff line number Diff line Loading @@ -22927,6 +22927,8 @@ package android.media { method public java.util.Map<java.util.Locale, java.lang.String> getLabels(); method public java.util.Locale getLocale(); method public int getMasteringIndication(); method public int getPresentationId(); method public int getProgramId(); method public boolean hasAudioDescription(); method public boolean hasDialogueEnhancement(); method public boolean hasSpokenSubtitles(); Loading @@ -22937,6 +22939,18 @@ package android.media { field public static final int MASTERING_NOT_INDICATED = 0; // 0x0 } public static class AudioPresentation.Builder { ctor public AudioPresentation.Builder(int); method public android.media.AudioPresentation build(); method public android.media.AudioPresentation.Builder setHasAudioDescription(boolean); method public android.media.AudioPresentation.Builder setHasDialogueEnhancement(boolean); method public android.media.AudioPresentation.Builder setHasSpokenSubtitles(boolean); method public android.media.AudioPresentation.Builder setLabels(java.util.Map<android.icu.util.ULocale, java.lang.String>); method public android.media.AudioPresentation.Builder setLocale(android.icu.util.ULocale); method public android.media.AudioPresentation.Builder setMasteringIndication(int); method public android.media.AudioPresentation.Builder setProgramId(int); } public class AudioRecord implements android.media.AudioRouting { ctor public AudioRecord(int, int, int, int, int) throws java.lang.IllegalArgumentException; method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
api/test-current.txt +0 −6 Original line number Diff line number Diff line Loading @@ -578,12 +578,6 @@ package android.media { method public static boolean isEncodingLinearPcm(int); } public final class AudioPresentation { ctor public AudioPresentation(int, int, java.util.Map<java.lang.String, java.lang.String>, java.lang.String, int, boolean, boolean, boolean); method public int getPresentationId(); method public int getProgramId(); } public final class BufferingParams implements android.os.Parcelable { method public int describeContents(); method public int getInitialMarkMs(); Loading
media/java/android/media/AudioPresentation.java +215 −39 Original line number Diff line number Diff line Loading @@ -19,13 +19,14 @@ package android.media; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; import android.icu.util.ULocale; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Objects; /** Loading @@ -34,7 +35,7 @@ import java.util.Map; * * Used by {@link MediaExtractor} {@link MediaExtractor#getAudioPresentations(int)} and * {@link AudioTrack} {@link AudioTrack#setPresentation(AudioPresentation)} to query available * presentations and to select one. * presentations and to select one, respectively. * * A list of available audio presentations in a media source can be queried using * {@link MediaExtractor#getAudioPresentations(int)}. This list can be presented to a user for Loading @@ -49,8 +50,7 @@ import java.util.Map; public final class AudioPresentation { private final int mPresentationId; private final int mProgramId; private final Map<String, String> mLabels; private final String mLanguage; private final ULocale mLanguage; /** @hide */ @IntDef( Loading @@ -63,72 +63,98 @@ public final class AudioPresentation { }) @Retention(RetentionPolicy.SOURCE) public @interface MasteringIndicationType {} private final @MasteringIndicationType int mMasteringIndication; private final boolean mAudioDescriptionAvailable; private final boolean mSpokenSubtitlesAvailable; private final boolean mDialogueEnhancementAvailable; private final Map<ULocale, String> mLabels; /** * No preferred reproduction channel layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERING_NOT_INDICATED = 0; /** * Stereo speaker layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_STEREO = 1; /** * Two-dimensional (e.g. 5.1) speaker layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_SURROUND = 2; /** * Three-dimensional (e.g. 5.1.2) speaker layout. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_3D = 3; /** * Prerendered for headphone playback. * * @see Builder#setMasteringIndication(int) */ public static final int MASTERED_FOR_HEADPHONE = 4; /** * @hide * This ID is reserved. No items can be explicitly assigned this ID. */ @TestApi public AudioPresentation(int presentationId, private static final int UNKNOWN_ID = -1; /** * This allows an application developer to construct an AudioPresentation object with all the * parameters. * The IDs are all that is required for an * {@link AudioTrack#setPresentation(AudioPresentation)} to be successful. * The rest of the metadata is informative only so as to distinguish features * of different presentations. * @param presentationId Presentation ID to be decoded by a next generation audio decoder. * @param programId Program ID to be decoded by a next generation audio decoder. * @param language Locale corresponding to ISO 639-1/639-2 language code. * @param masteringIndication One of {@link AudioPresentation#MASTERING_NOT_INDICATED}, * {@link AudioPresentation#MASTERED_FOR_STEREO}, * {@link AudioPresentation#MASTERED_FOR_SURROUND}, * {@link AudioPresentation#MASTERED_FOR_3D}, * {@link AudioPresentation#MASTERED_FOR_HEADPHONE}. * @param audioDescriptionAvailable Audio description for the visually impaired. * @param spokenSubtitlesAvailable Spoken subtitles for the visually impaired. * @param dialogueEnhancementAvailable Dialogue enhancement. * @param labels Text label indexed by its locale corresponding to the language code. */ private AudioPresentation(int presentationId, int programId, @NonNull Map<String, String> labels, @NonNull String language, @NonNull ULocale language, @MasteringIndicationType int masteringIndication, boolean audioDescriptionAvailable, boolean spokenSubtitlesAvailable, boolean dialogueEnhancementAvailable) { this.mPresentationId = presentationId; this.mProgramId = programId; this.mLanguage = language; this.mMasteringIndication = masteringIndication; this.mAudioDescriptionAvailable = audioDescriptionAvailable; this.mSpokenSubtitlesAvailable = spokenSubtitlesAvailable; this.mDialogueEnhancementAvailable = dialogueEnhancementAvailable; this.mLabels = new HashMap<String, String>(labels); boolean dialogueEnhancementAvailable, @NonNull Map<ULocale, String> labels) { mPresentationId = presentationId; mProgramId = programId; mLanguage = language; mMasteringIndication = masteringIndication; mAudioDescriptionAvailable = audioDescriptionAvailable; mSpokenSubtitlesAvailable = spokenSubtitlesAvailable; mDialogueEnhancementAvailable = dialogueEnhancementAvailable; mLabels = new HashMap<ULocale, String>(labels); } /** * The framework uses this presentation id to select an audio presentation rendered by a * decoder. Presentation id is typically sequential, but does not have to be. * @hide * Returns presentation ID used by the framework to select an audio presentation rendered by a * decoder. Presentation ID is typically sequential, but does not have to be. */ @TestApi public int getPresentationId() { return mPresentationId; } /** * The framework uses this program id to select an audio presentation rendered by a decoder. * Program id can be used to further uniquely identify the presentation to a decoder. * @hide * Returns program ID used by the framework to select an audio presentation rendered by a * decoder. Program ID can be used to further uniquely identify the presentation to a decoder. */ @TestApi public int getProgramId() { return mProgramId; } Loading @@ -139,9 +165,9 @@ public final class AudioPresentation { * or ISO 639-2/T could be used. */ public Map<Locale, String> getLabels() { Map<Locale, String> localeLabels = new HashMap<>(); for (Map.Entry<String, String> entry : mLabels.entrySet()) { localeLabels.put(new Locale(entry.getKey()), entry.getValue()); Map<Locale, String> localeLabels = new HashMap<Locale, String>(); for (Map.Entry<ULocale, String> entry : mLabels.entrySet()) { localeLabels.put(entry.getKey().toLocale(), entry.getValue()); } return localeLabels; } Loading @@ -150,13 +176,20 @@ public final class AudioPresentation { * @return the locale corresponding to audio presentation's ISO 639-1/639-2 language code. */ public Locale getLocale() { return new Locale(mLanguage); return mLanguage.toLocale(); } private ULocale getULocale() { return mLanguage; } /** * @return the mastering indication of the audio presentation. * See {@link #MASTERING_NOT_INDICATED}, {@link #MASTERED_FOR_STEREO}, * {@link #MASTERED_FOR_SURROUND}, {@link #MASTERED_FOR_3D}, {@link #MASTERED_FOR_HEADPHONE} * See {@link AudioPresentation#MASTERING_NOT_INDICATED}, * {@link AudioPresentation#MASTERED_FOR_STEREO}, * {@link AudioPresentation#MASTERED_FOR_SURROUND}, * {@link AudioPresentation#MASTERED_FOR_3D}, * {@link AudioPresentation#MASTERED_FOR_HEADPHONE} */ @MasteringIndicationType public int getMasteringIndication() { Loading Loading @@ -186,4 +219,147 @@ public final class AudioPresentation { public boolean hasDialogueEnhancement() { return mDialogueEnhancementAvailable; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof AudioPresentation)) { return false; } AudioPresentation obj = (AudioPresentation) o; return mPresentationId == obj.getPresentationId() && mProgramId == obj.getProgramId() && mLanguage == obj.getULocale() && mMasteringIndication == obj.getMasteringIndication() && mAudioDescriptionAvailable == obj.hasAudioDescription() && mSpokenSubtitlesAvailable == obj.hasSpokenSubtitles() && mDialogueEnhancementAvailable == obj.hasDialogueEnhancement() && mLabels.equals(obj.getLabels()); } @Override public int hashCode() { return Objects.hashCode(mPresentationId); } /** * A builder class for creating {@link AudioPresentation} objects. */ public static class Builder { private final int mPresentationId; private int mProgramId = UNKNOWN_ID; private ULocale mLanguage = new ULocale(""); private int mMasteringIndication = MASTERING_NOT_INDICATED; private boolean mAudioDescriptionAvailable = false; private boolean mSpokenSubtitlesAvailable = false; private boolean mDialogueEnhancementAvailable = false; private Map<ULocale, String> mLabels = new HashMap<ULocale, String>(); /** * Create a {@link Builder}. Any field that should be included in the * {@link AudioPresentation} must be added. * * @param presentationId the presentation ID of this audio presentation */ public Builder(int presentationId) { mPresentationId = presentationId; } /** * Sets the ProgramId to which this audio presentation refers. * * @param programId */ public @NonNull Builder setProgramId(int programId) { mProgramId = programId; return this; } /** * Sets the language information of the audio presentation. * * @param language code */ public @NonNull Builder setLocale(ULocale language) { mLanguage = language; return this; } /** * Sets the mastering indication. * * @param masteringIndication Input to set mastering indication. * @throws IllegalArgumentException if the mastering indication is not any of * {@link AudioPresentation#MASTERING_NOT_INDICATED}, * {@link AudioPresentation#MASTERED_FOR_STEREO}, * {@link AudioPresentation#MASTERED_FOR_SURROUND}, * {@link AudioPresentation#MASTERED_FOR_3D}, * and {@link AudioPresentation#MASTERED_FOR_HEADPHONE} */ public @NonNull Builder setMasteringIndication( @MasteringIndicationType int masteringIndication) { if (masteringIndication != MASTERING_NOT_INDICATED && masteringIndication != MASTERED_FOR_STEREO && masteringIndication != MASTERED_FOR_SURROUND && masteringIndication != MASTERED_FOR_3D && masteringIndication != MASTERED_FOR_HEADPHONE) { throw new IllegalArgumentException("Unknown mastering indication: " + masteringIndication); } mMasteringIndication = masteringIndication; return this; } /** * Sets locale / text label pairs describing the presentation. * * @param labels */ public @NonNull Builder setLabels(@NonNull Map<ULocale, String> labels) { mLabels = new HashMap<ULocale, String>(labels); return this; } /** * Indicate whether the presentation contains audio description for the visually impaired. * * @param audioDescriptionAvailable */ public @NonNull Builder setHasAudioDescription(boolean audioDescriptionAvailable) { mAudioDescriptionAvailable = audioDescriptionAvailable; return this; } /** * Indicate whether the presentation contains spoken subtitles for the visually impaired. * * @param spokenSubtitlesAvailable */ public @NonNull Builder setHasSpokenSubtitles(boolean spokenSubtitlesAvailable) { mSpokenSubtitlesAvailable = spokenSubtitlesAvailable; return this; } /** * Indicate whether the presentation supports dialogue enhancement. * * @param dialogueEnhancementAvailable */ public @NonNull Builder setHasDialogueEnhancement(boolean dialogueEnhancementAvailable) { mDialogueEnhancementAvailable = dialogueEnhancementAvailable; return this; } /** * Creates a {@link AudioPresentation} instance with the specified fields. * * @return The new {@link AudioPresentation} instance */ public @NonNull AudioPresentation build() { return new AudioPresentation(mPresentationId, mProgramId, mLanguage, mMasteringIndication, mAudioDescriptionAvailable, mSpokenSubtitlesAvailable, mDialogueEnhancementAvailable, mLabels); } } }
media/jni/android_media_AudioPresentation.h +30 −15 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ struct JAudioPresentationInfo { } constructID = env->GetMethodID(clazz, "<init>", "(IILjava/util/Map;Ljava/lang/String;IZZZ)V"); "(IILandroid/icu/util/ULocale;IZZZLjava/util/Map;)V"); env->DeleteLocalRef(lclazz); // list objects Loading Loading @@ -104,21 +104,26 @@ struct JAudioPresentationInfo { // don't expose private keys (starting with android._) continue; } jobject valueObj = NULL; AString val; CHECK(msg->findString(key, &val)); valueObj = env->NewStringUTF(val.c_str()); if (valueObj != NULL) { jstring keyObj = env->NewStringUTF(key); env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj); env->DeleteLocalRef(keyObj); keyObj = NULL; ScopedLocalRef<jclass> localeClazz(env, env->FindClass("android/icu/util/ULocale")); if (localeClazz.get() == NULL) { return -EINVAL; } jmethodID localeConstructID = env->GetMethodID(localeClazz.get(), "<init>", "(Ljava/lang/String;)V"); if (localeConstructID == NULL) { return -EINVAL; } jstring jLanguage = env->NewStringUTF(key); jobject jLocale = env->NewObject(localeClazz.get(), localeConstructID, jLanguage); env->CallObjectMethod(hashMap, hashMapPutID, jLocale, valueObj); env->DeleteLocalRef(jLocale); jLocale = NULL; env->DeleteLocalRef(valueObj); valueObj = NULL; env->DeleteLocalRef(jLanguage); jLanguage = NULL; } } Loading @@ -142,26 +147,36 @@ struct JAudioPresentationInfo { if (ConvertMessageToMap(env, labelMessage, &jLabelObject) != OK) { return NULL; } jstring jLanguage = env->NewStringUTF(ap->mLanguage.string()); ScopedLocalRef<jclass> localeClazz(env, env->FindClass("android/icu/util/ULocale")); if (localeClazz.get() == NULL) { return NULL; } jmethodID localeConstructID = env->GetMethodID(localeClazz.get(), "<init>", "(Ljava/lang/String;)V"); if (localeConstructID == NULL) { return NULL; } jstring jLanguage = env->NewStringUTF(ap->mLanguage.c_str()); jobject jLocale = env->NewObject(localeClazz.get(), localeConstructID, jLanguage); jobject jValueObj = env->NewObject(fields.clazz, fields.constructID, static_cast<jint>(ap->mPresentationId), static_cast<jint>(ap->mProgramId), jLabelObject, jLanguage, jLocale, static_cast<jint>(ap->mMasteringIndication), static_cast<jboolean>((ap->mAudioDescriptionAvailable == 1) ? 1 : 0), static_cast<jboolean>((ap->mSpokenSubtitlesAvailable == 1) ? 1 : 0), static_cast<jboolean>((ap->mDialogueEnhancementAvailable == 1) ? 1 : 0)); 1 : 0), jLabelObject); if (jValueObj == NULL) { env->DeleteLocalRef(jLanguage); jLanguage = NULL; return NULL; } env->CallBooleanMethod(list, fields.listAddId, jValueObj); env->DeleteLocalRef(jLocale); jLocale = NULL; env->DeleteLocalRef(jValueObj); jValueObj = NULL; env->DeleteLocalRef(jLanguage); jLanguage = NULL; } Loading