X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Frtpenc.c;h=633ce2995cd401dbbf022d12b9dcd50b11794628;hb=d8b91fae1df740eae4e1fd65fda09fbe650d4c1a;hp=511c0bd5bcd1cb61bc54a9d58fe2ec225b43e4ca;hpb=9edfaf3c6c726600559ad9df07f3d3331e157f6e;p=ffmpeg diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 511c0bd5bcd..633ce2995cd 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -19,25 +19,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavcodec/bitstream.h" #include "avformat.h" #include "mpegts.h" +#include "internal.h" #include -#include "network.h" #include "rtpenc.h" //#define DEBUG #define RTCP_SR_SIZE 28 -#define NTP_OFFSET 2208988800ULL -#define NTP_OFFSET_US (NTP_OFFSET * 1000000ULL) - -static uint64_t ntp_time(void) -{ - return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US; -} static int is_supported(enum CodecID id) { @@ -60,6 +52,8 @@ static int is_supported(enum CodecID id) case CODEC_ID_PCM_U16LE: case CODEC_ID_PCM_U8: case CODEC_ID_MPEG2TS: + case CODEC_ID_AMR_NB: + case CODEC_ID_AMR_WB: return 1; default: return 0; @@ -69,7 +63,7 @@ static int is_supported(enum CodecID id) static int rtp_write_header(AVFormatContext *s1) { RTPMuxContext *s = s1->priv_data; - int payload_type, max_packet_size, n; + int max_packet_size, n; AVStream *st; if (s1->nb_streams != 1) @@ -81,10 +75,9 @@ static int rtp_write_header(AVFormatContext *s1) return -1; } - payload_type = ff_rtp_get_payload_type(st->codec); - if (payload_type < 0) - payload_type = RTP_PT_PRIVATE; /* private payload type */ - s->payload_type = payload_type; + s->payload_type = ff_rtp_get_payload_type(st->codec); + if (s->payload_type < 0) + s->payload_type = RTP_PT_PRIVATE + (st->codec->codec_type == CODEC_TYPE_AUDIO); // following 2 FIXMEs could be set based on the current time, there is normally no info leak, as RTP will likely be transmitted immediately s->base_timestamp = 0; /* FIXME: was random(), what should this be? */ @@ -92,7 +85,7 @@ static int rtp_write_header(AVFormatContext *s1) s->cur_timestamp = 0; s->ssrc = 0; /* FIXME: was random(), what should this be? */ s->first_packet = 1; - s->first_rtcp_ntp_time = AV_NOPTS_VALUE; + s->first_rtcp_ntp_time = ff_ntp_time(); max_packet_size = url_fget_max_packet_size(s1->pb); if (max_packet_size <= 12) @@ -134,6 +127,23 @@ static int rtp_write_header(AVFormatContext *s1) s->max_payload_size = n * TS_PACKET_SIZE; s->buf_ptr = s->buf; break; + case CODEC_ID_AMR_NB: + case CODEC_ID_AMR_WB: + if (!s->max_frames_per_packet) + s->max_frames_per_packet = 12; + if (st->codec->codec_id == CODEC_ID_AMR_NB) + n = 31; + else + n = 61; + /* max_header_toc_size + the largest AMR payload must fit */ + if (1 + s->max_frames_per_packet + n > s->max_payload_size) { + av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for AMR\n"); + return -1; + } + if (st->codec->channels != 1) { + av_log(s1, AV_LOG_ERROR, "Only mono is supported\n"); + return -1; + } case CODEC_ID_AAC: s->num_frames = 0; default: @@ -155,7 +165,6 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time) dprintf(s1, "RTCP: %02x %"PRIx64" %x\n", s->payload_type, ntp_time, s->timestamp); - if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) s->first_rtcp_ntp_time = ntp_time; s->last_rtcp_ntp_time = ntp_time; rtp_ts = av_rescale_q(ntp_time - s->first_rtcp_ntp_time, (AVRational){1, 1000000}, s1->streams[0]->time_base) + s->base_timestamp; @@ -222,8 +231,6 @@ static void rtp_send_samples(AVFormatContext *s1, } } -/* NOTE: we suppose that exactly one frame is given as argument here */ -/* XXX: test it */ static void rtp_send_mpegaudio(AVFormatContext *s1, const uint8_t *buf1, int size) { @@ -321,22 +328,20 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1, } } -/* write an RTP packet. 'buf1' must contain a single specific frame. */ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) { RTPMuxContext *s = s1->priv_data; AVStream *st = s1->streams[0]; int rtcp_bytes; int size= pkt->size; - uint8_t *buf1= pkt->data; dprintf(s1, "%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; if (s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) && - (ntp_time() - s->last_rtcp_ntp_time > 5000000))) { - rtcp_send_sr(s1, ntp_time()); + (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) { + rtcp_send_sr(s1, ff_ntp_time()); s->last_octet_count = s->octet_count; s->first_packet = 0; } @@ -347,38 +352,42 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) case CODEC_ID_PCM_ALAW: case CODEC_ID_PCM_U8: case CODEC_ID_PCM_S8: - rtp_send_samples(s1, buf1, size, 1 * st->codec->channels); + rtp_send_samples(s1, pkt->data, size, 1 * st->codec->channels); break; case CODEC_ID_PCM_U16BE: case CODEC_ID_PCM_U16LE: case CODEC_ID_PCM_S16BE: case CODEC_ID_PCM_S16LE: - rtp_send_samples(s1, buf1, size, 2 * st->codec->channels); + rtp_send_samples(s1, pkt->data, size, 2 * st->codec->channels); break; case CODEC_ID_MP2: case CODEC_ID_MP3: - rtp_send_mpegaudio(s1, buf1, size); + rtp_send_mpegaudio(s1, pkt->data, size); break; case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: - ff_rtp_send_mpegvideo(s1, buf1, size); + ff_rtp_send_mpegvideo(s1, pkt->data, size); break; case CODEC_ID_AAC: - ff_rtp_send_aac(s1, buf1, size); + ff_rtp_send_aac(s1, pkt->data, size); + break; + case CODEC_ID_AMR_NB: + case CODEC_ID_AMR_WB: + ff_rtp_send_amr(s1, pkt->data, size); break; case CODEC_ID_MPEG2TS: - rtp_send_mpegts_raw(s1, buf1, size); + rtp_send_mpegts_raw(s1, pkt->data, size); break; case CODEC_ID_H264: - ff_rtp_send_h264(s1, buf1, size); + ff_rtp_send_h264(s1, pkt->data, size); break; case CODEC_ID_H263: case CODEC_ID_H263P: - ff_rtp_send_h263(s1, buf1, size); + ff_rtp_send_h263(s1, pkt->data, size); break; default: /* better than nothing : send the codec raw data */ - rtp_send_raw(s1, buf1, size); + rtp_send_raw(s1, pkt->data, size); break; } return 0;