Skip to content

Commit 6b056c8

Browse files
Add: MTL common handle support in GStreamer (#1047)
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.
1 parent 8fdce09 commit 6b056c8

File tree

10 files changed

+145
-40
lines changed

10 files changed

+145
-40
lines changed

ecosystem/gstreamer_plugin/README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,19 @@ In MTL GStreamer plugins there are general arguments that apply to every plugin.
101101
| udp-port | uint | Receiving MTL node UDP port. | 0 to G_MAXUINT |
102102
| tx-queues | uint | Number of TX queues to initialize in DPDK backend. | 0 to G_MAXUINT |
103103
| rx-queues | uint | Number of RX queues to initialize in DPDK backend. | 0 to G_MAXUINT |
104-
| payload-type | uint | SMPTE ST 2110 payload type. | 0 to G_MAXUINT |
104+
| payload-type | uint | SMPTE ST 2110 payload type. | 0 to G_MAXUINT |
105105

106106
These are also general parameters accepted by plugins, but the functionality they provide to the user is not yet supported in plugins.
107107
| Property Name | Type | Description | Range |
108108
|---------------|--------|---------------------------------------------------------------------------------------------------|--------------------------|
109109
| dma-dev | string | **RESERVED FOR FUTURE USE** port for the MTL direct memory functionality. | N/A |
110110
| 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 |
111111

112+
> **Warning:**
113+
> Generally, the `log-level`, `dev-port`, `dev-ip`, `tx-queues`, and `rx-queues` are used to initialize the MTLlibrary. As the MTL library handle is shared between MTL
114+
> GStreamer plugins of the same pipeline, you only need to pass them once when specifying the arguments for the firstly initialized pipeline. Nothing happens when you specify them elsewhere;
115+
> they will just be ignored after the initialization of MTL has already happened.
116+
112117
### 2.3. General capabilities
113118

114119
Some structures describe the capabilities generally

ecosystem/gstreamer_plugin/gst_mtl_common.c

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88

99
#include "gst_mtl_common.h"
1010

11+
/* Shared handle for the MTL library used across plugins in the pipeline */
12+
struct gst_common_handle {
13+
mtl_handle mtl_handle;
14+
int mtl_handle_reference_count;
15+
pthread_mutex_t mutex;
16+
};
17+
18+
static struct gst_common_handle common_handle = {0, 0, PTHREAD_MUTEX_INITIALIZER};
1119
guint gst_mtl_port_idx = MTL_PORT_P;
1220

1321
gboolean gst_mtl_common_parse_input_finfo(const GstVideoFormatInfo* finfo,
@@ -393,19 +401,48 @@ gboolean gst_mtl_common_parse_dev_arguments(struct mtl_init_params* mtl_init_par
393401
return ret;
394402
}
395403

396-
mtl_handle gst_mtl_common_init_handle(struct mtl_init_params* p, StDevArgs* devArgs,
397-
guint* log_level) {
404+
/**
405+
* Initializes the device with the given parameters.
406+
*
407+
* If the common handle (MTL instance already initialized in the pipeline)
408+
* is already in use, the input parameters for the device
409+
* (rx_queues, tx_queues, dev_ip, dev_port, and log_level) will be ignored.
410+
* You can force to initialize another MTL instance to avoid this behavior with
411+
* force_to_initialize_new_instance flag.
412+
*
413+
* @param force_to_initialize_new_instance Force the creation of a new MTL
414+
* instance, ignoring any existing one.
415+
* @param devArgs Initialization parameters for the DPDK port
416+
* (ignored if using an existing MTL instance).
417+
* @param log_level Log level for the library (ignored if using an
418+
* existing MTL instance).
419+
*/
420+
mtl_handle gst_mtl_common_init_handle(StDevArgs* devArgs, guint* log_level,
421+
gboolean force_to_initialize_new_instance) {
398422
struct mtl_init_params mtl_init_params = {0};
423+
mtl_handle ret;
424+
pthread_mutex_lock(&common_handle.mutex);
425+
426+
if (!force_to_initialize_new_instance && common_handle.mtl_handle) {
427+
GST_INFO("Mtl is already initialized with shared handle %p",
428+
common_handle.mtl_handle);
429+
common_handle.mtl_handle_reference_count++;
430+
431+
pthread_mutex_unlock(&common_handle.mutex);
432+
return common_handle.mtl_handle;
433+
}
399434

400-
if (!p || !devArgs || !log_level) {
435+
if (!devArgs || !log_level) {
401436
GST_ERROR("Invalid input");
437+
pthread_mutex_unlock(&common_handle.mutex);
402438
return NULL;
403439
}
404440

405441
mtl_init_params.num_ports = 0;
406442

407443
if (gst_mtl_common_parse_dev_arguments(&mtl_init_params, devArgs) == FALSE) {
408444
GST_ERROR("Failed to parse dev arguments");
445+
pthread_mutex_unlock(&common_handle.mutex);
409446
return NULL;
410447
}
411448
mtl_init_params.flags |= MTL_FLAG_BIND_NUMA;
@@ -422,5 +459,53 @@ mtl_handle gst_mtl_common_init_handle(struct mtl_init_params* p, StDevArgs* devA
422459
}
423460
*log_level = mtl_init_params.log_level;
424461

425-
return mtl_init(&mtl_init_params);
462+
if (force_to_initialize_new_instance) {
463+
GST_INFO("MTL shared handle ignored");
464+
465+
ret = mtl_init(&mtl_init_params);
466+
pthread_mutex_unlock(&common_handle.mutex);
467+
468+
return ret;
469+
}
470+
471+
common_handle.mtl_handle = mtl_init(&mtl_init_params);
472+
common_handle.mtl_handle_reference_count++;
473+
pthread_mutex_unlock(&common_handle.mutex);
474+
475+
return common_handle.mtl_handle;
476+
}
477+
478+
/**
479+
* Deinitializes the MTL handle.
480+
* If the handle is the shared handle, the reference count is decremented.
481+
* If the reference count reaches zero, the handle is deinitialized.
482+
* If the handle is not the shared handle, it is deinitialized immediately.
483+
*
484+
* @param handle MTL handle to deinitialize (Null is an akceptable value then
485+
* shared value will be used).
486+
*/
487+
gint gst_mtl_common_deinit_handle(mtl_handle handle) {
488+
gint ret;
489+
490+
pthread_mutex_lock(&common_handle.mutex);
491+
492+
if (handle && handle != common_handle.mtl_handle) {
493+
ret = mtl_uninit(handle);
494+
pthread_mutex_unlock(&common_handle.mutex);
495+
return ret;
496+
}
497+
498+
common_handle.mtl_handle_reference_count--;
499+
500+
if (common_handle.mtl_handle_reference_count > 0) {
501+
common_handle.mtl_handle_reference_count--;
502+
503+
pthread_mutex_unlock(&common_handle.mutex);
504+
return 0;
505+
}
506+
ret = mtl_uninit(common_handle.mtl_handle);
507+
508+
pthread_mutex_unlock(&common_handle.mutex);
509+
pthread_mutex_destroy(&common_handle.mutex);
510+
return ret;
426511
}

ecosystem/gstreamer_plugin/gst_mtl_common.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ void gst_mtl_common_get_general_arguments(GObject* object, guint prop_id,
101101
StDevArgs* devArgs, SessionPortArgs* portArgs,
102102
guint* log_level);
103103

104-
mtl_handle gst_mtl_common_init_handle(struct mtl_init_params* p, StDevArgs* devArgs,
105-
guint* log_level);
104+
mtl_handle gst_mtl_common_init_handle(StDevArgs* devArgs, guint* log_level,
105+
gboolean force_to_initialize_new_instance);
106106

107+
gint gst_mtl_common_deinit_handle(mtl_handle handle);
107108
#endif /* __GST_MTL_COMMON_H__ */

ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ static void gst_mtl_st20p_rx_class_init(Gst_Mtl_St20p_RxClass* klass) {
197197
}
198198

199199
static gboolean gst_mtl_st20p_rx_start(GstBaseSrc* basesrc) {
200-
struct mtl_init_params mtl_init_params = {0};
201200
struct st20p_rx_ops* ops_rx;
202201
gint ret;
203202

@@ -208,7 +207,7 @@ static gboolean gst_mtl_st20p_rx_start(GstBaseSrc* basesrc) {
208207
GST_DEBUG("Media Transport Initialization start");
209208

210209
src->mtl_lib_handle =
211-
gst_mtl_common_init_handle(&mtl_init_params, &(src->devArgs), &(src->log_level));
210+
gst_mtl_common_init_handle(&(src->devArgs), &(src->log_level), FALSE);
212211

213212
if (!src->mtl_lib_handle) {
214213
GST_ERROR("Could not initialize MTL");
@@ -510,7 +509,8 @@ static void gst_mtl_st20p_rx_finalize(GObject* object) {
510509
}
511510

512511
if (src->mtl_lib_handle) {
513-
if (mtl_stop(src->mtl_lib_handle) || mtl_uninit(src->mtl_lib_handle)) {
512+
if (mtl_stop(src->mtl_lib_handle) ||
513+
gst_mtl_common_deinit_handle(src->mtl_lib_handle)) {
514514
GST_ERROR("Failed to uninitialize MTL library");
515515
return;
516516
}

ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,14 @@ static void gst_mtl_st20p_tx_class_init(Gst_Mtl_St20p_TxClass* klass) {
170170
}
171171

172172
static gboolean gst_mtl_st20p_tx_start(GstBaseSink* bsink) {
173-
struct mtl_init_params mtl_init_params = {0};
174-
175173
Gst_Mtl_St20p_Tx* sink = GST_MTL_ST20P_TX(bsink);
176174

177175
GST_DEBUG_OBJECT(sink, "start");
178176
GST_DEBUG("Media Transport Initialization start");
179177
gst_base_sink_set_async_enabled(bsink, FALSE);
180178

181179
sink->mtl_lib_handle =
182-
gst_mtl_common_init_handle(&mtl_init_params, &(sink->devArgs), &(sink->log_level));
180+
gst_mtl_common_init_handle(&(sink->devArgs), &(sink->log_level), FALSE);
183181

184182
if (!sink->mtl_lib_handle) {
185183
GST_ERROR("Could not initialize MTL");
@@ -459,7 +457,8 @@ static void gst_mtl_st20p_tx_finalize(GObject* object) {
459457
}
460458

461459
if (sink->mtl_lib_handle) {
462-
if (mtl_stop(sink->mtl_lib_handle) || mtl_uninit(sink->mtl_lib_handle)) {
460+
if (mtl_stop(sink->mtl_lib_handle) ||
461+
gst_mtl_common_deinit_handle(sink->mtl_lib_handle)) {
463462
GST_ERROR("Failed to uninitialize MTL library");
464463
return;
465464
}

ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ static void gst_mtl_st30p_rx_class_init(Gst_Mtl_St30p_RxClass* klass) {
183183
}
184184

185185
static gboolean gst_mtl_st30p_rx_start(GstBaseSrc* basesrc) {
186-
struct mtl_init_params mtl_init_params = {0};
187186
struct st30p_rx_ops* ops_rx;
188187
gint ret;
189188

@@ -194,7 +193,7 @@ static gboolean gst_mtl_st30p_rx_start(GstBaseSrc* basesrc) {
194193
GST_DEBUG("Media Transport Initialization start");
195194

196195
src->mtl_lib_handle =
197-
gst_mtl_common_init_handle(&mtl_init_params, &(src->devArgs), &(src->log_level));
196+
gst_mtl_common_init_handle(&(src->devArgs), &(src->log_level), FALSE);
198197

199198
if (!src->mtl_lib_handle) {
200199
GST_ERROR("Could not initialize MTL");
@@ -469,7 +468,8 @@ static void gst_mtl_st30p_rx_finalize(GObject* object) {
469468
}
470469

471470
if (src->mtl_lib_handle) {
472-
if (mtl_stop(src->mtl_lib_handle) || mtl_uninit(src->mtl_lib_handle)) {
471+
if (mtl_stop(src->mtl_lib_handle) ||
472+
gst_mtl_common_deinit_handle(src->mtl_lib_handle)) {
473473
GST_ERROR("Failed to uninitialize MTL library");
474474
return;
475475
}

ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,14 @@ static void gst_mtl_st30p_tx_class_init(Gst_Mtl_St30p_TxClass* klass) {
181181
}
182182

183183
static gboolean gst_mtl_st30p_tx_start(GstBaseSink* bsink) {
184-
struct mtl_init_params mtl_init_params = {0};
185-
186184
Gst_Mtl_St30p_Tx* sink = GST_MTL_ST30P_TX(bsink);
187185

188186
GST_DEBUG_OBJECT(sink, "start");
189187
GST_DEBUG("Media Transport Initialization start");
190188
gst_base_sink_set_async_enabled(bsink, FALSE);
191189

192190
sink->mtl_lib_handle =
193-
gst_mtl_common_init_handle(&mtl_init_params, &(sink->devArgs), &(sink->log_level));
191+
gst_mtl_common_init_handle(&(sink->devArgs), &(sink->log_level), FALSE);
194192

195193
if (!sink->mtl_lib_handle) {
196194
GST_ERROR("Could not initialize MTL");
@@ -499,7 +497,8 @@ static void gst_mtl_st30p_tx_finalize(GObject* object) {
499497
}
500498

501499
if (sink->mtl_lib_handle) {
502-
if (mtl_stop(sink->mtl_lib_handle) || mtl_uninit(sink->mtl_lib_handle)) {
500+
if (mtl_stop(sink->mtl_lib_handle) ||
501+
gst_mtl_common_deinit_handle(sink->mtl_lib_handle)) {
503502
GST_ERROR("Failed to uninitialize MTL library");
504503
return;
505504
}

ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ static void gst_mtl_st40_rx_class_init(Gst_Mtl_St40_RxClass* klass) {
182182
}
183183

184184
static gboolean gst_mtl_st40_rx_start(GstBaseSrc* basesrc) {
185-
struct mtl_init_params mtl_init_params = {0};
186185
struct st40_rx_ops ops_rx = {0};
187186
gint ret;
188187

@@ -192,7 +191,7 @@ static gboolean gst_mtl_st40_rx_start(GstBaseSrc* basesrc) {
192191
GST_DEBUG("Media Transport Initialization start");
193192

194193
src->mtl_lib_handle =
195-
gst_mtl_common_init_handle(&mtl_init_params, &(src->devArgs), &(src->log_level));
194+
gst_mtl_common_init_handle(&(src->devArgs), &(src->log_level), FALSE);
196195

197196
if (!src->mtl_lib_handle) {
198197
GST_ERROR("Could not initialize MTL");
@@ -464,7 +463,8 @@ static void gst_mtl_st40_rx_finalize(GObject* object) {
464463
pthread_cond_destroy(&src->mbuff_cond);
465464

466465
if (src->mtl_lib_handle) {
467-
if (mtl_stop(src->mtl_lib_handle) || mtl_uninit(src->mtl_lib_handle)) {
466+
if (mtl_stop(src->mtl_lib_handle) ||
467+
gst_mtl_common_deinit_handle(src->mtl_lib_handle)) {
468468
GST_ERROR("Failed to uninitialize MTL library");
469469
}
470470
}

ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,14 @@ static void gst_mtl_st40p_tx_class_init(Gst_Mtl_St40p_TxClass* klass) {
177177
}
178178

179179
static gboolean gst_mtl_st40p_tx_start(GstBaseSink* bsink) {
180-
struct mtl_init_params mtl_init_params = {0};
181-
182180
Gst_Mtl_St40p_Tx* sink = GST_MTL_ST40P_TX(bsink);
183181

184182
GST_DEBUG_OBJECT(sink, "start");
185183
GST_DEBUG("Media Transport Initialization start");
186184
gst_base_sink_set_async_enabled(bsink, FALSE);
187185

188186
sink->mtl_lib_handle =
189-
gst_mtl_common_init_handle(&mtl_init_params, &(sink->devArgs), &(sink->log_level));
187+
gst_mtl_common_init_handle(&(sink->devArgs), &(sink->log_level), FALSE);
190188

191189
if (!sink->mtl_lib_handle) {
192190
GST_ERROR("Could not initialize MTL");
@@ -483,7 +481,8 @@ static void gst_mtl_st40p_tx_finalize(GObject* object) {
483481
}
484482

485483
if (sink->mtl_lib_handle) {
486-
if (mtl_stop(sink->mtl_lib_handle) || mtl_uninit(sink->mtl_lib_handle)) {
484+
if (mtl_stop(sink->mtl_lib_handle) ||
485+
gst_mtl_common_deinit_handle(sink->mtl_lib_handle)) {
487486
GST_ERROR("Failed to uninitialize MTL library");
488487
return;
489488
}

0 commit comments

Comments
 (0)