@@ -1608,6 +1608,8 @@ room-<unique room ID>: {
1608
1608
"mcast" : "<multicast group port for receiving RTP packets, if any>",
1609
1609
"iface" : "<network interface or IP address to bind to, if any (binds to all otherwise)>",
1610
1610
"port" : <local port for receiving all RTP packets; 0 will bind to a random one (default)>,
1611
+ "srtp_suite" : <length of authentication tag (32 or 80); optional>,
1612
+ "srtp_crypto" : "<key to use as crypto (base64 encoded key as in SDES); optional>",
1611
1613
"streams" : [
1612
1614
{
1613
1615
"type" : "<type of published stream #1 (audio|video|data)">,
@@ -1657,6 +1659,8 @@ room-<unique room ID>: {
1657
1659
"secret" : "<password required to edit the room, mandatory if configured in the room>",
1658
1660
"display" : "<new display name for the remote publisher; optional>",
1659
1661
"metadata" : <new valid json object of metadata; optional>,
1662
+ "srtp_suite" : <length of authentication tag (32 or 80); optional>,
1663
+ "srtp_crypto" : "<key to use as crypto (base64 encoded key as in SDES); optional>",
1660
1664
"streams" : [
1661
1665
{
1662
1666
// Same syntax as add_remote_publisher: only needs to
@@ -1713,7 +1717,9 @@ room-<unique room ID>: {
1713
1717
"host" : "<host address to forward the RTP and data packets to>",
1714
1718
"host_family" : "<ipv4|ipv6, if we need to resolve the host address to an IP; by default, whatever we get>",
1715
1719
"port" : <port to forward the packets to>,
1716
- "rtcp_port" : <port to contact to receive RTCP feedback from the recipient; optional, and only for RTP streams, not data>
1720
+ "rtcp_port" : <port to contact to receive RTCP feedback from the recipient; optional, and only for RTP streams, not data>,
1721
+ "srtp_suite" : <length of authentication tag (32 or 80); optional>,
1722
+ "srtp_crypto" : "<key to use as crypto (base64 encoded key as in SDES); optional>"
1717
1723
}
1718
1724
\endverbatim
1719
1725
*
@@ -2194,7 +2200,9 @@ static struct janus_json_parameter publish_remotely_parameters[] = {
2194
2200
{"host", JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
2195
2201
{"host_family", JSON_STRING, 0},
2196
2202
{"port", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE | JANUS_JSON_PARAM_REQUIRED},
2197
- {"rtcp_port", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}
2203
+ {"rtcp_port", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
2204
+ {"srtp_suite", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
2205
+ {"srtp_crypto", JSON_STRING, 0}
2198
2206
};
2199
2207
static struct janus_json_parameter unpublish_remotely_parameters[] = {
2200
2208
{"secret", JSON_STRING, 0},
@@ -2207,13 +2215,17 @@ static struct janus_json_parameter remote_publisher_parameters[] = {
2207
2215
{"iface", JANUS_JSON_STRING, 0},
2208
2216
{"port", JANUS_JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
2209
2217
{"streams", JANUS_JSON_ARRAY, JANUS_JSON_PARAM_REQUIRED},
2210
- {"metadata", JSON_OBJECT, 0}
2218
+ {"metadata", JSON_OBJECT, 0},
2219
+ {"srtp_suite", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
2220
+ {"srtp_crypto", JSON_STRING, 0}
2211
2221
};
2212
2222
static struct janus_json_parameter remote_publisher_update_parameters[] = {
2213
2223
{"secret", JSON_STRING, 0},
2214
2224
{"display", JANUS_JSON_STRING, 0},
2215
2225
{"metadata", JSON_OBJECT, 0},
2216
- {"streams", JANUS_JSON_ARRAY, JANUS_JSON_PARAM_REQUIRED}
2226
+ {"streams", JANUS_JSON_ARRAY, JANUS_JSON_PARAM_REQUIRED},
2227
+ {"srtp_suite", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
2228
+ {"srtp_crypto", JSON_STRING, 0}
2217
2229
};
2218
2230
static struct janus_json_parameter remote_publisher_stream_parameters[] = {
2219
2231
{"mid", JANUS_JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
@@ -2498,6 +2510,12 @@ typedef struct janus_videoroom_publisher_stream {
2498
2510
volatile gint need_pli; /* Whether we need to send a PLI later */
2499
2511
volatile gint sending_pli; /* Whether we're currently sending a PLI */
2500
2512
gint64 pli_latest; /* Time of latest sent PLI (to avoid flooding) */
2513
+ /* Only needed for SRTP support for remote publisher */
2514
+ gboolean is_srtp;
2515
+ int srtp_suite;
2516
+ char *srtp_crypto;
2517
+ srtp_t srtp_ctx;
2518
+ srtp_policy_t srtp_policy;
2501
2519
/* Subscriptions to this publisher stream (who's receiving it) */
2502
2520
GSList *subscribers;
2503
2521
janus_mutex subscribers_mutex;
@@ -2622,11 +2640,15 @@ typedef struct janus_videoroom_remote_recipient {
2622
2640
uint16_t port; /* Port this publisher is being relayed to */
2623
2641
uint16_t rtcp_port; /* RTCP port this publisher is going to latch to */
2624
2642
gboolean rtcp_added; /* Whether we created an RTCP socket for this remotization */
2643
+ /* Only needed for SRTP support for remote publisher */
2644
+ int srtp_suite;
2645
+ char *srtp_crypto;
2625
2646
} janus_videoroom_remote_recipient;
2626
2647
static void janus_videoroom_remote_recipient_free(janus_videoroom_remote_recipient *r) {
2627
2648
if(r) {
2628
2649
g_free(r->remote_id);
2629
2650
g_free(r->host);
2651
+ g_free(r->srtp_crypto);
2630
2652
g_free(r);
2631
2653
}
2632
2654
}
@@ -2710,6 +2732,11 @@ static void janus_videoroom_publisher_stream_free(const janus_refcount *ps_ref)
2710
2732
janus_mutex_destroy(&ps->subscribers_mutex);
2711
2733
janus_mutex_destroy(&ps->rid_mutex);
2712
2734
janus_rtp_simulcasting_cleanup(NULL, NULL, ps->rid, NULL);
2735
+ if(ps->is_srtp) {
2736
+ g_free(ps->srtp_crypto);
2737
+ srtp_dealloc(ps->srtp_ctx);
2738
+ g_free(ps->srtp_policy.key);
2739
+ }
2713
2740
g_free(ps);
2714
2741
}
2715
2742
@@ -7120,6 +7147,22 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7120
7147
if(error_code != 0)
7121
7148
goto prepare_response;
7122
7149
}
7150
+ /* We may need to SRTP-encrypt this stream */
7151
+ int srtp_suite = 0;
7152
+ const char *srtp_crypto = NULL;
7153
+ json_t *s_suite = json_object_get(root, "srtp_suite");
7154
+ json_t *s_crypto = json_object_get(root, "srtp_crypto");
7155
+ if(s_suite && s_crypto) {
7156
+ srtp_suite = json_integer_value(s_suite);
7157
+ if(srtp_suite != 32 && srtp_suite != 80) {
7158
+ JANUS_LOG(LOG_ERR, "Invalid SRTP suite (%d)\n", srtp_suite);
7159
+ error_code = JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT;
7160
+ g_snprintf(error_cause, 512, "Invalid SRTP suite (%d)", srtp_suite);
7161
+ goto prepare_response;
7162
+ }
7163
+ srtp_crypto = json_string_value(s_crypto);
7164
+ JANUS_LOG(LOG_VERB, "SRTP setting s_suite (%d) and s_crypto (%s) on publish_remotely\n", srtp_suite, srtp_crypto);
7165
+ }
7123
7166
const char *remote_id = json_string_value(json_object_get(root, "remote_id"));
7124
7167
json_t *pub_id = json_object_get(root, "publisher_id");
7125
7168
json_t *json_host = json_object_get(root, "host");
@@ -7267,7 +7310,7 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7267
7310
f = janus_videoroom_rtp_forwarder_add_helper(publisher, ps,
7268
7311
host, port, -1, 0,
7269
7312
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP),
7270
- FALSE, 0, NULL , 0, FALSE, FALSE);
7313
+ FALSE, srtp_suite, srtp_crypto , 0, FALSE, FALSE);
7271
7314
if(f != NULL)
7272
7315
f->metadata = g_strdup(remote_id);
7273
7316
} else if(ps->type == JANUS_VIDEOROOM_MEDIA_VIDEO) {
@@ -7276,7 +7319,7 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7276
7319
f = janus_videoroom_rtp_forwarder_add_helper(publisher, ps,
7277
7320
host, port, add_rtcp ? rtcp_port : -1, 0,
7278
7321
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP),
7279
- FALSE, 0, NULL , 0, TRUE, FALSE);
7322
+ FALSE, srtp_suite, srtp_crypto , 0, TRUE, FALSE);
7280
7323
if(f != NULL)
7281
7324
f->metadata = g_strdup(remote_id);
7282
7325
if(add_rtcp)
@@ -7286,15 +7329,15 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7286
7329
f = janus_videoroom_rtp_forwarder_add_helper(publisher, ps,
7287
7330
host, port, -1, 0,
7288
7331
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP + 1),
7289
- FALSE, 0, NULL , 1, TRUE, FALSE);
7332
+ FALSE, srtp_suite, srtp_crypto , 1, TRUE, FALSE);
7290
7333
if(f != NULL)
7291
7334
f->metadata = g_strdup(remote_id);
7292
7335
}
7293
7336
if(ps->vssrc[2] || ps->rid[2]) {
7294
7337
f = janus_videoroom_rtp_forwarder_add_helper(publisher, ps,
7295
7338
host, port, -1, 0,
7296
7339
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP + 2),
7297
- FALSE, 0, NULL , 2, TRUE, FALSE);
7340
+ FALSE, srtp_suite, srtp_crypto , 2, TRUE, FALSE);
7298
7341
if(f != NULL)
7299
7342
f->metadata = g_strdup(remote_id);
7300
7343
}
@@ -7316,6 +7359,8 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7316
7359
recipient->port = port;
7317
7360
recipient->rtcp_port = rtcp_port;
7318
7361
recipient->rtcp_added = rtcp_added;
7362
+ recipient->srtp_suite = srtp_suite;
7363
+ recipient->srtp_crypto = srtp_crypto ? g_strdup(srtp_crypto) : NULL;
7319
7364
g_hash_table_insert(publisher->remote_recipients, g_strdup(remote_id), recipient);
7320
7365
/* Done */
7321
7366
janus_mutex_unlock(&publisher->rtp_forwarders_mutex);
@@ -7592,6 +7637,22 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7592
7637
}
7593
7638
}
7594
7639
}
7640
+ /* We may need to SRTP-decrypt this stream */
7641
+ int srtp_suite = 0;
7642
+ const char *srtp_crypto = NULL;
7643
+ json_t *s_suite = json_object_get(root, "srtp_suite");
7644
+ json_t *s_crypto = json_object_get(root, "srtp_crypto");
7645
+ if(s_suite && s_crypto) {
7646
+ srtp_suite = json_integer_value(s_suite);
7647
+ if(srtp_suite != 32 && srtp_suite != 80) {
7648
+ JANUS_LOG(LOG_ERR, "Invalid SRTP suite (%d)\n", srtp_suite);
7649
+ error_code = JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT;
7650
+ g_snprintf(error_cause, 512, "Invalid SRTP suite (%d)", srtp_suite);
7651
+ goto prepare_response;
7652
+ }
7653
+ srtp_crypto = json_string_value(s_crypto);
7654
+ JANUS_LOG(LOG_VERB, "SRTP setting s_suite (%d) and s_crypto (%s) on add_remote_publisher\n", srtp_suite, srtp_crypto);
7655
+ }
7595
7656
if(error_code != 0)
7596
7657
goto prepare_response;
7597
7658
/* Now access the room */
@@ -7772,6 +7833,45 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7772
7833
gboolean disabled = json_is_true(json_object_get(s, "disabled"));
7773
7834
/* Create a publisher stream */
7774
7835
ps = g_malloc0(sizeof(janus_videoroom_publisher_stream));
7836
+ if(mtype == JANUS_VIDEOROOM_MEDIA_AUDIO || mtype == JANUS_VIDEOROOM_MEDIA_VIDEO) {
7837
+ /* First of all, let's check if we need to setup an SRTP for remote publisher */
7838
+ if(srtp_suite > 0 && srtp_crypto != NULL) {
7839
+ JANUS_LOG(LOG_VERB, "enabling SRTP crypto (%s) for stream.\n", srtp_crypto);
7840
+ gsize len = 0;
7841
+ guchar *srtp_crypto_decoded = g_base64_decode(srtp_crypto, &len);
7842
+ if(len < SRTP_MASTER_LENGTH) {
7843
+ /* Something went wrong */
7844
+ g_free(srtp_crypto_decoded);
7845
+ JANUS_LOG(LOG_ERR, "Invalid SRTP crypto (%s), disabling stream\n", srtp_crypto);
7846
+ ps->is_srtp = FALSE;
7847
+ disabled = TRUE;
7848
+ } else {
7849
+ /* Set SRTP policy */
7850
+ srtp_policy_t *policy = &ps->srtp_policy;
7851
+ srtp_crypto_policy_set_rtp_default(&policy->rtp);
7852
+ if(srtp_suite == 32) {
7853
+ srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy->rtp);
7854
+ } else if(srtp_suite == 80) {
7855
+ srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy->rtp);
7856
+ }
7857
+ policy->ssrc.type = ssrc_any_inbound;
7858
+ policy->key = srtp_crypto_decoded;
7859
+ policy->next = NULL;
7860
+ /* Create SRTP context */
7861
+ srtp_err_status_t res = srtp_create(&ps->srtp_ctx, policy);
7862
+ if(res == srtp_err_status_ok) {
7863
+ ps->is_srtp = TRUE;
7864
+ ps->srtp_suite = srtp_suite;
7865
+ ps->srtp_crypto = g_strdup(srtp_crypto);
7866
+ } else {
7867
+ /* Something went wrong... */
7868
+ JANUS_LOG(LOG_ERR, "Error creating SRTP context: %d (%s), disabling stream\n", res, janus_srtp_error_str(res));
7869
+ ps->is_srtp = FALSE;
7870
+ disabled = TRUE;
7871
+ }
7872
+ }
7873
+ }
7874
+ }
7775
7875
ps->type = mtype;
7776
7876
ps->mindex = mindex;
7777
7877
char mid[5];
@@ -7974,6 +8074,22 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
7974
8074
}
7975
8075
}
7976
8076
}
8077
+ /* We may need to SRTP-decrypt this stream */
8078
+ int srtp_suite = 0;
8079
+ const char *srtp_crypto = NULL;
8080
+ json_t *s_suite = json_object_get(root, "srtp_suite");
8081
+ json_t *s_crypto = json_object_get(root, "srtp_crypto");
8082
+ if(s_suite && s_crypto) {
8083
+ srtp_suite = json_integer_value(s_suite);
8084
+ if(srtp_suite != 32 && srtp_suite != 80) {
8085
+ JANUS_LOG(LOG_ERR, "Invalid SRTP suite (%d)\n", srtp_suite);
8086
+ error_code = JANUS_VIDEOROOM_ERROR_INVALID_ELEMENT;
8087
+ g_snprintf(error_cause, 512, "Invalid SRTP suite (%d)", srtp_suite);
8088
+ goto prepare_response;
8089
+ }
8090
+ srtp_crypto = json_string_value(s_crypto);
8091
+ JANUS_LOG(LOG_VERB, "SRTP setting s_suite (%d) and s_crypto (%s) on add_remote_publisher\n", srtp_suite, srtp_crypto);
8092
+ }
7977
8093
if(error_code != 0)
7978
8094
goto prepare_response;
7979
8095
/* Now access the room */
@@ -8061,6 +8177,46 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
8061
8177
gboolean disabled = json_is_true(json_object_get(s, "disabled"));
8062
8178
/* Create a publisher stream */
8063
8179
ps = g_malloc0(sizeof(janus_videoroom_publisher_stream));
8180
+ if(mtype == JANUS_VIDEOROOM_MEDIA_AUDIO || mtype == JANUS_VIDEOROOM_MEDIA_VIDEO) {
8181
+ /* First of all, let's check if we need to setup an SRTP for remote publisher */
8182
+ if(srtp_suite > 0 && srtp_crypto != NULL) {
8183
+ JANUS_LOG(LOG_VERB, "Enabling SRTP crypto (%s) for stream\n", srtp_crypto);
8184
+ gsize len = 0;
8185
+ guchar *srtp_crypto_decoded = g_base64_decode(srtp_crypto, &len);
8186
+ if(len < SRTP_MASTER_LENGTH) {
8187
+ /* Something went wrong */
8188
+ g_free(srtp_crypto_decoded);
8189
+ JANUS_LOG(LOG_ERR, "Invalid SRTP crypto (%s), disabling stream\n", srtp_crypto);
8190
+ disabled = TRUE;
8191
+ } else {
8192
+ /* Set SRTP policy */
8193
+ srtp_policy_t *policy = &ps->srtp_policy;
8194
+ srtp_crypto_policy_set_rtp_default(&policy->rtp);
8195
+ if(srtp_suite == 32) {
8196
+ srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy->rtp);
8197
+ } else if(srtp_suite == 80) {
8198
+ srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy->rtp);
8199
+ }
8200
+ policy->ssrc.type = ssrc_any_inbound;
8201
+ policy->key = srtp_crypto_decoded;
8202
+ policy->next = NULL;
8203
+ /* Create SRTP context */
8204
+ srtp_err_status_t res = srtp_create(&ps->srtp_ctx, policy);
8205
+ if(res == srtp_err_status_ok) {
8206
+ ps->is_srtp = TRUE;
8207
+ ps->srtp_suite = srtp_suite;
8208
+ ps->srtp_crypto = g_strdup(srtp_crypto);
8209
+ } else {
8210
+ /* Something went wrong... */
8211
+ JANUS_LOG(LOG_ERR, "Error creating SRTP context: %d (%s), disabling stream\n", res, janus_srtp_error_str(res));
8212
+ ps->is_srtp = FALSE;
8213
+ disabled = TRUE;
8214
+ }
8215
+ }
8216
+ } else {
8217
+ JANUS_LOG(LOG_ERR, "SRTP crypto (%d) (%s) not enabled for stream\n", srtp_suite, srtp_crypto);
8218
+ }
8219
+ }
8064
8220
ps->type = mtype;
8065
8221
ps->mindex = mindex;
8066
8222
char pmid[5];
@@ -12918,7 +13074,7 @@ static void *janus_videoroom_handler(void *data) {
12918
13074
f = janus_videoroom_rtp_forwarder_add_helper(participant, ps,
12919
13075
r->host, r->port, -1, 0,
12920
13076
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP),
12921
- FALSE, 0, NULL , 0, FALSE, FALSE);
13077
+ FALSE, r->srtp_suite, r->srtp_crypto , 0, FALSE, FALSE);
12922
13078
if(f != NULL)
12923
13079
f->metadata = g_strdup(r->remote_id);
12924
13080
} else if(ps->type == JANUS_VIDEOROOM_MEDIA_VIDEO) {
@@ -12927,7 +13083,7 @@ static void *janus_videoroom_handler(void *data) {
12927
13083
f = janus_videoroom_rtp_forwarder_add_helper(participant, ps,
12928
13084
r->host, r->port, add_rtcp ? r->rtcp_port : -1, 0,
12929
13085
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP),
12930
- FALSE, 0, NULL , 0, TRUE, FALSE);
13086
+ FALSE, r->srtp_suite, r->srtp_crypto , 0, TRUE, FALSE);
12931
13087
if(f != NULL)
12932
13088
f->metadata = g_strdup(r->remote_id);
12933
13089
if(add_rtcp)
@@ -12937,15 +13093,15 @@ static void *janus_videoroom_handler(void *data) {
12937
13093
f = janus_videoroom_rtp_forwarder_add_helper(participant, ps,
12938
13094
r->host, r->port, -1, 0,
12939
13095
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP + 1),
12940
- FALSE, 0, NULL , 1, TRUE, FALSE);
13096
+ FALSE, r->srtp_suite, r->srtp_crypto , 1, TRUE, FALSE);
12941
13097
if(f != NULL)
12942
13098
f->metadata = g_strdup(r->remote_id);
12943
13099
}
12944
13100
if(ps->vssrc[2] || ps->rid[2]) {
12945
13101
f = janus_videoroom_rtp_forwarder_add_helper(participant, ps,
12946
13102
r->host, r->port, -1, 0,
12947
13103
(REMOTE_PUBLISHER_BASE_SSRC + ps->mindex*REMOTE_PUBLISHER_SSRC_STEP + 2),
12948
- FALSE, 0, NULL , 2, TRUE, FALSE);
13104
+ FALSE, r->srtp_suite, r->srtp_crypto , 2, TRUE, FALSE);
12949
13105
if(f != NULL)
12950
13106
f->metadata = g_strdup(r->remote_id);
12951
13107
}
@@ -13745,6 +13901,20 @@ static void *janus_videoroom_remote_publisher_thread(void *user_data) {
13745
13901
janus_videoroom_incoming_data_internal(publisher->session, publisher, &data);
13746
13902
continue;
13747
13903
}
13904
+ /* Is this SRTP? */
13905
+ if(ps->is_srtp) {
13906
+ int buflen = bytes;
13907
+ srtp_err_status_t res = srtp_unprotect(ps->srtp_ctx, buffer, &buflen);
13908
+ if(res != srtp_err_status_ok) {
13909
+ janus_mutex_unlock(&publisher->streams_mutex);
13910
+ guint32 timestamp = ntohl(rtp->timestamp);
13911
+ guint16 seq = ntohs(rtp->seq_number);
13912
+ JANUS_LOG(LOG_ERR, "[%s] Publisher stream (#%d) SRTP unprotect error: %s (len=%d-->%d, ts=%"SCNu32", seq=%"SCNu16")\n",
13913
+ publisher->user_id_str, ps->mindex, janus_srtp_error_str(res), bytes, buflen, timestamp, seq);
13914
+ continue;
13915
+ }
13916
+ bytes = buflen;
13917
+ }
13748
13918
/* Prepare the RTP packet */
13749
13919
pkt.mindex = mindex;
13750
13920
pkt.video = (ps->type == JANUS_VIDEOROOM_MEDIA_VIDEO);
0 commit comments