#include "webrtc_internal.h"
#include "webrtc_private.h"
+#include "webrtc_source_private.h"
//LCOV_EXCL_START
int webrtc_set_ecore_wl_display(webrtc_h webrtc, unsigned int track_id, void *ecore_wl_window)
return WEBRTC_ERROR_NONE;
}
+int webrtc_null_source_set_media_type(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type)
+{
+ webrtc_s *_webrtc = (webrtc_s *)webrtc;
+ webrtc_gst_slot_s *source;
+ g_autoptr(GMutexLocker) locker = NULL;
+ int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
+ int av_opposite_idx = (av_idx == AV_IDX_AUDIO) ? AV_IDX_VIDEO : AV_IDX_AUDIO;
+ const ini_item_media_source_s *ini_source;
+ int ret;
+ g_autofree gchar *joined_str_codecs = NULL;
+ int i;
+
+ RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0");
+
+ locker = g_mutex_locker_new(&_webrtc->mutex);
+
+ RET_VAL_IF((source = _get_slot_by_id(_webrtc->gst.source_slots, source_id)) == NULL,
+ WEBRTC_ERROR_INVALID_PARAMETER, "could not find source");
+ RET_VAL_IF(source->type != WEBRTC_MEDIA_SOURCE_TYPE_NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source type is not WEBRTC_MEDIA_SOURCE_TYPE_NULL");
+ RET_VAL_IF(source->av[av_idx].codec, WEBRTC_ERROR_INVALID_OPERATION, "codec[%s] was already set", source->av[av_idx].codec);
+ RET_VAL_IF(source->av[av_opposite_idx].codec, WEBRTC_ERROR_INVALID_OPERATION, "codec[%s] was already set", source->av[av_opposite_idx].codec);
+
+ ret = _build_src_check_params_and_get_ini_source(webrtc, source, &ini_source);
+ RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _build_src_check_params_and_get_ini_source()");
+
+ /* clean up the other side */
+ for (i = 0; i < source->av[av_opposite_idx].num_of_codecs; i++) {
+ source->av[av_opposite_idx].multiple_codecs[i].codec = NULL;
+ source->av[av_opposite_idx].multiple_codecs[i].pt = 0;
+ }
+
+ GStrv codecs = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? ini_source->a_codecs : ini_source->v_codecs;
+ source->av[av_idx].num_of_codecs = g_strv_length(codecs);
+ for (i = 0; i < source->av[av_idx].num_of_codecs; i++) {
+ source->av[av_idx].multiple_codecs[i].codec = codecs[i];
+ }
+
+ source->media_types = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? MEDIA_TYPE_AUDIO : MEDIA_TYPE_VIDEO;
+
+ LOG_INFO("webrtc[%p] source_id[%u] media_type[%d]", _webrtc, source_id, media_type);
+
+ joined_str_codecs = g_strjoinv(" ", codecs);
+ LOG_INFO(" - codecs: %s", joined_str_codecs);
+
+ return WEBRTC_ERROR_NONE;
+}
+
int webrtc_get_local_description(webrtc_h webrtc, char **description)
{
g_autoptr(GMutexLocker) locker = NULL;
return WEBRTC_ERROR_NONE;
}
+int __add_transceiver_with_multiple_codecs(webrtc_gst_slot_s *source, webrtc_media_type_e media_type)
+{
+ int i;
+ GstWebRTCRTPTransceiver *trans;
+ GstCaps *caps = NULL;
+ GstCaps *_caps;
+ int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
+ rtp_payload_info_s *payload_info = NULL;
+ int pt;
+
+ ASSERT(source);
+
+ for (i = 0; i < source->av[av_idx].num_of_codecs; i++) {
+ if (!(payload_info = __get_payload_info_by_encoding_name(source->av[av_idx].multiple_codecs[i].codec)))
+ return WEBRTC_ERROR_INVALID_OPERATION;
+
+ if ((pt = __get_available_payload_type(source->webrtc)) == -1)
+ return WEBRTC_ERROR_INVALID_OPERATION;
+
+ source->av[av_idx].multiple_codecs[i].pt = pt;
+
+ _caps = gst_caps_new_simple("application/x-rtp",
+ "media", G_TYPE_STRING, payload_info->media_type,
+ "encoding-name", G_TYPE_STRING, payload_info->encoding_name,
+ "clock-rate", G_TYPE_INT, payload_info->clock_rate,
+ "payload", G_TYPE_INT, pt,
+ NULL);
+ if (payload_info->codec == WEBRTC_TRANSCEIVER_CODEC_OPUS)
+ gst_caps_set_simple(_caps,
+ "encoding-params", G_TYPE_STRING, "2",
+ NULL);
+ else if (payload_info->codec == WEBRTC_TRANSCEIVER_CODEC_H264)
+ gst_caps_set_simple(_caps,
+ "level-asymmetry-allowed", G_TYPE_STRING, "1",
+ "packetization-mode", G_TYPE_STRING, "1",
+ "profile-level-id", G_TYPE_STRING, "42e01f",
+ NULL);
+
+ if (i == 0)
+ caps = _caps;
+ else
+ gst_caps_append(caps, _caps);
+ }
+
+ ASSERT(caps);
+ PRINT_CAPS(caps, "transceiver");
+
+ if (!source->av[av_idx].transceiver) {
+ g_signal_emit_by_name(source->webrtc->gst.webrtcbin, "add-transceiver",
+ GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY, caps, &trans, NULL);
+ gst_object_unref(trans);
+
+ } else {
+ g_object_set(G_OBJECT(source->av[av_idx].transceiver), "codec-preferences", caps, NULL);
+ }
+
+ gst_caps_unref(caps);
+
+ LOG_DEBUG("webrtc[%p] source_id[%u] [%s] transceiver[%p]",
+ source->webrtc, source->id, payload_info->media_type, source->av[av_idx].transceiver);
+
+ return WEBRTC_ERROR_NONE;
+}
+
int _check_and_add_recvonly_transceiver(webrtc_gst_slot_s *source)
{
rtp_payload_info_s *payload_info = NULL;
for (i = AV_IDX_AUDIO; i < AV_IDX_MAX; i++) {
media_type = (i == AV_IDX_AUDIO) ? WEBRTC_MEDIA_TYPE_AUDIO : WEBRTC_MEDIA_TYPE_VIDEO;
- if (source->av[i].direction == WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY && source->av[i].codec) {
- if (g_hash_table_size(source->av[i].encodings) > 0)
- __add_transceiver_for_simulcast(source, media_type);
- else if (!(payload_info = __get_payload_info_by_encoding_name(source->av[i].codec)))
- return WEBRTC_ERROR_INVALID_OPERATION;
- _add_transceiver(source, media_type, payload_info);
+ if (source->av[i].direction == WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY) {
+ if (source->av[i].codec) {
+ if (g_hash_table_size(source->av[i].encodings) > 0)
+ __add_transceiver_for_simulcast(source, media_type);
+ else if (!(payload_info = __get_payload_info_by_encoding_name(source->av[i].codec)))
+ return WEBRTC_ERROR_INVALID_OPERATION;
+ _add_transceiver(source, media_type, payload_info);
+
+ } else if (source->av[i].num_of_codecs > 0) {
+ __add_transceiver_with_multiple_codecs(source, media_type);
+ }
}
}
return WEBRTC_ERROR_NONE;
GstCaps *caps;
int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
- RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
- RET_VAL_IF(payload_info == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "payload_info is NULL");
+ ASSERT(source);
+ ASSERT(payload_info);
caps = __make_transceiver_caps(payload_info);
PRINT_CAPS(caps, "transceiver");
/* NOTE: for null source, set media_types here exceptionally. */
if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL)
- source->media_types |= (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? MEDIA_TYPE_AUDIO : MEDIA_TYPE_VIDEO;
+ source->media_types = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? MEDIA_TYPE_AUDIO : MEDIA_TYPE_VIDEO;
if ((ret = __validate_codec(webrtc, source, media_type, codec)) != WEBRTC_ERROR_NONE)
return ret;
source->av[av_idx].codec = payload_info->encoding_name;
+ /* clean up multiple codecs */
+ source->av[av_idx].num_of_codecs = 0;
+
/* FIXME: to utilize 'codec-preferences' of trans object, we need to re-create and re-link elements again */
LOG_INFO("webrtc[%p] source_id[%u] media_type[%d] codec[%s]", webrtc, source_id, media_type, payload_info->encoding_name);