]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/rtpenc.c
copy_block: Change type of array stride parameters to ptrdiff_t
[ffmpeg] / libavformat / rtpenc.c
index 647a8073b7f5b570fc2debd2bd7764437b45bb60..2cae839e583adbe51dfcb963de1367817530552e 100644 (file)
@@ -49,6 +49,7 @@ static const AVClass rtp_muxer_class = {
 static int is_supported(enum AVCodecID id)
 {
     switch(id) {
+    case AV_CODEC_ID_H261:
     case AV_CODEC_ID_H263:
     case AV_CODEC_ID_H263P:
     case AV_CODEC_ID_H264:
@@ -88,7 +89,7 @@ static int is_supported(enum AVCodecID id)
 static int rtp_write_header(AVFormatContext *s1)
 {
     RTPMuxContext *s = s1->priv_data;
-    int n;
+    int n, ret = AVERROR(EINVAL);
     AVStream *st;
 
     if (s1->nb_streams != 1) {
@@ -96,8 +97,8 @@ static int rtp_write_header(AVFormatContext *s1)
         return AVERROR(EINVAL);
     }
     st = s1->streams[0];
-    if (!is_supported(st->codec->codec_id)) {
-        av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codec->codec_id);
+    if (!is_supported(st->codecpar->codec_id)) {
+        av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codecpar->codec_id);
 
         return -1;
     }
@@ -105,7 +106,7 @@ static int rtp_write_header(AVFormatContext *s1)
     if (s->payload_type < 0) {
         /* Re-validate non-dynamic payload types */
         if (st->id < RTP_PT_PRIVATE)
-            st->id = ff_rtp_get_payload_type(s1, st->codec, -1);
+            st->id = ff_rtp_get_payload_type(s1, st->codecpar, -1);
 
         s->payload_type = st->id;
     } else {
@@ -148,38 +149,17 @@ static int rtp_write_header(AVFormatContext *s1)
     }
     s->max_payload_size = s1->packet_size - 12;
 
-    s->max_frames_per_packet = 0;
-    if (s1->max_delay > 0) {
-        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-            int frame_size = av_get_audio_frame_duration(st->codec, 0);
-            if (!frame_size)
-                frame_size = st->codec->frame_size;
-            if (frame_size == 0) {
-                av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n");
-            } else {
-                s->max_frames_per_packet =
-                        av_rescale_q_rnd(s1->max_delay,
-                                         AV_TIME_BASE_Q,
-                                         (AVRational){ frame_size, st->codec->sample_rate },
-                                         AV_ROUND_DOWN);
-            }
-        }
-        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-            /* FIXME: We should round down here... */
-            if (st->avg_frame_rate.num > 0 && st->avg_frame_rate.den > 0) {
-                s->max_frames_per_packet = av_rescale_q(s1->max_delay,
-                                                        (AVRational){1, 1000000},
-                                                        av_inv_q(st->avg_frame_rate));
-            } else
-                s->max_frames_per_packet = 1;
-        }
+    if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+        avpriv_set_pts_info(st, 32, 1, st->codecpar->sample_rate);
+    } else {
+        avpriv_set_pts_info(st, 32, 1, 90000);
     }
-
-    avpriv_set_pts_info(st, 32, 1, 90000);
-    switch(st->codec->codec_id) {
+    s->buf_ptr = s->buf;
+    switch(st->codecpar->codec_id) {
     case AV_CODEC_ID_MP2:
     case AV_CODEC_ID_MP3:
         s->buf_ptr = s->buf + 4;
+        avpriv_set_pts_info(st, 32, 1, 90000);
         break;
     case AV_CODEC_ID_MPEG1VIDEO:
     case AV_CODEC_ID_MPEG2VIDEO:
@@ -189,37 +169,44 @@ static int rtp_write_header(AVFormatContext *s1)
         if (n < 1)
             n = 1;
         s->max_payload_size = n * TS_PACKET_SIZE;
-        s->buf_ptr = s->buf;
+        break;
+    case AV_CODEC_ID_H261:
+        if (s1->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+            av_log(s, AV_LOG_ERROR,
+                   "Packetizing H.261 is experimental and produces incorrect "
+                   "packetization for cases where GOBs don't fit into packets "
+                   "(even though most receivers may handle it just fine). "
+                   "Please set -f_strict experimental in order to enable it.\n");
+            ret = AVERROR_EXPERIMENTAL;
+            goto fail;
+        }
         break;
     case AV_CODEC_ID_H264:
         /* check for H.264 MP4 syntax */
-        if (st->codec->extradata_size > 4 && st->codec->extradata[0] == 1) {
-            s->nal_length_size = (st->codec->extradata[4] & 0x03) + 1;
+        if (st->codecpar->extradata_size > 4 && st->codecpar->extradata[0] == 1) {
+            s->nal_length_size = (st->codecpar->extradata[4] & 0x03) + 1;
         }
         break;
     case AV_CODEC_ID_HEVC:
         /* Only check for the standardized hvcC version of extradata, keeping
-         * things simple and similar to the avcC/H264 case above, instead
+         * things simple and similar to the avcC/H.264 case above, instead
          * of trying to handle the pre-standardization versions (as in
          * libavcodec/hevc.c). */
-        if (st->codec->extradata_size > 21 && st->codec->extradata[0] == 1) {
-            s->nal_length_size = (st->codec->extradata[21] & 0x03) + 1;
+        if (st->codecpar->extradata_size > 21 && st->codecpar->extradata[0] == 1) {
+            s->nal_length_size = (st->codecpar->extradata[21] & 0x03) + 1;
         }
         break;
     case AV_CODEC_ID_VORBIS:
     case AV_CODEC_ID_THEORA:
-        if (!s->max_frames_per_packet) s->max_frames_per_packet = 15;
-        s->max_frames_per_packet = av_clip(s->max_frames_per_packet, 1, 15);
-        s->max_payload_size -= 6; // ident+frag+tdt/vdt+pkt_num+pkt_length
-        s->num_frames = 0;
-        goto defaultcase;
+        s->max_frames_per_packet = 15;
+        break;
     case AV_CODEC_ID_ADPCM_G722:
         /* Due to a historical error, the clock rate for G722 in RTP is
          * 8000, even if the sample rate is 16000. See RFC 3551. */
         avpriv_set_pts_info(st, 32, 1, 8000);
         break;
     case AV_CODEC_ID_OPUS:
-        if (st->codec->channels > 2) {
+        if (st->codecpar->channels > 2) {
             av_log(s1, AV_LOG_ERROR, "Multistream opus not supported in RTP\n");
             goto fail;
         }
@@ -229,20 +216,16 @@ static int rtp_write_header(AVFormatContext *s1)
         avpriv_set_pts_info(st, 32, 1, 48000);
         break;
     case AV_CODEC_ID_ILBC:
-        if (st->codec->block_align != 38 && st->codec->block_align != 50) {
+        if (st->codecpar->block_align != 38 && st->codecpar->block_align != 50) {
             av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n");
             goto fail;
         }
-        if (!s->max_frames_per_packet)
-            s->max_frames_per_packet = 1;
-        s->max_frames_per_packet = FFMIN(s->max_frames_per_packet,
-                                         s->max_payload_size / st->codec->block_align);
-        goto defaultcase;
+        s->max_frames_per_packet = s->max_payload_size / st->codecpar->block_align;
+        break;
     case AV_CODEC_ID_AMR_NB:
     case AV_CODEC_ID_AMR_WB:
-        if (!s->max_frames_per_packet)
-            s->max_frames_per_packet = 12;
-        if (st->codec->codec_id == AV_CODEC_ID_AMR_NB)
+        s->max_frames_per_packet = 50;
+        if (st->codecpar->codec_id == AV_CODEC_ID_AMR_NB)
             n = 31;
         else
             n = 61;
@@ -251,18 +234,15 @@ static int rtp_write_header(AVFormatContext *s1)
             av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n");
             goto fail;
         }
-        if (st->codec->channels != 1) {
+        if (st->codecpar->channels != 1) {
             av_log(s1, AV_LOG_ERROR, "Only mono is supported\n");
             goto fail;
         }
+        break;
     case AV_CODEC_ID_AAC:
-        s->num_frames = 0;
+        s->max_frames_per_packet = 50;
+        break;
     default:
-defaultcase:
-        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-            avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
-        }
-        s->buf_ptr = s->buf;
         break;
     }
 
@@ -270,7 +250,7 @@ defaultcase:
 
 fail:
     av_freep(&s->buf);
-    return AVERROR(EINVAL);
+    return ret;
 }
 
 /* send an rtcp sender report packet */
@@ -279,7 +259,7 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye)
     RTPMuxContext *s = s1->priv_data;
     uint32_t rtp_ts;
 
-    av_dlog(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
+    av_log(s1, AV_LOG_TRACE, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
 
     s->last_rtcp_ntp_time = ntp_time;
     rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000},
@@ -324,7 +304,7 @@ void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
 {
     RTPMuxContext *s = s1->priv_data;
 
-    av_dlog(s1, "rtp_send_data size=%d\n", len);
+    av_log(s1, AV_LOG_TRACE, "rtp_send_data size=%d\n", len);
 
     /* build the RTP header */
     avio_w8(s1->pb, RTP_VERSION << 6);
@@ -452,6 +432,7 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1,
     RTPMuxContext *s = s1->priv_data;
     int len, out_len;
 
+    s->timestamp = s->cur_timestamp;
     while (size >= TS_PACKET_SIZE) {
         len = s->max_payload_size - (s->buf_ptr - s->buf);
         if (len > size)
@@ -473,23 +454,28 @@ static int rtp_send_ilbc(AVFormatContext *s1, const uint8_t *buf, int size)
 {
     RTPMuxContext *s = s1->priv_data;
     AVStream *st = s1->streams[0];
-    int frame_duration = av_get_audio_frame_duration(st->codec, 0);
-    int frame_size = st->codec->block_align;
+    int frame_duration = av_get_audio_frame_duration2(st->codecpar, 0);
+    int frame_size = st->codecpar->block_align;
     int frames = size / frame_size;
 
     while (frames > 0) {
-        int n = FFMIN(s->max_frames_per_packet - s->num_frames, frames);
+        if (s->num_frames > 0 &&
+            av_compare_ts(s->cur_timestamp - s->timestamp, st->time_base,
+                          s1->max_delay, AV_TIME_BASE_Q) >= 0) {
+            ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1);
+            s->num_frames = 0;
+        }
 
         if (!s->num_frames) {
             s->buf_ptr = s->buf;
             s->timestamp = s->cur_timestamp;
         }
-        memcpy(s->buf_ptr, buf, n * frame_size);
-        frames           -= n;
-        s->num_frames    += n;
-        s->buf_ptr       += n * frame_size;
-        buf              += n * frame_size;
-        s->cur_timestamp += n * frame_duration;
+        memcpy(s->buf_ptr, buf, frame_size);
+        frames--;
+        s->num_frames++;
+        s->buf_ptr       += frame_size;
+        buf              += frame_size;
+        s->cur_timestamp += frame_duration;
 
         if (s->num_frames == s->max_frames_per_packet) {
             ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1);
@@ -506,7 +492,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
     int rtcp_bytes;
     int size= pkt->size;
 
-    av_dlog(s1, "%d: write len=%d\n", pkt->stream_index, size);
+    av_log(s1, AV_LOG_TRACE, "%d: write len=%d\n", pkt->stream_index, size);
 
     rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
         RTCP_TX_RATIO_DEN;
@@ -519,26 +505,26 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
     }
     s->cur_timestamp = s->base_timestamp + pkt->pts;
 
-    switch(st->codec->codec_id) {
+    switch(st->codecpar->codec_id) {
     case AV_CODEC_ID_PCM_MULAW:
     case AV_CODEC_ID_PCM_ALAW:
     case AV_CODEC_ID_PCM_U8:
     case AV_CODEC_ID_PCM_S8:
-        return rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels);
+        return rtp_send_samples(s1, pkt->data, size, 8 * st->codecpar->channels);
     case AV_CODEC_ID_PCM_U16BE:
     case AV_CODEC_ID_PCM_U16LE:
     case AV_CODEC_ID_PCM_S16BE:
     case AV_CODEC_ID_PCM_S16LE:
-        return rtp_send_samples(s1, pkt->data, size, 16 * st->codec->channels);
+        return rtp_send_samples(s1, pkt->data, size, 16 * st->codecpar->channels);
     case AV_CODEC_ID_ADPCM_G722:
         /* The actual sample size is half a byte per sample, but since the
          * stream clock rate is 8000 Hz while the sample rate is 16000 Hz,
          * the correct parameter for send_samples_bits is 8 bits per stream
          * clock. */
-        return rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels);
+        return rtp_send_samples(s1, pkt->data, size, 8 * st->codecpar->channels);
     case AV_CODEC_ID_ADPCM_G726:
         return rtp_send_samples(s1, pkt->data, size,
-                                st->codec->bits_per_coded_sample * st->codec->channels);
+                                st->codecpar->bits_per_coded_sample * st->codecpar->channels);
     case AV_CODEC_ID_MP2:
     case AV_CODEC_ID_MP3:
         rtp_send_mpegaudio(s1, pkt->data, size);
@@ -561,7 +547,10 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
         rtp_send_mpegts_raw(s1, pkt->data, size);
         break;
     case AV_CODEC_ID_H264:
-        ff_rtp_send_h264(s1, pkt->data, size);
+        ff_rtp_send_h264_hevc(s1, pkt->data, size);
+        break;
+    case AV_CODEC_ID_H261:
+        ff_rtp_send_h261(s1, pkt->data, size);
         break;
     case AV_CODEC_ID_H263:
         if (s->flags & FF_RTP_FLAG_RFC2190) {
@@ -577,7 +566,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
         ff_rtp_send_h263(s1, pkt->data, size);
         break;
     case AV_CODEC_ID_HEVC:
-        ff_rtp_send_hevc(s1, pkt->data, size);
+        ff_rtp_send_h264_hevc(s1, pkt->data, size);
         break;
     case AV_CODEC_ID_VORBIS:
     case AV_CODEC_ID_THEORA:
@@ -631,4 +620,5 @@ AVOutputFormat ff_rtp_muxer = {
     .write_packet      = rtp_write_packet,
     .write_trailer     = rtp_write_trailer,
     .priv_class        = &rtp_muxer_class,
+    .flags             = AVFMT_TS_NONSTRICT,
 };