mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Use RTSP Setup response timeout value in KeepAliveMonitor intervalMs
Set KeepAliveMonitor to send a keep-alive message at half the timeout value, if provided, by the RTSP Setup response. Issue: androidx/media#662 PiperOrigin-RevId: 570946237
This commit is contained in:
parent
bf7b91e57e
commit
42c1846984
@ -33,6 +33,9 @@
|
|||||||
* Allow multiple of the same DASH identifier in segment template url.
|
* Allow multiple of the same DASH identifier in segment template url.
|
||||||
* Smooth Streaming Extension:
|
* Smooth Streaming Extension:
|
||||||
* RTSP Extension:
|
* RTSP Extension:
|
||||||
|
* Use RTSP Setup Response timeout value in time interval of sending
|
||||||
|
keep-alive RTSP Options requests
|
||||||
|
([#662](https://github.com/androidx/media/issues/662)).
|
||||||
* Decoder Extensions (FFmpeg, VP9, AV1, MIDI, etc.):
|
* Decoder Extensions (FFmpeg, VP9, AV1, MIDI, etc.):
|
||||||
* Add `DecoderOutputBuffer.shouldBeSkipped` to directly mark output
|
* Add `DecoderOutputBuffer.shouldBeSkipped` to directly mark output
|
||||||
buffers that don't need to be presented. This is preferred over
|
buffers that don't need to be presented. This is preferred over
|
||||||
@ -138,6 +141,8 @@ This release includes the following changes since the
|
|||||||
([#577](https://github.com/androidx/media/issues/577)).
|
([#577](https://github.com/androidx/media/issues/577)).
|
||||||
* Ignore custom Rtsp request methods in Options response public header
|
* Ignore custom Rtsp request methods in Options response public header
|
||||||
([#613](https://github.com/androidx/media/issues/613)).
|
([#613](https://github.com/androidx/media/issues/613)).
|
||||||
|
* Decoder Extensions (FFmpeg, VP9, AV1, etc.):
|
||||||
|
* MIDI extension:
|
||||||
* Leanback extension:
|
* Leanback extension:
|
||||||
* Fix bug where disabling a surface can cause an `ArithmeticException` in
|
* Fix bug where disabling a surface can cause an `ArithmeticException` in
|
||||||
Leanback code ([#617](https://github.com/androidx/media/issues/617)).
|
Leanback code ([#617](https://github.com/androidx/media/issues/617)).
|
||||||
|
@ -98,7 +98,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
public static final int RTSP_STATE_PLAYING = 2;
|
public static final int RTSP_STATE_PLAYING = 2;
|
||||||
|
|
||||||
private static final String TAG = "RtspClient";
|
private static final String TAG = "RtspClient";
|
||||||
private static final long DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_MS = 30_000;
|
|
||||||
|
/**
|
||||||
|
* The default divisor used on the session timeout value to be set as the {@link
|
||||||
|
* KeepAliveMonitor#intervalMs}.
|
||||||
|
*/
|
||||||
|
private static final int DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_DIVISOR = 2;
|
||||||
|
|
||||||
/** A listener for session information update. */
|
/** A listener for session information update. */
|
||||||
public interface SessionInfoListener {
|
public interface SessionInfoListener {
|
||||||
@ -145,6 +150,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
private RtspMessageChannel messageChannel;
|
private RtspMessageChannel messageChannel;
|
||||||
@Nullable private RtspAuthUserInfo rtspAuthUserInfo;
|
@Nullable private RtspAuthUserInfo rtspAuthUserInfo;
|
||||||
@Nullable private String sessionId;
|
@Nullable private String sessionId;
|
||||||
|
private long sessionTimeoutMs;
|
||||||
@Nullable private KeepAliveMonitor keepAliveMonitor;
|
@Nullable private KeepAliveMonitor keepAliveMonitor;
|
||||||
@Nullable private RtspAuthenticationInfo rtspAuthenticationInfo;
|
@Nullable private RtspAuthenticationInfo rtspAuthenticationInfo;
|
||||||
private @RtspState int rtspState;
|
private @RtspState int rtspState;
|
||||||
@ -186,6 +192,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
this.messageSender = new MessageSender();
|
this.messageSender = new MessageSender();
|
||||||
this.uri = RtspMessageUtil.removeUserInfo(uri);
|
this.uri = RtspMessageUtil.removeUserInfo(uri);
|
||||||
this.messageChannel = new RtspMessageChannel(new MessageListener());
|
this.messageChannel = new RtspMessageChannel(new MessageListener());
|
||||||
|
this.sessionTimeoutMs = RtspMessageUtil.DEFAULT_RTSP_TIMEOUT_MS;
|
||||||
this.rtspAuthUserInfo = RtspMessageUtil.parseUserInfo(uri);
|
this.rtspAuthUserInfo = RtspMessageUtil.parseUserInfo(uri);
|
||||||
this.pendingSeekPositionUs = C.TIME_UNSET;
|
this.pendingSeekPositionUs = C.TIME_UNSET;
|
||||||
this.rtspState = RTSP_STATE_UNINITIALIZED;
|
this.rtspState = RTSP_STATE_UNINITIALIZED;
|
||||||
@ -733,6 +740,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
|
|
||||||
rtspState = RTSP_STATE_READY;
|
rtspState = RTSP_STATE_READY;
|
||||||
sessionId = response.sessionHeader.sessionId;
|
sessionId = response.sessionHeader.sessionId;
|
||||||
|
sessionTimeoutMs = response.sessionHeader.timeoutMs;
|
||||||
continueSetupRtspTrack();
|
continueSetupRtspTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,7 +749,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
|
|
||||||
rtspState = RTSP_STATE_PLAYING;
|
rtspState = RTSP_STATE_PLAYING;
|
||||||
if (keepAliveMonitor == null) {
|
if (keepAliveMonitor == null) {
|
||||||
keepAliveMonitor = new KeepAliveMonitor(DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_MS);
|
keepAliveMonitor =
|
||||||
|
new KeepAliveMonitor(
|
||||||
|
/* intervalMs= */ sessionTimeoutMs / DEFAULT_RTSP_KEEP_ALIVE_INTERVAL_DIVISOR);
|
||||||
keepAliveMonitor.start();
|
keepAliveMonitor.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,13 +407,19 @@ public final class RtspMessageUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseSessionHeader_withSessionIdContainingSpecialCharactersAndTimeout_succeeds()
|
public void parseSessionHeader_usingDefaultTimeout_succeeds() throws Exception {
|
||||||
throws Exception {
|
String sessionHeaderString = "610a63df-9b57.4856_97ac$665f+56e9c04";
|
||||||
String sessionHeaderString = "610a63df-9b57.4856_97ac$665f+56e9c04;timeout=60";
|
|
||||||
RtspMessageUtil.RtspSessionHeader sessionHeader =
|
RtspMessageUtil.RtspSessionHeader sessionHeader =
|
||||||
RtspMessageUtil.parseSessionHeader(sessionHeaderString);
|
RtspMessageUtil.parseSessionHeader(sessionHeaderString);
|
||||||
assertThat(sessionHeader.sessionId).isEqualTo("610a63df-9b57.4856_97ac$665f+56e9c04");
|
assertThat(sessionHeader.timeoutMs).isEqualTo(RtspMessageUtil.DEFAULT_RTSP_TIMEOUT_MS);
|
||||||
assertThat(sessionHeader.timeoutMs).isEqualTo(60_000);
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseSessionHeader_withCustomTimeout_succeeds() throws Exception {
|
||||||
|
String sessionHeaderString = "610a63df-9b57.4856_97ac$665f+56e9c04;timeout=30";
|
||||||
|
RtspMessageUtil.RtspSessionHeader sessionHeader =
|
||||||
|
RtspMessageUtil.parseSessionHeader(sessionHeaderString);
|
||||||
|
assertThat(sessionHeader.timeoutMs).isEqualTo(30_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -46,7 +46,9 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@ -55,6 +57,7 @@ import org.junit.Rule;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadows.ShadowLooper;
|
||||||
|
|
||||||
/** Playback testing for RTSP. */
|
/** Playback testing for RTSP. */
|
||||||
@Config(sdk = 29)
|
@Config(sdk = 29)
|
||||||
@ -103,9 +106,12 @@ public final class RtspPlaybackTest {
|
|||||||
new ResponseProvider(
|
new ResponseProvider(
|
||||||
clock,
|
clock,
|
||||||
ImmutableList.of(aacRtpPacketStreamDump, mpeg2tsRtpPacketStreamDump),
|
ImmutableList.of(aacRtpPacketStreamDump, mpeg2tsRtpPacketStreamDump),
|
||||||
fakeRtpDataChannel);
|
fakeRtpDataChannel,
|
||||||
|
RtspMessageUtil.DEFAULT_RTSP_TIMEOUT_MS,
|
||||||
|
/* optionsRequestCounter= */ Optional.empty());
|
||||||
rtspServer = new RtspServer(responseProvider);
|
rtspServer = new RtspServer(responseProvider);
|
||||||
ExoPlayer player = createExoPlayer(rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
|
ExoPlayer player =
|
||||||
|
createExoPlayer(clock, rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
|
||||||
|
|
||||||
PlaybackOutput playbackOutput = PlaybackOutput.register(player, capturingRenderersFactory);
|
PlaybackOutput playbackOutput = PlaybackOutput.register(player, capturingRenderersFactory);
|
||||||
player.prepare();
|
player.prepare();
|
||||||
@ -125,8 +131,13 @@ public final class RtspPlaybackTest {
|
|||||||
rtspServer =
|
rtspServer =
|
||||||
new RtspServer(
|
new RtspServer(
|
||||||
new ResponseProvider(
|
new ResponseProvider(
|
||||||
clock, ImmutableList.of(mpeg2tsRtpPacketStreamDump), fakeRtpDataChannel));
|
clock,
|
||||||
ExoPlayer player = createExoPlayer(rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
|
ImmutableList.of(mpeg2tsRtpPacketStreamDump),
|
||||||
|
fakeRtpDataChannel,
|
||||||
|
RtspMessageUtil.DEFAULT_RTSP_TIMEOUT_MS,
|
||||||
|
/* optionsRequestCounter= */ Optional.empty()));
|
||||||
|
ExoPlayer player =
|
||||||
|
createExoPlayer(clock, rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
|
||||||
|
|
||||||
AtomicReference<Throwable> playbackError = new AtomicReference<>();
|
AtomicReference<Throwable> playbackError = new AtomicReference<>();
|
||||||
player.prepare();
|
player.prepare();
|
||||||
@ -158,7 +169,7 @@ public final class RtspPlaybackTest {
|
|||||||
new UdpDataSourceRtpDataChannelFactory(DEFAULT_TIMEOUT_MS), rtpTcpDataChannelFactory);
|
new UdpDataSourceRtpDataChannelFactory(DEFAULT_TIMEOUT_MS), rtpTcpDataChannelFactory);
|
||||||
rtspServer = new RtspServer(responseProviderSupportingOnlyTcp);
|
rtspServer = new RtspServer(responseProviderSupportingOnlyTcp);
|
||||||
ExoPlayer player =
|
ExoPlayer player =
|
||||||
createExoPlayer(rtspServer.startAndGetPortNumber(), forwardingRtpDataChannelFactory);
|
createExoPlayer(clock, rtspServer.startAndGetPortNumber(), forwardingRtpDataChannelFactory);
|
||||||
|
|
||||||
PlaybackOutput playbackOutput = PlaybackOutput.register(player, capturingRenderersFactory);
|
PlaybackOutput playbackOutput = PlaybackOutput.register(player, capturingRenderersFactory);
|
||||||
player.prepare();
|
player.prepare();
|
||||||
@ -183,7 +194,8 @@ public final class RtspPlaybackTest {
|
|||||||
ImmutableList.of(aacRtpPacketStreamDump, mpeg2tsRtpPacketStreamDump),
|
ImmutableList.of(aacRtpPacketStreamDump, mpeg2tsRtpPacketStreamDump),
|
||||||
fakeUdpRtpDataChannel);
|
fakeUdpRtpDataChannel);
|
||||||
rtspServer = new RtspServer(responseProvider);
|
rtspServer = new RtspServer(responseProvider);
|
||||||
ExoPlayer player = createExoPlayer(rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
|
ExoPlayer player =
|
||||||
|
createExoPlayer(clock, rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
|
||||||
|
|
||||||
AtomicReference<PlaybackException> playbackError = new AtomicReference<>();
|
AtomicReference<PlaybackException> playbackError = new AtomicReference<>();
|
||||||
player.prepare();
|
player.prepare();
|
||||||
@ -220,7 +232,7 @@ public final class RtspPlaybackTest {
|
|||||||
new ForwardingRtpDataChannelFactory(rtpDataChannelFactory, rtpDataChannelFactory);
|
new ForwardingRtpDataChannelFactory(rtpDataChannelFactory, rtpDataChannelFactory);
|
||||||
rtspServer = new RtspServer(responseProviderSupportingOnlyTcp);
|
rtspServer = new RtspServer(responseProviderSupportingOnlyTcp);
|
||||||
ExoPlayer player =
|
ExoPlayer player =
|
||||||
createExoPlayer(rtspServer.startAndGetPortNumber(), forwardingRtpDataChannelFactory);
|
createExoPlayer(clock, rtspServer.startAndGetPortNumber(), forwardingRtpDataChannelFactory);
|
||||||
|
|
||||||
AtomicReference<PlaybackException> playbackError = new AtomicReference<>();
|
AtomicReference<PlaybackException> playbackError = new AtomicReference<>();
|
||||||
player.prepare();
|
player.prepare();
|
||||||
@ -240,8 +252,39 @@ public final class RtspPlaybackTest {
|
|||||||
assertThat(playbackError.get()).hasCauseThat().hasMessageThat().isEqualTo("SETUP 461");
|
assertThat(playbackError.get()).hasCauseThat().hasMessageThat().isEqualTo("SETUP 461");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void play_withCustomSessionTimeoutDuration_sendsKeepAliveOptionsRequest()
|
||||||
|
throws Exception {
|
||||||
|
FakeUdpDataSourceRtpDataChannel fakeRtpDataChannel = new FakeUdpDataSourceRtpDataChannel();
|
||||||
|
RtpDataChannel.Factory rtpDataChannelFactory = (trackId) -> fakeRtpDataChannel;
|
||||||
|
FakeClock fakeClock = new FakeClock(/* initialTimeMs= */ 0, true);
|
||||||
|
Optional<AtomicInteger> optionsRequestCounter = Optional.of(new AtomicInteger());
|
||||||
|
ResponseProvider responseProvider =
|
||||||
|
new ResponseProvider(
|
||||||
|
fakeClock,
|
||||||
|
ImmutableList.of(aacRtpPacketStreamDump),
|
||||||
|
fakeRtpDataChannel,
|
||||||
|
/* sessionTimeoutMs= */ 30_000L,
|
||||||
|
optionsRequestCounter);
|
||||||
|
rtspServer = new RtspServer(responseProvider);
|
||||||
|
ExoPlayer player =
|
||||||
|
createExoPlayer(fakeClock, rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
|
||||||
|
player.prepare();
|
||||||
|
player.play();
|
||||||
|
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY);
|
||||||
|
// Reset optionsRequestCounter to count requests made by the keep-alive monitor
|
||||||
|
optionsRequestCounter.get().getAndSet(0);
|
||||||
|
|
||||||
|
fakeClock.advanceTime(/* timeDiffMs= */ 16_000L);
|
||||||
|
ShadowLooper.idleMainLooper();
|
||||||
|
|
||||||
|
assertThat(optionsRequestCounter.get().get()).isEqualTo(1);
|
||||||
|
|
||||||
|
player.release();
|
||||||
|
}
|
||||||
|
|
||||||
private ExoPlayer createExoPlayer(
|
private ExoPlayer createExoPlayer(
|
||||||
int serverRtspPortNumber, RtpDataChannel.Factory rtpDataChannelFactory) {
|
Clock clock, int serverRtspPortNumber, RtpDataChannel.Factory rtpDataChannelFactory) {
|
||||||
ExoPlayer player =
|
ExoPlayer player =
|
||||||
new ExoPlayer.Builder(applicationContext, capturingRenderersFactory)
|
new ExoPlayer.Builder(applicationContext, capturingRenderersFactory)
|
||||||
.setClock(clock)
|
.setClock(clock)
|
||||||
@ -260,11 +303,14 @@ public final class RtspPlaybackTest {
|
|||||||
private static class ResponseProvider implements RtspServer.ResponseProvider {
|
private static class ResponseProvider implements RtspServer.ResponseProvider {
|
||||||
|
|
||||||
protected static final String SESSION_ID = "00000000";
|
protected static final String SESSION_ID = "00000000";
|
||||||
|
private static final String SESSION_TIMEOUT_HEADER_TAG = ";timeout=";
|
||||||
|
|
||||||
protected final Clock clock;
|
protected final Clock clock;
|
||||||
protected final ArrayList<RtpPacketStreamDump> dumpsForSetUpTracks;
|
protected final List<RtpPacketStreamDump> dumpsForSetUpTracks = new ArrayList<>();
|
||||||
protected final ImmutableList<RtpPacketStreamDump> rtpPacketStreamDumps;
|
protected final ImmutableList<RtpPacketStreamDump> rtpPacketStreamDumps;
|
||||||
private final RtspMessageChannel.InterleavedBinaryDataListener binaryDataListener;
|
private final RtspMessageChannel.InterleavedBinaryDataListener binaryDataListener;
|
||||||
|
private final long sessionTimeoutMs;
|
||||||
|
private final Optional<AtomicInteger> optionsRequestCounter;
|
||||||
|
|
||||||
protected RtpPacketTransmitter packetTransmitter;
|
protected RtpPacketTransmitter packetTransmitter;
|
||||||
|
|
||||||
@ -275,15 +321,21 @@ public final class RtspPlaybackTest {
|
|||||||
* @param rtpPacketStreamDumps A list of {@link RtpPacketStreamDump}.
|
* @param rtpPacketStreamDumps A list of {@link RtpPacketStreamDump}.
|
||||||
* @param binaryDataListener A {@link RtspMessageChannel.InterleavedBinaryDataListener} to send
|
* @param binaryDataListener A {@link RtspMessageChannel.InterleavedBinaryDataListener} to send
|
||||||
* RTP data.
|
* RTP data.
|
||||||
|
* @param sessionTimeoutMs Duration RTSP server will keep the session active without receiving
|
||||||
|
* any requests.
|
||||||
|
* @param optionsRequestCounter for how many RTSP Options requests were sent.
|
||||||
*/
|
*/
|
||||||
public ResponseProvider(
|
ResponseProvider(
|
||||||
Clock clock,
|
Clock clock,
|
||||||
List<RtpPacketStreamDump> rtpPacketStreamDumps,
|
List<RtpPacketStreamDump> rtpPacketStreamDumps,
|
||||||
RtspMessageChannel.InterleavedBinaryDataListener binaryDataListener) {
|
RtspMessageChannel.InterleavedBinaryDataListener binaryDataListener,
|
||||||
|
long sessionTimeoutMs,
|
||||||
|
Optional<AtomicInteger> optionsRequestCounter) {
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.rtpPacketStreamDumps = ImmutableList.copyOf(rtpPacketStreamDumps);
|
this.rtpPacketStreamDumps = ImmutableList.copyOf(rtpPacketStreamDumps);
|
||||||
this.binaryDataListener = binaryDataListener;
|
this.binaryDataListener = binaryDataListener;
|
||||||
dumpsForSetUpTracks = new ArrayList<>();
|
this.sessionTimeoutMs = sessionTimeoutMs;
|
||||||
|
this.optionsRequestCounter = optionsRequestCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a list of the received SETUP requests' corresponding {@link RtpPacketStreamDump}. */
|
/** Returns a list of the received SETUP requests' corresponding {@link RtpPacketStreamDump}. */
|
||||||
@ -295,6 +347,7 @@ public final class RtspPlaybackTest {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RtspResponse getOptionsResponse() {
|
public RtspResponse getOptionsResponse() {
|
||||||
|
optionsRequestCounter.ifPresent(AtomicInteger::getAndIncrement);
|
||||||
return new RtspResponse(
|
return new RtspResponse(
|
||||||
/* status= */ 200,
|
/* status= */ 200,
|
||||||
new RtspHeaders.Builder()
|
new RtspHeaders.Builder()
|
||||||
@ -316,9 +369,15 @@ public final class RtspPlaybackTest {
|
|||||||
packetTransmitter = new RtpPacketTransmitter(rtpPacketStreamDump, clock);
|
packetTransmitter = new RtpPacketTransmitter(rtpPacketStreamDump, clock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RtspResponse(
|
return new RtspResponse(
|
||||||
/* status= */ 200, headers.buildUpon().add(RtspHeaders.SESSION, SESSION_ID).build());
|
/* status= */ 200,
|
||||||
|
headers
|
||||||
|
.buildUpon()
|
||||||
|
.add(
|
||||||
|
RtspHeaders.SESSION,
|
||||||
|
// Convert sessionTimeoutMs to seconds
|
||||||
|
SESSION_ID + SESSION_TIMEOUT_HEADER_TAG + (sessionTimeoutMs / 1000))
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -348,7 +407,12 @@ public final class RtspPlaybackTest {
|
|||||||
Clock clock,
|
Clock clock,
|
||||||
List<RtpPacketStreamDump> rtpPacketStreamDumps,
|
List<RtpPacketStreamDump> rtpPacketStreamDumps,
|
||||||
RtspMessageChannel.InterleavedBinaryDataListener binaryDataListener) {
|
RtspMessageChannel.InterleavedBinaryDataListener binaryDataListener) {
|
||||||
super(clock, rtpPacketStreamDumps, binaryDataListener);
|
super(
|
||||||
|
clock,
|
||||||
|
rtpPacketStreamDumps,
|
||||||
|
binaryDataListener,
|
||||||
|
RtspMessageUtil.DEFAULT_RTSP_TIMEOUT_MS,
|
||||||
|
/* optionsRequestCounter= */ Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user