Skip to content

Commit f9cc158

Browse files
Add: St40pipline mode ability to parse 0 anc_count
1 parent 0530c54 commit f9cc158

File tree

16 files changed

+390
-333
lines changed

16 files changed

+390
-333
lines changed

ecosystem/gstreamer_plugin/gst_mtl_common.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -407,15 +407,16 @@ void gst_mtl_common_get_general_arguments(GObject* object, guint prop_id,
407407
}
408408

409409
/**
410-
* Copies general initialization port values to session-specific port arguments if not
411-
* specified. If the primary port is not specified, the redundant port argument will be
412-
* copied from the general initialization ports regardless of its specification. If the
413-
* UDP port for the redundant port is not specified, it will be incremented by one over
414-
* the primary port.
410+
* Copies general initialization port values to session-specific port arguments
411+
* if not specified. If the primary port is not specified, the redundant port
412+
* argument will be copied from the general initialization ports regardless of
413+
* its specification. If the UDP port for the redundant port is not specified,
414+
* it will be incremented by one over the primary port.
415415
*
416-
* @param general_args Pointer to the structure containing general initialization
417-
* parameters.
418-
* @param port_args Pointer to the structure containing session-specific port arguments.
416+
* @param general_args Pointer to the structure containing general
417+
* initialization parameters.
418+
* @param port_args Pointer to the structure containing session-specific port
419+
* arguments.
419420
*/
420421
void gst_mtl_common_copy_general_to_session_args(GeneralArgs* general_args,
421422
SessionPortArgs* port_args) {
@@ -437,8 +438,9 @@ void gst_mtl_common_copy_general_to_session_args(GeneralArgs* general_args,
437438
}
438439

439440
/**
440-
* Parses the transmission port arguments and initializes the tranmission port structure.
441-
* Validates and sets the destination IP address, port number, UDP port, and payload type.
441+
* Parses the transmission port arguments and initializes the tranmission port
442+
* structure. Validates and sets the destination IP address, port number, UDP
443+
* port, and payload type.
442444
*
443445
* @param port Pointer to the transmission port structure to be initialized.
444446
* @param port_args Pointer to the structure containing the port arguments.
@@ -485,8 +487,9 @@ guint gst_mtl_common_parse_tx_port_arguments(struct st_tx_port* port,
485487
}
486488

487489
/**
488-
* Parses the transmission port arguments and initializes the receive port structure.
489-
* Validates and sets the destination IP address, port number, UDP port, and payload type.
490+
* Parses the transmission port arguments and initializes the receive port
491+
* structure. Validates and sets the destination IP address, port number, UDP
492+
* port, and payload type.
490493
*
491494
* @param port Pointer to the transmission port structure to be initialized.
492495
* @param port_args Pointer to the structure containing the port arguments.

ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ static void gst_mtl_st20p_rx_class_init(Gst_Mtl_St20p_RxClass* klass) {
149149
gstelement_class = GST_ELEMENT_CLASS(klass);
150150
gstbasesrc_class = GST_BASE_SRC_CLASS(klass);
151151

152-
gst_element_class_set_metadata(
153-
gstelement_class, "MtlRxSt20Src", "Src/Video",
154-
"MTL transmission plugin for SMPTE ST 2110-20 standard (uncompressed video)",
155-
"Dawid Wesierski <[email protected]>");
152+
gst_element_class_set_metadata(gstelement_class, "MtlRxSt20Src", "Src/Video",
153+
"MTL transmission plugin for SMPTE ST 2110-20 "
154+
"standard (uncompressed video)",
155+
"Dawid Wesierski <[email protected]>");
156156

157157
gst_element_class_add_static_pad_template(gstelement_class,
158158
&gst_mtl_st20p_rx_src_pad_template);

ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,10 @@ static void gst_mtl_st20p_tx_class_init(Gst_Mtl_St20p_TxClass* klass) {
163163
gstelement_class = GST_ELEMENT_CLASS(klass);
164164
gstvideosinkelement_class = GST_VIDEO_SINK_CLASS(klass);
165165

166-
gst_element_class_set_metadata(
167-
gstelement_class, "MtlTxSt20Sink", "Sink/Video",
168-
"MTL transmission plugin for SMPTE ST 2110-20 standard (uncompressed video)",
169-
"Dawid Wesierski <[email protected]>");
166+
gst_element_class_set_metadata(gstelement_class, "MtlTxSt20Sink", "Sink/Video",
167+
"MTL transmission plugin for SMPTE ST 2110-20 "
168+
"standard (uncompressed video)",
169+
"Dawid Wesierski <[email protected]>");
170170

171171
gst_element_class_add_static_pad_template(gstelement_class,
172172
&gst_mtl_st20p_tx_sink_pad_template);
@@ -199,12 +199,13 @@ static void gst_mtl_st20p_tx_class_init(Gst_Mtl_St20p_TxClass* klass) {
199199

200200
g_object_class_install_property(
201201
gobject_class, PROP_ST20P_TX_USE_PTS_FOR_PACING,
202-
g_param_spec_boolean(
203-
"use-pts-for-pacing", "Use PTS for packet pacing",
204-
"This property modifies the default behavior where MTL handles packet pacing. "
205-
"Instead, it uses the buffer's PTS (Presentation Timestamp) to determine the "
206-
"precise time for sending packets.",
207-
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
202+
g_param_spec_boolean("use-pts-for-pacing", "Use PTS for packet pacing",
203+
"This property modifies the default behavior where "
204+
"MTL handles packet pacing. "
205+
"Instead, it uses the buffer's PTS (Presentation "
206+
"Timestamp) to determine the "
207+
"precise time for sending packets.",
208+
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
208209

209210
g_object_class_install_property(
210211
gobject_class, PROP_ST20P_TX_PTS_PACING_OFFSET,

ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ static void gst_mtl_st30p_rx_class_init(Gst_Mtl_St30p_RxClass* klass) {
135135
gstelement_class = GST_ELEMENT_CLASS(klass);
136136
gstbasesrc_class = GST_BASE_SRC_CLASS(klass);
137137

138-
gst_element_class_set_metadata(
139-
gstelement_class, "MtlRxSt30Src", "Src/Audio",
140-
"MTL transmission plugin for SMPTE ST 2110-30 standard (uncompressed audio)",
141-
"Dawid Wesierski <[email protected]>");
138+
gst_element_class_set_metadata(gstelement_class, "MtlRxSt30Src", "Src/Audio",
139+
"MTL transmission plugin for SMPTE ST 2110-30 "
140+
"standard (uncompressed audio)",
141+
"Dawid Wesierski <[email protected]>");
142142

143143
gst_element_class_add_static_pad_template(gstelement_class,
144144
&gst_mtl_st30p_rx_src_pad_template);

ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,13 @@ static void gst_mtl_st30p_tx_class_init(Gst_Mtl_St30p_TxClass* klass) {
182182

183183
g_object_class_install_property(
184184
gobject_class, PROP_ST30P_TX_USE_PTS_FOR_PACING,
185-
g_param_spec_boolean(
186-
"use-pts-for-pacing", "Use PTS for packet pacing",
187-
"This property modifies the default behavior where MTL handles packet pacing. "
188-
"Instead, it uses the buffer's PTS (Presentation Timestamp) to determine the "
189-
"precise time for sending packets.",
190-
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
185+
g_param_spec_boolean("use-pts-for-pacing", "Use PTS for packet pacing",
186+
"This property modifies the default behavior where "
187+
"MTL handles packet pacing. "
188+
"Instead, it uses the buffer's PTS (Presentation "
189+
"Timestamp) to determine the "
190+
"precise time for sending packets.",
191+
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
191192

192193
g_object_class_install_property(
193194
gobject_class, PROP_ST30P_TX_PTS_PACING_OFFSET,

ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ struct _Gst_Mtl_St30p_Tx {
6666
pthread_t session_thread;
6767

6868
/*
69-
* Handles incomplete frame buffers when their size does not match the expected size.
69+
* Handles incomplete frame buffers when their size does not match the
70+
* expected size.
7071
*/
7172
struct st30_frame* cur_frame;
7273
guint cur_frame_available_size;

ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -387,19 +387,32 @@ static void* gst_mtl_st40_rx_get_mbuf_with_timeout(Gst_Mtl_St40_Rx* src,
387387

388388
static struct st40_rfc8331_payload_hdr* gst_mtl_st40_rx_shift_payload_hdr(
389389
struct st40_rfc8331_payload_hdr* payload_hdr, int udw_size) {
390-
int package_size;
391-
int payload_len;
390+
gint package_size;
391+
gint payload_len;
392392

393-
package_size =
394-
((OFFSET_COUNT_IN_10_BIT + udw_size) * USER_DATA_WORD_BIT_SIZE) / BYTE_SIZE;
395-
package_size =
396-
(OFFSET_COUNT_IN_10_BIT - package_size % OFFSET_COUNT_IN_10_BIT) + package_size;
397-
payload_len =
398-
sizeof(struct st40_rfc8331_payload_hdr) - OFFSET_COUNT_IN_10_BIT + package_size;
393+
package_size = ((WORD_10_BIT_ALIGN + udw_size) * USER_DATA_WORD_BIT_SIZE) / BYTE_SIZE;
394+
payload_len = sizeof(struct st40_rfc8331_payload_hdr) -
395+
(package_size % WORD_10_BIT_ALIGN) + package_size;
399396

400397
return (struct st40_rfc8331_payload_hdr*)((uint8_t*)payload_hdr + payload_len);
401398
}
402399

400+
static GstFlowReturn gst_mtl_st40_rx_check_parity(const struct st40_rfc8331_payload_hdr* payload_hdr) {
401+
if (!st40_check_parity_bits(payload_hdr->second_hdr_chunk.did)) {
402+
GST_ERROR("Parity check failed for DID");
403+
return GST_FLOW_ERROR;
404+
}
405+
if (!st40_check_parity_bits(payload_hdr->second_hdr_chunk.sdid)) {
406+
GST_ERROR("Parity check failed for SDID");
407+
return GST_FLOW_ERROR;
408+
}
409+
if (!st40_check_parity_bits(payload_hdr->second_hdr_chunk.data_count)) {
410+
GST_ERROR("Parity check failed for Data Count");
411+
return GST_FLOW_ERROR;
412+
}
413+
return GST_FLOW_OK;
414+
}
415+
403416
static GstFlowReturn gst_mtl_st40_rx_fill_buffer(Gst_Mtl_St40_Rx* src, GstBuffer** buffer,
404417
void* usrptr) {
405418
struct st40_rfc8331_rtp_hdr* hdr;
@@ -412,12 +425,21 @@ static GstFlowReturn gst_mtl_st40_rx_fill_buffer(Gst_Mtl_St40_Rx* src, GstBuffer
412425
hdr = (struct st40_rfc8331_rtp_hdr*)usrptr;
413426
anc_count = hdr->first_hdr_chunk.anc_count;
414427

415-
if (anc_count == 0 || anc_count > ST40_RFC8331_PAYLOAD_MAX_ANCILLARY_COUNT) {
428+
if (anc_count < 0 || anc_count > ST40_RFC8331_PAYLOAD_MAX_ANCILLARY_COUNT) {
416429
GST_ERROR("Ancillary data count: %d (must be between 1 and %d)", anc_count,
417430
ST40_RFC8331_PAYLOAD_MAX_ANCILLARY_COUNT);
418431
return GST_FLOW_ERROR;
419432
}
420433

434+
if (anc_count == 0) {
435+
*buffer = gst_buffer_new_allocate(NULL, 0, NULL);
436+
if (!*buffer) {
437+
GST_ERROR("Failed to allocate empty buffer");
438+
return GST_FLOW_ERROR;
439+
}
440+
return GST_FLOW_OK;
441+
}
442+
421443
/* local is fine anc_count will not be bigger than 20*/
422444
guint8* anc_data[anc_count];
423445
guint8 anc_data_count[anc_count];
@@ -426,20 +448,9 @@ static GstFlowReturn gst_mtl_st40_rx_fill_buffer(Gst_Mtl_St40_Rx* src, GstBuffer
426448
for (int i = 0; i < anc_count; i++) {
427449
payload_hdr->swapped_first_hdr_chunk = ntohl(payload_hdr->swapped_first_hdr_chunk);
428450
payload_hdr->swapped_second_hdr_chunk = ntohl(payload_hdr->swapped_second_hdr_chunk);
429-
if (!st40_check_parity_bits(payload_hdr->second_hdr_chunk.did)) {
430-
GST_ERROR("Parity check failed for DID");
431-
for (int j = 0; j < i; j++) free(anc_data[j]);
432-
return GST_FLOW_ERROR;
433-
}
434-
if (!st40_check_parity_bits(payload_hdr->second_hdr_chunk.sdid)) {
435-
GST_ERROR("Parity check failed for SDID");
436-
for (int j = 0; j < i; j++) free(anc_data[j]);
437-
return GST_FLOW_ERROR;
438-
}
439-
if (!st40_check_parity_bits(payload_hdr->second_hdr_chunk.data_count)) {
440-
GST_ERROR("Parity check failed for Data Count");
441-
for (int j = 0; j < i; j++) free(anc_data[j]);
442-
return GST_FLOW_ERROR;
451+
if(gst_mtl_st40_rx_check_parity(payload_hdr) != GST_FLOW_OK) {
452+
for (int j = 0; j < i; j++) free(anc_data[j]);
453+
return GST_FLOW_ERROR;
443454
}
444455

445456
udw_size = payload_hdr->second_hdr_chunk.data_count & 0xff;
@@ -494,6 +505,7 @@ static GstFlowReturn gst_mtl_st40_rx_fill_buffer(Gst_Mtl_St40_Rx* src, GstBuffer
494505

495506
if (!gst_buffer_map(*buffer, &dest_info, GST_MAP_WRITE)) {
496507
GST_ERROR("Failed to map the buffer");
508+
for (int i = 0; i < anc_count; i++) free(anc_data[i]);
497509
return GST_FLOW_ERROR;
498510
}
499511

ecosystem/gstreamer_plugin/gst_mtl_st40_rx.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,14 @@
5252
#define USER_DATA_WORD_BIT_SIZE 10
5353
#define BYTE_SIZE 8
5454
#define OFFSET_BIT 32
55-
#define OFFSET_COUNT_IN_10_BIT ((OFFSET_BIT / USER_DATA_WORD_BIT_SIZE) + 1)
55+
#define WORD_10_BIT_ALIGN ((OFFSET_BIT / USER_DATA_WORD_BIT_SIZE) + 1)
5656

5757
/**
5858
* ST40_SIZE_OF_PAYLOAD_METADATA:
5959
* Defines the size (in bytes) of the payload metadata for ST40 streams.
6060
* This value is set to 8 to accommodate the following fields:
61-
* c | line_number | horizontal_offset | s | stream_num | did | sdid | data_count
61+
* c | line_number | horizontal_offset | s | stream_num | did | sdid |
62+
* data_count
6263
*/
6364
#define ST40_BYTE_SIZE_OF_PAYLOAD_METADATA 8
6465

ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,13 @@ static void gst_mtl_st40p_tx_class_init(Gst_Mtl_St40p_TxClass* klass) {
200200

201201
g_object_class_install_property(
202202
gobject_class, PROP_ST40P_TX_USE_PTS_FOR_PACING,
203-
g_param_spec_boolean(
204-
"use-pts-for-pacing", "Use PTS for packet pacing",
205-
"This property modifies the default behavior where MTL handles packet pacing. "
206-
"Instead, it uses the buffer's PTS (Presentation Timestamp) to determine the "
207-
"precise time for sending packets.",
208-
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
203+
g_param_spec_boolean("use-pts-for-pacing", "Use PTS for packet pacing",
204+
"This property modifies the default behavior where "
205+
"MTL handles packet pacing. "
206+
"Instead, it uses the buffer's PTS (Presentation "
207+
"Timestamp) to determine the "
208+
"precise time for sending packets.",
209+
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
209210

210211
g_object_class_install_property(
211212
gobject_class, PROP_ST40P_TX_PTS_PACING_OFFSET,
@@ -409,8 +410,8 @@ static gboolean gst_mtl_st40p_tx_session_create(Gst_Mtl_St40p_Tx* sink) {
409410
}
410411

411412
ops_tx.interlaced = false;
412-
/* Only single ANC data packet is possible when metadata is not being parsed from
413-
* parse_rfc8331_input mode per frame. anc_count = 1 TODO: allow more */
413+
/* Only single ANC data packet is possible when metadata is not being parsed
414+
* from parse_rfc8331_input mode per frame. anc_count = 1 TODO: allow more */
414415
sink->frame_size = MAX_UDW_SIZE;
415416

416417
if (sink->max_combined_udw_size)
@@ -469,13 +470,14 @@ static gboolean gst_mtl_st40p_tx_sink_event(GstPad* pad, GstObject* parent,
469470
/**
470471
* @brief Fills the metadata for a st40 frame.
471472
*
472-
* This function initializes the metadata fields of a given st40 frame with the provided
473-
* data and metadata values. It sets the first metadata entry with the specified DID,
474-
* SDID, and data size, and assigns the data pointer to the frame.
475-
* Note: Most of the fields are hardcoded, and only first metadata block is filled as
476-
* only one ANC Data packet per frame is allowed.
473+
* This function initializes the metadata fields of a given st40 frame with the
474+
* provided data and metadata values. It sets the first metadata entry with the
475+
* specified DID, SDID, and data size, and assigns the data pointer to the
476+
* frame. Note: Most of the fields are hardcoded, and only first metadata block
477+
* is filled as only one ANC Data packet per frame is allowed.
477478
*
478-
* @param frame Pointer to the st40_frame structure to be filled. Cannot be NULL.
479+
* @param frame Pointer to the st40_frame structure to be filled. Cannot be
480+
* NULL.
479481
* @param data Pointer to the data to be associated with the frame.
480482
* @param data_size Size of the data in bytes.
481483
* @param did Data Identifier (DID) to be set in the metadata.
@@ -496,7 +498,8 @@ static void gst_mtl_st40p_tx_fill_meta(struct st40_frame_info* frame_info, void*
496498
frame_info->meta_num = 1;
497499
}
498500

499-
/* we dont' really check the data here we let the st40 ancillary data to do so */
501+
/* we dont' really check the data here we let the st40 ancillary data to do so
502+
*/
500503
static GstFlowReturn gst_mtl_st40p_tx_parse_8331_meta(
501504
struct st40_frame_info* frame_info, struct st40_rfc8331_payload_hdr payload_header,
502505
guint anc_idx, guint udw_offset) {
@@ -546,6 +549,8 @@ static GstFlowReturn gst_mtl_st40p_tx_parse_8331_anc_words(
546549
return GST_FLOW_ERROR;
547550
}
548551

552+
frame_info->meta_num = 0;
553+
549554
for (int i = 0; i < anc_count; i++) {
550555
/* Processing of the input 8331 header */
551556
if (bytes_left_to_process < sizeof(struct st40_rfc8331_payload_hdr)) {
@@ -679,12 +684,11 @@ static GstFlowReturn gst_mtl_st40p_tx_parse_8331_memory_block(Gst_Mtl_St40p_Tx*
679684
/**
680685
* @brief Parses a GstBuffer and prepares a frame for transmission.
681686
*
682-
* This function retrieves a frame from the ST40p transmitter handle, copies the relevant
683-
* data from the provided GstBuffer into the frame buffer, fills in ancillary metadata,
684-
* and submits the frame for transmission. It also handles timestamping if pacing is
685-
* enabled.
686-
* No memory management is done here, the caller is responsible for managing the
687-
* GstBuffer and its associated memory.
687+
* This function retrieves a frame from the ST40p transmitter handle, copies the
688+
* relevant data from the provided GstBuffer into the frame buffer, fills in
689+
* ancillary metadata, and submits the frame for transmission. It also handles
690+
* timestamping if pacing is enabled. No memory management is done here, the
691+
* caller is responsible for managing the GstBuffer and its associated memory.
688692
*
689693
* @param sink Pointer to the Gst_Mtl_St40p_Tx sink element.
690694
* @param gst_buffer_memory GstMemory associated with the GstBuffer.

lib/src/st2110/experimental/st40_pipeline_tx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ int st40p_tx_put_frame(st40p_tx_handle handle, struct st40_frame_info* frame_inf
440440
framebuff->anc_frame->data_size = frame_info->udw_buffer_fill;
441441

442442
if (framebuff->anc_frame->meta_num > ST40_MAX_META ||
443-
framebuff->anc_frame->meta_num < 1) {
443+
framebuff->anc_frame->meta_num < 0) {
444444
err("%s(%d), frame %u meta_num %u invalid\n", __func__, idx, producer_idx,
445445
frame_info->meta_num);
446446
return -EIO;

0 commit comments

Comments
 (0)