1 /*
2  * Copyright (C) 2010 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.net.rtp;
18 
19 import java.util.Arrays;
20 
21 /**
22  * This class defines a collection of audio codecs to be used with
23  * {@link AudioStream}s. Their parameters are designed to be exchanged using
24  * Session Description Protocol (SDP). Most of the values listed here can be
25  * found in RFC 3551, while others are described in separated standards.
26  *
27  * <p>Few simple configurations are defined as public static instances for the
28  * convenience of direct uses. More complicated ones could be obtained using
29  * {@link #getCodec(int, String, String)}. For example, one can use the
30  * following snippet to create a mode-1-only AMR codec.</p>
31  * <pre>
32  * AudioCodec codec = AudioCodec.getCodec(100, "AMR/8000", "mode-set=1");
33  * </pre>
34  *
35  * @see AudioStream
36  *
37  * @deprecated {@link android.net.sip.SipManager} and associated classes are no longer
38  * supported and should not be used as the basis of future VOIP apps.
39  */
40 public class AudioCodec {
41     /**
42      * The RTP payload type of the encoding.
43      */
44     public final int type;
45 
46     /**
47      * The encoding parameters to be used in the corresponding SDP attribute.
48      */
49     public final String rtpmap;
50 
51     /**
52      * The format parameters to be used in the corresponding SDP attribute.
53      */
54     public final String fmtp;
55 
56     /**
57      * G.711 u-law audio codec.
58      */
59     public static final AudioCodec PCMU = new AudioCodec(0, "PCMU/8000", null);
60 
61     /**
62      * G.711 a-law audio codec.
63      */
64     public static final AudioCodec PCMA = new AudioCodec(8, "PCMA/8000", null);
65 
66     /**
67      * GSM Full-Rate audio codec, also known as GSM-FR, GSM 06.10, GSM, or
68      * simply FR.
69      */
70     public static final AudioCodec GSM = new AudioCodec(3, "GSM/8000", null);
71 
72     /**
73      * GSM Enhanced Full-Rate audio codec, also known as GSM-EFR, GSM 06.60, or
74      * simply EFR.
75      */
76     public static final AudioCodec GSM_EFR = new AudioCodec(96, "GSM-EFR/8000", null);
77 
78     /**
79      * Adaptive Multi-Rate narrowband audio codec, also known as AMR or AMR-NB.
80      * Currently CRC, robust sorting, and interleaving are not supported. See
81      * more details about these features in RFC 4867.
82      */
83     public static final AudioCodec AMR = new AudioCodec(97, "AMR/8000", null);
84 
85     private static final AudioCodec[] sCodecs = {GSM_EFR, AMR, GSM, PCMU, PCMA};
86 
AudioCodec(int type, String rtpmap, String fmtp)87     private AudioCodec(int type, String rtpmap, String fmtp) {
88         this.type = type;
89         this.rtpmap = rtpmap;
90         this.fmtp = fmtp;
91     }
92 
93     /**
94      * Returns system supported audio codecs.
95      */
getCodecs()96     public static AudioCodec[] getCodecs() {
97         return Arrays.copyOf(sCodecs, sCodecs.length);
98     }
99 
100     /**
101      * Creates an AudioCodec according to the given configuration.
102      *
103      * @param type The payload type of the encoding defined in RTP/AVP.
104      * @param rtpmap The encoding parameters specified in the corresponding SDP
105      *     attribute, or null if it is not available.
106      * @param fmtp The format parameters specified in the corresponding SDP
107      *     attribute, or null if it is not available.
108      * @return The configured AudioCodec or {@code null} if it is not supported.
109      */
getCodec(int type, String rtpmap, String fmtp)110     public static AudioCodec getCodec(int type, String rtpmap, String fmtp) {
111         if (type < 0 || type > 127) {
112             return null;
113         }
114 
115         AudioCodec hint = null;
116         if (rtpmap != null) {
117             String clue = rtpmap.trim().toUpperCase();
118             for (AudioCodec codec : sCodecs) {
119                 if (clue.startsWith(codec.rtpmap)) {
120                     String channels = clue.substring(codec.rtpmap.length());
121                     if (channels.length() == 0 || channels.equals("/1")) {
122                         hint = codec;
123                     }
124                     break;
125                 }
126             }
127         } else if (type < 96) {
128             for (AudioCodec codec : sCodecs) {
129                 if (type == codec.type) {
130                     hint = codec;
131                     rtpmap = codec.rtpmap;
132                     break;
133                 }
134             }
135         }
136 
137         if (hint == null) {
138             return null;
139         }
140         if (hint == AMR && fmtp != null) {
141             String clue = fmtp.toLowerCase();
142             if (clue.contains("crc=1") || clue.contains("robust-sorting=1") ||
143                     clue.contains("interleaving=")) {
144                 return null;
145             }
146         }
147         return new AudioCodec(type, rtpmap, fmtp);
148     }
149 }
150