[WEBRTC_TRANSCEIVER_DIRECTION_SENDRECV] = { "SENDRECV", GST_WEBRTC_RTP_TRANSCEIVER_DIRECTION_SENDRECV }
};
+typedef struct {
+ webrtc_transceiver_codec_e codec;
+ const char *gst_media_type;
+ const char *media_type;
+ const char *encoding_name;
+ int clock_rate;
+} rtp_payload_info_s;
+
+static rtp_payload_info_s __payload_info[] = {
+ { WEBRTC_TRANSCEIVER_CODEC_PCMU, MEDIA_TYPE_AUDIO_MULAW, "audio", "PCMU", 8000 },
+ { WEBRTC_TRANSCEIVER_CODEC_PCMA, MEDIA_TYPE_AUDIO_ALAW, "audio", "PCMA", 8000 },
+ { WEBRTC_TRANSCEIVER_CODEC_OPUS, MEDIA_TYPE_AUDIO_OPUS, "audio", "OPUS", 48000 },
+ { WEBRTC_TRANSCEIVER_CODEC_VP8, MEDIA_TYPE_VIDEO_VP8, "video", "VP8", 90000 },
+ { WEBRTC_TRANSCEIVER_CODEC_VP9, MEDIA_TYPE_VIDEO_VP9, "video", "VP9", 90000 },
+ { WEBRTC_TRANSCEIVER_CODEC_H264, MEDIA_TYPE_VIDEO_H264, "video", "H264", 90000 },
+ { 0, NULL, NULL, NULL, 0 }
+};
+
typedef struct {
const char *appsrc_name;
const char *queue_name;
case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
case WEBRTC_MEDIA_SOURCE_TYPE_SCREEN:
case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO:
- _media_type = __get_video_media_type(ini_source->v_codec);
+ _media_type = __get_video_media_type(source->av[AV_IDX_VIDEO].codec);
RET_VAL_IF(_media_type == NULL, NULL, "_media_type is NULL");
caps = __get_caps_from_encoded_video_media_type(_media_type, ini_source->v_width, ini_source->v_height);
case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
case WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO:
- _media_type = __get_audio_media_type(ini_source->a_codec);
+ _media_type = __get_audio_media_type(source->av[AV_IDX_AUDIO].codec);
RET_VAL_IF(_media_type == NULL, NULL, "_media_type is NULL");
caps = __get_caps_from_encoded_audio_media_type(_media_type, ini_source->a_channels, ini_source->a_samplerate);
break;
}
//LCOV_EXCL_START
+static GstCaps *__make_transceiver_caps(rtp_payload_info_s *payload_info, int payload_type)
+{
+ RET_VAL_IF(payload_info == NULL, NULL, "payload_info is NULL");
+
+ return 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, payload_type,
+ NULL);
+}
+
/* Use g_free() to free the media_type parameter. */
static GstCaps *__make_encoded_caps_from_media_format(webrtc_gst_slot_s *source, gchar **media_type)
{
source->media_types = MEDIA_TYPE_VIDEO;
source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
+ source->av[AV_IDX_VIDEO].codec = ini_source->v_codec;
if (!(screensrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_SCREEN), ELEMENT_NAME_SCREENSRC)))
return WEBRTC_ERROR_INVALID_OPERATION;
source->media_types = MEDIA_TYPE_VIDEO;
source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
+ source->av[AV_IDX_VIDEO].codec = ini_source->v_codec;
#ifndef TIZEN_TV
if (webrtc->ini.resource_acquisition.camera)
source->media_types = MEDIA_TYPE_AUDIO;
source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
source->av[AV_IDX_AUDIO].raw_format = g_strdup(ini_source->a_raw_format);
+ source->av[AV_IDX_AUDIO].codec = ini_source->a_codec;
source_factory_name = __get_source_element(webrtc, use_mic ? WEBRTC_MEDIA_SOURCE_TYPE_MIC : WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST);
if (!(audiosrc = _create_element(source_factory_name, use_mic ? ELEMENT_NAME_MIC_SRC: NULL)))
source->media_types = MEDIA_TYPE_VIDEO;
source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
source->av[AV_IDX_VIDEO].raw_format = g_strdup(ini_source->v_raw_format);
+ source->av[AV_IDX_VIDEO].codec = ini_source->v_codec;
if (!(videotestsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST), ELEMENT_NAME_VIDEO_SRC)))
return WEBRTC_ERROR_INVALID_OPERATION;
static int __build_custom_videosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
{
int ret = WEBRTC_ERROR_NONE;
+ const ini_item_media_source_s *ini_source;
GstElement *custom_videosrc;
GstElement *capsfilter;
GList *element_list = NULL;
RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+ if (!(ini_source = _ini_get_source_by_type(&webrtc->ini, source->type))) {
+ LOG_ERROR("ini_source is NULL");
+ return WEBRTC_ERROR_INVALID_OPERATION;
+ }
+
ret = _add_no_target_ghostpad_to_slot(source, true, &src_pad);
RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _add_no_target_ghostpad_to_slot()");
source->media_types = MEDIA_TYPE_VIDEO;
source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+ source->av[AV_IDX_VIDEO].codec = ini_source->v_codec;
if (!(custom_videosrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO), ELEMENT_NAME_VIDEO_SRC)))
return WEBRTC_ERROR_INVALID_OPERATION;
static int __build_custom_audiosrc(webrtc_s *webrtc, webrtc_gst_slot_s *source)
{
int ret = WEBRTC_ERROR_NONE;
+ const ini_item_media_source_s *ini_source;
const char *source_factory_name;
GstElement *custom_audiosrc;
GstElement *volume;
RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
+ if (!(ini_source = _ini_get_source_by_type(&webrtc->ini, source->type))) {
+ LOG_ERROR("ini_source is NULL");
+ return WEBRTC_ERROR_INVALID_OPERATION;
+ }
+
ret = _add_no_target_ghostpad_to_slot(source, true, &src_pad);
RET_VAL_IF(ret != WEBRTC_ERROR_NONE, ret, "failed to _add_no_target_ghostpad_to_slot()");
source->media_types = MEDIA_TYPE_AUDIO;
source->zerocopy_enabled = __is_hw_encoder_used(webrtc, source->type, source->media_types);
+ source->av[AV_IDX_AUDIO].codec = ini_source->a_codec;
source_factory_name = __get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_AUDIO);
if (!(custom_audiosrc = _create_element(source_factory_name, NULL)))
RET_IF(source == NULL, "source is NULL");
LOG_DEBUG("[%s, id:%u, media_types:0x%x, [AUDIO]mline:%d, [VIDEO]mline:%d] is removed",
- GST_ELEMENT_NAME(source->bin), source->id, source->media_types, source->av[AV_IDX_AUDIO].mline, source->av[AV_IDX_VIDEO].mline);
+ source->bin ? GST_ELEMENT_NAME(source->bin) : "null", source->id, source->media_types,
+ source->av[AV_IDX_AUDIO].mline, source->av[AV_IDX_VIDEO].mline);
- gst_element_foreach_src_pad(GST_ELEMENT(source->bin), __foreach_src_pad_cb, source);
+ if (source->bin)
+ gst_element_foreach_src_pad(GST_ELEMENT(source->bin), __foreach_src_pad_cb, source);
for (i = 0; i < AV_IDX_MAX; i++) {
__remove_probe_from_pad_for_pause(source, i);
SAFE_GST_OBJECT_UNREF(source->av[i].render.pipeline);
}
+ if (source->av[i].transceiver)
+ gst_object_unref(source->av[i].transceiver);
+
g_free(source->av[i].raw_format);
}
- gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), GST_ELEMENT(source->bin));
+ if (source->bin)
+ gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), GST_ELEMENT(source->bin));
if (source->media_format)
media_format_unref(source->media_format);
return ret;
}
+//LCOV_EXCL_START
+static int __add_null_source(webrtc_s *webrtc, unsigned int *source_id)
+{
+ unsigned int id;
+ webrtc_gst_slot_s *source = NULL;
+ gchar *bin_name = NULL;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(source_id == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is NULL");
+ RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
+
+ /* bin_name/source will be freed by function which is set to g_hash_table_new_full() */
+ id = __get_unoccupied_id(webrtc->gst.source_slots);
+ RET_VAL_IF(id == 0, WEBRTC_ERROR_INVALID_OPERATION, "source_slots are full");
+
+ bin_name = g_strdup_printf("media_source_%u", id);
+
+ MALLOC_AND_INIT_SLOT(source, id, bin_name, webrtc);
+ source->type = WEBRTC_MEDIA_SOURCE_TYPE_NULL;
+ /* This functionality comes from 7.0 branch, but it is not prepared for all the codes of 7.0, we unref the bin here temporarily. */
+ SAFE_GST_OBJECT_UNREF(source->bin);
+
+ /* The gst_element_get_request_pad() of webrtcbin will trigger the transceiver callback. To update the mline value of
+ * new transceiver object to the source structure in the callback, hash table inserting should be preceded. */
+ if (!g_hash_table_insert(webrtc->gst.source_slots, bin_name, (gpointer)source)) {
+ LOG_ERROR("should not be reached here, name[%s] already exist, source id[%u] will be removed", bin_name, source->id);
+ g_hash_table_remove(webrtc->gst.source_slots, bin_name);
+ return WEBRTC_ERROR_INVALID_OPERATION;
+ }
+
+ *source_id = source->id;
+
+ LOG_INFO("added a source slot[%p, id:%u]", source, source->id);
+
+ return WEBRTC_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
+
static int __add_media_source(webrtc_s *webrtc, int type, unsigned int *source_id)
{
int ret = WEBRTC_ERROR_NONE;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
RET_VAL_IF(source_id == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is NULL");
RET_VAL_IF(type <= WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET, WEBRTC_ERROR_INVALID_PARAMETER, "invalid internal source type(%d)", type);
- RET_VAL_IF(type > WEBRTC_MEDIA_SOURCE_TYPE_CUSTOM_VIDEO, WEBRTC_ERROR_INVALID_PARAMETER, "invalid internal source type(%d)", type);
+ RET_VAL_IF(type > WEBRTC_MEDIA_SOURCE_TYPE_NULL, WEBRTC_ERROR_INVALID_PARAMETER, "invalid internal source type(%d)", type);
RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
+ if (type == WEBRTC_MEDIA_SOURCE_TYPE_NULL)
+ return __add_null_source(webrtc, source_id);
+
return __add_media_source(webrtc, type, source_id);
}
//LCOV_EXCL_STOP
RET_VAL_IF(webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL");
RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+ RET_VAL_IF(source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL && direction != WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY,
+ WEBRTC_ERROR_INVALID_PARAMETER, "null source only allow RECVONLY direction");
if (media_type == WEBRTC_MEDIA_TYPE_AUDIO && source->media_types & MEDIA_TYPE_AUDIO) {
mline = source->av[AV_IDX_AUDIO].mline;
return ret;
}
+//LCOV_EXCL_START
+static int __convert_audio_codec(const char *codec_name, webrtc_transceiver_codec_e *codec)
+{
+ RET_VAL_IF(codec_name == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec_name is NULL");
+ RET_VAL_IF(codec == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec is NULL");
+
+ if (!strcmp(codec_name, "pcmu") || !strcmp(codec_name, "PCMU")) {
+ *codec = WEBRTC_TRANSCEIVER_CODEC_PCMU;
+ return WEBRTC_ERROR_NONE;
+ }
+ if (!strcmp(codec_name, "pcma") || !strcmp(codec_name, "PCMA")) {
+ *codec = WEBRTC_TRANSCEIVER_CODEC_PCMA;
+ return WEBRTC_ERROR_NONE;
+ }
+ if (!strcmp(codec_name, "opus") || !strcmp(codec_name, "OPUS")) {
+ *codec = WEBRTC_TRANSCEIVER_CODEC_OPUS;
+ return WEBRTC_ERROR_NONE;
+ }
+
+ LOG_ERROR("not supported audio codec_name[%s]", codec_name);
+
+ return WEBRTC_ERROR_INVALID_PARAMETER;
+}
+
+static int __convert_video_codec(const char *codec_name, webrtc_transceiver_codec_e *codec)
+{
+ RET_VAL_IF(codec_name == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec_name is NULL");
+ RET_VAL_IF(codec == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec is NULL");
+
+ if (!strcmp(codec_name, "vp8") || !strcmp(codec_name, "VP8")) {
+ *codec = WEBRTC_TRANSCEIVER_CODEC_VP8;
+ return WEBRTC_ERROR_NONE;
+ }
+ if (!strcmp(codec_name, "vp9") || !strcmp(codec_name, "VP9")) {
+ *codec = WEBRTC_TRANSCEIVER_CODEC_VP9;
+ return WEBRTC_ERROR_NONE;
+ }
+ if (!strcmp(codec_name, "h264") || !strcmp(codec_name, "H264")) {
+ *codec = WEBRTC_TRANSCEIVER_CODEC_H264;
+ return WEBRTC_ERROR_NONE;
+ }
+
+ LOG_ERROR("not supported video codec_name[%s]", codec_name);
+
+ return WEBRTC_ERROR_INVALID_PARAMETER;
+}
+
+typedef int (*convert_codec_func)(const char *codec_name, webrtc_transceiver_codec_e *codec);
+
+static convert_codec_func convert_codec_funcs[] = {
+ [WEBRTC_MEDIA_TYPE_AUDIO] = __convert_audio_codec,
+ [WEBRTC_MEDIA_TYPE_VIDEO] = __convert_video_codec,
+};
+
+int _set_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, int codec)
+{
+ webrtc_gst_slot_s *source;
+ int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
+ int i;
+ rtp_payload_info_s *payload_info = NULL;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL");
+ RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
+ RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+ RET_VAL_IF((source->type != WEBRTC_MEDIA_SOURCE_TYPE_NULL), WEBRTC_ERROR_INVALID_PARAMETER, "this API only supports the null source");
+
+ for (i = 0; i != (int)__payload_info[i].codec; i++) {
+ if (__payload_info[i].codec != (webrtc_transceiver_codec_e)codec)
+ continue;
+ payload_info = &__payload_info[i];
+ break;
+ }
+ RET_VAL_IF(payload_info == NULL, WEBRTC_ERROR_INVALID_OPERATION, "could not find payload_info");
+
+ /* FIXME: check media_type with valid codec type */
+ source->media_types |= (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? MEDIA_TYPE_AUDIO : MEDIA_TYPE_VIDEO;
+
+ source->av[av_idx].codec = payload_info->encoding_name;
+
+ if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL) {
+ GstWebRTCRTPTransceiver *trans = NULL;
+ GstCaps *caps;
+ int payload_id;
+
+ if ((payload_id = __get_fixed_payload_id(payload_info->gst_media_type)) == -1)
+ if ((payload_id = __get_available_payload_id(webrtc)) == 0)
+ return WEBRTC_ERROR_NONE;
+ source->av[av_idx].payload_id = payload_id;
+
+ caps = __make_transceiver_caps(payload_info, payload_id);
+ PRINT_CAPS(caps, "transceiver");
+
+ if (!source->av[av_idx].transceiver) {
+ g_signal_emit_by_name(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);
+ }
+ LOG_DEBUG("webrtc[%p] source_id[%u] [%s] transceiver[%p] codec[%s]",
+ webrtc, source_id, payload_info->media_type, source->av[av_idx].transceiver, payload_info->encoding_name);
+
+ gst_caps_unref(caps);
+ }
+
+ /* 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);
+
+ return WEBRTC_ERROR_NONE;
+}
+
+int _get_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, int *codec)
+{
+ int ret;
+ webrtc_gst_slot_s *source;
+ const char *codec_str;
+ webrtc_transceiver_codec_e _codec;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(codec == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "codec is NULL");
+ RET_VAL_IF(webrtc->gst.webrtcbin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "webrtcbin is NULL");
+ RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
+ RET_VAL_IF((source = _get_slot_by_id(webrtc->gst.source_slots, source_id)) == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+
+ if (media_type == WEBRTC_MEDIA_TYPE_AUDIO && source->media_types & MEDIA_TYPE_AUDIO) {
+ codec_str = source->av[AV_IDX_AUDIO].codec;
+
+ } else if (media_type == WEBRTC_MEDIA_TYPE_VIDEO && source->media_types & MEDIA_TYPE_VIDEO) {
+ codec_str = source->av[AV_IDX_VIDEO].codec;
+
+ } else {
+ LOG_ERROR("invalid media_type[%d] for source[media_types:0x%x, id:%u]", media_type, source->media_types, source_id);
+ return WEBRTC_ERROR_INVALID_PARAMETER;
+ }
+
+ if ((ret = convert_codec_funcs[media_type](codec_str, &_codec)) != WEBRTC_ERROR_NONE)
+ return ret;
+
+ *codec = _codec;
+
+ LOG_INFO("webrtc[%p] source_id[%u] media_type[%d] codec[%s]", webrtc, source_id, media_type, codec_str);
+
+ return WEBRTC_ERROR_NONE;
+}
+//LCOV_EXCL_STOP
+
int _set_pause(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool pause)
{
webrtc_gst_slot_s *source;
RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
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, "this API does not support the null source");
switch (media_type) {
case WEBRTC_MEDIA_TYPE_AUDIO:
RET_VAL_IF(paused == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "paused is NULL");
RET_VAL_IF(webrtc->gst.source_slots == NULL, WEBRTC_ERROR_INVALID_OPERATION, "source_slots is NULL");
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, "this API does not support the null source");
switch (media_type) {
case WEBRTC_MEDIA_TYPE_AUDIO:
RET_VAL_IF((source->media_types & MEDIA_TYPE_VIDEO) == 0x0, WEBRTC_ERROR_INVALID_PARAMETER, "it's not a video source");
RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the file source");
RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the media packet source");
+ RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the null source");
if (webrtc->state != WEBRTC_STATE_IDLE) {
ini_item_media_source_s *ini_source;
RET_VAL_IF((source->media_types & MEDIA_TYPE_VIDEO) == 0x0, WEBRTC_ERROR_INVALID_PARAMETER, "it's not a video source");
RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the file source");
RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the media packet source");
+ RET_VAL_IF((source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL), WEBRTC_ERROR_INVALID_PARAMETER, "this API does not support the null source");
*width = source->video_info.width;
*height = source->video_info.height;
}
//LCOV_EXCL_START
+static gboolean __check_transceiver_is_not_set_cb(gpointer key, gpointer value, gpointer user_data)
+{
+ const webrtc_gst_slot_s *source = (webrtc_gst_slot_s *)value;
+ int i;
+
+ if (source->type == GPOINTER_TO_INT(user_data)) {
+ LOG_INFO("found media null source[%p, id:%u]", source, source->id);
+ for (i = 0; i < AV_IDX_MAX; i++) {
+ if (source->av[i].transceiver)
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool _check_if_transceiver_is_set_to_null_sources(webrtc_s *webrtc)
+{
+ const webrtc_gst_slot_s *source;
+
+ RET_VAL_IF(webrtc == NULL, false, "webrtc is NULL");
+
+ source = g_hash_table_find(webrtc->gst.source_slots, __check_transceiver_is_not_set_cb, GINT_TO_POINTER(WEBRTC_MEDIA_SOURCE_TYPE_NULL));
+ if (source) {
+ LOG_ERROR("transceiver is not set to the media null source[%u]", source->id);
+ LOG_ERROR("please use webrtc_media_source_set_transceiver_codec()");
+ return false;
+ }
+
+ return true;
+}
+
static void __release_filesrc_resources(webrtc_gst_slot_s *source)
{
GstElement *appsrc = NULL;