]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/rtpdec.c
mp3dec: read the initial/trailing padding from the LAME tag
[ffmpeg] / libavformat / rtpdec.c
index 76228be48dcfceb062a4afc2d80276b4edb3dbda..4eae626ad7c5f28ec1a5ec2a95c62efa447d5618 100644 (file)
@@ -21,8 +21,9 @@
 
 #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"
@@ -50,6 +51,12 @@ static RTPDynamicProtocolHandler opus_dynamic_handler = {
     .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)
@@ -60,12 +67,15 @@ void ff_register_dynamic_payload_handler(RTPDynamicProtocolHandler *handler)
 
 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);
@@ -76,6 +86,7 @@ void ff_register_rtp_dynamic_payload_handlers(void)
     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);
@@ -91,9 +102,11 @@ void ff_register_rtp_dynamic_payload_handlers(void)
     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,
@@ -102,7 +115,8 @@ 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;
@@ -130,19 +144,18 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf,
         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;
@@ -315,7 +328,7 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
         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 */
@@ -342,9 +355,9 @@ int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd,
     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;
@@ -440,7 +453,7 @@ int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
     /* 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;
@@ -484,7 +497,7 @@ int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,
 
 /**
  * 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)
@@ -500,14 +513,18 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st,
     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;
@@ -599,7 +616,7 @@ static int rtp_parse_packet_internal(RTPDemuxContext *s, AVPacket *pkt,
     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;
@@ -667,7 +684,7 @@ void ff_rtp_reset_packet_queue(RTPDemuxContext *s)
     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;
@@ -682,14 +699,16 @@ static void enqueue_packet(RTPDemuxContext *s, uint8_t *buf, int len)
 
     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)
@@ -711,7 +730,7 @@ static int rtp_parse_queued_packet(RTPDemuxContext *s, AVPacket *pkt)
         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 */
@@ -761,7 +780,7 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
     }
 
     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);
@@ -778,7 +797,7 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
         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) {
@@ -787,12 +806,16 @@ static int rtp_parse_one_packet(RTPDemuxContext *s, AVPacket *pkt,
             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;
         }
     }
@@ -815,7 +838,7 @@ int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
         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);
 }
@@ -832,7 +855,7 @@ int ff_parse_fmtp(AVFormatContext *s,
                   int (*parse_fmtp)(AVFormatContext *s,
                                     AVStream *stream,
                                     PayloadContext *data,
-                                    char *attr, char *value))
+                                    const char *attr, const char *value))
 {
     char attr[256];
     char *value;
@@ -840,7 +863,7 @@ int ff_parse_fmtp(AVFormatContext *s,
     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);
     }