g_free(dot_name); \
} while (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"
#define DEFAULT_ELEMENT_FAKESINK "fakesink"
webrtc_gst_slot_s* _get_slot_by_id(GHashTable *slots, unsigned int id);
int _add_no_target_ghostpad_to_slot(webrtc_gst_slot_s *slot, bool is_src, GstPad **new_pad);
int _set_ghost_pad_target(GstPad *ghost_pad, GstElement *target_element, bool is_src);
-int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad);
+int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_audio);
int _add_forwarding_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_audio);
int _set_stream_info_to_sink(webrtc_s *webrtc, unsigned int track_id, sound_stream_info_h stream_info);
int _set_display_to_sink(webrtc_s *webrtc, unsigned int track_id, unsigned int type, void *display);
gchar * _get_media_type_from_pad(GstPad *pad);
gchar * _get_mime_type_from_pad(GstPad *pad);
+int _get_payload_id_from_pad(GstPad *pad);
bool _is_supported_media_type(const char *media_type);
bool _is_audio_media_type(const char *media_type);
return mime_type;
}
+int _get_payload_id_from_pad(GstPad *pad)
+{
+ GstCaps *caps = NULL;
+ gint id = -1;
+
+ RET_VAL_IF(pad == NULL, -1, "pad is NULL");
+
+ caps = gst_pad_get_current_caps(pad);
+ RET_VAL_IF(caps == NULL, -1, "caps is NULL");
+
+ if (!gst_structure_get_int(gst_caps_get_structure(caps, 0), "payload", &id))
+ LOG_ERROR("failed to gst_structure_get_int()");
+ else
+ LOG_DEBUG("payload id[%d]", id);
+
+ gst_caps_unref(caps);
+
+ return id;
+}
//LCOV_EXCL_STOP
bool _is_supported_media_type(const char *media_type)
ret = _add_forwarding_sink_bin(webrtc, new_pad, is_audio);
RET_IF(ret != WEBRTC_ERROR_NONE, "failed to _add_forwarding_sink_bin()");
} else {
- ret = _add_rendering_sink_bin(webrtc, new_pad);
+ ret = _add_rendering_sink_bin(webrtc, new_pad, is_audio);
RET_IF(ret != WEBRTC_ERROR_NONE, "failed to _add_rendering_sink_bin()");
}
static void __decodebin_element_added_cb(GstElement *decodebin, GstElement *element, gpointer user_data)
{
+ webrtc_gst_slot_s *sink = (webrtc_gst_slot_s *)user_data;
gchar *factory_name = NULL;
RET_IF(decodebin == NULL, "decodebin is NULL");
RET_IF(element == NULL, "element is NULL");
+ RET_IF(sink == NULL, "sink is NULL");
factory_name = GST_OBJECT_NAME(gst_element_get_factory(element));
LOG_INFO("element[name: %s] was added to decodebin", GST_ELEMENT_NAME(element));
if (g_strrstr(factory_name, "rtpvp8depay")) {
- LOG_INFO("set wait-for-keyframe to rtpvp8depay");
+ LOG_INFO("set wait-for-keyframe to %s", factory_name);
g_object_set(G_OBJECT(element), "wait-for-keyframe", TRUE, NULL);
+
+ } else if (g_strrstr(factory_name, "opusdec")) {
+ int i;
+ for (i = 0; i < MAX_MLINE_NUM; i ++) { /* FIXME: we don't know mline in this situation, so retrieve the array here. */
+ if (!sink->webrtc->data_recovery_types[i].inbandfec.use)
+ continue;
+ if (sink->webrtc->data_recovery_types[i].inbandfec.pt != (int)sink->av[AV_IDX_AUDIO].payload_id)
+ continue;
+ if (!g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(element)), "use-inband-fec")) {
+ LOG_WARNING("could not find 'use-inband-fec' property");
+ break;
+ }
+ LOG_INFO("set plc and use-inband-fec to %s", factory_name);
+ g_object_set(G_OBJECT(element),
+ "plc", TRUE,
+ "use-inband-fec", TRUE,
+ NULL);
+ }
}
}
factory_name = GST_OBJECT_NAME(factory);
klass = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS);
- LOG_INFO("decodebin[%p] factory[name:%s, klass:%s]", decodebin, factory_name, klass);
+ LOG_DEBUG("decodebin[%p] factory[name:%s, klass:%s]", decodebin, factory_name, klass);
str_arr = webrtc->ini.general.gst_excluded_elements;
while (str_arr && *str_arr) {
g_free(sink);
}
-int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad)
+int _add_rendering_sink_bin(webrtc_s *webrtc, GstPad *src_pad, bool is_audio)
{
int ret = WEBRTC_ERROR_NONE;
unsigned int id;
if (!decodebin)
goto error_before_insert;
+ sink->av[GET_AV_IDX(is_audio)].payload_id = _get_payload_id_from_pad(src_pad);
+
gst_bin_add(sink->bin, decodebin);
g_signal_connect(decodebin, "pad-added", G_CALLBACK(__decodebin_pad_added_cb), webrtc);
g_signal_connect(decodebin, "autoplug-select", G_CALLBACK(_decodebin_autoplug_select_cb), webrtc);
- g_signal_connect(decodebin, "element-added", G_CALLBACK(__decodebin_element_added_cb), NULL);
+ g_signal_connect(decodebin, "element-added", G_CALLBACK(__decodebin_element_added_cb), sink);
ret = _add_no_target_ghostpad_to_slot(sink, false, &sink_pad);
if (ret != WEBRTC_ERROR_NONE)