diff --git a/fuzzers/rtp_fuzzer.c b/fuzzers/rtp_fuzzer.c index 0fdb005a8a..34ffb07f22 100644 --- a/fuzzers/rtp_fuzzer.c +++ b/fuzzers/rtp_fuzzer.c @@ -76,7 +76,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { janus_rtp_header_extension_parse_audio_level((char *)data, size, 1, NULL, NULL); janus_rtp_header_extension_parse_playout_delay((char *)data, size, 1, NULL, NULL); janus_rtp_header_extension_parse_transport_wide_cc((char *)data, size, 1, &transport_seq_num); - janus_rtp_header_extension_parse_abs_sent_time((char *)data, size, 1, NULL); + janus_rtp_header_extension_parse_abs_send_time((char *)data, size, 1, NULL); + janus_rtp_header_extension_parse_abs_capture_time((char *)data, size, 1, NULL); janus_rtp_header_extension_parse_video_orientation((char * )data, size, 1, &c, &f, &r1, &r0); janus_rtp_header_extension_parse_dependency_desc((char *)data, size, 1, (uint8_t *)&dd, &sizedd); diff --git a/src/ice.c b/src/ice.c index 0e5b25f4cb..7d334efa26 100644 --- a/src/ice.c +++ b/src/ice.c @@ -2876,6 +2876,13 @@ static void janus_ice_cb_nice_recv(NiceAgent *agent, guint stream_id, guint comp memcpy(rtp.extensions.dd_content, dd, len); } } + if(pc->abs_capture_time_ext_id != -1) { + uint64_t abs_ts = 0; + if(janus_rtp_header_extension_parse_abs_capture_time(buf, buflen, + pc->abs_capture_time_ext_id, &abs_ts) == 0) { + rtp.extensions.abs_capture_ts = abs_ts; + } + } /* Pass the packet to the plugin */ janus_plugin *plugin = (janus_plugin *)handle->app; if(plugin && plugin->incoming_rtp && handle->app_handle && @@ -3877,7 +3884,7 @@ static void janus_ice_rtp_extension_update(janus_ice_handle *handle, janus_ice_p totlen += plen; /* We need to strip extensions, here, and add those that need to be there manually */ uint16_t extlen = 0; - char extensions[300]; + char extensions[320]; uint16_t extbufsize = sizeof(extensions); janus_rtp_header *header = (janus_rtp_header *)packet->data; header->extension = 0; @@ -3888,7 +3895,8 @@ static void janus_ice_rtp_extension_update(janus_ice_handle *handle, janus_ice_p (!video && packet->extensions.audio_level > -1 && handle->pc->audiolevel_ext_id > 0) || (video && packet->extensions.video_rotation > -1 && handle->pc->videoorientation_ext_id > 0) || (video && packet->extensions.min_delay > -1 && packet->extensions.max_delay > -1 && handle->pc->playoutdelay_ext_id > 0) || - (video && packet->extensions.dd_len > 0 && handle->pc->dependencydesc_ext_id > 0)) { + (video && packet->extensions.dd_len > 0 && handle->pc->dependencydesc_ext_id > 0) || + (packet->extensions.abs_capture_ts > 0 && handle->pc->abs_capture_time_ext_id > 0)) { /* Do we need 2-byte extemsions, or are 1-byte extensions fine? */ gboolean use_2byte = (video && packet->extensions.dd_len > 16 && handle->pc->dependencydesc_ext_id > 0); /* Write the extension(s) */ @@ -4071,6 +4079,26 @@ static void janus_ice_rtp_extension_update(janus_ice_handle *handle, janus_ice_p } } } + /* Check if we need to add the abs-capture-time extension */ + if(packet->extensions.abs_capture_ts > 0 && handle->pc->abs_capture_time_ext_id > 0) { + uint64_t abs64 = htonll(packet->extensions.abs_capture_ts); + if(!use_2byte) { + *index = (handle->pc->abs_capture_time_ext_id << 4) + 15; + memcpy(index+1, &abs64, 8); + memset(index+9, 0, 8); + index += 17; + extlen += 17; + extbufsize -= 17; + } else { + *index = handle->pc->abs_capture_time_ext_id; + *(index+1) = 16; + memcpy(index+2, &abs64, 8); + memset(index+8, 0, 8); + index += 18; + extlen += 18; + extbufsize -= 18; + } + } /* Calculate the whole length */ uint16_t words = extlen/4; if(extlen%4 != 0) diff --git a/src/ice.h b/src/ice.h index 2c28d1b5c3..e9d121f2eb 100644 --- a/src/ice.h +++ b/src/ice.h @@ -472,6 +472,8 @@ struct janus_ice_peerconnection { gint dependencydesc_ext_id; /*! \brief Absolute Send Time ext ID */ gint abs_send_time_ext_id; + /*! \brief Absolute Capture Time ext ID */ + gint abs_capture_time_ext_id; /*! \brief Whether we do transport wide cc */ gboolean do_transport_wide_cc; /*! \brief Transport wide cc rtp ext ID */ diff --git a/src/janus.c b/src/janus.c index 80be2646c0..11378ddd36 100644 --- a/src/janus.c +++ b/src/janus.c @@ -1591,11 +1591,12 @@ int janus_process_incoming_request(janus_request *request) { janus_request_ice_handle_answer(handle, jsep_sdp); /* Check if the answer does contain the mid/abs-send-time/twcc extmaps */ int mindex = 0; - gboolean do_mid = FALSE, do_twcc = FALSE, do_dd = FALSE, do_abs_send_time = FALSE; + gboolean do_mid = FALSE, do_twcc = FALSE, do_dd = FALSE, do_abs_send_time = FALSE, do_abs_capture_time = FALSE; GList *temp = parsed_sdp->m_lines; while(temp) { janus_sdp_mline *m = (janus_sdp_mline *)temp->data; - gboolean have_mid = FALSE, have_twcc = FALSE, have_dd = FALSE, have_abs_send_time = FALSE; + gboolean have_mid = FALSE, have_twcc = FALSE, have_dd = FALSE, + have_abs_send_time = FALSE, have_abs_capture_time = FALSE; GList *tempA = m->attributes; while(tempA) { janus_sdp_attribute *a = (janus_sdp_attribute *)tempA->data; @@ -1608,6 +1609,8 @@ int janus_process_incoming_request(janus_request *request) { have_dd = TRUE; else if(strstr(a->value, JANUS_RTP_EXTMAP_ABS_SEND_TIME)) have_abs_send_time = TRUE; + else if(strstr(a->value, JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME)) + have_abs_capture_time = TRUE; } tempA = tempA->next; } @@ -1615,6 +1618,7 @@ int janus_process_incoming_request(janus_request *request) { do_twcc = do_twcc || have_twcc; do_dd = do_dd || have_dd; do_abs_send_time = do_abs_send_time || have_abs_send_time; + do_abs_capture_time = do_abs_capture_time || have_abs_capture_time; mindex++; temp = temp->next; } @@ -1628,6 +1632,8 @@ int janus_process_incoming_request(janus_request *request) { handle->pc->dependencydesc_ext_id = 0; if(!do_abs_send_time && handle->pc) handle->pc->abs_send_time_ext_id = 0; + if(!do_abs_capture_time && handle->pc) + handle->pc->abs_capture_time_ext_id = 0; } else { /* Check if the mid RTP extension is being negotiated */ handle->pc->mid_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_MID); @@ -1642,6 +1648,8 @@ int janus_process_incoming_request(janus_request *request) { handle->pc->playoutdelay_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_PLAYOUT_DELAY); /* Check if the abs-send-time ID extension is being negotiated */ handle->pc->abs_send_time_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_ABS_SEND_TIME); + /* Check if the abs-capture-time ID extension is being negotiated */ + handle->pc->abs_capture_time_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME); /* Check if transport wide CC is supported */ int transport_wide_cc_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC); handle->pc->do_transport_wide_cc = transport_wide_cc_ext_id > 0 ? TRUE : FALSE; @@ -1708,6 +1716,8 @@ int janus_process_incoming_request(janus_request *request) { handle->pc->playoutdelay_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_PLAYOUT_DELAY); /* Check if the abs-send-time ID extension is being negotiated */ handle->pc->abs_send_time_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_ABS_SEND_TIME); + /* Check if the abs-capture-time ID extension is being negotiated */ + handle->pc->abs_capture_time_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME); /* Check if transport wide CC is supported */ int transport_wide_cc_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC); handle->pc->do_transport_wide_cc = transport_wide_cc_ext_id > 0 ? TRUE : FALSE; @@ -3256,6 +3266,8 @@ json_t *janus_admin_peerconnection_summary(janus_ice_peerconnection *pc) { json_object_set_new(se, JANUS_RTP_EXTMAP_REPAIRED_RID, json_integer(pc->ridrtx_ext_id)); if(pc->abs_send_time_ext_id > 0) json_object_set_new(se, JANUS_RTP_EXTMAP_ABS_SEND_TIME, json_integer(pc->abs_send_time_ext_id)); + if(pc->abs_capture_time_ext_id > 0) + json_object_set_new(se, JANUS_RTP_EXTMAP_ABS_SEND_TIME, json_integer(pc->abs_capture_time_ext_id)); if(pc->transport_wide_cc_ext_id > 0) json_object_set_new(se, JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC, json_integer(pc->transport_wide_cc_ext_id)); if(pc->audiolevel_ext_id > 0) @@ -3824,7 +3836,7 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug } /* Make sure we don't send the rid/repaired-rid attributes when offering ourselves */ int mindex = 0; - int mid_ext_id = 0, transport_wide_cc_ext_id = 0, abs_send_time_ext_id = 0, + int mid_ext_id = 0, transport_wide_cc_ext_id = 0, abs_send_time_ext_id = 0, abs_capture_time_ext_id = 0, audiolevel_ext_id = 0, videoorientation_ext_id = 0, playoutdelay_ext_id = 0, dependencydesc_ext_id = 0; GList *temp = parsed_sdp->m_lines; while(temp) { @@ -3842,6 +3854,8 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug transport_wide_cc_ext_id = atoi(a->value); else if(strstr(a->value, JANUS_RTP_EXTMAP_ABS_SEND_TIME)) abs_send_time_ext_id = atoi(a->value); + else if(strstr(a->value, JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME)) + abs_capture_time_ext_id = atoi(a->value); else if(strstr(a->value, JANUS_RTP_EXTMAP_AUDIO_LEVEL)) audiolevel_ext_id = atoi(a->value); else if(strstr(a->value, JANUS_RTP_EXTMAP_VIDEO_ORIENTATION)) @@ -3878,6 +3892,8 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug } if(ice_handle->pc && ice_handle->pc->abs_send_time_ext_id != abs_send_time_ext_id) ice_handle->pc->abs_send_time_ext_id = abs_send_time_ext_id; + if(ice_handle->pc && ice_handle->pc->abs_capture_time_ext_id != abs_capture_time_ext_id) + ice_handle->pc->abs_capture_time_ext_id = abs_capture_time_ext_id; if(ice_handle->pc && ice_handle->pc->audiolevel_ext_id != audiolevel_ext_id) ice_handle->pc->audiolevel_ext_id = audiolevel_ext_id; if(ice_handle->pc && ice_handle->pc->videoorientation_ext_id != videoorientation_ext_id) @@ -3891,7 +3907,7 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug /* Check if the answer does contain the mid/rid/repaired-rid/abs-send-time/twcc extmaps */ int mindex = 0; gboolean do_mid = FALSE, do_rid = FALSE, do_repaired_rid = FALSE, - do_dd = FALSE, do_twcc = FALSE, do_abs_send_time = FALSE; + do_dd = FALSE, do_twcc = FALSE, do_abs_send_time = FALSE, do_abs_capture_time = FALSE; GList *temp = parsed_sdp->m_lines; janus_mutex_lock(&ice_handle->mutex); while(temp) { @@ -3899,7 +3915,8 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug janus_ice_peerconnection_medium *medium = ice_handle->pc ? g_hash_table_lookup(ice_handle->pc->media, GUINT_TO_POINTER(mindex)) : NULL; gboolean have_mid = FALSE, have_rid = FALSE, have_repaired_rid = FALSE, - have_twcc = FALSE, have_dd = FALSE, have_abs_send_time = FALSE, have_msid = FALSE; + have_twcc = FALSE, have_dd = FALSE, have_abs_send_time = FALSE, + have_abs_capture_time = FALSE, have_msid = FALSE; int opusred_pt = -1; GList *tempA = m->attributes; while(tempA) { @@ -3945,6 +3962,8 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug do_dd = TRUE; else if(strstr(a->value, JANUS_RTP_EXTMAP_ABS_SEND_TIME)) have_abs_send_time = TRUE; + else if(strstr(a->value, JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME)) + have_abs_capture_time = TRUE; } else if(m->type == JANUS_SDP_AUDIO && medium != NULL && medium->opusred_pt > 0 && a->name && a->value && !strcasecmp(a->name, "rtpmap") && strstr(a->value, "red/48000/2")) { opusred_pt = atoi(a->value); @@ -3979,6 +3998,7 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug do_twcc = do_twcc || have_twcc; do_dd = do_dd || have_dd; do_abs_send_time = do_abs_send_time || have_abs_send_time; + do_abs_capture_time = do_abs_capture_time || have_abs_capture_time; mindex++; temp = temp->next; } @@ -3998,6 +4018,8 @@ json_t *janus_plugin_handle_sdp(janus_plugin_session *plugin_session, janus_plug ice_handle->pc->dependencydesc_ext_id = 0; if(!do_abs_send_time && ice_handle->pc) ice_handle->pc->abs_send_time_ext_id = 0; + if(!do_abs_capture_time && ice_handle->pc) + ice_handle->pc->abs_capture_time_ext_id = 0; janus_mutex_unlock(&ice_handle->mutex); } if(!updating && !janus_ice_is_full_trickle_enabled()) { diff --git a/src/plugins/janus_echotest.c b/src/plugins/janus_echotest.c index 4ef6907014..5e54c15125 100644 --- a/src/plugins/janus_echotest.c +++ b/src/plugins/janus_echotest.c @@ -1261,6 +1261,8 @@ static void *janus_echotest_handler(void *data) { JANUS_SDP_OA_ACCEPT_EXTMAP, JANUS_RTP_EXTMAP_PLAYOUT_DELAY, JANUS_SDP_OA_ACCEPT_EXTMAP, JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC, JANUS_SDP_OA_ACCEPT_EXTMAP, JANUS_RTP_EXTMAP_DEPENDENCY_DESC, + JANUS_SDP_OA_ACCEPT_EXTMAP, JANUS_RTP_EXTMAP_ABS_SEND_TIME, + JANUS_SDP_OA_ACCEPT_EXTMAP, JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME, JANUS_SDP_OA_DONE); temp = temp->next; } diff --git a/src/plugins/janus_recordplay.c b/src/plugins/janus_recordplay.c index 0812a0bdd9..6fd1086987 100644 --- a/src/plugins/janus_recordplay.c +++ b/src/plugins/janus_recordplay.c @@ -778,8 +778,6 @@ static void janus_recordplay_message_free(janus_recordplay_message *msg) { #define JANUS_RECORDPLAY_ERROR_RECORDING_EXISTS 420 #define JANUS_RECORDPLAY_ERROR_UNKNOWN_ERROR 499 -#define ntohll(x) ((1==ntohl(1)) ? (x) : ((gint64)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) - /* Plugin implementation */ int janus_recordplay_init(janus_callbacks *callback, const char *config_path) { if(g_atomic_int_get(&stopping)) { @@ -2529,7 +2527,7 @@ janus_recordplay_frame_packet *janus_recordplay_get_frames(const char *dir, cons JANUS_LOG(LOG_WARN, "Missing data timestamp header"); break; } - when = ntohll(when); + when = ntohll((uint64_t)when); offset += sizeof(gint64); len -= sizeof(gint64); /* Generate frame packet and insert in the ordered list */ diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h index 2c3c174024..93d234dc04 100644 --- a/src/plugins/plugin.h +++ b/src/plugins/plugin.h @@ -171,7 +171,7 @@ janus_plugin *create(void) { * Janus instance or it will crash. * */ -#define JANUS_PLUGIN_API_VERSION 102 +#define JANUS_PLUGIN_API_VERSION 103 /*! \brief Initialization of all plugin properties to NULL * @@ -575,6 +575,8 @@ struct janus_plugin_rtp_extensions { uint8_t dd_len; /*! \brief Dependency Descriptor content */ uint8_t dd_content[256]; + /*! \brief Absolute Capture Time timestamp */ + uint64_t abs_capture_ts; }; /*! \brief Helper method to initialise/reset the RTP extensions field * @note This is important because each of the supported extensions may diff --git a/src/postprocessing/janus-pp-rec.c b/src/postprocessing/janus-pp-rec.c index 45422f1478..0a20a3c229 100644 --- a/src/postprocessing/janus-pp-rec.c +++ b/src/postprocessing/janus-pp-rec.c @@ -133,9 +133,6 @@ Usage: janus-pp-rec [OPTIONS] source.mjr #include "pp-srt.h" #include "pp-binary.h" -#define htonll(x) ((1==htonl(1)) ? (x) : ((gint64)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) -#define ntohll(x) ((1==ntohl(1)) ? (x) : ((gint64)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) - int janus_log_level = 4; gboolean janus_log_timestamps = FALSE; gboolean janus_log_colors = TRUE; @@ -836,7 +833,7 @@ int main(int argc, char *argv[]) { JANUS_LOG(LOG_WARN, "Missing data timestamp header"); break; } - when = ntohll(when); + when = ntohll((uint64_t)when); offset += sizeof(gint64); len -= sizeof(gint64); /* Generate frame packet and insert in the ordered list */ diff --git a/src/record.c b/src/record.c index 050142599c..bd36753e03 100644 --- a/src/record.c +++ b/src/record.c @@ -29,9 +29,6 @@ #include "debug.h" #include "utils.h" -#define htonll(x) ((1==htonl(1)) ? (x) : ((gint64)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) -#define ntohll(x) ((1==ntohl(1)) ? (x) : ((gint64)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) - /* Info header in the structured recording */ static const char *header = "MJR00002"; @@ -439,7 +436,7 @@ int janus_recorder_save_frame(janus_recorder *recorder, char *buffer, uint lengt } if(recorder->type == JANUS_RECORDER_DATA) { /* If it's data, then we need to prepend timing related info, as it's not there by itself */ - gint64 now = htonll(janus_get_real_time()); + gint64 now = htonll((uint64_t)janus_get_real_time()); res = fwrite(&now, sizeof(gint64), 1, recorder->file); if(res != 1) { JANUS_LOG(LOG_WARN, "Couldn't write data timestamp in .mjr file (%zu != %zu, %s), expect issues post-processing\n", diff --git a/src/rtp.c b/src/rtp.c index 086ff19054..b07667ba61 100644 --- a/src/rtp.c +++ b/src/rtp.c @@ -103,6 +103,8 @@ const char *janus_rtp_header_extension_get_from_id(const char *sdp, int id) { return JANUS_RTP_EXTMAP_TOFFSET; if(strstr(extension, JANUS_RTP_EXTMAP_ABS_SEND_TIME)) return JANUS_RTP_EXTMAP_ABS_SEND_TIME; + if(strstr(extension, JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME)) + return JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME; if(strstr(extension, JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC)) return JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC; if(strstr(extension, JANUS_RTP_EXTMAP_MID)) @@ -332,7 +334,7 @@ int janus_rtp_header_extension_parse_dependency_desc(char *buf, int len, int id, return 0; } -int janus_rtp_header_extension_parse_abs_sent_time(char *buf, int len, int id, uint32_t *abs_ts) { +int janus_rtp_header_extension_parse_abs_send_time(char *buf, int len, int id, uint32_t *abs_ts) { char *ext = NULL; uint8_t idlen = 0; if(janus_rtp_header_extension_find(buf, len, id, NULL, NULL, &ext, &idlen) < 0) @@ -363,6 +365,37 @@ int janus_rtp_header_extension_set_abs_send_time(char *buf, int len, int id, uin return 0; } +int janus_rtp_header_extension_parse_abs_capture_time(char *buf, int len, int id, uint64_t *abs_ts) { + char *ext = NULL; + uint8_t idlen = 0; + if(janus_rtp_header_extension_find(buf, len, id, NULL, NULL, &ext, &idlen) < 0) + return -1; + /* a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time */ + if(ext == NULL) + return -2; + if(idlen < 8 || idlen > len-(ext-buf)-1) + return -3; + uint64_t abs64 = 0; + memcpy(&abs64, ext, 8); + if(abs_ts) + *abs_ts = ntohll(abs64); + return 0; +} + +int janus_rtp_header_extension_set_abs_capture_time(char *buf, int len, int id, uint64_t abs_ts) { + char *ext = NULL; + uint8_t idlen = 0; + if(janus_rtp_header_extension_find(buf, len, id, NULL, NULL, &ext, &idlen) < 0) + return -1; + if(ext == NULL) + return -2; + if(idlen < 8 || idlen > len-(ext-buf)-1) + return -3; + uint64_t abs64 = htonll(abs_ts); + memcpy(ext, &abs64, 8); + return 0; +} + int janus_rtp_header_extension_parse_transport_wide_cc(char *buf, int len, int id, uint16_t *transSeqNum) { char *ext = NULL; uint8_t idlen = 0; diff --git a/src/rtp.h b/src/rtp.h index cebb8b3c86..34d698b9fb 100644 --- a/src/rtp.h +++ b/src/rtp.h @@ -78,6 +78,8 @@ typedef struct janus_rtp_header_extension { #define JANUS_RTP_EXTMAP_TOFFSET "urn:ietf:params:rtp-hdrext:toffset" /*! \brief a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time */ #define JANUS_RTP_EXTMAP_ABS_SEND_TIME "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time" +/*! \brief a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time */ +#define JANUS_RTP_EXTMAP_ABS_CAPTURE_TIME "http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time" /*! \brief a=extmap:4 urn:3gpp:video-orientation */ #define JANUS_RTP_EXTMAP_VIDEO_ORIENTATION "urn:3gpp:video-orientation" /*! \brief a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 */ @@ -221,7 +223,7 @@ int janus_rtp_header_extension_parse_dependency_desc(char *buf, int len, int id, * @param[in] id The extension ID to look for * @param[out] abs_ts Variable where the parsed abs-send-time value will be stored * @returns 0 if found, -1 otherwise */ -int janus_rtp_header_extension_parse_abs_sent_time(char *buf, int len, int id, uint32_t *abs_ts); +int janus_rtp_header_extension_parse_abs_send_time(char *buf, int len, int id, uint32_t *abs_ts); /*! \brief Helper to set an abs-send-time RTP extension (http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time) * @param[in] buf The packet data @@ -231,6 +233,22 @@ int janus_rtp_header_extension_parse_abs_sent_time(char *buf, int len, int id, u * @returns 0 if found, -1 otherwise */ int janus_rtp_header_extension_set_abs_send_time(char *buf, int len, int id, uint32_t abs_ts); +/*! \brief Helper to parse an abs-capture-time RTP extension (http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time) + * @param[in] buf The packet data + * @param[in] len The packet data length in bytes + * @param[in] id The extension ID to look for + * @param[out] abs_ts Variable where the parsed abs-capture-time value will be stored + * @returns 0 if found, -1 otherwise */ +int janus_rtp_header_extension_parse_abs_capture_time(char *buf, int len, int id, uint64_t *abs_ts); + +/*! \brief Helper to set an abs-capture-time RTP extension (http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time) + * @param[in] buf The packet data + * @param[in] len The packet data length in bytes + * @param[in] id The extension ID to look for + * @param[out] abs_ts Absolute Send Time value to set + * @returns 0 if found, -1 otherwise */ +int janus_rtp_header_extension_set_abs_capture_time(char *buf, int len, int id, uint64_t abs_ts); + /*! \brief Helper to parse a transport wide sequence number (https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01) * @param[in] buf The packet data * @param[in] len The packet data length in bytes diff --git a/src/utils.h b/src/utils.h index d20e2fde6f..cf4ef987c8 100644 --- a/src/utils.h +++ b/src/utils.h @@ -32,6 +32,14 @@ struct janus_json_parameter { unsigned int flags; }; +#ifndef htonll +#define htonll(x) ((1==htonl(1)) ? (x) : ((guint64)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#endif +#ifndef ntohll +#define ntohll(x) ((1==ntohl(1)) ? (x) : ((guint64)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) +#endif + + /*! \brief Helper to retrieve the system monotonic time, as Glib's * g_get_monotonic_time may not be available (only since 2.28) * @returns The system monotonic time */