From 62783535f52db132da5a21e34e605a4f1806b13b Mon Sep 17 00:00:00 2001 From: "Kasiewicz, Marek" Date: Fri, 31 Jan 2025 14:04:46 +0000 Subject: [PATCH] Add: ptime as a parameter to st30 gst plugins Signed-off-by: Kasiewicz, Marek --- ecosystem/gstreamer_plugin/README.md | 2 ++ ecosystem/gstreamer_plugin/gst_mtl_common.c | 32 +++++++++++++++++++ ecosystem/gstreamer_plugin/gst_mtl_common.h | 1 + ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c | 26 ++++++++++++++- ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.h | 2 +- ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c | 25 ++++++++++++++- ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.h | 1 + 7 files changed, 86 insertions(+), 3 deletions(-) diff --git a/ecosystem/gstreamer_plugin/README.md b/ecosystem/gstreamer_plugin/README.md index f53daae93..022959708 100644 --- a/ecosystem/gstreamer_plugin/README.md +++ b/ecosystem/gstreamer_plugin/README.md @@ -275,6 +275,7 @@ The `mtl_st30p_tx` plugin supports the following pad capabilities: |---------------------|--------|-------------------------------------------------------|-------------------------|---------------| | tx-samplerate | uint | Sample rate of the audio. | [gst_mtl_supported_audio_sampling](#232-supported-audio-sampling-rates-gst_mtl_supported_audio_sampling) | 0 | | tx-channels | uint | Number of audio channels. | 1 to 8 | 2 | +| tx-ptime | string | Packetization time for the audio stream. | `1ms`, `125us`, `250us`, `333us`, `4ms`, `80us`, `1.09ms`, `0.14ms`, `0.09ms` | `1.09ms` for 44.1kHz, `1ms` for others | #### 4.1.2. Example GStreamer Pipeline for Transmission with s16LE format @@ -310,6 +311,7 @@ The `mtl_st30p_rx` plugin supports the following pad capabilities: | rx-channel | uint | Audio channel number. | 0 to G_MAXUINT | 2 | | rx-sampling | uint | Audio sampling rate. | [gst_mtl_supported_audio_sampling](#232-supported-audio-sampling-rates-gst_mtl_supported_audio_sampling) | 48000 | | rx-audio-format | string | Audio format type. | `S8`, `S16LE`, `S24LE` | `S16LE` | +| rx-ptime | string | Packetization time for the audio stream. | `1ms`, `125us`, `250us`, `333us`, `4ms`, `80us`, `1.09ms`, `0.14ms`, `0.09ms` | `1.09ms` for 44.1kHz, `1ms` for others | #### 4.2.2. Preparing Output Path diff --git a/ecosystem/gstreamer_plugin/gst_mtl_common.c b/ecosystem/gstreamer_plugin/gst_mtl_common.c index d32b9f4dc..f22cae959 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_common.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_common.c @@ -171,6 +171,38 @@ gboolean gst_mtl_common_parse_pixel_format(const char* format, enum st_frame_fmt return TRUE; } +gboolean gst_mtl_common_parse_ptime(const char* ptime_str, enum st30_ptime* ptime) { + if (!ptime_str || !ptime) { + GST_ERROR("%s, invalid input\n", __func__); + return FALSE; + } + + if (strcmp(ptime_str, "1ms") == 0) { + *ptime = ST30_PTIME_1MS; + } else if (strcmp(ptime_str, "125us") == 0) { + *ptime = ST30_PTIME_125US; + } else if (strcmp(ptime_str, "250us") == 0) { + *ptime = ST30_PTIME_250US; + } else if (strcmp(ptime_str, "333us") == 0) { + *ptime = ST30_PTIME_333US; + } else if (strcmp(ptime_str, "4ms") == 0) { + *ptime = ST30_PTIME_4MS; + } else if (strcmp(ptime_str, "80us") == 0) { + *ptime = ST31_PTIME_80US; + } else if (strcmp(ptime_str, "1.09ms") == 0) { + *ptime = ST31_PTIME_1_09MS; + } else if (strcmp(ptime_str, "0.14ms") == 0) { + *ptime = ST31_PTIME_0_14MS; + } else if (strcmp(ptime_str, "0.09ms") == 0) { + *ptime = ST31_PTIME_0_09MS; + } else { + GST_ERROR("invalid packet time %s\n", ptime_str); + return FALSE; + } + + return TRUE; +} + gboolean gst_mtl_common_parse_audio_format(const char* format, enum st30_fmt* audio) { if (!audio || !format) { GST_ERROR("%s, invalid input\n", __func__); diff --git a/ecosystem/gstreamer_plugin/gst_mtl_common.h b/ecosystem/gstreamer_plugin/gst_mtl_common.h index c8233598c..a13f662fd 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_common.h +++ b/ecosystem/gstreamer_plugin/gst_mtl_common.h @@ -84,6 +84,7 @@ gboolean gst_mtl_common_parse_fps_code(gint fps_code, enum st_fps* fps); gboolean gst_mtl_common_parse_pixel_format(const char* format, enum st_frame_fmt* fmt); gboolean gst_mtl_common_parse_audio_format(const char* format, enum st30_fmt* audio); +gboolean gst_mtl_common_parse_ptime(const char* ptime_str, enum st30_ptime* ptime); gboolean gst_mtl_common_gst_to_st_sampling(gint sampling, enum st30_sampling* st_sampling); gboolean gst_mtl_common_st_to_gst_sampling(enum st30_sampling st_sampling, diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c b/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c index f444a37fc..59340f5a0 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c @@ -96,6 +96,7 @@ enum { PROP_ST30P_RX_CHANNEL, PROP_ST30P_RX_SAMPLING, PROP_ST30P_RX_AUDIO_FORMAT, + PROP_ST30P_RX_PTIME, PROP_MAX }; @@ -180,6 +181,12 @@ static void gst_mtl_st30p_rx_class_init(Gst_Mtl_St30p_RxClass* klass) { gobject_class, PROP_ST30P_RX_AUDIO_FORMAT, g_param_spec_string("rx-audio-format", "Audio format", "Audio format type.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + gobject_class, PROP_ST30P_RX_PTIME, + g_param_spec_string("rx-ptime", "Packetization time", + "Packetization time for the audio stream", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static gboolean gst_mtl_st30p_rx_start(GstBaseSrc* basesrc) { @@ -205,7 +212,6 @@ static gboolean gst_mtl_st30p_rx_start(GstBaseSrc* basesrc) { ops_rx->name = "st30src"; ops_rx->channel = src->channel; ops_rx->port.num_port = 1; - ops_rx->ptime = ST30_PTIME_1MS; ops_rx->flags |= ST30P_RX_FLAG_BLOCK_GET; if (!gst_mtl_common_gst_to_st_sampling(src->sampling, &ops_rx->sampling)) { @@ -213,6 +219,18 @@ static gboolean gst_mtl_st30p_rx_start(GstBaseSrc* basesrc) { return FALSE; } + if (src->ptime[0] != '\0') { + if (!gst_mtl_common_parse_ptime(src->ptime, &ops_rx->ptime)) { + GST_ERROR("Failed to parse ops_rx ptime %s", src->ptime); + return FALSE; + } + } else { + if (ops_rx->sampling == ST31_SAMPLING_44K) + ops_rx->ptime = ST31_PTIME_1_09MS; + else + ops_rx->ptime = ST30_PTIME_1MS; + } + if (!gst_mtl_common_parse_audio_format(src->audio_format, &ops_rx->fmt)) { GST_ERROR("Failed to parse ops_rx audio format %s", src->audio_format); return FALSE; @@ -312,6 +330,9 @@ static void gst_mtl_st30p_rx_set_property(GObject* object, guint prop_id, case PROP_ST30P_RX_AUDIO_FORMAT: strncpy(self->audio_format, g_value_get_string(value), MTL_PORT_MAX_LEN); break; + case PROP_ST30P_RX_PTIME: + g_strlcpy(self->ptime, g_value_get_string(value), MTL_PORT_MAX_LEN); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -341,6 +362,9 @@ static void gst_mtl_st30p_rx_get_property(GObject* object, guint prop_id, GValue case PROP_ST30P_RX_AUDIO_FORMAT: g_value_set_string(value, src->audio_format); break; + case PROP_ST30P_RX_PTIME: + g_value_set_string(value, src->ptime); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.h b/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.h index 6c41486ba..dd9a50543 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.h +++ b/ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.h @@ -76,7 +76,7 @@ struct _Gst_Mtl_St30p_Rx { /* audio (st30p) specific arguments */ guint channel; guint sampling; - gboolean ptime; + gchar ptime[MTL_PORT_MAX_LEN]; gchar audio_format[MTL_PORT_MAX_LEN]; }; diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c b/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c index fc80dd287..3b706f639 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c +++ b/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c @@ -94,6 +94,7 @@ enum { PROP_ST30P_TX_RETRY = PROP_GENERAL_MAX, PROP_ST30P_TX_FRAMERATE, PROP_ST30P_TX_FRAMEBUFF_NUM, + PROP_ST30P_TX_PTIME, PROP_MAX }; @@ -157,6 +158,12 @@ static void gst_mtl_st30p_tx_class_init(Gst_Mtl_St30p_TxClass* klass) { g_param_spec_uint("tx-framebuff-num", "Number of framebuffers", "Number of framebuffers to be used for transmission.", 0, G_MAXUINT, 3, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property( + gobject_class, PROP_ST30P_TX_PTIME, + g_param_spec_string("tx-ptime", "Packetization time", + "Packetization time for the audio stream", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } static gboolean gst_mtl_st30p_tx_start(GstBaseSink* bsink) { @@ -215,6 +222,9 @@ static void gst_mtl_st30p_tx_set_property(GObject* object, guint prop_id, case PROP_ST30P_TX_FRAMEBUFF_NUM: self->framebuffer_num = g_value_get_uint(value); break; + case PROP_ST30P_TX_PTIME: + g_strlcpy(self->ptime, g_value_get_string(value), MTL_PORT_MAX_LEN); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -241,6 +251,9 @@ static void gst_mtl_st30p_tx_get_property(GObject* object, guint prop_id, GValue case PROP_ST30P_TX_FRAMEBUFF_NUM: g_value_set_uint(value, sink->framebuffer_num); break; + case PROP_ST30P_TX_PTIME: + g_value_set_string(value, sink->ptime); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -296,7 +309,17 @@ static gboolean gst_mtl_st30p_tx_session_create(Gst_Mtl_St30p_Tx* sink, GstCaps* return FALSE; } gst_audio_info_free(info); - ops_tx.ptime = ST30_PTIME_1MS; + if (sink->ptime[0] != '\0') { + if (!gst_mtl_common_parse_ptime(sink->ptime, &ops_tx.ptime)) { + GST_ERROR("Failed to parse ops_tx ptime %s", sink->ptime); + return FALSE; + } + } else { + if (ops_tx.sampling == ST31_SAMPLING_44K) + ops_tx.ptime = ST31_PTIME_1_09MS; + else + ops_tx.ptime = ST30_PTIME_1MS; + } ops_tx.port.num_port = 1; diff --git a/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.h b/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.h index 038cbcfb9..902fc9b07 100644 --- a/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.h +++ b/ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.h @@ -73,6 +73,7 @@ struct _Gst_Mtl_St30p_Tx { SessionPortArgs portArgs; /* imtl tx session */ guint framebuffer_num; guint framerate; + gchar ptime[MTL_PORT_MAX_LEN]; }; G_END_DECLS