/
RtpPayloadFormat.java
174 lines (163 loc) · 6.29 KB
/
RtpPayloadFormat.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
* Copyright 2021 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 androidx.media3.exoplayer.rtsp;
import static androidx.media3.common.util.Assertions.checkArgument;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.UnstableApi;
import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
/**
* Represents the payload format used in RTP.
*
* <p>In RTSP playback, the format information is always present in the {@link SessionDescription}
* enclosed in the response of a DESCRIBE request. Within each track's {@link MediaDescription}, it
* is the attributes FMTP and RTPMAP that allows us to recreate the media format.
*
* <p>This class wraps around the {@link Format} class, in addition to the instance fields that are
* specific to RTP.
*/
@UnstableApi
public final class RtpPayloadFormat {
private static final String RTP_MEDIA_AC3 = "AC3";
private static final String RTP_MEDIA_AMR = "AMR";
private static final String RTP_MEDIA_AMR_WB = "AMR-WB";
private static final String RTP_MEDIA_MPEG4_GENERIC = "MPEG4-GENERIC";
private static final String RTP_MEDIA_MPEG4_VIDEO = "MP4V-ES";
private static final String RTP_MEDIA_H264 = "H264";
private static final String RTP_MEDIA_H265 = "H265";
private static final String RTP_MEDIA_PCM_L8 = "L8";
private static final String RTP_MEDIA_PCM_L16 = "L16";
private static final String RTP_MEDIA_PCMA = "PCMA";
private static final String RTP_MEDIA_PCMU = "PCMU";
private static final String RTP_MEDIA_VP8 = "VP8";
/** Returns whether the format of a {@link MediaDescription} is supported. */
public static boolean isFormatSupported(MediaDescription mediaDescription) {
switch (Ascii.toUpperCase(mediaDescription.rtpMapAttribute.mediaEncoding)) {
case RTP_MEDIA_AC3:
case RTP_MEDIA_AMR:
case RTP_MEDIA_AMR_WB:
case RTP_MEDIA_H264:
case RTP_MEDIA_H265:
case RTP_MEDIA_MPEG4_VIDEO:
case RTP_MEDIA_MPEG4_GENERIC:
case RTP_MEDIA_PCM_L8:
case RTP_MEDIA_PCM_L16:
case RTP_MEDIA_PCMA:
case RTP_MEDIA_PCMU:
case RTP_MEDIA_VP8:
return true;
default:
return false;
}
}
/**
* Gets the MIME type that is associated with the RTP media type.
*
* <p>For instance, RTP media type "H264" maps to {@link MimeTypes#VIDEO_H264}.
*
* @throws IllegalArgumentException When the media type is not supported/recognized.
*/
public static String getMimeTypeFromRtpMediaType(String mediaType) {
switch (Ascii.toUpperCase(mediaType)) {
case RTP_MEDIA_AC3:
return MimeTypes.AUDIO_AC3;
case RTP_MEDIA_AMR:
return MimeTypes.AUDIO_AMR_NB;
case RTP_MEDIA_AMR_WB:
return MimeTypes.AUDIO_AMR_WB;
case RTP_MEDIA_MPEG4_GENERIC:
return MimeTypes.AUDIO_AAC;
case RTP_MEDIA_PCM_L8:
case RTP_MEDIA_PCM_L16:
return MimeTypes.AUDIO_RAW;
case RTP_MEDIA_PCMA:
return MimeTypes.AUDIO_ALAW;
case RTP_MEDIA_PCMU:
return MimeTypes.AUDIO_MLAW;
case RTP_MEDIA_H264:
return MimeTypes.VIDEO_H264;
case RTP_MEDIA_H265:
return MimeTypes.VIDEO_H265;
case RTP_MEDIA_MPEG4_VIDEO:
return MimeTypes.VIDEO_MP4V;
case RTP_MEDIA_VP8:
return MimeTypes.VIDEO_VP8;
default:
throw new IllegalArgumentException(mediaType);
}
}
/** Returns the PCM encoding type for {@code mediaEncoding}. */
public static @C.PcmEncoding int getRawPcmEncodingType(String mediaEncoding) {
checkArgument(
mediaEncoding.equals(RTP_MEDIA_PCM_L8) || mediaEncoding.equals(RTP_MEDIA_PCM_L16));
return mediaEncoding.equals(RtpPayloadFormat.RTP_MEDIA_PCM_L8)
? C.ENCODING_PCM_8BIT
: C.ENCODING_PCM_16BIT_BIG_ENDIAN;
}
/** The payload type associated with this format. */
public final int rtpPayloadType;
/** The clock rate in Hertz, associated with the format. */
public final int clockRate;
/** The {@link Format} of this RTP payload. */
public final Format format;
/** The format parameters, mapped from the SDP FMTP attribute (RFC2327 Page 22). */
public final ImmutableMap<String, String> fmtpParameters;
/**
* Creates a new instance.
*
* @param format The associated {@link Format media format}.
* @param rtpPayloadType The assigned RTP payload type, from the RTPMAP attribute in {@link
* MediaDescription}.
* @param clockRate The associated clock rate in hertz.
* @param fmtpParameters The format parameters, from the SDP FMTP attribute (RFC2327 Page 22),
* empty if unset. The keys and values are specified in the RFCs for specific formats. For
* instance, RFC3640 Section 4.1 defines keys like profile-level-id and config.
*/
public RtpPayloadFormat(
Format format, int rtpPayloadType, int clockRate, Map<String, String> fmtpParameters) {
this.rtpPayloadType = rtpPayloadType;
this.clockRate = clockRate;
this.format = format;
this.fmtpParameters = ImmutableMap.copyOf(fmtpParameters);
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
RtpPayloadFormat that = (RtpPayloadFormat) o;
return rtpPayloadType == that.rtpPayloadType
&& clockRate == that.clockRate
&& format.equals(that.format)
&& fmtpParameters.equals(that.fmtpParameters);
}
@Override
public int hashCode() {
int result = 7;
result = 31 * result + rtpPayloadType;
result = 31 * result + clockRate;
result = 31 * result + format.hashCode();
result = 31 * result + fmtpParameters.hashCode();
return result;
}
}