yading@11: /* yading@11: * RTP demuxer definitions yading@11: * Copyright (c) 2002 Fabrice Bellard yading@11: * Copyright (c) 2006 Ryan Martell yading@11: * yading@11: * This file is part of FFmpeg. yading@11: * yading@11: * FFmpeg is free software; you can redistribute it and/or yading@11: * modify it under the terms of the GNU Lesser General Public yading@11: * License as published by the Free Software Foundation; either yading@11: * version 2.1 of the License, or (at your option) any later version. yading@11: * yading@11: * FFmpeg is distributed in the hope that it will be useful, yading@11: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@11: * Lesser General Public License for more details. yading@11: * yading@11: * You should have received a copy of the GNU Lesser General Public yading@11: * License along with FFmpeg; if not, write to the Free Software yading@11: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@11: */ yading@11: yading@11: #ifndef AVFORMAT_RTPDEC_H yading@11: #define AVFORMAT_RTPDEC_H yading@11: yading@11: #include "libavcodec/avcodec.h" yading@11: #include "avformat.h" yading@11: #include "rtp.h" yading@11: #include "url.h" yading@11: #include "srtp.h" yading@11: yading@11: typedef struct PayloadContext PayloadContext; yading@11: typedef struct RTPDynamicProtocolHandler RTPDynamicProtocolHandler; yading@11: yading@11: #define RTP_MIN_PACKET_LENGTH 12 yading@11: #define RTP_MAX_PACKET_LENGTH 8192 yading@11: yading@11: #define RTP_REORDER_QUEUE_DEFAULT_SIZE 10 yading@11: yading@11: #define RTP_NOTS_VALUE ((uint32_t)-1) yading@11: yading@11: typedef struct RTPDemuxContext RTPDemuxContext; yading@11: RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, yading@11: int payload_type, int queue_size); yading@11: void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx, yading@11: RTPDynamicProtocolHandler *handler); yading@11: void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite, yading@11: const char *params); yading@11: int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, yading@11: uint8_t **buf, int len); yading@11: void ff_rtp_parse_close(RTPDemuxContext *s); yading@11: int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s); yading@11: void ff_rtp_reset_packet_queue(RTPDemuxContext *s); yading@11: int ff_rtp_get_local_rtp_port(URLContext *h); yading@11: int ff_rtp_get_local_rtcp_port(URLContext *h); yading@11: yading@11: int ff_rtp_set_remote_url(URLContext *h, const char *uri); yading@11: yading@11: /** yading@11: * Send a dummy packet on both port pairs to set up the connection yading@11: * state in potential NAT routers, so that we're able to receive yading@11: * packets. yading@11: * yading@11: * Note, this only works if the NAT router doesn't remap ports. This yading@11: * isn't a standardized procedure, but it works in many cases in practice. yading@11: * yading@11: * The same routine is used with RDT too, even if RDT doesn't use normal yading@11: * RTP packets otherwise. yading@11: */ yading@11: void ff_rtp_send_punch_packets(URLContext* rtp_handle); yading@11: yading@11: /** yading@11: * some rtp servers assume client is dead if they don't hear from them... yading@11: * so we send a Receiver Report to the provided URLContext or AVIOContext yading@11: * (we don't have access to the rtcp handle from here) yading@11: */ yading@11: int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd, yading@11: AVIOContext *avio, int count); yading@11: int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd, yading@11: AVIOContext *avio); yading@11: yading@11: // these statistics are used for rtcp receiver reports... yading@11: typedef struct RTPStatistics { yading@11: uint16_t max_seq; ///< highest sequence number seen yading@11: uint32_t cycles; ///< shifted count of sequence number cycles yading@11: uint32_t base_seq; ///< base sequence number yading@11: uint32_t bad_seq; ///< last bad sequence number + 1 yading@11: int probation; ///< sequence packets till source is valid yading@11: uint32_t received; ///< packets received yading@11: uint32_t expected_prior; ///< packets expected in last interval yading@11: uint32_t received_prior; ///< packets received in last interval yading@11: uint32_t transit; ///< relative transit time for previous packet yading@11: uint32_t jitter; ///< estimated jitter. yading@11: } RTPStatistics; yading@11: yading@11: #define RTP_FLAG_KEY 0x1 ///< RTP packet contains a keyframe yading@11: #define RTP_FLAG_MARKER 0x2 ///< RTP marker bit was set for this packet yading@11: /** yading@11: * Packet parsing for "private" payloads in the RTP specs. yading@11: * yading@11: * @param ctx RTSP demuxer context yading@11: * @param s stream context yading@11: * @param st stream that this packet belongs to yading@11: * @param pkt packet in which to write the parsed data yading@11: * @param timestamp pointer to the RTP timestamp of the input data, can be yading@11: * updated by the function if returning older, buffered data yading@11: * @param buf pointer to raw RTP packet data yading@11: * @param len length of buf yading@11: * @param seq RTP sequence number of the packet yading@11: * @param flags flags from the RTP packet header (RTP_FLAG_*) yading@11: */ yading@11: typedef int (*DynamicPayloadPacketHandlerProc)(AVFormatContext *ctx, yading@11: PayloadContext *s, yading@11: AVStream *st, AVPacket *pkt, yading@11: uint32_t *timestamp, yading@11: const uint8_t * buf, yading@11: int len, uint16_t seq, int flags); yading@11: yading@11: struct RTPDynamicProtocolHandler { yading@11: const char enc_name[50]; yading@11: enum AVMediaType codec_type; yading@11: enum AVCodecID codec_id; yading@11: int static_payload_id; /* 0 means no payload id is set. 0 is a valid yading@11: * payload ID (PCMU), too, but that format doesn't yading@11: * require any custom depacketization code. */ yading@11: yading@11: /** Initialize dynamic protocol handler, called after the full rtpmap line is parsed, may be null */ yading@11: int (*init)(AVFormatContext *s, int st_index, PayloadContext *priv_data); yading@11: /** Parse the a= line from the sdp field */ yading@11: int (*parse_sdp_a_line)(AVFormatContext *s, int st_index, yading@11: PayloadContext *priv_data, const char *line); yading@11: /** Allocate any data needed by the rtp parsing for this dynamic data. */ yading@11: PayloadContext *(*alloc)(void); yading@11: /** Free any data needed by the rtp parsing for this dynamic data. */ yading@11: void (*free)(PayloadContext *protocol_data); yading@11: /** Parse handler for this dynamic packet */ yading@11: DynamicPayloadPacketHandlerProc parse_packet; yading@11: int (*need_keyframe)(PayloadContext *context); yading@11: yading@11: struct RTPDynamicProtocolHandler *next; yading@11: }; yading@11: yading@11: typedef struct RTPPacket { yading@11: uint16_t seq; yading@11: uint8_t *buf; yading@11: int len; yading@11: int64_t recvtime; yading@11: struct RTPPacket *next; yading@11: } RTPPacket; yading@11: yading@11: struct RTPDemuxContext { yading@11: AVFormatContext *ic; yading@11: AVStream *st; yading@11: int payload_type; yading@11: uint32_t ssrc; yading@11: uint16_t seq; yading@11: uint32_t timestamp; yading@11: uint32_t base_timestamp; yading@11: uint32_t cur_timestamp; yading@11: int64_t unwrapped_timestamp; yading@11: int64_t range_start_offset; yading@11: int max_payload_size; yading@11: /* used to send back RTCP RR */ yading@11: char hostname[256]; yading@11: yading@11: int srtp_enabled; yading@11: struct SRTPContext srtp; yading@11: yading@11: /** Statistics for this stream (used by RTCP receiver reports) */ yading@11: RTPStatistics statistics; yading@11: yading@11: /** Fields for packet reordering @{ */ yading@11: int prev_ret; ///< The return value of the actual parsing of the previous packet yading@11: RTPPacket* queue; ///< A sorted queue of buffered packets not yet returned yading@11: int queue_len; ///< The number of packets in queue yading@11: int queue_size; ///< The size of queue, or 0 if reordering is disabled yading@11: /*@}*/ yading@11: yading@11: /* rtcp sender statistics receive */ yading@11: int64_t last_rtcp_ntp_time; yading@11: int64_t last_rtcp_reception_time; yading@11: int64_t first_rtcp_ntp_time; yading@11: uint32_t last_rtcp_timestamp; yading@11: int64_t rtcp_ts_offset; yading@11: yading@11: /* rtcp sender statistics */ yading@11: unsigned int packet_count; yading@11: unsigned int octet_count; yading@11: unsigned int last_octet_count; yading@11: int64_t last_feedback_time; yading@11: yading@11: /* dynamic payload stuff */ yading@11: const RTPDynamicProtocolHandler *handler; yading@11: PayloadContext *dynamic_protocol_context; yading@11: }; yading@11: yading@11: void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler); yading@11: RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name, yading@11: enum AVMediaType codec_type); yading@11: RTPDynamicProtocolHandler *ff_rtp_handler_find_by_id(int id, yading@11: enum AVMediaType codec_type); yading@11: yading@11: /* from rtsp.c, but used by rtp dynamic protocol handlers. */ yading@11: int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, yading@11: char *value, int value_size); yading@11: yading@11: int ff_parse_fmtp(AVStream *stream, PayloadContext *data, const char *p, yading@11: int (*parse_fmtp)(AVStream *stream, yading@11: PayloadContext *data, yading@11: char *attr, char *value)); yading@11: yading@11: void av_register_rtp_dynamic_payload_handlers(void); yading@11: yading@11: /** yading@11: * Close the dynamic buffer and make a packet from it. yading@11: */ yading@11: int ff_rtp_finalize_packet(AVPacket *pkt, AVIOContext **dyn_buf, int stream_idx); yading@11: yading@11: #endif /* AVFORMAT_RTPDEC_H */