• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/rtpenc.c

Go to the documentation of this file.
00001 /*
00002  * RTP output format
00003  * Copyright (c) 2002 Fabrice Bellard
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "libavcodec/bitstream.h"
00023 #include "avformat.h"
00024 #include "mpegts.h"
00025 
00026 #include <unistd.h>
00027 #include "network.h"
00028 
00029 #include "rtpenc.h"
00030 
00031 //#define DEBUG
00032 
00033 #define RTCP_SR_SIZE 28
00034 #define NTP_OFFSET 2208988800ULL
00035 #define NTP_OFFSET_US (NTP_OFFSET * 1000000ULL)
00036 
00037 static uint64_t ntp_time(void)
00038 {
00039   return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
00040 }
00041 
00042 static int rtp_write_header(AVFormatContext *s1)
00043 {
00044     RTPMuxContext *s = s1->priv_data;
00045     int payload_type, max_packet_size, n;
00046     AVStream *st;
00047 
00048     if (s1->nb_streams != 1)
00049         return -1;
00050     st = s1->streams[0];
00051 
00052     payload_type = ff_rtp_get_payload_type(st->codec);
00053     if (payload_type < 0)
00054         payload_type = RTP_PT_PRIVATE; /* private payload type */
00055     s->payload_type = payload_type;
00056 
00057 // following 2 FIXMEs could be set based on the current time, there is normally no info leak, as RTP will likely be transmitted immediately
00058     s->base_timestamp = 0; /* FIXME: was random(), what should this be? */
00059     s->timestamp = s->base_timestamp;
00060     s->cur_timestamp = 0;
00061     s->ssrc = 0; /* FIXME: was random(), what should this be? */
00062     s->first_packet = 1;
00063     s->first_rtcp_ntp_time = AV_NOPTS_VALUE;
00064 
00065     max_packet_size = url_fget_max_packet_size(s1->pb);
00066     if (max_packet_size <= 12)
00067         return AVERROR(EIO);
00068     s->buf = av_malloc(max_packet_size);
00069     if (s->buf == NULL) {
00070         return AVERROR(ENOMEM);
00071     }
00072     s->max_payload_size = max_packet_size - 12;
00073 
00074     s->max_frames_per_packet = 0;
00075     if (s1->max_delay) {
00076         if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
00077             if (st->codec->frame_size == 0) {
00078                 av_log(s1, AV_LOG_ERROR, "Cannot respect max delay: frame size = 0\n");
00079             } else {
00080                 s->max_frames_per_packet = av_rescale_rnd(s1->max_delay, st->codec->sample_rate, AV_TIME_BASE * st->codec->frame_size, AV_ROUND_DOWN);
00081             }
00082         }
00083         if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
00084             /* FIXME: We should round down here... */
00085             s->max_frames_per_packet = av_rescale_q(s1->max_delay, (AVRational){1, 1000000}, st->codec->time_base);
00086         }
00087     }
00088 
00089     av_set_pts_info(st, 32, 1, 90000);
00090     switch(st->codec->codec_id) {
00091     case CODEC_ID_MP2:
00092     case CODEC_ID_MP3:
00093         s->buf_ptr = s->buf + 4;
00094         break;
00095     case CODEC_ID_MPEG1VIDEO:
00096     case CODEC_ID_MPEG2VIDEO:
00097         break;
00098     case CODEC_ID_MPEG2TS:
00099         n = s->max_payload_size / TS_PACKET_SIZE;
00100         if (n < 1)
00101             n = 1;
00102         s->max_payload_size = n * TS_PACKET_SIZE;
00103         s->buf_ptr = s->buf;
00104         break;
00105     case CODEC_ID_AAC:
00106         s->num_frames = 0;
00107     default:
00108         if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
00109             av_set_pts_info(st, 32, 1, st->codec->sample_rate);
00110         }
00111         s->buf_ptr = s->buf;
00112         break;
00113     }
00114 
00115     return 0;
00116 }
00117 
00118 /* send an rtcp sender report packet */
00119 static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time)
00120 {
00121     RTPMuxContext *s = s1->priv_data;
00122     uint32_t rtp_ts;
00123 
00124     dprintf(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp);
00125 
00126     if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) s->first_rtcp_ntp_time = ntp_time;
00127     s->last_rtcp_ntp_time = ntp_time;
00128     rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000},
00129                           s1->streams[0]->time_base) + s->base_timestamp;
00130     put_byte(s1->pb, (RTP_VERSION << 6));
00131     put_byte(s1->pb, 200);
00132     put_be16(s1->pb, 6); /* length in words - 1 */
00133     put_be32(s1->pb, s->ssrc);
00134     put_be32(s1->pb, ntp_time / 1000000);
00135     put_be32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000);
00136     put_be32(s1->pb, rtp_ts);
00137     put_be32(s1->pb, s->packet_count);
00138     put_be32(s1->pb, s->octet_count);
00139     put_flush_packet(s1->pb);
00140 }
00141 
00142 /* send an rtp packet. sequence number is incremented, but the caller
00143    must update the timestamp itself */
00144 void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
00145 {
00146     RTPMuxContext *s = s1->priv_data;
00147 
00148     dprintf(s1, "rtp_send_data size=%d\n", len);
00149 
00150     /* build the RTP header */
00151     put_byte(s1->pb, (RTP_VERSION << 6));
00152     put_byte(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
00153     put_be16(s1->pb, s->seq);
00154     put_be32(s1->pb, s->timestamp);
00155     put_be32(s1->pb, s->ssrc);
00156 
00157     put_buffer(s1->pb, buf1, len);
00158     put_flush_packet(s1->pb);
00159 
00160     s->seq++;
00161     s->octet_count += len;
00162     s->packet_count++;
00163 }
00164 
00165 /* send an integer number of samples and compute time stamp and fill
00166    the rtp send buffer before sending. */
00167 static void rtp_send_samples(AVFormatContext *s1,
00168                              const uint8_t *buf1, int size, int sample_size)
00169 {
00170     RTPMuxContext *s = s1->priv_data;
00171     int len, max_packet_size, n;
00172 
00173     max_packet_size = (s->max_payload_size / sample_size) * sample_size;
00174     /* not needed, but who nows */
00175     if ((size % sample_size) != 0)
00176         av_abort();
00177     n = 0;
00178     while (size > 0) {
00179         s->buf_ptr = s->buf;
00180         len = FFMIN(max_packet_size, size);
00181 
00182         /* copy data */
00183         memcpy(s->buf_ptr, buf1, len);
00184         s->buf_ptr += len;
00185         buf1 += len;
00186         size -= len;
00187         s->timestamp = s->cur_timestamp + n / sample_size;
00188         ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
00189         n += (s->buf_ptr - s->buf);
00190     }
00191 }
00192 
00193 /* NOTE: we suppose that exactly one frame is given as argument here */
00194 /* XXX: test it */
00195 static void rtp_send_mpegaudio(AVFormatContext *s1,
00196                                const uint8_t *buf1, int size)
00197 {
00198     RTPMuxContext *s = s1->priv_data;
00199     int len, count, max_packet_size;
00200 
00201     max_packet_size = s->max_payload_size;
00202 
00203     /* test if we must flush because not enough space */
00204     len = (s->buf_ptr - s->buf);
00205     if ((len + size) > max_packet_size) {
00206         if (len > 4) {
00207             ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
00208             s->buf_ptr = s->buf + 4;
00209         }
00210     }
00211     if (s->buf_ptr == s->buf + 4) {
00212         s->timestamp = s->cur_timestamp;
00213     }
00214 
00215     /* add the packet */
00216     if (size > max_packet_size) {
00217         /* big packet: fragment */
00218         count = 0;
00219         while (size > 0) {
00220             len = max_packet_size - 4;
00221             if (len > size)
00222                 len = size;
00223             /* build fragmented packet */
00224             s->buf[0] = 0;
00225             s->buf[1] = 0;
00226             s->buf[2] = count >> 8;
00227             s->buf[3] = count;
00228             memcpy(s->buf + 4, buf1, len);
00229             ff_rtp_send_data(s1, s->buf, len + 4, 0);
00230             size -= len;
00231             buf1 += len;
00232             count += len;
00233         }
00234     } else {
00235         if (s->buf_ptr == s->buf + 4) {
00236             /* no fragmentation possible */
00237             s->buf[0] = 0;
00238             s->buf[1] = 0;
00239             s->buf[2] = 0;
00240             s->buf[3] = 0;
00241         }
00242         memcpy(s->buf_ptr, buf1, size);
00243         s->buf_ptr += size;
00244     }
00245 }
00246 
00247 static void rtp_send_raw(AVFormatContext *s1,
00248                          const uint8_t *buf1, int size)
00249 {
00250     RTPMuxContext *s = s1->priv_data;
00251     int len, max_packet_size;
00252 
00253     max_packet_size = s->max_payload_size;
00254 
00255     while (size > 0) {
00256         len = max_packet_size;
00257         if (len > size)
00258             len = size;
00259 
00260         s->timestamp = s->cur_timestamp;
00261         ff_rtp_send_data(s1, buf1, len, (len == size));
00262 
00263         buf1 += len;
00264         size -= len;
00265     }
00266 }
00267 
00268 /* NOTE: size is assumed to be an integer multiple of TS_PACKET_SIZE */
00269 static void rtp_send_mpegts_raw(AVFormatContext *s1,
00270                                 const uint8_t *buf1, int size)
00271 {
00272     RTPMuxContext *s = s1->priv_data;
00273     int len, out_len;
00274 
00275     while (size >= TS_PACKET_SIZE) {
00276         len = s->max_payload_size - (s->buf_ptr - s->buf);
00277         if (len > size)
00278             len = size;
00279         memcpy(s->buf_ptr, buf1, len);
00280         buf1 += len;
00281         size -= len;
00282         s->buf_ptr += len;
00283 
00284         out_len = s->buf_ptr - s->buf;
00285         if (out_len >= s->max_payload_size) {
00286             ff_rtp_send_data(s1, s->buf, out_len, 0);
00287             s->buf_ptr = s->buf;
00288         }
00289     }
00290 }
00291 
00292 /* write an RTP packet. 'buf1' must contain a single specific frame. */
00293 static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
00294 {
00295     RTPMuxContext *s = s1->priv_data;
00296     AVStream *st = s1->streams[0];
00297     int rtcp_bytes;
00298     int size= pkt->size;
00299     uint8_t *buf1= pkt->data;
00300 
00301     dprintf(s1, "%d: write len=%d\n", pkt->stream_index, size);
00302 
00303     rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) /
00304         RTCP_TX_RATIO_DEN;
00305     if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) &&
00306                            (ntp_time() - s->last_rtcp_ntp_time > 5000000))) {
00307         rtcp_send_sr(s1, ntp_time());
00308         s->last_octet_count = s->octet_count;
00309         s->first_packet = 0;
00310     }
00311     s->cur_timestamp = s->base_timestamp + pkt->pts;
00312 
00313     switch(st->codec->codec_id) {
00314     case CODEC_ID_PCM_MULAW:
00315     case CODEC_ID_PCM_ALAW:
00316     case CODEC_ID_PCM_U8:
00317     case CODEC_ID_PCM_S8:
00318         rtp_send_samples(s1, buf1, size, 1 * st->codec->channels);
00319         break;
00320     case CODEC_ID_PCM_U16BE:
00321     case CODEC_ID_PCM_U16LE:
00322     case CODEC_ID_PCM_S16BE:
00323     case CODEC_ID_PCM_S16LE:
00324         rtp_send_samples(s1, buf1, size, 2 * st->codec->channels);
00325         break;
00326     case CODEC_ID_MP2:
00327     case CODEC_ID_MP3:
00328         rtp_send_mpegaudio(s1, buf1, size);
00329         break;
00330     case CODEC_ID_MPEG1VIDEO:
00331     case CODEC_ID_MPEG2VIDEO:
00332         ff_rtp_send_mpegvideo(s1, buf1, size);
00333         break;
00334     case CODEC_ID_AAC:
00335         ff_rtp_send_aac(s1, buf1, size);
00336         break;
00337     case CODEC_ID_MPEG2TS:
00338         rtp_send_mpegts_raw(s1, buf1, size);
00339         break;
00340     case CODEC_ID_H264:
00341         ff_rtp_send_h264(s1, buf1, size);
00342         break;
00343     default:
00344         /* better than nothing : send the codec raw data */
00345         rtp_send_raw(s1, buf1, size);
00346         break;
00347     }
00348     return 0;
00349 }
00350 
00351 static int rtp_write_trailer(AVFormatContext *s1)
00352 {
00353     RTPMuxContext *s = s1->priv_data;
00354 
00355     av_freep(&s->buf);
00356 
00357     return 0;
00358 }
00359 
00360 AVOutputFormat rtp_muxer = {
00361     "rtp",
00362     NULL_IF_CONFIG_SMALL("RTP output format"),
00363     NULL,
00364     NULL,
00365     sizeof(RTPMuxContext),
00366     CODEC_ID_PCM_MULAW,
00367     CODEC_ID_NONE,
00368     rtp_write_header,
00369     rtp_write_packet,
00370     rtp_write_trailer,
00371 };

Generated on Tue Nov 4 2014 12:59:24 for ffmpeg by  doxygen 1.7.1