int rtp_queue_unlock(void* queue, void* ptr, int size) { unsigned int v; struct rtp_queue *q; struct rtp_frame *frame; // time64_t tnow = time64_now(); q = (struct rtp_queue *)queue; frame = (struct rtp_frame *)ptr - 1; assert(frame->ptr == (unsigned char *)ptr); v = nbo_r32((unsigned char *)ptr); frame->seq = RTP_SEQ(v); // frame->timestamp = ntohl(((const unsigned int *)ptr)[1]); // frame->ssrc = ntohl(((const unsigned int *)ptr)[2]); frame->clock = rtpclock(); frame->len = size; assert(!frame->next); locker_lock(&q->locker); rtp_queue_push(q, frame); // rtp_queue_dump(q); locker_unlock(&q->locker); return 0; }
static int rtcp_parse(struct rtp_context *ctx, const unsigned char* data, size_t bytes) { uint32_t rtcphd; rtcp_header_t header; assert(bytes >= sizeof(rtcphd)); rtcphd = nbo_r32(data); header.v = RTCP_V(rtcphd); header.p = RTCP_P(rtcphd); header.rc = RTCP_RC(rtcphd); header.pt = RTCP_PT(rtcphd); header.length = RTCP_LEN(rtcphd); assert((header.length+1)*4 <= bytes); assert(2 == header.v); // 1. RTP version field must equal 2 (p69) // 2. The payload type filed of the first RTCP packet in a compound packet must be SR or RR (p69) // 3. padding only valid at the last packet if(1 == header.p) { assert((header.length+1)*4 + 4 <= bytes); header.length -= *(data + header.length - 1) * 4; } switch(header.pt) { case RTCP_SR: rtcp_sr_unpack(ctx, &header, data+4); break; case RTCP_RR: rtcp_rr_unpack(ctx, &header, data+4); break; case RTCP_SDES: rtcp_sdes_unpack(ctx, &header, data+4); break; case RTCP_BYE: rtcp_bye_unpack(ctx, &header, data+4); break; case RTCP_APP: rtcp_app_unpack(ctx, &header, data+4); break; default: assert(0); } return (header.length+1)*4; }