From dc18c9ced74c26c569f8b54357d150afd92417b1 Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Wed, 8 Feb 2023 16:36:06 +0100 Subject: [PATCH 1/5] Add support for abs-capture-time RTP extension --- src/ice.c | 32 +++++++++++++++++++++++++++++-- src/ice.h | 2 ++ src/janus.c | 32 ++++++++++++++++++++++++++----- src/plugins/janus_echotest.c | 2 ++ src/plugins/janus_recordplay.c | 4 +--- src/plugins/plugin.h | 2 ++ src/record.c | 5 +---- src/rtp.c | 35 +++++++++++++++++++++++++++++++++- src/rtp.h | 20 ++++++++++++++++++- src/utils.h | 8 ++++++++ 10 files changed, 126 insertions(+), 16 deletions(-) diff --git a/src/ice.c b/src/ice.c index 412ad5d3d0..8fa37c9be8 100644 --- a/src/ice.c +++ b/src/ice.c @@ -2816,6 +2816,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 && @@ -3814,7 +3821,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; @@ -3825,7 +3832,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) */ @@ -4008,6 +4016,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 36509770cd..803ddfd7c5 100644 --- a/src/ice.h +++ b/src/ice.h @@ -458,6 +458,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 17cfc37ec1..6889a7778b 100644 --- a/src/janus.c +++ b/src/janus.c @@ -1536,11 +1536,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; @@ -1553,6 +1554,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; } @@ -1560,6 +1563,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; } @@ -1573,6 +1577,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); @@ -1587,6 +1593,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; @@ -1653,6 +1661,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; @@ -3195,6 +3205,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) @@ -3763,7 +3775,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) { @@ -3781,6 +3793,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)) @@ -3817,6 +3831,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) @@ -3830,7 +3846,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) { @@ -3838,7 +3854,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) { @@ -3884,6 +3901,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); @@ -3918,6 +3937,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; } @@ -3937,6 +3957,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 ea7704d2ab..e7dc612d94 100644 --- a/src/plugins/janus_echotest.c +++ b/src/plugins/janus_echotest.c @@ -1152,6 +1152,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 d55bfe0487..7ec67c2c35 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)) { @@ -2532,7 +2530,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..c6bf66fb7e 100644 --- a/src/plugins/plugin.h +++ b/src/plugins/plugin.h @@ -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/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 55b02dbb03..f52b304440 100644 --- a/src/rtp.c +++ b/src/rtp.c @@ -104,6 +104,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)) @@ -333,7 +335,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) @@ -364,6 +366,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 8b3134fd4c..1aecc5238e 100644 --- a/src/rtp.h +++ b/src/rtp.h @@ -77,6 +77,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 */ @@ -220,7 +222,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 @@ -230,6 +232,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 7f173b1172..786b45c6de 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 */ From 201cab5996cab6fdf9622f8c1ef8aeb3e6af2f51 Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Wed, 8 Feb 2023 16:56:28 +0100 Subject: [PATCH 2/5] Fixed typo in RTP fuzzer --- fuzzers/rtp_fuzzer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fuzzers/rtp_fuzzer.c b/fuzzers/rtp_fuzzer.c index 0fdb005a8a..f24f3a34fd 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, 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); From d463df3515b9337b783e8e67a1ea87bb2d3b1948 Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Wed, 8 Feb 2023 16:56:43 +0100 Subject: [PATCH 3/5] Fixed double define in janus-pp-rec --- src/postprocessing/janus-pp-rec.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/postprocessing/janus-pp-rec.c b/src/postprocessing/janus-pp-rec.c index 802ef686eb..9f71f4284c 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 */ From dadf460f4e5bad17cbf6d6fa91c14b830029dc96 Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Wed, 8 Feb 2023 17:00:29 +0100 Subject: [PATCH 4/5] Fixed (another) typo in the RTP fuzzer --- fuzzers/rtp_fuzzer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzzers/rtp_fuzzer.c b/fuzzers/rtp_fuzzer.c index f24f3a34fd..34ffb07f22 100644 --- a/fuzzers/rtp_fuzzer.c +++ b/fuzzers/rtp_fuzzer.c @@ -77,7 +77,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 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_send_time((char *)data, size, 1, NULL); - janus_rtp_header_extension_parse_abs_capture_time((char *)data, size, 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); From c9b06659b75e694573e0449dcf927decd3aabffc Mon Sep 17 00:00:00 2001 From: Lorenzo Miniero Date: Thu, 9 Feb 2023 15:24:54 +0100 Subject: [PATCH 5/5] Bump plugin API version, due to new extension support --- src/plugins/plugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h index c6bf66fb7e..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 *