mirror of
https://mirror.skon.top/https://github.com/FFmpeg/FFmpeg
synced 2026-04-20 21:00:41 +08:00
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user