return CODEC_TYPE_NOT_SUPPORTED;
}
-static GstCaps *__make_rtp_caps(const gchar *media_type)
+static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int id)
{
gchar *caps_str;
GstCaps *caps;
"media", G_TYPE_STRING, g_strrstr(media_type, "video") ? "video" : "audio",
"clock-rate", G_TYPE_INT, payload_types[codec_type].clock_rate, /* FIXME: support various clock-rate */
"encoding-name", G_TYPE_STRING, payload_types[codec_type].encoding_name,
- "payload", G_TYPE_INT, 96, NULL); /* FIXME: payload identifier should be assigned dynamically */
+ "payload", G_TYPE_INT, id + 95, NULL);
caps_str = gst_caps_to_string(caps);
LOG_DEBUG("RTP caps is created [%s]", caps_str);
return WEBRTC_ERROR_NONE;
}
-static int __create_rest_of_elements(webrtc_media_source_type_e type, GstElement **capsfilter, GstElement **encoder, GstElement **payloader, GstElement **queue, GstElement **capsfilter2)
+static int __create_rest_of_elements(webrtc_gst_slot_s *source, GstElement **capsfilter, GstElement **encoder, GstElement **payloader, GstElement **queue, GstElement **capsfilter2)
{
GstCaps *sink_caps;
+ webrtc_media_source_type_e type;
element_info_s elem_info;
const gchar *encoder_klass_name;
gchar *media_type;
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(capsfilter == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "capsfilter is NULL");
RET_VAL_IF(encoder == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "encoder is NULL");
RET_VAL_IF(payloader == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "payloader is NULL");
RET_VAL_IF(queue == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "queue is NULL");
RET_VAL_IF(capsfilter2 == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "capsfilter2 is NULL");
+ type = source->type;
+
if (!(*capsfilter = __create_element(DEFAULT_ELEMENT_CAPSFILTER, NULL))) {
LOG_ERROR("failed to create capsfilter");
return WEBRTC_ERROR_INVALID_OPERATION;
g_free(media_type);
return WEBRTC_ERROR_INVALID_OPERATION;
}
- if ((sink_caps = __make_rtp_caps(media_type))) {
+ if ((sink_caps = __make_rtp_caps(media_type, source->id))) {
g_object_set(G_OBJECT(*capsfilter2), "caps", sink_caps, NULL);
gst_caps_unref(sink_caps);
}
return WEBRTC_ERROR_NONE;
}
-static int __build_camerasrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_camerasrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
{
int ret = WEBRTC_ERROR_NONE;
GstElement *camerasrc;
GstElement *queue;
GstElement *capsfilter2;
- RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+ RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
/* FIXME: get factory name from ini */
if (!(camerasrc = __create_element(DEFAULT_ELEMENT_CAMERASRC, NULL))) {
}
/* FIXME: set camera default setting from ini */
- if ((ret = __create_rest_of_elements(type, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+ if ((ret = __create_rest_of_elements(source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
return ret;
- gst_bin_add_many(GST_BIN(bin), camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
+ gst_bin_add_many(GST_BIN(source->bin), camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
if (!gst_element_link_many(camerasrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL)) {
LOG_ERROR("failed to gst_element_link_many()");
return WEBRTC_ERROR_INVALID_OPERATION;
return __set_ghost_pad_target(ghost_src_pad, capsfilter2, TRUE);
}
-static int __build_audiosrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_audiosrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
{
int ret = WEBRTC_ERROR_NONE;
GstElement *audiosrc;
GstElement *queue;
GstElement *capsfilter2;
- RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+ RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
if (!(audiosrc = __create_element(DEFAULT_ELEMENT_AUDIOSRC, NULL))) {
LOG_ERROR("failed to create audiosrc");
return WEBRTC_ERROR_INVALID_OPERATION;
}
- if ((ret = __create_rest_of_elements(type, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+ if ((ret = __create_rest_of_elements(source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
return ret;
- gst_bin_add_many(GST_BIN(bin), audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
+ gst_bin_add_many(GST_BIN(source->bin), audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
if (!gst_element_link_many(audiosrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL)) {
LOG_ERROR("failed to gst_element_link_many()");
return WEBRTC_ERROR_INVALID_OPERATION;
return __set_ghost_pad_target(ghost_src_pad, capsfilter2, TRUE);
}
-static int __build_videotestsrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_videotestsrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
{
int ret = WEBRTC_ERROR_NONE;
GstElement *videotestsrc;
GstElement *queue;
GstElement *capsfilter2;
- RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+ RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
if (!(videotestsrc = __create_element(DEFAULT_ELEMENT_VIDEOTESTSRC, NULL))) {
LOG_ERROR("failed to create videotestsrc");
}
g_object_set(G_OBJECT(videotestsrc), "is-live", TRUE, NULL);
- if ((ret = __create_rest_of_elements(type, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+ if ((ret = __create_rest_of_elements(source, &capsfilter, &videoenc, &videopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
return ret;
- gst_bin_add_many(GST_BIN(bin), videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
+ gst_bin_add_many(GST_BIN(source->bin), videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL);
if (!gst_element_link_many(videotestsrc, capsfilter, videoenc, videopay, queue, capsfilter2, NULL)) {
LOG_ERROR("failed to gst_element_link_many()");
return WEBRTC_ERROR_INVALID_OPERATION;
return __set_ghost_pad_target(ghost_src_pad, capsfilter2, TRUE);
}
-static int __build_audiotestsrc(GstElement *bin, webrtc_media_source_type_e type, GstPad *ghost_src_pad)
+static int __build_audiotestsrc(webrtc_gst_slot_s *source, GstPad *ghost_src_pad)
{
int ret = WEBRTC_ERROR_NONE;
GstElement *audiotestsrc;
GstElement *queue;
GstElement *capsfilter2;
- RET_VAL_IF(bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+ RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(ghost_src_pad == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "ghost_src_pad is NULL");
+ RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
if (!(audiotestsrc = __create_element(DEFAULT_ELEMENT_AUDIOTESTSRC, NULL))) {
LOG_ERROR("failed to create audiotestsrc");
}
g_object_set(G_OBJECT(audiotestsrc), "is-live", TRUE, NULL);
- if ((ret = __create_rest_of_elements(type, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
+ if ((ret = __create_rest_of_elements(source, &capsfilter, &audioenc, &audiopay, &queue, &capsfilter2)) != WEBRTC_ERROR_NONE)
return ret;
- gst_bin_add_many(GST_BIN(bin), audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
+ gst_bin_add_many(GST_BIN(source->bin), audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL);
if (!gst_element_link_many(audiotestsrc, capsfilter, audioenc, audiopay, queue, capsfilter2, NULL)) {
LOG_ERROR("failed to gst_element_link_many()");
return WEBRTC_ERROR_INVALID_OPERATION;
gchar *pad_name;
RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
- RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "bin is NULL");
+ RET_VAL_IF(source->bin == NULL, WEBRTC_ERROR_INVALID_OPERATION, "bin is NULL");
pad_name = g_strdup_printf("src_%u", source->id);
if (!(src_pad =__add_no_target_ghostpad(source->bin, pad_name))) {
switch (source->type) {
case WEBRTC_MEDIA_SOURCE_TYPE_CAMERA:
- return __build_camerasrc(source->bin, source->type, src_pad);
+ return __build_camerasrc(source, src_pad);
case WEBRTC_MEDIA_SOURCE_TYPE_MIC:
- return __build_audiosrc(source->bin, source->type, src_pad);
+ return __build_audiosrc(source, src_pad);
case WEBRTC_MEDIA_SOURCE_TYPE_VIDEOTEST:
- return __build_videotestsrc(source->bin, source->type, src_pad);
+ return __build_videotestsrc(source, src_pad);
case WEBRTC_MEDIA_SOURCE_TYPE_AUDIOTEST:
- return __build_audiotestsrc(source->bin, source->type, src_pad);
+ return __build_audiotestsrc(source, src_pad);
default:
LOG_ERROR_IF_REACHED("type(%d)", source->type);
return WEBRTC_ERROR_NONE;
}
+static unsigned int __get_unoccupied_id(GHashTable *slots)
+{
+ int i;
+ gchar *key;
+
+ RET_VAL_IF(slots == NULL, 0, "slot is NULL");
+
+ /* Payload identifiers 96–127 are used for payloads defined dynamically during a session,
+ * hence the id range is limited here to 1-32. */
+ for (i = 1; i < 33; i++) {
+ key = g_strdup_printf("media_source_%u", i);
+ if (g_hash_table_contains(slots, key)) {
+ g_free(key);
+ continue;
+ }
+ g_free(key);
+ return i;
+ }
+
+ LOG_ERROR("all slots are occupied(1-32)");
+
+ return 0;
+}
+
int _add_media_source(webrtc_s *webrtc, webrtc_media_source_type_e type, unsigned int *source_id)
{
int ret = WEBRTC_ERROR_NONE;
- static unsigned int id = 0;
+ unsigned int id;
webrtc_gst_slot_s *source = NULL;
gchar *bin_name = NULL;
GstPad *webrtc_sinkpad;
RET_VAL_IF(source_id == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is NULL");
/* bin_name/source will be freed by function which is set to g_hash_table_new_full() */
- bin_name = g_strdup_printf("media_source_%u", ++id);
+ 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);
source = g_new0(webrtc_gst_slot_s, 1);
source->type = type;