diff --git a/libavformat/rdt.c b/libavformat/rdt.c index c1238b2d46..0dd9a6ef87 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -140,27 +140,25 @@ rdt_load_mdpr (rdt_data *rdt, AVStream *st, int rule_nr) * Actual data handling. */ -static int rdt_parse_header(struct RTPDemuxContext *s, const uint8_t *buf, - int len, int *seq, uint32_t *timestamp, int *flags) +int +ff_rdt_parse_header(const uint8_t *buf, int len, + int *sn, int *seq, int *rn, uint32_t *ts) { - rdt_data *rdt = s->dynamic_protocol_context; - int consumed = 0, sn; + int consumed = 10; - if (buf[0] < 0x40 || buf[0] > 0x42) { + if (len > 0 && (buf[0] < 0x40 || buf[0] > 0x42)) { buf += 9; len -= 9; consumed += 9; } - sn = (buf[0]>>1) & 0x1f; - *seq = AV_RB16(buf+1); - *timestamp = AV_RB32(buf+4); - if (!(buf[3] & 1) && (sn != rdt->prev_sn || *timestamp != rdt->prev_ts)) { - *flags |= PKT_FLAG_KEY; - rdt->prev_sn = sn; - rdt->prev_ts = *timestamp; - } + if (len < 10) + return -1; + if (sn) *sn = (buf[0]>>1) & 0x1f; + if (seq) *seq = AV_RB16(buf+1); + if (ts) *ts = AV_RB32(buf+4); + if (rn) *rn = buf[3] & 0x3f; - return consumed + 10; + return consumed; } /**< return 0 on packet, no more left, 1 on packet, 1 on partial packet... */ @@ -208,7 +206,8 @@ int ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt, const uint8_t *buf, int len) { - int seq, flags = 0; + rdt_data *rdt = s->dynamic_protocol_context; + int seq, flags = 0, rule, sn; uint32_t timestamp; int rv= 0; @@ -221,9 +220,14 @@ ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt, if (len < 12) return -1; - rv = rdt_parse_header(s, buf, len, &seq, ×tamp, &flags); + rv = ff_rdt_parse_header(buf, len, &sn, &seq, &rule, ×tamp); if (rv < 0) return rv; + if (!(rule & 1) && (sn != rdt->prev_sn || timestamp != rdt->prev_ts)) { + flags |= PKT_FLAG_KEY; + rdt->prev_sn = sn; + rdt->prev_ts = timestamp; + } buf += rv; len -= rv; s->seq = seq; diff --git a/libavformat/rdt.h b/libavformat/rdt.h index 5a13127fb5..2fe11873ac 100644 --- a/libavformat/rdt.h +++ b/libavformat/rdt.h @@ -56,6 +56,20 @@ void ff_rdt_subscribe_rule(char *cmd, int size, void ff_rdt_subscribe_rule2(RTPDemuxContext *s, char *cmd, int size, int stream_nr, int rule_nr); +/** + * Parse RDT-style packet header. + * + * @param buf input buffer + * @param len length of input buffer + * @param sn will be set to the stream number this packet belongs to + * @param seq will be set to the sequence number this packet belongs to + * @param rn will be set to the rule number this packet belongs to + * @param ts will be set to the timestamp of the packet + * @return the amount of bytes consumed, or <0 on error + */ +int ff_rdt_parse_header(const uint8_t *buf, int len, + int *sn, int *seq, int *rn, uint32_t *ts); + /** * Parse RDT-style packet data (header + media data). * Usage similar to rtp_parse_packet(). diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index b6013de267..254931cf3d 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1265,6 +1265,9 @@ static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, ret = url_readbuf(rt->rtsp_hd, buf, len); if (ret != len) return -1; + if (rt->transport == RTSP_TRANSPORT_RDT && + ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL) < 0) + return -1; /* find the matching stream */ for(i = 0; i < rt->nb_rtsp_streams; i++) {