#include "webrtc_private.h"
//LCOV_EXCL_START
-typedef void (*__parse_stats_func)(const GstStructure *s, webrtc_callbacks_s *cb);
/*
* Description below is extracted from GstWebRTCBin::get-stats:
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
__get_common_stats(s, &common);
__get_codec_stats(s, &codec);
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
__get_common_stats(s, &common);
__get_rtp_stream_stats(s, &rtp_stream);
__get_received_rtp_stream_stats(s, &received_rtp_stream);
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
__get_common_stats(s, &common);
__get_rtp_stream_stats(s, &rtp_stream);
__get_sent_rtp_stream_stats(s, &sent_rtp_stream);
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
__get_common_stats(s, &common);
__get_rtp_stream_stats(s, &rtp_stream);
/* FIXME: only 'jitter' and 'packet-lost'(int) are available. type of 'packet-lost' should be fixed.
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
__get_common_stats(s, &common);
__get_rtp_stream_stats(s, &rtp_stream);
__get_remote_outbound_rtp_stream_stats(s, &remote_outbound_rtp_stream);
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
__get_common_stats(s, &common);
__get_peer_connection_stats(s, &peer_connection);
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
{
RET_IF(cb == NULL, "cb is NULL");
+ LOG_DEBUG_ENTER();
+
gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
/* not implemented */
}
-static __parse_stats_func __parse_stats_funcs[] = {
- [GST_WEBRTC_STATS_CODEC] = __parse_codec_and_invoke_callback,
- [GST_WEBRTC_STATS_INBOUND_RTP] = __parse_inbound_rtp_and_invoke_callback,
- [GST_WEBRTC_STATS_OUTBOUND_RTP] = __parse_outbound_rtp_and_invoke_callback,
- [GST_WEBRTC_STATS_REMOTE_INBOUND_RTP] = __parse_remote_inbound_rtp_and_invoke_callback,
- [GST_WEBRTC_STATS_REMOTE_OUTBOUND_RTP] = __parse_remote_outbound_rtp_and_invoke_callback,
- [GST_WEBRTC_STATS_CSRC] = __parse_csrc_and_invoke_callback,
- [GST_WEBRTC_STATS_PEER_CONNECTION] = __parse_peer_connection_and_invoke_callback,
- [GST_WEBRTC_STATS_DATA_CHANNEL] = __parse_data_channel_and_invoke_callback,
- [GST_WEBRTC_STATS_STREAM] = __parse_stream_and_invoke_callback,
- [GST_WEBRTC_STATS_TRANSPORT] = __parse_transport_and_invoke_callback,
- [GST_WEBRTC_STATS_CANDIDATE_PAIR] = __parse_candidate_pair_and_invoke_callback,
- [GST_WEBRTC_STATS_LOCAL_CANDIDATE] = __parse_local_candidate_and_invoke_callback,
- [GST_WEBRTC_STATS_REMOTE_CANDIDATE] = __parse_remote_candidate_and_invoke_callback,
- [GST_WEBRTC_STATS_CERTIFICATE] = __parse_certificate_and_invoke_callback,
+typedef void (*stats_func)(const GstStructure *s, webrtc_callbacks_s *cb);
+
+/* Note that stats_type_mask_e below follows GstWebRTCStatsType of webrtc_fwd.h */
+typedef enum {
+ STATS_TYPE_ALL_MASK = 0xFFFF,
+ STATS_TYPE_CODEC_MASK = 0x0001,
+ STATS_TYPE_INBOUND_RTP_MASK = 0x0002,
+ STATS_TYPE_OUTBOUND_RTP_MASK = 0x0004,
+ STATS_TYPE_REMOTE_INBOUND_RTP_MASK = 0x0008,
+ STATS_TYPE_REMOTE_OUTBOUND_RTP_MASK = 0x0010,
+ STATS_TYPE_CSRC_MASK = 0x0020,
+ STATS_TYPE_PEER_CONNECTION_MASK = 0x0040,
+ STATS_TYPE_DATA_CHANNEL_MASK = 0x0080,
+ STATS_TYPE_STREAM_MASK = 0x0100,
+ STATS_TYPE_TRANSPORT_MASK = 0x0200,
+ STATS_TYPE_CANDIDATE_PAIR_MASK = 0x0400,
+ STATS_TYPE_LOCAL_CANDIDATE_MASK = 0x0800,
+ STATS_TYPE_REMOTE_CANDIDATE_MASK = 0x1000,
+ STATS_TYPE_CERTIFICATE_MASK = 0x2000,
+} stats_type_mask_e;
+
+typedef struct {
+ stats_func func;
+ stats_type_mask_e type_mask;
+} parse_stats_s;
+
+static parse_stats_s parse_stats[] = {
+ [GST_WEBRTC_STATS_CODEC] = { __parse_codec_and_invoke_callback, STATS_TYPE_CODEC_MASK },
+ [GST_WEBRTC_STATS_INBOUND_RTP] = { __parse_inbound_rtp_and_invoke_callback, STATS_TYPE_INBOUND_RTP_MASK },
+ [GST_WEBRTC_STATS_OUTBOUND_RTP] = { __parse_outbound_rtp_and_invoke_callback, STATS_TYPE_OUTBOUND_RTP_MASK },
+ [GST_WEBRTC_STATS_REMOTE_INBOUND_RTP] = { __parse_remote_inbound_rtp_and_invoke_callback, STATS_TYPE_REMOTE_INBOUND_RTP_MASK },
+ [GST_WEBRTC_STATS_REMOTE_OUTBOUND_RTP] = { __parse_remote_outbound_rtp_and_invoke_callback, STATS_TYPE_REMOTE_OUTBOUND_RTP_MASK },
+ [GST_WEBRTC_STATS_CSRC] = { __parse_csrc_and_invoke_callback, STATS_TYPE_CSRC_MASK },
+ [GST_WEBRTC_STATS_PEER_CONNECTION] = { __parse_peer_connection_and_invoke_callback, STATS_TYPE_PEER_CONNECTION_MASK },
+ [GST_WEBRTC_STATS_DATA_CHANNEL] = { __parse_data_channel_and_invoke_callback, STATS_TYPE_DATA_CHANNEL_MASK },
+ [GST_WEBRTC_STATS_STREAM] = { __parse_stream_and_invoke_callback, STATS_TYPE_STREAM_MASK },
+ [GST_WEBRTC_STATS_TRANSPORT] = { __parse_transport_and_invoke_callback, STATS_TYPE_TRANSPORT_MASK },
+ [GST_WEBRTC_STATS_CANDIDATE_PAIR] = { __parse_candidate_pair_and_invoke_callback, STATS_TYPE_CANDIDATE_PAIR_MASK },
+ [GST_WEBRTC_STATS_LOCAL_CANDIDATE] = { __parse_local_candidate_and_invoke_callback, STATS_TYPE_LOCAL_CANDIDATE_MASK },
+ [GST_WEBRTC_STATS_REMOTE_CANDIDATE] = { __parse_remote_candidate_and_invoke_callback, STATS_TYPE_REMOTE_CANDIDATE_MASK },
+ [GST_WEBRTC_STATS_CERTIFICATE] = { __parse_certificate_and_invoke_callback, STATS_TYPE_CERTIFICATE_MASK }
};
+typedef struct _stats_userdata_s {
+ webrtc_s *webrtc;
+ int type_mask;
+} stats_userdata_s;
+
static gboolean __webrtcbin_stats_cb(GQuark field_id, const GValue *value, gpointer user_data)
{
- webrtc_s *webrtc = (webrtc_s *)user_data;
+ stats_userdata_s *stats_userdata = (stats_userdata_s *)user_data;
const GstStructure *s;
GstWebRTCStatsType type;
+ RET_VAL_IF(stats_userdata == NULL, TRUE, "stats_userdata is NULL");
+
if (GST_VALUE_HOLDS_STRUCTURE(value)) {
s = gst_value_get_structure(value);
gst_structure_get(s, "type", GST_TYPE_WEBRTC_STATS_TYPE, &type, NULL);
RET_VAL_IF((type < GST_WEBRTC_STATS_CODEC || type > GST_WEBRTC_STATS_CERTIFICATE),
TRUE, "invalid type(%u)", type);
- __parse_stats_funcs[type](s, &webrtc->stats_cb);
+ if (!(stats_userdata->type_mask & parse_stats[type].type_mask))
+ return TRUE;
+
+ parse_stats[type].func(s, &stats_userdata->webrtc->stats_cb);
} else {
LOG_ERROR("unknown field \'%s\' value type: \'%s\'",
return TRUE;
}
-static void __webrtcbin_get_stats_cb(GstPromise *promise, webrtc_s *webrtc)
+static void __webrtcbin_get_stats_cb(GstPromise *promise, gpointer user_data)
{
const GstStructure *stats;
stats = gst_promise_get_reply(promise);
RET_IF(stats == NULL, "failed to gst_promise_get_reply()");
- gst_structure_foreach(stats, __webrtcbin_stats_cb, webrtc);
+ gst_structure_foreach(stats, __webrtcbin_stats_cb, user_data);
}
-void _webrtcbin_get_stats(webrtc_s *webrtc)
+void _webrtcbin_get_stats(webrtc_s *webrtc, int type_mask)
{
GstPromise *promise;
+ stats_userdata_s stats_userdata = { webrtc, type_mask };
RET_IF(webrtc == NULL, "webrtc is NULL");
RET_IF(webrtc->gst.webrtcbin == NULL, "webrtcbin is NULL");
- promise = gst_promise_new_with_change_func((GstPromiseChangeFunc)__webrtcbin_get_stats_cb, webrtc, NULL);
+ promise = gst_promise_new_with_change_func((GstPromiseChangeFunc)__webrtcbin_get_stats_cb, &stats_userdata, NULL);
g_signal_emit_by_name(webrtc->gst.webrtcbin, "get-stats", NULL, promise);
LOG_DEBUG("emitting 'get-stats' on %p", webrtc->gst.webrtcbin);
webrtc_s *webrtc = (webrtc_s *)user_data;
if (webrtc->state == WEBRTC_STATE_PLAYING)
- _webrtcbin_get_stats(webrtc);
+ _webrtcbin_get_stats(webrtc, STATS_TYPE_ALL_MASK);
return G_SOURCE_CONTINUE;
}