123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990 |
- #include "precompile.h"
- #include "rtp.h"
- #include <time.h>
- #include "modCheck.h"
- #include "memutil.h"
- #include <winpr/string.h>
- #include <winpr/winsock.h>
- #include "dbgutil.h"
- #ifndef _WIN32
- #include <winpr/sysinfo.h>
- #include <arpa/inet.h>
- #endif //NOT _WIN32
- #ifndef H264_VIDEO_PT
- #define H264_VIDEO_PT 97 // H264
- #endif
- #define TAG TOOLKIT_TAG("rtp")
- #define DEFAULT_RTP_STATE_TRANSMIT_INTERVAL 1500 /* 1.5 seconds */
- struct rtp_state {
- /* for rtp sending */
- unsigned int ts; /* host byte order */
- unsigned int ssrc; /* network byte order */
- unsigned int p; /* padding bit */
- unsigned short seq; /* host byte order */
- unsigned int x; /* extension bit */
- /* for sdes */
- char *sdes_str[RTCP_SDES_COUNT];
- /* for statistics */
- rtcp_statistics s;
- /* for rtcp sending */
- DWORD transmit_interval;
- DWORD last_transmit_tick;
- /*for rtcp tmmbr */
- RtcpTmmbrInfo tmmbr_info;
- };
- #ifndef JAN_1970
- #define JAN_1970 0x83aa7e80 /* 2208988800 1970 - 1900 in seconds */
- #endif
- #define SECS_TO_FT_MULT 10000000
- #define rtcp_fb_tmmbr_fci_get_ssrc(tmmbr) ntohl((tmmbr)->ssrc)
- #define rtcp_fb_tmmbr_fci_get_mxtbr_exp(tmmbr) \
- ((unsigned char)((ntohl((tmmbr)->value) >> 26) & 0x0000003F))
- #define rtcp_fb_tmmbr_fci_set_mxtbr_exp(tmmbr, mxtbr_exp) \
- ((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0x03FFFFFF) | (((mxtbr_exp) & 0x0000003F) << 26))
- #define rtcp_fb_tmmbr_fci_get_mxtbr_mantissa(tmmbr) \
- ((unsigned int)((ntohl((tmmbr)->value) >> 9) & 0x0001FFFF))
- #define rtcp_fb_tmmbr_fci_set_mxtbr_mantissa(tmmbr, mxtbr_mantissa) \
- ((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0xFC0001FF) | (((mxtbr_mantissa) & 0x0001FFFF) << 9))
- #define rtcp_fb_tmmbr_fci_get_measured_overhead(tmmbr) \
- ((unsigned short)(ntohl((tmmbr)->value) & 0x000001FF))
- #define rtcp_fb_tmmbr_fci_set_measured_overhead(tmmbr, measured_overhead) \
- ((tmmbr)->value) = htonl((ntohl((tmmbr)->value) & 0xFFFFFE00) | ((measured_overhead) & 0x000001FF))
- #define MIN_RTCP_PSFB_PACKET_SIZE (sizeof(rtcp_common_t) + sizeof(rtcp_fb_header_t))
- #define MIN_RTCP_RTPFB_PACKET_SIZE (sizeof(rtcp_common_t) + sizeof(rtcp_fb_header_t))
- TOOLKIT_API int rtp_state_fill_rtcp_sender_info(rtp_state *rs, rtcp_sender_info_t *info);
- TOOLKIT_API int rtp_state_fill_rtcp_reception_report(rtp_state *rs, rtcp_rr_t *report);
- TOOLKIT_API int rtp_state_fill_rtcp_sdes_item(rtp_state *rs, rtcp_sdes_type_t type, rtcp_sdes_item_t *item, int *fill_n);
- TOOLKIT_API int rtp_state_fill_rtcp_sdes_item_raw(rtp_state *rs, rtcp_sdes_type_t type,
- const char *str, rtcp_sdes_item_t *item, int *fill_n);
- TOOLKIT_API int rtp_state_fill_rtcp_bye(rtp_state *rs, rtcp_bye_t* bye);
- TOOLKIT_API int rtp_state_rtcp_make_bye(rtp_state *rs, char *buf, size_t buflen);
- TOOLKIT_API int rtp_state_rtcp_make_h261_nack(rtp_state *rs, char *buf, size_t buflen);
- TOOLKIT_API int rtp_state_set_sdes_str(rtp_state *rs, rtcp_sdes_type_t type, const char *str);
- TOOLKIT_API void rtp_state_update_send_rtcp_ticks(rtp_state *state);
- #ifdef _WIN32
- // Find 1st Jan 1970 as a FILETIME
- static void get_base_time(void)
- {
- SYSTEMTIME st;
- FILETIME ft;
- memset(&st, 0, sizeof(st));
- st.wYear = 1970;
- st.wMonth = 1;
- st.wDay = 1;
- printf("%s::%d\n", __FUNCTION__, __LINE__);
- SystemTimeToFileTime(&st, &ft);
- /*for linux compatibility*/
- toolkit_getResource()->base_time.u.LowPart = ft.dwLowDateTime;
- toolkit_getResource()->base_time.u.HighPart = ft.dwHighDateTime;
- toolkit_getResource()->base_time.QuadPart /= SECS_TO_FT_MULT;
- }
- static void gettimeofday(struct timeval* tv, struct timezone* tzp)
- {
- SYSTEMTIME st;
- FILETIME ft;
- LARGE_INTEGER li;
- GetSystemTime(&st);
- SystemTimeToFileTime(&st, &ft);
- if (toolkit_getResource()->base_time.QuadPart == 0)
- get_base_time();
- li.u.LowPart = ft.dwLowDateTime;
- li.u.HighPart = ft.dwHighDateTime;
- li.QuadPart /= SECS_TO_FT_MULT;
- li.QuadPart -= toolkit_getResource()->base_time.QuadPart;
- tv->tv_sec = li.u.LowPart;
- tv->tv_usec = st.wMilliseconds * 1000;
- }
- #endif //_MSC_VER
- static char *copymsg(const char *msg, int len)
- {
- char *newm;
- newm = (char*)malloc(len);
- if (newm == NULL) return newm;
- memcpy(newm,msg,len);
- return newm;
- }
- static void freemsg(char *msg)
- {
- if (msg != NULL) {
- free(msg);
- }
- }
- static size_t rtcp_get_size(const char *msg)
- {
- rtcp_common_t *ch = (rtcp_common_t *)msg;
- if (ch==NULL) return 0;
- return (1+ntohs(ch->length))*4;
- }
- static int rtcp_is_rtpfb(const char *msg)
- {
- rtcp_common_t *ch = (rtcp_common_t *)msg;
- if ((ch != NULL) && (ch->pt == RTCP_RTPFB)) {
- return TRUE;
- }
- return FALSE;
- }
- static rtcp_rtpfb_type_t rtcp_rtpfb_get_type(const char *msg)
- {
- rtcp_common_t *ch = (rtcp_common_t *)msg;
- return (rtcp_rtpfb_type_t)ch->count;
- }
- static unsigned int rtcp_rtpfb_get_packet_sender_ssrc(const char *msg)
- {
- rtcp_fb_header_t *fbh = (rtcp_fb_header_t *)(msg + sizeof(rtcp_common_t));
- return ntohl(fbh->packet_sender_ssrc);
- }
- static unsigned int rtcp_rtpfb_get_media_source_ssrc(const char *msg)
- {
- rtcp_fb_header_t *fbh = (rtcp_fb_header_t *)(msg + sizeof(rtcp_common_t));
- return ntohl(fbh->media_source_ssrc);
- }
- static rtcp_fb_tmmbr_fci_t * rtcp_rtpfb_tmmbr_get_fci(const char *msg)
- {
- size_t size = sizeof(rtcp_common_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_tmmbr_fci_t);
- size_t rtcp_size = rtcp_get_size(msg);
- if (size > rtcp_size) {
- return NULL;
- }
- return (rtcp_fb_tmmbr_fci_t *)(msg + size - sizeof(rtcp_fb_tmmbr_fci_t));
- }
- static u__int64_t rtcp_rtpfb_tmmbr_get_max_bitrate(const char *msg)
- {
- rtcp_fb_tmmbr_fci_t *fci = rtcp_rtpfb_tmmbr_get_fci(msg);
- return rtcp_fb_tmmbr_fci_get_mxtbr_mantissa(fci) * (1 << rtcp_fb_tmmbr_fci_get_mxtbr_exp(fci));
- }
- const rtcp_rr_t * rtcp_SR_get_report_block(const char *msg)
- {
- rtcp_sr_t *sr=(rtcp_sr_t*)msg;
- rtcp_rr_t *rb=&sr->rb[0];
- size_t size=rtcp_get_size(msg);
- if ( ( (char *)rb)+sizeof(rtcp_rr_t) <= msg + size ) {
- return rb;
- }
- return NULL;
- }
- const rtcp_rr_t * rtcp_RR_get_report_block(const char *msg)
- {
- int n = 0;
- size_t size;
- unsigned int *sender_ssrc;
- rtcp_rr_t *rb;
- //rtcp_common
- const rtcp_common_t *common = (rtcp_common_t *)msg;
- n += sizeof(rtcp_common_t);
- //sender_ssrc
- sender_ssrc = (unsigned int *)(msg + n);
- rb = (rtcp_rr_t *)(msg + n + sizeof(*sender_ssrc));
- size=rtcp_get_size(msg);
- if ( ( (char *)rb)+sizeof(rtcp_rr_t) <= (msg + size ) ){
- return rb;
- }
- return NULL;
- }
- TOOLKIT_API int rtp_state_fill_rtp(rtp_state *rs, void *hdr, unsigned int pt, unsigned int mark, unsigned int delta_ts)
- {
- rtp_hdr *header;
- TOOLKIT_ASSERT(rs && hdr);
- header = (rtp_hdr*)hdr;
- header->csrc = 0;
- header->x = rs->x;
- header->p = rs->p;
- header->v = 2;
- header->pt = pt&0x7f;
- header->m = !!mark;
- header->seq = htons(rs->seq);
- rs->seq++;
- rs->ts += delta_ts;
-
- if (H264_VIDEO_PT == pt) {
- header->ts = htonl(delta_ts);
- }
- else {
- header->ts = htonl(rs->ts);
- }
- header->ssrc = rs->ssrc;
- return 0;
- }
- TOOLKIT_API int rtp_state_advance_timestamp(rtp_state *rs, unsigned int delta_ts)
- {
- TOOLKIT_ASSERT(rs);
- rs->ts += delta_ts;
- return 0;
- }
- TOOLKIT_API int rtp_state_set_rtcp_sdes_string(rtp_state *rs,
- rtcp_sdes_type_t type,
- const char *str)
- {
- if (!rs)
- return -1;
- if (type <= 0 || type > RTCP_SDES_PRIV)
- return -1;
- if (rs->sdes_str[type]) {
- free(rs->sdes_str[type]);
- }
- rs->sdes_str[type] = _strdup(str);
- return rs->sdes_str[type] ? 0 : -1;
- }
- static u__int64_t rtp_timeval_to_ntp(const struct timeval *tv)
- {
- u__int64_t msw;
- u__int64_t lsw;
- msw=tv->tv_sec + 0x83AA7E80; /* 0x83AA7E80 is the number of seconds from 1900 to 1970 */
- lsw=(unsigned int)((double)tv->tv_usec*(double)(((u__int64_t)1)<<32)*1.0e-6);
- return msw<<32 | lsw;
- }
- TOOLKIT_API int rtp_state_fill_rtcp_sender_info(rtp_state *rs, rtcp_sender_info_t *info)
- {
- struct timeval tv;
- u__int64_t ntp;
- if (!rs)
- return -1;
- info->ssrc = rs->ssrc; /* sender's own ssrc */
- gettimeofday(&tv, NULL);
- ntp=rtp_timeval_to_ntp(&tv);
- info->ntp_sec = htonl(ntp >>32);//(unsigned int)htonl(tv.tv_sec + JAN_1970);
- info->ntp_frac = htonl(ntp & 0xFFFFFFFF);//(unsigned int)htonl((unsigned long)(tv.tv_usec*4294.967296));
- info->rtp_ts = (unsigned int)htonl(rs->ts);
- info->psent = (unsigned int)htonl((unsigned long)rs->s.total_tx_packets);
- info->osent = (unsigned int)htonl((unsigned long)rs->s.total_tx_bytes);
- return 0;
- }
- TOOLKIT_API int rtp_state_fill_rtcp_reception_report(rtp_state *rs, rtcp_rr_t *report)
- {
- int packet_loss_since_last_sr;
- unsigned char loss_fraction;
- unsigned int ext_seq;
- unsigned int expected;
- unsigned int delay_since_lsr = 0;
- if (!rs || !report)
- return -1;
- if (rs->s.last_seq == rs->s.first_seq && rs->s.seq_circles == 0) /* have not recv any peer's data */
- return -1;
- ext_seq = ((unsigned int)rs->s.seq_circles << 16 | (unsigned int)rs->s.last_seq);
- expected = ext_seq - rs->s.rx_seq_at_last_sr;
- packet_loss_since_last_sr = expected - rs->s.rx_packets_since_last_sr;
- if (packet_loss_since_last_sr < 0)
- packet_loss_since_last_sr = 0;
- rs->s.rx_seq_at_last_sr = ext_seq; /* update */
- rs->s.rx_packets_since_last_sr = 0;//RESET
- rs->s.total_packet_lost += (unsigned int)packet_loss_since_last_sr;
- if (expected == 0)
- expected = 1;
- if (rs->s.lsr_tm.tv_sec != 0) {
- struct timeval now;
- double delay;
- gettimeofday(&now, NULL);
- delay= (now.tv_sec-rs->s.lsr_tm.tv_sec)+ ((now.tv_usec-rs->s.lsr_tm.tv_usec)*1e-6);
- delay= (delay*65536);
- delay_since_lsr=(unsigned int) delay;
- }
- loss_fraction = (unsigned char)(256 * packet_loss_since_last_sr / expected);
- report->ssrc = rs->s.peer_ssrc;
- report->fl_cnpl = htonl((loss_fraction << 24) | (rs->s.total_packet_lost&0xffffff));
- report->last_seq = htonl(ext_seq);
- report->jitter = htonl(rs->s.inter_jitter);
- report->lsr = htonl(rs->s.lsr);
- report->dlsr = htonl(delay_since_lsr);
-
- return 0;
- }
- TOOLKIT_API int rtp_state_fill_rtcp_sdes_item_raw(rtp_state *rs
- , rtcp_sdes_type_t type
- , const char *str, rtcp_sdes_item_t *item, int *fill_n)
- {
- if (!rs || !item || !fill_n)
- return -1;
- *fill_n = 0;
- if (type == RTCP_SDES_END) {
- char *t = (char*)item;
- do {
- *t++ = 0;
- *fill_n += 1;
- } while (((unsigned int)t&3) != 0); /* force 32-bit alignment */
- } else {
- int n = str ? (int)strlen(str) : 0;
- if (n) {
- n = min(n, 255);
- memcpy(&item->data[0], str, n);
- }
- item->type = type;
- item->length = (unsigned char)n;
- *fill_n = 2 + n;
- }
- return 0;
- }
- TOOLKIT_API int rtp_state_fill_rtcp_sdes_item(rtp_state *rs, rtcp_sdes_type_t type, rtcp_sdes_item_t *item, int *fill_n)
- {
- if (!rs || !item || !fill_n)
- return -1;
- *fill_n = 0;
- if (type == RTCP_SDES_END) {
- char *t = (char*)item;
- do {
- *t++ = 0;
- *fill_n += 1;
- } while (((unsigned int)t&3) != 0); /* force 32-bit alignment */
- } else if (rs->sdes_str[type] == NULL) {
- return -1; /* null */
- } else {
- int n = (int)strlen(rs->sdes_str[type]);
- if (n) {
- memcpy(&item->data[0], rs->sdes_str[type], n);
- }
- item->type = type;
- item->length = (unsigned char)n;
- *fill_n = 2 + n;
- }
- return 0;
- }
- TOOLKIT_API int rtp_state_fill_rtcp_bye(rtp_state *rs, rtcp_bye_t* bye)
- {
- if (!rs || !bye)
- return -1;
- bye->ssrc[0] = rs->ssrc;
- bye->common.pt = RTCP_BYE;
- bye->common.count = 1;
- bye->common.p = 0;
- bye->common.version = 2;
- bye->common.length = htons(1);
- return 0;
- }
- TOOLKIT_API int rtp_state_rtcp_make_sr(rtp_state *rs, char *buf, size_t buflen)
- {
- rtcp_common_t *common;
- rtcp_sdes_t *sdes;
- int n, t, m;
- int reception_report_result;
- if (!buf)
- return -1;
-
- /* sr block */
- n = 0;
- common = (rtcp_common_t*)&buf[n];
- n += sizeof(rtcp_common_t);
- rtp_state_fill_rtcp_sender_info(rs, (rtcp_sender_info_t *)&buf[n]);
- n += sizeof(rtcp_sender_info_t);
- reception_report_result = rtp_state_fill_rtcp_reception_report(rs, (rtcp_rr_t *)&buf[n]);
- if (reception_report_result < 0) {
- //have not recv any peer's data, not fill_reception_report.
- } else {
- n += sizeof(rtcp_rr_t);
- }
- common->p = 0;
- common->version = 2;
- common->pt = RTCP_SR;
- common->count = 1;
- common->length = htons(n / 4 - 1);
- /* sdes block */
- m = n;
- common = (rtcp_common_t*)&buf[m];
- m += sizeof(rtcp_common_t);
- sdes = (rtcp_sdes_t *)&buf[m];
- sdes->ssrc = rs->ssrc;
- m += sizeof(sdes->ssrc);
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_CNAME, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_END, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- common->p = 0;
- common->version = 2;
- common->pt = RTCP_SDES;
- common->count = 1;
- common->length = htons((m - n) / 4 - 1);
- return m;
- }
- TOOLKIT_API int rtp_state_rtcp_make_rr(rtp_state *rs, char *buf, size_t buflen)
- {
- rtcp_common_t *common;
- rtcp_sdes_t *sdes;
- int n, t, m;
- unsigned int *sender_ssrc;
- int reception_report_result;
- if (!buf)
- return -1;
- /* sr block */
- n = 0;
- common = (rtcp_common_t*)&buf[n];
- n += sizeof(rtcp_common_t);
- sender_ssrc = (unsigned int *)&buf[n];
- *sender_ssrc = rs->ssrc; /* sender's own ssrc */
- n += sizeof(*sender_ssrc);
- reception_report_result = rtp_state_fill_rtcp_reception_report(rs, (rtcp_rr_t *)&buf[n]);
- if (reception_report_result < 0){
- return reception_report_result;
- }
- n += sizeof(rtcp_rr_t);
- common->p = 0;
- common->version = 2;
- common->pt = RTCP_RR;
- common->count = 1;
- common->length = htons(n / 4 - 1);
- /* sdes block */
- m = n;
- common = (rtcp_common_t*)&buf[m];
- m += sizeof(rtcp_common_t);
- sdes = (rtcp_sdes_t *)&buf[m];
- sdes->ssrc = rs->ssrc;
- m += sizeof(sdes->ssrc);
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_CNAME, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_END, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- common->p = 0;
- common->version = 2;
- common->pt = RTCP_SDES;
- common->count = 1;
- common->length = htons((m - n) / 4 - 1);
- return m;
- }
- TOOLKIT_API int rtp_state_rtcp_make_bye(rtp_state *rs, char *buf, size_t buflen)
- {
- rtcp_bye_t* bye;
- rtcp_common_t *common;
- int n, t, m;
- if (!buf)
- return -1;
- /* bye block, already contains rtcp_common_t */
- n = 0;
- bye = (rtcp_bye_t*)&buf[n];
- n += sizeof(rtcp_bye_t);
- bye->common.p = 0;
- bye->common.version = 2;
- bye->common.pt = RTCP_BYE;
- bye->common.count = 1;
- bye->ssrc[0] = rs->ssrc;
- bye->common.length = htons(n / 4 - 1);
- /* sdes block */
- m = n;
- common = (rtcp_common_t*)&buf[m];
- m += sizeof(rtcp_common_t);
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_CNAME, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_END, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- common->p = 1;
- common->version = 2;
- common->pt = RTCP_SDES;
- common->count = 1;
- common->length = htons((m - n) / 4 - 1);
- return m;
- }
- TOOLKIT_API int rtp_state_rtcp_make_h261_fir(rtp_state *rs, char *buf, size_t buflen)
- {
- rtcp_fir_t *fir;
- rtcp_common_t *common;
- rtcp_sdes_t *sdes;
- int n, t, m;
- int reception_report_result;
- /* sr block */
- n = 0;
- common = (rtcp_common_t*)&buf[n];
- n += sizeof(rtcp_common_t);
- rtp_state_fill_rtcp_sender_info(rs, (rtcp_sender_info_t *)&buf[n]);
- n += sizeof(rtcp_sender_info_t);
- reception_report_result = rtp_state_fill_rtcp_reception_report(rs, (rtcp_rr_t *)&buf[n]);
- if (reception_report_result < 0){
- //have not recv any peer's data, not fill_reception_report.
- } else {
- n += sizeof(rtcp_rr_t);
- }
- common->p = 0;
- common->version = 2;
- common->pt = RTCP_SR;
- common->count = 1;
- common->length = htons(n / 4 - 1);
- m = n;
- common = (rtcp_common_t*)&buf[n];
- n += sizeof(rtcp_common_t);
- sdes = (rtcp_sdes_t *)&buf[n];
- sdes->ssrc = rs->ssrc;
- n += sizeof(sdes->ssrc);
- //rtp_state_fill_rtcp_sdes_item_raw(rs, RTCP_SDES_CNAME, "fast_media_video_2b227aa1@huawei.com", (rtcp_sdes_item_t*)&buf[n], &t);
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_CNAME, (rtcp_sdes_item_t*)&buf[n], &t);
- n += t;
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_END, (rtcp_sdes_item_t*)&buf[n], &t);
- n += t;
- common->p = 0;
- common->version = 2;
- common->pt = RTCP_SDES;
- common->count = 1;
- common->length = htons((n-m) / 4 - 1);
- m = n;
- fir = (rtcp_fir_t *)&buf[n];
- n += sizeof(rtcp_fir_t);
- fir->common.p = 0;
- fir->common.pt = RTCP_FIR;
- fir->common.version = 2;
- fir->common.count = 1;
- fir->ssrc = rs->ssrc;
- fir->common.length = htons((n-m)/4 - 1);
- return n;
- }
- TOOLKIT_API int rtp_state_rtcp_make_h261_nack(rtp_state *rs, char *buf, size_t buflen)
- {
- rtcp_common_t *common;
- int n, t, m;
- n = 0;
- common = (rtcp_common_t*)&buf[0];
- n += sizeof(rtcp_common_t);
- common->count = 0;
- common->version = 2;
- common->p = 0;
- common->pt = RTCP_NACK;
- common->length = htons(n / 4 - 1);
- /* sdes block */
- m = n;
- common = (rtcp_common_t*)&buf[m];
- m += sizeof(rtcp_common_t);
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_CNAME, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- rtp_state_fill_rtcp_sdes_item(rs, RTCP_SDES_END, (rtcp_sdes_item_t*)&buf[m], &t);
- m += t;
- common->p = 1;
- common->version = 2;
- common->pt = RTCP_SDES;
- common->count = 1;
- common->length = htons((m - n) / 4 - 1);
- return m;
- }
- TOOLKIT_API int rtp_state_rtcp_make_rtcp_fb_tmmbr(rtp_state *rs, char *buf, size_t buflen
- , u__int64_t mxtbr, unsigned short measured_overhead) {
- rtcp_common_t *ch;
- rtcp_fb_header_t *fbh;
- rtcp_fb_tmmbr_fci_t *fci;
- unsigned char mxtbr_exp = 0;
- unsigned int mxtbr_mantissa = 0;
- int length = 0;
- /* Compute mxtbr exp and mantissa */
- while (mxtbr >= (1 << 17)) {
- mxtbr >>= 1;
- mxtbr_exp++;
- }
- mxtbr_mantissa = mxtbr & 0x0001FFFF;
- /* Fill TMMBR */
- ch = (rtcp_common_t *)&buf[length];
- length += sizeof(rtcp_common_t);
- fbh = (rtcp_fb_header_t *)&buf[length];
- length += sizeof(rtcp_fb_header_t);
- fci = (rtcp_fb_tmmbr_fci_t *)&buf[length];
- length += sizeof(rtcp_fb_tmmbr_fci_t);
- fbh->packet_sender_ssrc = rs->ssrc;
- fbh->media_source_ssrc = htonl(0);
- fci->ssrc = rs->s.peer_ssrc;
- rtcp_fb_tmmbr_fci_set_mxtbr_exp(fci, mxtbr_exp);
- rtcp_fb_tmmbr_fci_set_mxtbr_mantissa(fci, mxtbr_mantissa);
- rtcp_fb_tmmbr_fci_set_measured_overhead(fci, measured_overhead);
- /* Fill common header */
- ch->p = 0;
- ch->version = 2;
- ch->pt = RTCP_RTPFB;
- ch->count = RTCP_RTPFB_TMMBR;
- ch->length = htons(length / 4 - 1);
- /* Store packet to be able to retransmit. */
- if (rs->tmmbr_info.sent) freemsg(rs->tmmbr_info.sent);
- rs->tmmbr_info.sent = copymsg(buf, length);
- return length;
- }
- TOOLKIT_API int rtp_state_rtcp_make_rtcp_fb_tmmbn(rtp_state *rs, char *buf, size_t buflen, unsigned int ssrc) {
- rtcp_common_t *ch;
- rtcp_fb_header_t *fbh;
- rtcp_fb_tmmbr_fci_t *fci;
- int length = 0;
- if (!rs->tmmbr_info.received) return 0;
- /* Fill TMMBN */
- ch = (rtcp_common_t *)&buf[length];
- length += sizeof(rtcp_common_t);
- fbh = (rtcp_fb_header_t *)&buf[length];
- length += sizeof(rtcp_fb_header_t);
- fci = (rtcp_fb_tmmbr_fci_t *)&buf[length];
- length += sizeof(rtcp_fb_tmmbr_fci_t);
- fbh->packet_sender_ssrc = rs->ssrc;
- fbh->media_source_ssrc = htonl(0);
- memcpy(fci, rtcp_rtpfb_tmmbr_get_fci(rs->tmmbr_info.received), sizeof(rtcp_fb_tmmbr_fci_t));
- fci->ssrc = htonl(ssrc);
- /* Fill common header */
- ch->p = 0;
- ch->version = 2;
- ch->pt = RTCP_RTPFB;
- ch->count = RTCP_RTPFB_TMMBN;
- ch->length = htons(length / 4 - 1);
- return length;
- }
- int rtp_state_get_tmmbr_wait_send_maxbitrate(rtp_state *rs, u__int64_t *mxtbr){
- if (rs->tmmbr_info.sent) {
- *mxtbr = rtcp_rtpfb_tmmbr_get_max_bitrate(rs->tmmbr_info.sent);
- return 0;
- }
- return -1;
- }
- static void handle_rtcp_rtpfb_packet(rtp_state *rs, const char *buf, int len) {
- rtcp_common_t *ch = (rtcp_common_t *)&buf[0];
- switch ((rtcp_rtpfb_type_t)ch->count) {
- case RTCP_RTPFB_TMMBR:
- if (rs->tmmbr_info.received) freemsg((char *)(rs->tmmbr_info.received));
- rs->tmmbr_info.received = copymsg(buf, len);
- rs->s.tmmbr_max_bitrate = rtcp_rtpfb_tmmbr_get_max_bitrate(buf);
- break;
- case RTCP_RTPFB_TMMBN:
- if (rs->tmmbr_info.sent) {
- rtcp_fb_tmmbr_fci_t *tmmbn_fci = rtcp_rtpfb_tmmbr_get_fci((char *)buf);
- rtcp_fb_tmmbr_fci_t *tmmbr_fci = rtcp_rtpfb_tmmbr_get_fci((char *)(rs->tmmbr_info.sent));
- if ((tmmbn_fci->ssrc == rs->ssrc) && (tmmbn_fci->value == tmmbr_fci->value)) {
- freemsg((char *)(rs->tmmbr_info.sent));
- rs->tmmbr_info.sent = NULL;
- }
- }
- break;
- default:
- break;
- }
- }
- static unsigned int report_block_get_fraction_lost(const rtcp_rr_t * rr) {
- return (ntohl(rr->fl_cnpl)>>24);
- }
- static unsigned int report_block_get_cum_packet_lost(const rtcp_rr_t * rr){
- unsigned int cum_loss = (unsigned int)ntohl(rr->fl_cnpl);
- if (((cum_loss>>23)&1)==0)
- return (unsigned int) (0x00FFFFFF & cum_loss);
- else
- return (unsigned int)(0xFF000000 | (cum_loss-0xFFFFFF-1));
- }
- static void compute_rtt_from_report_block(rtp_state *rs, const struct timeval *now, rtcp_rr_t *rr) {
- unsigned int last_sr_time;
- unsigned int sr_delay;
-
- u__int64_t curntp;
- unsigned int approx_ntp;
- last_sr_time = ntohl(rr->lsr);
- sr_delay = ntohl(rr->dlsr);
- curntp=rtp_timeval_to_ntp(now);
- approx_ntp=(curntp>>16) & 0xFFFFFFFF;
- //printf("compute_rtt_from_report_block, last_sr_time:%u sr_delay:%u, approx_ntp:%u", last_sr_time, sr_delay, approx_ntp);
- if (last_sr_time!=0 && sr_delay!=0){
- /*we cast to int32_t to check for crazy RTT time (negative)*/
- double rtt_frac=(unsigned int)(approx_ntp-last_sr_time-sr_delay);
- //printf("compute_rtt_from_report_block, rtt_frac:%lf", rtt_frac);
- if (rtt_frac>=0){
- rtt_frac/=65536.0;
- rs->s.rtt=(float)rtt_frac;
- }
- }
- rs->s.cum_loss = report_block_get_cum_packet_lost(rr);
- rs->s.fraction_lost = report_block_get_fraction_lost(rr);
- }
- /**
- * called when receive a peer's rtp data packet
- */
- TOOLKIT_API int rtp_state_on_recv_rtcp(rtp_state *rs, const void *buf, int len)
- {
- if (rs && buf && len >= sizeof(rtcp_common_t)) {
- int n = 0;
- while( n < len) {
- const rtcp_common_t *common = (rtcp_common_t *)((const char*)buf + n);
- if (common->version != 2)
- return -1;
- n += sizeof(rtcp_common_t);
- if (common->pt == RTCP_SR) {
- rtcp_sender_info_t *si;
- si = (rtcp_sender_info_t *)((const char*)buf + n);
- rs->s.lsr = ( ntohl( si->ntp_sec ) << 16 ) | ( ntohl( si->ntp_frac ) >> 16 );
- gettimeofday(&rs->s.lsr_tm, NULL);
- }
- if ((common->pt == RTCP_SR || common->pt == RTCP_RR) && common->count) {
- rtcp_rr_t *rr;
- struct timeval now;
- gettimeofday(&now, NULL);
-
- if (common->pt == RTCP_SR)
- rr = rtcp_SR_get_report_block((const char*)buf);
- else {
- rr = rtcp_RR_get_report_block((const char*)buf);
- }
-
- if (rr != NULL){
- compute_rtt_from_report_block(rs, &now, rr);
- rs->s.report_block_last_number_of_packets = ntohl(rr->last_seq) - rs->s.report_block_last_seq;
- rs->s.report_block_last_seq = ntohl(rr->last_seq);
- }
-
- }
- if (rtcp_is_rtpfb((char *)common), rtcp_get_size((char *)common)) {
- handle_rtcp_rtpfb_packet(rs, (char *)common, rtcp_get_size((char *)common));
- }
- n += ntohs(common->length) * 4;
- }
- return 0;
- }
- return -1;
- }
- #define MAX_DROPOUT 3000
- #define MAX_MISORDER 100
- #define MIN_SEQUENTIAL 2
- /**
- * called when receive a peer's rtp data packet
- */
- TOOLKIT_API int rtp_state_on_recv_rtp(rtp_state *rs, const void *buf, int len)
- {
- if (rs && buf && len >= sizeof(rtp_hdr)) {
- rtp_hdr *hdr = (rtp_hdr*)buf;
- unsigned short seq = ntohs(hdr->seq);
- if (rs->s.first_seq == 0 && rs->s.seq_circles == 0) {
- rs->s.first_seq = seq;
- rs->s.max_seq = seq;
- rs->s.peer_ssrc = hdr->ssrc;
- //rs->s.last_seq = seq;
- } else {
- unsigned short delta = seq - rs->s.max_seq;
- if (delta < MAX_DROPOUT) {
- if (seq < rs->s.max_seq)
- rs->s.seq_circles ++;
- rs->s.max_seq = seq;
- } else {
- /* duplicated */
- }
- }
- //len -= sizeof(rtp_hdr);
- rs->s.total_rx_packets ++;
- rs->s.total_rx_bytes += len;
- rs->s.last_seq = seq;
- rs->s.rx_packets_since_last_sr++;
- return 0;
- }
- return -1;
- }
- /**
- * called when send rtp data packet out
- */
- TOOLKIT_API int rtp_state_on_send_rtp(rtp_state *rs, int len)
- {
- if (rs) {
- len -= sizeof(rtp_hdr);
- rs->s.total_tx_packets ++;
- rs->s.total_tx_bytes += len;
- return 0;
- }
- return -1;
- }
- /**
- * set sdes string, only ascii string less than 255 accepted
- */
- TOOLKIT_API int rtp_state_set_sdes_str(rtp_state *rs, rtcp_sdes_type_t type, const char *str)
- {
- char *t;
- if (!rs)
- return -1;
- if (str == NULL) {
- if (rs->sdes_str[type]) {
- free(rs->sdes_str[type]);
- rs->sdes_str[type] = NULL;
- }
- return 0;
- }
- t = (char*)malloc(RTP_MAX_SDES);
- if (!t)
- return -1;
- strncpy(t, str, RTP_MAX_SDES);
- t[RTP_MAX_SDES-1] = 0;
- if (rs->sdes_str[type])
- free(rs->sdes_str[type]);
- rs->sdes_str[type] = t;
- return 0;
- }
- // rtp_state_set_params();
- TOOLKIT_API int rtp_state_reset(rtp_state *rs,
- unsigned int ssrc,
- unsigned int padding,
- unsigned int extension)
- {
- if (!rs)
- return -1;
- if (ssrc == 0)
- ssrc = (unsigned int)rand();
- #if defined(_MSC_VER)
- rs->ssrc = htonl(ssrc);
- #else
- rs->ssrc = _htonl(ssrc);
- #endif //_MSC_VER
- rs->p = !!padding;
- rs->x = !!extension;
- rs->ts = 0;
- rs->seq = 0;
- //.
- return 0;
- }
- TOOLKIT_API rtp_state *rtp_state_create(int transmit_interval)
- {
- rtp_state *state;
-
- if (transmit_interval <= 0)
- transmit_interval = DEFAULT_RTP_STATE_TRANSMIT_INTERVAL;
- else if (transmit_interval > 5000)
- transmit_interval = 5000;
-
- state = malloc(sizeof(rtp_state));
- if (state) {
- memset(state, 0, sizeof(rtp_state));
- //..
- state->transmit_interval = (DWORD)transmit_interval;
- state->last_transmit_tick = 0;
- }
- return state;
- }
- TOOLKIT_API void rtp_state_destroy(rtp_state *rs)
- {
- if (rs) {
- int i;
- for (i = 0; i < RTCP_SDES_COUNT; ++i) {
- if (rs->sdes_str[i])
- free(rs->sdes_str[i]);
- }
- free(rs);
- }
- }
- TOOLKIT_API int rtp_state_get_stat(rtp_state *rs, rtcp_statistics *stat)
- {
- if (rs && stat) {
- memcpy(stat, &rs->s, sizeof(rtcp_statistics));
- return 0;
- }
- return -1;
- }
- TOOLKIT_API int rtp_state_need_send_rtcp(rtp_state *state, int update_ticks)
- {
- DWORD now;
- DWORD diff;
- TOOLKIT_ASSERT(state);
- now = GetTickCount();
- diff = now - state->last_transmit_tick;
- if (diff >= state->transmit_interval) {
- if (update_ticks)
- state->last_transmit_tick = now;
- return 1;
- } else {
- return 0;
- }
- }
- TOOLKIT_API void rtp_state_update_send_rtcp_ticks(rtp_state *state)
- {
- TOOLKIT_ASSERT(state);
- state->last_transmit_tick = GetTickCount();
- }
|