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