RTPDemuxContext for RTP) for these streams where the transport protocol is RDT (as served by Realmedia servers). Originally committed as revision 15544 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
@@ -34,11 +34,42 @@ | |||
#include "rm.h" | |||
#include "internal.h" | |||
struct RDTDemuxContext { | |||
AVFormatContext *ic; | |||
AVStream *st; | |||
void *dynamic_protocol_context; | |||
DynamicPayloadPacketHandlerProc parse_packet; | |||
uint32_t prev_sn, prev_ts; | |||
}; | |||
RDTDemuxContext * | |||
ff_rdt_parse_open(AVFormatContext *ic, AVStream *st, | |||
void *priv_data, RTPDynamicProtocolHandler *handler) | |||
{ | |||
RDTDemuxContext *s = av_mallocz(sizeof(RDTDemuxContext)); | |||
if (!s) | |||
return NULL; | |||
s->ic = ic; | |||
s->st = st; | |||
s->prev_sn = -1; | |||
s->prev_ts = -1; | |||
s->parse_packet = handler->parse_packet; | |||
s->dynamic_protocol_context = priv_data; | |||
return s; | |||
} | |||
void | |||
ff_rdt_parse_close(RDTDemuxContext *s) | |||
{ | |||
av_free(s); | |||
} | |||
struct PayloadContext { | |||
AVFormatContext *rmctx; | |||
uint8_t *mlti_data; | |||
unsigned int mlti_data_size; | |||
uint32_t prev_sn, prev_ts; | |||
char buffer[RTP_MAX_PACKET_LENGTH + FF_INPUT_BUFFER_PADDING_SIZE]; | |||
}; | |||
@@ -202,10 +233,9 @@ rdt_parse_packet (PayloadContext *rdt, AVStream *st, | |||
} | |||
int | |||
ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt, | |||
ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt, | |||
const uint8_t *buf, int len) | |||
{ | |||
PayloadContext *rdt = s->dynamic_protocol_context; | |||
int seq, flags = 0, rule, sn; | |||
uint32_t timestamp; | |||
int rv= 0; | |||
@@ -226,14 +256,13 @@ ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt, | |||
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)) { | |||
if (!(rule & 1) && (sn != s->prev_sn || timestamp != s->prev_ts)) { | |||
flags |= PKT_FLAG_KEY; | |||
rdt->prev_sn = sn; | |||
rdt->prev_ts = timestamp; | |||
s->prev_sn = sn; | |||
s->prev_ts = timestamp; | |||
} | |||
buf += rv; | |||
len -= rv; | |||
s->seq = seq; | |||
rv = s->parse_packet(s->dynamic_protocol_context, | |||
s->st, pkt, ×tamp, buf, len, flags); | |||
@@ -250,7 +279,7 @@ ff_rdt_subscribe_rule (char *cmd, int size, | |||
} | |||
void | |||
ff_rdt_subscribe_rule2 (RTPDemuxContext *s, char *cmd, int size, | |||
ff_rdt_subscribe_rule2 (RDTDemuxContext *s, char *cmd, int size, | |||
int stream_nr, int rule_nr) | |||
{ | |||
PayloadContext *rdt = s->dynamic_protocol_context; | |||
@@ -292,8 +321,6 @@ rdt_new_extradata (void) | |||
PayloadContext *rdt = av_mallocz(sizeof(PayloadContext)); | |||
av_open_input_stream(&rdt->rmctx, NULL, "", &rdt_demuxer, NULL); | |||
rdt->prev_ts = -1; | |||
rdt->prev_sn = -1; | |||
return rdt; | |||
} | |||
@@ -22,6 +22,13 @@ | |||
#ifndef AVFORMAT_RDT_H | |||
#define AVFORMAT_RDT_H | |||
typedef struct RDTDemuxContext RDTDemuxContext; | |||
RDTDemuxContext *ff_rdt_parse_open(AVFormatContext *ic, AVStream *st, | |||
void *priv_data, | |||
RTPDynamicProtocolHandler *handler); | |||
void ff_rdt_parse_close(RDTDemuxContext *s); | |||
/** | |||
* Calculate the response (RealChallenge2 in the RTSP header) to the | |||
* challenge (RealChallenge1 in the RTSP header from the Real/Helix | |||
@@ -53,7 +60,7 @@ void av_register_rdt_dynamic_payload_handlers(void); | |||
void ff_rdt_subscribe_rule(char *cmd, int size, | |||
int stream_nr, int rule_nr); | |||
// FIXME this will be removed ASAP | |||
void ff_rdt_subscribe_rule2(RTPDemuxContext *s, char *cmd, int size, | |||
void ff_rdt_subscribe_rule2(RDTDemuxContext *s, char *cmd, int size, | |||
int stream_nr, int rule_nr); | |||
/** | |||
@@ -74,7 +81,7 @@ int ff_rdt_parse_header(const uint8_t *buf, int len, | |||
* Parse RDT-style packet data (header + media data). | |||
* Usage similar to rtp_parse_packet(). | |||
*/ | |||
int ff_rdt_parse_packet(RTPDemuxContext *s, AVPacket *pkt, | |||
int ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt, | |||
const uint8_t *buf, int len); | |||
#endif /* AVFORMAT_RDT_H */ |
@@ -873,8 +873,12 @@ static void rtsp_close_streams(RTSPState *rt) | |||
for(i=0;i<rt->nb_rtsp_streams;i++) { | |||
rtsp_st = rt->rtsp_streams[i]; | |||
if (rtsp_st) { | |||
if (rtsp_st->tx_ctx) | |||
if (rtsp_st->tx_ctx) { | |||
if (rt->transport == RTSP_TRANSPORT_RDT) | |||
ff_rdt_parse_close(rtsp_st->tx_ctx); | |||
else | |||
rtp_parse_close(rtsp_st->tx_ctx); | |||
} | |||
if (rtsp_st->rtp_handle) | |||
url_close(rtsp_st->rtp_handle); | |||
if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) | |||
@@ -887,6 +891,7 @@ static void rtsp_close_streams(RTSPState *rt) | |||
static int | |||
rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) | |||
{ | |||
RTSPState *rt = s->priv_data; | |||
AVStream *st = NULL; | |||
/* open the RTP context */ | |||
@@ -894,11 +899,17 @@ rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) | |||
st = s->streams[rtsp_st->stream_index]; | |||
if (!st) | |||
s->ctx_flags |= AVFMTCTX_NOHEADER; | |||
if (rt->transport == RTSP_TRANSPORT_RDT) | |||
rtsp_st->tx_ctx = ff_rdt_parse_open(s, st, | |||
rtsp_st->dynamic_protocol_context, | |||
rtsp_st->dynamic_handler); | |||
else | |||
rtsp_st->tx_ctx = rtp_parse_open(s, st, rtsp_st->rtp_handle, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data); | |||
if (!rtsp_st->tx_ctx) { | |||
return AVERROR(ENOMEM); | |||
} else { | |||
} else if (rt->transport != RTSP_TRANSPORT_RDT) { | |||
if(rtsp_st->dynamic_handler) { | |||
rtp_parse_set_dynamic_protocol(rtsp_st->tx_ctx, | |||
rtsp_st->dynamic_protocol_context, | |||