//LCOV_EXCL_START
+typedef struct _stats_field_s {
+ const gchar *name;
+ GQuark id;
+} stats_field_s;
+
/*
* Description below is extracted from GstWebRTCBin::get-stats:
* Each statistics structure contains the following values as defined by
* "type" GST_TYPE_WEBRTC_STATS_TYPE the type of statistics reported
* "id" G_TYPE_STRING unique identifier
*/
-typedef struct _stats_common_s {
- gdouble timestamp;
- GstWebRTCStatsType type;
- gchar *id;
-} stats_common_s;
+static stats_field_s __stats_common_fields[] = {
+ { "timestamp", 0 },
+ { "type", 0 },
+ { "id", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
* "payload-type" G_TYPE_UINT the rtp payload number in use
* "clock-rate" G_TYPE_UINT the rtp clock-rate
*/
-typedef struct _stats_codec_s {
- guint payload_type;
- guint clock_rate;
- guint ssrc;
-} stats_codec_s;
+static stats_field_s __stats_codec_fields[] = {
+ { "payload-type", 0 },
+ { "clock-rate", 0 },
+ { "ssrc", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
* "pli-count" G_TYPE_UINT PLI requests received by the sender (only for local statistics)
* "nack-count" G_TYPE_UINT NACK requests received by the sender (only for local statistics)
*/
-typedef struct _stats_rtp_stream_s {
- guint ssrc;
- gchar *transport_id;
- gchar *codec_id;
-} stats_rtp_stream_s;
+static stats_field_s __stats_rtp_stream_fields[] = {
+ { "ssrc", 0 },
+ { "transport-id", 0 },
+ { "codec-id", 0 },
+ { "fir-count", 0 },
+ { "pli-count", 0 },
+ { "nack-count", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
* "packets-lost" G_TYPE_UINT number of packets lost
* "jitter" G_TYPE_DOUBLE packet jitter measured in seconds
*/
-typedef struct _stats_received_rtp_stream_s {
- guint64 packets_received;
- guint64 packets_lost;
- guint64 packets_discarded;
- guint64 packets_repaired;
- gdouble jitter;
-} stats_received_rtp_stream_s;
+static stats_field_s __stats_received_rtp_stream_fields[] = {
+ { "packets-received", 0 },
+ { "packets-lost", 0 },
+ { "packets-discarded", 0 },
+ { "packets-repaired", 0 },
+ { "jitter", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
*
* "remote-id" G_TYPE_STRING identifier for the associated RTCRemoteOutboundRTPStreamStats
*/
-typedef struct _stats_inbound_rtp_stream_s {
- gchar *remote_id;
- guint64 bytes_received;
- guint64 packets_duplicated;
- guint fir_count;
- guint pli_count;
- guint nack_count;
-} stats_inbound_rtp_stream_s;
+static stats_field_s __stats_inbound_rtp_stream_fields[] = {
+ { "remote-id", 0 },
+ { "bytes-received", 0 },
+ { "packets-duplicated", 0 },
+ { "fir-count", 0 },
+ { "pli-count", 0 },
+ { "nack-count", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
* "packets-sent" G_TYPE_UINT64 number of packets sent (only for local outbound)
* "bytes-sent" G_TYPE_UINT64 number of packets sent (only for local outbound)
*/
-typedef struct _stats_sent_rtp_stream_s {
- guint64 packets_sent;
- guint64 bytes_sent;
-} stats_sent_rtp_stream_s;
+static stats_field_s __stats_sent_rtp_stream_fields[] = {
+ { "packets-sent", 0 },
+ { "bytes-sent", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
*
* "remote-id" G_TYPE_STRING identifier for the associated RTCRemoteInboundRTPSTreamStats
*/
-typedef struct _stats_outbound_rtp_stream_s {
- gchar *remote_id;
- guint fir_count; /* FIR/PLI/NACK counts exists here that differ from WebRTC SPEC */
- guint pli_count;
- guint nack_count;
-} stats_outbound_rtp_stream_s;
+static stats_field_s __stats_outbound_rtp_stream_fields[] = {
+ { "remote-id", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
* "local-id" G_TYPE_STRING identifier for the associated RTCOutboundRTPSTreamStats
* "round-trip-time" G_TYPE_DOUBLE round trip time of packets measured in seconds
*/
-typedef struct _stats_remote_inbound_rtp_stream_s {
- gchar *local_id;
- gdouble round_trip_time;
-} stats_remote_inbound_rtp_stream_s;
+static stats_field_s __stats_remote_inbound_rtp_stream_fields[] = {
+ { "local-id", 0 },
+ { "round-trip-time", 0 },
+ { NULL, 0 }
+};
/*
* Description below is extracted from GstWebRTCBin::get-stats:
* RTCRemoteOutboundRTPStreamStats supported fields (https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*)
*
* "local-id" G_TYPE_STRING identifier for the associated RTCInboundRTPSTreamStats
+ * "remote-timestamp" G_TYPE_DOUBLE the remote timestamp at which these statistics were sent by the remote endpoint
*/
-typedef struct _stats_remote_outbound_rtp_stream_s {
- gchar *local_id;
- gdouble remote_timestamp;
-} stats_remote_outbound_rtp_stream_s;
-
-typedef struct _stats_peer_connection_s {
- guint data_channels_opened;
- guint data_channels_closed;
- guint data_channels_requested;
- guint data_channels_accepted;
-} stats_peer_connection_s;
-
-/* This is for debug purpose to check which fields are actually provided via webrtcbin. */
-static gboolean __gststructure_foreach_cb(GQuark field_id, const GValue *val, gpointer data)
+static stats_field_s __stats_remote_outbound_rtp_stream_fields[] = {
+ { "local-id", 0 },
+ { "remote-timestamp", 0 },
+ { NULL, 0 }
+};
+
+/*
+ * Description below is extracted from GstWebRTCBin::get-stats:
+ * RTCRemoteOutboundRTPStreamStats supported fields (https://w3c.github.io/webrtc-stats/#pcstats-dict*)
+ *
+ * "data-channels-opened" G_TYPE_UINT the number of unique RTCDataChannels that have entered the "open" state during their lifetime
+ * "data-channels-closed" G_TYPE_UINT the number of unique RTCDataChannels that have left the "open" state during their lifetime
+ * "data-channels-requested" G_TYPE_UINT the number of unique RTCDataChannels returned from a successful createDataChannel() call on the RTCPeerConnection
+ * "data-channels-accepted" G_TYPE_UINT the number of unique RTCDataChannels signaled in a ondatachannel event on the RTCPeerConnection
+ */
+static stats_field_s __stats_peer_connection_fields[] = {
+ { "data-channels-opened", 0 },
+ { "data-channels-closed", 0 },
+ { "data-channels-requested", 0 },
+ { "data-channels-accepted", 0 },
+ { NULL, 0 }
+};
+
+static stats_field_s *__stats_all_fields_list[] = {
+ __stats_common_fields,
+ __stats_codec_fields,
+ __stats_rtp_stream_fields,
+ __stats_received_rtp_stream_fields,
+ __stats_inbound_rtp_stream_fields,
+ __stats_sent_rtp_stream_fields,
+ __stats_outbound_rtp_stream_fields,
+ __stats_remote_inbound_rtp_stream_fields,
+ __stats_remote_outbound_rtp_stream_fields,
+ __stats_peer_connection_fields,
+ NULL
+};
+
+static stats_field_s *__stats_codec_fields_list[] = {
+ __stats_common_fields,
+ __stats_codec_fields,
+ NULL
+};
+
+static stats_field_s *__stats_inbound_rtp_fields_list[] = {
+ __stats_common_fields,
+ __stats_rtp_stream_fields,
+ __stats_received_rtp_stream_fields,
+ __stats_inbound_rtp_stream_fields,
+ NULL
+};
+
+static stats_field_s *__stats_outbound_rtp_fields_list[] = {
+ __stats_common_fields,
+ __stats_rtp_stream_fields,
+ __stats_sent_rtp_stream_fields,
+ __stats_outbound_rtp_stream_fields,
+ NULL
+};
+
+/* NOTE: __stats_received_rtp_stream_fields does not exist that differs from WebRTC SPEC. */
+static stats_field_s *__stats_remote_inbound_rtp_fields_list[] = {
+ __stats_common_fields,
+ __stats_rtp_stream_fields,
+ //__stats_received_rtp_stream_fields,
+ __stats_remote_inbound_rtp_stream_fields,
+ NULL
+};
+
+/* NOTE: stats_sent_rtp_stream_s does not exist that differs from WebRTC SPEC. */
+static stats_field_s *__stats_remote_outbound_rtp_fields_list[] = {
+ __stats_common_fields,
+ __stats_rtp_stream_fields,
+ //__stats_sent_rtp_stream_fields,
+ __stats_remote_outbound_rtp_stream_fields,
+ NULL
+};
+
+static stats_field_s *__stats_peer_connection_fields_list[] = {
+ __stats_common_fields,
+ __stats_peer_connection_fields,
+ NULL
+};
+
+typedef struct _stats_userdata_s {
+ webrtc_s *webrtc;
+ int type_mask;
+ stats_field_s **fields_list;
+} stats_userdata_s;
+
+static gboolean __gststructure_foreach_cb(GQuark field_id, const GValue *val, gpointer user_data)
{
+ stats_userdata_s *stats = (stats_userdata_s *)user_data;
+ int i, j;
+
+ RET_VAL_IF(user_data == NULL, FALSE, "user_data is NULL");
+ RET_VAL_IF(stats->webrtc == NULL, FALSE, "webrtc is NULL");
+ RET_VAL_IF(stats->fields_list == NULL, FALSE, "fields_list is NULL");
+
+ /* Note that it only allow fields pre-defined in list */
+ for (i = 0; stats->fields_list[i]; i++)
+ for (j = 0; stats->fields_list[i][j].name; j++)
+ if (stats->fields_list[i][j].id == field_id)
+ goto invoke_cb;
+
+ /* field id below will be skipped here, it should be handled with gst_structure_foreach() */
+ if (!g_strcmp0(g_quark_to_string(field_id), "gst-rtpjitterbuffer-stats") ||
+ !g_strcmp0(g_quark_to_string(field_id), "gst-rtpsource-stats"))
+ return TRUE;
+
+ LOG_WARNING("this field[%s] is not supported", g_quark_to_string(field_id));
+ return TRUE;
+
+invoke_cb:
+ /* TODO: invoke callback */
switch (G_VALUE_TYPE(val)) {
case G_TYPE_BOOLEAN:
LOG_DEBUG("field_id[%s] GType[%s] value[%u]",
return TRUE;
}
-static void __get_common_stats(const GstStructure *s, stats_common_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "timestamp", G_TYPE_DOUBLE, &stats->timestamp,
- "type", GST_TYPE_WEBRTC_STATS_TYPE, &stats->type,
- "id", G_TYPE_STRING, &stats->id,
- NULL);
-
- LOG_DEBUG("timestamp[%lf] type[%u] id[%s]", stats->timestamp, stats->type, stats->id);
-}
-
-static void __get_codec_stats(const GstStructure *s, stats_codec_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "payload-type", G_TYPE_UINT, &stats->payload_type,
- "clock-rate", G_TYPE_UINT, &stats->clock_rate,
- "ssrc", G_TYPE_UINT, &stats->ssrc,
- NULL);
-
- LOG_DEBUG("payload-type[%u] clock-rate[%u] ssrc[%u]", stats->payload_type, stats->clock_rate, stats->ssrc);
-}
-
-static void __get_rtp_stream_stats(const GstStructure *s, stats_rtp_stream_s *stats)
+static void __stats_codec_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "ssrc", G_TYPE_UINT, &stats->ssrc,
- "transport-id", G_TYPE_STRING, &stats->transport_id,
- "codec-id", G_TYPE_STRING, &stats->codec_id,
- NULL);
-
- LOG_DEBUG("ssrc[%u] transport-id[%s] codec-id[%s] ", stats->ssrc, stats->transport_id, stats->codec_id);
-}
-
-static void __get_received_rtp_stream_stats(const GstStructure *s, stats_received_rtp_stream_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "packets-received", G_TYPE_UINT64, &stats->packets_received,
- "packets-lost", G_TYPE_UINT64, &stats->packets_lost,
- "packets-discarded", G_TYPE_UINT64, &stats->packets_discarded,
- "packets-repaired", G_TYPE_UINT64, &stats->packets_repaired,
- "jitter", G_TYPE_DOUBLE, &stats->jitter,
- NULL);
-
- LOG_DEBUG("packet-received[%"G_GUINT64_FORMAT"] packets-lost[%"G_GUINT64_FORMAT"] \
- packets-discarded[%"G_GUINT64_FORMAT"] packets-repaired[%"G_GUINT64_FORMAT"] jitter[%lf]",
- stats->packets_received, stats->packets_lost, stats->packets_discarded, stats->packets_repaired, stats->jitter);
-}
-
-static void __get_inbound_rtp_stream_stats(const GstStructure *s, stats_inbound_rtp_stream_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "remote-id", G_TYPE_STRING, &stats->remote_id,
- "bytes-received", G_TYPE_UINT64, &stats->bytes_received,
- "packets-duplicated", G_TYPE_UINT64, &stats->packets_duplicated,
- "fir-count", G_TYPE_UINT, &stats->fir_count,
- "pli-count", G_TYPE_UINT, &stats->pli_count,
- "nack-count", G_TYPE_UINT, &stats->nack_count,
- NULL);
-
- LOG_DEBUG("remote-id[%s] bytes-received[%"G_GUINT64_FORMAT"] packets-duplicated[%"G_GUINT64_FORMAT"] \
- fir-count[%u] pli-count[%u] nack-count[%u]", stats->remote_id, stats->bytes_received, stats->packets_duplicated,
- stats->fir_count, stats->pli_count, stats->nack_count);
-}
-
-static void __get_sent_rtp_stream_stats(const GstStructure *s, stats_sent_rtp_stream_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "packets-sent", G_TYPE_UINT64, &stats->packets_sent,
- "bytes-sent", G_TYPE_UINT64, &stats->bytes_sent,
- NULL);
-
- LOG_DEBUG("packet-sent[%"G_GUINT64_FORMAT"] bytes-sent[%"G_GUINT64_FORMAT"]", stats->packets_sent, stats->bytes_sent);
-}
-
-static void __get_outbound_rtp_stream_stats(const GstStructure *s, stats_outbound_rtp_stream_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "remote-id", G_TYPE_STRING, &stats->remote_id,
- "fir-count", G_TYPE_UINT, &stats->fir_count,
- "pli-count", G_TYPE_UINT, &stats->pli_count,
- "nack-count", G_TYPE_UINT, &stats->nack_count,
- NULL);
-
- LOG_DEBUG("remote-id[%s] fir-count[%u] pli-count[%u] nack-count[%u]",
- stats->remote_id, stats->fir_count, stats->pli_count, stats->nack_count);
-}
-
-static void __get_remote_inbound_rtp_stream_stats(const GstStructure *s, stats_remote_inbound_rtp_stream_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "local-id", G_TYPE_STRING, &stats->local_id,
- "round-trip-time", G_TYPE_DOUBLE, &stats->round_trip_time,
- NULL);
- /* FIXME: fraction-lost should be added */
-
- LOG_DEBUG("local-id[%s] round-trip-time[%lf]", stats->local_id, stats->round_trip_time);
-}
-
-static void __get_remote_outbound_rtp_stream_stats(const GstStructure *s, stats_remote_outbound_rtp_stream_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "local-id", G_TYPE_STRING, &stats->local_id,
- "remote-timestamp", G_TYPE_DOUBLE, &stats->remote_timestamp,
- NULL);
-
- LOG_DEBUG("local-id[%s] remote-timestamp[%lf]", stats->local_id, stats->remote_timestamp);
-}
-
-static void __get_peer_connection_stats(const GstStructure *s, stats_peer_connection_s *stats)
-{
- RET_IF(s == NULL, "s is NULL");
- RET_IF(stats == NULL, "stats is NULL");
-
- gst_structure_get(s,
- "data-channels-opened", G_TYPE_UINT, &stats->data_channels_opened,
- "data-channels-closed", G_TYPE_UINT, &stats->data_channels_closed,
- "data-channels-requested", G_TYPE_UINT, &stats->data_channels_requested,
- "data-channels-accepted", G_TYPE_UINT, &stats->data_channels_accepted,
- NULL);
-
- LOG_DEBUG("data-channels-[opened:%u, closed:%u, requested:%u, accepted:%u]",
- stats->data_channels_opened, stats->data_channels_closed, stats->data_channels_requested, stats->data_channels_accepted);
-}
-
-static void __parse_codec_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
-{
- stats_common_s common;
- stats_codec_s codec;
-
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- __get_common_stats(s, &common);
- __get_codec_stats(s, &codec);
-
- /* TODO: invoke callback */
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
}
-static void __parse_inbound_rtp_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_inbound_rtp_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- stats_common_s common;
- stats_rtp_stream_s rtp_stream;
- stats_received_rtp_stream_s received_rtp_stream;
- stats_inbound_rtp_stream_s inbound_rtp_stream;
GstStructure *rtpjitterbuffer_stats;
GstStructure *rtpsource_stats;
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data 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);
- __get_inbound_rtp_stream_stats(s, &inbound_rtp_stream);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
gst_structure_get(s,
"gst-rtpjitterbuffer-stats", GST_TYPE_STRUCTURE, &rtpjitterbuffer_stats,
"gst-rtpsource-stats", GST_TYPE_STRUCTURE, &rtpsource_stats,
NULL);
-
- gst_structure_foreach(rtpjitterbuffer_stats, __gststructure_foreach_cb, NULL);
- gst_structure_foreach(rtpsource_stats, __gststructure_foreach_cb, NULL);
-
- /* TODO: invoke callback */
+ gst_structure_foreach(rtpjitterbuffer_stats, __gststructure_foreach_cb, user_data);
+ gst_structure_foreach(rtpsource_stats, __gststructure_foreach_cb, user_data);
}
-static void __parse_outbound_rtp_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_outbound_rtp_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- stats_common_s common;
- stats_rtp_stream_s rtp_stream;
- stats_sent_rtp_stream_s sent_rtp_stream;
- stats_outbound_rtp_stream_s outbound_rtp_stream;
GstStructure *rtpsource_stats;
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data 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);
- __get_outbound_rtp_stream_stats(s, &outbound_rtp_stream);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
gst_structure_get(s, "gst-rtpsource-stats", GST_TYPE_STRUCTURE, &rtpsource_stats, NULL);
- gst_structure_foreach(rtpsource_stats, __gststructure_foreach_cb, NULL);
-
- /* TODO: invoke callback */
+ gst_structure_foreach(rtpsource_stats, __gststructure_foreach_cb, user_data);
}
-static void __parse_remote_inbound_rtp_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_remote_inbound_rtp_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- stats_common_s common;
- stats_rtp_stream_s rtp_stream;
- stats_remote_inbound_rtp_stream_s remote_inbound_rtp_stream;
-
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data 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.
- * __get_received_rtp_stream_stats(s, &received_rtp_stream); */
- __get_remote_inbound_rtp_stream_stats(s, &remote_inbound_rtp_stream);
-
- /* TODO: invoke callback */
+ /* FIXME: only 'jitter' and 'packet-lost'(int) are available. type of 'packet-lost' should be fixed.*/
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
}
-static void __parse_remote_outbound_rtp_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_remote_outbound_rtp_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- stats_common_s common;
- stats_rtp_stream_s rtp_stream;
- stats_remote_outbound_rtp_stream_s remote_outbound_rtp_stream;
- /* NOTE: stats_sent_rtp_stream_s does not exist that differs from WebRTC SPEC. */
-
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data 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);
-
- /* TODO: invoke callback */
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
}
-static void __parse_csrc_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_csrc_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-static void __parse_peer_connection_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_peer_connection_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- stats_common_s common;
- stats_peer_connection_s peer_connection;
-
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- __get_common_stats(s, &common);
- __get_peer_connection_stats(s, &peer_connection);
-
- /* TODO: invoke callback */
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
}
-static void __parse_data_channel_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_data_channel_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-static void __parse_stream_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_stream_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-static void __parse_transport_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_transport_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-static void __parse_candidate_pair_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_candidate_pair_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-static void __parse_local_candidate_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_local_candidate_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-static void __parse_remote_candidate_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_remote_candidate_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-static void __parse_certificate_and_invoke_callback(const GstStructure *s, webrtc_callbacks_s *cb)
+static void __stats_certificate_invoke_callback(const GstStructure *s, stats_userdata_s *user_data)
{
- RET_IF(cb == NULL, "cb is NULL");
+ RET_IF(user_data == NULL, "user_data is NULL");
LOG_DEBUG_ENTER();
- gst_structure_foreach(s, __gststructure_foreach_cb, NULL);
+ gst_structure_foreach(s, __gststructure_foreach_cb, user_data);
/* not implemented */
}
-typedef void (*stats_func)(const GstStructure *s, webrtc_callbacks_s *cb);
+typedef void (*stats_func)(const GstStructure *s, stats_userdata_s *user_data);
/* Note that stats_type_mask_e below follows GstWebRTCStatsType of webrtc_fwd.h */
typedef enum {
typedef struct {
stats_func func;
stats_type_mask_e type_mask;
+ stats_field_s **fields_list;
} 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 }
+ [GST_WEBRTC_STATS_CODEC] = {
+ __stats_codec_invoke_callback, STATS_TYPE_CODEC_MASK, __stats_codec_fields_list },
+ [GST_WEBRTC_STATS_INBOUND_RTP] = {
+ __stats_inbound_rtp_invoke_callback, STATS_TYPE_INBOUND_RTP_MASK, __stats_inbound_rtp_fields_list },
+ [GST_WEBRTC_STATS_OUTBOUND_RTP] = {
+ __stats_outbound_rtp_invoke_callback, STATS_TYPE_OUTBOUND_RTP_MASK, __stats_outbound_rtp_fields_list },
+ [GST_WEBRTC_STATS_REMOTE_INBOUND_RTP] = {
+ __stats_remote_inbound_rtp_invoke_callback, STATS_TYPE_REMOTE_INBOUND_RTP_MASK, __stats_remote_inbound_rtp_fields_list },
+ [GST_WEBRTC_STATS_REMOTE_OUTBOUND_RTP] = {
+ __stats_remote_outbound_rtp_invoke_callback, STATS_TYPE_REMOTE_OUTBOUND_RTP_MASK, __stats_remote_outbound_rtp_fields_list },
+ [GST_WEBRTC_STATS_CSRC] = {
+ __stats_csrc_invoke_callback, STATS_TYPE_CSRC_MASK, NULL },
+ [GST_WEBRTC_STATS_PEER_CONNECTION] = {
+ __stats_peer_connection_invoke_callback, STATS_TYPE_PEER_CONNECTION_MASK, __stats_peer_connection_fields_list },
+ [GST_WEBRTC_STATS_DATA_CHANNEL] = {
+ __stats_data_channel_invoke_callback, STATS_TYPE_DATA_CHANNEL_MASK, NULL },
+ [GST_WEBRTC_STATS_STREAM] = {
+ __stats_stream_invoke_callback, STATS_TYPE_STREAM_MASK, NULL },
+ [GST_WEBRTC_STATS_TRANSPORT] = {
+ __stats_transport_invoke_callback, STATS_TYPE_TRANSPORT_MASK, NULL },
+ [GST_WEBRTC_STATS_CANDIDATE_PAIR] = {
+ __stats_candidate_pair_invoke_callback, STATS_TYPE_CANDIDATE_PAIR_MASK, NULL },
+ [GST_WEBRTC_STATS_LOCAL_CANDIDATE] = {
+ __stats_local_candidate_invoke_callback, STATS_TYPE_LOCAL_CANDIDATE_MASK, NULL },
+ [GST_WEBRTC_STATS_REMOTE_CANDIDATE] = {
+ __stats_remote_candidate_invoke_callback, STATS_TYPE_REMOTE_CANDIDATE_MASK, NULL },
+ [GST_WEBRTC_STATS_CERTIFICATE] = {
+ __stats_certificate_invoke_callback, STATS_TYPE_CERTIFICATE_MASK, NULL }
};
-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)
{
stats_userdata_s *stats_userdata = (stats_userdata_s *)user_data;
return TRUE;
}
- parse_stats[type].func(s, &stats_userdata->webrtc->stats_cb);
+ stats_userdata->fields_list = parse_stats[type].fields_list;
+ parse_stats[type].func(s, stats_userdata);
} else {
LOG_ERROR("unknown field \'%s\' value type: \'%s\'",
LOG_DEBUG("remove stats_timer_src[%u]", webrtc->stats_timer_src);
webrtc->stats_timer_src = 0;
}
+
+void _init_stats_all_fields_list(void)
+{
+ int i, j;
+ for (i = 0; __stats_all_fields_list[i]; i++)
+ for (j = 0; __stats_all_fields_list[i][j].name; j++)
+ if (__stats_all_fields_list[i][j].id == 0)
+ __stats_all_fields_list[i][j].id = g_quark_from_string(__stats_all_fields_list[i][j].name);
+}
//LCOV_EXCL_STOP
\ No newline at end of file