x_webrtc->idle_cb_event_source_ids[x_idx] = 0; \
} while (0)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
#define GET_AV_IDX(x_is_audio) (x_is_audio) ? AV_IDX_AUDIO : AV_IDX_VIDEO
#define GET_MEDIA_TYPE_NAME(x_is_audio) (x_is_audio) ? "audio" : "video"
int _get_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_transceiver_codec_e *codec);
void _update_transceivers_fec(webrtc_s *webrtc, bool is_offer);
int _foreach_supported_transceiver_codec(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, webrtc_media_source_supported_transceiver_codec_cb callback, void *user_data);
-bool _check_if_transceiver_is_set_to_null_sources(webrtc_s *webrtc);
+bool _check_if_codec_is_set_to_null_sources(webrtc_s *webrtc);
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);
case WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET:
if (source->media_types == MEDIA_TYPE_AUDIO) {
- _media_type = _get_audio_media_type(ini_source->a_codecs[0]);
+ _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);
+
} else if (source->media_types == MEDIA_TYPE_VIDEO) {
- _media_type = _get_video_media_type(ini_source->v_codecs[0]);
+ _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);
+
} else {
LOG_ERROR_IF_REACHED("source->media_types(0x%x)", source->media_types);
return NULL;
return WEBRTC_ERROR_NONE;
}
+static rtp_payload_info_s * __get_payload_info(const char *codec)
+{
+ int i = 0;
+ size_t n = 0;
+
+ RET_VAL_IF(codec == NULL, NULL, "codec is NULL");
+
+ n = ARRAY_SIZE(__payload_info);
+
+ for (i = 0; i < (int)n; i++) {
+ if ((__payload_info[i].encoding_name) && !strcasecmp(__payload_info[i].encoding_name, codec))
+ return &__payload_info[i];
+ }
+
+ LOG_ERROR("could not find payload_info. codec[%s]", codec);
+
+ return NULL;
+}
+
+static void __check_and_add_recvonly_transceiver(webrtc_gst_slot_s *source)
+{
+ rtp_payload_info_s *payload_info = NULL;
+
+ RET_IF(source == NULL, "source is NULL");
+
+ if (source->av[AV_IDX_AUDIO].direction == WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY && source->av[AV_IDX_AUDIO].codec) {
+ payload_info = __get_payload_info(source->av[AV_IDX_AUDIO].codec);
+ if (payload_info)
+ __add_transceiver(source, WEBRTC_MEDIA_TYPE_AUDIO, payload_info);
+ }
+
+ if (source->av[AV_IDX_VIDEO].direction == WEBRTC_TRANSCEIVER_DIRECTION_RECVONLY && source->av[AV_IDX_VIDEO].codec) {
+ payload_info = __get_payload_info(source->av[AV_IDX_VIDEO].codec);
+ if (payload_info)
+ __add_transceiver(source, WEBRTC_MEDIA_TYPE_VIDEO, payload_info);
+ }
+}
+
int _complete_sources(webrtc_s *webrtc)
{
int i;
for (i = 0; i < MAX_SOURCE_NUM; i++) {
if (!(source = webrtc->gst.sources[i]))
continue;
- if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE ||
- source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET ||
- source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL)
- continue;
LOG_DEBUG("source[id:%u, type:%d, media_types:0x%x]", source->id, source->type, source->media_types);
+ if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE)
+ continue;
+
+ if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET ||
+ source->type == WEBRTC_MEDIA_SOURCE_TYPE_NULL) {
+ goto add_transceiver;
+ }
+
if (source->media_types == MEDIA_TYPE_AUDIO)
__complete_rest_of_audiosrc(webrtc, source);
else
__complete_rest_of_videosrc(webrtc, source);
+
+add_transceiver:
+ __check_and_add_recvonly_transceiver(source);
}
return WEBRTC_ERROR_NONE;
LOG_INFO("setting caps for [%s appsrc] successfully", (av_idx == AV_IDX_AUDIO) ? "audio" : "video");
PRINT_CAPS(caps, "appsrc");
+
+ source->av[av_idx].codec = gst_structure_get_string(gst_caps_get_structure(caps, 0), "encoding-name");
gst_caps_unref(caps);
source->filesrc_av[av_idx].sink_pad = pad;
}
*source_id = source->id;
+ webrtc->gst.sources[*source_id - 1] = source;
LOG_INFO("added a source slot[%p, id:%u]", source, source->id);
if((ret = __set_payload_type(webrtc, source, av_idx, payload_info->gst_media_type)) != WEBRTC_ERROR_NONE)
return ret;
-
- if((ret = __add_transceiver(source, media_type, payload_info)) != WEBRTC_ERROR_NONE)
- return ret;
}
/* FIXME: to utilize 'codec-preferences' of trans object, we need to re-create and re-link elements again */
media_format_ref(format);
source->media_format = format;
+ if((ret = _set_mediapacketsrc_codec_info(webrtc, source, mime_type)) != WEBRTC_ERROR_NONE)
+ goto error;
if ((mime_type & MEDIA_FORMAT_RAW) &&
!(mime_type == MEDIA_FORMAT_PCMU || mime_type == MEDIA_FORMAT_PCMA)) /* FIXME: media_format.h defined PCMU/PCMA as a raw format, it's a bug. */
return true;
}
-static gboolean __check_transceiver_is_not_set_cb(gpointer key, gpointer value, gpointer user_data)
+static gboolean __check_codec_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)
+ if (source->av[i].codec)
return FALSE;
}
return TRUE;
return FALSE;
}
-bool _check_if_transceiver_is_set_to_null_sources(webrtc_s *webrtc)
+bool _check_if_codec_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));
+ source = g_hash_table_find(webrtc->gst.source_slots, __check_codec_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("codec is not set to the media null source[%u]", source->id);
LOG_ERROR("please use webrtc_media_source_set_transceiver_codec()");
return false;
}
RET_VAL_IF(media_format_get_audio_info(source->media_format, &mime_type, &channels, &samplerate, NULL, NULL) != MEDIA_FORMAT_ERROR_NONE,
NULL, "failed to media_format_get_audio_info()");
- _media_type = _get_audio_media_type(_get_audio_format_name(mime_type));
+ _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, channels, samplerate);
RET_VAL_IF(media_format_get_video_frame_rate(source->media_format, &framerate) != MEDIA_FORMAT_ERROR_NONE,
NULL, "failed to media_format_get_video_frame_rate()");
- _media_type = _get_video_media_type(_get_video_format_name(mime_type, source->zerocopy_enabled));
+ _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, width, height);
return ret;
}
//LCOV_EXCL_STOP
+
+int _set_mediapacketsrc_codec_info(webrtc_s *webrtc, webrtc_gst_slot_s *source, media_format_mimetype_e mime_type)
+{
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
+ RET_VAL_IF(source->media_format == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "media_format is NULL");
+ RET_VAL_IF(((source->media_types != MEDIA_TYPE_AUDIO) && (source->media_types != MEDIA_TYPE_VIDEO)),
+ WEBRTC_ERROR_INVALID_PARAMETER, "invalid media_types [%d]", source->media_types);
+
+ if ((mime_type & MEDIA_FORMAT_RAW) &&
+ !(mime_type == MEDIA_FORMAT_PCMU || mime_type == MEDIA_FORMAT_PCMA)) { /* FIXME: media_format.h defined PCMU/PCMA as a raw format, it's a bug. */
+
+ const ini_item_media_source_s *ini_source = _ini_get_source_by_type(&webrtc->ini, source->type);
+ if (ini_source == NULL)
+ ini_source = &(webrtc->ini.media_source);
+
+ if (source->media_types == MEDIA_TYPE_AUDIO)
+ source->av[AV_IDX_AUDIO].codec = ini_source->a_codecs[0];
+ else
+ source->av[AV_IDX_VIDEO].codec = ini_source->v_codecs[0];
+
+ } else {
+ if (source->media_types == MEDIA_TYPE_AUDIO)
+ source->av[AV_IDX_AUDIO].codec = _get_audio_format_name(mime_type);
+ else
+ source->av[AV_IDX_VIDEO].codec = _get_video_format_name(mime_type, source->zerocopy_enabled);
+
+ }
+
+ LOG_DEBUG("%s codec info [%s]", (source->media_types == MEDIA_TYPE_AUDIO) ? "audio" : "video", source->av[GET_AV_IDX_BY_TYPE(source->media_types)].codec);
+
+ return WEBRTC_ERROR_NONE;
+}