1 /**
2  * Copyright (C) 2024 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.telephony.imsmedia;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 
22 import androidx.annotation.NonNull;
23 import androidx.annotation.Nullable;
24 
25 import java.util.Objects;
26 
27 /**
28  * Class to encapsulate RTP (Real-time Transport Protocol) reception parameters required to transfer
29  * the reception statistics for the delay adjustment
30  *
31  * @hide
32  */
33 
34 public final class RtpReceptionStats implements Parcelable {
35     /* The timestamp reflects the sampling instant of the latest RTP packet received */
36     private int mRtpTimestamp;
37     /* The timestamp reflects the sampling instant of the latest RTCP-SR packet received */
38     private int mRtcpSrTimestamp;
39     /* The NTP timestamp of latest RTCP-SR packet received */
40     private long mRtcpSrNtpTimestamp;
41     /**
42      * The mean jitter buffer delay of a media stream from received to playback, measured in
43      * milliseconds, within the reporting interval
44      */
45     private int mJitterBufferMs;
46     /* The round trip time delay in millisecond when latest RTP packet received */
47     private int mRoundTripTimeMs;
48     /* Maximum 16bit value */
49     private static final int MAX_VALUE_16BIT = Short.MAX_VALUE;
50 
51     /** @hide **/
RtpReceptionStats(Parcel in)52     public RtpReceptionStats(Parcel in) {
53         mRtpTimestamp = in.readInt();
54         mRtcpSrTimestamp = in.readInt();
55         mRtcpSrNtpTimestamp = in.readLong();
56         mJitterBufferMs = in.readInt();
57         mRoundTripTimeMs = in.readInt();
58     }
59 
RtpReceptionStats(int rtpTs, int rtcpTs, long ntp, int delay, int roundtrip)60     private RtpReceptionStats(int rtpTs, int rtcpTs, long ntp, int delay, int roundtrip) {
61         this.mRtpTimestamp = rtpTs;
62         this.mRtcpSrTimestamp = rtcpTs;
63         this.mRtcpSrNtpTimestamp = ntp;
64         this.mJitterBufferMs = delay;
65         this.mRoundTripTimeMs = roundtrip;
66     }
67 
68     /** @hide **/
getRtpTimestamp()69     public int getRtpTimestamp() {
70         return mRtpTimestamp;
71     }
72 
73     /** @hide **/
getRtcpSrTimestamp()74     public int getRtcpSrTimestamp() {
75         return mRtcpSrTimestamp;
76     }
77 
78     /** @hide **/
getRtcpSrNtpTimestamp()79     public long getRtcpSrNtpTimestamp() {
80         return mRtcpSrNtpTimestamp;
81     }
82 
83     /** @hide **/
getJitterBufferMs()84     public int getJitterBufferMs() {
85         return mJitterBufferMs;
86     }
87 
88     /** @hide **/
getRoundTripTimeMs()89     public int getRoundTripTimeMs() {
90         return mRoundTripTimeMs;
91     }
92 
93 
94     @NonNull
95     @Override
toString()96     public String toString() {
97         return "RtpReceptionStats: {"
98                 + "mRtpTimestamp=" + mRtpTimestamp
99                 + ", mRtcpSrTimestamp=" + mRtcpSrTimestamp
100                 + ", mRtcpSrNtpTimestamp=" + mRtcpSrNtpTimestamp
101                 + ", mJitterBufferMs=" + mJitterBufferMs
102                 + ", mRoundTripTimeMs=" + mRoundTripTimeMs
103             + " }";
104     }
105 
106     @Override
hashCode()107     public int hashCode() {
108         return Objects.hash(mRtpTimestamp, mRtcpSrTimestamp, mRtcpSrNtpTimestamp,
109             mJitterBufferMs, mRoundTripTimeMs);
110     }
111 
112     @Override
equals(@ullable Object o)113     public boolean equals(@Nullable Object o) {
114         if (o == null || !(o instanceof RtpReceptionStats) || hashCode() != o.hashCode()) {
115             return false;
116         }
117 
118         if (this == o) {
119             return true;
120         }
121 
122         RtpReceptionStats s = (RtpReceptionStats) o;
123 
124         return (mRtpTimestamp == s.mRtpTimestamp
125                 && mRtcpSrTimestamp == s.mRtcpSrTimestamp
126                 && mRtcpSrNtpTimestamp == s.mRtcpSrNtpTimestamp
127                 && mJitterBufferMs == s.mJitterBufferMs
128                 && mRoundTripTimeMs == s.mRoundTripTimeMs);
129     }
130 
131     /**
132      * {@link Parcelable#describeContents}
133      */
describeContents()134     public int describeContents() {
135         return 0;
136     }
137 
138     /**
139      * {@link Parcelable#writeToParcel}
140      */
writeToParcel(Parcel dest, int flags)141     public void writeToParcel(Parcel dest, int flags) {
142         dest.writeInt(mRtpTimestamp);
143         dest.writeInt(mRtcpSrTimestamp);
144         dest.writeLong(mRtcpSrNtpTimestamp);
145         dest.writeInt(mJitterBufferMs);
146         dest.writeInt(mRoundTripTimeMs);
147     }
148 
149     public static final @NonNull Parcelable.Creator<RtpReceptionStats>
150             CREATOR = new Parcelable.Creator() {
151                 public RtpReceptionStats createFromParcel(Parcel in) {
152                     // TODO use builder class so it will validate
153                     return new RtpReceptionStats(in);
154                 }
155 
156                 public RtpReceptionStats[] newArray(int size) {
157                     return new RtpReceptionStats[size];
158                 }
159             };
160 
161     /**
162      * Provides a convenient way to set the fields of a {@link RtpReceptionStats} when creating a
163      * new instance.
164      */
165     public static final class Builder {
166         private int mRtpTimestamp;
167         private int mRtcpSrTimestamp;
168         private long mRtcpSrNtpTimestamp;
169         private int mJitterBufferMs;
170         private int mRoundTripTimeMs;
171 
172         /**
173          * Default constructor for Builder.
174          */
Builder()175         public Builder() {
176         }
177 
178         /**
179          * Set the timestamp.
180          *
181          * @param timestamp The timestamp of last RTP packet sent
182          * @return The same instance of the builder.
183          */
setRtpTimestamp(final int timestamp)184         public @NonNull Builder setRtpTimestamp(final int timestamp) {
185             this.mRtpTimestamp = timestamp;
186             return this;
187         }
188 
189         /**
190          * Set the timestamp reflects the sampling instant of the latest RTCP-SR packet received
191          *
192          * @param timestamp The timestamp of the latest RTCP-SR packet received
193          * @return The same instance of the builder.
194          */
setRtcpSrTimestamp(final int timestamp)195         public @NonNull Builder setRtcpSrTimestamp(final int timestamp) {
196             this.mRtcpSrTimestamp = timestamp;
197             return this;
198         }
199 
200         /**
201          * Set the NTP timestamp of latest RTCP-SR packet received
202          *
203          * @param ntp The NTP timestamp of the latest RTCP-SR packet received
204          * @return The same instance of the builder.
205          */
setRtcpSrNtpTimestamp(final long ntp)206         public @NonNull Builder setRtcpSrNtpTimestamp(final long ntp) {
207             this.mRtcpSrNtpTimestamp = ntp;
208             return this;
209         }
210 
211         /**
212          * Set the mean jitter buffering time from received to play out in millisecond measured in
213          * the reporting interval
214          *
215          * @param time The mean jitter buffering time in millisecond
216          * @return The same instance of the builder.
217          */
setJitterBufferMs(final int time)218         public @NonNull Builder setJitterBufferMs(final int time) {
219             this.mJitterBufferMs = time;
220             return this;
221         }
222 
223         /**
224          * Set round trip time delay in millisecond when latest RTP packet received
225          *
226          * @param time The round trip time in millisecond
227          * @return The same instance of the builder.
228          */
setRoundTripTimeMs(final int time)229         public @NonNull Builder setRoundTripTimeMs(final int time) {
230             this.mRoundTripTimeMs = time;
231             return this;
232         }
233 
234         /**
235          * Build the RtpReceptionStats.
236          *
237          * @return the RtpReceptionStats object.
238          */
build()239         public @NonNull RtpReceptionStats build() {
240             return new RtpReceptionStats(mRtpTimestamp, mRtcpSrTimestamp, mRtcpSrNtpTimestamp,
241                     mJitterBufferMs, mRoundTripTimeMs);
242         }
243     }
244 }
245