Skip to content

Commit

Permalink
Allow empty information attributes in RTSP Session Description
Browse files Browse the repository at this point in the history
Issue: androidx#1087
PiperOrigin-RevId: 608534659
  • Loading branch information
microkatz authored and copybara-github committed Feb 20, 2024
1 parent 04bdf3e commit 52c1d60
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 0 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
* DASH Extension:
* Smooth Streaming Extension:
* RTSP Extension:
* Skip empty session information values (i-tags) in SDP parsing
([#1087](https://github.com/androidx/media/issues/1087)).
* Decoder Extensions (FFmpeg, VP9, AV1, MIDI, etc.):
* Leanback extension:
* Cast Extension:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import androidx.media3.common.ParserException;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -35,6 +36,8 @@
// SDP line always starts with an one letter tag, followed by an equal sign. The information
// under the given tag follows an optional space.
private static final Pattern SDP_LINE_PATTERN = Pattern.compile("([a-z])=\\s?(.+)");
// SDP line with a one letter tag, an equal sign, and an empty value.
private static final Pattern SDP_LINE_WITH_EMPTY_VALUE_PATTERN = Pattern.compile("^([a-z])=$");
// Matches an attribute line (with a= sdp tag removed. Example: range:npt=0-50.0).
// Attribute can also be a flag, i.e. without a value, like recvonly. Reference RFC4566 Section 9
// Page 43, under "token-char".
Expand Down Expand Up @@ -81,6 +84,11 @@ public static SessionDescription parse(String sdpString) throws ParserException

Matcher matcher = SDP_LINE_PATTERN.matcher(line);
if (!matcher.matches()) {
Matcher sdpTagMatcher = SDP_LINE_WITH_EMPTY_VALUE_PATTERN.matcher(line);
if (sdpTagMatcher.matches() && Objects.equals(sdpTagMatcher.group(1), INFORMATION_TYPE)) {
// Allow and skip empty Session Information (tag 'i') attributes
continue;
}
throw ParserException.createForMalformedManifest(
"Malformed SDP line: " + line, /* cause= */ null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static org.junit.Assert.assertThrows;

import android.net.Uri;
import androidx.media3.common.ParserException;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -270,6 +271,38 @@ public void parse_sdpStringWithExtraSpaceInRtpMapAttribute_succeeds() throws Exc
assertThat(rtpMapAttribute.clockRate).isEqualTo(44100);
}

@Test
public void parse_sdpStringWithEmptyInformationAttribute_succeeds() throws Exception {
String testMediaSdpInfo =
"v=0\r\n"
+ "o=MNobody 2890844526 2890842807 IN IP4 192.0.2.46\r\n"
+ "s=SDP Seminar\r\n"
+ "i=\r\n"
+ "t=0 0\r\n"
+ "a=control:*\r\n"
+ "m=audio 3456 RTP/AVP 0\r\n"
+ "i=\r\n"
+ "a=rtpmap:97 AC3/44100 \r\n";

SessionDescription sessionDescription = SessionDescriptionParser.parse(testMediaSdpInfo);

assertThat(sessionDescription.sessionInfo).isNull();
assertThat(sessionDescription.mediaDescriptionList.get(0).mediaTitle).isNull();
}

@Test
public void parse_sdpStringWithEmptySessionAttribute_throwsParserException() {
String testMediaSdpInfo =
"v=0\r\n"
+ "o=MNobody 2890844526 2890842807 IN IP4 192.0.2.46\r\n"
+ "s=\r\n"
+ "a=control:*\r\n"
+ "m=audio 3456 RTP/AVP 0\r\n"
+ "a=rtpmap:97 AC3/44100 \r\n";

assertThrows(ParserException.class, () -> SessionDescriptionParser.parse(testMediaSdpInfo));
}

@Test
public void buildMediaDescription_withInvalidRtpmapAttribute_throwsIllegalStateException() {
assertThrows(
Expand Down

0 comments on commit 52c1d60

Please sign in to comment.