static int rtp_ps_unpack_input(void* p, const void* packet, size_t bytes, int64_t time) { rtp_packet_t pkt; struct rtp_ps_unpack_t *unpacker; unpacker = (struct rtp_ps_unpack_t *)p; if(0 != rtp_packet_deserialize(&pkt, packet, bytes) || pkt.payloadlen < 1) return -1; if((uint16_t)pkt.rtp.seq != unpacker->seq+1 && 0!=unpacker->seq) { // packet lost unpacker->size = 0; // clear flags unpacker->flag = 1; } unpacker->seq = (uint16_t)pkt.rtp.seq; assert(pkt.payloadlen > 0); if(pkt.payloadlen > 0 && 0 == unpacker->flag) { if(pkt.payloadlen > 0 && unpacker->size + pkt.payloadlen > unpacker->capacity) { uint8_t *ptr = (uint8_t*)realloc(unpacker->ptr, unpacker->capacity + pkt.payloadlen + 2048); if(!p) { unpacker->flag = 1; return ENOMEM; } unpacker->ptr = ptr; unpacker->capacity += pkt.payloadlen + 2048; } memcpy(unpacker->ptr + unpacker->size, pkt.payload, pkt.payloadlen); unpacker->size += pkt.payloadlen; } // RTP marker bit if(pkt.rtp.m) { if(unpacker->size > 0 && 0==unpacker->flag) unpacker->func.packet(unpacker->cbparam, (uint8_t)pkt.rtp.pt, unpacker->ptr, unpacker->size, time); unpacker->flag = 0; unpacker->size = 0; } return 0; }
int rtp_onsend(void* rtp, const void* data, int bytes) { // time64_t ntp; struct rtp_packet_t pkt; struct rtp_context *ctx = (struct rtp_context *)rtp; ctx->role = RTP_SENDER; // don't need add self to sender list // rtp_member_list_add(ctx->senders, ctx->self); if(0 != rtp_packet_deserialize(&pkt, data, bytes)) return -1; // packet error ctx->self->rtp_clock = rtpclock(); ctx->self->rtp_timestamp = pkt.rtp.timestamp; // RTP timestamp ctx->self->rtp_bytes += pkt.payloadlen; ctx->self->rtp_packets += 1; return 0; }
int rtcp_input_rtp(struct rtp_context *ctx, const void* data, size_t bytes, time64_t *time) { time64_t clock; rtp_packet_t pkt; struct rtp_member *sender; if(0 != rtp_packet_deserialize(&pkt, data, bytes)) return -1; // packet error assert(2 == pkt.rtp.v); sender = rtp_sender_fetch(ctx, pkt.rtp.ssrc); if(!sender) return -1; clock = time64_now(); // RFC3550 A.8 Estimating the Interarrival Jitter // the jitter estimate is updated: if(0 != sender->rtp_clock) { int D; D = (int)((unsigned int)((clock - sender->rtp_clock)*ctx->frequence/1000) - (pkt.rtp.timestamp - sender->rtp_timestamp)); if(D < 0) D = -D; sender->jitter += (D - sender->jitter)/16.0; } sender->rtp_clock = clock; sender->rtp_timestamp = pkt.rtp.timestamp; sender->rtp_octets += pkt.payloadlen; ++sender->rtp_packets; // RFC3550 A.1 RTP Data Header Validity Checks if(0 == sender->seq_max && 0 == sender->seq_cycles) { sender->seq_probation = 0; sender->seq_max = (uint16_t)pkt.rtp.seq; sender->seq_base = (uint16_t)pkt.rtp.seq; } else if( RTP_SEQ_DIFF(pkt.rtp.seq, sender->seq_max) < RTP_MISORDER) { if(pkt.rtp.seq < 0x1000 && sender->seq_max > 0x8000) { sender->seq_cycles += 1; sender->seq_max = (uint16_t)pkt.rtp.seq; } else { sender->seq_max = (uint16_t)MAX(pkt.rtp.seq, sender->seq_max); } } else { if(++sender->seq_probation > RTP_MINISEQ) { sender->seq_cycles = 0; sender->seq_probation = 0; sender->seq_max = (uint16_t)pkt.rtp.seq; sender->seq_base = (uint16_t)pkt.rtp.seq; } } // calculate wallclock from RTP timestamp if(0 != sender->rtcp_sr.ntpmsw) { *time = (uint64_t)ntp2clock((((uint64_t)sender->rtcp_sr.ntpmsw) << 32) | sender->rtcp_sr.ntplsw); *time += ((uint64_t)(uint32_t)(sender->rtp_timestamp - sender->rtcp_sr.rtpts)) * 1000 / ctx->frequence; // rtp timestamp round per 13-hours(0xFFFFFFFF / 90000 / 3600) // update wall-clock per hour if(clock - sender->rtcp_sr_clock > 1 * 3600 * 1000 || (uint32_t)RTP_ABS((int32_t)(sender->rtp_timestamp - sender->rtcp_sr.rtpts)) > 0x10000000) { time64_t ltnow; ltnow = clock2ntp(*time); sender->rtcp_sr_clock = clock; sender->rtcp_sr.rtpts = sender->rtp_timestamp; sender->rtcp_sr.ntpmsw = (uint32_t)((ltnow >> 32) & 0xFFFFFFFF); sender->rtcp_sr.ntplsw = (uint32_t)ltnow; }