Skip to content

Commit fc4c95a

Browse files
authored
Add support of endianness for st40_rfc8331_rtp_hdr (#1203)
Added option to support conversion from big to little endian in st40 RTP header.
1 parent 5813394 commit fc4c95a

File tree

7 files changed

+72
-28
lines changed

7 files changed

+72
-28
lines changed

ecosystem/gstreamer_plugin/gst_mtl_st40_rx.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,11 @@ static GstFlowReturn gst_mtl_st40_rx_fill_buffer(Gst_Mtl_St40_Rx* src, GstBuffer
381381
gint udw_size;
382382

383383
hdr = (struct st40_rfc8331_rtp_hdr*)usrptr;
384+
384385
payload_hdr = (struct st40_rfc8331_payload_hdr*)(&hdr[1]);
386+
387+
hdr->swapped_first_hdr_chunk = ntohl(hdr->swapped_first_hdr_chunk);
388+
385389
payload_hdr_swapped.swapped_second_hdr_chunk =
386390
ntohl(payload_hdr->swapped_second_hdr_chunk);
387391
udw_size = payload_hdr_swapped.second_hdr_chunk.data_count & 0xff;

include/st40_api.h

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,23 +84,49 @@ enum st40_type {
8484
/**
8585
* A structure describing a st2110-40(ancillary) rfc8331 rtp header
8686
*/
87+
#ifdef MTL_LITTLE_ENDIAN
8788
MTL_PACK(struct st40_rfc8331_rtp_hdr {
8889
/** Rtp rfc3550 base hdr */
8990
struct st_rfc3550_rtp_hdr base;
9091
/** Extended Sequence Number */
9192
uint16_t seq_number_ext;
9293
/** Number of octets of the ANC data RTP payload */
9394
uint16_t length;
94-
95-
struct {
96-
/** the count of the total number of ANC data packets carried in the RTP payload */
97-
uint32_t anc_count : 8;
98-
/** signaling the field specified by the RTP timestamp in an interlaced SDI raster */
99-
uint32_t f : 2;
100-
/** reserved */
101-
uint32_t reserved : 22;
95+
union {
96+
struct {
97+
/** reserved */
98+
uint32_t reserved : 22;
99+
/** signaling the field specified by the RTP timestamp in an interlaced SDI raster
100+
*/
101+
uint32_t f : 2;
102+
/** the count of the total number of ANC data packets carried in the RTP payload */
103+
uint32_t anc_count : 8;
104+
} first_hdr_chunk;
105+
uint32_t swapped_first_hdr_chunk;
102106
};
103107
});
108+
#else
109+
MTL_PACK(struct st40_rfc8331_rtp_hdr {
110+
/** Rtp rfc3550 base hdr */
111+
struct st_rfc3550_rtp_hdr base;
112+
/** Extended Sequence Number */
113+
uint16_t seq_number_ext;
114+
/** Number of octets of the ANC data RTP payload */
115+
uint16_t length;
116+
union {
117+
struct {
118+
/** the count of the total number of ANC data packets carried in the RTP payload */
119+
uint32_t anc_count : 8;
120+
/** signaling the field specified by the RTP timestamp in an interlaced SDI raster
121+
*/
122+
uint32_t f : 2;
123+
/** reserved */
124+
uint32_t reserved : 22;
125+
} first_hdr_chunk;
126+
uint32_t swapped_first_hdr_chunk;
127+
};
128+
});
129+
#endif
104130

105131
/* A structure describing the first 32 bits of an ST 2110-40 (ancillary) payload header */
106132
#ifdef MTL_LITTLE_ENDIAN

lib/src/st2110/st_rx_ancillary_session.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static int rx_ancillary_session_handle_pkt(struct mtl_main_impl* impl,
9393
uint16_t seq_id = ntohs(rtp->seq_number);
9494
uint8_t payload_type = rtp->payload_type;
9595
struct st40_rfc8331_rtp_hdr* rfc8331 = (struct st40_rfc8331_rtp_hdr*)rtp;
96+
rfc8331->swapped_first_hdr_chunk = ntohl(rfc8331->swapped_first_hdr_chunk);
9697
MTL_MAY_UNUSED(s_port);
9798
uint32_t pkt_len = mbuf->data_len - sizeof(struct st40_rfc8331_rtp_hdr);
9899
MTL_MAY_UNUSED(pkt_len);
@@ -115,14 +116,14 @@ static int rx_ancillary_session_handle_pkt(struct mtl_main_impl* impl,
115116
}
116117

117118
/* Drop if F is 0b01 (invalid: bit 0 set, bit 1 clear) */
118-
if ((rfc8331->f & 0x3) == 0x1) {
119+
if ((rfc8331->first_hdr_chunk.f & 0x3) == 0x1) {
119120
s->stat_pkts_wrong_interlace_dropped++;
120121
return -EINVAL;
121122
}
122123
/* 0b10: first field (bit 1 set, bit 0 clear)
123124
0b11: second field (bit 1 set, bit 0 set) */
124-
if (rfc8331->f & 0x2) {
125-
if (rfc8331->f & 0x1)
125+
if (rfc8331->first_hdr_chunk.f & 0x2) {
126+
if (rfc8331->first_hdr_chunk.f & 0x1)
126127
s->stat_interlace_second_field++;
127128
else
128129
s->stat_interlace_first_field++;

lib/src/st2110/st_tx_ancillary_session.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ static int tx_ancillary_session_init_hdr(struct mtl_main_impl* impl,
131131
struct rte_ipv4_hdr* ipv4 = &hdr->ipv4;
132132
struct rte_udp_hdr* udp = &hdr->udp;
133133
struct st40_rfc8331_rtp_hdr* rtp = &hdr->rtp;
134+
135+
/* Print rtp_header in both host and network byte order to check endianness */
134136
uint8_t* dip = ops->dip_addr[s_port];
135137
uint8_t* sip = mt_sip_addr(impl, port);
136138
struct rte_ether_addr* d_addr = mt_eth_d_addr(eth);
@@ -465,19 +467,21 @@ static int tx_ancillary_session_build_packet(struct st_tx_ancillary_session_impl
465467
pkt->data_len += payload_size + sizeof(struct st40_rfc8331_rtp_hdr);
466468
pkt->pkt_len = pkt->data_len;
467469
rtp->length = htons(payload_size);
468-
rtp->anc_count = idx - s->st40_pkt_idx;
470+
rtp->first_hdr_chunk.anc_count = idx - s->st40_pkt_idx;
469471
if (s->ops.interlaced) {
470472
if (frame_info->tc_meta.second_field)
471-
rtp->f = 0b11;
473+
rtp->first_hdr_chunk.f = 0b11;
472474
else
473-
rtp->f = 0b10;
475+
rtp->first_hdr_chunk.f = 0b10;
474476
} else {
475-
rtp->f = 0b00;
477+
rtp->first_hdr_chunk.f = 0b00;
476478
}
477479
if (idx == anc_count) rtp->base.marker = 1;
478480
dbg("%s(%d), anc_count %d, payload_size %d\n", __func__, s->idx, anc_count,
479481
payload_size);
480482

483+
rtp->swapped_first_hdr_chunk = htonl(rtp->swapped_first_hdr_chunk);
484+
481485
udp->dgram_len = htons(pkt->pkt_len - pkt->l2_len - pkt->l3_len);
482486
ipv4->total_length = htons(pkt->pkt_len - pkt->l2_len);
483487

@@ -553,16 +557,19 @@ static int tx_ancillary_session_build_rtp_packet(struct st_tx_ancillary_session_
553557
pkt->data_len = payload_size + sizeof(struct st40_rfc8331_rtp_hdr);
554558
pkt->pkt_len = pkt->data_len;
555559
rtp->length = htons(payload_size);
556-
rtp->anc_count = idx - anc_idx;
560+
rtp->first_hdr_chunk.anc_count = idx - anc_idx;
557561
if (s->ops.interlaced) {
558562
if (frame_info->tc_meta.second_field)
559-
rtp->f = 0b11;
563+
rtp->first_hdr_chunk.f = 0b11;
560564
else
561-
rtp->f = 0b10;
565+
rtp->first_hdr_chunk.f = 0b10;
562566
} else {
563-
rtp->f = 0b00;
567+
rtp->first_hdr_chunk.f = 0b00;
564568
}
565569
if (idx == anc_count) rtp->base.marker = 1;
570+
571+
rtp->swapped_first_hdr_chunk = htonl(rtp->swapped_first_hdr_chunk);
572+
566573
dbg("%s(%d), anc_count %d, payload_size %d\n", __func__, s->idx, anc_count,
567574
payload_size);
568575
return idx;
@@ -595,7 +602,8 @@ static int tx_ancillary_session_rtp_update_packet(struct mtl_main_impl* impl,
595602
bool second_field = false;
596603
if (s->ops.interlaced) {
597604
struct st40_rfc8331_rtp_hdr* rfc8331 = (struct st40_rfc8331_rtp_hdr*)rtp;
598-
second_field = (rfc8331->f == 0b11) ? true : false;
605+
second_field = (rfc8331->first_hdr_chunk.f == 0b11) ? true : false;
606+
rfc8331->swapped_first_hdr_chunk = htonl(rfc8331->swapped_first_hdr_chunk);
599607
}
600608
tx_ancillary_session_sync_pacing(impl, s, false, 0, second_field);
601609
}
@@ -651,14 +659,16 @@ static int tx_ancillary_session_build_packet_chain(struct mtl_main_impl* impl,
651659
bool second_field = false;
652660
if (s->ops.interlaced) {
653661
struct st40_rfc8331_rtp_hdr* rfc8331 = (struct st40_rfc8331_rtp_hdr*)&udp[1];
654-
second_field = (rfc8331->f == 0b11) ? true : false;
662+
second_field = (rfc8331->first_hdr_chunk.f == 0b11) ? true : false;
663+
rfc8331->swapped_first_hdr_chunk = htonl(rfc8331->swapped_first_hdr_chunk);
655664
}
656665
tx_ancillary_session_sync_pacing(impl, s, false, 0, second_field);
657666
}
658667
if (s->ops.flags & ST40_TX_FLAG_USER_TIMESTAMP) {
659668
s->pacing.rtp_time_stamp = ntohl(rtp->base.tmstamp);
660669
}
661670
rtp->base.tmstamp = htonl(s->pacing.rtp_time_stamp);
671+
rtp->swapped_first_hdr_chunk = htonl(rtp->swapped_first_hdr_chunk);
662672
}
663673
}
664674

tests/tools/RxTxApp/src/rx_ancillary_app.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ static void app_rx_anc_handle_rtp(struct st_app_rx_anc_session* s, void* usrptr)
88
struct st40_rfc8331_rtp_hdr* hdr = (struct st40_rfc8331_rtp_hdr*)usrptr;
99
struct st40_rfc8331_payload_hdr* payload_hdr =
1010
(struct st40_rfc8331_payload_hdr*)(&hdr[1]);
11-
int anc_count = hdr->anc_count;
11+
12+
int anc_count = hdr->first_hdr_chunk.anc_count;
1213
int idx, total_size, payload_len;
1314
dbg("%s(%d), anc_count %d\n", __func__, s->idx, anc_count);
1415

tests/tools/RxTxApp/src/tx_ancillary_app.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,20 +196,21 @@ static void app_tx_anc_build_rtp(struct st_app_tx_anc_session* s, void* usrptr,
196196
uint16_t* mbuf_len) {
197197
/* generate one anc rtp for test purpose */
198198
struct st40_rfc8331_rtp_hdr* hdr = (struct st40_rfc8331_rtp_hdr*)usrptr;
199+
199200
struct st40_rfc8331_payload_hdr* payload_hdr =
200201
(struct st40_rfc8331_payload_hdr*)(&hdr[1]);
201202
uint16_t udw_size = s->st40_source_end - s->st40_frame_cursor > 255
202203
? 255
203204
: s->st40_source_end - s->st40_frame_cursor;
204205
uint16_t check_sum, total_size, payload_len;
205206
hdr->base.marker = 1;
206-
hdr->anc_count = 1;
207+
hdr->first_hdr_chunk.anc_count = 1;
207208
hdr->base.payload_type = s->st40_payload_type;
208209
hdr->base.version = 2;
209210
hdr->base.extension = 0;
210211
hdr->base.padding = 0;
211212
hdr->base.csrc_count = 0;
212-
hdr->f = 0b00;
213+
hdr->first_hdr_chunk.f = 0b00;
213214
hdr->base.tmstamp = s->st40_rtp_tmstamp;
214215
hdr->base.ssrc = htonl(0x88888888 + s->idx);
215216
/* update rtp seq*/
@@ -242,6 +243,7 @@ static void app_tx_anc_build_rtp(struct st_app_tx_anc_session* s, void* usrptr,
242243
sizeof(struct st40_rfc8331_payload_hdr) - 4 + total_size; // Full size of one ANC
243244
*mbuf_len = payload_len + sizeof(struct st40_rfc8331_rtp_hdr);
244245
hdr->length = htons(payload_len);
246+
245247
s->st40_frame_cursor += udw_size;
246248
if (s->st40_frame_cursor == s->st40_source_end)
247249
s->st40_frame_cursor = s->st40_source_begin;

tests/unittest/st40_test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ static int tx_anc_build_rtp_packet(tests_context* s, struct st40_rfc8331_rtp_hdr
3636
/* rtp hdr */
3737
memset(rtp, 0x0, sizeof(*rtp));
3838
rtp->base.marker = 1;
39-
rtp->anc_count = 0;
39+
rtp->first_hdr_chunk.anc_count = 0;
4040
rtp->base.payload_type = ST40_TEST_PAYLOAD_TYPE;
4141
rtp->base.version = 2;
4242
rtp->base.extension = 0;
4343
rtp->base.padding = 0;
4444
rtp->base.csrc_count = 0;
45-
rtp->f = 0b00;
45+
rtp->first_hdr_chunk.f = 0b00;
4646
rtp->base.tmstamp = s->rtp_tmstamp;
4747
rtp->base.ssrc = htonl(0x88888888 + s->idx);
4848
/* update rtp seq*/
@@ -64,7 +64,7 @@ static int tx_anc_build_rtp_packet(tests_context* s, struct st40_rfc8331_rtp_hdr
6464
payload_hdr->second_hdr_chunk.data_count = st40_add_parity_bits(udw_size);
6565
payload_hdr->swapped_first_hdr_chunk = htonl(payload_hdr->swapped_first_hdr_chunk);
6666
payload_hdr->swapped_second_hdr_chunk = htonl(payload_hdr->swapped_second_hdr_chunk);
67-
rtp->anc_count = 1;
67+
rtp->first_hdr_chunk.anc_count = 1;
6868
for (int i = 0; i < udw_size; i++) {
6969
st40_set_udw(i + 3,
7070
st40_add_parity_bits(s->frame_buf[s->seq_id % TEST_SHA_HIST_NUM][i]),
@@ -131,7 +131,7 @@ static int tx_rtp_done(void* args) {
131131
static void rx_handle_rtp(tests_context* s, struct st40_rfc8331_rtp_hdr* hdr) {
132132
struct st40_rfc8331_payload_hdr* payload_hdr =
133133
(struct st40_rfc8331_payload_hdr*)(&hdr[1]);
134-
int anc_count = hdr->anc_count;
134+
int anc_count = hdr->first_hdr_chunk.anc_count;
135135
int idx, total_size, payload_len;
136136

137137
for (idx = 0; idx < anc_count; idx++) {

0 commit comments

Comments
 (0)