int _remove_media_source(webrtc_s *webrtc, unsigned int source_id);
int _set_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_direction_e direction);
int _get_transceiver_direction(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_direction_e *direction);
+void _update_transceivers_fec(webrtc_s *webrtc, bool is_offer);
int _set_pause(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool pause);
int _get_pause(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool *paused);
int _set_audio_mute(webrtc_s *webrtc, unsigned int source_id, bool mute);
LOG_INFO("webrtc[%p] offer[%p]", webrtc, offer);
+ _update_transceivers_fec(webrtc, true);
+
return _webrtcbin_create_session_description(webrtc, true, offer);
}
LOG_INFO("webrtc[%p] answer[%p]", webrtc, answer);
+ _update_transceivers_fec(webrtc, false);
+
return _webrtcbin_create_session_description(webrtc, false, answer);
}
GHashTableIter iter;
gpointer key, value;
webrtc_gst_slot_s *source;
- const ini_item_media_source_s *ini_source;
int i;
RET_IF(webrtcbin == NULL, "webrtcbin is NULL");
source->av[i].mline = transceiver->mline;
LOG_DEBUG("source[%s, id:%u, mline:%d for %s]",
(gchar*)key, source->id, source->av[i].mline, i == AV_IDX_AUDIO ? "AUDIO" : "VIDEO");
+ return;
+ }
+ }
+ }
+}
- ini_source = _ini_get_source_by_type(&webrtc->ini, source->type);
- if (ini_source == NULL)
- ini_source = &(webrtc->ini.media_source);
- if (!ini_source->use_ulpfec_red)
- return;
+void _update_transceivers_fec(webrtc_s *webrtc, bool is_offer)
+{
+ const ini_item_media_source_s *ini_source;
+ GstWebRTCRTPTransceiver *transceiver;
+ GHashTableIter iter;
+ gpointer key, value;
+ webrtc_gst_slot_s *source;
+ int i;
+
+ RET_IF(webrtc == NULL, "webrtc is NULL");
+ g_hash_table_iter_init(&iter, webrtc->gst.source_slots);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ source = (webrtc_gst_slot_s*)value;
+ for (i = AV_IDX_AUDIO; i < AV_IDX_MAX; i++) {
+ if (!(source->media_types & (i == AV_IDX_AUDIO ? MEDIA_TYPE_AUDIO : MEDIA_TYPE_VIDEO)))
+ continue;
+ if (source->av[i].mline == -1)
+ continue;
+
+ g_signal_emit_by_name(G_OBJECT(webrtc->gst.webrtcbin), "get-transceiver", source->av[i].mline, &transceiver);
+ if (!transceiver) {
+ LOG_ERROR("transceiver of mline[%u] is NULL", source->av[i].mline);
+ continue;
+ }
+
+ ini_source = _ini_get_source_by_type(&webrtc->ini, source->type);
+ if (ini_source == NULL)
+ ini_source = &(webrtc->ini.media_source);
+
+ if (is_offer) {
+ if (!ini_source->use_ulpfec_red)
+ continue;
+ __webrtcbin_transceiver_set_ulpfec_red(webrtc, transceiver);
+ } else {
+ /* NOTE that this maximum value exists only for data_recovery_types due to the scenario an answerer
+ * without any added media sources. It would be moved to the source slot without this scenario. */
+ if (transceiver->mline >= MAX_MLINE_NUM) {
+ LOG_ERROR("mline[%u] exceeds the max value", transceiver->mline);
+ continue;
+ }
+ if (!webrtc->data_recovery_types[transceiver->mline].red ||
+ !webrtc->data_recovery_types[transceiver->mline].ulpfec)
+ continue;
__webrtcbin_transceiver_set_ulpfec_red(webrtc, transceiver);
- __webrtcbin_transceiver_set_fec_percentage(webrtc, transceiver, ini_source->fec_percentage);
- return;
}
+
+ if (transceiver->direction == GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDONLY ||
+ transceiver->direction == GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV)
+ __webrtcbin_transceiver_set_fec_percentage(webrtc, transceiver, ini_source->fec_percentage);
}
}
}