From e3d98689490c8b4f68a1de73c960ac89cfaa0064 Mon Sep 17 00:00:00 2001 From: dawidwesierski4 Date: Mon, 27 Jan 2025 15:20:32 +0100 Subject: [PATCH] Add: MTL common handle support in GStreamer - Add ability to use the same MTL instance for multiple GStreamer plugin instances in the same pipeline. - Change the default behavior of the MTL GStreamer plugins to make all subsequent plugins ignore dev arguments after the first one. After this change only one MTL library process is spawned per pipeline. - Add a new module called gst_common to hold the address of the MTL instance. - Update documentation to include a warning about the behavior change. --- ecosystem/gstreamer_plugin/README.md | 5 ++- ecosystem/gstreamer_plugin/gst_mtl_common.c | 41 +++++++++++++++---- ecosystem/gstreamer_plugin/gst_mtl_common.h | 4 +- ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c | 3 +- ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c | 4 +- ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c | 3 +- ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c | 4 +- ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c | 3 +- ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c | 4 +- 9 files changed, 44 insertions(+), 27 deletions(-) diff --git a/ecosystem/gstreamer_plugin/README.md b/ecosystem/gstreamer_plugin/README.md index d8aaf1aa..74e41f31 100644 --- a/ecosystem/gstreamer_plugin/README.md +++ b/ecosystem/gstreamer_plugin/README.md @@ -101,7 +101,7 @@ In MTL GStreamer plugins there are general arguments that apply to every plugin. | udp-port | uint | Receiving MTL node UDP port. | 0 to G_MAXUINT | | tx-queues | uint | Number of TX queues to initialize in DPDK backend. | 0 to G_MAXUINT | | rx-queues | uint | Number of RX queues to initialize in DPDK backend. | 0 to G_MAXUINT | -| payload-type | uint | SMPTE ST 2110 payload type. | 0 to G_MAXUINT | +| payload-type | uint | SMPTE ST 2110 payload type. | 0 to G_MAXUINT | These are also general parameters accepted by plugins, but the functionality they provide to the user is not yet supported in plugins. | Property Name | Type | Description | Range | @@ -109,6 +109,9 @@ These are also general parameters accepted by plugins, but the functionality the | dma-dev | string | **RESERVED FOR FUTURE USE** port for the MTL direct memory functionality. | N/A | | port | string | **RESERVED FOR FUTURE USE** DPDK device port. Utilized when multiple ports are passed to the MTL library to select the port for the session. | N/A | +> **Warning:** +> Generally, the `log-level`, `dev-port`, `dev-ip`, `tx-queues`, and `rx-queues` are used to initialize the MTL library. As the MTL library handle is shared between MTL GStreamer plugins of the same pipeline, you only need to pass them once when specifying the arguments for the first pipeline. Nothing happens when you specify them elsewhere; they will just be ignored after the initialization of MTL has already happened. + ### 2.3. General capabilities Some structures describe the capabilities generally diff --git a/ecosystem/gstreamer_plugin/gst_mtl_common.c b/ecosystem/gstreamer_plugin/gst_mtl_common.c index b79195f6..6a22c541 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_common.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_common.c @@ -395,18 +395,35 @@ gboolean gst_mtl_common_parse_dev_arguments(struct mtl_init_params* mtl_init_par return ret; } -mtl_handle gst_mtl_common_init_handle(struct mtl_init_params* p, StDevArgs* devArgs, - guint* log_level, gboolean force_to_initialize_new) { +/** + * Initializes the device with the given parameters. + * + * If the common handle (MTL instance already initialized in the pipeline) + * is already in use, the input parameters for the device + * (rx_queues, tx_queues, dev_ip, dev_port, and log_level) will be ignored. + * You can force to initialize another MTL instance to avoid this behavior with + * force_to_initialize_new_instance flag. + * + * @param force_to_initialize_new_instance Force the creation of a new MTL + * instance, ignoring any existing one. + * @param devArgs Initialization parameters for the DPDK port + * (ignored if using an existing MTL instance). + * @param log_level Log level for the library (ignored if using an + * existing MTL instance). + */ +mtl_handle gst_mtl_common_init_handle(StDevArgs* devArgs, guint* log_level, + gboolean force_to_initialize_new_instance) { struct mtl_init_params mtl_init_params = {0}; - if (!p || !devArgs || !log_level) { - GST_ERROR("Invalid input"); - return NULL; + if (!force_to_initialize_new_instance && gst_mtl_common_shared_handle) { + GST_INFO("Mtl is already initialized with shared handle %p", + gst_mtl_common_shared_handle); + return gst_mtl_common_shared_handle; } - if (gst_mtl_common_shared_handle) { - GST_INFO("Mtl is already initialized with shared handle %p", gst_mtl_common_shared_handle); - return gst_mtl_common_shared_handle; + if (!devArgs || !log_level) { + GST_ERROR("Invalid input"); + return NULL; } mtl_init_params.num_ports = 0; @@ -429,5 +446,11 @@ mtl_handle gst_mtl_common_init_handle(struct mtl_init_params* p, StDevArgs* devA } *log_level = mtl_init_params.log_level; - return mtl_init(&mtl_init_params); + if (!gst_mtl_common_shared_handle) { + gst_mtl_common_shared_handle = mtl_init(&mtl_init_params); + return gst_mtl_common_shared_handle; + } else { + GST_INFO("MTL shared handle %p ignored", gst_mtl_common_shared_handle); + return mtl_init(&mtl_init_params); + } } diff --git a/ecosystem/gstreamer_plugin/gst_mtl_common.h b/ecosystem/gstreamer_plugin/gst_mtl_common.h index f297806a..f23b1333 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_common.h +++ b/ecosystem/gstreamer_plugin/gst_mtl_common.h @@ -101,7 +101,7 @@ void gst_mtl_common_get_general_arguments(GObject* object, guint prop_id, StDevArgs* devArgs, SessionPortArgs* portArgs, guint* log_level); -mtl_handle gst_mtl_common_init_handle(struct mtl_init_params* p, StDevArgs* devArgs, - guint* log_level, gboolean force_to_initialize_new); +mtl_handle gst_mtl_common_init_handle(StDevArgs* devArgs, guint* log_level, + gboolean force_to_initialize_new_instance); #endif /* __GST_MTL_COMMON_H__ */ \ No newline at end of file diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c b/ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c index e63b7afc..cafe5c07 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c @@ -197,7 +197,6 @@ static void gst_mtl_st20p_rx_class_init(Gst_Mtl_St20p_RxClass* klass) { } static gboolean gst_mtl_st20p_rx_start(GstBaseSrc* basesrc) { - struct mtl_init_params mtl_init_params = {0}; struct st20p_rx_ops* ops_rx; gint ret; @@ -208,7 +207,7 @@ static gboolean gst_mtl_st20p_rx_start(GstBaseSrc* basesrc) { GST_DEBUG("Media Transport Initialization start"); src->mtl_lib_handle = - gst_mtl_common_init_handle(&mtl_init_params, &(src->devArgs), &(src->log_level), FALSE); + gst_mtl_common_init_handle(&(src->devArgs), &(src->log_level), FALSE); if (!src->mtl_lib_handle) { GST_ERROR("Could not initialize MTL"); diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c b/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c index 4d5fa25d..0c109a1f 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c @@ -170,8 +170,6 @@ static void gst_mtl_st20p_tx_class_init(Gst_Mtl_St20p_TxClass* klass) { } static gboolean gst_mtl_st20p_tx_start(GstBaseSink* bsink) { - struct mtl_init_params mtl_init_params = {0}; - Gst_Mtl_St20p_Tx* sink = GST_MTL_ST20P_TX(bsink); GST_DEBUG_OBJECT(sink, "start"); @@ -179,7 +177,7 @@ static gboolean gst_mtl_st20p_tx_start(GstBaseSink* bsink) { gst_base_sink_set_async_enabled(bsink, FALSE); sink->mtl_lib_handle = - gst_mtl_common_init_handle(&mtl_init_params, &(sink->devArgs), &(sink->log_level), FALSE); + gst_mtl_common_init_handle(&(sink->devArgs), &(sink->log_level), FALSE); if (!sink->mtl_lib_handle) { GST_ERROR("Could not initialize MTL"); diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c b/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c index 612f8b14..3722d207 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c @@ -183,7 +183,6 @@ static void gst_mtl_st30p_rx_class_init(Gst_Mtl_St30p_RxClass* klass) { } static gboolean gst_mtl_st30p_rx_start(GstBaseSrc* basesrc) { - struct mtl_init_params mtl_init_params = {0}; struct st30p_rx_ops* ops_rx; gint ret; @@ -194,7 +193,7 @@ static gboolean gst_mtl_st30p_rx_start(GstBaseSrc* basesrc) { GST_DEBUG("Media Transport Initialization start"); src->mtl_lib_handle = - gst_mtl_common_init_handle(&mtl_init_params, &(src->devArgs), &(src->log_level), FALSE); + gst_mtl_common_init_handle(&(src->devArgs), &(src->log_level), FALSE); if (!src->mtl_lib_handle) { GST_ERROR("Could not initialize MTL"); diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c b/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c index 66dd0dc6..b93192b8 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c @@ -181,8 +181,6 @@ static void gst_mtl_st30p_tx_class_init(Gst_Mtl_St30p_TxClass* klass) { } static gboolean gst_mtl_st30p_tx_start(GstBaseSink* bsink) { - struct mtl_init_params mtl_init_params = {0}; - Gst_Mtl_St30p_Tx* sink = GST_MTL_ST30P_TX(bsink); GST_DEBUG_OBJECT(sink, "start"); @@ -190,7 +188,7 @@ static gboolean gst_mtl_st30p_tx_start(GstBaseSink* bsink) { gst_base_sink_set_async_enabled(bsink, FALSE); sink->mtl_lib_handle = - gst_mtl_common_init_handle(&mtl_init_params, &(sink->devArgs), &(sink->log_level), FALSE); + gst_mtl_common_init_handle(&(sink->devArgs), &(sink->log_level), FALSE); if (!sink->mtl_lib_handle) { GST_ERROR("Could not initialize MTL"); diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c b/ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c index c13ae33d..469cb7dd 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c @@ -182,7 +182,6 @@ static void gst_mtl_st40_rx_class_init(Gst_Mtl_St40_RxClass* klass) { } static gboolean gst_mtl_st40_rx_start(GstBaseSrc* basesrc) { - struct mtl_init_params mtl_init_params = {0}; struct st40_rx_ops ops_rx = {0}; gint ret; @@ -192,7 +191,7 @@ static gboolean gst_mtl_st40_rx_start(GstBaseSrc* basesrc) { GST_DEBUG("Media Transport Initialization start"); src->mtl_lib_handle = - gst_mtl_common_init_handle(&mtl_init_params, &(src->devArgs), &(src->log_level), FALSE); + gst_mtl_common_init_handle(&(src->devArgs), &(src->log_level), FALSE); if (!src->mtl_lib_handle) { GST_ERROR("Could not initialize MTL"); diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c b/ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c index dbbe08fc..e787e50e 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c @@ -177,8 +177,6 @@ static void gst_mtl_st40p_tx_class_init(Gst_Mtl_St40p_TxClass* klass) { } static gboolean gst_mtl_st40p_tx_start(GstBaseSink* bsink) { - struct mtl_init_params mtl_init_params = {0}; - Gst_Mtl_St40p_Tx* sink = GST_MTL_ST40P_TX(bsink); GST_DEBUG_OBJECT(sink, "start"); @@ -186,7 +184,7 @@ static gboolean gst_mtl_st40p_tx_start(GstBaseSink* bsink) { gst_base_sink_set_async_enabled(bsink, FALSE); sink->mtl_lib_handle = - gst_mtl_common_init_handle(&mtl_init_params, &(sink->devArgs), &(sink->log_level), FALSE); + gst_mtl_common_init_handle(&(sink->devArgs), &(sink->log_level), FALSE); if (!sink->mtl_lib_handle) { GST_ERROR("Could not initialize MTL");