|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #include "rtp-demuxer.h"
- #include "rtp-internal.h"
- #include "rtp-payload.h"
- #include "rtp-packet.h"
- #include "rtp-queue.h"
- #include "rtp-param.h"
- #include "rtp.h"
- #include "rtcp-header.h"
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <stdio.h>
- #include <errno.h>
-
- struct rtp_demuxer_t
- {
- uint32_t ssrc;
- uint64_t clock; // rtcp clock
-
- uint8_t* ptr;
- int cap, max;
-
- rtp_queue_t* queue;
- void* payload;
- void* rtp;
-
- rtp_demuxer_onpacket onpkt;
- void* param;
- };
-
- static int rtp_onpacket(void* param, const void *packet, int bytes, uint32_t timestamp, int flags)
- {
- struct rtp_demuxer_t* rtp;
- rtp = (struct rtp_demuxer_t*)param;
-
- // TODO: rtp timestamp -> pts/dts
-
- return rtp->onpkt ? rtp->onpkt(rtp->param, packet, bytes, timestamp, flags) : -1;
- }
-
- static void rtp_on_rtcp(void* param, const struct rtcp_msg_t* msg)
- {
- //struct rtp_demuxer_t* rtp;
- //rtp = (struct rtp_demuxer_t*)param;
- if (RTCP_BYE == msg->type)
- {
- printf("finished\n");
- //rtp->onpkt(rtp->param, NULL, 0, 0, 0);
- }
- }
-
- static struct rtp_packet_t* rtp_demuxer_alloc(struct rtp_demuxer_t* rtp, const void* data, int bytes)
- {
- int r;
- uint8_t* ptr;
- struct rtp_packet_t* pkt;
-
- if(rtp->cap < bytes + (int)sizeof(struct rtp_packet_t) + (int)sizeof(int) /*bytes*/ )
- {
- r = bytes + sizeof(struct rtp_packet_t) + sizeof(int);
- r = r > 1500 ? r : 1500;
- ptr = (uint8_t*)realloc(rtp->ptr, r + sizeof(int) /*cap*/ );
- if(!ptr)
- return NULL;
-
- rtp->cap = r;
- rtp->ptr = ptr;
- *(int*)ptr = r; /*cap*/
- }
-
- *((int*)rtp->ptr + 1) = bytes; /*bytes*/
- pkt = (struct rtp_packet_t*)(rtp->ptr + sizeof(int) /*cap*/ + sizeof(int) /*bytes*/ );
- memcpy(pkt + 1, data, bytes);
-
- r = rtp_packet_deserialize(pkt, pkt + 1, bytes);
- if(0 != r)
- return NULL;
-
- rtp->cap = 0; // need more memory
- rtp->ptr = NULL;
- return pkt;
- }
-
- static void rtp_demuxer_freepkt(void* param, struct rtp_packet_t* pkt)
- {
- int cap;
- uint8_t* ptr;
- struct rtp_demuxer_t* rtp;
- rtp = (struct rtp_demuxer_t*)param;
- ptr = (uint8_t*)pkt - sizeof(int) /*cap*/ - sizeof(int) /*bytes*/ ;
- cap = *(int*)ptr;
-
- if(cap <= rtp->cap)
- {
- free(ptr);
- return;
- }
-
- if(rtp->cap > 0 && rtp->ptr)
- free(rtp->ptr);
- rtp->cap = cap;
- rtp->ptr = ptr;
- }
-
- static int rtp_demuxer_init(struct rtp_demuxer_t* rtp, int jitter, int frequency, int payload, const char* encoding)
- {
- uint32_t timestamp;
- struct rtp_event_t evthandler;
- struct rtp_payload_t handler;
- // const struct rtp_profile_t* profile;
- // profile = rtp_profile_find(payload);
- // frequency = profile ? profile->frequency : 90000;
-
- memset(&handler, 0, sizeof(handler));
- handler.alloc = NULL;
- handler.free = NULL;
- handler.packet = rtp_onpacket;
- rtp->payload = rtp_payload_decode_create(payload, encoding, &handler, rtp);
-
- timestamp = (uint32_t)rtpclock();
- evthandler.on_rtcp = rtp_on_rtcp;
- rtp->rtp = rtp_create(&evthandler, rtp, rtp->ssrc, timestamp, frequency ? frequency : 90000, 2 * 1024 * 1024, 0);
-
- rtp->queue = rtp_queue_create(jitter, frequency, rtp_demuxer_freepkt, rtp);
-
- return rtp->payload && rtp->rtp && rtp->queue? 0 : -1;
- }
-
- struct rtp_demuxer_t* rtp_demuxer_create(int jitter, int frequency, int payload, const char* encoding, rtp_demuxer_onpacket onpkt, void* param)
- {
- struct rtp_demuxer_t* rtp;
- rtp = (struct rtp_demuxer_t*)calloc(1, sizeof(*rtp));
- if(!rtp)
- return NULL;
-
- if(0 != rtp_demuxer_init(rtp, jitter, frequency, payload, encoding))
- {
- rtp_demuxer_destroy(&rtp);
- return NULL;
- }
-
- rtp->onpkt = onpkt;
- rtp->param = param;
- rtp->clock = rtpclock();
- rtp->ssrc = rtp_ssrc();
- rtp->max = RTP_PAYLOAD_MAX_SIZE;
- return rtp;
- }
-
- int rtp_demuxer_destroy(struct rtp_demuxer_t** pprtp)
- {
- struct rtp_demuxer_t* rtp;
- if(pprtp && *pprtp)
- {
- rtp = *pprtp;
- if(rtp->rtp)
- rtp_destroy(rtp->rtp);
-
- if(rtp->payload)
- rtp_payload_decode_destroy(rtp->payload);
-
- if(rtp->queue)
- rtp_queue_destroy(rtp->queue);
-
- if(rtp->ptr)
- free(rtp->ptr);
- free(rtp);
- }
-
- return 0;
- }
-
- int rtp_demuxer_input(struct rtp_demuxer_t* rtp, const void* data, int bytes)
- {
- int r;
- uint8_t pt;
- struct rtp_packet_t* pkt;
-
- if (bytes < 12 || bytes > rtp->max)
- return -EINVAL;
-
- pt = ((uint8_t*)data)[1];
- // RFC7983 SRTP: https://tools.ietf.org/html/draft-ietf-avtcore-rfc5764-mux-fixes
- // http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-4
- // RFC 5761 (RTCP-mux) states this range for secure RTCP/RTP detection.
- // RTCP packet types in the ranges 1-191 and 224-254 SHOULD only be used when other values have been exhausted.
- if(pt < RTCP_FIR || pt > RTCP_LIMIT)
- {
- pkt = rtp_demuxer_alloc(rtp, data, bytes);
- if (!pkt)
- return -ENOMEM;
-
- r = rtp_queue_write(rtp->queue, pkt);
- if(r <= 0) // 0-discard packet(duplicate/too late)
- {
- rtp_demuxer_freepkt(rtp, pkt);
- return r;
- }
-
- // re-order packet
- pkt = rtp_queue_read(rtp->queue);
- while(pkt)
- {
- bytes = *(int*)((uint8_t*)pkt - sizeof(int) /*bytes*/ );
-
- r = rtp_onreceived(rtp->rtp, pkt + 1, bytes);
- r = rtp_payload_decode_input(rtp->payload, pkt + 1, bytes);
- rtp_demuxer_freepkt(rtp, pkt);
- if(r < 0)
- return r;
-
- pkt = rtp_queue_read(rtp->queue);
- }
- }
- else
- {
- r = rtp_onreceived_rtcp(rtp->rtp, data, bytes);
- (void)r; // ignore rtcp handler
-
- return pt; // rtcp message type
- }
-
- return 0;
- }
-
- int rtp_demuxer_rtcp(struct rtp_demuxer_t* rtp, void* buf, int len)
- {
- int r;
- int interval;
- uint64_t clock;
-
- r = 0;
- clock = rtpclock();
- interval = rtp_rtcp_interval(rtp->rtp);
- if (rtp->clock + (uint64_t)interval * 1000 < clock)
- {
- // RTCP report
- r = rtp_rtcp_report(rtp->rtp, buf, len);
- rtp->clock = clock;
- }
-
- return r;
- }
|