gst_caps_unref(x_elem_info.src_caps); \
} while (0)
-#define MALLOC_AND_INIT_SLOT(x_slot, x_id, x_bin_name, x_webrtcbin) \
+#define MALLOC_AND_INIT_SLOT(x_slot, x_id, x_bin_name, x_webrtc) \
do { \
x_slot = g_new0(webrtc_gst_slot_s, 1); \
x_slot->id = x_id; \
x_slot->bin = GST_BIN(gst_bin_new(x_bin_name)); \
x_slot->av[AV_IDX_AUDIO].mline = -1; \
x_slot->av[AV_IDX_VIDEO].mline = -1; \
- x_slot->webrtcbin = x_webrtcbin; \
+ x_slot->webrtc = x_webrtc; \
} while (0)
#define GENERATE_DOT(x_webrtc, x_fmt, x_arg...) \
#define MEDIA_TYPE_VIDEO_JPEG "image/jpeg"
#define WEBRTC_DISPLAY_TYPE_ECORE_WL 2
+#define PAYLOAD_ID_NUM 32 /* 96 ~ 127 */
#define SIGNALING_MESSAGE_PREFIX_CONNECTED "CONNECTED"
#define SIGNALING_MESSAGE_PREFIX_REQUEST_SESSION "REQUEST_SESSION"
GCond desc_cond;
webrtc_gst_s gst;
+ bool payload_ids[PAYLOAD_ID_NUM];
gchar *stun_server_url;
GList *turn_server_urls;
typedef struct _webrtc_gst_slot_s {
unsigned int id;
GstBin *bin;
- GstElement *webrtcbin;
+ webrtc_s *webrtc;
GList *signals;
webrtc_media_source_type_e type;
GstPad *src_pad;
gulong src_pad_probe_id;
bool pause;
+ unsigned int payload_id;
} av[AV_IDX_MAX];
struct {
int width;
GstAllocator *allocator;
webrtc_callbacks_s buffer_state_changed_cb;
webrtc_callbacks_s *encoded_frame_cb;
- webrtc_s *webrtc;
gulong probe_id;
bool video_muted;
return caps;
}
-static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int id)
+static GstCaps *__make_rtp_caps(const gchar *media_type, unsigned int payload_id)
{
GstCaps *caps;
bool is_video;
caps = gst_caps_new_simple("application/x-rtp",
"media", G_TYPE_STRING, is_video ? "video" : "audio",
- "payload", G_TYPE_INT, id + 95, NULL);
+ "payload", G_TYPE_INT, payload_id, NULL);
PRINT_CAPS(caps, "RTP");
return ini_source->v_encoded_fmt_support;
}
+static unsigned int __get_available_payload_id(webrtc_s *webrtc)
+{
+ int i;
+
+ RET_VAL_IF(webrtc == NULL, 0, "webrtc is NULL");
+
+ for (i = 0; i < PAYLOAD_ID_NUM; i++) {
+ if (!webrtc->payload_ids[i]) {
+ webrtc->payload_ids[i] = true;
+ LOG_DEBUG("found available payload id[%d]", i + 96);
+ return i + 96;
+ }
+ }
+ LOG_ERROR("could not assign payload id");
+ return 0;
+}
+
+static void __return_payload_id(webrtc_s *webrtc, unsigned int payload_id)
+{
+ RET_IF(webrtc == NULL, "webrtc is NULL");
+ RET_IF(payload_id < 96 || payload_id > 127, "invalid payload_id(%u)", payload_id);
+
+ webrtc->payload_ids[payload_id - 96] = false;
+}
+
static int __create_rest_of_elements(webrtc_s *webrtc, webrtc_gst_slot_s *source, bool need_capsfilter, GList **element_list)
{
GstElement *capsfilter = NULL;
const gchar *encoder_klass_name;
gchar *media_type = NULL;
gchar *encoder_name = NULL;
+ unsigned int payload_id;
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(element_list == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "element_list is NULL");
if (need_capsfilter) {
- if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER))) {
- LOG_ERROR("failed to create capsfilter");
+ if (!(capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_FIRST_CAPSFILTER)))
return WEBRTC_ERROR_INVALID_OPERATION;
- }
if (__is_encoded_format_supported(source->type, &webrtc->ini)) {
if ((sink_caps = __make_default_encoded_caps(source, &webrtc->ini, NULL))) {
}
if (!(queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) {
- LOG_ERROR("failed to create queue");
g_free(media_type);
return WEBRTC_ERROR_INVALID_OPERATION;
}
if (!(capsfilter2 = _create_element(DEFAULT_ELEMENT_CAPSFILTER, ELEMENT_NAME_RTP_CAPSFILTER))) {
- LOG_ERROR("failed to create capsfilter");
g_free(media_type);
return WEBRTC_ERROR_INVALID_OPERATION;
}
- if ((sink_caps = __make_rtp_caps(media_type, source->id))) {
+
+ payload_id = __get_available_payload_id(webrtc);
+ if (payload_id == 0) {
+ g_free(media_type);
+ return WEBRTC_ERROR_INVALID_OPERATION;
+ }
+ source->av[source->media_types == MEDIA_TYPE_VIDEO ? AV_IDX_VIDEO : AV_IDX_AUDIO].payload_id = payload_id;
+
+ if ((sink_caps = __make_rtp_caps(media_type, payload_id))) {
g_object_set(G_OBJECT(capsfilter2), "caps", sink_caps, NULL);
gst_caps_unref(sink_caps);
}
}
if (!(*queue = _create_element(DEFAULT_ELEMENT_QUEUE, NULL))) {
- LOG_ERROR("failed to create queue");
g_free(media_type);
return WEBRTC_ERROR_INVALID_OPERATION;
}
if (!(*capsfilter = _create_element(DEFAULT_ELEMENT_CAPSFILTER, NULL))) {
- LOG_ERROR("failed to create capsfilter");
g_free(media_type);
return WEBRTC_ERROR_INVALID_OPERATION;
}
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 (!(appsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), NULL))) {
- LOG_ERROR("failed to create appsrc");
+ if (!(appsrc = _create_element(__get_source_element(webrtc, WEBRTC_MEDIA_SOURCE_TYPE_MEDIA_PACKET), NULL)))
return WEBRTC_ERROR_INVALID_OPERATION;
- }
g_object_set(G_OBJECT(appsrc), "is-live", TRUE, "do-timestamp", TRUE, "format", GST_FORMAT_TIME, NULL);
GstPad *peer = gst_pad_get_peer(pad);
RET_VAL_IF(source == NULL, FALSE, "source is NULL");
+ RET_VAL_IF(source->webrtc == NULL, FALSE, "webrtc is NULL");
RET_VAL_IF(peer == NULL, TRUE, "peer pad is NULL");
LOG_DEBUG("about to release request pad[%s]", GST_PAD_NAME(peer));
- gst_element_release_request_pad(source->webrtcbin, peer);
+ gst_element_release_request_pad(source->webrtc->gst.webrtcbin, peer);
/* Two unrefing here, one for getting request pad, another one for getting peer pad */
gst_object_unref(peer);
gst_pad_remove_probe(source->av[i].src_pad, source->av[i].src_pad_probe_id);
source->av[i].src_pad_probe_id = 0;
}
+ if (source->av[i].payload_id > 0)
+ __return_payload_id(source->webrtc, source->av[i].payload_id);
}
gst_bin_remove(GST_BIN(gst_element_get_parent(source->bin)), GST_ELEMENT(source->bin));
bin_name = g_strdup_printf("media_source_%u", id);
- MALLOC_AND_INIT_SLOT(source, id, bin_name, webrtc->gst.webrtcbin);
+ MALLOC_AND_INIT_SLOT(source, id, bin_name, webrtc);
source->type = type;
ret = __build_source_bin(webrtc, source);