|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- // RFC3550 6.4.1 SR: Sender Report RTCP Packet
-
- #include "rtp-internal.h"
- #include "rtp-util.h"
-
- void rtcp_sr_unpack(struct rtp_context *ctx, const rtcp_header_t *header, const uint8_t* ptr, size_t bytes)
- {
- uint32_t i;
- rtcp_sr_t *sr;
- rtcp_rb_t *rb;
- struct rtcp_msg_t msg;
- struct rtp_member *sender;
-
- assert(24 == sizeof(rtcp_sr_t));
- assert(24 == sizeof(rtcp_rb_t));
- if (bytes < 24/*sizeof(rtcp_sr_t)*/ + header->rc * 24/*sizeof(rtcp_rb_t)*/)
- {
- assert(0);
- return;
- }
- msg.ssrc = nbo_r32(ptr);
- msg.type = RTCP_RR;
-
- sender = rtp_sender_fetch(ctx, msg.ssrc);
- if(!sender) return; // error
-
- assert(sender != ctx->self);
- assert(sender->rtcp_sr.ssrc == msg.ssrc);
- //assert(sender->rtcp_rb.ssrc == msg.ssrc);
- sender->rtcp_clock = rtpclock();
-
- // update sender information
- sr = &sender->rtcp_sr;
- sr->ntpmsw = nbo_r32(ptr + 4);
- sr->ntplsw = nbo_r32(ptr + 8);
- sr->rtpts = nbo_r32(ptr + 12);
- sr->spc = nbo_r32(ptr + 16);
- sr->soc = nbo_r32(ptr + 20);
-
- ptr += 24;
- // report block
- for(i = 0; i < header->rc; i++, ptr+=24/*sizeof(rtcp_rb_t)*/)
- {
- msg.u.sr.ssrc = nbo_r32(ptr);
- //if(msg.u.rr.ssrc != ctx->self->ssrc)
- // continue; // ignore
- //rb = &sender->rtcp_rb;
-
- rb = &msg.u.sr;
- rb->fraction = ptr[4];
- rb->cumulative = (((uint32_t)ptr[5])<<16) | (((uint32_t)ptr[6])<<8)| ptr[7];
- rb->exthsn = nbo_r32(ptr+8);
- rb->jitter = nbo_r32(ptr+12);
- rb->lsr = nbo_r32(ptr+16);
- rb->dlsr = nbo_r32(ptr+20);
-
- ctx->handler.on_rtcp(ctx->cbparam, &msg);
- }
- }
-
- int rtcp_sr_pack(struct rtp_context *ctx, uint8_t* ptr, int bytes)
- {
- uint32_t i, timestamp;
- uint64_t ntp;
- rtcp_header_t header;
-
- assert(24 == sizeof(rtcp_sr_t));
- assert(24 == sizeof(rtcp_rb_t));
- assert(rtp_member_list_count(ctx->senders) < 32);
- header.v = 2;
- header.p = 0;
- header.pt = RTCP_SR;
- header.rc = MIN(31, rtp_member_list_count(ctx->senders));
- header.length = (24/*sizeof(rtcp_sr_t)*/ + header.rc*24/*sizeof(rtcp_rb_t)*/)/4; // see 6.4.1 SR: Sender Report RTCP Packet
-
- if((uint32_t)bytes < (header.length+1) * 4)
- return (header.length+1) * 4;
-
- nbo_write_rtcp_header(ptr, &header);
-
- // RFC3550 6.4.1 SR: Sender Report RTCP Packet (p32)
- // Note that in most cases this timestamp will not be equal to the RTP
- // timestamp in any adjacent data packet. Rather, it must be calculated from the corresponding
- // NTP timestamp using the relationship between the RTP timestamp counter and real time as
- // maintained by periodically checking the wallclock time at a sampling instant.
- ntp = rtpclock();
- if (0 == ctx->self->rtp_packets)
- ctx->self->rtp_clock = ntp;
- timestamp = (uint32_t)((ntp - ctx->self->rtp_clock) * ctx->frequence / 1000000) + ctx->self->rtp_timestamp;
-
- ntp = clock2ntp(ntp);
- nbo_w32(ptr+4, ctx->self->ssrc);
- nbo_w32(ptr+8, (uint32_t)(ntp >> 32));
- nbo_w32(ptr+12, (uint32_t)(ntp & 0xFFFFFFFF));
- nbo_w32(ptr+16, timestamp);
- nbo_w32(ptr+20, ctx->self->rtp_packets); // send packets
- nbo_w32(ptr+24, (uint32_t)ctx->self->rtp_bytes); // send bytes
-
- ptr += 28;
- // report block
- for(i = 0; i < header.rc; i++)
- {
- struct rtp_member *sender;
-
- sender = rtp_member_list_get(ctx->senders, i);
- if(0 == sender->rtp_packets || sender->ssrc == ctx->self->ssrc)
- continue; // don't receive any packet
-
- ptr += rtcp_report_block(sender, ptr, 24);
- }
-
- return (header.length+1) * 4;
- }
-
- int rtcp_report_block(struct rtp_member* sender, uint8_t* ptr, int bytes)
- {
- uint64_t delay;
- int lost_interval;
- int lost;
- uint32_t fraction;
- uint32_t expected, extseq;
- uint32_t expected_interval;
- uint32_t received_interval;
- uint32_t lsr, dlsr;
-
- if (bytes < 24)
- return 0;
-
- extseq = sender->rtp_seq_cycles + sender->rtp_seq; // 32-bits sequence number
- assert(extseq >= sender->rtp_seq_base);
- expected = extseq - sender->rtp_seq_base + 1;
- expected_interval = expected - sender->rtp_expected0;
- received_interval = sender->rtp_packets - sender->rtp_packets0;
- lost_interval = (int)(expected_interval - received_interval);
- if (lost_interval < 0 || 0 == expected_interval)
- fraction = 0;
- else
- fraction = (lost_interval << 8) / expected_interval;
-
- lost = expected - sender->rtp_packets;
- if (lost > 0x007FFFFF)
- {
- lost = 0x007FFFFF;
- }
- else if (lost < 0)
- {
- // 'Clamp' this loss number to a 24-bit signed value:
- // live555 RTCP.cpp RTCPInstance::enqueueReportBlock line:799
- lost = 0;
- }
-
- delay = rtpclock() - sender->rtcp_clock; // now - Last SR time
- lsr = ((sender->rtcp_sr.ntpmsw & 0xFFFF) << 16) | ((sender->rtcp_sr.ntplsw >> 16) & 0xFFFF);
- // in units of 1/65536 seconds
- // 65536/1000000 == 1024/15625
- dlsr = (uint32_t)(delay / 1000000.0f * 65536);
-
- nbo_w32(ptr, sender->ssrc);
- ptr[4] = (unsigned char)fraction;
- ptr[5] = (unsigned char)((lost >> 16) & 0xFF);
- ptr[6] = (unsigned char)((lost >> 8) & 0xFF);
- ptr[7] = (unsigned char)(lost & 0xFF);
- nbo_w32(ptr + 8, extseq);
- nbo_w32(ptr + 12, (uint32_t)sender->jitter);
- nbo_w32(ptr + 16, lsr);
- nbo_w32(ptr + 20, 0 == lsr ? 0 : dlsr);
-
- sender->rtp_expected0 = expected; // update source prior data
- sender->rtp_packets0 = sender->rtp_packets;
-
- return 24; /*sizeof(rtcp_rb_t)*/
- }
|