Commit 541526fc authored by rbultje's avatar rbultje

This patch refactors RDT packet header parsing so that it can be used in

rtsp.c to detect the ID of the packet source also in case of TCP streams.
This allows proper playback of RDT streams with multiple stream types, e.g.
audio + video. Accepted by LucaB in "RDT/Realmedia patches #2" thread on ML.



git-svn-id: file:///var/local/repositories/ffmpeg/trunk@15496 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 291b902a
...@@ -140,27 +140,25 @@ rdt_load_mdpr (rdt_data *rdt, AVStream *st, int rule_nr) ...@@ -140,27 +140,25 @@ rdt_load_mdpr (rdt_data *rdt, AVStream *st, int rule_nr)
* Actual data handling. * Actual data handling.
*/ */
static int rdt_parse_header(struct RTPDemuxContext *s, const uint8_t *buf, int
int len, int *seq, uint32_t *timestamp, int *flags) 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 = 10;
int consumed = 0, sn;
if (buf[0] < 0x40 || buf[0] > 0x42) { if (len > 0 && (buf[0] < 0x40 || buf[0] > 0x42)) {
buf += 9; buf += 9;
len -= 9; len -= 9;
consumed += 9; consumed += 9;
} }
sn = (buf[0]>>1) & 0x1f; if (len < 10)
*seq = AV_RB16(buf+1); return -1;
*timestamp = AV_RB32(buf+4); if (sn) *sn = (buf[0]>>1) & 0x1f;
if (!(buf[3] & 1) && (sn != rdt->prev_sn || *timestamp != rdt->prev_ts)) { if (seq) *seq = AV_RB16(buf+1);
*flags |= PKT_FLAG_KEY; if (ts) *ts = AV_RB32(buf+4);
rdt->prev_sn = sn; if (rn) *rn = buf[3] & 0x3f;
rdt->prev_ts = *timestamp;
}
return consumed + 10; return consumed;
} }
/**< return 0 on packet, no more left, 1 on packet, 1 on partial packet... */ /**< return 0 on packet, no more left, 1 on packet, 1 on partial packet... */
...@@ -208,7 +206,8 @@ int ...@@ -208,7 +206,8 @@ int
ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt, ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
const uint8_t *buf, int len) 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; uint32_t timestamp;
int rv= 0; int rv= 0;
...@@ -221,9 +220,14 @@ ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt, ...@@ -221,9 +220,14 @@ ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
if (len < 12) if (len < 12)
return -1; return -1;
rv = rdt_parse_header(s, buf, len, &seq, &timestamp, &flags); rv = ff_rdt_parse_header(buf, len, &sn, &seq, &rule, &timestamp);
if (rv < 0) if (rv < 0)
return rv; 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; buf += rv;
len -= rv; len -= rv;
s->seq = seq; s->seq = seq;
......
...@@ -56,6 +56,20 @@ void ff_rdt_subscribe_rule(char *cmd, int size, ...@@ -56,6 +56,20 @@ void ff_rdt_subscribe_rule(char *cmd, int size,
void ff_rdt_subscribe_rule2(RTPDemuxContext *s, char *cmd, int size, void ff_rdt_subscribe_rule2(RTPDemuxContext *s, char *cmd, int size,
int stream_nr, int rule_nr); 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). * Parse RDT-style packet data (header + media data).
* Usage similar to rtp_parse_packet(). * Usage similar to rtp_parse_packet().
......
...@@ -1265,6 +1265,9 @@ static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, ...@@ -1265,6 +1265,9 @@ static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
ret = url_readbuf(rt->rtsp_hd, buf, len); ret = url_readbuf(rt->rtsp_hd, buf, len);
if (ret != len) if (ret != len)
return -1; 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 */ /* find the matching stream */
for(i = 0; i < rt->nb_rtsp_streams; i++) { for(i = 0; i < rt->nb_rtsp_streams; i++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment