1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.TestApi;
22 
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 
26 import java.util.HashMap;
27 import java.util.Locale;
28 import java.util.Map;
29 
30 
31 /**
32  * The AudioPresentation class encapsulates the information that describes an audio presentation
33  * which is available in next generation audio content.
34  *
35  * Used by {@link MediaExtractor} {@link MediaExtractor#getAudioPresentations(int)} and
36  * {@link AudioTrack} {@link AudioTrack#setPresentation(AudioPresentation)} to query available
37  * presentations and to select one.
38  *
39  * A list of available audio presentations in a media source can be queried using
40  * {@link MediaExtractor#getAudioPresentations(int)}. This list can be presented to a user for
41  * selection.
42  * An AudioPresentation can be passed to an offloaded audio decoder via
43  * {@link AudioTrack#setPresentation(AudioPresentation)} to request decoding of the selected
44  * presentation. An audio stream may contain multiple presentations that differ by language,
45  * accessibility, end point mastering and dialogue enhancement. An audio presentation may also have
46  * a set of description labels in different languages to help the user to make an informed
47  * selection.
48  */
49 public final class AudioPresentation {
50     private final int mPresentationId;
51     private final int mProgramId;
52     private final Map<String, String> mLabels;
53     private final String mLanguage;
54 
55     /** @hide */
56     @IntDef(
57         value = {
58             MASTERING_NOT_INDICATED,
59             MASTERED_FOR_STEREO,
60             MASTERED_FOR_SURROUND,
61             MASTERED_FOR_3D,
62             MASTERED_FOR_HEADPHONE,
63     })
64     @Retention(RetentionPolicy.SOURCE)
65     public @interface MasteringIndicationType {}
66 
67     private final @MasteringIndicationType int mMasteringIndication;
68     private final boolean mAudioDescriptionAvailable;
69     private final boolean mSpokenSubtitlesAvailable;
70     private final boolean mDialogueEnhancementAvailable;
71 
72     /**
73      * No preferred reproduction channel layout.
74      */
75     public static final int MASTERING_NOT_INDICATED         = 0;
76     /**
77      * Stereo speaker layout.
78      */
79     public static final int MASTERED_FOR_STEREO             = 1;
80     /**
81      * Two-dimensional (e.g. 5.1) speaker layout.
82      */
83     public static final int MASTERED_FOR_SURROUND           = 2;
84     /**
85      * Three-dimensional (e.g. 5.1.2) speaker layout.
86      */
87     public static final int MASTERED_FOR_3D                 = 3;
88     /**
89      * Prerendered for headphone playback.
90      */
91     public static final int MASTERED_FOR_HEADPHONE          = 4;
92 
93     /**
94      * @hide
95      */
96     @TestApi
AudioPresentation(int presentationId, int programId, @NonNull Map<String, String> labels, @NonNull String language, @MasteringIndicationType int masteringIndication, boolean audioDescriptionAvailable, boolean spokenSubtitlesAvailable, boolean dialogueEnhancementAvailable)97     public AudioPresentation(int presentationId,
98                         int programId,
99                         @NonNull Map<String, String> labels,
100                         @NonNull String language,
101                         @MasteringIndicationType int masteringIndication,
102                         boolean audioDescriptionAvailable,
103                         boolean spokenSubtitlesAvailable,
104                         boolean dialogueEnhancementAvailable) {
105         this.mPresentationId = presentationId;
106         this.mProgramId = programId;
107         this.mLanguage = language;
108         this.mMasteringIndication = masteringIndication;
109         this.mAudioDescriptionAvailable = audioDescriptionAvailable;
110         this.mSpokenSubtitlesAvailable = spokenSubtitlesAvailable;
111         this.mDialogueEnhancementAvailable = dialogueEnhancementAvailable;
112 
113         this.mLabels = new HashMap<String, String>(labels);
114     }
115 
116     /**
117      * The framework uses this presentation id to select an audio presentation rendered by a
118      * decoder. Presentation id is typically sequential, but does not have to be.
119      * @hide
120      */
121     @TestApi
getPresentationId()122     public int getPresentationId() {
123         return mPresentationId;
124     }
125 
126     /**
127      * The framework uses this program id to select an audio presentation rendered by a decoder.
128      * Program id can be used to further uniquely identify the presentation to a decoder.
129      * @hide
130      */
131     @TestApi
getProgramId()132     public int getProgramId() {
133         return mProgramId;
134     }
135 
136     /**
137      * @return a map of available text labels for this presentation. Each label is indexed by its
138      * locale corresponding to the language code as specified by ISO 639-2. Either ISO 639-2/B
139      * or ISO 639-2/T could be used.
140      */
getLabels()141     public Map<Locale, String> getLabels() {
142         Map<Locale, String> localeLabels = new HashMap<>();
143         for (Map.Entry<String, String> entry : mLabels.entrySet()) {
144             localeLabels.put(new Locale(entry.getKey()), entry.getValue());
145         }
146         return localeLabels;
147     }
148 
149     /**
150      * @return the locale corresponding to audio presentation's ISO 639-1/639-2 language code.
151      */
getLocale()152     public Locale getLocale() {
153         return new Locale(mLanguage);
154     }
155 
156     /**
157      * @return the mastering indication of the audio presentation.
158      * See {@link #MASTERING_NOT_INDICATED}, {@link #MASTERED_FOR_STEREO},
159      * {@link #MASTERED_FOR_SURROUND}, {@link #MASTERED_FOR_3D}, {@link #MASTERED_FOR_HEADPHONE}
160      */
161     @MasteringIndicationType
getMasteringIndication()162     public int getMasteringIndication() {
163         return mMasteringIndication;
164     }
165 
166     /**
167      * Indicates whether an audio description for the visually impaired is available.
168      * @return {@code true} if audio description is available.
169      */
hasAudioDescription()170     public boolean hasAudioDescription() {
171         return mAudioDescriptionAvailable;
172     }
173 
174     /**
175      * Indicates whether spoken subtitles for the visually impaired are available.
176      * @return {@code true} if spoken subtitles are available.
177      */
hasSpokenSubtitles()178     public boolean hasSpokenSubtitles() {
179         return mSpokenSubtitlesAvailable;
180     }
181 
182     /**
183      * Indicates whether dialogue enhancement is available.
184      * @return {@code true} if dialogue enhancement is available.
185      */
hasDialogueEnhancement()186     public boolean hasDialogueEnhancement() {
187         return mDialogueEnhancementAvailable;
188     }
189 }
190