[gst-debugger/refactor-v1.0] refactor: part 1
- From: Marcin Kolny <mkolny src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gst-debugger/refactor-v1.0] refactor: part 1
- Date: Wed, 30 Sep 2015 23:07:42 +0000 (UTC)
commit 76e77b443d854582ab7c0852b37b117d2c51bf27
Author: Marcin Kolny <marcin kolny gmail com>
Date: Sun Sep 27 13:58:05 2015 +0200
refactor: part 1
src/common/gstdebugger.proto | 293 ++++----
src/common/serializer.c | 2 +-
src/debugserver/Makefile.am | 8 +-
src/debugserver/gstdebugserver.c | 784 +++++---------------
src/debugserver/gstdebugserver.h | 16 +-
src/debugserver/gstdebugserverfactory.c | 101 ---
src/debugserver/gstdebugserverlog.c | 168 +++--
src/debugserver/gstdebugserverlog.h | 22 +-
src/debugserver/gstdebugservermessage.c | 130 ++--
src/debugserver/gstdebugservermessage.h | 38 +-
src/debugserver/gstdebugserverqe.c | 248 +++----
src/debugserver/gstdebugserverqe.h | 23 +-
src/debugserver/gstdebugservertcp.c | 267 ++++---
src/debugserver/gstdebugservertcp.h | 37 +-
src/debugserver/gstdebugservertopology.c | 79 +-
src/debugserver/gstdebugservertopology.h | 8 +-
src/debugserver/gstdebugservertypes.c | 157 ++++
...tdebugserverfactory.h => gstdebugservertypes.h} | 15 +-
src/debugserver/gstdebugserverwatcher.c | 95 +++
src/debugserver/gstdebugserverwatcher.h | 52 ++
src/gst-debugger/Makefile.am | 137 ++---
src/gst-debugger/controller/command_factory.cpp | 132 ++--
src/gst-debugger/controller/command_factory.h | 19 +-
src/gst-debugger/controller/controller.cpp | 167 +++--
src/gst-debugger/controller/controller.h | 52 +-
src/gst-debugger/controller/tcp_client.cpp | 9 +-
src/gst-debugger/controller/tcp_client.h | 5 +-
.../controller/topology_controller.cpp | 30 +-
src/gst-debugger/controller/topology_controller.h | 8 +-
src/gst-debugger/dialogs/enums_dialog.cpp | 2 +-
src/gst-debugger/dialogs/factories_dialog.cpp | 8 +-
src/gst-debugger/dialogs/factories_dialog.h | 2 +-
src/gst-debugger/main.cpp | 4 +-
src/gst-debugger/main_window.cpp | 7 +-
src/gst-debugger/main_window.h | 15 +-
src/gst-debugger/models/gst_pipeline_model.cpp | 4 +-
src/gst-debugger/models/gst_pipeline_model.h | 2 +-
src/gst-debugger/modules/base_main_module.cpp | 67 ++-
src/gst-debugger/modules/base_main_module.h | 36 +-
src/gst-debugger/modules/bus_messages_module.cpp | 95 ---
src/gst-debugger/modules/bus_messages_module.h | 44 --
src/gst-debugger/modules/control_module.h | 120 ++--
src/gst-debugger/modules/event_module.cpp | 79 ++
src/gst-debugger/modules/event_module.h | 37 +
src/gst-debugger/modules/gst_properties_module.cpp | 31 +-
src/gst-debugger/modules/gst_properties_module.h | 6 +-
src/gst-debugger/modules/log_module.cpp | 118 ++--
src/gst-debugger/modules/log_module.h | 40 +-
src/gst-debugger/modules/main_module.cpp | 22 +-
src/gst-debugger/modules/message_module.cpp | 113 +++
src/gst-debugger/modules/message_module.h | 50 ++
src/gst-debugger/modules/pad_data_modules.cpp | 209 ------
src/gst-debugger/modules/pad_data_modules.h | 100 ---
.../modules/pad_path_control_module.cpp | 119 ---
src/gst-debugger/modules/pad_path_control_module.h | 39 -
.../modules/pad_path_types_control_module.h | 51 --
src/gst-debugger/modules/qe_control_module.h | 99 +++
src/gst-debugger/modules/query_module.cpp | 73 ++
src/gst-debugger/modules/query_module.h | 37 +
src/gst-debugger/modules/types_control_module.cpp | 145 ----
src/gst-debugger/modules/types_control_module.h | 45 --
src/gst-debugger/pipeline-drawer/graph_module.cpp | 2 +-
src/gst-debugger/ui/gst-debugger.glade | 9 +-
src/gst-debugger/ui_utils.cpp | 2 +-
src/gst-debugger/ui_utils.h | 2 +-
65 files changed, 2262 insertions(+), 2674 deletions(-)
---
diff --git a/src/common/gstdebugger.proto b/src/common/gstdebugger.proto
index 78abc61..e53afa7 100644
--- a/src/common/gstdebugger.proto
+++ b/src/common/gstdebugger.proto
@@ -1,118 +1,166 @@
syntax = "proto2";
-enum Toggle {
- ENABLE = 0;
- DISABLE = 1;
+package GstDebugger;
+
+enum Action {
+ ADD = 0;
+ REMOVE = 1;
}
-message PadWatch {
- required string pad_path = 1;
- required Toggle toggle = 2;
+message Value {
+ required uint64 gtype = 1;
+ optional int32 internal_type = 2;
+ required bytes data = 3;
+}
- enum WatchType {
- BUFFER = 0;
- EVENT = 1;
- QUERY = 2;
- }
- required WatchType watch_type = 3;
- optional int32 qe_type = 4;
+message PropertyInfo {
+ required string name = 1;
+ required string nick = 2;
+ required string blurb = 3;
+ required int32 flags = 4;
+ required Value value = 5;
+ required string object = 6;
}
-message LogWatch {
- required int32 log_level = 1; // not supported yet
- required Toggle toggle = 2;
- optional string log_category = 3; // not supported yet
+message PropertyRequest {
+ optional string name = 1;
+ required string object = 2;
}
-message MessageWatch {
- required int32 message_type = 1;
- required Toggle toggle = 2;
+message MessageRequest {
+ required Action action = 1;
+ required int32 type = 2;
}
-message DebugCategoryList {
- required string list = 1;
+message MessageInfo {
+ required int32 type = 1;
+ required uint64 timestamp = 2;
+ required string source = 3;
+ required uint32 seqnum = 4;
+ required bytes structure_data = 5;
}
-message LogThreshold {
- required string list = 1;
- required bool overwrite = 2;
+message LogRequest {
+ required Action action = 1;
+ required int32 level = 2;
+ optional string category = 3;
}
-message EnumEntry {
- required string name = 1;
- required int32 value = 2;
- required string nick = 3;
+message QueryWatchRequest {
+ required int32 type = 1;
}
-message EnumType {
- repeated EnumEntry entry = 1;
- required string type_name = 2;
- required uint64 base_gtype = 3;
-}
-
-message Property {
- required string element_path = 1;
- required string property_name = 2;
- optional uint32 type = 3;
- optional int32 internal_type = 4;
- optional string type_name = 5;
- optional string property_value = 6;
- optional string description = 7;
- optional int32 flags = 8;
-}
-
-message Command {
- optional PadWatch pad_watch = 1;
- optional LogWatch log_watch = 2;
- optional MessageWatch message_watch = 3;
- optional LogThreshold log_threshold = 4;
- optional Property property = 5;
- optional string enum_name = 6;
- optional string factory_name = 7;
- optional string pad_path = 8;
-
- enum CommandType {
- PAD_WATCH = 0;
- LOG_WATCH = 1;
- MESSAGE_WATCH = 2;
- LOG_THRESHOLD = 3;
- DEBUG_CATEGORIES = 4;
- TOPOLOGY = 5;
- PROPERTY = 6;
- ENUM_TYPE = 7;
- FACTORY = 8;
- PAD_DYNAMIC_INFO = 9;
+message BufferWatchRequest {
+ required bool send_data = 1;
+}
+
+message EventWatchRequest {
+ required int32 type = 1;
+}
+
+message PadWatchRequest {
+ required Action action = 1;
+ optional string pad = 2;
+
+ oneof pad_watch_type {
+ QueryWatchRequest query = 3;
+ BufferWatchRequest buffer = 4;
+ EventWatchRequest event = 5;
}
- required CommandType command_type = 9;
}
-message GstreamerLog {
+message EventInfo {
+ required int32 type = 1;
+ required uint64 timestamp = 2;
+ required uint32 seqnum = 3;
+ required string pad = 4;
+ required bytes structure_data = 5;
+}
+
+message QueryInfo {
+ required int32 type = 1;
+ required string pad = 2;
+ required bytes structure_data = 3;
+}
+
+message TypeDescriptionRequest {
+ enum Type {
+ FACTORY = 0;
+ ENUM_FLAGS = 1;
+ KLASS = 2;
+ }
+
+ required string name = 1;
+ required Type type = 2;
+}
+
+message Command {
+ oneof command_type {
+ TypeDescriptionRequest type_description = 1;
+ bool debug_categories_list = 2;
+ MessageRequest message = 3;
+ LogRequest log = 4;
+ PadWatchRequest pad_watch = 5;
+ string log_threshold = 6;
+ bool entire_topology = 7;
+ PropertyRequest property = 8;
+ }
+}
+
+message DebugCategories {
+ repeated string category = 1;
+}
+
+message LogInfo {
required int32 level = 1;
- required string category_name = 2;
+ required string category = 2;
required string file = 3;
required string function = 4;
required int32 line = 5;
- required string object_path = 6;
+ required string object = 6;
required string message = 7;
}
-message GstreamerQEBM {
- required bytes payload = 1;
- optional string pad_path = 2;
+message EnumFlagsValue {
+ required string name = 1;
+ required int32 value = 2;
+ required string nick = 3;
+}
+
+message EnumFlagsType {
+ enum EnumFlagsKind {
+ ENUM = 0;
+ FLAGS = 1;
+ }
+
+ required string type_name = 1;
+ required EnumFlagsKind kind = 2;
+ repeated EnumFlagsValue values = 3;
}
-message TopologyLink {
- required string src_pad_path = 1;
- required string sink_pad_path = 2;
+message FactoryMeta {
+ required string key = 1;
+ required string value = 2;
}
-message TopologyTemplate {
+message PadTemplate {
required string name_template = 1;
required int32 direction = 2;
required int32 presence = 3;
required string caps = 4;
}
+message FactoryType {
+ required string name = 1;
+ repeated FactoryMeta metadata = 2;
+ repeated PadTemplate templates = 3;
+}
+
+message TopologyLink {
+ required string src_pad = 1;
+ required string sink_pad = 2;
+}
+
message TopologyElement {
required string path = 1;
required string type_name = 2;
@@ -125,77 +173,30 @@ message TopologyPad {
required bool is_ghostpad = 2;
required int32 direction = 3;
required int32 presence = 4;
- optional TopologyTemplate template = 5;
+ optional PadTemplate template = 5;
}
-message PadDynamicInfo {
- required string allowed_caps = 1;
- required string current_caps = 2;
- required string pad_path = 3;
-}
+message TopologyInfo {
+ required Action action = 1;
-message FactoryMetaEntry {
- required string key = 1;
- required string value = 2;
-}
-
-message FactoryInfo {
- required string name = 1;
- repeated TopologyTemplate templates = 2;
- repeated FactoryMetaEntry meta_entries = 3;
+ oneof topology_type {
+ TopologyLink link = 2;
+ TopologyElement element = 3;
+ TopologyPad pad = 4;
+ }
}
-message Topology {
- enum ObjectType {
- PAD = 0;
- ELEMENT = 1;
- LINK = 2;
+message GStreamerData {
+ oneof info_type {
+ DebugCategories debug_categories = 1;
+ LogInfo log_info = 2;
+ EnumFlagsType enum_flags_type = 3;
+ FactoryType factory = 4;
+ MessageInfo message_info = 5;
+ Command confirmation = 6;
+ EventInfo event_info = 7;
+ TopologyInfo topology_info = 8;
+ QueryInfo query_info = 9;
+ PropertyInfo property_info = 10;
}
- enum Action {
- ADD = 0;
- REMOVE = 1;
- }
-
- required ObjectType type = 1;
- required Action action = 2;
- optional TopologyPad pad = 3;
- optional TopologyElement element = 4;
- optional TopologyLink link = 5;
-}
-
-message ServerError {
- required string message = 1;
-}
-
-message GstreamerInfo {
- enum InfoType {
- BUFFER = 0;
- EVENT = 1;
- QUERY = 2;
- MESSAGE = 3;
- LOG = 4;
- DEBUG_CATEGORIES = 5;
- TOPOLOGY = 6;
- PAD_WATCH_CONFIRMATION = 7;
- MESSAGE_CONFIRMATION = 8;
- PROPERTY = 9;
- SERVER_ERROR = 10;
- ENUM_TYPE = 11;
- FACTORY = 12;
- PAD_DYNAMIC_INFO = 13;
- }
-
- required InfoType info_type = 1;
-
- optional GstreamerLog log = 2;
- optional DebugCategoryList debug_categories = 3;
- optional GstreamerQEBM qebm = 4;
- optional PadWatch confirmation = 5;
- optional MessageWatch bus_msg_confirmation = 6;
- optional Topology topology = 7;
- optional Property property = 8;
- optional ServerError server_error = 9;
- optional EnumType enum_type = 10;
- optional FactoryInfo factory_info = 11;
- optional PadDynamicInfo pad_dynamic_info = 12;
-}
\ No newline at end of file
+}
diff --git a/src/common/serializer.c b/src/common/serializer.c
index 52beffa..6ab3c04 100644
--- a/src/common/serializer.c
+++ b/src/common/serializer.c
@@ -128,7 +128,7 @@ gchar * g_value_serialize (GValue * value, GType * type, InternalGType * interna
val = g_value_get_flags (value);
*internal_type = INTERNAL_GTYPE_FLAGS;
} else {
- val = g_value_get_enum(value);
+ val = g_value_get_enum (value);
*internal_type = INTERNAL_GTYPE_ENUM;
}
g_value_set_int(&tmp, val);
diff --git a/src/debugserver/Makefile.am b/src/debugserver/Makefile.am
index b2feecf..ba3f26e 100644
--- a/src/debugserver/Makefile.am
+++ b/src/debugserver/Makefile.am
@@ -3,12 +3,14 @@ plugin_LTLIBRARIES = libgstdebugserver.la
libgstdebugserver_la_SOURCES = \
gstdebugserver.c gstdebugserver.h \
gstdebugservertcp.c gstdebugservertcp.h \
- gstdebugserverbuffer.c gstdebugserverbuffer.h \
- gstdebugservermessage.c gstdebugservermessage.h \
gstdebugserverlog.c gstdebugserverlog.h \
+ gstdebugservermessage.c gstdebugservermessage.h \
+ gstdebugservertypes.c gstdebugservertypes.h \
gstdebugserverqe.c gstdebugserverqe.h \
gstdebugservertopology.c gstdebugservertopology.h \
- gstdebugserverfactory.c gstdebugserverfactory.h
+ gstdebugserverwatcher.c gstdebugserverwatcher.h
+# gstdebugserverbuffer.c gstdebugserverbuffer.h \
+# gstdebugserverfactory.c gstdebugserverfactory.h
libgstdebugserver_la_LDFLAGS = $(GSTREAMER_LIBS) $(PROTOBUF_C_LIBS) $(GIO_LIBS)
libgstdebugserver_la_LIBADD = ../common/libgst-debugger-common-c- GST_DEBUGGER_API_VERSION@.la
diff --git a/src/debugserver/gstdebugserver.c b/src/debugserver/gstdebugserver.c
index ff6d950..789ef9c 100644
--- a/src/debugserver/gstdebugserver.c
+++ b/src/debugserver/gstdebugserver.c
@@ -31,12 +31,11 @@
#endif
#include "gstdebugserver.h"
+
#include "gstdebugservertopology.h"
-#include "gstdebugserverfactory.h"
+
#include "common/gst-utils.h"
-#include "common/buffer-prepare-utils.h"
#include "common/serializer.h"
-#include "common/deserializer.h"
#include <string.h>
@@ -61,49 +60,33 @@ static void gst_debugserver_tracer_set_property (GObject * object,
static void gst_debugserver_tracer_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec);
+static void gst_debugserver_command_handler (GstDebugger__Command * command,
+ gpointer debugtracer, TcpClient * client);
+
static void gst_debugserver_tracer_finalize (GObject * obj);
static void
-gst_debugserver_handle_error (GstDebugserverTracer *server,
- GSocketConnection * client_id, const gchar * message);
+gst_debugserver_log_handler (GstDebugCategory *category, GstDebugLevel level,
+ const gchar *file, const gchar *function, gint line, GObject *object,
+ GstDebugMessage *message, gpointer user_data) G_GNUC_NO_INSTRUMENT;
static void
-gst_debugserver_tracer_log_function (GstDebugCategory * category,
- GstDebugLevel level, const gchar * file, const gchar * function, gint line,
- GObject * object, GstDebugMessage * message, gpointer user_data)
- G_GNUC_NO_INSTRUMENT;
-
-static void gst_debugserver_tracer_close_connection (GstDebugserverTracer * debugserver)
+gst_debugserver_log_handler (GstDebugCategory *category, GstDebugLevel level,
+ const gchar *file, const gchar *function, gint line, GObject *object,
+ GstDebugMessage *message, gpointer user_data)
{
- gst_debugserver_message_clean (debugserver->msg_handler);
- gst_debugserver_log_clean (debugserver->log_handler);
- gst_debugserver_qe_clean (debugserver->event_handler);
- gst_debugserver_qe_clean (debugserver->query_handler);
- gst_debugserver_buffer_clean (debugserver->buffer_handler);
+ GstDebugserverTracer *tracer = GST_DEBUGSERVER_TRACER (user_data);
- gst_debugserver_tcp_stop_server (debugserver->tcp_server);
+ gst_debugserver_log_send_log (tracer->log, tracer->tcp_server, category, level,
+ file, function, line, object, message);
}
static void
message_broadcaster (GstBus * bus, GstMessage * message, gpointer user_data)
{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (user_data);
- GSocketConnection *connection;
- GSList *clients = gst_debugserver_message_get_clients (debugserver->msg_handler,
- GST_MESSAGE_TYPE (message));
- GSList *cl_tmp = clients;
- gsize size;
- gchar buff[1024];
-
- while (clients != NULL) {
- connection = (GSocketConnection*)clients->data;
- size = gst_debugserver_qebm_prepare_buffer (GST_MINI_OBJECT (message), NULL, buff, 1024);
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, connection,
- buff, size);
- clients = clients->next;
- }
+ GstDebugserverTracer *self = GST_DEBUGSERVER_TRACER (user_data);
- g_slist_free (cl_tmp);
+ gst_debugserver_message_send_message (self->message, self->tcp_server, message);
}
static void
@@ -122,28 +105,25 @@ do_element_new (GstTracer * self, guint64 ts, GstElement * element)
static void
do_pad_unlink_post (GstTracer * self, guint64 ts, GstPad * src, GstPad * sink, gboolean result)
{
- if (result == FALSE) {
- return;
+ if (result == TRUE) {
+ gst_debugserver_topology_send_pad_link (src, sink, FALSE, GST_DEBUGSERVER_TRACER (self)->tcp_server,
NULL);
}
- gst_debugserver_topology_send_pad_link (src, sink, FALSE, GST_DEBUGSERVER_TRACER (self)->tcp_server, NULL);
}
static void
do_pad_link_post (GstTracer * self, guint64 ts, GstPad * src, GstPad * sink, GstPadLinkReturn result)
{
- if (result == FALSE) {
- return;
+ if (result == TRUE) {
+ gst_debugserver_topology_send_pad_link (src, sink, TRUE, GST_DEBUGSERVER_TRACER (self)->tcp_server,
NULL);
}
- gst_debugserver_topology_send_pad_link (src, sink, TRUE, GST_DEBUGSERVER_TRACER (self)->tcp_server, NULL);
}
static void
do_bin_add_post (GstTracer * self, gint64 ts, GstBin * bin, GstElement * element, gboolean result)
{
- if (result == FALSE) {
- return;
+ if (result == TRUE) {
+ gst_debugserver_topology_send_element_in_bin (bin, element, TRUE, GST_DEBUGSERVER_TRACER
(self)->tcp_server, NULL);
}
- gst_debugserver_topology_send_element_in_bin (bin, element, TRUE, GST_DEBUGSERVER_TRACER
(self)->tcp_server, NULL);
}
static void
@@ -164,518 +144,36 @@ do_element_remove_pad (GstTracer * self, gint64 ts, GstElement * element, GstPad
gst_debugserver_topology_send_pad_in_element (element, pad, FALSE, GST_DEBUGSERVER_TRACER
(self)->tcp_server, NULL);
}
-
static void
do_push_event_pre (GstTracer * self, guint64 ts, GstPad * pad, GstEvent * event)
{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (self);
- GSocketConnection *connection;
- GSList *clients = gst_debugserver_qe_get_clients (debugserver->event_handler,
- pad, event->type);
- gsize size;
- SAFE_PREPARE_BUFFER_INIT (1024);
+ GstDebugserverTracer *tracer = GST_DEBUGSERVER_TRACER (self);
- if (clients == NULL) {
- return;
- }
-
- SAFE_PREPARE_BUFFER (
- gst_debugserver_qebm_prepare_buffer (GST_MINI_OBJECT (event), gst_utils_get_object_path
(GST_OBJECT_CAST (pad)), m_buff, max_m_buff_size), size);
-
- while (clients != NULL) {
- connection = (GSocketConnection*)clients->data;
- gst_debugserver_tcp_send_packet (GST_DEBUGSERVER_TRACER (self)->tcp_server, connection,
- m_buff, size);
- clients = clients->next;
- }
-
- SAFE_PREPARE_BUFFER_CLEAN;
+ gst_debugserver_qe_send_qe (tracer->event, tracer->tcp_server, pad, GST_MINI_OBJECT_CAST (event));
}
static void
do_pad_query_pre (GstTracer * self, guint64 ts, GstPad * pad, GstQuery * query)
{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (self);
- GSocketConnection *connection;
- GSList *clients = gst_debugserver_qe_get_clients (debugserver->query_handler,
- pad, query->type);
- gsize size;
- gchar buff[1024];
-
- while (clients != NULL) {
- connection = (GSocketConnection*)clients->data;
- size = gst_debugserver_qebm_prepare_buffer (GST_MINI_OBJECT (query), gst_utils_get_object_path
(GST_OBJECT_CAST (pad)), buff, 1024);
- gst_debugserver_tcp_send_packet (GST_DEBUGSERVER_TRACER (self)->tcp_server, connection,
- buff, size);
- clients = clients->next;
- }
-}
-
-static void
-do_pad_push_pre (GstTracer * self, guint64 ts, GstPad * pad, GstBuffer * buffer)
-{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (self);
- GSocketConnection *connection;
- GSList *clients = gst_debugserver_buffer_get_clients (debugserver->buffer_handler,
- pad);
- gsize size;
- SAFE_PREPARE_BUFFER_INIT (1024);
-
- if (clients == NULL) {
- return;
- }
-
- SAFE_PREPARE_BUFFER (
- gst_debugserver_qebm_prepare_buffer (GST_MINI_OBJECT (buffer), gst_utils_get_object_path
(GST_OBJECT_CAST (pad)), m_buff, max_m_buff_size), size);
-
- while (clients != NULL) {
- connection = (GSocketConnection*)clients->data;
- gst_debugserver_tcp_send_packet (GST_DEBUGSERVER_TRACER (self)->tcp_server, connection,
- m_buff, size);
- clients = clients->next;
- }
-
- SAFE_PREPARE_BUFFER_CLEAN;
-
- g_slist_free (clients);
-}
-
-#define ENUM_FLAG_PREPARE_BUFFER_METHOD(KLASS_VALUE, BASE_GTYPE) \
- do { \
- KLASS_VALUE *values = klass->values; \
- guint i = 0; \
- EnumEntry **entries; \
- GstreamerInfo info = GSTREAMER_INFO__INIT; \
- EnumType msg = ENUM_TYPE__INIT; \
- info.info_type = GSTREAMER_INFO__INFO_TYPE__ENUM_TYPE; \
- gint len; \
- entries = g_malloc (sizeof (EnumEntry) * (klass->n_values)); \
- for (i = 0; i < klass->n_values; i++) { \
- entries[i] = g_malloc (sizeof (EnumEntry)); \
- enum_entry__init (entries[i]); \
- entries[i]->name = (gchar*) values[i].value_name; \
- entries[i]->value = values[i].value; \
- entries[i]->nick = (gchar*) values[i].value_nick; \
- } \
- msg.entry = entries; \
- msg.n_entry = klass->n_values; \
- msg.type_name = (gchar*) G_ENUM_CLASS_TYPE_NAME (klass); \
- msg.base_gtype = BASE_GTYPE; \
- info.enum_type = &msg; \
- len = gstreamer_info__get_packed_size (&info); \
- if (len > size) { \
- goto finalize; \
- } \
- gstreamer_info__pack (&info, (uint8_t*) buffer); \
- finalize: \
- for (i = 0; i < klass->n_values; i++) { \
- g_free (entries[i]); \
- } \
- g_free (entries); \
- return len; \
- } while (FALSE);
-
-static gint
-gst_debug_server_prepare_enum_type_buffer (GEnumClass * klass, gchar * buffer, gint size)
-{
- ENUM_FLAG_PREPARE_BUFFER_METHOD(GEnumValue, G_TYPE_ENUM)
-}
+ GstDebugserverTracer *tracer = GST_DEBUGSERVER_TRACER (self);
-static gint
-gst_debug_server_prepare_flags_type_buffer (GFlagsClass * klass, gchar * buffer, gint size)
-{
- ENUM_FLAG_PREPARE_BUFFER_METHOD(GFlagsValue, G_TYPE_FLAGS)
+ gst_debugserver_qe_send_qe (tracer->query, tracer->tcp_server, pad, GST_MINI_OBJECT_CAST (query));
}
static void
-gst_debugserver_send_enum (GstDebugserverTracer * debugserver, GSocketConnection * client, const gchar *
klass_name)
-{
- GType type = g_type_from_name (klass_name);
- GEnumClass *klass = g_type_class_peek (type);
- SAFE_PREPARE_BUFFER_INIT (1024);
- gint size;
-
- if (klass == NULL) {
- gst_debugserver_handle_error (debugserver, client, "Cannot find enum type");
- return;
- }
-
- SAFE_PREPARE_BUFFER (
- gst_debug_server_prepare_enum_type_buffer (klass, m_buff, max_m_buff_size), size);
-
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, client, m_buff, size);
- SAFE_PREPARE_BUFFER_CLEAN;
-}
-
-static void
-gst_debugserver_send_flag (GstDebugserverTracer * debugserver, GSocketConnection * client, const gchar *
klass_name)
-{
- GType type = g_type_from_name (klass_name);
- GFlagsClass *klass = g_type_class_peek (type);
- SAFE_PREPARE_BUFFER_INIT (1024);
- gint size;
-
- if (klass == NULL) {
- gst_debugserver_handle_error (debugserver, client, "Cannot find flags type");
- return;
- }
-
- SAFE_PREPARE_BUFFER (
- gst_debug_server_prepare_flags_type_buffer (klass, m_buff, max_m_buff_size), size);
-
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, client, m_buff, size);
- SAFE_PREPARE_BUFFER_CLEAN;
-}
-
-static void
-gst_debugserver_send_enum_flags (GstDebugserverTracer * debugserver, GSocketConnection * client, const gchar
* klass_name)
-{
- GType type = g_type_from_name (klass_name);
-
- if (G_TYPE_IS_ENUM (type)) {
- gst_debugserver_send_enum (debugserver, client, klass_name);
- } else if (G_TYPE_IS_FLAGS (type)) {
- gst_debugserver_send_flag (debugserver, client, klass_name);
- } else {
- gst_debugserver_handle_error (debugserver, client, "requested type info is neither enum nor flags");
- }
-}
-
-static gint
-gst_debugserver_pad_prepare_dynamic_info_buffer (GstPad * pad, gchar * buffer, gint max_size)
-{
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- PadDynamicInfo pad_info = PAD_DYNAMIC_INFO__INIT;
- gint size;
- GstCaps *allowed_caps = gst_pad_get_allowed_caps (pad);
- gchar *allowed_caps_str = gst_caps_to_string (allowed_caps);
- GstCaps *current_caps = gst_pad_get_current_caps (pad);
- gchar *current_caps_str = gst_caps_to_string (current_caps);
- gchar *pad_path = gst_utils_get_object_path (GST_OBJECT_CAST (pad));
- pad_info.pad_path = pad_path;
- pad_info.allowed_caps = allowed_caps_str;
- pad_info.current_caps = current_caps_str;
- info.pad_dynamic_info = &pad_info;
- info.info_type = GSTREAMER_INFO__INFO_TYPE__PAD_DYNAMIC_INFO;
-
- size = gstreamer_info__get_packed_size (&info);
- if (size > max_size) {
- goto finalize;
- }
- gstreamer_info__pack (&info, (guint8*)buffer);
-
-finalize:
- if (allowed_caps != NULL) {
- gst_caps_unref (allowed_caps);
- }
- if (current_caps != NULL) {
- gst_caps_unref (current_caps);
- }
- g_free (allowed_caps_str);
- g_free (current_caps_str);
-
- return size;
-
-}
-
-static void
-gst_debugserver_send_pad_dynamic_info (GstDebugserverTracer * debugserver, GSocketConnection * client, const
gchar * pad_path)
-{
- gint size;
- GstPad *pad = gst_utils_get_pad_from_path (GST_ELEMENT_CAST (debugserver->pipeline), pad_path);
- SAFE_PREPARE_BUFFER_INIT (1024);
-
- if (pad == NULL) {
- gst_debugserver_handle_error (debugserver, client, "Cannot find pad for sending dynamic info");
- return;
- }
-
- SAFE_PREPARE_BUFFER (
- gst_debugserver_pad_prepare_dynamic_info_buffer (pad, m_buff, max_m_buff_size), size);
-
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, client, m_buff, size);
- SAFE_PREPARE_BUFFER_CLEAN;
-}
-
-static void
-gst_debugserver_tracer_send_categories (GstDebugserverTracer * debugserver, gpointer client_id)
-{
- gint size;
- GSocketConnection *connection = (GSocketConnection*) client_id;
- SAFE_PREPARE_BUFFER_INIT (1024);
- SAFE_PREPARE_BUFFER (gst_debugserver_log_prepare_categories_buffer (m_buff, max_m_buff_size), size);
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, connection,
- m_buff, size);
- SAFE_PREPARE_BUFFER_CLEAN;
-}
-
-static void
-gst_debugserver_tracer_send_factory (GstDebugserverTracer * debugserver, gpointer client_id, const gchar *
factory_name)
-{
- gint size;
- GstElementFactory *factory = gst_element_factory_find (factory_name);
- if (factory == NULL) {
- gchar *msg = g_strdup_printf ("Cannot find factory %s", factory_name);
- gst_debugserver_handle_error (debugserver, client_id, msg);
- g_free (msg);
- return;
- }
- GSocketConnection *connection = (GSocketConnection*) client_id;
- SAFE_PREPARE_BUFFER_INIT (1024);
- SAFE_PREPARE_BUFFER (gst_debugserver_factory_prepare_buffer (factory, m_buff, max_m_buff_size), size);
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, connection,
- m_buff, size);
- SAFE_PREPARE_BUFFER_CLEAN;
-
- gst_object_unref (factory);
-}
-
-static void
-gst_debugserver_tracer_client_disconnected (gpointer client_id, gpointer user_data)
-{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (user_data);
-
- gst_debugserver_log_set_watch (debugserver->log_handler, FALSE, client_id);
- gst_debugserver_qe_remove_client (debugserver->event_handler, client_id);
- gst_debugserver_qe_remove_client (debugserver->query_handler, client_id);
- gst_debugserver_buffer_remove_client (debugserver->buffer_handler, client_id);
- gst_debugserver_message_remove_client (debugserver->msg_handler, client_id);
-}
-
-static void
-gst_debugserver_tracer_client_connected (gpointer client_id, gpointer user_data)
-{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (user_data);
-
- gst_debugserver_topology_send_entire_topology (
- GST_BIN (debugserver->pipeline), debugserver->tcp_server, client_id);
-
- gst_debugserver_send_enum (debugserver, client_id, "GstQueryType");
-
- gst_debugserver_send_enum (debugserver, client_id, "GstEventType");
-
- gst_debugserver_send_flag (debugserver, client_id, "GstMessageType");
-
- gst_debugserver_tracer_send_categories (debugserver, client_id);
-}
-
-static gint
-gst_debugserver_prepare_property (const gchar * element_path, const GstElement *element, const GParamSpec
*param, gchar * buffer, gint max_size)
-{
- GValue value = {0};
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- Property property = PROPERTY__INIT;
- info.info_type = GSTREAMER_INFO__INFO_TYPE__PROPERTY;
- gint size;
- GType tmptype;
- InternalGType internal_type;
-
- g_value_init (&value, param->value_type);
- g_object_get_property (G_OBJECT (element), param->name, &value);
-
- property.element_path = (gchar*) element_path;
- property.property_name = (gchar*) param->name;
- property.property_value = g_value_serialize (&value, &tmptype, &internal_type);
- property.internal_type = internal_type;
- property.has_internal_type = TRUE;
- property.type = tmptype;
- property.has_type = TRUE;
- property.type_name = (gchar*) g_type_name (value.g_type);
- property.description = (gchar*) g_param_spec_get_blurb ((GParamSpec*) param);
- property.has_flags = TRUE;
- property.flags = param->flags;
- info.property = &property;
- size = gstreamer_info__get_packed_size (&info);
-
- if (size > max_size) {
- goto finalize;
- }
- gstreamer_info__pack (&info, (guint8*)buffer);
-
-finalize:
- return size;
-}
-
-static void
-gst_debugserver_property_send_single_property (GstDebugserverTracer * server, GSocketConnection * client_id,
- const gchar * element_path, const GstElement *element, const GParamSpec *param)
-{
- gint size;
- SAFE_PREPARE_BUFFER_INIT (1024);
-
- SAFE_PREPARE_BUFFER (
- gst_debugserver_prepare_property (element_path, element, param, m_buff, max_m_buff_size), size);
-
- gst_debugserver_tcp_send_packet (server->tcp_server, client_id, m_buff, size);
-
- SAFE_PREPARE_BUFFER_CLEAN;
-}
-
-static gint
-gst_debugserver_prepare_error (const gchar * message, gchar * buffer, gint max_size)
-{
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- ServerError s_err = SERVER_ERROR__INIT;
- gint size;
-
- info.info_type = GSTREAMER_INFO__INFO_TYPE__SERVER_ERROR;
- s_err.message = (gchar*) message;
- info.server_error = &s_err;
-
- size = gstreamer_info__get_packed_size (&info);
-
- if (size > max_size) {
- goto finalize;
- }
-
- gstreamer_info__pack (&info, (guint8*)buffer);
-
-finalize:
- return size;
-}
-
-static void
-gst_debugserver_handle_error (GstDebugserverTracer *server, GSocketConnection * client_id, const gchar *
message)
-{
- gint size;
- SAFE_PREPARE_BUFFER_INIT (1024);
-
- GST_WARNING_OBJECT (server, "%s", message);
-
- SAFE_PREPARE_BUFFER (
- gst_debugserver_prepare_error (message, m_buff, max_m_buff_size), size);
-
- gst_debugserver_tcp_send_packet (server->tcp_server, client_id, m_buff, size);
-
- SAFE_PREPARE_BUFFER_CLEAN;
-}
-
-static void
-gst_debugserver_property_send_property (GstDebugserverTracer * server, GSocketConnection * client_id, const
gchar * element_path, const gchar * property_name)
-{
- GstElement *element = gst_utils_get_element_from_path (GST_ELEMENT_CAST (server->pipeline), element_path);
-
- if (element == NULL) {
- gst_debugserver_handle_error (server, client_id, "Cannot find element");
- return;
- }
-
- GstElementClass *element_class = GST_ELEMENT_GET_CLASS (element);
-
- if (property_name == NULL || strlen (property_name) == 0) {
- guint num_properties, i;
- GParamSpec **property_specs = g_object_class_list_properties
- (G_OBJECT_GET_CLASS (element), &num_properties);
-
- for (i = 0; i < num_properties; i++) {
- gst_debugserver_property_send_single_property (server, client_id, element_path, element,
property_specs[i]);
- }
-
- g_free (property_specs);
- } else {
- GParamSpec *param = g_object_class_find_property ((GObjectClass *)element_class, property_name);
- if (param == NULL) {
- gst_debugserver_handle_error (server, client_id, "Cannot find property");
- return;
- }
- gst_debugserver_property_send_single_property (server, client_id, element_path, element, param);
- }
-}
-
-static void
-gst_debugserver_tracer_process_pad_watch_command (GstDebugserverTracer* debugserver, PadWatch *watch,
gpointer client_id)
+do_pad_push_pre (GstTracer * self, guint64 ts, GstPad * pad, GstBuffer * buffer)
{
- gint size;
- gchar buff[1024];
-
- switch (watch->watch_type) {
- case PAD_WATCH__WATCH_TYPE__EVENT:
- case PAD_WATCH__WATCH_TYPE__QUERY:
- if (gst_debugserver_qe_set_watch (
- watch->watch_type == PAD_WATCH__WATCH_TYPE__EVENT ? debugserver->event_handler :
debugserver->query_handler,
- watch->toggle == TOGGLE__ENABLE,
- gst_utils_get_pad_from_path (GST_ELEMENT (debugserver->pipeline), watch->pad_path),
- watch->qe_type, client_id)) {
- size = gst_debugserver_qeb_prepare_confirmation_buffer (watch->pad_path,
- watch->qe_type, watch->toggle, buff, 1024, watch->watch_type);
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, client_id,
- buff, size);
- }
- break;
- case PAD_WATCH__WATCH_TYPE__BUFFER:
- if (gst_debugserver_buffer_set_watch (debugserver->buffer_handler,
- watch->toggle == TOGGLE__ENABLE,
- gst_utils_get_pad_from_path (GST_ELEMENT (debugserver->pipeline), watch->pad_path),
- client_id)) {
- size = gst_debugserver_qeb_prepare_confirmation_buffer (watch->pad_path,
- -1, watch->toggle, buff, 1024, PAD_WATCH__WATCH_TYPE__BUFFER);
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, client_id,
- buff, size);
- }
- break;
- default:
- break;
- }
}
static void
-gst_debugserver_tracer_process_command (Command * cmd, gpointer client_id,
- gpointer user_data)
+gst_debugserver_tracer_client_disconnected (TcpClient * client, gpointer user_data)
{
- gchar buff[1024];
- gint size;
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (user_data);
+ GstDebugserverTracer *self = GST_DEBUGSERVER_TRACER (user_data);
- switch (cmd->command_type) {
- case COMMAND__COMMAND_TYPE__LOG_THRESHOLD:
- gst_debug_set_threshold_from_string (cmd->log_threshold->list, cmd->log_threshold->overwrite);
- break;
- case COMMAND__COMMAND_TYPE__MESSAGE_WATCH:
- if (gst_debugserver_message_set_watch (debugserver->msg_handler,
- cmd->message_watch->toggle == TOGGLE__ENABLE,
- cmd->message_watch->message_type, client_id)) {
- size = gst_debugserver_message_prepare_confirmation_buffer (cmd->message_watch,
- buff, 1024);
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, client_id,
- buff, size);
- }
- break;
- case COMMAND__COMMAND_TYPE__LOG_WATCH:
- gst_debugserver_log_set_watch (debugserver->log_handler,
- cmd->log_watch->toggle == TOGGLE__ENABLE, client_id);
- break;
- case COMMAND__COMMAND_TYPE__PAD_WATCH:
- gst_debugserver_tracer_process_pad_watch_command (debugserver, cmd->pad_watch, client_id);
- break;
- case COMMAND__COMMAND_TYPE__DEBUG_CATEGORIES:
- gst_debugserver_tracer_send_categories (debugserver, client_id);
- break;
- case COMMAND__COMMAND_TYPE__FACTORY:
- gst_debugserver_tracer_send_factory (debugserver, client_id, cmd->factory_name);
- break;
- case COMMAND__COMMAND_TYPE__TOPOLOGY:
- gst_debugserver_topology_send_entire_topology (GST_BIN (debugserver->pipeline), debugserver->tcp_server,
client_id);
- break;
- case COMMAND__COMMAND_TYPE__PROPERTY:
- if (cmd->property->has_type == FALSE) {
- gst_debugserver_property_send_property (debugserver, client_id, cmd->property->element_path,
cmd->property->property_name);
- } else {
- GValue val = G_VALUE_INIT;
- GstElement *element = gst_utils_get_element_from_path (GST_ELEMENT_CAST (debugserver->pipeline),
cmd->property->element_path);
- g_value_deserialize (&val, cmd->property->type, cmd->property->internal_type,
cmd->property->property_value);
- g_object_set_property (G_OBJECT (element), cmd->property->property_name, &val);
- g_value_unset (&val);
- }
- break;
- case COMMAND__COMMAND_TYPE__ENUM_TYPE:
- gst_debugserver_send_enum_flags (debugserver, client_id, cmd->enum_name);
- break;
- case COMMAND__COMMAND_TYPE__PAD_DYNAMIC_INFO:
- gst_debugserver_send_pad_dynamic_info (debugserver, client_id, cmd->pad_path);
- break;
- default:
- GST_WARNING_OBJECT (debugserver, "Unsupported command type %d", cmd->command_type);
- }
+ gst_debugserver_log_remove_client (self->log, client);
+ gst_debugserver_message_remove_client (self->message, client);
+ gst_debugserver_qe_remove_client (self->event, client);
+ gst_debugserver_qe_remove_client (self->query, client);
}
static void
@@ -694,31 +192,52 @@ gst_debugserver_tracer_class_init (GstDebugserverTracerClass * klass)
}
static void
-gst_debugserver_tracer_log_function (GstDebugCategory * category,
- GstDebugLevel level, const gchar * file, const gchar * function, gint line,
- GObject * object, GstDebugMessage * message, gpointer user_data)
+gst_debugserver_tracer_send_property (GstDebugserverTcp * tcp_server, TcpClient * client, GParamSpec * spec,
GstElement * element)
{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (user_data);
- GSocketConnection *connection;
- GSList *clients = gst_debugserver_log_get_clients (debugserver->log_handler);
- gsize size;
- SAFE_PREPARE_BUFFER_INIT (1024);
+ GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__PropertyInfo property = GST_DEBUGGER__PROPERTY_INFO__INIT;
+ GstDebugger__Value value = GST_DEBUGGER__VALUE__INIT;
+ GType out_gtype;
+ InternalGType out_internal_type;
+ GValue gvalue = G_VALUE_INIT;
+ gchar *object = gst_utils_get_object_path (GST_OBJECT_CAST (element));
+ gchar *serialized_data = NULL;
- if (clients == NULL) {
+ if (spec == NULL) {
return;
}
- SAFE_PREPARE_BUFFER (gst_debugserver_log_prepare_buffer (category, level, file, function,
- line, object, message, m_buff, max_m_buff_size), size);
+ property.blurb = (gchar*) g_param_spec_get_blurb (spec);
+ property.flags = spec->flags;
+ property.name = (gchar*) g_param_spec_get_name (spec);
+ property.nick = (gchar*) g_param_spec_get_nick (spec);
+ property.object = (gchar*) object;
+
+ g_value_init (&gvalue, spec->value_type);
+ g_object_get_property (G_OBJECT (element), g_param_spec_get_name (spec), &gvalue);
+
+ serialized_data = g_value_serialize (&gvalue, &out_gtype, &out_internal_type);
- while (clients != NULL) {
- connection = (GSocketConnection*)clients->data;
- gst_debugserver_tcp_send_packet (debugserver->tcp_server, connection,
- m_buff, size);
- clients = clients->next;
+ value.data.data = serialized_data;
+ value.data.len = serialized_data == NULL ? 0 : strlen (serialized_data);
+ value.gtype = out_gtype;
+
+ if (out_gtype == spec->value_type) {
+ value.internal_type = out_internal_type;
+ value.has_internal_type = TRUE;
+ } else {
+ value.has_internal_type = FALSE;
}
- SAFE_PREPARE_BUFFER_CLEAN;
+ property.value = &value;
+ gst_data.property_info = &property;
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_PROPERTY_INFO;
+
+ gst_debugserver_tcp_send_packet (tcp_server, client, &gst_data);
+
+ g_value_unset (&gvalue);
+ g_free (serialized_data);
+ g_free (object);
}
static void
@@ -726,13 +245,22 @@ gst_debugserver_tracer_init (GstDebugserverTracer * self)
{
GstTracer *tracer = GST_TRACER (self);
- self->pipeline = NULL;
self->port = DEFAULT_PORT;
- self->msg_handler = gst_debugserver_message_new ();
- self->log_handler = gst_debugserver_log_new ();
- self->event_handler = gst_debugserver_qe_new ();
- self->query_handler = gst_debugserver_qe_new ();
- self->buffer_handler = gst_debugserver_buffer_new ();
+
+ self->log = gst_debugserver_log_new ();
+ gst_debug_add_log_function (gst_debugserver_log_handler, self, NULL);
+
+ self->tcp_server = gst_debugserver_tcp_new ();
+ self->tcp_server->command_handler = gst_debugserver_command_handler;
+ self->tcp_server->client_disconnected_handler = gst_debugserver_tracer_client_disconnected;
+ self->tcp_server->owner = self;
+ gst_debugserver_tcp_start_server (self->tcp_server, self->port);
+
+ self->message = gst_debugserver_message_new ();
+
+ self->event = gst_debugserver_qe_new ();
+
+ self->query = gst_debugserver_qe_new ();
gst_tracing_register_hook (tracer, "element-new",
G_CALLBACK (do_element_new));
@@ -754,52 +282,36 @@ gst_debugserver_tracer_init (GstDebugserverTracer * self)
G_CALLBACK (do_pad_link_post));
gst_tracing_register_hook (tracer, "pad-unlink-post",
G_CALLBACK (do_pad_unlink_post));
-
- gst_debug_add_log_function (gst_debugserver_tracer_log_function, self, NULL);
-
- self->tcp_server = gst_debugserver_tcp_new ();
- self->tcp_server->process_command = gst_debugserver_tracer_process_command;
- self->tcp_server->process_command_user_data = self;
- self->tcp_server->client_disconnected = gst_debugserver_tracer_client_disconnected;
- self->tcp_server->parent = self;
- self->tcp_server->client_connected = gst_debugserver_tracer_client_connected;
- gst_debugserver_tcp_start_server (self->tcp_server, self->port);
}
static void
gst_debugserver_tracer_finalize (GObject * obj)
{
- GstDebugserverTracer *debugserver = GST_DEBUGSERVER_TRACER (obj);
+ GstDebugserverTracer *self = GST_DEBUGSERVER_TRACER (obj);
- gst_debug_remove_log_function (gst_debugserver_tracer_log_function);
+ gst_object_unref (GST_DEBUGSERVER_TCP (self->tcp_server));
- gst_debugserver_tracer_close_connection (debugserver);
-
- gst_debugserver_message_free (debugserver->msg_handler);
- gst_debugserver_log_free (debugserver->log_handler);
- gst_debugserver_qe_free (debugserver->event_handler);
- gst_debugserver_qe_free (debugserver->query_handler);
- // gst_debugserver_buffer_free (debugserver->buffer_handler);
-
- g_object_unref (G_OBJECT (debugserver->tcp_server));
+ gst_debug_remove_log_function (gst_debugserver_log_handler);
+ gst_debugserver_log_free (self->log);
+ gst_debugserver_message_free (self->message);
+ gst_debugserver_qe_free (self->event);
+ gst_debugserver_qe_free (self->query);
}
static void
gst_debugserver_tracer_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
- GstDebugserverTracer *debugserver;
+ GstDebugserverTracer *self = GST_DEBUGSERVER_TRACER (object);
gint tmp_port;
- debugserver = GST_DEBUGSERVER_TRACER (object);
-
switch (prop_id) {
case PROP_PORT:
tmp_port = g_value_get_int (value);
- if (tmp_port != debugserver->port) {
- debugserver->port = g_value_get_int (value);
- gst_debugserver_tracer_close_connection (debugserver);
- gst_debugserver_tcp_start_server (debugserver->tcp_server, debugserver->port);
+ if (tmp_port != self->port) {
+ self->port = g_value_get_int (value);
+ gst_debugserver_tcp_stop_server (self->tcp_server);
+ gst_debugserver_tcp_start_server (self->tcp_server, self->port);
}
break;
default:
@@ -826,6 +338,106 @@ gst_debugserver_tracer_get_property (GObject * object, guint prop_id,
}
}
+static void gst_debugserver_process_pad_watch (GstDebugserverTracer * self, GstDebugger__Command * command,
TcpClient * client)
+{
+ GstDebugger__PadWatchRequest *request = command->pad_watch;
+ GstPad *pad = gst_utils_get_pad_from_path (GST_ELEMENT_CAST (self->pipeline), request->pad);
+
+ switch (request->pad_watch_type_case)
+ {
+ case GST_DEBUGGER__PAD_WATCH_REQUEST__PAD_WATCH_TYPE_EVENT:
+ if (gst_debugserver_qe_set_watch (self->event, request->action == GST_DEBUGGER__ACTION__ADD,
request->event->type, pad, request->pad, client)) {
+ GstDebugger__GStreamerData data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ data.confirmation = command;
+ data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_CONFIRMATION;
+ gst_debugserver_tcp_send_packet (self->tcp_server, client, &data);
+ }
+ break;
+ case GST_DEBUGGER__PAD_WATCH_REQUEST__PAD_WATCH_TYPE_QUERY:
+ if (gst_debugserver_qe_set_watch (self->query, request->action == GST_DEBUGGER__ACTION__ADD,
request->query->type, pad, request->pad, client)) {
+ GstDebugger__GStreamerData data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ data.confirmation = command;
+ data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_CONFIRMATION;
+ gst_debugserver_tcp_send_packet (self->tcp_server, client, &data);
+ }
+ break;
+ }
+}
+
+static void gst_debugserver_send_single_property (GstDebugserverTracer * self, TcpClient * client,
GstElement * element, const gchar * name)
+{
+ GParamSpec *spec = g_object_class_find_property (G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (element)), name);
+
+ gst_debugserver_tracer_send_property (self->tcp_server, client, spec, element);
+}
+
+static void gst_debugserver_process_property_request (GstDebugserverTracer * self, TcpClient * client,
+ GstDebugger__PropertyRequest * request)
+{
+ GstElement * element = gst_utils_get_element_from_path (GST_ELEMENT_CAST (self->pipeline),
request->object);
+ gint n_properties, i;
+ GParamSpec **spec;
+
+ if (element == NULL) {
+ return;
+ }
+
+ if (request->name == NULL || request->name[0] == '\0') {
+ spec = g_object_class_list_properties (G_OBJECT_CLASS (GST_ELEMENT_GET_CLASS (element)), &n_properties);
+
+ for (i = 0; i < n_properties; i++) {
+ gst_debugserver_send_single_property (self, client, element, spec[i]->name);
+ }
+ } else {
+ gst_debugserver_send_single_property (self, client, element, request->name);
+ }
+}
+
+static void gst_debugserver_command_handler (GstDebugger__Command * command,
+ gpointer debugtracer, TcpClient * client)
+{
+ GstDebugserverTracer *self = GST_DEBUGSERVER_TRACER (debugtracer);
+ GstDebugserverTcp * tcp = self->tcp_server;
+
+ switch (command->command_type_case) {
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_TYPE_DESCRIPTION:
+ gst_debugserver_types_send_type (tcp, client, command->type_description);
+ break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_DEBUG_CATEGORIES_LIST:
+ gst_debugserver_log_send_debug_categories (tcp, client);
+ break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_LOG_THRESHOLD:
+ gst_debugserver_log_set_threshold (command->log_threshold);
+ break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_MESSAGE:
+ if (gst_debugserver_message_set_watch (self->message, client, command->message)) {
+ GstDebugger__GStreamerData data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ data.confirmation = command;
+ data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_CONFIRMATION;
+ gst_debugserver_tcp_send_packet (self->tcp_server, client, &data);
+ }
+ break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_LOG:
+ if (gst_debugserver_log_set_watch (self->log, command->log->action == GST_DEBUGGER__ACTION__ADD,
+ command->log->level, command->log->category, client)) {
+ GstDebugger__GStreamerData data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ data.confirmation = command;
+ data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_CONFIRMATION;
+ gst_debugserver_tcp_send_packet (self->tcp_server, client, &data);
+ }
+ break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_PAD_WATCH:
+ gst_debugserver_process_pad_watch (self, command, client);
+ break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_ENTIRE_TOPOLOGY:
+ gst_debugserver_topology_send_entire_topology (GST_BIN_CAST (self->pipeline), self->tcp_server, client);
+ break;
+ case GST_DEBUGGER__COMMAND__COMMAND_TYPE_PROPERTY:
+ gst_debugserver_process_property_request (self, client, command->property);
+ break;
+ }
+}
+
static gboolean
plugin_init (GstPlugin * plugin)
{
diff --git a/src/debugserver/gstdebugserver.h b/src/debugserver/gstdebugserver.h
index 5296457..fc35572 100644
--- a/src/debugserver/gstdebugserver.h
+++ b/src/debugserver/gstdebugserver.h
@@ -24,9 +24,8 @@
#define __GST_DEBUGSERVER_TRACER_H__
#include "gstdebugservertcp.h"
-#include "gstdebugservermessage.h"
#include "gstdebugserverlog.h"
-#include "gstdebugserverbuffer.h"
+#include "gstdebugservermessage.h"
#include "gstdebugserverqe.h"
#include <gst/gst.h>
@@ -60,14 +59,13 @@ struct _GstDebugserverTracer {
GstTracer parent;
/*< private >*/
+ GstPipeline *pipeline;
gint port;
- GstPipeline * pipeline;
- GstDebugserverTcp * tcp_server;
- GstDebugserverMessage * msg_handler;
- GstDebugserverLog * log_handler;
- GstDebugserverQE * event_handler;
- GstDebugserverQE * query_handler;
- GstDebugserverBuffer * buffer_handler;
+ GstDebugserverTcp *tcp_server;
+ GstDebugserverLog *log;
+ GstDebugserverMessage *message;
+ GstDebugserverQE *event;
+ GstDebugserverQE *query;
};
struct _GstDebugserverTracerClass {
diff --git a/src/debugserver/gstdebugserverlog.c b/src/debugserver/gstdebugserverlog.c
index 13a5a9f..9d33fe9 100644
--- a/src/debugserver/gstdebugserverlog.c
+++ b/src/debugserver/gstdebugserverlog.c
@@ -22,64 +22,122 @@
#include <string.h>
+typedef struct {
+ GstDebugLevel level;
+ gchar * category;
+} DebugWatch;
+
+static DebugWatch * debug_watch_new (GstDebugLevel level, const gchar * category)
+{
+ DebugWatch * watch = (DebugWatch *) g_malloc (sizeof (DebugWatch));
+
+ watch->level = level;
+ watch->category = g_strdup (category);
+
+ return watch;
+}
+
+static void debug_watch_free (DebugWatch * watch)
+{
+ g_free (watch->category);
+ g_free (watch);
+}
+
+static void debug_watch_list_free (gpointer ptr)
+{
+ g_slist_free_full (ptr, (GDestroyNotify) debug_watch_free);
+}
+
+static gint debug_watch_compare (gconstpointer p1, gconstpointer p2)
+{
+ const DebugWatch *w1 = p1, *w2 = p2;
+
+ if (w1->level >= w2->level && (w1->category == NULL ||
+ g_strcmp0 (w1->category, w2->category) == 0)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static gboolean gst_debugserver_log_ok (GstDebugger__GStreamerData* original, gpointer new_ptr)
+{
+ GstDebugger__LogInfo* info = original->log_info;
+ GSList *list = new_ptr;
+ DebugWatch watch = { info->level, info->category };
+
+ return g_slist_find_custom (list, &watch, debug_watch_compare) != NULL;
+}
+
GstDebugserverLog * gst_debugserver_log_new (void)
{
GstDebugserverLog *log = (GstDebugserverLog*)g_malloc (sizeof(GstDebugserverLog));
- log->clients = NULL;
+ gst_debugserver_watcher_init (&log->watcher, gst_debugserver_log_ok, (GDestroyNotify)
debug_watch_list_free, debug_watch_compare);
return log;
}
void gst_debugserver_log_free (GstDebugserverLog * log)
{
- g_slist_free (log->clients);
+ gst_debugserver_log_clean (log);
+ gst_debugserver_watcher_deinit (&log->watcher);
g_free (log);
}
-void gst_debugserver_log_set_watch (GstDebugserverLog * log, gboolean enable,
- gpointer client_info)
+void gst_debugserver_log_clean (GstDebugserverLog * log)
+{
+ gst_debugserver_watcher_clean (&log->watcher);
+}
+
+static gboolean gst_debugserver_log_add_watch (GstDebugserverLog * log, gint level,
+ const gchar * category, TcpClient * client)
{
- if (enable == TRUE) {
- if (g_slist_find (log->clients, client_info) == NULL) {
- log->clients = g_slist_append (log->clients, client_info);
- }
+ DebugWatch *w = debug_watch_new (level, category);
+ if (gst_debugserver_watcher_add_watch (&log->watcher, w, client) == TRUE) {
+ return TRUE;
} else {
- log->clients = g_slist_remove (log->clients, client_info);
+ debug_watch_free (w);
+ return FALSE;
}
}
-GSList* gst_debugserver_log_get_clients (GstDebugserverLog * log)
+static gboolean gst_debugserver_log_remove_watch (GstDebugserverLog * log,
+ gint level, const gchar * category, TcpClient * client)
{
- return log->clients;
+ DebugWatch w = { level, (gchar*)category };
+
+ return gst_debugserver_watcher_remove_watch (&log->watcher, &w, client);
}
-gint gst_debugserver_log_prepare_buffer (GstDebugCategory * category,
- GstDebugLevel level, const gchar * file, const gchar * function, gint line,
- GObject * object, GstDebugMessage * message, gchar * buffer, gint max_size)
+gboolean gst_debugserver_log_set_watch (GstDebugserverLog * log, gboolean enable,
+ gint level, const gchar * category, TcpClient * client)
{
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- GstreamerLog log = GSTREAMER_LOG__INIT;
- gint size;
+ if (enable) {
+ return gst_debugserver_log_add_watch (log, level, category, client);
+ } else {
+ return gst_debugserver_log_remove_watch (log, level, category, client);
+ }
+}
- log.level = (gint)level;
- log.category_name = (gchar*) gst_debug_category_get_name (category);
- log.file = (gchar*) file;
- log.function = (gchar*) function;
- log.line = line;
- log.object_path = "todo";
- log.message = (gchar*) gst_debug_message_get (message);
- info.info_type = GSTREAMER_INFO__INFO_TYPE__LOG;
- info.log = &log;
- size = gstreamer_info__get_packed_size (&info);
+void gst_debugserver_log_send_log (GstDebugserverLog * log, GstDebugserverTcp * tcp_server,
+ GstDebugCategory * category, GstDebugLevel level, const gchar * file, const gchar * function,
+ gint line, GObject * object, GstDebugMessage * message)
+{
+ GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__LogInfo log_info = GST_DEBUGGER__LOG_INFO__INIT;
- if (max_size < size) {
- goto finalize;
- }
+ log_info.level = (gint)level;
+ log_info.category = (gchar*) gst_debug_category_get_name (category);
+ log_info.file = (gchar*) file;
+ log_info.function = (gchar*) function;
+ log_info.line = line;
+ log_info.object = "todo";
+ log_info.message = (gchar*) gst_debug_message_get (message);
- gstreamer_info__pack (&info, (guint8*)buffer);
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_LOG_INFO;
+ gst_data.log_info = &log_info;
-finalize:
- return size;
+ gst_debugserver_watcher_send_data (&log->watcher, tcp_server, &gst_data);
}
static gint
@@ -89,41 +147,43 @@ sort_by_category_name (gconstpointer a, gconstpointer b)
gst_debug_category_get_name ((GstDebugCategory *) b));
}
-gint gst_debugserver_log_prepare_categories_buffer (gchar * buffer, gint max_size)
+void gst_debugserver_log_send_debug_categories (GstDebugserverTcp *tcp_server, TcpClient *client)
{
+ GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__DebugCategories debug_categories = GST_DEBUGGER__DEBUG_CATEGORIES__INIT;
+ gint categories_count, i = 0;
+
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_DEBUG_CATEGORIES;
+
GSList *tmp, *all_categories = gst_debug_get_all_categories ();
- GString *categories = g_string_new (NULL);
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- DebugCategoryList category_list = DEBUG_CATEGORY_LIST__INIT;
- gint size;
tmp = all_categories = g_slist_sort (all_categories, sort_by_category_name);
+ categories_count = g_slist_length (all_categories);
+
+ debug_categories.n_category = categories_count;
+ debug_categories.category = (char **) g_malloc (sizeof (char*) * categories_count);
while (tmp) {
GstDebugCategory *cat = (GstDebugCategory *) tmp->data;
- g_string_append (categories, gst_debug_category_get_name (cat));
- g_string_append_c (categories, ';');
+ debug_categories.category[i++] = (char *) gst_debug_category_get_name (cat);
tmp = g_slist_next (tmp);
}
+ g_slist_free (all_categories);
- category_list.list = g_string_free (categories, FALSE);
- info.info_type = GSTREAMER_INFO__INFO_TYPE__DEBUG_CATEGORIES;
- info.debug_categories = &category_list;
- size = gstreamer_info__get_packed_size (&info);
- if (size > max_size) {
- goto finalize;
- }
- gstreamer_info__pack (&info, (guint8*)buffer);
+ gst_data.debug_categories = &debug_categories;
-finalize:
- g_slist_free (all_categories);
+ gst_debugserver_tcp_send_packet (tcp_server, client, &gst_data);
- return size;
+ g_free (debug_categories.category);
+}
+void gst_debugserver_log_set_threshold (const gchar * threshold)
+{
+ gst_debug_set_threshold_from_string (threshold, TRUE);
}
-void gst_debugserver_log_clean (GstDebugserverLog * log)
+void gst_debugserver_log_remove_client (GstDebugserverLog * log,
+ TcpClient * client)
{
- g_slist_free (log->clients);
- log->clients = NULL;
+ g_hash_table_remove (log->watcher.clients, client);
}
diff --git a/src/debugserver/gstdebugserverlog.h b/src/debugserver/gstdebugserverlog.h
index a7f5fe7..1b4cbef 100644
--- a/src/debugserver/gstdebugserverlog.h
+++ b/src/debugserver/gstdebugserverlog.h
@@ -20,34 +20,38 @@
#ifndef __GST_DEBUGSERVER_LOG_H__
#define __GST_DEBUGSERVER_LOG_H__
+#include "gstdebugserverwatcher.h"
+
#include <gst/gst.h>
-#include <glib.h>
G_BEGIN_DECLS
typedef struct _GstDebugserverLog GstDebugserverLog;
struct _GstDebugserverLog {
- GSList *clients;
+ GstDebugserverWatcher watcher;
};
GstDebugserverLog * gst_debugserver_log_new (void);
void gst_debugserver_log_free (GstDebugserverLog * log);
-gint gst_debugserver_log_prepare_buffer (GstDebugCategory * category,
- GstDebugLevel level, const gchar * file, const gchar * function, gint line,
- GObject * object, GstDebugMessage * message, gchar * buffer, gint max_size);
+void gst_debugserver_log_send_log (GstDebugserverLog * log, GstDebugserverTcp * tcp_server,
+ GstDebugCategory * category, GstDebugLevel level, const gchar * file, const gchar * function,
+ gint line, GObject * object, GstDebugMessage * message);
-GSList* gst_debugserver_log_get_clients (GstDebugserverLog * log);
+gboolean gst_debugserver_log_set_watch (GstDebugserverLog * log, gboolean enable, gint level,
+ const gchar * category, TcpClient * client);
-void gst_debugserver_log_set_watch (GstDebugserverLog * log, gboolean enable,
- gpointer client_info);
+void gst_debugserver_log_send_debug_categories (GstDebugserverTcp *tcp_server, TcpClient *client);
-gint gst_debugserver_log_prepare_categories_buffer (gchar * buffer, gint max_size);
+void gst_debugserver_log_set_threshold (const gchar * threshold);
void gst_debugserver_log_clean (GstDebugserverLog * log);
+void gst_debugserver_log_remove_client (GstDebugserverLog * log,
+ TcpClient * client);
+
G_END_DECLS
#endif /* __GST_DEBUGSERVER_LOG_H__ */
diff --git a/src/debugserver/gstdebugservermessage.c b/src/debugserver/gstdebugservermessage.c
index 77cc4a4..007d3f5 100644
--- a/src/debugserver/gstdebugservermessage.c
+++ b/src/debugserver/gstdebugservermessage.c
@@ -19,116 +19,84 @@
#include "gstdebugservermessage.h"
+#include <string.h>
#include <assert.h>
-GstDebugserverMessage * gst_debugserver_message_new (void)
+static gint g_int_cmp (gconstpointer v1, gconstpointer v2)
{
- GstDebugserverMessage *msg = (GstDebugserverMessage*)g_malloc (sizeof(GstDebugserverMessage));
- msg->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
- (GDestroyNotify) g_slist_free);
-
- return msg;
-}
-
-void gst_debugserver_message_free (GstDebugserverMessage * msg)
-{
- g_hash_table_unref (msg->clients);
- g_free (msg);
+ return GPOINTER_TO_INT (v1) != GPOINTER_TO_INT (v2);
}
-gboolean gst_debugserver_message_add_watch (GstDebugserverMessage * msg,
- GstMessageType msg_type, gpointer client_info)
+static gboolean gst_debugserver_message_ok (GstDebugger__GStreamerData* original, gpointer new_ptr)
{
- GSList *listeners =
- (GSList *) g_hash_table_lookup (msg->clients, GINT_TO_POINTER (msg_type));
+ GSList *list = new_ptr;
+ GstDebugger__MessageInfo *msg = original->message_info;
- if (listeners == NULL) {
- listeners = g_slist_append (listeners, client_info);
- g_hash_table_insert (msg->clients, GINT_TO_POINTER (msg_type), listeners);
- return TRUE;
+ while (list) {
+ if (msg->type == GPOINTER_TO_INT (list->data) || GPOINTER_TO_INT (list->data) == GST_MESSAGE_ANY) {
+ return TRUE;
+ }
+ list = g_slist_next (list);
}
- if (g_slist_find (listeners, client_info) == NULL) {
- listeners = g_slist_append (listeners, client_info);
- g_hash_table_replace (msg->clients, GINT_TO_POINTER (msg_type),
- listeners);
- return TRUE;
- } else {
- return FALSE;
- }
+ return FALSE;
}
-gboolean gst_debugserver_message_remove_watch (GstDebugserverMessage * msg,
- GstMessageType msg_type, gpointer client_info)
+GstDebugserverMessage * gst_debugserver_message_new (void)
{
- GSList *listeners =
- (GSList *) g_hash_table_lookup (msg->clients, GINT_TO_POINTER (msg_type));
+ GstDebugserverMessage *msg = (GstDebugserverMessage*)g_malloc (sizeof(GstDebugserverMessage));
- if (g_slist_find (listeners, client_info) == NULL) {
- return FALSE;
- } else {
- listeners = g_slist_remove (listeners, client_info);
- g_hash_table_replace (msg->clients, GINT_TO_POINTER (msg_type), listeners);
- return TRUE;
- }
+ gst_debugserver_watcher_init (&msg->watcher, gst_debugserver_message_ok, (GDestroyNotify) g_slist_free,
g_int_cmp);
+
+ return msg;
}
-void gst_debugserver_message_remove_client (GstDebugserverMessage * msg,
- gpointer client_info)
+void gst_debugserver_message_free (GstDebugserverMessage * msg)
{
- GList * keys = g_hash_table_get_keys (msg->clients);
-
- while (keys) {
- gst_debugserver_message_remove_watch (msg, GPOINTER_TO_INT (keys->data), client_info);
- keys = keys->next;
- }
+ gst_debugserver_log_clean (msg);
+ gst_debugserver_watcher_deinit (&msg->watcher);
+ g_free (msg);
}
-GSList* gst_debugserver_message_get_clients (GstDebugserverMessage * msg,
- GstMessageType msg_type)
+void gst_debugserver_message_clean (GstDebugserverMessage * msg)
{
- GSList *base = (GSList *) g_hash_table_lookup (msg->clients, GINT_TO_POINTER (msg_type));
- GSList *clients = g_slist_copy (base);
- base = (GSList *) g_hash_table_lookup (msg->clients, GINT_TO_POINTER(GST_MESSAGE_ANY));
-
- for (; base != NULL; base = g_slist_next (base)) {
- if (g_slist_find (clients, base->data) == NULL) {
- clients = g_slist_append(clients, base->data);
- }
- }
-
- return clients;
+ gst_debugserver_watcher_clean (&msg->watcher);
}
gboolean gst_debugserver_message_set_watch (GstDebugserverMessage * msg,
- gboolean enable, GstMessageType msg_type, gpointer client_info)
+ TcpClient * client, GstDebugger__MessageRequest * request)
{
- if (enable) {
- return gst_debugserver_message_add_watch (msg, msg_type, client_info);
+ if (request->action == GST_DEBUGGER__ACTION__ADD) {
+ return gst_debugserver_watcher_add_watch (&msg->watcher, GINT_TO_POINTER (request->type), client);
} else {
- return gst_debugserver_message_remove_watch (msg, msg_type, client_info);
+ return gst_debugserver_watcher_remove_watch (&msg->watcher, GINT_TO_POINTER (request->type), client);
}
}
-gint gst_debugserver_message_prepare_confirmation_buffer (MessageWatch *watch,
- gchar * buffer, gint max_size)
+void gst_debugserver_message_remove_client (GstDebugserverMessage * msg,
+ TcpClient * client)
{
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- gint size;
- MessageWatch msg_watch = MESSAGE_WATCH__INIT;
-
- info.info_type = GSTREAMER_INFO__INFO_TYPE__MESSAGE_CONFIRMATION;
- msg_watch.message_type = watch->message_type;
- msg_watch.toggle = watch->toggle;
- info.bus_msg_confirmation = &msg_watch;
- size = gstreamer_info__get_packed_size (&info);
- assert(size <= max_size);
- gstreamer_info__pack (&info, (guint8*)buffer);
-
- return size;
+ g_hash_table_remove (msg->watcher.clients, client);
}
-void gst_debugserver_message_clean (GstDebugserverMessage * msg)
+
+void gst_debugserver_message_send_message (GstDebugserverMessage * msg, GstDebugserverTcp * tcp_server,
+ GstMessage * gst_msg)
{
- g_hash_table_remove_all (msg->clients);
+ GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__MessageInfo msg_info = GST_DEBUGGER__MESSAGE_INFO__INIT;
+ gchar *structure_data = gst_structure_to_string (gst_message_get_structure (gst_msg));
+
+ msg_info.seqnum = gst_msg->seqnum;
+ msg_info.timestamp = gst_msg->timestamp;
+ msg_info.type = gst_msg->type;
+ msg_info.structure_data.data = structure_data;
+ msg_info.structure_data.len = strlen (structure_data);
+
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_MESSAGE_INFO;
+ gst_data.message_info = &msg_info;
+
+ gst_debugserver_watcher_send_data (&msg->watcher, tcp_server, &gst_data);
+
+ g_free (structure_data);
}
diff --git a/src/debugserver/gstdebugservermessage.h b/src/debugserver/gstdebugservermessage.h
index 5a560fe..ae866fa 100644
--- a/src/debugserver/gstdebugservermessage.h
+++ b/src/debugserver/gstdebugservermessage.h
@@ -20,7 +20,8 @@
#ifndef __GST_DEBUGSERVER_MESSAGE_H__
#define __GST_DEBUGSERVER_MESSAGE_H__
-#include "common/gstdebugger.pb-c.h"
+#include "gstdebugservertcp.h"
+#include "gstdebugserverwatcher.h"
#include <gst/gst.h>
#include <glib.h>
@@ -29,35 +30,34 @@ G_BEGIN_DECLS
typedef struct _GstDebugserverMessage GstDebugserverMessage;
-struct _GstDebugserverMessage {
+typedef struct {
GHashTable *clients;
+
+ gboolean (*accept_client) (gpointer);
+ void (*serialize_data) (GstDebugger__GStreamerData*);
+ void (*free_data) (GstDebugger__GStreamerData*);
+ void (*compare) (gpointer, gpointer);
+} Watcher;
+
+
+struct _GstDebugserverMessage {
+ GstDebugserverWatcher watcher;
};
GstDebugserverMessage * gst_debugserver_message_new (void);
-void gst_debugserver_message_free (GstDebugserverMessage * msg);
-gboolean gst_debugserver_message_add_watch (GstDebugserverMessage * msg,
- GstMessageType msg_type, gpointer client_info);
+void gst_debugserver_message_free (GstDebugserverMessage * msg);
-gboolean gst_debugserver_message_remove_watch (GstDebugserverMessage * msg,
- GstMessageType msg_type, gpointer client_info);
+void gst_debugserver_message_clean (GstDebugserverMessage * msg);
gboolean gst_debugserver_message_set_watch (GstDebugserverMessage * msg,
- gboolean enable, GstMessageType msg_type, gpointer client_info);
+ TcpClient * client, GstDebugger__MessageRequest * request);
void gst_debugserver_message_remove_client (GstDebugserverMessage * msg,
- gpointer client_info);
-
-GSList* gst_debugserver_message_get_clients (GstDebugserverMessage * msg,
- GstMessageType msg_type);
+ TcpClient * client);
-gint gst_debugserver_message_prepare_buffer (GstMessage * gst_msg,
- gchar * buffer, gint max_size);
-
-gint gst_debugserver_message_prepare_confirmation_buffer (MessageWatch *msg_watch,
- gchar * buffer, gint max_size);
-
-void gst_debugserver_message_clean (GstDebugserverMessage * msg);
+void gst_debugserver_message_send_message (GstDebugserverMessage * msg,
+ GstDebugserverTcp * tcp_server, GstMessage * gst_msg);
G_END_DECLS
diff --git a/src/debugserver/gstdebugserverqe.c b/src/debugserver/gstdebugserverqe.c
index 8023cc6..0a82727 100644
--- a/src/debugserver/gstdebugserverqe.c
+++ b/src/debugserver/gstdebugserverqe.c
@@ -21,199 +21,147 @@
#include "common/serializer.h"
#include "common/gstdebugger.pb-c.h"
-
-#include "common/buffer-prepare-utils.h"
+#include "common/gst-utils.h"
#include <string.h>
-GstDebugserverQE * gst_debugserver_qe_new (void)
+typedef struct _QEWatch {
+ gint qe_type;
+ GstPad * pad;
+ gchar * pad_path;
+} QEWatch;
+
+static QEWatch * qe_watch_new (gint type, GstPad * pad, gchar * pad_path)
{
- GstDebugserverQE *qe = (GstDebugserverQE*)g_malloc (sizeof(GstDebugserverQE));
- qe->watches = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
+ QEWatch * watch = (QEWatch *) g_malloc (sizeof (QEWatch));
- return qe;
-}
+ watch->qe_type = type;
+ watch->pad = pad;
+ watch->pad_path = g_strdup (pad_path);
-static void gst_debugserver_qe_clean_client (gpointer key, gpointer value,
- gpointer user_data)
-{
- g_slist_free_full (value, g_free);
+ return watch;
}
-void gst_debugserver_qe_free (GstDebugserverQE * qe)
+static void qe_watch_free (QEWatch * watch)
{
- g_hash_table_foreach (qe->watches, gst_debugserver_qe_clean_client, NULL);
- g_hash_table_destroy (qe->watches);
- g_free (qe);
+ g_free (watch->pad_path);
+ g_free (watch);
}
-gint gst_debugserver_qeb_prepare_confirmation_buffer (gchar * pad_path, gint qe_type,
- gboolean toggle, gchar * buffer, gint max_size, PadWatch__WatchType type)
+static void qe_watch_list_free (gpointer ptr)
{
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- PadWatch pad_watch = PAD_WATCH__INIT;
- gint size;
- pad_watch.pad_path = pad_path;
- pad_watch.toggle = toggle;
- pad_watch.watch_type = type;
- pad_watch.has_qe_type = 1;
- pad_watch.qe_type = qe_type;
- info.confirmation = &pad_watch;
- info.info_type = GSTREAMER_INFO__INFO_TYPE__PAD_WATCH_CONFIRMATION;
-
- size = gstreamer_info__get_packed_size (&info);
- assert(size <= max_size);
- gstreamer_info__pack (&info, (guint8*)buffer);
- return size;
+ g_slist_free_full (ptr, (GDestroyNotify) qe_watch_free);
}
-// todo improve performance (when size > max_size)
-gint gst_debugserver_qebm_prepare_buffer (GstMiniObject * miniobj, gchar *pad_path, gchar * buffer, gint
max_size)
+static gint qe_watch_compare (gconstpointer a, gconstpointer b)
{
- gint size;
- SAFE_PREPARE_BUFFER_INIT (1024);
-
- GstreamerInfo__InfoType info_type;
- if (GST_IS_QUERY (miniobj)) {
- SAFE_PREPARE_BUFFER (
- gst_query_serialize (GST_QUERY (miniobj), m_buff, max_m_buff_size), size);
- info_type = GSTREAMER_INFO__INFO_TYPE__QUERY;
- } else if (GST_IS_EVENT (miniobj)) {
- SAFE_PREPARE_BUFFER (
- gst_event_serialize (GST_EVENT (miniobj), m_buff, max_m_buff_size), size);
- info_type = GSTREAMER_INFO__INFO_TYPE__EVENT;
- } else if (GST_IS_MESSAGE (miniobj)) {
- SAFE_PREPARE_BUFFER (
- gst_message_serialize (GST_MESSAGE (miniobj), m_buff, max_m_buff_size), size);
- info_type = GSTREAMER_INFO__INFO_TYPE__MESSAGE;
- } else if (GST_IS_BUFFER (miniobj)) {
- SAFE_PREPARE_BUFFER (
- gst_buffer_serialize (GST_BUFFER (miniobj), m_buff, max_m_buff_size), size);
- info_type = GSTREAMER_INFO__INFO_TYPE__BUFFER;
- }
+ QEWatch *a1 = (QEWatch*) a;
+ QEWatch *b1 = (QEWatch*) b;
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- GstreamerQEBM evt = GSTREAMER_QEBM__INIT;
- evt.payload.len = size;
- evt.pad_path = pad_path;
- evt.payload.data = (uint8_t*) m_buff;
- info.info_type = info_type;
- info.qebm = &evt;
- size = gstreamer_info__get_packed_size (&info);
-
- if (size > max_size) {
- goto finalize;
+ if (a1->qe_type == b1->qe_type && (g_strcmp0 (a1->pad_path, b1->pad_path) == 0 || a1->pad == NULL)) {
+ return 0;
+ } else {
+ return 1;
}
-
- gstreamer_info__pack (&info, (guint8*)buffer);
-
-finalize:
- SAFE_PREPARE_BUFFER_CLEAN;
- return size;
}
-static void gst_debugserver_qe_append_client (gpointer key, gpointer value,
- gpointer user_data)
+static gboolean gst_debugserver_qe_ok (GstDebugger__GStreamerData* original, gpointer new_ptr)
{
- GArray *tmp = (GArray *) user_data;
- GSList **clients = g_array_index (tmp, GSList**, 0);
- gint type = *g_array_index (tmp, gint*, 1);
- GstPad *pad = g_array_index (tmp, GstPad*, 2);
- GSList * watches = (GSList*) value;
- QEWatch *watch;
- gboolean pad_ok, type_ok;
-
- while (watches != NULL) {
- watch = (QEWatch*)watches->data;
- pad_ok = watch->pad == NULL || watch->pad == pad;
- type_ok = watch->qe_type == -1 || type == watch->qe_type;
-
- if (pad_ok && type_ok) {
- *clients = g_slist_append (*clients, key);
- break;
- }
- watches = watches->next;
+ GSList *list = new_ptr;
+ QEWatch watch;
+
+ watch.pad = NULL;
+
+ if (original->event_info != NULL) {
+ watch.qe_type = original->event_info->type;
+ watch.pad_path = original->event_info->pad;
+ } else {
+ watch.qe_type = original->query_info->type;
+ watch.pad_path = original->query_info->pad;
}
+
+ return g_slist_find_custom (list, &watch, qe_watch_compare) != NULL;
}
-GSList* gst_debugserver_qe_get_clients (GstDebugserverQE * evt, GstPad * pad,
- gint type)
+GstDebugserverQE * gst_debugserver_qe_new (void)
{
- GSList * clients = NULL;
- GSList ** ptr_clients = &clients;
- GArray *tmp = g_array_new (FALSE, FALSE, sizeof (gpointer));
- gpointer type_ptr = &type;
-
- g_array_insert_val (tmp, 0, ptr_clients);
- g_array_insert_val (tmp, 1, type_ptr);
- g_array_insert_val (tmp, 2, pad);
-
- g_hash_table_foreach (evt->watches, gst_debugserver_qe_append_client, tmp);
- g_array_unref (tmp);
+ GstDebugserverQE *qe = (GstDebugserverQE*)g_malloc (sizeof(GstDebugserverQE));
+ gst_debugserver_watcher_init (&qe->watcher, gst_debugserver_qe_ok, (GDestroyNotify) qe_watch_list_free,
qe_watch_compare);
- return clients;
+ return qe;
}
-static gint qe_watch_compare (gconstpointer a, gconstpointer b)
+void gst_debugserver_qe_free (GstDebugserverQE * qe)
{
- QEWatch *a1 = (QEWatch*) a;
- QEWatch *b1 = (QEWatch*) b;
+ gst_debugserver_qe_clean (qe);
+ gst_debugserver_watcher_deinit (&qe->watcher);
+ g_free (qe);
+}
- if (a1->qe_type == b1->qe_type && a1->pad == b1->pad) {
- return 0;
+static gboolean gst_debugserver_qe_add_watch (GstDebugserverQE * qe, gint type,
+ GstPad * pad, gchar * pad_path, TcpClient * client)
+{
+ QEWatch *w = qe_watch_new (type, pad, pad_path);
+ if (gst_debugserver_watcher_add_watch (&qe->watcher, w, client) == TRUE) {
+ return TRUE;
} else {
- return 1;
+ qe_watch_free (w);
+ return FALSE;
}
}
-gboolean gst_debugserver_qe_set_watch (GstDebugserverQE * evt, gboolean enable,
- GstPad * pad, gint type, gpointer client_info)
+static gboolean gst_debugserver_qe_remove_watch (GstDebugserverQE * qe,
+ gint type, GstPad * pad, gchar * pad_path, TcpClient * client)
{
- if (enable == TRUE) {
- QEWatch *watch = g_malloc (sizeof (QEWatch));
- watch->qe_type = type;
- watch->pad = pad;
- GSList *watches = g_hash_table_lookup (evt->watches, client_info);
- if (watches == NULL) {
- watches = g_slist_append (watches, watch);
- g_hash_table_insert (evt->watches, client_info, watches);
- return TRUE;
- } else if (g_slist_find_custom (watches, watch, qe_watch_compare) != NULL) {
- return FALSE;
- }
-
- watches = g_slist_append (watches, watch);
- g_hash_table_replace (evt->watches, client_info, watches);
- return TRUE;
+ QEWatch w = { type, pad, pad_path };
+
+ return gst_debugserver_watcher_remove_watch (&qe->watcher, &w, client);
+}
+
+gboolean gst_debugserver_qe_set_watch (GstDebugserverQE * qe, gboolean enable,
+ gint type, GstPad * pad, gchar * pad_path, TcpClient * client)
+{
+ if (enable) {
+ return gst_debugserver_qe_add_watch (qe, type, pad, pad_path, client);
} else {
- GSList *list = g_hash_table_lookup (evt->watches, client_info);
- if (list == NULL) {
- return FALSE;
- }
- QEWatch w; w.pad = pad; w.qe_type = type;
- GSList *link = g_slist_find_custom (list, &w, qe_watch_compare);
- if (link == NULL) {
- return FALSE;
- }
- g_free (link->data);
- list = g_slist_delete_link (list, link);
- g_hash_table_replace (evt->watches, client_info, list);
- return TRUE;
+ return gst_debugserver_qe_remove_watch (qe, type, pad, pad_path, client);
}
}
-void gst_debugserver_qe_remove_client (GstDebugserverQE * evt, gpointer client_info)
+void gst_debugserver_qe_send_qe (GstDebugserverQE * qe, GstDebugserverTcp * tcp_server, GstPad * pad,
GstMiniObject * obj)
{
- GSList *list = g_hash_table_lookup (evt->watches, client_info);
- if (list == NULL) {
- return;
+ GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__EventInfo event_info = GST_DEBUGGER__EVENT_INFO__INIT;
+ GstDebugger__QueryInfo query_info = GST_DEBUGGER__QUERY_INFO__INIT;
+ gchar *pad_path = gst_utils_get_object_path (GST_OBJECT_CAST (pad));
+
+ if (GST_IS_EVENT (obj)) {
+ GstEvent *event = GST_EVENT_CAST (obj);
+ event_info.type = event->type;
+ event_info.seqnum = event->seqnum;
+ event_info.timestamp = event->timestamp;
+ event_info.pad = pad_path;
+ gst_data.event_info = &event_info;
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_EVENT_INFO;
+ } else if (GST_IS_QUERY (obj)) {
+ GstQuery *query = GST_QUERY_CAST (obj);
+ query_info.type = query->type;
+ query_info.pad = pad_path;
+ gst_data.query_info = &query_info;
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_QUERY_INFO;
}
- g_slist_free_full (list, g_free);
- g_hash_table_remove (evt->watches, client_info);
+ gst_debugserver_watcher_send_data (&qe->watcher, tcp_server, &gst_data);
+
+ g_free (pad_path);
}
void gst_debugserver_qe_clean (GstDebugserverQE * qe)
{
- g_hash_table_remove_all (qe->watches);
+ gst_debugserver_watcher_clean (&qe->watcher);
+}
+
+void gst_debugserver_qe_remove_client (GstDebugserverQE * qe, TcpClient * client)
+{
+ g_hash_table_remove (qe->watcher.clients, client);
}
diff --git a/src/debugserver/gstdebugserverqe.h b/src/debugserver/gstdebugserverqe.h
index 5cb9462..8a37c3d 100644
--- a/src/debugserver/gstdebugserverqe.h
+++ b/src/debugserver/gstdebugserverqe.h
@@ -20,43 +20,30 @@
#ifndef __GST_DEBUGSERVER_EVENT_H__
#define __GST_DEBUGSERVER_EVENT_H__
-#include "common/gstdebugger.pb-c.h"
+#include "gstdebugserverwatcher.h"
#include <gst/gst.h>
-#include <glib.h>
G_BEGIN_DECLS
typedef struct _GstDebugserverQE GstDebugserverQE;
-typedef struct _QEWatch {
- gint qe_type;
- GstPad * pad;
-} QEWatch;
-
struct _GstDebugserverQE {
- GHashTable * watches;
+ GstDebugserverWatcher watcher;
};
GstDebugserverQE * gst_debugserver_qe_new (void);
void gst_debugserver_qe_free (GstDebugserverQE * qe);
-gint gst_debugserver_qeb_prepare_confirmation_buffer (gchar * pad_path, gint qe_type,
- gboolean toggle, gchar * buffer, gint max_size, PadWatch__WatchType type);
-
gboolean gst_debugserver_qe_set_watch (GstDebugserverQE * qe, gboolean enable,
- GstPad * pad, gint qe_type, gpointer client_info);
-
-GSList* gst_debugserver_qe_get_clients (GstDebugserverQE * qe, GstPad * pad,
- gint type);
+ gint qe_type, GstPad * pad, gchar * pad_path, TcpClient * client);
-gint gst_debugserver_qebm_prepare_buffer (GstMiniObject * miniobj, gchar *pad_path,
- gchar * buffer, gint max_size);
+void gst_debugserver_qe_send_qe (GstDebugserverQE * qe, GstDebugserverTcp * tcp_server, GstPad * pad,
GstMiniObject * obj);
void gst_debugserver_qe_clean (GstDebugserverQE * qe);
-void gst_debugserver_qe_remove_client (GstDebugserverQE * evt, gpointer client_info);
+void gst_debugserver_qe_remove_client (GstDebugserverQE * evt, TcpClient * client);
G_END_DECLS
diff --git a/src/debugserver/gstdebugservertcp.c b/src/debugserver/gstdebugservertcp.c
index b3855f9..ed6891b 100644
--- a/src/debugserver/gstdebugservertcp.c
+++ b/src/debugserver/gstdebugservertcp.c
@@ -18,7 +18,9 @@
*/
#include "gstdebugservertcp.h"
+
#include "common/protocol_utils.h"
+#include "common/gstdebugger.pb-c.h"
#include <gst/gst.h>
#define GST_USE_UNSTABLE_API
@@ -32,9 +34,21 @@ GST_DEBUG_CATEGORY_STATIC (gst_debugserver_tcp);
G_DEFINE_TYPE_WITH_CODE (GstDebugserverTcp, gst_debugserver_tcp,
G_TYPE_OBJECT, _do_init)
-static void gst_debugserver_tcp_finalize (GObject * tcp);
+static void
+gst_debugserver_tcp_finalize (GObject * tcp);
+
+static gboolean
+gst_debugserver_tcp_incoming_callback (GSocketService * service,
+ GSocketConnection * connection, GObject * source_object, gpointer user_data);
-static TcpClient* gst_debugserver_tcp_find_client (GstDebugserverTcp * tcp, GSocketConnection * connection);
+static gpointer
+gst_debugserver_tcp_handle_client (gpointer user_data);
+
+static TcpClient*
+gst_debugserver_tcp_add_client (GstDebugserverTcp * tcp, GSocketConnection * connection);
+
+static gboolean
+gst_debugserver_tcp_send_packet_to_all_clients (GstDebugserverTcp * tcp, GstDebugger__GStreamerData *
gst_data);
static void
gst_debugserver_tcp_class_init (GstDebugserverTcpClass * klass)
@@ -46,24 +60,6 @@ gst_debugserver_tcp_class_init (GstDebugserverTcpClass * klass)
}
static void
-gst_debugserver_tcp_init (GstDebugserverTcp * self)
-{
- self->service = NULL;
- self->process_command = NULL;
- self->process_command_user_data = NULL;
- self->client_disconnected = NULL;
- self->parent = NULL;
- self->client_connected = NULL;
-}
-
-GstDebugserverTcp * gst_debugserver_tcp_new (void)
-{
- GstDebugserverTcp * tcp = g_object_new (GST_TYPE_DEBUGSERVER_TCP, NULL);
- tcp->clients = NULL;
- return tcp;
-}
-
-static void
gst_debugserver_tcp_finalize (GObject * obj)
{
GstDebugserverTcp * tcp = GST_DEBUGSERVER_TCP (obj);
@@ -71,98 +67,45 @@ gst_debugserver_tcp_finalize (GObject * obj)
g_slist_free_full (tcp->clients, g_free);
}
-static gpointer
-gst_debugserver_tcp_process_client (gpointer user_data)
+static void
+gst_debugserver_tcp_init (GstDebugserverTcp * self)
{
- GArray *tmp = (GArray *) user_data;
- GSocketConnection *connection = g_array_index (tmp, GSocketConnection *, 0);
- GstDebugserverTcp *tcp =
- g_array_index (tmp, GstDebugserverTcp*, 1);
- GInputStream *istream;
- gchar message[1024];
- Command *command;
- gint size;
-
- g_array_unref (tmp);
-
- istream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
-
- GST_DEBUG_OBJECT (tcp, "Received connection from client!\n");
-
- if (tcp->client_connected != NULL) {
- tcp->client_connected (connection, tcp->parent);
- }
-
- while ((size = gst_debugger_protocol_utils_read_header (istream, NULL)) > 0) {
- assert (size <= 1024);
- GST_DEBUG_OBJECT (tcp, "Received message of size: %d\n", size);
- gst_debugger_protocol_utils_read_requested_size (istream, size, message, NULL);
- command = command__unpack (NULL, size, (guint8*)message);
- if (command == NULL) {
- g_print ("error unpacking incoming message\n");
- continue;
- }
-
- GST_LOG_OBJECT (tcp, "Command type: %d\n", command->command_type);
-
- if (tcp->process_command)
- tcp->process_command (command, connection, tcp->process_command_user_data);
-
- command__free_unpacked (command, NULL);
- }
-
- if (tcp->client_disconnected)
- tcp->client_disconnected (connection, tcp->parent);
-
- TcpClient *c = gst_debugserver_tcp_find_client (tcp, connection);
- tcp->clients = g_slist_remove (tcp->clients, c);
- g_free (c);
-
- GST_LOG_OBJECT (tcp, "Client disconnected");
-
- return NULL;
+ self->service = NULL;
+ self->clients = NULL;
+ self->client_disconnected_handler = NULL;
+ self->command_handler = NULL;
+ self->owner = NULL;
}
-static void gst_debugserver_tcp_add_client (GstDebugserverTcp * tcp, GSocketConnection * connection)
+GstDebugserverTcp * gst_debugserver_tcp_new (void)
{
- TcpClient *client = (TcpClient*) g_malloc (sizeof (TcpClient));
- client->connection = connection;
- g_mutex_init (&client->mutex);
- tcp->clients = g_slist_append (tcp->clients, client);
-}
+ GstDebugserverTcp * tcp = g_object_new (GST_TYPE_DEBUGSERVER_TCP, NULL);
-static gboolean
-gst_debugserver_tcp_incoming_callback (GSocketService * service,
- GSocketConnection * connection, GObject * source_object, gpointer user_data)
-{
- GArray *tmp = g_array_new (FALSE, FALSE, sizeof (gpointer));
- gst_debugserver_tcp_add_client (GST_DEBUGSERVER_TCP (user_data), connection);
- g_array_insert_val (tmp, 0, connection);
- g_array_insert_val (tmp, 1, user_data);
- g_object_ref (connection);
- g_thread_new ("connection",
- (GThreadFunc) gst_debugserver_tcp_process_client, tmp);
- return TRUE;
+ return tcp;
}
-void
+gboolean
gst_debugserver_tcp_start_server (GstDebugserverTcp * tcp, guint port)
{
GError *error = NULL;
+
tcp->service = g_socket_service_new ();
g_socket_listener_add_inet_port ((GSocketListener *) tcp->service,
port, NULL, &error);
if (error != NULL) {
- GST_ERROR ("%s", error->message);
+ GST_ERROR ("Error on running server: %s", error->message);
g_error_free (error);
+ return FALSE;
}
g_signal_connect (tcp->service,
"incoming", G_CALLBACK (gst_debugserver_tcp_incoming_callback), tcp);
g_socket_service_start (tcp->service);
+
+ return TRUE;
}
void
@@ -174,7 +117,82 @@ gst_debugserver_tcp_stop_server (GstDebugserverTcp * tcp)
}
}
-TcpClient* gst_debugserver_tcp_find_client (GstDebugserverTcp * tcp, GSocketConnection * connection)
+static gboolean
+gst_debugserver_tcp_incoming_callback (GSocketService * service,
+ GSocketConnection * connection, GObject * source_object, gpointer user_data)
+{
+ GArray *user_data_array = g_array_new (FALSE, FALSE, sizeof (gpointer));
+ TcpClient *client = gst_debugserver_tcp_add_client (GST_DEBUGSERVER_TCP (user_data), connection);
+
+ g_array_insert_val (user_data_array, 0, client);
+ g_array_insert_val (user_data_array, 1, user_data);
+ g_object_ref (connection);
+ g_thread_new ("connection",
+ (GThreadFunc) gst_debugserver_tcp_handle_client, user_data_array);
+
+ return TRUE;
+}
+
+static TcpClient*
+gst_debugserver_tcp_add_client (GstDebugserverTcp * tcp, GSocketConnection * connection)
+{
+ TcpClient *client = (TcpClient*) g_malloc (sizeof (TcpClient));
+
+ g_mutex_init (&client->mutex);
+ client->connection = connection;
+ tcp->clients = g_slist_append (tcp->clients, client);
+
+ return client;
+}
+
+static gpointer
+gst_debugserver_tcp_handle_client (gpointer user_data)
+{
+ GArray *user_data_array = (GArray *) user_data;
+ TcpClient *client = g_array_index (user_data_array, TcpClient *, 0);
+ GstDebugserverTcp *self = g_array_index (user_data_array, GstDebugserverTcp*, 1);
+ GInputStream *istream;
+ gchar buffer[1024];
+ gint size;
+ GstDebugger__Command *command;
+
+ g_array_unref (user_data_array);
+
+ istream = g_io_stream_get_input_stream (G_IO_STREAM (client->connection));
+
+ GST_DEBUG_OBJECT (self, "Received connection from client!\n");
+
+ while ((size = gst_debugger_protocol_utils_read_header (istream, NULL)) > 0) {
+ assert (size <= 1024); // todo max message size in global file
+ GST_DEBUG_OBJECT (self, "Received message of size: %d\n", size);
+ gst_debugger_protocol_utils_read_requested_size (istream, size, buffer, NULL);
+ command = gst_debugger__command__unpack (NULL, size, (uint8_t*) buffer);
+ if (command == NULL) {
+ g_print ("error unpacking incoming message\n");
+ continue;
+ }
+
+ if (self->command_handler != NULL) {
+ self->command_handler (command, self->owner, client);
+ }
+
+ gst_debugger__command__free_unpacked (command, NULL);
+ }
+
+ self->clients = g_slist_remove (self->clients, client);
+
+ if (self->client_disconnected_handler)
+ self->client_disconnected_handler (client, self->owner);
+
+ g_free (client);
+
+ GST_LOG_OBJECT (self, "Client disconnected");
+
+ return NULL;
+}
+
+TcpClient*
+gst_debugserver_tcp_find_client (GstDebugserverTcp * tcp, GSocketConnection * connection)
{
GSList *client_list = tcp->clients;
TcpClient *client;
@@ -186,29 +204,59 @@ TcpClient* gst_debugserver_tcp_find_client (GstDebugserverTcp * tcp, GSocketConn
}
client_list = g_slist_next (client_list);
}
- return NULL;
+ return NULL;
}
-gboolean gst_debugserver_tcp_send_packet (GstDebugserverTcp * tcp, GSocketConnection * connection,
- gchar * buffer, gint size)
+#define SAFE_PREPARE_BUFFER_INIT(BUFFER_SIZE) \
+ gchar buff[BUFFER_SIZE]; \
+ gchar *m_buff = buff; \
+ gint max_m_buff_size = BUFFER_SIZE;
+
+#define SAFE_PREPARE_BUFFER(FUNCTION_CALL, SIZE_VAR) \
+ do { \
+ SIZE_VAR = (FUNCTION_CALL); \
+ if (SIZE_VAR > 1024) { \
+ m_buff = (gchar *) g_malloc (SIZE_VAR); \
+ max_m_buff_size = SIZE_VAR; \
+ SIZE_VAR = (FUNCTION_CALL); \
+ } \
+ } while (0)
+
+#define SAFE_PREPARE_BUFFER_CLEAN \
+ do { \
+ if (m_buff != buff) { \
+ g_free (m_buff); \
+ } \
+ } while (0)
+
+gboolean
+gst_debugserver_tcp_send_packet (GstDebugserverTcp * tcp, TcpClient * client,
+ GstDebugger__GStreamerData * gst_data)
{
GError *err = NULL;
gchar size_buffer[4];
GSocket *socket;
- TcpClient *client;
+ gchar buff[1024];
+ gchar *m_buff = buff;
+ gint size;
+
+ if (client == NULL) {
+ return gst_debugserver_tcp_send_packet_to_all_clients (tcp, gst_data);
+ }
+
+ g_mutex_lock (&client->mutex);
- if (connection == NULL) {
- return gst_debugserver_tcp_send_packet_to_all_clients (tcp, buffer, size);
+ if (!g_socket_connection_is_connected (client->connection)) {
+ return FALSE;
}
- client = gst_debugserver_tcp_find_client (tcp, connection);
- assert (client != NULL);
- socket = g_socket_connection_get_socket (connection);
+ socket = g_socket_connection_get_socket (client->connection);
+ size = gst_debugger__gstreamer_data__get_packed_size (gst_data);
gst_debugger_protocol_utils_serialize_integer64 (size, size_buffer, 4);
- g_mutex_lock (&client->mutex);
g_socket_send (socket, (gchar*)size_buffer, 4, NULL, &err);
+
if (err) {
g_mutex_unlock (&client->mutex);
g_print ("cannot send size of data: %s\n", err->message);
@@ -216,8 +264,20 @@ gboolean gst_debugserver_tcp_send_packet (GstDebugserverTcp * tcp, GSocketConnec
return FALSE;
}
- g_socket_send (socket, (gchar*)buffer, size, NULL, &err);
+ if (size > 1024) {
+ m_buff = (char*) g_malloc (size * sizeof (char));
+ }
+
+ gst_debugger__gstreamer_data__pack (gst_data, m_buff);
+
+ g_socket_send (socket, (gchar*)m_buff, size, NULL, &err);
+
+ if (m_buff != buff) {
+ g_free (m_buff);
+ }
+
g_mutex_unlock (&client->mutex);
+
if (err) {
g_print ("cannot send data: %s\n", err->message);
g_error_free (err);
@@ -227,7 +287,8 @@ gboolean gst_debugserver_tcp_send_packet (GstDebugserverTcp * tcp, GSocketConnec
return TRUE;
}
-gboolean gst_debugserver_tcp_send_packet_to_all_clients (GstDebugserverTcp * tcp, gchar * buffer, gint size)
+static gboolean
+gst_debugserver_tcp_send_packet_to_all_clients (GstDebugserverTcp * tcp, GstDebugger__GStreamerData *
gst_data)
{
GSList *clients = tcp->clients;
TcpClient *client;
@@ -235,7 +296,7 @@ gboolean gst_debugserver_tcp_send_packet_to_all_clients (GstDebugserverTcp * tcp
while (clients != NULL) {
client = (TcpClient*)clients->data;
- ret = ret && gst_debugserver_tcp_send_packet (tcp, client->connection, buffer, size);
+ ret = ret && gst_debugserver_tcp_send_packet (tcp, client, gst_data);
clients = clients->next;
}
diff --git a/src/debugserver/gstdebugservertcp.h b/src/debugserver/gstdebugservertcp.h
index 521de28..6d14c59 100644
--- a/src/debugserver/gstdebugservertcp.h
+++ b/src/debugserver/gstdebugservertcp.h
@@ -38,29 +38,26 @@ G_BEGIN_DECLS
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DEBUGSERVER_TCP))
#define GST_DEBUGSERVER_TCP_CAST(obj) ((GstDebugserverTcp *)(obj))
-typedef struct _GstDebugserverTcp GstDebugserverTcp;
-typedef struct _GstDebugserverTcpClass GstDebugserverTcpClass;
-
-typedef void (*GstDebugserverTcpProcessCommandFunction)
- (Command * command, gpointer client_id, gpointer user_data);
-
-typedef void (*GstDebugserverTcpClientChanged)
- (gpointer client_id, gpointer user_data);
-
typedef struct _TcpClient {
GSocketConnection * connection;
GMutex mutex;
} TcpClient;
+typedef void (*GstDebugserverTcpHandleCommandFunction)
+ (GstDebugger__Command * command, gpointer user_data, TcpClient * client);
+
+typedef void (*GstDebugserverTcpClientDisconnectedFunction)
+ (TcpClient * client, gpointer user_data);
+
+typedef struct _GstDebugserverTcp GstDebugserverTcp;
+typedef struct _GstDebugserverTcpClass GstDebugserverTcpClass;
+
struct _GstDebugserverTcp {
GObject parent_instance;
+ gpointer owner;
- GstDebugserverTcpProcessCommandFunction process_command;
- gpointer process_command_user_data;
-
- GstDebugserverTcpClientChanged client_disconnected;
- GstDebugserverTcpClientChanged client_connected;
- gpointer parent;
+ GstDebugserverTcpHandleCommandFunction command_handler;
+ GstDebugserverTcpClientDisconnectedFunction client_disconnected_handler;
/*< private >*/
GSocketService * service;
@@ -71,18 +68,18 @@ struct _GstDebugserverTcp {
struct _GstDebugserverTcpClass
{
GObjectClass parent_class;
+
+ void (*command_received) (gpointer *tracer, GstDebugger__Command *command);
};
GstDebugserverTcp * gst_debugserver_tcp_new (void);
-void gst_debugserver_tcp_start_server (GstDebugserverTcp * tcp, guint port);
+gboolean gst_debugserver_tcp_start_server (GstDebugserverTcp * tcp, guint port);
void gst_debugserver_tcp_stop_server (GstDebugserverTcp * tcp);
-gboolean gst_debugserver_tcp_send_packet (GstDebugserverTcp * tcp, GSocketConnection * connection,
- gchar * buffer, gint size);
-
-gboolean gst_debugserver_tcp_send_packet_to_all_clients (GstDebugserverTcp * tcp, gchar * buffer, gint size);
+gboolean gst_debugserver_tcp_send_packet (GstDebugserverTcp * tcp, TcpClient * client,
+ GstDebugger__GStreamerData * gst_data);
G_GNUC_INTERNAL GType gst_debugserver_tcp_get_type (void);
diff --git a/src/debugserver/gstdebugservertopology.c b/src/debugserver/gstdebugservertopology.c
index 119601e..c1fe0f9 100644
--- a/src/debugserver/gstdebugservertopology.c
+++ b/src/debugserver/gstdebugservertopology.c
@@ -25,10 +25,10 @@
GSList *src_pads;
-static TopologyTemplate
+static GstDebugger__PadTemplate
get_topology_template_object (GstPadTemplate *template)
{
- TopologyTemplate tpl = TOPOLOGY_TEMPLATE__INIT;
+ GstDebugger__PadTemplate tpl = GST_DEBUGGER__PAD_TEMPLATE__INIT;
tpl.caps = gst_caps_to_string (GST_PAD_TEMPLATE_CAPS (template));
tpl.direction = GST_PAD_TEMPLATE_DIRECTION (template);
@@ -39,17 +39,17 @@ get_topology_template_object (GstPadTemplate *template)
}
static void
-send_object (GstObject *object, Topology__Action action, GstDebugserverTcp * server, GSocketConnection *
client)
+send_object (GstObject *object, GstDebugger__Action action, GstDebugserverTcp * server, TcpClient * client)
{
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- Topology topology = TOPOLOGY__INIT;
+ GstDebugger__GStreamerData info = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__TopologyInfo topology = GST_DEBUGGER__TOPOLOGY_INFO__INIT;
gint size;
gchar buffer[1024];
- TopologyElement element_tp = TOPOLOGY_ELEMENT__INIT;
- TopologyPad pad_tp = TOPOLOGY_PAD__INIT;
- TopologyTemplate template = TOPOLOGY_TEMPLATE__INIT;
+ GstDebugger__TopologyElement element_tp = GST_DEBUGGER__TOPOLOGY_ELEMENT__INIT;
+ GstDebugger__TopologyPad pad_tp = GST_DEBUGGER__TOPOLOGY_PAD__INIT;
+ GstDebugger__PadTemplate template = GST_DEBUGGER__PAD_TEMPLATE__INIT;
- info.info_type = GSTREAMER_INFO__INFO_TYPE__TOPOLOGY;
+ info.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_TOPOLOGY_INFO;
topology.action = action;
if (GST_IS_ELEMENT (object)) {
@@ -58,7 +58,7 @@ send_object (GstObject *object, Topology__Action action, GstDebugserverTcp * ser
element_tp.is_bin = GST_IS_BIN (object);
element_tp.factory_name = gst_plugin_feature_get_name (gst_element_get_factory (GST_ELEMENT_CAST
(object)));
topology.element = &element_tp;
- topology.type = TOPOLOGY__OBJECT_TYPE__ELEMENT;
+ topology.topology_type_case = GST_DEBUGGER__TOPOLOGY_INFO__TOPOLOGY_TYPE_ELEMENT;
} else if (GST_IS_PAD (object)) {
GstPad *pad = GST_PAD (object);
pad_tp.path = gst_utils_get_object_path (object);
@@ -70,42 +70,39 @@ send_object (GstObject *object, Topology__Action action, GstDebugserverTcp * ser
pad_tp.template_ = &template;
}
topology.pad = &pad_tp;
- topology.type = TOPOLOGY__OBJECT_TYPE__PAD;
+ topology.topology_type_case = GST_DEBUGGER__TOPOLOGY_INFO__TOPOLOGY_TYPE_PAD;
} else {
assert (FALSE);
}
- info.topology = &topology;
- size = gstreamer_info__get_packed_size (&info);
- assert(size <= 1024);
- gstreamer_info__pack (&info, (guint8*)buffer);
+ info.topology_info = &topology;
+ gst_debugserver_tcp_send_packet (server, client, &info);
g_free (template.caps);
- gst_debugserver_tcp_send_packet (server, client, buffer, size);
}
static void
-send_link (GstPad *src_pad, GstPad *sink_pad, Topology__Action action, GstDebugserverTcp *server,
GSocketConnection * client)
+send_link (GstPad *src_pad, GstPad *sink_pad, GstDebugger__Action action, GstDebugserverTcp *server,
TcpClient * client)
{
- GstreamerInfo info = GSTREAMER_INFO__INIT;
- Topology topology = TOPOLOGY__INIT;
+ GstDebugger__GStreamerData info = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__TopologyInfo topology = GST_DEBUGGER__TOPOLOGY_INFO__INIT;
gint size;
gchar buffer[1024];
- TopologyLink link_tp = TOPOLOGY_LINK__INIT;
+ GstDebugger__TopologyLink link_tp = GST_DEBUGGER__TOPOLOGY_LINK__INIT;
if (!gst_utils_check_pad_has_element_parent (src_pad) || !gst_utils_check_pad_has_element_parent
(sink_pad)) {
return;
}
- info.info_type = GSTREAMER_INFO__INFO_TYPE__TOPOLOGY;
+ info.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_TOPOLOGY_INFO;
topology.action = action;
- topology.type = TOPOLOGY__OBJECT_TYPE__LINK;
+ topology.topology_type_case = GST_DEBUGGER__TOPOLOGY_INFO__TOPOLOGY_TYPE_LINK;
if (GST_IS_PROXY_PAD (src_pad) && !GST_IS_GHOST_PAD (src_pad)) {
return;
}
- link_tp.src_pad_path = gst_utils_get_object_path (GST_OBJECT_CAST (src_pad));
+ link_tp.src_pad = gst_utils_get_object_path (GST_OBJECT_CAST (src_pad));
if (GST_IS_PROXY_PAD (sink_pad)) {
if (GST_IS_GHOST_PAD (sink_pad)) {
GstPad *internal = gst_pad_get_peer (GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
(sink_pad))));
@@ -117,18 +114,16 @@ send_link (GstPad *src_pad, GstPad *sink_pad, Topology__Action action, GstDebugs
}
}
- link_tp.sink_pad_path = gst_utils_get_object_path (GST_OBJECT_CAST (sink_pad));
+ link_tp.sink_pad = gst_utils_get_object_path (GST_OBJECT_CAST (sink_pad));
topology.link = &link_tp;
- topology.type = TOPOLOGY__OBJECT_TYPE__LINK;
- info.topology = &topology;
- size = gstreamer_info__get_packed_size (&info);
- assert(size <= 1024);
- gstreamer_info__pack (&info, (guint8*)buffer);
- gst_debugserver_tcp_send_packet (server, client, buffer, size);
+ topology.topology_type_case = GST_DEBUGGER__TOPOLOGY_INFO__TOPOLOGY_TYPE_LINK;
+ info.topology_info = &topology;
+
+ gst_debugserver_tcp_send_packet (server, client, &info);
}
static void
-send_element_pads (GstElement * element, GstDebugserverTcp *server, GSocketConnection * client)
+send_element_pads (GstElement * element, GstDebugserverTcp *server, TcpClient * client)
{
gboolean done;
GstPad *pad;
@@ -143,7 +138,7 @@ send_element_pads (GstElement * element, GstDebugserverTcp *server, GSocketConne
if (gst_pad_get_direction (pad) == GST_PAD_SRC && gst_pad_get_peer (pad)) {
src_pads = g_slist_append (src_pads, pad);
}
- send_object (GST_OBJECT (pad), TOPOLOGY__ACTION__ADD, server, client);
+ send_object (GST_OBJECT (pad), GST_DEBUGGER__ACTION__ADD, server, client);
g_value_reset (&item);
break;
case GST_ITERATOR_RESYNC:
@@ -160,13 +155,13 @@ send_element_pads (GstElement * element, GstDebugserverTcp *server, GSocketConne
}
static void
-gst_debugserver_topology_send_element (GstElement * element, GstDebugserverTcp *server, GSocketConnection *
client)
+gst_debugserver_topology_send_element (GstElement * element, GstDebugserverTcp *server, TcpClient * client)
{
GstIterator *element_it;
gboolean done;
if (GST_ELEMENT_PARENT (element) != NULL) {
- send_object (GST_OBJECT (element), TOPOLOGY__ACTION__ADD, server, client);
+ send_object (GST_OBJECT (element), GST_DEBUGGER__ACTION__ADD, server, client);
}
send_element_pads (element, server, client);
@@ -198,36 +193,36 @@ gst_debugserver_topology_send_element (GstElement * element, GstDebugserverTcp *
gst_iterator_free (element_it);
}
-void gst_debugserver_topology_send_entire_topology (GstBin *bin, GstDebugserverTcp * server,
GSocketConnection * client)
+void gst_debugserver_topology_send_entire_topology (GstBin *bin, GstDebugserverTcp * server, TcpClient *
client)
{
src_pads = NULL;
gst_debugserver_topology_send_element (GST_ELEMENT (bin), server, client);
GSList *tmp_list = src_pads;
while (tmp_list != NULL) {
GstPad *pad = (GstPad*)tmp_list->data;
- send_link (pad, gst_pad_get_peer (pad), TOPOLOGY__ACTION__ADD, server, client);
+ send_link (pad, gst_pad_get_peer (pad), GST_DEBUGGER__ACTION__ADD, server, client);
tmp_list = tmp_list->next;
}
g_slist_free (src_pads);
}
-void gst_debugserver_topology_send_pad_link (GstPad * src, GstPad * sink, gboolean link, GstDebugserverTcp *
server, GSocketConnection * client)
+void gst_debugserver_topology_send_pad_link (GstPad * src, GstPad * sink, gboolean link, GstDebugserverTcp *
server, TcpClient * client)
{
- send_link (src, sink, link ? TOPOLOGY__ACTION__ADD : TOPOLOGY__ACTION__REMOVE, server, client);
+ send_link (src, sink, link ? GST_DEBUGGER__ACTION__ADD : GST_DEBUGGER__ACTION__REMOVE, server, client);
}
-void gst_debugserver_topology_send_element_in_bin (GstBin * bin, GstElement * element, gboolean add,
GstDebugserverTcp * server, GSocketConnection * client)
+void gst_debugserver_topology_send_element_in_bin (GstBin * bin, GstElement * element, gboolean add,
GstDebugserverTcp * server, TcpClient * client)
{
- send_object (GST_OBJECT_CAST (element), add ? TOPOLOGY__ACTION__ADD : TOPOLOGY__ACTION__REMOVE, server,
client);
+ send_object (GST_OBJECT_CAST (element), add ? GST_DEBUGGER__ACTION__ADD : GST_DEBUGGER__ACTION__REMOVE,
server, client);
}
-void gst_debugserver_topology_send_pad_in_element (GstElement * element, GstPad * pad, gboolean add,
GstDebugserverTcp * server, GSocketConnection * client)
+void gst_debugserver_topology_send_pad_in_element (GstElement * element, GstPad * pad, gboolean add,
GstDebugserverTcp * server, TcpClient * client)
{
if (GST_OBJECT_PARENT (element) == NULL) {
return;
}
- send_object (GST_OBJECT_CAST (pad), add ? TOPOLOGY__ACTION__ADD : TOPOLOGY__ACTION__REMOVE, server,
client);
+ send_object (GST_OBJECT_CAST (pad), add ? GST_DEBUGGER__ACTION__ADD : GST_DEBUGGER__ACTION__REMOVE,
server, client);
}
diff --git a/src/debugserver/gstdebugservertopology.h b/src/debugserver/gstdebugservertopology.h
index 7691c11..8f69218 100644
--- a/src/debugserver/gstdebugservertopology.h
+++ b/src/debugserver/gstdebugservertopology.h
@@ -24,12 +24,12 @@
#include <gst/gst.h>
-void gst_debugserver_topology_send_entire_topology (GstBin *root, GstDebugserverTcp * server,
GSocketConnection * client);
+void gst_debugserver_topology_send_entire_topology (GstBin *root, GstDebugserverTcp * server, TcpClient *
client);
-void gst_debugserver_topology_send_pad_link (GstPad * src, GstPad * sink, gboolean link, GstDebugserverTcp *
server, GSocketConnection * client);
+void gst_debugserver_topology_send_pad_link (GstPad * src, GstPad * sink, gboolean link, GstDebugserverTcp *
server, TcpClient * client);
-void gst_debugserver_topology_send_element_in_bin (GstBin * bin, GstElement * element, gboolean add,
GstDebugserverTcp * server, GSocketConnection * client);
+void gst_debugserver_topology_send_element_in_bin (GstBin * bin, GstElement * element, gboolean add,
GstDebugserverTcp * server, TcpClient * client);
-void gst_debugserver_topology_send_pad_in_element (GstElement * element, GstPad * pad, gboolean add,
GstDebugserverTcp * server, GSocketConnection * client);
+void gst_debugserver_topology_send_pad_in_element (GstElement * element, GstPad * pad, gboolean add,
GstDebugserverTcp * server, TcpClient * client);
#endif /* SRC_DEBUGSERVER_GSTDEBUGSERVERTOPOLOGY_H_ */
diff --git a/src/debugserver/gstdebugservertypes.c b/src/debugserver/gstdebugservertypes.c
new file mode 100644
index 0000000..7f70f98
--- /dev/null
+++ b/src/debugserver/gstdebugservertypes.c
@@ -0,0 +1,157 @@
+/* GStreamer
+ * Copyright (C) 2015 Marcin Kolny <marcin kolny gmail com>
+ *
+ * gstdebugserver.c: tracing module that sends serialized data to
+ * an user.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gstdebugservertypes.h"
+
+#include <gst/gst.h>
+
+#define SERIALIZE_ENUM_FLAGS \
+ do { \
+ n_values = klass->n_values; \
+ values = g_malloc (sizeof (GstDebugger__EnumFlagsValue*) * n_values); \
+ \
+ for (i = 0; i < klass->n_values; i++) { \
+ values[i] = (GstDebugger__EnumFlagsValue*) g_malloc (sizeof (GstDebugger__EnumFlagsValue)); \
+ gst_debugger__enum_flags_value__init (values[i]); \
+ values[i]->name = (gchar*) klass->values[i].value_name; \
+ values[i]->nick = (gchar*) klass->values[i].value_nick; \
+ values[i]->value = klass->values[i].value; \
+ } \
+ \
+ data_type.values = values; \
+ data_type.n_values = klass->n_values; \
+ data_type.type_name = (gchar*) name; \
+ gst_data.enum_flags_type = &data_type; \
+ } while (FALSE)
+
+static void gst_debugserver_types_send_enum_flags (GstDebugserverTcp *tcp_server, TcpClient *client, const
gchar * name)
+{
+ GType type = g_type_from_name (name);
+ GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__EnumFlagsType data_type = GST_DEBUGGER__ENUM_FLAGS_TYPE__INIT;
+ GstDebugger__EnumFlagsValue **values = NULL;
+ gint i = 0, n_values = 0;
+
+ if (G_TYPE_IS_ENUM (type)) {
+ GEnumClass * klass = g_type_class_peek (type);
+ SERIALIZE_ENUM_FLAGS;
+ data_type.kind = GST_DEBUGGER__ENUM_FLAGS_TYPE__ENUM_FLAGS_KIND__ENUM;
+ } else if (G_TYPE_IS_FLAGS (type)) {
+ GFlagsClass * klass = g_type_class_peek (type);
+ SERIALIZE_ENUM_FLAGS;
+ data_type.kind = GST_DEBUGGER__ENUM_FLAGS_TYPE__ENUM_FLAGS_KIND__FLAGS;
+ } else {
+ // todo
+ }
+
+ gst_data.enum_flags_type = &data_type;
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_ENUM_FLAGS_TYPE;
+
+ gst_debugserver_tcp_send_packet (tcp_server, client, &gst_data);
+
+ for (i = 0; i < n_values; i++) {
+ g_free (values[i]);
+ }
+ g_free (values);
+}
+
+static void gst_debugserver_types_send_factory (GstDebugserverTcp *tcp_server, TcpClient *client, const
gchar * name)
+{
+ GstDebugger__GStreamerData gst_data = GST_DEBUGGER__GSTREAMER_DATA__INIT;
+ GstDebugger__FactoryType factory_type = GST_DEBUGGER__FACTORY_TYPE__INIT;
+ GstDebugger__PadTemplate **templates = NULL;
+ GstElementFactory *factory = gst_element_factory_find (name);
+ GstStaticPadTemplate *static_template = NULL;
+ GList *tpls = NULL;
+ gint i = 0;
+
+ if (factory == NULL) {
+ // todo
+ return;
+ }
+
+ factory_type.name = gst_plugin_feature_get_name (factory);
+ factory_type.n_templates = gst_element_factory_get_num_pad_templates (factory);
+ if (factory_type.n_templates != 0) {
+ templates = g_malloc (factory_type.n_templates * sizeof (GstDebugger__PadTemplate*));
+ tpls = (GList*)gst_element_factory_get_static_pad_templates (factory);
+
+ while (tpls) {
+ static_template = (GstStaticPadTemplate*) tpls->data;
+ tpls = g_list_next (tpls);
+ templates[i] = g_malloc (sizeof (GstDebugger__PadTemplate));
+ gst_debugger__pad_template__init (templates[i]);
+ templates[i]->caps = (gchar*) static_template->static_caps.string;
+ templates[i]->direction = static_template->direction;
+ templates[i]->presence = static_template->presence;
+ templates[i]->name_template = (gchar*) static_template->name_template;
+ i++;
+ }
+ }
+ factory_type.templates = templates;
+
+ gchar **keys, **k;
+ gint meta_cnt = 0;
+ i = 0;
+ GstDebugger__FactoryMeta **entries = NULL;
+ keys = gst_element_factory_get_metadata_keys (factory);
+ if (keys != NULL) {
+ for (k = keys; *k != NULL; ++k) { meta_cnt++; }
+ entries = g_malloc (sizeof (GstDebugger__FactoryMeta*) * meta_cnt);
+ for (k = keys; *k != NULL; ++k) {
+ entries[i] = g_malloc (sizeof (GstDebugger__FactoryMeta));
+ gst_debugger__factory_meta__init (entries[i]);
+ entries[i]->key = *k;
+ entries[i]->value = (gchar*) gst_element_factory_get_metadata (factory, *k);
+ i++;
+ }
+ }
+ factory_type.metadata = entries;
+ factory_type.n_metadata = meta_cnt;
+
+ gst_data.factory = &factory_type;
+ gst_data.info_type_case = GST_DEBUGGER__GSTREAMER_DATA__INFO_TYPE_FACTORY;
+
+ gst_debugserver_tcp_send_packet (tcp_server, client, &gst_data);
+
+ for (i = 0; i < (gint) factory_type.n_templates; i++) {
+ g_free (templates[i]);
+ }
+ g_free (templates);
+
+ for (i = 0; i < (gint) factory_type.n_metadata; i++) {
+ g_free (entries[i]);
+ }
+ g_free (entries);
+ g_strfreev (keys);
+}
+
+void gst_debugserver_types_send_type (GstDebugserverTcp *tcp_server, TcpClient *client, const
GstDebugger__TypeDescriptionRequest *request)
+{
+ switch (request->type) {
+ case GST_DEBUGGER__TYPE_DESCRIPTION_REQUEST__TYPE__FACTORY:
+ gst_debugserver_types_send_factory (tcp_server, client, request->name);
+ break;
+ case GST_DEBUGGER__TYPE_DESCRIPTION_REQUEST__TYPE__ENUM_FLAGS:
+ gst_debugserver_types_send_enum_flags (tcp_server, client, request->name);
+ }
+}
diff --git a/src/debugserver/gstdebugserverfactory.h b/src/debugserver/gstdebugservertypes.h
similarity index 69%
rename from src/debugserver/gstdebugserverfactory.h
rename to src/debugserver/gstdebugservertypes.h
index 32429c3..2f6e35d 100644
--- a/src/debugserver/gstdebugserverfactory.h
+++ b/src/debugserver/gstdebugservertypes.h
@@ -1,6 +1,9 @@
/* GStreamer
* Copyright (C) 2015 Marcin Kolny <marcin kolny gmail com>
*
+ * gstdebugserver.c: tracing module that sends serialized data to
+ * an user.
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
@@ -17,11 +20,13 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef __GST_DEBUGSERVER_FACTORY_H__
-#define __GST_DEBUGSERVER_FACTORY_H__
+#ifndef __GST_DEBUGSERVER_ENUM_H__
+#define __GST_DEBUGSERVER_ENUM_H__
+
+#include "gstdebugservertcp.h"
-#include <gst/gst.h>
+void gst_debugserver_types_send_type (GstDebugserverTcp *tcp_server, TcpClient *client,
+ const GstDebugger__TypeDescriptionRequest *request);
-gint gst_debugserver_factory_prepare_buffer (GstElementFactory *factory, gchar * buffer, gint max_size);
-#endif /* __GST_DEBUGSERVER_FACTORY_H__ */
+#endif /* __GST_DEBUGSERVER_ENUM_H__ */
diff --git a/src/debugserver/gstdebugserverwatcher.c b/src/debugserver/gstdebugserverwatcher.c
new file mode 100644
index 0000000..1cb7d85
--- /dev/null
+++ b/src/debugserver/gstdebugserverwatcher.c
@@ -0,0 +1,95 @@
+/* GStreamer
+ * Copyright (C) 2015 Marcin Kolny <marcin kolny gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gstdebugserverwatcher.h"
+
+void gst_debugserver_watcher_init (GstDebugserverWatcher * watcher, OkFunction ok_function,
+ GDestroyNotify hash_destroy, GCompareFunc cmp_func)
+{
+ watcher->clients = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, hash_destroy);
+ g_mutex_init (&watcher->mutex);
+ watcher->ok_function = ok_function;
+ watcher->cmp_function = cmp_func;
+}
+
+void gst_debugserver_watcher_deinit (GstDebugserverWatcher * watcher)
+{
+ g_mutex_lock (&watcher->mutex);
+ g_hash_table_destroy (watcher->clients);
+ g_mutex_unlock (&watcher->mutex);
+}
+
+void gst_debugserver_watcher_clean (GstDebugserverWatcher * watcher)
+{
+ g_mutex_lock (&watcher->mutex);
+ g_hash_table_remove_all (watcher->clients);
+ g_mutex_unlock (&watcher->mutex);
+}
+
+void gst_debugserver_watcher_send_data (GstDebugserverWatcher * watcher, GstDebugserverTcp * tcp_server,
GstDebugger__GStreamerData * gst_data)
+{
+ GHashTableIter iter;
+ gpointer client, value;
+
+ g_mutex_lock (&watcher->mutex);
+ g_hash_table_iter_init (&iter, watcher->clients);
+ while (g_hash_table_iter_next (&iter, &client, &value)) {
+ if (watcher->ok_function (gst_data, value))
+ gst_debugserver_tcp_send_packet (tcp_server, (TcpClient*) client, gst_data);
+ }
+ g_mutex_unlock (&watcher->mutex);
+}
+
+gboolean gst_debugserver_watcher_add_watch (GstDebugserverWatcher * watcher, gpointer data, TcpClient *
client)
+{
+ GSList *listeners =
+ (GSList *) g_hash_table_lookup (watcher->clients, client);
+
+ if (listeners == NULL) {
+ listeners = g_slist_append (listeners, data);
+ g_hash_table_insert (watcher->clients, client, listeners);
+ return TRUE;
+ }
+
+ if (g_slist_find_custom (listeners, data, watcher->cmp_function) == NULL) {
+ listeners = g_slist_append (listeners, data);
+ g_hash_table_steal (watcher->clients, client);
+ g_hash_table_insert (watcher->clients, client, listeners);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+gboolean gst_debugserver_watcher_remove_watch (GstDebugserverWatcher * watcher,
+ gpointer data, TcpClient * client)
+{
+ GSList *listeners =
+ (GSList *) g_hash_table_lookup (watcher->clients, client);
+
+ GSList *l = g_slist_find_custom (listeners, data, watcher->cmp_function);
+ if (l == NULL) {
+ return FALSE;
+ } else {
+ listeners = g_slist_remove_link (listeners, l);
+ g_hash_table_steal (watcher->clients, client);
+ g_hash_table_insert (watcher->clients, client, listeners);
+ return TRUE;
+ }
+}
diff --git a/src/debugserver/gstdebugserverwatcher.h b/src/debugserver/gstdebugserverwatcher.h
new file mode 100644
index 0000000..445ad9d
--- /dev/null
+++ b/src/debugserver/gstdebugserverwatcher.h
@@ -0,0 +1,52 @@
+/* GStreamer
+ * Copyright (C) 2015 Marcin Kolny <marcin kolny gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_DEBUGSERVER_WATCHER_H__
+#define __GST_DEBUGSERVER_WATCHER_H__
+
+#include "gstdebugservertcp.h"
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef gboolean (*OkFunction)(GstDebugger__GStreamerData*, gpointer);
+
+typedef struct {
+ GHashTable *clients;
+ GMutex mutex;
+ OkFunction ok_function;
+ GCompareFunc cmp_function;
+} GstDebugserverWatcher;
+
+void gst_debugserver_watcher_init (GstDebugserverWatcher * watcher, OkFunction ok_function, GDestroyNotify
hash_destroy, GCompareFunc cmp_func);
+
+void gst_debugserver_watcher_deinit (GstDebugserverWatcher * watcher);
+
+void gst_debugserver_watcher_clean (GstDebugserverWatcher * watcher);
+
+gboolean gst_debugserver_watcher_add_watch (GstDebugserverWatcher * watcher,
+ gpointer data, TcpClient * client);
+
+gboolean gst_debugserver_watcher_remove_watch (GstDebugserverWatcher * watcher,
+ gpointer data, TcpClient * client);
+
+G_END_DECLS
+
+#endif
diff --git a/src/gst-debugger/Makefile.am b/src/gst-debugger/Makefile.am
index 4d361a8..b213570 100644
--- a/src/gst-debugger/Makefile.am
+++ b/src/gst-debugger/Makefile.am
@@ -14,92 +14,59 @@ BUILT_SOURCES = gst-debugger-resources.h
bin_PROGRAMS = gst-debugger- GST_API_VERSION@
-gst_debugger_headers = \
- common_model_columns.h \
- controller/base_controller.h \
- controller/command_factory.h \
- controller/connection_controller.h \
- controller/controller.h \
- controller/element_path_processor.h \
- controller/iview.h \
- controller/tcp_client.h \
- controller/topology_controller.h \
- dialogs/buffer_data_dialog.h \
- dialogs/connection_properties_dialog.h \
- dialogs/enums_dialog.h \
- dialogs/factories_dialog.h \
- dialogs/remote_data_dialog.h \
- filter-parser/expression.h \
- filter-parser/lexer.h \
- filter-parser/parser.h \
- filter-parser/tokens.h \
- graphviz-plugin/graphviz-gstdebugger.h \
- gst-debugger-resources.h \
- gvalue-converter/gvalue_base.h \
- gvalue-converter/gvalue_boolean.h \
- gvalue-converter/gvalue_caps.h \
- gvalue-converter/gvalue_enum.h \
- gvalue-converter/gvalue_numeric.h \
- gvalue-converter/gvalue_string.h \
- main_window.h \
- models/gst_enum_model.h \
- models/gst_factory_model.h \
- models/gst_pipeline_model.h \
- models/remote_data_container.h \
- modules/base_main_module.h \
- modules/bus_messages_module.h \
- modules/control_module.h \
- modules/filter_utils.h \
- modules/gst_properties_module.h \
- modules/log_module.h \
- modules/main_module.h \
- modules/pad_data_modules.h \
- modules/pad_path_control_module.h \
- modules/pad_path_types_control_module.h \
- modules/types_control_module.h \
- pipeline-drawer/graph_module.h \
- pipeline-drawer/gst_bin_to_dot_converter.h \
- ui_utils.h
-
-
gst_debugger_ GST_API_VERSION@_SOURCES = \
- controller/command_factory.cpp \
- controller/controller.cpp \
- controller/tcp_client.cpp \
- controller/topology_controller.cpp \
- dialogs/buffer_data_dialog.cpp \
- dialogs/connection_properties_dialog.cpp \
- dialogs/enums_dialog.cpp \
- dialogs/factories_dialog.cpp \
- graphviz-plugin/gvdevice_gstdebugger.c \
- filter-parser/lexer.cpp \
- filter-parser/parser.cpp \
- filter-parser/tokens.cpp \
- graphviz-plugin/gvplugin_gstdebugger.c \
- gst-debugger-resources.c \
- gvalue-converter/gvalue_base.cpp \
- gvalue-converter/gvalue_boolean.cpp \
- gvalue-converter/gvalue_caps.cpp \
- gvalue-converter/gvalue_enum.cpp \
- gvalue-converter/gvalue_numeric.cpp \
- gvalue-converter/gvalue_string.cpp \
- main.cpp \
- main_window.cpp \
- models/gst_factory_model.cpp \
- models/gst_pipeline_model.cpp \
- modules/base_main_module.cpp \
- modules/bus_messages_module.cpp \
- modules/filter_utils.cpp \
- modules/gst_properties_module.cpp \
- modules/log_module.cpp \
- modules/main_module.cpp \
- modules/pad_data_modules.cpp \
- modules/pad_path_control_module.cpp \
- modules/types_control_module.cpp \
- pipeline-drawer/graph_module.cpp \
- pipeline-drawer/gst_bin_to_dot_converter.cpp \
- ui_utils.cpp \
- $(gst_debugger_headers)
+ main.cpp \
+ main_window.cpp \
+ main_window.h \
+ controller/controller.cpp \
+ controller/controller.h \
+ controller/command_factory.cpp \
+ controller/command_factory.h \
+ ui_utils.cpp \
+ ui_utils.h \
+ gst-debugger-resources.c \
+ gst-debugger-resources.h \
+ controller/base_controller.h \
+ controller/tcp_client.cpp \
+ controller/tcp_client.h \
+ dialogs/connection_properties_dialog.cpp \
+ dialogs/connection_properties_dialog.h \
+ modules/base_main_module.cpp \
+ modules/base_main_module.h \
+ modules/log_module.cpp \
+ modules/log_module.h \
+ modules/main_module.cpp \
+ modules/main_module.h \
+ controller/iview.h \
+ controller/topology_controller.cpp \
+ controller/topology_controller.h \
+ common_model_columns.h \
+ modules/message_module.cpp \
+ modules/message_module.h \
+ models/gst_enum_model.h \
+ models/gst_factory_model.cpp \
+ models/gst_factory_model.h \
+ models/gst_pipeline_model.cpp \
+ models/gst_pipeline_model.h \
+ modules/event_module.cpp \
+ modules/event_module.h \
+ modules/query_module.cpp \
+ modules/query_module.h \
+ pipeline-drawer/graph_module.cpp \
+ pipeline-drawer/graph_module.h \
+ pipeline-drawer/gst_bin_to_dot_converter.cpp \
+ pipeline-drawer/gst_bin_to_dot_converter.h \
+ graphviz-plugin/graphviz-gstdebugger.h \
+ graphviz-plugin/gvdevice_gstdebugger.c \
+ graphviz-plugin/gvplugin_gstdebugger.c \
+ controller/element_path_processor.h \
+ modules/qe_control_module.h \
+ dialogs/enums_dialog.cpp \
+ dialogs/enums_dialog.h \
+ dialogs/factories_dialog.cpp \
+ dialogs/factories_dialog.h \
+ modules/gst_properties_module.cpp \
+ modules/gst_properties_module.h
gst_debugger_ GST_API_VERSION@_LDFLAGS = $(GTKMM_LIBS) $(GSTMM_LIBS) $(GVC_LIBS) $(PROTOBUF_LIBS) -lX11
gst_debugger_ GST_API_VERSION@_LDADD = ../common/libgst-debugger-common-cpp- GST_DEBUGGER_API_VERSION@.la
diff --git a/src/gst-debugger/controller/command_factory.cpp b/src/gst-debugger/controller/command_factory.cpp
index d2a78c5..9882c9c 100644
--- a/src/gst-debugger/controller/command_factory.cpp
+++ b/src/gst-debugger/controller/command_factory.cpp
@@ -9,88 +9,125 @@
#include "common/common.h"
#include "common/serializer.h"
-void CommandFactory::send_pad_watch_command(bool enable, PadWatch_WatchType watch_type, const std::string
&pad_path, int qe_type)
+void CommandFactory::send_property_request_command(const std::string &element_path, const std::string
&property_name)
{
- Command cmd;
- PadWatch *pad_watch = new PadWatch();
- pad_watch->set_toggle(enable ? ENABLE : DISABLE);
- pad_watch->set_watch_type(watch_type);
- pad_watch->set_pad_path(pad_path);
- pad_watch->set_qe_type(qe_type);
- cmd.set_command_type(Command_CommandType_PAD_WATCH);
- cmd.set_allocated_pad_watch(pad_watch);
+ GstDebugger::Command cmd;
+ GstDebugger::PropertyRequest *request = new GstDebugger::PropertyRequest();
+ request->set_object(element_path);
+ request->set_name(property_name);
+ cmd.set_allocated_property(request);
client->send_command(cmd);
}
-void CommandFactory::send_property_request_command(const std::string &element_path, const std::string
&property_name)
+
+void CommandFactory::send_request_entire_topology_command()
{
- Command cmd;
- Property *property = new Property();
- property->set_element_path(element_path);
- property->set_property_name(property_name);
- cmd.set_command_type(Command_CommandType_PROPERTY);
- cmd.set_allocated_property(property);
+ GstDebugger::Command cmd;
+ cmd.set_entire_topology(true);
+
+ client->send_command(cmd);
+}
+
+GstDebugger::PadWatchRequest* CommandFactory::create_pad_watch_request(bool enable, const std::string
&pad_path)
+{
+ GstDebugger::PadWatchRequest *request = new GstDebugger::PadWatchRequest();
+ request->set_pad(pad_path);
+ request->set_action(enable ? GstDebugger::ADD : GstDebugger::REMOVE);
+ return request;
+}
+
+void CommandFactory::send_query_request_command(bool enable, const std::string &pad_path, int type)
+{
+ auto request = create_pad_watch_request(enable, pad_path);
+ GstDebugger::QueryWatchRequest *ev_request = new GstDebugger::QueryWatchRequest();
+ ev_request->set_type(type);
+ request->set_allocated_query(ev_request);
+ GstDebugger::Command cmd;
+ cmd.set_allocated_pad_watch(request);
+
+ client->send_command(cmd);
+}
+
+void CommandFactory::send_event_request_command(bool enable, const std::string &pad_path, int type)
+{
+ auto request = create_pad_watch_request(enable, pad_path);
+ GstDebugger::EventWatchRequest *ev_request = new GstDebugger::EventWatchRequest();
+ ev_request->set_type(type);
+ request->set_allocated_event(ev_request);
+ GstDebugger::Command cmd;
+ cmd.set_allocated_pad_watch(request);
+
client->send_command(cmd);
}
void CommandFactory::send_message_request_command(int message_type, bool enable)
{
- MessageWatch *msg_watch = new MessageWatch();
- msg_watch->set_message_type(message_type);
- msg_watch->set_toggle(enable ? ENABLE : DISABLE);
- Command cmd;
- cmd.set_command_type(Command_CommandType_MESSAGE_WATCH);
- cmd.set_allocated_message_watch(msg_watch);
+ GstDebugger::MessageRequest *request = new GstDebugger::MessageRequest();
+ request->set_type(message_type);
+ request->set_action(enable ? GstDebugger::ADD : GstDebugger::REMOVE);
+ GstDebugger::Command cmd;
+ cmd.set_allocated_message(request);
client->send_command(cmd);
}
void CommandFactory::send_set_threshold_command(const std::string &threshold_list, bool overwrite)
{
- Command cmd;
- LogThreshold *log_threshold = new LogThreshold();
- log_threshold->set_list(threshold_list);
- log_threshold->set_overwrite(overwrite);
- cmd.set_command_type(Command_CommandType_LOG_THRESHOLD);
- cmd.set_allocated_log_threshold(log_threshold);
+ GstDebugger::Command cmd;
+ // todo overwrite
+ cmd.set_log_threshold(threshold_list);
+ client->send_command(cmd);
+}
+
+void CommandFactory::send_set_log_watch_command(bool enable, const std::string &category, int log_level)
+{
+ GstDebugger::Command cmd;
+ GstDebugger::LogRequest *request = new GstDebugger::LogRequest();
+ request->set_level(log_level);
+ request->set_action(enable ? GstDebugger::ADD : GstDebugger::REMOVE);
+ request->set_category(category);
+ cmd.set_allocated_log(request);
client->send_command(cmd);
}
-void CommandFactory::send_set_log_watch_command(bool enable, int log_level)
+void CommandFactory::send_data_type_request_command(const std::string &type_name,
GstDebugger::TypeDescriptionRequest_Type type)
{
- Command cmd;
- LogWatch *log_watch = new LogWatch();
- log_watch->set_toggle(enable ? ENABLE : DISABLE);
- log_watch->set_log_level(log_level);
- cmd.set_command_type(Command_CommandType_LOG_WATCH);
- cmd.set_allocated_log_watch(log_watch);
+ GstDebugger::Command cmd;
+ GstDebugger::TypeDescriptionRequest *request = new GstDebugger::TypeDescriptionRequest();
+ request->set_type(type);
+ request->set_name(type_name);
+ cmd.set_allocated_type_description(request);
client->send_command(cmd);
}
void CommandFactory::send_request_debug_categories_command()
{
- Command cmd;
- cmd.set_command_type(Command_CommandType_DEBUG_CATEGORIES);
+ GstDebugger::Command cmd;
+ cmd.set_debug_categories_list(true);
client->send_command(cmd);
}
-void CommandFactory::send_request_topology_command()
+void CommandFactory::send_request_factory_command(const std::string &factory_name)
{
- Command cmd;
- cmd.set_command_type(Command_CommandType_TOPOLOGY);
+ GstDebugger::Command cmd;
+ auto rq = new GstDebugger::TypeDescriptionRequest();
+ rq->set_type(GstDebugger::TypeDescriptionRequest_Type_FACTORY);
+ rq->set_name(factory_name);
+ cmd.set_allocated_type_description(rq);
client->send_command(cmd);
}
-void CommandFactory::send_enum_type_request_command(const std::string &enum_name)
+
+/*
+void CommandFactory::send_request_topology_command()
{
Command cmd;
- cmd.set_command_type(Command_CommandType_ENUM_TYPE);
- cmd.set_enum_name(enum_name);
+ cmd.set_command_type(Command_CommandType_TOPOLOGY);
client->send_command(cmd);
}
@@ -113,14 +150,6 @@ void CommandFactory::send_property_command(const std::string &path, const std::s
client->send_command(cmd);
}
-void CommandFactory::send_request_factory(const std::string &factory_name)
-{
- Command cmd;
- cmd.set_command_type(Command_CommandType_FACTORY);
- cmd.set_factory_name(factory_name);
- client->send_command(cmd);
-}
-
void CommandFactory::send_request_pad_dynamic_info(const std::string &pad_path)
{
Command cmd;
@@ -128,3 +157,4 @@ void CommandFactory::send_request_pad_dynamic_info(const std::string &pad_path)
cmd.set_pad_path(pad_path);
client->send_command(cmd);
}
+*/
diff --git a/src/gst-debugger/controller/command_factory.h b/src/gst-debugger/controller/command_factory.h
index fa6b1c2..62c71cf 100644
--- a/src/gst-debugger/controller/command_factory.h
+++ b/src/gst-debugger/controller/command_factory.h
@@ -12,20 +12,25 @@
#include "common/gstdebugger.pb.h"
+#include <boost/optional/optional.hpp>
+
class CommandFactory : public virtual BaseController
{
+ static GstDebugger::PadWatchRequest* create_pad_watch_request(bool enable, const std::string
&pad_path);
+
public:
- void send_pad_watch_command(bool enable, PadWatch_WatchType watch_type, const std::string &pad_path,
int qe_type);
void send_property_request_command(const std::string &element_path, const std::string &property_name);
+ void send_event_request_command(bool enable, const std::string &pad_path, int type);
+ void send_query_request_command(bool enable, const std::string &pad_path, int type);
void send_message_request_command(int message_type, bool enable);
void send_set_threshold_command(const std::string &threshold_list, bool overwrite);
- void send_set_log_watch_command(bool enable, int log_level);
+ void send_set_log_watch_command(bool enable, const std::string &category, int log_level);
+ void send_data_type_request_command(const std::string &type_name,
GstDebugger::TypeDescriptionRequest_Type type);
void send_request_debug_categories_command();
- void send_request_topology_command();
- void send_enum_type_request_command(const std::string &enum_name);
- void send_property_command(const std::string &path, const std::string &property_name, GValue *gvalue);
- void send_request_factory(const std::string &factory_name);
- void send_request_pad_dynamic_info(const std::string &pad_path);
+ void send_request_entire_topology_command();
+ void send_request_factory_command(const std::string &factory_name);
+ /*void send_property_command(const std::string &path, const std::string &property_name, GValue
*gvalue);
+ void send_request_pad_dynamic_info(const std::string &pad_path);*/
};
#endif /* SRC_GST_DEBUGGER_CONTROLLER_COMMAND_FACTORY_H_ */
diff --git a/src/gst-debugger/controller/controller.cpp b/src/gst-debugger/controller/controller.cpp
index 618b321..fe7b567 100644
--- a/src/gst-debugger/controller/controller.cpp
+++ b/src/gst-debugger/controller/controller.cpp
@@ -6,23 +6,25 @@
*/
#include "controller.h"
-#include "element_path_processor.h"
-
#include "ui_utils.h"
-#include "common/common.h"
-#include "common/deserializer.h"
-#include "common/serializer.h"
-
#include <gtkmm.h>
-#include <boost/algorithm/string/split.hpp>
-
Controller::Controller(IMainView *view)
: view(view)
{
client->signal_frame_received.connect(sigc::mem_fun(*this, &Controller::process_frame));
- client->signal_status_changed.connect([this](bool connected) { if (!connected) client_disconnected();
});
+ client->signal_status_changed.connect([this](bool connected) {
+ if (!connected) client_disconnected();
+ else
+ {
+ send_data_type_request_command("GstMessageType",
GstDebugger::TypeDescriptionRequest_Type_ENUM_FLAGS);
+ send_data_type_request_command("GstEventType",
GstDebugger::TypeDescriptionRequest_Type_ENUM_FLAGS);
+ send_data_type_request_command("GstQueryType",
GstDebugger::TypeDescriptionRequest_Type_ENUM_FLAGS);
+ send_request_entire_topology_command();
+ send_request_debug_categories_command();
+ }
+ });
}
int Controller::run(int &argc, char **&argv)
@@ -32,37 +34,40 @@ int Controller::run(int &argc, char **&argv)
return app->run(*view);
}
-void Controller::send_command(const Command& cmd)
+void Controller::process_frame(const GstDebugger::GStreamerData &data)
{
- client->send_command(cmd);
-}
+ on_frame_received(data);
-void Controller::process_frame(const GstreamerInfo &info)
-{
- switch (info.info_type())
+ switch (data.info_type_case())
{
- case GstreamerInfo_InfoType_TOPOLOGY:
- process(info.topology());
+ case GstDebugger::GStreamerData::kDebugCategories:
+ debug_categories.clear();
+ for (auto c : data.debug_categories().category())
+ debug_categories.push_back(c);
+ on_debug_categories_changed();
+ break;
+ case GstDebugger::GStreamerData::kEnumFlagsType:
+ update_enum_model(data.enum_flags_type());
+ on_enum_list_changed(data.enum_flags_type().type_name(), true);
+ break;
+ case GstDebugger::GStreamerData::kConfirmation:
+ on_confirmation_received(data.confirmation());
+ break;
+ case GstDebugger::GStreamerData::kTopologyInfo:
+ process(data.topology_info());
on_model_changed(current_model);
- // todo get info from process??
- if (info.topology().type() == Topology_ObjectType_ELEMENT)
+ if (data.topology_info().has_element() &&
!get_factory(data.topology_info().element().factory_name()))
{
- send_request_factory(info.topology().element().factory_name());
+ send_request_factory_command(data.topology_info().element().factory_name());
}
-
break;
- case GstreamerInfo_InfoType_DEBUG_CATEGORIES:
- {
- boost::split(debug_categories, info.debug_categories().list(), [](char c) { return c == ';';
});
- debug_categories.erase(std::remove_if(debug_categories.begin(), debug_categories.end(),
- [](const std::string &s){return s.empty();}), debug_categories.end());
- on_debug_categories_changed();
+ case GstDebugger::GStreamerData::kFactory:
+ update_factory_model(data.factory());
+ on_factory_list_changed(data.factory().name(), true);
break;
}
- case GstreamerInfo_InfoType_LOG:
- on_log_received(info.log());
- break;
+ /*
case GstreamerInfo_InfoType_PROPERTY:
{
std::string name = info.property().type_name();
@@ -74,22 +79,6 @@ void Controller::process_frame(const GstreamerInfo &info)
on_property_received(info.property());
break;
}
- case GstreamerInfo_InfoType_BUFFER:
- case GstreamerInfo_InfoType_EVENT:
- case GstreamerInfo_InfoType_QUERY:
- case GstreamerInfo_InfoType_MESSAGE:
- on_qebm_received(info.qebm(), info.info_type());
- break;
- case GstreamerInfo_InfoType_PAD_WATCH_CONFIRMATION:
- on_pad_watch_confirmation_received(info.confirmation(), info.confirmation().watch_type());
- break;
- case GstreamerInfo_InfoType_MESSAGE_CONFIRMATION:
- on_message_confirmation_received(info.bus_msg_confirmation());
- break;
- case GstreamerInfo_InfoType_ENUM_TYPE:
- update_enum_model(info.enum_type());
- on_enum_list_changed(info.enum_type().type_name(), true);
- break;
case GstreamerInfo_InfoType_FACTORY:
update_factory_model(info.factory_info());
on_factory_list_changed(info.factory_info().name());
@@ -99,9 +88,33 @@ void Controller::process_frame(const GstreamerInfo &info)
break;
default:
break;
- }
+ }*/
+}
+
+template<typename T>
+boost::optional<T> get_from_container(const std::vector<T>& container, const std::string &name,
std::function<std::string(const T& val)> get_t_name)
+{
+ auto it = std::find_if(container.begin(), container.end(), [name, get_t_name](const T& enum_type) {
+ return get_t_name(enum_type) == name;
+ });
+
+ if (it == container.end())
+ return boost::none;
+ else
+ return *it;
+}
+
+boost::optional<GstEnumType> Controller::get_enum_type(const std::string &name)
+{
+ return get_from_container<GstEnumType>(enum_container, name, [](const GstEnumType& enum_type) {return
enum_type.get_name(); } );
}
+boost::optional<FactoryModel> Controller::get_factory(const std::string &name)
+{
+ return get_from_container<FactoryModel>(factory_container, name, [](const FactoryModel& factory)
{return factory.get_name(); } );
+}
+
+
void Controller::model_up()
{
if (current_model == ElementModel::get_root())
@@ -150,22 +163,35 @@ void Controller::set_selected_object(const std::string &name)
if (obj && is_pad)
{
- send_request_pad_dynamic_info(ElementPathProcessor::get_object_path(obj));
+ // send_request_pad_dynamic_info(ElementPathProcessor::get_object_path(obj));
}
}
}
-void Controller::update_enum_model(const EnumType &enum_type)
+void Controller::update_enum_model(const GstDebugger::EnumFlagsType &enum_type)
{
- GstEnumType et(enum_type.type_name(), enum_type.base_gtype());
- for (int i = 0; i < enum_type.entry_size(); i++)
+ GstEnumType et(enum_type.type_name(), G_TYPE_ENUM); // todo G_TYPE_FLAGS
+ for (int i = 0; i < enum_type.values_size(); i++)
+ {
+ et.add_value(enum_type.values(i).name(), enum_type.values(i).value(),
enum_type.values(i).nick());
+ }
+
+ // todo copy & paste get_enum_type()
+ auto it = std::find_if(enum_container.begin(), enum_container.end(), [enum_type](const GstEnumType&
type) {
+ return type.get_name() == enum_type.type_name();
+ });
+
+ if (it == enum_container.end())
+ {
+ enum_container.push_back(et);
+ }
+ else
{
- et.add_value(enum_type.entry(i).name(), enum_type.entry(i).value(),
enum_type.entry(i).nick());
+ *it = et;
}
- enum_container.update_item(et);
}
-void Controller::update_factory_model(const FactoryInfo &factory_info)
+void Controller::update_factory_model(const GstDebugger::FactoryType &factory_info)
{
FactoryModel model(factory_info.name());
@@ -174,14 +200,26 @@ void Controller::update_factory_model(const FactoryInfo &factory_info)
model.append_template(protocol_template_to_gst_template(factory_info.templates(i)));
}
- for (int i = 0; i < factory_info.meta_entries_size(); i++)
+ for (int i = 0; i < factory_info.metadata_size(); i++)
{
- model.append_meta(factory_info.meta_entries(i).key(), factory_info.meta_entries(i).value());
+ model.append_meta(factory_info.metadata(i).key(), factory_info.metadata(i).value());
}
- factory_container.update_item(model);
-}
+ // todo copy & paste get_enum_type()
+ auto it = std::find_if(factory_container.begin(), factory_container.end(), [model](const
FactoryModel& type) {
+ return type.get_name() == model.get_name();
+ });
+ if (it == factory_container.end())
+ {
+ factory_container.push_back(model);
+ }
+ else
+ {
+ *it = model;
+ }
+}
+/*
void Controller::append_property(const Property& property)
{
GValue *value = new GValue;
@@ -195,19 +233,19 @@ void Controller::append_property(const Property& property)
this->send_property_command(property.element_path(), property.property_name(),
gvalue->get_gvalue());
});
}
-
+*/
void Controller::log(const std::string &message)
{
// todo date/time?
std::cerr << message << std::endl;
- on_new_log_entry(message);
+ //on_new_log_entry(message);
}
void Controller::client_disconnected()
{
- auto root_model = ElementModel::get_root();
+/* auto root_model = ElementModel::get_root();
root_model->clean_model();
on_model_changed(root_model);
@@ -228,9 +266,9 @@ void Controller::client_disconnected()
}
debug_categories.clear();
- on_debug_categories_changed();
+ on_debug_categories_changed();*/
}
-
+/*
void Controller::update_pad_dynamic_info(const PadDynamicInfo &info)
{
auto pad = std::dynamic_pointer_cast<PadModel>(ElementPathProcessor(info.pad_path()).get_last_obj());
@@ -245,4 +283,5 @@ void Controller::update_pad_dynamic_info(const PadDynamicInfo &info)
{
on_selected_object_changed();
}
-}
+}*/
+
diff --git a/src/gst-debugger/controller/controller.h b/src/gst-debugger/controller/controller.h
index 16ed7f2..7f9cc62 100644
--- a/src/gst-debugger/controller/controller.h
+++ b/src/gst-debugger/controller/controller.h
@@ -8,48 +8,50 @@
#ifndef SRC_GST_DEBUGGER_CONTROLLER_CONTROLLER_H_
#define SRC_GST_DEBUGGER_CONTROLLER_CONTROLLER_H_
-#include "command_factory.h"
#include "iview.h"
#include "connection_controller.h"
+#include "command_factory.h"
#include "topology_controller.h"
+
#include "models/gst_enum_model.h"
-#include "models/remote_data_container.h"
#include "models/gst_factory_model.h"
-#include "common/gstdebugger.pb.h"
+
+#include <boost/optional/optional.hpp>
class Controller :
public std::enable_shared_from_this<Controller>,
- public CommandFactory,
public ConnectionController,
+ public CommandFactory,
public TopologyController
{
private:
IMainView *view;
+ std::vector<GstEnumType> enum_container;
+ std::vector<FactoryModel> factory_container;
+ std::vector<std::string> debug_categories;
+
std::shared_ptr<ObjectModel> selected_object;
- RemoteDataContainer<GstEnumType> enum_container;
- RemoteDataContainer<FactoryModel> factory_container;
- std::vector<std::string> debug_categories;
+ void process_frame(const GstDebugger::GStreamerData& info);
- void process_frame(const GstreamerInfo& info);
+ void update_enum_model(const GstDebugger::EnumFlagsType &enum_type);
+ void update_factory_model(const GstDebugger::FactoryType &factory_info);
- void update_enum_model(const EnumType &enum_type);
+ /*
- void update_factory_model(const FactoryInfo &factory_info);
void append_property(const Property& property);
- void client_disconnected();
-
void update_pad_dynamic_info(const PadDynamicInfo& info);
+*/
+
+ void client_disconnected();
public:
Controller(IMainView *view);
- void send_command(const Command& cmd);
-
int run(int &argc, char **&argv);
void model_up();
@@ -57,25 +59,27 @@ public:
void set_selected_object(const std::string &name);
- const RemoteDataContainer<GstEnumType>& get_enum_container() const { return enum_container; }
- const RemoteDataContainer<FactoryModel>& get_factory_container() const { return factory_container; }
const std::vector<std::string>& get_debug_categories() const { return debug_categories; }
+ boost::optional<GstEnumType> get_enum_type(const std::string &name);
+ boost::optional<FactoryModel> get_factory(const std::string &name);
+
+ const std::vector<FactoryModel>& get_factories() const { return factory_container; }
+ const std::vector<GstEnumType> get_enums() const { return enum_container; }
+
std::shared_ptr<ObjectModel> get_selected_object() const { return selected_object; }
void log(const std::string &message);
- sigc::signal<void, const GstreamerLog&> on_log_received;
sigc::signal<void> on_debug_categories_changed;
- sigc::signal<void, std::shared_ptr<ElementModel>> on_model_changed;
- sigc::signal<void, const Property&> on_property_received;
- sigc::signal<void, const GstreamerQEBM&, GstreamerInfo_InfoType> on_qebm_received;
- sigc::signal<void, const MessageWatch&> on_message_confirmation_received;
- sigc::signal<void, const PadWatch&, PadWatch_WatchType> on_pad_watch_confirmation_received;
+ sigc::signal<void, const GstDebugger::GStreamerData&> on_frame_received;
+ sigc::signal<void, const GstDebugger::Command&> on_confirmation_received;
sigc::signal<void, const Glib::ustring&, bool> on_enum_list_changed; /* enum name, true - add, false
- remove */
+ sigc::signal<void, const Glib::ustring&, bool> on_factory_list_changed;
+ sigc::signal<void, std::shared_ptr<ElementModel>> on_model_changed;
+ sigc::signal<void, const GstDebugger::PropertyInfo&> on_property_received;
sigc::signal<void> on_selected_object_changed;
- sigc::signal<void, const Glib::ustring&> on_factory_list_changed;
- sigc::signal<void, const Glib::ustring&> on_new_log_entry;
+/* sigc::signal<void, const Glib::ustring&> on_new_log_entry;*/
};
#endif /* SRC_GST_DEBUGGER_CONTROLLER_CONTROLLER_H_ */
diff --git a/src/gst-debugger/controller/tcp_client.cpp b/src/gst-debugger/controller/tcp_client.cpp
index e33d428..f4de69f 100644
--- a/src/gst-debugger/controller/tcp_client.cpp
+++ b/src/gst-debugger/controller/tcp_client.cpp
@@ -56,13 +56,14 @@ void TcpClient::read_data()
m_buff = buffer;
}
gst_debugger_protocol_utils_read_requested_size(input_stream->gobj(), size, m_buff,
cancel->gobj());
- GstreamerInfo info;
- info.ParseFromArray(m_buff, size);
+
+ GstDebugger::GStreamerData data;
+ data.ParseFromArray(m_buff, size);
if (m_buff != buffer)
{
delete m_buff;
}
- signal_frame_received(info);
+ signal_frame_received(data);
}
connected = false;
@@ -84,7 +85,7 @@ void TcpClient::write_data(char *data, int size)
stream->write(data, size);
}
-void TcpClient::send_command(const Command &cmd)
+void TcpClient::send_command(const GstDebugger::Command &cmd)
{
if (!is_connected())
throw Gio::Error(Gio::Error::FAILED, "No connection!");
diff --git a/src/gst-debugger/controller/tcp_client.h b/src/gst-debugger/controller/tcp_client.h
index 9d8fdb2..e460a56 100644
--- a/src/gst-debugger/controller/tcp_client.h
+++ b/src/gst-debugger/controller/tcp_client.h
@@ -19,7 +19,7 @@
class TcpClient
{
public:
- typedef sigc::signal1<void, const GstreamerInfo&> frame_received_slot;
+ typedef sigc::signal1<void, const GstDebugger::GStreamerData&> frame_received_slot;
private:
Glib::RefPtr<Gio::SocketClient> client;
@@ -36,12 +36,13 @@ public:
bool connect(const std::string &address, int port);
bool disconnect();
void write_data(char *data, int size);
- void send_command(const Command &cmd);
+ void send_command(const GstDebugger::Command &gst_data);
bool is_connected() const { return connected; }
sigc::signal1<void, bool> signal_status_changed;
frame_received_slot signal_frame_received;
+
};
#endif /* SRC_GST_DEBUGGER_GST_DEBUGGER_TCP_CLIENT_H_ */
diff --git a/src/gst-debugger/controller/topology_controller.cpp
b/src/gst-debugger/controller/topology_controller.cpp
index 4a75cb2..b5cfc1a 100644
--- a/src/gst-debugger/controller/topology_controller.cpp
+++ b/src/gst-debugger/controller/topology_controller.cpp
@@ -12,19 +12,19 @@
#include <boost/algorithm/string/split.hpp>
-void TopologyController::process(const Topology& topology)
+void TopologyController::process(const GstDebugger::TopologyInfo& topology)
{
lock_topology();
- switch (topology.type())
+ switch (topology.topology_type_case())
{
- case Topology_ObjectType_ELEMENT:
+ case GstDebugger::TopologyInfo::kElement:
process_element(topology.element(), topology.action());
break;
- case Topology_ObjectType_PAD:
+ case GstDebugger::TopologyInfo::kPad:
process_pad(topology.pad(), topology.action());
break;
- case Topology_ObjectType_LINK:
+ case GstDebugger::TopologyInfo::kLink:
process_link(topology.link(), topology.action());
break;
default:
@@ -34,7 +34,7 @@ void TopologyController::process(const Topology& topology)
unlock_topology();
}
-void TopologyController::process_element(const TopologyElement &element, Topology_Action action)
+void TopologyController::process_element(const GstDebugger::TopologyElement &element, GstDebugger::Action
action)
{
ElementPathProcessor path_processor(element.path());
auto parent = path_processor.get_parent_element();
@@ -43,10 +43,10 @@ void TopologyController::process_element(const TopologyElement &element, Topolog
switch (action)
{
- case Topology_Action_ADD:
+ case GstDebugger::ADD:
parent->add_child(std::make_shared<ElementModel>(path_processor.get_last_obj_str(),
element.type_name(), element.is_bin()));
break;
- case Topology_Action_REMOVE:
+ case GstDebugger::REMOVE:
parent->remove_child(path_processor.get_last_obj_str());
break;
default:
@@ -54,7 +54,7 @@ void TopologyController::process_element(const TopologyElement &element, Topolog
}
}
-void TopologyController::process_pad(const TopologyPad &pad, Topology_Action action)
+void TopologyController::process_pad(const GstDebugger::TopologyPad &pad, GstDebugger::Action action)
{
ElementPathProcessor path_processor(pad.path());
auto parent = path_processor.get_parent_element();
@@ -63,27 +63,27 @@ void TopologyController::process_pad(const TopologyPad &pad, Topology_Action act
switch (action)
{
- case Topology_Action_ADD:
+ case GstDebugger::ADD:
parent->add_pad(std::make_shared<PadModel>(path_processor.get_last_obj_str(),
protocol_template_to_gst_template(pad.template_()),
pad.is_ghostpad(), static_cast<Gst::PadDirection>(pad.direction()),
static_cast<Gst::PadPresence>(pad.presence())));
break;
- case Topology_Action_REMOVE:
+ case GstDebugger::REMOVE:
parent->remove_pad(path_processor.get_last_obj_str());
break;
}
}
-void TopologyController::process_link(const TopologyLink &link, Topology_Action action)
+void TopologyController::process_link(const GstDebugger::TopologyLink &link, GstDebugger::Action action)
{
- ElementPathProcessor src_processor(link.src_pad_path()), sink_processor(link.sink_pad_path());
+ ElementPathProcessor src_processor(link.src_pad()), sink_processor(link.sink_pad());
std::shared_ptr<PadModel> src = std::dynamic_pointer_cast<PadModel>(src_processor.get_last_obj()),
sink = std::dynamic_pointer_cast<PadModel>(sink_processor.get_last_obj());
switch (action)
{
- case Topology_Action_ADD:
+ case GstDebugger::ADD:
if (src == nullptr || sink == nullptr)
return;
src->set_peer(sink);
@@ -92,7 +92,7 @@ void TopologyController::process_link(const TopologyLink &link, Topology_Action
sink->set_peer(src);
}
break;
- case Topology_Action_REMOVE:
+ case GstDebugger::REMOVE:
{
std::shared_ptr<PadModel> empty;
if (src != nullptr)
diff --git a/src/gst-debugger/controller/topology_controller.h
b/src/gst-debugger/controller/topology_controller.h
index f932550..6c8f657 100644
--- a/src/gst-debugger/controller/topology_controller.h
+++ b/src/gst-debugger/controller/topology_controller.h
@@ -18,14 +18,14 @@ class TopologyController : public virtual BaseController
{
std::mutex m_topology;
- void process_element(const TopologyElement &element, Topology_Action action);
- void process_pad(const TopologyPad &pad, Topology_Action action);
- void process_link(const TopologyLink &link, Topology_Action action);
+ void process_element(const GstDebugger::TopologyElement &element, GstDebugger::Action action);
+ void process_pad(const GstDebugger::TopologyPad &pad, GstDebugger::Action action);
+ void process_link(const GstDebugger::TopologyLink &link, GstDebugger::Action action);
public:
void lock_topology() { m_topology.lock(); }
void unlock_topology() { m_topology.unlock(); }
- void process(const Topology &topology);
+ void process(const GstDebugger::TopologyInfo &topology);
};
#endif /* SRC_GST_DEBUGGER_CONTROLLER_TOPOLOGY_CONTROLLER_H_ */
diff --git a/src/gst-debugger/dialogs/enums_dialog.cpp b/src/gst-debugger/dialogs/enums_dialog.cpp
index 9148d78..6407a73 100644
--- a/src/gst-debugger/dialogs/enums_dialog.cpp
+++ b/src/gst-debugger/dialogs/enums_dialog.cpp
@@ -34,7 +34,7 @@ void EnumsDialog::reload_list(const Glib::ustring& enum_name, bool add)
{
tree_model->clear();
- for (auto enum_type : controller->get_enum_container())
+ for (auto enum_type : controller->get_enums())
{
auto row = *(tree_model->append());
row[enums_columns.m_col_name] = enum_type.get_name();
diff --git a/src/gst-debugger/dialogs/factories_dialog.cpp b/src/gst-debugger/dialogs/factories_dialog.cpp
index 8ce9412..c397fbf 100644
--- a/src/gst-debugger/dialogs/factories_dialog.cpp
+++ b/src/gst-debugger/dialogs/factories_dialog.cpp
@@ -25,11 +25,13 @@ void FactoriesDialog::set_controller(const std::shared_ptr<Controller> &controll
{
IBaseView::set_controller(controller);
controller->on_factory_list_changed.connect(sigc::mem_fun(*this, &FactoriesDialog::reload_list));
- reload_list("");
+ reload_list("", true);
}
-void FactoriesDialog::reload_list(const Glib::ustring &factory_name)
+void FactoriesDialog::reload_list(const Glib::ustring &factory_name, bool add)
{
+ // todo if (add)
+
tree_model->clear();
#define APPEND_SUB_ROW(name, value, parent) \
@@ -40,7 +42,7 @@ void FactoriesDialog::reload_list(const Glib::ustring &factory_name)
return childrow; \
} ()
- for (auto factory : controller->get_factory_container())
+ for (auto factory : controller->get_factories())
{
auto row = *(tree_model->append());
row[factories_columns.m_col_name] = factory.get_name();
diff --git a/src/gst-debugger/dialogs/factories_dialog.h b/src/gst-debugger/dialogs/factories_dialog.h
index 1f7730b..344aaf9 100644
--- a/src/gst-debugger/dialogs/factories_dialog.h
+++ b/src/gst-debugger/dialogs/factories_dialog.h
@@ -29,7 +29,7 @@ class FactoriesDialog : public RemoteDataDialog
FactoryModelColumns factories_columns;
Glib::RefPtr<Gtk::TreeStore> factories_tree_model;
- void reload_list(const Glib::ustring &factory_name);
+ void reload_list(const Glib::ustring &factory_name, bool add);
public:
FactoriesDialog(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder);
diff --git a/src/gst-debugger/main.cpp b/src/gst-debugger/main.cpp
index 3d6fc53..b8e7839 100644
--- a/src/gst-debugger/main.cpp
+++ b/src/gst-debugger/main.cpp
@@ -12,8 +12,6 @@
#include <gtkmm.h>
#include <gstreamermm.h>
-#include "filter-parser/parser.h"
-
int main(int argc, char** argv)
{
Gst::init(argc, argv);
@@ -22,7 +20,7 @@ int main(int argc, char** argv)
MainWindow* wnd_handler;
builder->get_widget_derived("mainWindow", wnd_handler);
- std::shared_ptr<Controller> controller(new Controller(wnd_handler));
+ std::shared_ptr<Controller> controller(new Controller(wnd_handler));
controller->run(argc, argv);
diff --git a/src/gst-debugger/main_window.cpp b/src/gst-debugger/main_window.cpp
index c810c9f..3f0e5a3 100644
--- a/src/gst-debugger/main_window.cpp
+++ b/src/gst-debugger/main_window.cpp
@@ -19,10 +19,9 @@ MainWindow::MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>
builder(builder),
dispatcher(std::make_shared<Glib::Dispatcher>()),
main_module(std::make_shared<MainModule>(builder)),
+ graph_module(std::make_shared<GraphModule>(builder)),
properties_module(std::make_shared<GstPropertiesModule>(builder))
{
- graph_module = std::make_shared<GraphModule>(builder);
-
builder->get_widget("connectionPropertiesMenuItem", connection_properties);
connection_properties->signal_activate().connect(sigc::mem_fun(*this,
&MainWindow::connectionPropertiesMenuItem_activate_cb));
@@ -77,7 +76,6 @@ void MainWindow::set_controller(const std::shared_ptr<Controller> &controller)
main_module->set_controller(controller);
graph_module->set_controller(controller);
- properties_module->set_controller(controller);
enums_dialog->set_controller(controller);
enums_dialog->set_transient_for(*this);
@@ -85,6 +83,8 @@ void MainWindow::set_controller(const std::shared_ptr<Controller> &controller)
factories_dialog->set_controller(controller);
factories_dialog->set_transient_for(*this);
+ properties_module->set_controller(controller);
+
connection_properties_dialog->set_transient_for(*this);
}
@@ -117,4 +117,3 @@ void MainWindow::connection_status_changed(bool connected)
((Gtk::Label*)connect_menu_item->get_child())->set_text("Connect");
}
}
-
diff --git a/src/gst-debugger/main_window.h b/src/gst-debugger/main_window.h
index a813a07..44ca02b 100644
--- a/src/gst-debugger/main_window.h
+++ b/src/gst-debugger/main_window.h
@@ -8,18 +8,16 @@
#ifndef SRC_GST_DEBUGGER_MAIN_WINDOW_H_
#define SRC_GST_DEBUGGER_MAIN_WINDOW_H_
-#include "controller/tcp_client.h"
#include "dialogs/connection_properties_dialog.h"
#include "dialogs/enums_dialog.h"
#include "dialogs/factories_dialog.h"
-#include "modules/gst_properties_module.h"
#include "modules/main_module.h"
+#include "modules/gst_properties_module.h"
#include "pipeline-drawer/graph_module.h"
-#include <gtkmm.h>
-
#include "controller/iview.h"
-#include "models/gst_enum_model.h"
+
+#include <gtkmm.h>
#include <map>
@@ -37,19 +35,18 @@ class MainWindow : public IMainView
Gtk::MenuItem *about_menu_item;
Gtk::MenuItem *quit_menu_item;
+ Gtk::AboutDialog *about_dialog;
+ Gtk::Statusbar *main_statusbar;
+
ConnectionPropertiesDialog *connection_properties_dialog;
EnumsDialog *enums_dialog;
FactoriesDialog *factories_dialog;
- Gtk::AboutDialog *about_dialog;
- Gtk::Statusbar *main_statusbar;
std::shared_ptr<Glib::Dispatcher> dispatcher;
std::shared_ptr<MainModule> main_module;
std::shared_ptr<GraphModule> graph_module;
std::shared_ptr<GstPropertiesModule> properties_module;
- GstreamerInfo info;
-
public:
MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder);
virtual ~MainWindow() {}
diff --git a/src/gst-debugger/models/gst_pipeline_model.cpp b/src/gst-debugger/models/gst_pipeline_model.cpp
index f2488cd..017b2d2 100644
--- a/src/gst-debugger/models/gst_pipeline_model.cpp
+++ b/src/gst-debugger/models/gst_pipeline_model.cpp
@@ -70,7 +70,7 @@ std::shared_ptr<ElementModel> ElementModel::get_child(const std::string &child_n
return (it != children.end()) ? *it : std::shared_ptr<ElementModel>();
}
-void ElementModel::add_property(const std::string &name, const std::shared_ptr<GValueBase>& gvalue)
+/*void ElementModel::add_property(const std::string &name, const std::shared_ptr<GValueBase>& gvalue)
{
if (properties.find(name) == properties.end())
{
@@ -81,7 +81,7 @@ void ElementModel::add_property(const std::string &name, const std::shared_ptr<G
gvalue->update_gvalue(gvalue);
}
}
-
+*/
std::shared_ptr<ElementModel> ElementModel::get_parent_element_from_path(const std::string &path)
{
ElementPathProcessor proc(path);
diff --git a/src/gst-debugger/models/gst_pipeline_model.h b/src/gst-debugger/models/gst_pipeline_model.h
index 803a9e7..3d233dd 100644
--- a/src/gst-debugger/models/gst_pipeline_model.h
+++ b/src/gst-debugger/models/gst_pipeline_model.h
@@ -111,7 +111,7 @@ public:
const std::vector<std::shared_ptr<PadModel>>& get_pads() const { return pads; }
- void add_property(const std::string &name, const std::shared_ptr<GValueBase>& gvalue);
+ //void add_property(const std::string &name, const std::shared_ptr<GValueBase>& gvalue);
static std::shared_ptr<ElementModel> get_parent_element_from_path(const std::string &path);
diff --git a/src/gst-debugger/modules/base_main_module.cpp b/src/gst-debugger/modules/base_main_module.cpp
index 896433b..123d7e2 100644
--- a/src/gst-debugger/modules/base_main_module.cpp
+++ b/src/gst-debugger/modules/base_main_module.cpp
@@ -7,34 +7,50 @@
#include "base_main_module.h"
+#include "controller/controller.h"
+
DetailsModelColumns BaseMainModule::detail_columns;
-BaseMainModule::BaseMainModule()
-{
- details_model = Gtk::ListStore::create(detail_columns);
-}
+inline void free_data(GstDebugger::GStreamerData* data) { delete data; }
-void BaseMainModule::configure_main_list_view(Gtk::TreeView *view)
+BaseMainModule::BaseMainModule(GstDebugger::GStreamerData::InfoTypeCase info_type, const std::string
&module_name)
+: supported_info_type(info_type),
+ model(Gtk::ListStore::create(columns)),
+ details_model(Gtk::ListStore::create(detail_columns)),
+ module_name(module_name)
{
- view->remove_all_columns();
+ create_dispatcher("new-data", sigc::mem_fun(*this, &BaseMainModule::data_received_),
(GDestroyNotify)free_data);
filter = Gtk::TreeModelFilter::create(model);
filter->set_visible_func([this](const Gtk::TreeModel::const_iterator& it){
return filter_function(it);
});
+}
+void BaseMainModule::configure_main_list_view(Gtk::TreeView *view)
+{
+ view->remove_all_columns();
view->set_model(filter);
+ view->append_column(module_name, columns.header);
}
void BaseMainModule::load_details(Gtk::TreeView *view, const Gtk::TreeModel::Path &path)
{
details_model->clear();
view->set_model(details_model);
+
+ Gtk::TreeModel::iterator iter = filter->get_iter(path);
+ if (!iter)
+ {
+ return;
+ }
+
+ load_details((*iter)[columns.data]);
}
void BaseMainModule::update_filter_expression(const std::string &expr)
{
- Parser p;
+/* Parser p;
auto prev = filter_expression;
try
{
@@ -45,7 +61,7 @@ void BaseMainModule::update_filter_expression(const std::string &expr)
if (prev != filter_expression)
{
filter->refilter();
- }
+ }*/
}
void BaseMainModule::configure_details_view(Gtk::TreeView *view)
@@ -72,14 +88,35 @@ void BaseMainModule::append_details_from_structure(Gst::Structure& structure)
*tmp_val = G_VALUE_INIT;
g_value_init(tmp_val, value.gobj()->g_type);
g_value_copy(value.gobj(), tmp_val);
- auto gvalue = GValueBase::build_gvalue(tmp_val);
- if (gvalue == nullptr)
+ //auto gvalue = GValueBase::build_gvalue(tmp_val);
+ //if (gvalue == nullptr)
append_details_row(name, std::string("<unsupported type ") +
g_type_name(G_VALUE_TYPE(value.gobj())) + ">");
- else
- {
- append_details_row(name, gvalue->to_string());
- delete gvalue;
- }
+ //else
+ //{
+ // append_details_row(name, gvalue->to_string());
+ // delete gvalue;
+ //}
return true;
});
}
+
+void BaseMainModule::data_received_()
+{
+ auto msg = gui_pop<GstDebugger::GStreamerData*>("new-data");
+ Gtk::TreeModel::Row row = *(model->append());
+ data_received(row, msg);
+ delete msg;
+}
+
+void BaseMainModule::set_controller(const std::shared_ptr<Controller> &controller)
+{
+ IBaseView::set_controller(controller);
+
+ controller->on_frame_received.connect([this] (const GstDebugger::GStreamerData &data) {
+ if (data.info_type_case() != supported_info_type)
+ return;
+
+ gui_push("new-data", new GstDebugger::GStreamerData(data));
+ gui_emit("new-data");
+ });
+}
diff --git a/src/gst-debugger/modules/base_main_module.h b/src/gst-debugger/modules/base_main_module.h
index 6912f56..c7432a6 100644
--- a/src/gst-debugger/modules/base_main_module.h
+++ b/src/gst-debugger/modules/base_main_module.h
@@ -8,18 +8,37 @@
#ifndef SRC_GST_DEBUGGER_MODULES_BASE_MAIN_MODULE_H_
#define SRC_GST_DEBUGGER_MODULES_BASE_MAIN_MODULE_H_
-#include "controller/iview.h"
#include "common_model_columns.h"
-#include "filter-parser/parser.h"
+
+#include "controller/iview.h"
+
+#include "common/gstdebugger.pb.h"
#include <gtkmm/liststore.h>
#include <gtkmm/treeview.h>
#include <gtkmm/treemodel.h>
+class MainModuleModelColumns : public Gtk::TreeModel::ColumnRecord
+{
+public:
+ MainModuleModelColumns() {
+ add(header); add(data);
+ }
+
+ Gtk::TreeModelColumn<Glib::ustring> header;
+ Gtk::TreeModelColumn<gpointer> data;
+};
+
+
class BaseMainModule : public IBaseView
{
+ void data_received_();
+
+ GstDebugger::GStreamerData::InfoTypeCase supported_info_type;
+ std::string module_name;
+
protected:
- std::shared_ptr<Expression> filter_expression;
+ MainModuleModelColumns columns;
static DetailsModelColumns detail_columns;
@@ -30,14 +49,17 @@ protected:
void append_details_row(const std::string &name, const std::string &value);
void append_details_from_structure(Gst::Structure& structure);
+ virtual void data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data) = 0;
virtual bool filter_function(const Gtk::TreeModel::const_iterator& it) { return true; }
+ virtual void load_details(gpointer data) = 0;
+
public:
- BaseMainModule();
+ BaseMainModule(GstDebugger::GStreamerData::InfoTypeCase info_type, const std::string &module_name);
virtual ~BaseMainModule() {}
- virtual void configure_main_list_view(Gtk::TreeView *view) = 0;
- virtual void load_details(Gtk::TreeView *view, const Gtk::TreeModel::Path &path) = 0;
+ void configure_main_list_view(Gtk::TreeView *view);
+ void load_details(Gtk::TreeView *view, const Gtk::TreeModel::Path &path);
virtual void details_activated(const Gtk::TreeModel::Path &path) {}
static void configure_details_view(Gtk::TreeView *view);
@@ -45,6 +67,8 @@ public:
void update_filter_expression(const std::string &expr);
Glib::RefPtr<Gtk::ListStore> get_model() const { return model; }
+
+ void set_controller(const std::shared_ptr<Controller> &controller) override;
};
#endif /* SRC_GST_DEBUGGER_MODULES_BASE_MAIN_MODULE_H_ */
diff --git a/src/gst-debugger/modules/control_module.h b/src/gst-debugger/modules/control_module.h
index 465505b..2e9b8aa 100644
--- a/src/gst-debugger/modules/control_module.h
+++ b/src/gst-debugger/modules/control_module.h
@@ -15,111 +15,107 @@
#include <gtkmm/widget.h>
-class ControlModule : public IBaseView
-{
-public:
- virtual ~ControlModule() {};
-
- virtual Gtk::Widget* get_widget() = 0;
-};
-
class HooksModelColumns : public Gtk::TreeModel::ColumnRecord
{
public:
HooksModelColumns() {
- add(pad_path); add(qe_type_name); add(qe_type);
+ add(str1); add(str2); add(int1); add(int2);
}
- Gtk::TreeModelColumn<Glib::ustring> pad_path;
- Gtk::TreeModelColumn<Glib::ustring> qe_type_name;
- Gtk::TreeModelColumn<gint> qe_type;
+ Gtk::TreeModelColumn<Glib::ustring> str1;
+ Gtk::TreeModelColumn<Glib::ustring> str2;
+ Gtk::TreeModelColumn<gint> int1;
+ Gtk::TreeModelColumn<gint> int2;
};
+inline void free_confirmation(GstDebugger::Command *cmd) { delete cmd; }
-class HooksControlModule : public ControlModule
+class ControlModule : public IBaseView
{
- Gtk::ScrolledWindow *wnd;
-
protected:
- PadWatch_WatchType watch_type;
-
Glib::RefPtr<Gtk::ListStore> hooks_model;
HooksModelColumns hooks_model_columns;
+ Gtk::Box *main_box;
+ Gtk::Button *add_watch_button;
+ Gtk::Button *remove_watch_button;
Gtk::TreeView *hooks_tree_view;
- Gtk::Box *main_box = nullptr;
- Gtk::Button *remove_hook_button;
- Gtk::Button *add_hook_button;
+ Gtk::ScrolledWindow *wnd;
- void append_hook_widgets()
+ void confirmation_()
{
- main_box->pack_start(*add_hook_button, false, true);
- main_box->pack_start(*Gtk::manage(new Gtk::Label("Existing hooks:")), false, true);
-
- main_box->pack_start(*wnd, true, true);
- main_box->pack_start(*remove_hook_button, false, true);
-
- update_add_hook();
+ auto confirmation = gui_pop<GstDebugger::Command*>("confirmation");
+ confirmation_received(confirmation);
+ delete confirmation;
}
- virtual bool add_hook_unlocked() { return true; }
-
- void update_add_hook()
+ template<typename T>
+ void remove_hook(const T& confirmation)
{
- add_hook_button->set_sensitive(add_hook_unlocked());
+ for (auto iter = hooks_model->children().begin();
+ iter != hooks_model->children().end(); ++iter)
+ {
+ if (hook_is_the_same(*iter, &confirmation))
+ {
+ hooks_model->erase(iter);
+ break;
+ }
+ }
}
- virtual int get_type() const { return -1; }
- virtual std::string get_pad_path() const { return std::string(); }
+ virtual bool hook_is_the_same(const Gtk::TreeModel::Row& row, gconstpointer confirmation) = 0;
+ virtual void add_watch() {}
+ virtual void remove_watch(const Gtk::TreeModel::Row& row) {}
+ virtual void confirmation_received(GstDebugger::Command* cmd) {}
public:
- HooksControlModule(PadWatch_WatchType w_type)
- : watch_type(w_type)
+ ControlModule()
{
- add_hook_button = Gtk::manage(new Gtk::Button("Add hook"));
- add_hook_button->signal_clicked().connect([this]{
- if ((int)watch_type == -1) // todo it has to be fixed on design protocol level
- controller->send_message_request_command(get_type(), true);
- else
- controller->send_pad_watch_command(true, watch_type, get_pad_path(),
get_type());
- });
+ main_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
- wnd = Gtk::manage(new Gtk::ScrolledWindow);
+ add_watch_button = Gtk::manage(new Gtk::Button("Add watch"));
+ add_watch_button->signal_clicked().connect([this] {
+ add_watch();
+ });
+ main_box->pack_start(*add_watch_button, false, true);
hooks_tree_view = Gtk::manage(new Gtk::TreeView());
+ wnd = Gtk::manage(new Gtk::ScrolledWindow);
wnd->add(*hooks_tree_view);
+ main_box->pack_start(*wnd, true, true);
hooks_model = Gtk::ListStore::create(hooks_model_columns);
hooks_tree_view->set_model(hooks_model);
- remove_hook_button = Gtk::manage(new Gtk::Button("Remove selected hook"));
- remove_hook_button->signal_clicked().connect([this]{
+ remove_watch_button = Gtk::manage(new Gtk::Button("Remove watch"));
+ main_box->pack_start(*remove_watch_button, false, true);
+ remove_watch_button->signal_clicked().connect([this]{
auto selection = hooks_tree_view->get_selection();
if (!selection) return;
auto iter = selection->get_selected();
if (!iter) return;
- Gtk::TreeModel::Row row = *iter;
- auto type = row[hooks_model_columns.qe_type];
- auto pad_path = (Glib::ustring)row[hooks_model_columns.pad_path];
-
- if ((int)watch_type == -1) // todo
- controller->send_message_request_command(type, false);
- else
- controller->send_pad_watch_command(false, watch_type, pad_path, type);
+ remove_watch(*iter);
});
+
+ create_dispatcher("confirmation", sigc::mem_fun(*this, &ControlModule::confirmation_),
(GDestroyNotify)free_confirmation);
}
- virtual ~HooksControlModule() {}
+ virtual ~ControlModule() {};
- Gtk::Widget* get_widget() override
+ Gtk::Widget* get_widget()
{
- if (main_box == nullptr)
- {
- main_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); // todo possible
memleak
-
- append_hook_widgets();
- }
return main_box;
}
+
+ void set_controller(const std::shared_ptr<Controller> &controller)
+ {
+ IBaseView::set_controller(controller);
+
+ controller->on_confirmation_received.connect([this](const GstDebugger::Command&
command) {
+
+ gui_push("confirmation", new GstDebugger::Command(command));
+ gui_emit("confirmation");
+ });
+ }
};
#endif /* SRC_GST_DEBUGGER_MODULES_CONTROL_MODULE_H_ */
diff --git a/src/gst-debugger/modules/event_module.cpp b/src/gst-debugger/modules/event_module.cpp
new file mode 100644
index 0000000..c8ceaad
--- /dev/null
+++ b/src/gst-debugger/modules/event_module.cpp
@@ -0,0 +1,79 @@
+/*
+ * event_module.cpp
+ *
+ * Created on: Sep 29, 2015
+ * Author: loganek
+ */
+
+#include "event_module.h"
+
+#include "controller/controller.h"
+
+EventModule::EventModule()
+: BaseMainModule(GstDebugger::GStreamerData::kEventInfo, "Events")
+{
+}
+
+void EventModule::load_details(gpointer data)
+{
+ auto evt_info = (GstDebugger::EventInfo*)data;
+
+ append_details_row("event type", Gst::Enums::get_name((Gst::EventType)evt_info->type()));
+ {
+ gchar buffer[20];
+ snprintf(buffer, 20, "%" GST_TIME_FORMAT, GST_TIME_ARGS(evt_info->timestamp()));
+ append_details_row("event timestamp", buffer);
+ }
+ append_details_row("event sequence number", std::to_string(evt_info->seqnum()));
+ append_details_row("sent from pad", evt_info->pad());
+
+ auto structure = Glib::wrap(gst_structure_from_string(evt_info->structure_data().c_str(), NULL),
false);
+ append_details_from_structure(structure);
+}
+
+void EventModule::data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data)
+{
+ row[columns.header] = "Event of type: " +
Gst::Enums::get_name((Gst::EventType)data->event_info().type());
+ row[columns.data] = new GstDebugger::EventInfo(data->event_info());
+}
+
+EventControlModule::EventControlModule()
+: ControlModule(),
+ QEControlModule("GstEventType")
+{
+}
+
+void EventControlModule::add_watch()
+{
+ auto it = types_combobox->get_active();
+ if (it)
+ {
+ Gtk::TreeModel::Row row = *it;
+ controller->send_event_request_command(true, get_pad_path(),
row[types_model_columns.type_id]);
+ }
+}
+
+void EventControlModule::remove_watch(const Gtk::TreeModel::Row& row)
+{
+ Glib::ustring pad = row[hooks_model_columns.str2];
+ controller->send_event_request_command(false, pad, row[hooks_model_columns.int1]);
+}
+
+void EventControlModule::confirmation_received(GstDebugger::Command* cmd)
+{
+ if (!cmd->has_pad_watch() || !cmd->pad_watch().has_event())
+ return;
+
+ auto confirmation = cmd->pad_watch();
+ if (confirmation.action() == GstDebugger::ADD)
+ {
+ Gtk::TreeModel::Row row = *(hooks_model->append());
+ row[hooks_model_columns.str1] =
Gst::Enums::get_name(static_cast<Gst::EventType>(confirmation.event().type()));
+ row[hooks_model_columns.str2] = confirmation.pad();
+ row[hooks_model_columns.int1] = confirmation.event().type();
+ }
+ else
+ {
+ remove_hook(confirmation);
+ }
+}
diff --git a/src/gst-debugger/modules/event_module.h b/src/gst-debugger/modules/event_module.h
new file mode 100644
index 0000000..8cb7cc9
--- /dev/null
+++ b/src/gst-debugger/modules/event_module.h
@@ -0,0 +1,37 @@
+/*
+ * event_module.h
+ *
+ * Created on: Sep 29, 2015
+ * Author: loganek
+ */
+
+#ifndef SRC_GST_DEBUGGER_MODULES_EVENT_MODULE_H_
+#define SRC_GST_DEBUGGER_MODULES_EVENT_MODULE_H_
+
+#include "base_main_module.h"
+#include "control_module.h"
+#include "qe_control_module.h"
+
+class EventModule : public BaseMainModule
+{
+ void data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data) override;
+ void load_details(gpointer data) override;
+
+public:
+ EventModule();
+ virtual ~EventModule() {}
+};
+
+class EventControlModule : virtual public ControlModule, public QEControlModule
+{
+ void confirmation_received(GstDebugger::Command* cmd) override;
+
+ void add_watch() override;
+ void remove_watch(const Gtk::TreeModel::Row& row) override;
+
+public:
+ EventControlModule();
+ virtual ~EventControlModule() {}
+};
+
+#endif /* SRC_GST_DEBUGGER_MODULES_EVENT_MODULE_H_ */
diff --git a/src/gst-debugger/modules/gst_properties_module.cpp
b/src/gst-debugger/modules/gst_properties_module.cpp
index 8950424..9a995d2 100644
--- a/src/gst-debugger/modules/gst_properties_module.cpp
+++ b/src/gst-debugger/modules/gst_properties_module.cpp
@@ -6,7 +6,6 @@
*/
#include "gst_properties_module.h"
-#include "gvalue-converter/gvalue_enum.h"
#include "common/deserializer.h"
#include "controller/command_factory.h"
#include "controller/controller.h"
@@ -15,7 +14,7 @@
#include <gst/gst.h>
-static void free_properties(Property *property) { delete property; }
+static void free_properties(GstDebugger::PropertyInfo *property) { delete property; }
GstPropertiesModule::GstPropertiesModule(const Glib::RefPtr<Gtk::Builder>& builder)
{
@@ -35,9 +34,9 @@ void GstPropertiesModule::set_controller(const std::shared_ptr<Controller> &cont
controller->on_selected_object_changed.connect(sigc::mem_fun(*this,
&GstPropertiesModule::selected_object_changed));
}
-void GstPropertiesModule::new_property(const Property &property)
+void GstPropertiesModule::new_property(const GstDebugger::PropertyInfo &property)
{
- gui_push("property", new Property (property));
+ gui_push("property", new GstDebugger::PropertyInfo(property));
gui_emit("property");
}
@@ -66,15 +65,15 @@ void GstPropertiesModule::showPropertiesButton_clicked_cb()
void GstPropertiesModule::new_property_()
{
- auto property = gui_pop<Property*>("property");
+ auto property = gui_pop<GstDebugger::PropertyInfo*>("property");
- auto element =
std::dynamic_pointer_cast<ElementModel>(ElementPathProcessor(property->element_path()).get_last_obj());
+ auto element =
std::dynamic_pointer_cast<ElementModel>(ElementPathProcessor(property->object()).get_last_obj());
if (!element)
{
return;
}
- std::shared_ptr<GValueBase> value_base = element->get_property(property->property_name());
+ /* todo std::shared_ptr<GValueBase> value_base = element->get_property(property->name());
std::shared_ptr<GValueEnum> value_enum = std::dynamic_pointer_cast<GValueEnum>(value_base);
auto& container = const_cast<RemoteDataContainer<GstEnumType>&>(controller->get_enum_container());
@@ -86,11 +85,11 @@ void GstPropertiesModule::new_property_()
if (!update_property(value_base, property))
{
append_property(value_base, property);
- }
+ }*/
delete property;
}
-bool GstPropertiesModule::update_property(const std::shared_ptr<GValueBase>& value_base, Property *property)
+/*bool GstPropertiesModule::update_property(const std::shared_ptr<GValueBase>& value_base,
GstDebugger::PropertyInfo *property)
{
for (auto internal_box : properties_box->get_children())
{
@@ -107,7 +106,7 @@ bool GstPropertiesModule::update_property(const std::shared_ptr<GValueBase>& val
{
if (label == nullptr && (label = dynamic_cast<Gtk::Label*>(cd)) != nullptr)
{
- if (label->get_text() != property->property_name())
+ if (label->get_text() != property->name())
{
label = nullptr;
break;
@@ -133,15 +132,15 @@ bool GstPropertiesModule::update_property(const std::shared_ptr<GValueBase>& val
}
return false;
-}
-
-void GstPropertiesModule::append_property(const std::shared_ptr<GValueBase>& value_base, Property *property)
+}*/
+/*
+void GstPropertiesModule::append_property(const std::shared_ptr<GValueBase>& value_base,
GstDebugger::PropertyInfo *property)
{
Gtk::Box *hbox = new Gtk::Box (Gtk::ORIENTATION_HORIZONTAL, 0);
hbox->show();
- auto prop_name = property->property_name();
+ auto prop_name = property->name();
Gtk::Label *lbl = Gtk::manage(new Gtk::Label(prop_name));
- lbl->set_tooltip_text(property->description());
+ lbl->set_tooltip_text(property->blurb());
lbl->show();
Gtk::Button *btn = Gtk::manage(new Gtk::Button("Refresh"));
btn->signal_clicked().connect([this, prop_name] {request_selected_element_property(prop_name);});
@@ -154,7 +153,7 @@ void GstPropertiesModule::append_property(const std::shared_ptr<GValueBase>& val
hbox->pack_start(*btn, false, false);
properties_box->pack_start(*hbox);
}
-
+*/
void GstPropertiesModule::clear_widgets()
{
for (auto c : properties_box->get_children())
diff --git a/src/gst-debugger/modules/gst_properties_module.h
b/src/gst-debugger/modules/gst_properties_module.h
index 1ee25eb..9b72ca7 100644
--- a/src/gst-debugger/modules/gst_properties_module.h
+++ b/src/gst-debugger/modules/gst_properties_module.h
@@ -25,13 +25,13 @@ private:
std::string previous_element_path;
- void append_property(const std::shared_ptr<GValueBase>& value_base, Property *property);
- bool update_property(const std::shared_ptr<GValueBase>& value_base, Property *property);
+// void append_property(const std::shared_ptr<GValueBase>& value_base, GstDebugger::PropertyInfo
*property);
+// bool update_property(const std::shared_ptr<GValueBase>& value_base, GstDebugger::PropertyInfo
*property);
void request_selected_element_property(const std::string &property_name);
void show_pad_properties();
- void new_property(const Property& property);
+ void new_property(const GstDebugger::PropertyInfo& property);
void new_property_();
void selected_object_changed();
diff --git a/src/gst-debugger/modules/log_module.cpp b/src/gst-debugger/modules/log_module.cpp
index a6b101e..b6cab95 100644
--- a/src/gst-debugger/modules/log_module.cpp
+++ b/src/gst-debugger/modules/log_module.cpp
@@ -9,64 +9,33 @@
#include "controller/controller.h"
-static void free_log(GstreamerLog *log) { delete log; }
-
LogModule::LogModule()
+: BaseMainModule(GstDebugger::GStreamerData::kLogInfo, "logs")
{
- model = Gtk::ListStore::create(columns);
-
- create_dispatcher("new-log", sigc::mem_fun(*this, &LogModule::log_received_),
(GDestroyNotify)free_log);
-}
-
-void LogModule::configure_main_list_view(Gtk::TreeView *view)
-{
- BaseMainModule::configure_main_list_view(view);
- view->append_column("Logs", columns.header);
}
-void LogModule::load_details(Gtk::TreeView *view, const Gtk::TreeModel::Path &path)
+void LogModule::load_details(gpointer data)
{
- BaseMainModule::load_details(view, path);
-
- Gtk::TreeModel::iterator iter = filter->get_iter(path);
- if (!iter)
- {
- return;
- }
-
- Gtk::TreeModel::Row row = *iter;
- auto log_info = (GstreamerLog*)row[columns.log];
+ auto log_info = (GstDebugger::LogInfo*)data;
append_details_row("Level", std::to_string(log_info->level()));
- append_details_row("Category name", log_info->category_name());
+ append_details_row("Category name", log_info->category());
append_details_row("File", log_info->file());
append_details_row("Function", log_info->function());
append_details_row("Line", std::to_string(log_info->line()));
- append_details_row("Object path", log_info->object_path());
+ append_details_row("Object path", log_info->object());
append_details_row("Message", log_info->message());
}
-void LogModule::set_controller(const std::shared_ptr<Controller> &controller)
+void LogModule::data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data)
{
- BaseMainModule::set_controller(controller);
-
- controller->on_log_received.connect([this] (const GstreamerLog &log) {
- gui_push("new-log", new GstreamerLog (log));
- gui_emit("new-log");
- });
-}
-
-void LogModule::log_received_()
-{
- auto log = gui_pop<GstreamerLog*>("new-log");
- Gtk::TreeModel::Row row = *(model->append());
- row[columns.header] = log->function();
- row[columns.log] = log;
+ row[columns.header] = data->log_info().function();
+ row[columns.data] = new GstDebugger::LogInfo(data->log_info());
}
bool LogModule::filter_function(const Gtk::TreeModel::const_iterator& it)
{
- if (!filter_expression)
+/* if (!filter_expression)
return true;
auto log = it->get_value(columns.log);
@@ -102,22 +71,24 @@ bool LogModule::filter_function(const Gtk::TreeModel::const_iterator& it)
MAKE_FIELD_FILTER("function", function, TokenString);
MAKE_FIELD_FILTER("object_path", object_path, TokenString);
MAKE_FIELD_FILTER("message", message, TokenString);
-
+*/
return true;
}
LogControlModule::LogControlModule()
+: ControlModule()
{
- main_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
+ auto lbl = Gtk::manage(new Gtk::Label("Debug categories"));
+ main_box->pack_start(*lbl, false, true);
+ main_box->reorder_child(*lbl, 0);
- set_watch_button = Gtk::manage(new Gtk::CheckButton("Watch log messages"));
- set_watch_button->signal_toggled().connect([this] {
- controller->send_set_log_watch_command(set_watch_button->get_active(), 10); // todo log level
- });
- main_box->pack_start(*set_watch_button, false, true);
+ debug_categories_combobox = Gtk::manage(new Gtk::ComboBoxText());
+ main_box->pack_start(*debug_categories_combobox, false, true);
+ main_box->reorder_child(*debug_categories_combobox, 1);
- main_box->pack_start(*Gtk::manage(new Gtk::Label("Debug categories")), false, true);
- main_box->pack_start(*Gtk::manage(new Gtk::ComboBox()), false, true);
+ log_level_entry = Gtk::manage(new Gtk::Entry());
+ main_box->pack_start(*log_level_entry, false, true);
+ main_box->reorder_child(*log_level_entry, 0);
main_box->pack_start(*Gtk::manage(new Gtk::Label("Log threshold:")), false, true);
@@ -133,9 +104,54 @@ LogControlModule::LogControlModule()
overwrite_threshold_check_button->get_active());
});
main_box->pack_start(*set_threshold_button, false, true);
+
+ hooks_tree_view->append_column("Level", hooks_model_columns.str1);
+ hooks_tree_view->append_column("Category", hooks_model_columns.str2);
}
-Gtk::Widget* LogControlModule::get_widget()
+void LogControlModule::set_controller(const std::shared_ptr<Controller> &controller)
{
- return main_box;
+ ControlModule::set_controller(controller);
+
+ controller->on_debug_categories_changed.connect([this] {
+ debug_categories_combobox->remove_all();
+ for (auto c : this->controller->get_debug_categories())
+ {
+ debug_categories_combobox->append(c);
+ }
+ if (!this->controller->get_debug_categories().empty())
+ debug_categories_combobox->set_active(0);
+ });
+}
+
+void LogControlModule::add_watch()
+{
+ controller->send_set_log_watch_command(true, debug_categories_combobox->get_active_text(),
+ atoi(log_level_entry->get_text().c_str()));
+}
+
+void LogControlModule::remove_watch(const Gtk::TreeModel::Row& row)
+{
+ Glib::ustring category = row[hooks_model_columns.str2];
+ int level = row[hooks_model_columns.int1];
+ controller->send_set_log_watch_command(false, category, level);
+}
+
+void LogControlModule::confirmation_received(GstDebugger::Command* cmd)
+{
+ if (!cmd->has_log())
+ return;
+
+ auto confirmation = cmd->log();
+ if (confirmation.action() == GstDebugger::ADD)
+ {
+ Gtk::TreeModel::Row row = *(hooks_model->append());
+ row[hooks_model_columns.str1] = gst_debug_level_get_name
(static_cast<GstDebugLevel>(confirmation.level()));
+ row[hooks_model_columns.int1] = confirmation.level();
+ row[hooks_model_columns.str2] = confirmation.category();
+ }
+ else
+ {
+ remove_hook(confirmation);
+ }
}
diff --git a/src/gst-debugger/modules/log_module.h b/src/gst-debugger/modules/log_module.h
index 048bacb..7c39163 100644
--- a/src/gst-debugger/modules/log_module.h
+++ b/src/gst-debugger/modules/log_module.h
@@ -11,24 +11,10 @@
#include "base_main_module.h"
#include "control_module.h"
-class GstreamerLog;
-
-class LogModelColumns : public Gtk::TreeModel::ColumnRecord
-{
-public:
- LogModelColumns() {
- add(header); add(log);
- }
-
- Gtk::TreeModelColumn<Glib::ustring> header;
- Gtk::TreeModelColumn<GstreamerLog*> log;
-};
-
class LogModule : public BaseMainModule
{
- void log_received_();
-
- LogModelColumns columns;
+ void data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data) override;
+ void load_details(gpointer data) override;
protected:
bool filter_function(const Gtk::TreeModel::const_iterator& it) override;
@@ -36,26 +22,32 @@ protected:
public:
LogModule();
virtual ~LogModule() {}
-
- void configure_main_list_view(Gtk::TreeView *view) override;
- void load_details(Gtk::TreeView *view, const Gtk::TreeModel::Path &path) override;
-
- void set_controller(const std::shared_ptr<Controller> &controller) override;
};
class LogControlModule : public ControlModule
{
- Gtk::Box *main_box;
- Gtk::CheckButton *set_watch_button;
Gtk::CheckButton *overwrite_threshold_check_button;
+ Gtk::Entry *log_level_entry;
+ Gtk::ComboBoxText *debug_categories_combobox;
Gtk::Button *set_threshold_button;
Gtk::Entry *threshold_entry;
+ void add_watch() override;
+ void remove_watch(const Gtk::TreeModel::Row& row) override;
+ void confirmation_received(GstDebugger::Command* cmd) override;
+
+ bool hook_is_the_same(const Gtk::TreeModel::Row& row, gconstpointer confirmation) override
+ {
+ auto log = reinterpret_cast<const GstDebugger::LogRequest*>(confirmation);
+ return row[hooks_model_columns.int1] == log->level() &&
+ row[hooks_model_columns.str2] == log->category();
+ }
+
public:
LogControlModule();
virtual ~LogControlModule() {}
- Gtk::Widget* get_widget() override;
+ void set_controller(const std::shared_ptr<Controller> &controller) override;
};
#endif /* SRC_GST_DEBUGGER_MODULES_LOG_MODULE_H_ */
diff --git a/src/gst-debugger/modules/main_module.cpp b/src/gst-debugger/modules/main_module.cpp
index 93a1901..d90eabd 100644
--- a/src/gst-debugger/modules/main_module.cpp
+++ b/src/gst-debugger/modules/main_module.cpp
@@ -7,10 +7,12 @@
#include "main_module.h"
-#include "pad_data_modules.h"
+//#include "pad_data_modules.h"
#include "log_module.h"
-#include "bus_messages_module.h"
-#include "pad_path_types_control_module.h"
+#include "message_module.h"
+#include "event_module.h"
+#include "query_module.h"
+//#include "pad_path_types_control_module.h"
#include "controller/controller.h"
#include "controller/element_path_processor.h"
@@ -40,16 +42,16 @@ void MainModule::load_submodules(const Glib::RefPtr<Gtk::Builder>& builder)
submodules["logMessages"].control_module = std::make_shared<LogControlModule>();
submodules["queries"].display_module = std::make_shared<QueryModule>();
- submodules["queries"].control_module = std::make_shared<PadPathTypesControlModule>("GstQueryType",
PadWatch_WatchType_QUERY);
+ submodules["queries"].control_module = std::make_shared<QueryControlModule>();
- submodules["busMessages"].display_module = std::make_shared<BusMessagesModule>();
- submodules["busMessages"].control_module = std::make_shared<TypesControlModule>("GstMessageType",
(PadWatch_WatchType)-1);
+ submodules["busMessages"].display_module = std::make_shared<MessageModule>();
+ submodules["busMessages"].control_module = std::make_shared<MessageControlModule>();
- submodules["buffers"].display_module = std::make_shared<BufferModule>();
+ /*submodules["buffers"].display_module = std::make_shared<BufferModule>();
submodules["buffers"].control_module =
std::make_shared<PadPathControlModule>(PadWatch_WatchType_BUFFER);
-
+*/
submodules["events"].display_module = std::make_shared<EventModule>();
- submodules["events"].control_module = std::make_shared<PadPathTypesControlModule>("GstEventType",
PadWatch_WatchType_EVENT);
+ submodules["events"].control_module = std::make_shared<EventControlModule>();
for (auto m : submodules)
{
@@ -69,7 +71,7 @@ void MainModule::set_controller(const std::shared_ptr<Controller> &controller)
{
IBaseView::set_controller(controller);
- controller->on_selected_object_changed.connect([this]{gui_emit("selected-object");});
+ //controller->on_selected_object_changed.connect([this]{gui_emit("selected-object");});
for (auto m : submodules)
{
diff --git a/src/gst-debugger/modules/message_module.cpp b/src/gst-debugger/modules/message_module.cpp
new file mode 100644
index 0000000..c0e8a8a
--- /dev/null
+++ b/src/gst-debugger/modules/message_module.cpp
@@ -0,0 +1,113 @@
+/*
+ * message_module.cpp
+ *
+ * Created on: Sep 27, 2015
+ * Author: loganek
+ */
+
+#include "message_module.h"
+
+#include "controller/controller.h"
+
+MessageModule::MessageModule()
+: BaseMainModule(GstDebugger::GStreamerData::kMessageInfo, "Messages")
+{
+}
+
+void MessageModule::load_details(gpointer data)
+{
+ auto msg_info = (GstDebugger::MessageInfo*)data;
+
+ append_details_row("message type", Gst::Enums::get_name((Gst::MessageType)msg_info->type()));
+ {
+ gchar buffer[20];
+ snprintf(buffer, 20, "%" GST_TIME_FORMAT, GST_TIME_ARGS(msg_info->timestamp()));
+ append_details_row("message timestamp", buffer);
+ }
+ append_details_row("message sequence number", std::to_string(msg_info->seqnum()));
+ append_details_row("object", "todo"); // todo
+
+ auto structure = Glib::wrap(gst_structure_from_string(msg_info->structure_data().c_str(), NULL),
false);
+ append_details_from_structure(structure);
+}
+
+void MessageModule::data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data)
+{
+ row[columns.header] = "Message of type: " +
Gst::Enums::get_name((Gst::MessageType)data->message_info().type());
+ row[columns.data] = new GstDebugger::MessageInfo(data->message_info());
+}
+
+
+MessageControlModule::MessageControlModule()
+: ControlModule()
+{
+ types_combobox = Gtk::manage(new Gtk::ComboBox());
+ types_model = Gtk::ListStore::create(types_model_columns);
+ types_combobox->set_model(types_model);
+ types_combobox->pack_start(types_model_columns.type_name);
+
+ main_box->pack_start(*types_combobox, false, true);
+ main_box->reorder_child(*types_combobox, 0);
+
+ hooks_tree_view->append_column("Type", hooks_model_columns.str1);
+}
+
+void MessageControlModule::add_watch()
+{
+ auto it = types_combobox->get_active();
+ if (it)
+ {
+ Gtk::TreeModel::Row row = *it;
+ controller->send_message_request_command(row[types_model_columns.type_id], true);
+ }
+}
+
+void MessageControlModule::remove_watch(const Gtk::TreeModel::Row& row)
+{
+ controller->send_message_request_command(row[hooks_model_columns.int1], false);
+}
+
+void MessageControlModule::set_controller(const std::shared_ptr<Controller> &controller)
+{
+ ControlModule::set_controller(controller);
+
+ controller->on_enum_list_changed.connect([this](const Glib::ustring& name, bool add) {
+ if (name != "GstMessageType")
+ return;
+ types_model->clear();
+ if (add)
+ {
+ boost::optional<GstEnumType> type = this->controller->get_enum_type(name);
+ if (!type)
+ return;
+
+ for (auto t : type.get().get_values())
+ {
+ Gtk::TreeModel::Row row = *(types_model->append());
+ row[types_model_columns.type_id] = t.first;
+ row[types_model_columns.type_name] = t.second.name;
+ }
+
+ if (!type.get().get_values().empty())
+ types_combobox->set_active(0);
+ }
+ });
+}
+
+void MessageControlModule::confirmation_received(GstDebugger::Command* cmd)
+{
+ if (!cmd->has_message())
+ return;
+
+ auto confirmation = cmd->message();
+ if (confirmation.action() == GstDebugger::ADD)
+ {
+ Gtk::TreeModel::Row row = *(hooks_model->append());
+ row[hooks_model_columns.str1] =
Gst::Enums::get_name(static_cast<Gst::MessageType>(confirmation.type()));
+ row[hooks_model_columns.int1] = confirmation.type();
+ }
+ else
+ {
+ remove_hook(confirmation);
+ }
+}
diff --git a/src/gst-debugger/modules/message_module.h b/src/gst-debugger/modules/message_module.h
new file mode 100644
index 0000000..71c5f23
--- /dev/null
+++ b/src/gst-debugger/modules/message_module.h
@@ -0,0 +1,50 @@
+/*
+ * message_module.h
+ *
+ * Created on: Sep 27, 2015
+ * Author: loganek
+ */
+
+#ifndef SRC_GST_DEBUGGER_MODULES_MESSAGE_MODULE_H_
+#define SRC_GST_DEBUGGER_MODULES_MESSAGE_MODULE_H_
+
+#include "base_main_module.h"
+#include "control_module.h"
+
+class MessageModule : public BaseMainModule
+{
+ void data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data) override;
+ void load_details(gpointer data) override;
+
+public:
+ MessageModule();
+ virtual ~MessageModule() {}
+};
+
+class MessageControlModule : public ControlModule
+{
+ TypesModelColumns types_model_columns;
+ Glib::RefPtr<Gtk::ListStore> types_model;
+ std::string type_name;
+
+ Gtk::ComboBox *types_combobox;
+
+ void confirmation_received(GstDebugger::Command* cmd) override;
+
+ void add_watch() override;
+ void remove_watch(const Gtk::TreeModel::Row& row) override;
+
+ bool hook_is_the_same(const Gtk::TreeModel::Row& row, gconstpointer confirmation) override
+ {
+ auto message = reinterpret_cast<const GstDebugger::MessageRequest*>(confirmation);
+ return row[hooks_model_columns.int1] == message->type();
+ }
+
+public:
+ MessageControlModule();
+ virtual ~MessageControlModule() {}
+
+ void set_controller(const std::shared_ptr<Controller> &controller) override;
+};
+
+#endif /* SRC_GST_DEBUGGER_MODULES_MESSAGE_MODULE_H_ */
diff --git a/src/gst-debugger/modules/qe_control_module.h b/src/gst-debugger/modules/qe_control_module.h
new file mode 100644
index 0000000..6f153cd
--- /dev/null
+++ b/src/gst-debugger/modules/qe_control_module.h
@@ -0,0 +1,99 @@
+/*
+ * qe_control_module.h
+ *
+ * Created on: Sep 29, 2015
+ * Author: loganek
+ */
+
+#ifndef SRC_GST_DEBUGGER_MODULES_QE_CONTROL_MODULE_H_
+#define SRC_GST_DEBUGGER_MODULES_QE_CONTROL_MODULE_H_
+
+#include "control_module.h"
+
+#include "controller/element_path_processor.h"
+
+class QEControlModule : virtual public ControlModule
+{
+ const std::string enum_name;
+
+protected:
+ TypesModelColumns types_model_columns;
+ Glib::RefPtr<Gtk::ListStore> types_model;
+
+ Gtk::Label *pad_path_label;
+ Gtk::ComboBox *types_combobox;
+
+ std::string get_pad_path() const
+ {
+ auto obj = controller->get_selected_object();
+
+ return (obj && std::dynamic_pointer_cast<PadModel>(obj)) ?
+ ElementPathProcessor::get_object_path(obj) :
+ std::string();
+ }
+
+ bool hook_is_the_same(const Gtk::TreeModel::Row& row, gconstpointer confirmation) override
+ {
+ auto pad = reinterpret_cast<const GstDebugger::PadWatchRequest*>(confirmation);
+ return row[hooks_model_columns.int1] == pad->event().type() && row[hooks_model_columns.str2]
== pad->pad();
+ }
+
+public:
+ QEControlModule(const std::string& enum_name)
+ : enum_name(enum_name)
+ {
+ pad_path_label = Gtk::manage(new Gtk::Label());
+ main_box->pack_start(*pad_path_label, false, true);
+ main_box->reorder_child(*pad_path_label, 0);
+
+ types_combobox = Gtk::manage(new Gtk::ComboBox());
+ types_model = Gtk::ListStore::create(types_model_columns);
+ types_combobox->set_model(types_model);
+ types_combobox->pack_start(types_model_columns.type_name);
+ main_box->pack_start(*types_combobox, false, true);
+ main_box->reorder_child(*types_combobox, 0);
+
+ hooks_tree_view->append_column("Type", hooks_model_columns.str1);
+ hooks_tree_view->append_column("Pad", hooks_model_columns.str2);
+
+ create_dispatcher("selected-object", [this] {
+ auto pad_path = get_pad_path();
+ if (pad_path.empty())
+ pad_path = "none (any path)";
+ pad_path_label->set_text(pad_path);
+ }, nullptr);
+ }
+
+ void set_controller(const std::shared_ptr<Controller> &controller) override
+ {
+ ControlModule::set_controller(controller);
+
+ controller->on_selected_object_changed.connect([this](){
+ gui_emit("selected-object");
+ });
+
+ controller->on_enum_list_changed.connect([this](const Glib::ustring& name, bool add) {
+ if (name != enum_name)
+ return;
+ types_model->clear();
+ if (add)
+ {
+ boost::optional<GstEnumType> type = this->controller->get_enum_type(name);
+ if (!type)
+ return;
+
+ for (auto t : type.get().get_values())
+ {
+ Gtk::TreeModel::Row row = *(types_model->append());
+ row[types_model_columns.type_id] = t.first;
+ row[types_model_columns.type_name] = t.second.name;
+ }
+
+ if (!type.get().get_values().empty())
+ types_combobox->set_active(0);
+ }
+ });
+ }
+};
+
+#endif /* SRC_GST_DEBUGGER_MODULES_QE_CONTROL_MODULE_H_ */
diff --git a/src/gst-debugger/modules/query_module.cpp b/src/gst-debugger/modules/query_module.cpp
new file mode 100644
index 0000000..1c83ce2
--- /dev/null
+++ b/src/gst-debugger/modules/query_module.cpp
@@ -0,0 +1,73 @@
+/*
+ * query_module.cpp
+ *
+ * Created on: Sep 29, 2015
+ * Author: loganek
+ */
+
+#include "query_module.h"
+
+#include "controller/controller.h"
+
+QueryModule::QueryModule()
+: BaseMainModule(GstDebugger::GStreamerData::kQueryInfo, "Queries")
+{
+}
+
+void QueryModule::load_details(gpointer data)
+{
+ auto query_info = (GstDebugger::QueryInfo*)data;
+
+ append_details_row("query type", Gst::Enums::get_name((Gst::QueryType)query_info->type()));
+ append_details_row("sent from pad", query_info->pad());
+
+ auto structure = Glib::wrap(gst_structure_from_string(query_info->structure_data().c_str(), NULL),
false);
+ append_details_from_structure(structure);
+}
+
+void QueryModule::data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data)
+{
+ row[columns.header] = "Query of type: " +
Gst::Enums::get_name((Gst::QueryType)data->query_info().type());
+ row[columns.data] = new GstDebugger::QueryInfo(data->query_info());
+}
+
+QueryControlModule::QueryControlModule()
+: ControlModule(),
+ QEControlModule("GstQueryType")
+{
+}
+
+void QueryControlModule::add_watch()
+{
+ auto it = types_combobox->get_active();
+ if (it)
+ {
+ Gtk::TreeModel::Row row = *it;
+ controller->send_query_request_command(true, get_pad_path(),
row[types_model_columns.type_id]);
+ }
+}
+
+void QueryControlModule::remove_watch(const Gtk::TreeModel::Row& row)
+{
+ Glib::ustring pad = row[hooks_model_columns.str2];
+ controller->send_query_request_command(false, pad, row[hooks_model_columns.int1]);
+}
+
+void QueryControlModule::confirmation_received(GstDebugger::Command* cmd)
+{
+ if (!cmd->has_pad_watch() || !cmd->pad_watch().has_query())
+ return;
+
+ auto confirmation = cmd->pad_watch();
+ if (confirmation.action() == GstDebugger::ADD)
+ {
+ Gtk::TreeModel::Row row = *(hooks_model->append());
+ row[hooks_model_columns.str1] =
Gst::Enums::get_name(static_cast<Gst::QueryType>(confirmation.query().type()));
+ row[hooks_model_columns.str2] = confirmation.pad();
+ row[hooks_model_columns.int1] = confirmation.query().type();
+ }
+ else
+ {
+ remove_hook(confirmation);
+ }
+}
diff --git a/src/gst-debugger/modules/query_module.h b/src/gst-debugger/modules/query_module.h
new file mode 100644
index 0000000..35c698a
--- /dev/null
+++ b/src/gst-debugger/modules/query_module.h
@@ -0,0 +1,37 @@
+/*
+ * query_module.h
+ *
+ * Created on: Sep 29, 2015
+ * Author: loganek
+ */
+
+#ifndef SRC_GST_DEBUGGER_MODULES_QUERY_MODULE_H_
+#define SRC_GST_DEBUGGER_MODULES_QUERY_MODULE_H_
+
+#include "base_main_module.h"
+#include "control_module.h"
+#include "qe_control_module.h"
+
+class QueryModule : public BaseMainModule
+{
+ void data_received(const Gtk::TreeModel::Row& row, GstDebugger::GStreamerData *data) override;
+ void load_details(gpointer data) override;
+
+public:
+ QueryModule();
+ virtual ~QueryModule() {}
+};
+
+class QueryControlModule : virtual public ControlModule, public QEControlModule
+{
+ void confirmation_received(GstDebugger::Command* cmd) override;
+
+ void add_watch() override;
+ void remove_watch(const Gtk::TreeModel::Row& row) override;
+
+public:
+ QueryControlModule();
+ virtual ~QueryControlModule() {}
+};
+
+#endif /* SRC_GST_DEBUGGER_MODULES_QUERY_MODULE_H_ */
diff --git a/src/gst-debugger/pipeline-drawer/graph_module.cpp
b/src/gst-debugger/pipeline-drawer/graph_module.cpp
index 37cb5d2..56a7586 100644
--- a/src/gst-debugger/pipeline-drawer/graph_module.cpp
+++ b/src/gst-debugger/pipeline-drawer/graph_module.cpp
@@ -300,5 +300,5 @@ void GraphModule::update_model_()
void GraphModule::refreshGraphButton_clicked_cb()
{
- controller->send_request_topology_command();
+ controller->send_request_entire_topology_command();
}
diff --git a/src/gst-debugger/ui/gst-debugger.glade b/src/gst-debugger/ui/gst-debugger.glade
index 65c746a..8ab3e52 100644
--- a/src/gst-debugger/ui/gst-debugger.glade
+++ b/src/gst-debugger/ui/gst-debugger.glade
@@ -303,16 +303,13 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
+ <property name="label_yalign">0</property>
<property name="shadow_type">none</property>
<child>
<placeholder/>
</child>
- <child type="label">
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Controller</property>
- </object>
+ <child type="label_item">
+ <placeholder/>
</child>
</object>
<packing>
diff --git a/src/gst-debugger/ui_utils.cpp b/src/gst-debugger/ui_utils.cpp
index d2d6144..02f3579 100644
--- a/src/gst-debugger/ui_utils.cpp
+++ b/src/gst-debugger/ui_utils.cpp
@@ -98,7 +98,7 @@ void display_caps(const Glib::RefPtr<Gst::Caps> &caps,
#undef APPEND_SUB_ROW
-Glib::RefPtr<Gst::PadTemplate> protocol_template_to_gst_template(const TopologyTemplate &tpl)
+Glib::RefPtr<Gst::PadTemplate> protocol_template_to_gst_template(const GstDebugger::PadTemplate &tpl)
{
return Gst::PadTemplate::create(tpl.name_template(),
static_cast<Gst::PadDirection>(tpl.direction()),
diff --git a/src/gst-debugger/ui_utils.h b/src/gst-debugger/ui_utils.h
index 0a7f76d..e763a43 100644
--- a/src/gst-debugger/ui_utils.h
+++ b/src/gst-debugger/ui_utils.h
@@ -36,7 +36,7 @@ void display_caps(const Glib::RefPtr<Gst::Caps> &caps,
const Glib::RefPtr<Gtk::TreeStore> &model, const Gtk::TreeModelColumn<Glib::ustring>
&col_name,
const Gtk::TreeModelColumn<Glib::ustring> &col_value, const Gtk::TreeModel::Row& parent_row);
-Glib::RefPtr<Gst::PadTemplate> protocol_template_to_gst_template(const TopologyTemplate &tpl);
+Glib::RefPtr<Gst::PadTemplate> protocol_template_to_gst_template(const GstDebugger::PadTemplate &tpl);
std::string flags_value_to_string(guint value);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]