1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 63047beccc..d59ec3dc8c 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -28,6 +28,8 @@
#include "rtpenc.h"
+#define EXT_ABS_SEND_TIME
+
static const AVOption options[] = {
FF_RTP_FLAG_OPTS(RTPMuxContext, flags),
{ "payload_type", "Specify RTP payload type", offsetof(RTPMuxContext, payload_type), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 127, AV_OPT_FLAG_ENCODING_PARAM },
@@ -146,7 +148,11 @@ static int rtp_write_header(AVFormatContext *s1)
s1->pb->max_packet_size);
} else
s1->packet_size = s1->pb->max_packet_size;
+#ifdef EXT_ABS_SEND_TIME
+ if (s1->packet_size <= 20) {
+#else
if (s1->packet_size <= 12) {
+#endif
av_log(s1, AV_LOG_ERROR, "Max packet size %u too low\n", s1->packet_size);
return AVERROR(EIO);
}
@@ -154,7 +160,11 @@ static int rtp_write_header(AVFormatContext *s1)
if (!s->buf) {
return AVERROR(ENOMEM);
}
+#ifdef EXT_ABS_SEND_TIME
+ s->max_payload_size = s1->packet_size - 20;
+#else
s->max_payload_size = s1->packet_size - 12;
+#endif
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
avpriv_set_pts_info(st, 32, 1, st->codecpar->sample_rate);
@@ -332,16 +342,34 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye)
void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m)
{
RTPMuxContext *s = s1->priv_data;
+ uint64_t ntp64_time;
+ uint32_t absoluteSendTime;
av_log(s1, AV_LOG_TRACE, "rtp_send_data size=%d\n", len);
/* build the RTP header */
+#ifdef EXT_ABS_SEND_TIME
+ avio_w8(s1->pb, RTP_VERSION << 6 | 0x10); // extention bit
+#else
avio_w8(s1->pb, RTP_VERSION << 6);
+#endif
avio_w8(s1->pb, (s->payload_type & 0x7f) | ((m & 0x01) << 7));
avio_wb16(s1->pb, s->seq);
avio_wb32(s1->pb, s->timestamp);
avio_wb32(s1->pb, s->ssrc);
+#ifdef EXT_ABS_SEND_TIME
+ avio_wb16(s1->pb, 0xBEDE); // magic word
+ avio_wb16(s1->pb, 0x0001); // length=1
+ avio_w8(s1->pb, 0x32); // ID=3 and lenght=2
+ ntp64_time = ff_get_formatted_ntp_time(ff_ntp_time());
+ absoluteSendTime = (uint32_t)((ntp64_time>> 14) & 0x00ffffff);
+ av_log(s1, AV_LOG_TRACE, "ntp64:%lu, abs_time:%u\n", ntp64_time, absoluteSendTime);
+ avio_w8(s1->pb, (uint8_t)(absoluteSendTime >> 16));
+ avio_w8(s1->pb, (uint8_t)(absoluteSendTime >> 8 & 0xff));
+ avio_w8(s1->pb, (uint8_t)(absoluteSendTime & 0xff));
+#endif
+
avio_write(s1->pb, buf1, len);
avio_flush(s1->pb);
|