This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 6d8950f04624f56f3bb1aec15422d47bad1f5910
Author:     Marvin Scholz <[email protected]>
AuthorDate: Sun Oct 5 23:08:01 2025 +0200
Commit:     Marvin Scholz <[email protected]>
CommitDate: Thu Feb 19 17:18:12 2026 +0100

    avformat: rtsp: handle interleaved pending packets
    
    Fixes the behavior when calling ff_rtsp_read_reply again after it
    was called at another place with return_on_interleaved_data set to
    true. Before, it would result in completely corrupting the internal
    state as the $ interleaved packet marker would have already been read
    which the next run of ff_rtsp_read_reply would look for but never find
    it, trying to read packet data as RTSP message.
---
 libavformat/rtsp.c    | 14 ++++++++++++++
 libavformat/rtsp.h    |  3 +++
 libavformat/rtspdec.c |  1 +
 3 files changed, 18 insertions(+)

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 9b022f6efa..fa227ada62 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1200,6 +1200,7 @@ int ff_rtsp_skip_packet(AVFormatContext *s)
     int ret, len, len1;
     uint8_t buf[MAX_URL_SIZE];
 
+    rt->pending_packet = 0;
     ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
     if (ret != 3)
         return ret < 0 ? ret : AVERROR(EIO);
@@ -1232,6 +1233,18 @@ int ff_rtsp_read_reply(AVFormatContext *s, 
RTSPMessageHeader *reply,
     int ret, content_length, line_count, request;
     unsigned char *content;
 
+    // If we returned on pending packet last time,
+    // do not try to read again, as it would corrupt
+    // the state due to the already consumed '$'.
+    if (rt->pending_packet) {
+        if (return_on_interleaved_data)
+            return 1;
+
+        ret = ff_rtsp_skip_packet(s);
+        if (ret < 0)
+            return ret;
+    }
+
 start:
     line_count = 0;
     request = 0;
@@ -1254,6 +1267,7 @@ start:
                 break;
             if (ch == '$' && q == buf) {
                 if (return_on_interleaved_data) {
+                    rt->pending_packet = 1;
                     return 1;
                 } else {
                     ret = ff_rtsp_skip_packet(s);
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index c27cbe1e03..9b2ceff996 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -286,6 +286,9 @@ typedef struct RTSPState {
     /** The last reply of the server to a RTSP command */
     char last_reply[2048]; /* XXX: allocate ? */
 
+    /** Indicates if a packet is pending to be read (useful for interleaved 
reads) */
+    int pending_packet;
+
     /** RTSPStream->transport_priv of the last stream that we read a
      * packet from */
     void *cur_transport_priv;
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 0d39daa39d..ad16630d2e 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -902,6 +902,7 @@ redo:
     ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
     if (ret != 3)
         return AVERROR(EIO);
+    rt->pending_packet = 0;
     id  = buf[0];
     len = AV_RB16(buf + 1);
     av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len);

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to