androidx / androidx/media

RTSP SDP fmtp attribute parsing issue

Open
#2,701 0 comments 0 reactions 1 assignee View on GitHub

@microkatz is already working on this.

Since Aug 7, 2025.

bug needs triage
Dominant language
Java
Stars
3k
Forks
955
Avg merge
12d 14h
Merged PRs (30d)
2

Description

Version

Media3 main branch

More version details

No response

Devices that reproduce the issue

All

Devices that do not reproduce the issue

No response

Reproducible in the demo app?

Not tested

Reproduction steps

I'm trying to receive an RTSP stream, but the connection fails immediately after the remote device responds to the DESCRIBE request with Reply.

   Caused by: java.lang.IllegalArgumentException: 0
      	at androidx.media3.common.util.Assertions.checkArgument(Assertions.java:55)
      	at androidx.media3.exoplayer.rtsp.MediaDescription.getFmtpParametersAsMap(MediaDescription.java:394)
      	at androidx.media3.exoplayer.rtsp.RtspMediaTrack.generatePayloadFormat(RtspMediaTrack.java:222)
      	at androidx.media3.exoplayer.rtsp.RtspMediaTrack.<init>(RtspMediaTrack.java:174)
      	at androidx.media3.exoplayer.rtsp.RtspClient.buildTrackList(RtspClient.java:366)
      	at androidx.media3.exoplayer.rtsp.RtspClient.access$1700(RtspClient.java:76)
      	at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener.onDescribeResponseReceived(RtspClient.java:735)
      	at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener.handleRtspResponse(RtspClient.java:641)
      	at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener.handleRtspMessage(RtspClient.java:531) 
      	at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener.lambda$onRtspMessageReceived$0$androidx-media3-exoplayer-rtsp-RtspClient$MessageListener(RtspClient.java:524) 
      	at androidx.media3.exoplayer.rtsp.RtspClient$MessageListener$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0) 
      	at android.os.Handler.handleCallback(Handler.java:959) 
      	at android.os.Handler.dispatchMessage(Handler.java:100) 
      	at android.os.Looper.loopOnce(Looper.java:257) 
      	at android.os.Looper.loop(Looper.java:342) 
      	at android.os.HandlerThread.run(HandlerThread.java:85) 

Below is the Reply packet:

Session Description Protocol
    Session Description Protocol Version (v): 0
    Owner/Creator, Session Id (o): - 1 1 IN IP4 127.0.0.1
    Session Name (s): Easy Rtsp 1.0
    Session Information (i): Easy
    Connection Information (c): IN IP4 0.0.0.0
    Time Description, active time (t): 0 0
    Media Description, name and address (m): video 0 RTP/AVP 96
    Bandwidth Information (b): AS:5000
    Media Attribute (a): rtpmap:96 H264/90000
    Media Attribute (a): fmtp:96 profile-level-id=42001F;packetization-mode=1;sprop-parameter-sets=Z0IAH/QFgJMg,aM48gA==
    Media Attribute (a): control:trackID=0
    Media Description, name and address (m): audio 0 RTP/AVP 0
    Media Attribute (a): rtpmap:0 PCMU/8000
    Media Attribute (a): fmtp:0
    Media Attribute (a): control:trackID=1

I believe the crash is caused by the SDP line a=fmtp:0
Normally, this line should include format parameters, but in this case, it's missing.

The parser seems to assume that parameters are always present, which leads to a crash when they're not.

I suggest adding a check like the following to handle this case safely:

if (!fmtpAttributeValue.contains(" ")) {
    return ImmutableMap.of();
}

Corrected Method:

  /**
   * Returns the FMTP attribute as a map of FMTP parameter names to values; or an empty map if the
   * {@link MediaDescription} does not contain any FMTP attribute.
   *
   * <p>FMTP format reference: RFC2327 Page 27. The spaces around the FMTP attribute delimiters are
   * removed.
   */
  public ImmutableMap<String, String> getFmtpParametersAsMap() {
    @Nullable String fmtpAttributeValue = attributes.get(ATTR_FMTP);
          
    if (fmtpAttributeValue == null) {
      return ImmutableMap.of();
    }

    
    // If there is no space, only the payload type is present and no fmtp parameters are provided. e.g. a=fmtp:0
    if (!fmtpAttributeValue.contains(" ")) {
      return ImmutableMap.of();
    }
    

    // fmtp format: RFC2327 Page 27.
    String[] fmtpComponents = Util.splitAtFirst(fmtpAttributeValue, " ");
    checkArgument(fmtpComponents.length == 2, fmtpAttributeValue);

    // Format of the parameter: RFC3640 Section 4.4.1:
    //   <parameter name>=<value>[; <parameter name>=<value>].
    // Split with an explicit limit of 0 to handle an optional trailing semicolon.
    String[] parameters = fmtpComponents[1].split(";\\s?", /* limit= */ 0);
    ImmutableMap.Builder<String, String> formatParametersBuilder = new ImmutableMap.Builder<>();
    for (String parameter : parameters) {
      // The parameter values can bear equal signs, so splitAtFirst must be used.
      String[] parameterPair = Util.splitAtFirst(parameter, "=");
      formatParametersBuilder.put(parameterPair[0], parameterPair[1]);
    }
    return formatParametersBuilder.buildOrThrow();
  }
Expected result

SETUP packet is sent after Reply

Actual result

The exception is thrown

Media

Not applicable

Bug Report
  • You will email the zip file produced by adb bugreport to android-media-github@google.com after filing this issue.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.