Index: libavformat/rtpproto.c =================================================================== --- libavformat/rtpproto.c (revision 21510) +++ libavformat/rtpproto.c (working copy) @@ -188,9 +188,9 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) { RTPContext *s = h->priv_data; - struct sockaddr_in from; + struct sockaddr from; socklen_t from_len; - int len, fd_max, n; + int len, fd_max, n, is_rtcp_packet; fd_set rfds; #if 0 for(;;) { @@ -216,8 +216,10 @@ FD_SET(s->rtcp_fd, &rfds); n = select(fd_max + 1, &rfds, NULL, NULL, NULL); if (n > 0) { + is_rtcp_packet = 0; /* first try RTCP */ if (FD_ISSET(s->rtcp_fd, &rfds)) { + is_rtcp_packet = 1; from_len = sizeof(from); len = recvfrom (s->rtcp_fd, buf, size, 0, (struct sockaddr *)&from, &from_len); @@ -244,6 +246,14 @@ } } } + + /* If we have an appropriate registered callback, allow it to decide whether to drop this packet or not */ + if (h->check_net_packet_callback != NULL) { + if (!(h->check_net_packet_callback(&from, buf, size))) { + av_log(NULL, AV_LOG_DEBUG, "Net packet callback check tells us to drop this packet, so we will."); + return AVERROR(EAGAIN); + } + } #endif return len; } Index: libavformat/avformat.h =================================================================== --- libavformat/avformat.h (revision 21510) +++ libavformat/avformat.h (working copy) @@ -683,6 +683,14 @@ */ #define RAW_PACKET_BUFFER_SIZE 2500000 int raw_packet_buffer_remaining_size; + + /** + * Callback called just after getting a packet but before returning + * for processing in demuxers dealing with data over a network; can + * be used to accept/reject packets based on eg. source address. + * Return 0 to reject the packet, nonzero to accept it. + */ + int (*check_net_packet_callback)(struct sockaddr *srcaddress, uint8_t *buf, int buflen); } AVFormatContext; typedef struct AVPacketList { Index: libavformat/rtsp.c =================================================================== --- libavformat/rtsp.c (revision 21510) +++ libavformat/rtsp.c (working copy) @@ -1808,6 +1808,7 @@ err = AVERROR_INVALIDDATA; goto fail; } + rtsp_st->rtp_handle->check_net_packet_callback = s->check_net_packet_callback; if ((err = rtsp_open_transport_ctx(s, rtsp_st))) goto fail; } Index: libavformat/Makefile =================================================================== --- libavformat/Makefile (revision 21510) +++ libavformat/Makefile (working copy) @@ -3,7 +3,7 @@ NAME = avformat FFLIBS = avcodec avutil -HEADERS = avformat.h avio.h +HEADERS = avformat.h avio.h network.h OBJS = allformats.o \ cutils.o \ Index: libavformat/avio.h =================================================================== --- libavformat/avio.h (revision 21510) +++ libavformat/avio.h (working copy) @@ -31,6 +31,7 @@ #include #include "libavutil/common.h" +/* #include "libavformat/network.h" - jez bookmark */ /* unbuffered I/O */ @@ -51,6 +52,13 @@ int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ void *priv_data; char *filename; /**< specified URL */ + /** + * Callback called just after getting a packet but before returning + * for processing in demuxers dealing with data over a network; can + * be used to accept/reject packets based on eg. source address. + * Return 0 to reject the packet, nonzero to accept it. + */ + int (*check_net_packet_callback)(struct sockaddr *srcaddress, uint8_t *buf, int buflen); } URLContext; typedef struct URLPollEntry {