#include "libavutil/mathematics.h"
#include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
#include "libavutil/time.h"
-#include "libavcodec/get_bits.h"
+
#include "avformat.h"
#include "network.h"
#include "srtp.h"
.codec_id = AV_CODEC_ID_OPUS,
};
+static RTPDynamicProtocolHandler t140_dynamic_handler = { /* RFC 4103 */
+ .enc_name = "t140",
+ .codec_type = AVMEDIA_TYPE_DATA,
+ .codec_id = AV_CODEC_ID_TEXT,
+};
+
static RTPDynamicProtocolHandler *rtp_first_dynamic_payload_handler = NULL;
void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
rtp_first_dynamic_payload_handler = handler;
}
-void av_register_rtp_dynamic_payload_handlers(void)
+void ff_register_rtp_dynamic_payload_handlers(void)
{
+ ff_register_dynamic_payload_handler(&ff_ac3_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_amr_nb_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_amr_wb_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_dv_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_g726_16_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_g726_24_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_g726_32_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_g726_40_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_h261_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h263_1998_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_hevc_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_jpeg_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mp4a_latm_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mp4v_es_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mpeg_audio_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_mpeg_audio_robust_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mpeg_video_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mpeg4_generic_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_mpegts_dynamic_handler);
- ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfa_handler);
+ ff_register_dynamic_payload_handler(&ff_ms_rtp_asf_pfv_handler);
ff_register_dynamic_payload_handler(&ff_qcelp_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_qt_rtp_aud_handler);
ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_vp8_dynamic_handler);
+ ff_register_dynamic_payload_handler(&ff_vp9_dynamic_handler);
ff_register_dynamic_payload_handler(&opus_dynamic_handler);
ff_register_dynamic_payload_handler(&realmedia_mp3_dynamic_handler);
ff_register_dynamic_payload_handler(&speex_dynamic_handler);
+ ff_register_dynamic_payload_handler(&t140_dynamic_handler);
}
RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
RTPDynamicProtocolHandler *handler;
for (handler = rtp_first_dynamic_payload_handler;
handler; handler = handler->next)
- if (!av_strcasecmp(name, handler->enc_name) &&
+ if (handler->enc_name &&
+ !av_strcasecmp(name, handler->enc_name) &&
codec_type == handler->codec_type)
return handler;
return NULL;
switch (buf[1]) {
case RTCP_SR:
if (payload_len < 20) {
- av_log(NULL, AV_LOG_ERROR,
- "Invalid length for RTCP SR packet\n");
+ av_log(s->ic, AV_LOG_ERROR, "Invalid RTCP SR packet length\n");
return AVERROR_INVALIDDATA;
}
- s->last_rtcp_reception_time = av_gettime();
+ s->last_rtcp_reception_time = av_gettime_relative();
s->last_rtcp_ntp_time = AV_RB64(buf + 8);
s->last_rtcp_timestamp = AV_RB32(buf + 16);
if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;
if (!s->base_timestamp)
s->base_timestamp = s->last_rtcp_timestamp;
- s->rtcp_ts_offset = s->last_rtcp_timestamp - s->base_timestamp;
+ s->rtcp_ts_offset = (int32_t)(s->last_rtcp_timestamp - s->base_timestamp);
}
break;
avio_wb32(pb, 0); /* delay since last SR */
} else {
uint32_t middle_32_bits = s->last_rtcp_ntp_time >> 16; // this is valid, right? do we need to handle 64 bit values special?
- uint32_t delay_since_last = av_rescale(av_gettime() - s->last_rtcp_reception_time,
+ uint32_t delay_since_last = av_rescale(av_gettime_relative() - s->last_rtcp_reception_time,
65536, AV_TIME_BASE);
avio_wb32(pb, middle_32_bits); /* last SR timestamp */
len = avio_close_dyn_buf(pb, &buf);
if ((len > 0) && buf) {
int av_unused result;
- av_dlog(s->ic, "sending %d bytes of RR\n", len);
+ av_log(s->ic, AV_LOG_TRACE, "sending %d bytes of RR\n", len);
result = ffurl_write(fd, buf, len);
- av_dlog(s->ic, "result from ffurl_write: %d\n", result);
+ av_log(s->ic, AV_LOG_TRACE, "result from ffurl_write: %d\n", result);
av_free(buf);
}
return 0;
AVIOContext *pb;
uint8_t *buf;
int64_t now;
- uint16_t first_missing, missing_mask;
+ uint16_t first_missing = 0, missing_mask = 0;
if (!fd && !avio)
return -1;
/* Send new feedback if enough time has elapsed since the last
* feedback packet. */
- now = av_gettime();
+ now = av_gettime_relative();
if (s->last_feedback_time &&
(now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)
return 0;
/**
* open a new RTP parse context for stream 'st'. 'st' can be NULL for
- * MPEG2-TS streams.
+ * MPEG-2 TS streams.
*/
RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
int payload_type, int queue_size)
s->ic = s1;
s->st = st;
s->queue_size = queue_size;
+
+ av_log(s->ic, AV_LOG_VERBOSE, "setting jitter buffer size to %d\n",
+ s->queue_size);
+
rtp_init_statistics(&s->statistics, 0);
if (st) {
- switch (st->codec->codec_id) {
+ switch (st->codecpar->codec_id) {
case AV_CODEC_ID_ADPCM_G722:
/* According to RFC 3551, the stream clock rate is 8000
* even if the sample rate is 16000. */
- if (st->codec->sample_rate == 8000)
- st->codec->sample_rate = 16000;
+ if (st->codecpar->sample_rate == 8000)
+ st->codecpar->sample_rate = 16000;
break;
default:
break;
st = s->st;
// only do something with this if all the rtp checks pass...
if (!rtp_valid_packet_in_sequence(&s->statistics, seq)) {
- av_log(st ? st->codec : NULL, AV_LOG_ERROR,
+ av_log(s->ic, AV_LOG_ERROR,
"RTP: PT=%02x: bad cseq %04x expected=%04x\n",
payload_type, seq, ((s->seq + 1) & 0xffff));
return -1;
s->prev_ret = 0;
}
-static void enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len)
+static int enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len)
{
uint16_t seq = AV_RB16(buf + 2);
RTPPacket **cur = &s->queue, *packet;
packet = av_mallocz(sizeof(*packet));
if (!packet)
- return;
- packet->recvtime = av_gettime();
+ return AVERROR(ENOMEM);
+ packet->recvtime = av_gettime_relative();
packet->seq = seq;
packet->len = len;
packet->buf = buf;
packet->next = *cur;
*cur = packet;
s->queue_len++;
+
+ return 0;
}
static int has_next_packet(RTPDemuxContext *s)
return -1;
if (!has_next_packet(s))
- av_log(s->st ? s->st->codec : NULL, AV_LOG_WARNING,
+ av_log(s->ic, AV_LOG_WARNING,
"RTP: missed %d packets\n", s->queue->seq - s->seq - 1);
/* Parse the first packet in the queue, and dequeue it */
}
if (s->st) {
- int64_t received = av_gettime();
+ int64_t received = av_gettime_relative();
uint32_t arrival_ts = av_rescale_q(received, AV_TIME_BASE_Q,
s->st->time_base);
timestamp = AV_RB32(buf + 4);
int16_t diff = seq - s->seq;
if (diff < 0) {
/* Packet older than the previously emitted one, drop */
- av_log(s->st ? s->st->codec : NULL, AV_LOG_WARNING,
+ av_log(s->ic, AV_LOG_WARNING,
"RTP: dropping old packet received too late\n");
return -1;
} else if (diff <= 1) {
return rv;
} else {
/* Still missing some packet, enqueue this one. */
- enqueue_packet(s, buf, len);
+ rv = enqueue_packet(s, buf, len);
+ if (rv < 0)
+ return rv;
*bufptr = NULL;
/* Return the first enqueued packet if the queue is full,
* even if we're missing something */
- if (s->queue_len >= s->queue_size)
+ if (s->queue_len >= s->queue_size) {
+ av_log(s->ic, AV_LOG_WARNING, "jitter buffer full\n");
return rtp_parse_queued_packet(s, pkt);
+ }
return -1;
}
}
return -1;
rv = rtp_parse_one_packet(s, pkt, bufptr, len);
s->prev_ret = rv;
- while (rv == AVERROR(EAGAIN) && has_next_packet(s))
+ while (rv < 0 && has_next_packet(s))
rv = rtp_parse_queued_packet(s, pkt);
return rv ? rv : has_next_packet(s);
}
av_free(s);
}
-int ff_parse_fmtp(AVStream *stream, PayloadContext *data, const char *p,
- int (*parse_fmtp)(AVStream *stream,
+int ff_parse_fmtp(AVFormatContext *s,
+ AVStream *stream, PayloadContext *data, const char *p,
+ int (*parse_fmtp)(AVFormatContext *s,
+ AVStream *stream,
PayloadContext *data,
- char *attr, char *value))
+ const char *attr, const char *value))
{
char attr[256];
char *value;
int value_size = strlen(p) + 1;
if (!(value = av_malloc(value_size))) {
- av_log(NULL, AV_LOG_ERROR, "Failed to allocate data for FMTP.");
+ av_log(s, AV_LOG_ERROR, "Failed to allocate data for FMTP.");
return AVERROR(ENOMEM);
}
while (ff_rtsp_next_attr_and_value(&p,
attr, sizeof(attr),
value, value_size)) {
- res = parse_fmtp(stream, data, attr, value);
+ res = parse_fmtp(s, stream, data, attr, value);
if (res < 0 && res != AVERROR_PATCHWELCOME) {
av_free(value);
return res;
int ff_rtp_finalize_packet(AVPacket *pkt, AVIOContext **dyn_buf, int stream_idx)
{
+ int ret;
av_init_packet(pkt);
pkt->size = avio_close_dyn_buf(*dyn_buf, &pkt->data);
pkt->stream_index = stream_idx;
- pkt->destruct = av_destruct_packet;
- *dyn_buf = NULL;
+ *dyn_buf = NULL;
+ if ((ret = av_packet_from_data(pkt, pkt->data, pkt->size)) < 0) {
+ av_freep(&pkt->data);
+ return ret;
+ }
return pkt->size;
}