-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
ReceiverConfig.java
313 lines (274 loc) · 12 KB
/
ReceiverConfig.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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
package org.rocstreaming.roctoolkit;
/**
* Receiver configuration.
* <p>
* ReceiverConfig object can be instantiated with {@link ReceiverConfig.Builder ReceiverConfig.Builder} objects.
*
* @see Receiver
* @see ReceiverConfig.Builder
*/
public class ReceiverConfig {
private int frameSampleRate;
private ChannelSet frameChannels;
private FrameEncoding frameEncoding;
private ClockSource clockSource;
private ResamplerBackend resamplerBackend;
private ResamplerProfile resamplerProfile;
private long targetLatency;
private long maxLatencyOverrun;
private long maxLatencyUnderrun;
private long noPlaybackTimeout;
private long brokenPlaybackTimeout;
private long breakageDetectionWindow;
private ReceiverConfig(
int frameSampleRate,
ChannelSet frameChannels,
FrameEncoding frameEncoding,
ClockSource clockSource,
ResamplerBackend resamplerBackend,
ResamplerProfile resamplerProfile,
long targetLatency,
long maxLatencyOverrun,
long maxLatencyUnderrun,
long noPlaybackTimeout,
long brokenPlaybackTimeout,
long breakageDetectionWindow) {
this.frameSampleRate = frameSampleRate;
this.frameChannels = frameChannels;
this.frameEncoding = frameEncoding;
this.clockSource = clockSource;
this.resamplerBackend = resamplerBackend;
this.resamplerProfile = resamplerProfile;
this.targetLatency = targetLatency;
this.maxLatencyOverrun = maxLatencyOverrun;
this.maxLatencyUnderrun = maxLatencyUnderrun;
this.noPlaybackTimeout = noPlaybackTimeout;
this.brokenPlaybackTimeout = brokenPlaybackTimeout;
this.breakageDetectionWindow = breakageDetectionWindow;
}
/**
* Builder class for {@link ReceiverConfig ReceiverConfig} objects
* @see ReceiverConfig
*/
public static class Builder {
private final int frameSampleRate;
private final ChannelSet frameChannels;
private final FrameEncoding frameEncoding;
private ClockSource clockSource;
private ResamplerBackend resamplerBackend;
private ResamplerProfile resamplerProfile;
private long targetLatency;
private long maxLatencyOverrun;
private long maxLatencyUnderrun;
private long noPlaybackTimeout;
private long brokenPlaybackTimeout;
private long breakageDetectionWindow;
/**
* Create a Builder object for building {@link ReceiverConfig ReceiverConfig}
*
* @param frameSampleRate The rate of the samples in the frames returned to the user.
* Number of samples per channel per second.
* @param frameChannels The channel set in the frames returned to the user.
* @param frameEncoding The sample encoding in the frames returned to the user.
*/
public Builder(int frameSampleRate, ChannelSet frameChannels, FrameEncoding frameEncoding) {
this.frameSampleRate = frameSampleRate;
this.frameChannels = frameChannels;
this.frameEncoding = frameEncoding;
}
/**
* @param clockSource Clock source to use.
* Defines whether read operation will be blocking or non-blocking.
* If zero, default value is used.
* @return this Builder
*/
public Builder clockSource(ClockSource clockSource) {
this.clockSource = clockSource;
return this;
}
/**
* @param resamplerBackend Resampler backend to use.
* @return this Builder
*/
public Builder resamplerBackend(ResamplerBackend resamplerBackend) {
this.resamplerBackend = resamplerBackend;
return this;
}
/**
* @param resamplerProfile Resampler profile to use.
* If non-zero, the receiver employs resampler for two purposes:
* <ul>
* <li>
* adjust the sender clock to the receiver clock, which
* may differ a bit
* </li>
* <li>
* convert the packet sample rate to the frame sample
* rate if they are different
* </li>
* </ul>
* @return this Builder
*/
public Builder resamplerProfile(ResamplerProfile resamplerProfile) {
this.resamplerProfile = resamplerProfile;
return this;
}
/**
* @param targetLatency Target latency, in nanoseconds.
* The session will not start playing until it accumulates the
* requested latency.
* Then, if resampler is enabled, the session will adjust its clock
* to keep actual latency as close as possible to the target latency.
* If zero, default value is used.
* @return this Builder
*/
public Builder targetLatency(long targetLatency) {
this.targetLatency = targetLatency;
return this;
}
/**
* @param maxLatencyOverrun Maximum delta between current and target latency, in nanoseconds.
* If current latency becomes larger than the target latency plus
* this value, the session is terminated.
* If zero, default value is used.
* @return this Builder
*/
public Builder maxLatencyOverrun(long maxLatencyOverrun) {
this.maxLatencyOverrun = maxLatencyOverrun;
return this;
}
/**
* @param maxLatencyUnderrun Maximum delta between target and current latency, in nanoseconds.
* If current latency becomes smaller than the target latency minus
* this value, the session is terminated.
* May be larger than the target latency because current latency may
* be negative, which means that the playback run ahead of the last
* packet received from network.
* If zero, default value is used.
* @return this Builder
*/
public Builder maxLatencyUnderrun(long maxLatencyUnderrun) {
this.maxLatencyUnderrun = maxLatencyUnderrun;
return this;
}
/**
* @param noPlaybackTimeout Timeout for the lack of playback, in nanoseconds.
* If there is no playback during this period, the session is terminated.
* This mechanism allows to detect dead, hanging, or broken clients
* generating invalid packets.
* If zero, default value is used. If negative, the timeout is disabled.
* @return this Builder
*/
public Builder noPlaybackTimeout(long noPlaybackTimeout) {
this.noPlaybackTimeout = noPlaybackTimeout;
return this;
}
/**
* @param brokenPlaybackTimeout Timeout for broken playback, in nanoseconds.
* If there the playback is considered broken during this period,
* the session is terminated. The playback is broken if there is
* a breakage detected at every <code>breakageDetectionWindow</code>
* during <code>brokenPlaybackTimeout</code>.
* This mechanism allows to detect vicious circles like when all
* client packets are a bit late and receiver constantly drops them
* producing unpleasant noise.
* If zero, default value is used. If negative, the timeout is disabled.
* @return this Builder
*/
public Builder brokenPlaybackTimeout(long brokenPlaybackTimeout) {
this.brokenPlaybackTimeout = brokenPlaybackTimeout;
return this;
}
/**
* @param breakageDetectionWindow Breakage detection window, in nanoseconds.
* If zero, default value is used.
* @see Builder#brokenPlaybackTimeout
* @return this Builder
*/
public Builder breakageDetectionWindow(long breakageDetectionWindow) {
this.breakageDetectionWindow = breakageDetectionWindow;
return this;
}
/**
* Build the {@link ReceiverConfig ReceiverConfig} object with <code>Builder</code> parameters.
* @return the new {@link ReceiverConfig ReceiverConfig}
*/
public ReceiverConfig build() {
return new ReceiverConfig(frameSampleRate, frameChannels, frameEncoding, clockSource, resamplerBackend,
resamplerProfile, targetLatency, maxLatencyOverrun, maxLatencyUnderrun,
noPlaybackTimeout, brokenPlaybackTimeout, breakageDetectionWindow);
}
}
public int getFrameSampleRate() {
return frameSampleRate;
}
public void setFrameSampleRate(int frameSampleRate) {
this.frameSampleRate = frameSampleRate;
}
public ChannelSet getFrameChannels() {
return frameChannels;
}
public void setFrameChannels(ChannelSet frameChannels) {
this.frameChannels = frameChannels;
}
public FrameEncoding getFrameEncoding() {
return frameEncoding;
}
public void setFrameEncoding(FrameEncoding frameEncoding) {
this.frameEncoding = frameEncoding;
}
public ClockSource getClockSource() {
return clockSource;
}
public void setClockSource(ClockSource clockSource) {
this.clockSource = clockSource;
}
public ResamplerBackend getResamplerBackend() {
return resamplerBackend;
}
public void setResamplerBackend(ResamplerBackend resamplerBackend) {
this.resamplerBackend = resamplerBackend;
}
public ResamplerProfile getResamplerProfile() {
return resamplerProfile;
}
public void setResamplerProfile(ResamplerProfile resamplerProfile) {
this.resamplerProfile = resamplerProfile;
}
public long getTargetLatency() {
return targetLatency;
}
public void setTargetLatency(long targetLatency) {
this.targetLatency = targetLatency;
}
public long getMaxLatencyOverrun() {
return maxLatencyOverrun;
}
public void setMaxLatencyOverrun(long maxLatencyOverrun) {
this.maxLatencyOverrun = maxLatencyOverrun;
}
public long getMaxLatencyUnderrun() {
return maxLatencyUnderrun;
}
public void setMaxLatencyUnderrun(long maxLatencyUnderrun) {
this.maxLatencyUnderrun = maxLatencyUnderrun;
}
public long getNoPlaybackTimeout() {
return noPlaybackTimeout;
}
public void setNoPlaybackTimeout(long noPlaybackTimeout) {
this.noPlaybackTimeout = noPlaybackTimeout;
}
public long getBrokenPlaybackTimeout() {
return brokenPlaybackTimeout;
}
public void setBrokenPlaybackTimeout(long brokenPlaybackTimeout) {
this.brokenPlaybackTimeout = brokenPlaybackTimeout;
}
public long getBreakageDetectionWindow() {
return breakageDetectionWindow;
}
public void setBreakageDetectionWindow(long breakageDetectionWindow) {
this.breakageDetectionWindow = breakageDetectionWindow;
}
}