Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTSP: app crash because of duplicated header from ip-camera #9014

Closed
ArtRoman opened this issue Jun 3, 2021 · 2 comments
Closed

RTSP: app crash because of duplicated header from ip-camera #9014

ArtRoman opened this issue Jun 3, 2021 · 2 comments
Assignees

Comments

@ArtRoman
Copy link

ArtRoman commented Jun 3, 2021

There is non-catchable app chash when opening RTSP link from ip camera because of duplicated RTSP key "framerate".

java.lang.IllegalArgumentException: Multiple entries with same key: framerate=25 and framerate=0S
  at com.google.common.collect.RegularImmutableMap.createHashTable(RegularImmutableMap.java:104)
  at com.google.common.collect.RegularImmutableMap.create(RegularImmutableMap.java:74)
  at com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:339)
  at com.google.android.exoplayer2.source.rtsp.MediaDescription$Builder.build(MediaDescription.java:198)
  at com.google.android.exoplayer2.source.rtsp.SessionDescriptionParser.addMediaDescriptionToSession(SessionDescriptionParser.java:201)
  at com.google.android.exoplayer2.source.rtsp.SessionDescriptionParser.parse(SessionDescriptionParser.java:186)
  at com.google.android.exoplayer2.source.rtsp.RtspClient$MessageListener.onRtspMessageReceived(RtspClient.java:384)
  at com.google.android.exoplayer2.source.rtsp.RtspMessageChannel$Receiver.lambda$handleRtspMessage$0$RtspMessageChannel$Receiver(RtspMessageChannel.java:291)
  at com.google.android.exoplayer2.source.rtsp.-$$Lambda$RtspMessageChannel$Receiver$HitD0FATwe-gLFkoSjlAUnzETfA.run(-.java:-1:-1)
  at android.os.Handler.handleCallback(Handler.java:755)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at android.os.HandlerThread.run(HandlerThread.java:61)

Corresponding RTSP response is:

RTSP/1.0 200 OK
Content-Type: application/sdp
Server: H264DVR 1.0
Cseq: 1
Content-Base: rtsp://192.168.1.11:554/user=admin&password=&channel=1&stream=0.sdp/
Cache-Control: private
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Content-Length: 412

v=0
o=- 38990265062388 38990265062388 IN IP4 192.168.1.11
s=RTSP Session
c=IN IP4 192.168.1.11
t=0 0
a=control:*
a=range:npt=0-
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000 
a=range:npt=0-
a=framerate:0S
a=fmtp:96 profile-level-id=4d0029; packetization-mode=1; sprop-parameter-sets=J00AKY1uBQBboQAAAwABAAADADKE,KO4Fcg==
a=framerate:25
a=control:trackID=3
m=audio 0 RTP/AVP 8
a=control:trackID=4

Player initialization:

val streamUrl = "rtsp://192.168.1.11:554/user=admin&password=&channel=1&stream=0.sdp"
val mediaSource = RtspMediaSource.Factory().createMediaSource(MediaItem.fromUri(streamUrl))

val player = SimpleExoPlayer.Builder(context).build()
player.repeatMode = Player.REPEAT_MODE_OFF
player.setVideoTextureView(ipcamVideoView)
player.setMediaSource(mediaSource)
player.prepare()
player.play()

Stream URL is not public available. I can do nothing with the camera, I couldn't find option to remove duplicated header.
Is there any way to filter RTSP headers before creating MediaDescription? Maybe any other suggestions to avoid crash?

One of ExoPlayer forks with RTSP support works quite good with this stream.

  • ExoPlayer 2.14.0
  • Android 7.1.2
  • TinkerBoard S
@claincly
Copy link
Contributor

claincly commented Jun 4, 2021

The SDP does look off, no? Setting frame rate to 0S and 25. I'll add the code to make the error surface a bit better. However, it wouldn't change the overall behaviour, because the semantics of this problem is also unclear: do you keep (for the same key) the first value, or the last, or some one in between? In your case, it probably makes more sense to keep "25", but there's no clear cut.

The fail is easy to fix, change the usage of the ImmutableMap.Builder here to use a regular Map,

private final ImmutableMap.Builder<String, String> attributesBuilder;

And change this line

ImmutableMap<String, String> attributes = attributesBuilder.build();

to something like

ImmutableMap<String, String> attributes = ImmutableMap.copyOf(yourMap);

@ArtRoman
Copy link
Author

ArtRoman commented Jun 4, 2021

the semantics of this problem is also unclear: do you keep (for the same key) the first value, or the last, or some one in between?

I expect HashMap-like behaviour: new value with the same key replaces the previous one, so the last header value is kept.

However, it wouldn't change the overall behaviour

Library shouldn't crash app because of uncatched exception. I can't validate all headers of any stream. Error should be handled via error listener, player should stop playing media.

The fail is easy to fix

I will try later to add submodule with modifications instead of library dependency.

marcbaechinger pushed a commit that referenced this issue Jun 8, 2021
The current code does not catch the IAE thrown when building a MediaDescription
or SessionDescription. This CL catches the IAE and propagates it as a
ParserException.

Issue: #9014.

#minor-release

PiperOrigin-RevId: 377544439
@claincly claincly closed this as completed Jun 8, 2021
ojw28 pushed a commit that referenced this issue Jun 10, 2021
The current code does not catch the IAE thrown when building a MediaDescription
or SessionDescription. This CL catches the IAE and propagates it as a
ParserException.

Issue: #9014.

PiperOrigin-RevId: 377544439
ojw28 pushed a commit that referenced this issue Jun 21, 2021
Some server will wrongly insert duplicated attributes. We used to treat this as
a unrecoverable error, but it is better to treat the duplicated attributes in
an "over-writable" fashion like HashMaps.

Issue: #9080,
Issue: #9014
PiperOrigin-RevId: 380547079
icbaker pushed a commit that referenced this issue Jul 21, 2021
Some server will wrongly insert duplicated attributes. We used to treat this as
a unrecoverable error, but it is better to treat the duplicated attributes in
an "over-writable" fashion like HashMaps.

Issue: #9080,
Issue: #9014
PiperOrigin-RevId: 380547079
@google google locked and limited conversation to collaborators Aug 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants