*/
int webrtc_media_source_get_transceiver_mid(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, char **mid);
+/**
+ * @internal
+ * @brief Sets drop of the receiving packets from the transceiver of the media source.
+ * @since_tizen 8.0
+ * @remarks If @a drop is set to @c true, playback of media received from a remote peer will be dropped without decoding.\n
+ * If the transceiver of @a source_id has the #WEBRTC_TRANSCEIVER_DIRECTION_SENDONLY direction, #WEBRTC_ERROR_INVALID_OPERATION will be returned.
+ * @param[in] webrtc WebRTC handle
+ * @param[in] source_id The source id
+ * @param[in] media_type The media type
+ * @param[in] drop Drop or not (@c true = drop, @c false = not drop)
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
+ * @see webrtc_media_source_get_transceiver_recv_drop()
+ */
+int webrtc_media_source_set_transceiver_recv_drop(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool drop);
+
+/**
+ * @internal
+ * @brief Gets the drop state of the receiving packets from the transceiver of the media source.
+ * @since_tizen 8.0
+ * @remarks The default value is @c false.
+ * @param[in] webrtc WebRTC handle
+ * @param[in] source_id The track id
+ * @param[in] media_type The media type
+ * @param[out] dropped Dropped or not (@c true = dropped, @c false = not dropped)
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #WEBRTC_ERROR_NONE Successful
+ * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see webrtc_media_source_set_transceiver_recv_drop()
+ */
+int webrtc_media_source_get_transceiver_recv_drop(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool *dropped);
+
/**
* @internal
* @brief Gets the media type of the media source.
* @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation
* @see webrtc_util_strip_description()
*/
-int webrtc_util_create_description(bool is_offer, const char *sdp, char **description);
+int webrtc_util_create_description(bool offer, const char *sdp, char **description);
/**
* @internal
GHashTable *data_channels;
GHashTable *track_build_contexts;
+ GHashTable *sources;
#ifdef TIZEN_FEATURE_SNAPSHOT
struct {
GstElement *appsrc;
GstCaps *appsrc_caps;
bool hw_decoder_used;
+ bool drop;
} render;
} av[AV_IDX_MAX];
struct {
int _remove_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid);
int _active_transceiver_encoding(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, const char *rid, bool active);
int _get_transceiver_mid(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, char **mid);
+int _set_transceiver_recv_drop(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool drop);
+int _get_transceiver_recv_drop(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool *dropped);
GstCaps *_make_rtp_caps_with_encoding(webrtc_gst_slot_s *source, bool is_audio);
/* file source */
Name: capi-media-webrtc
Summary: A WebRTC library in Tizen Native API
-Version: 0.4.53
+Version: 0.4.54
Release: 0
Group: Multimedia/API
License: Apache-2.0
return _get_transceiver_mid(webrtc, source_id, media_type, mid);
}
+int webrtc_media_source_set_transceiver_recv_drop(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool drop)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_s *_webrtc = (webrtc_s *)webrtc;
+
+ RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0");
+
+ locker = g_mutex_locker_new(&_webrtc->mutex);
+
+ return _set_transceiver_recv_drop(_webrtc, source_id, media_type, drop);
+}
+
+int webrtc_media_source_get_transceiver_recv_drop(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool *dropped)
+{
+ g_autoptr(GMutexLocker) locker = NULL;
+ webrtc_s *_webrtc = (webrtc_s *)webrtc;
+
+ RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL");
+ RET_VAL_IF(source_id == 0, WEBRTC_ERROR_INVALID_PARAMETER, "source_id is 0");
+ RET_VAL_IF(dropped == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "dropped is NULL");
+
+ locker = g_mutex_locker_new(&_webrtc->mutex);
+
+ return _get_transceiver_recv_drop(_webrtc, source_id, media_type, dropped);
+}
+
int webrtc_media_source_get_type(webrtc_h webrtc, unsigned int source_id, webrtc_media_type_e *media_type)
{
webrtc_s *_webrtc = (webrtc_s *)webrtc;
return WEBRTC_ERROR_NONE;
}
-int webrtc_util_create_description(bool is_offer, const char *sdp, char **description)
+int webrtc_util_create_description(bool offer, const char *sdp, char **description)
{
JsonObject *desc, *sdp_desc;
gchar *result;
RET_VAL_IF(description == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "description is NULL");
sdp_desc = json_object_new();
- json_object_set_string_member(sdp_desc, "type", is_offer ? "offer": "answer");
+ json_object_set_string_member(sdp_desc, "type", offer ? "offer": "answer");
json_object_set_string_member(sdp_desc, "sdp", sdp);
desc = json_object_new();
webrtc->gst.source_slots = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _source_slot_destroy_cb);
webrtc->gst.sink_slots = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _sink_slot_destroy_cb);
webrtc->track_build_contexts = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _track_build_context_destroy_cb);
+ webrtc->sources = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
return WEBRTC_ERROR_NONE;
}
__destroy_sink_pipeline(webrtc);
__destroy_source_pipeline(webrtc);
+ if (webrtc->sources) {
+ g_hash_table_destroy(webrtc->sources);
+ webrtc->sources = NULL;
+ }
if (webrtc->gst.bus_watcher > 0) {
gst_bus_remove_watch(webrtc->gst.bus);
webrtc->gst.bus_watcher = 0;
GstPadProbeReturn _webrtcbin_payloaded_data_probe_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
{
probe_userdata_s *probe_data = (probe_userdata_s *)user_data;
- g_autofree gchar *media_type = _get_mime_type_from_pad(pad);
webrtc_gst_slot_s *sink;
+ webrtc_gst_slot_s *source;
+ webrtc_s *webrtc;
+ g_autofree gchar *msid = NULL;
+ GstWebRTCRTPTransceiver *transceiver;
ASSERT(probe_data);
sink = probe_data->slot;
- LOG_VERBOSE("pad[%p] media_type[%s] av_idx[%d] sink[%p, id:%u]",
- pad, media_type, probe_data->av_idx, sink, sink->id);
+ ASSERT(sink);
+
+ webrtc = sink->webrtc;
+
+ g_object_get(pad,
+ "msid", &msid,
+ "transceiver", &transceiver,
+ NULL);
+
+ LOG_VERBOSE("pad[%p, remote msid:%s, transceiver:%p] av_idx[%d] sink[%p, id:%u]",
+ pad, msid, transceiver, probe_data->av_idx, sink, sink->id);
+
+ source = g_hash_table_lookup(webrtc->sources, transceiver);
+ if (!source) {
+ LOG_WARNING("could not find source by transceiver[%p]", transceiver);
+ return GST_PAD_PROBE_OK;
+ }
+
+ if (source->av[probe_data->av_idx].render.drop) {
+ LOG_DEBUG("data for this transceiver of source->id[%u], drop it,", source->id);
+ return GST_PAD_PROBE_DROP;
+ }
return GST_PAD_PROBE_OK;
}
_destroy_looopback_render_pipeline(source, i);
- if (source->av[i].transceiver)
+ if (source->av[i].transceiver) {
gst_object_unref(source->av[i].transceiver);
+ g_hash_table_remove(source->webrtc->sources, source->av[i].transceiver);
+ }
g_free(source->av[i].mid);
g_hash_table_destroy(source->av[i].encodings);
GstPad *sinkpad;
gchar *sinkpad_name = NULL;
gchar *srcpad_name = NULL;
+ g_autofree gchar *msid = NULL;
+ GstWebRTCRTPTransceiver *transceiver;
RET_VAL_IF(source == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "source is NULL");
RET_VAL_IF(webrtcbin == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtcbin is NULL");
goto exit;
}
+ g_object_get(sinkpad,
+ "msid", &msid,
+ "transceiver", &transceiver,
+ NULL);
+
+ LOG_DEBUG("sinkpad_name[%s] local msid[%s] transceiver[%p]", sinkpad_name, msid, transceiver);
+
if (source->type == WEBRTC_MEDIA_SOURCE_TYPE_FILE) {
if ((source->media_types & MEDIA_TYPE_AUDIO) && !__is_linked_pad(source, "audio"))
srcpad_name = g_strdup_printf("audio_src_%u", source->id);
LOG_INFO("source->id[%u] source->av[%s][transceiver:%p, direction:%s, mid:%s]",
source->id, j == AV_IDX_AUDIO ? "AUDIO" : "VIDEO", source->av[j].transceiver,
__convert_transceiver_direction(source->av[j].direction)->str, source->av[j].mid);
+
+ ASSERT(g_hash_table_insert(webrtc->sources, transceiver, source));
return;
}
}
return WEBRTC_ERROR_NONE;
}
+
+int _set_transceiver_recv_drop(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool drop)
+{
+ webrtc_gst_slot_s *source;
+ int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc 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->av[av_idx].direction == WEBRTC_TRANSCEIVER_DIRECTION_SENDONLY, WEBRTC_ERROR_INVALID_OPERATION, "direction is SENDONLY");
+
+ source->av[av_idx].render.drop = drop;
+
+ LOG_INFO("webrtc[%p] source_id[%u] media_type[%d] drop[%d]", webrtc, source_id, media_type, drop);
+
+ return WEBRTC_ERROR_NONE;
+}
+
+int _get_transceiver_recv_drop(webrtc_s *webrtc, unsigned int source_id, webrtc_media_type_e media_type, bool *dropped)
+{
+ webrtc_gst_slot_s *source;
+ int av_idx = (media_type == WEBRTC_MEDIA_TYPE_AUDIO) ? AV_IDX_AUDIO : AV_IDX_VIDEO;
+
+ RET_VAL_IF(webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc 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(dropped == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "dropped is NULL");
+
+ *dropped = source->av[av_idx].render.drop;
+
+ LOG_INFO("webrtc[%p] source_id[%u] media_type[%d] dropped[%d]", webrtc, source_id, media_type, *dropped);
+
+ return WEBRTC_ERROR_NONE;
+}