@@ -96,6 +96,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_mtl_st40_rx_debug);
96
96
enum {
97
97
PROP_ST40_RX_BUFFER_SIZE = PROP_GENERAL_MAX ,
98
98
PROP_ST40_RX_TIMEOUT_MBUF_GET ,
99
+ PROP_ST40_RX_INCLUDE_METADATA_IN_BUFFER ,
99
100
PROP_MAX
100
101
};
101
102
@@ -108,8 +109,6 @@ G_DEFINE_TYPE_WITH_CODE(Gst_Mtl_St40_Rx, gst_mtl_st40_rx, GST_TYPE_BASE_SRC,
108
109
GST_DEBUG_CATEGORY_INIT (gst_mtl_st40_rx_debug , "mtl_st40_rx" , 0 ,
109
110
"MTL St2110 st40 transmission src" ));
110
111
111
- #define IS_POWER_OF_2 (x ) (((x) & ((x)-1)) == 0)
112
-
113
112
GST_ELEMENT_REGISTER_DEFINE (mtl_st40_rx , "mtl_st40_rx" , GST_RANK_NONE ,
114
113
GST_TYPE_MTL_ST40_RX );
115
114
@@ -131,6 +130,8 @@ static GstFlowReturn gst_mtl_st40_rx_fill_buffer(Gst_Mtl_St40_Rx* src, GstBuffer
131
130
void * usrptr );
132
131
static guint gst_mtl_st40_rx_parse_port_arguments (struct st40_rx_ops * ops_rx ,
133
132
SessionPortArgs * portArgs );
133
+ static struct st40_rfc8331_payload_hdr * gst_mtl_st40_rx_shift_payload_hdr (
134
+ struct st40_rfc8331_payload_hdr * payload_hdr , int udw_size );
134
135
135
136
static gint gst_mtl_st40_rx_mbuff_available (void * priv ) {
136
137
Gst_Mtl_St40_Rx * src = (Gst_Mtl_St40_Rx * )priv ;
@@ -179,6 +180,12 @@ static void gst_mtl_st40_rx_class_init(Gst_Mtl_St40_RxClass* klass) {
179
180
g_param_spec_uint ("timeout" , "Timeout for Mbuf" ,
180
181
"Timeout in seconds for getting mbuf" , 0 , G_MAXUINT , 10 ,
181
182
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
183
+
184
+ g_object_class_install_property (
185
+ gobject_class , PROP_ST40_RX_INCLUDE_METADATA_IN_BUFFER ,
186
+ g_param_spec_boolean ("include-metadata-in-buffer" , "Include Metadata in Buffer" ,
187
+ "Whether to include metadata in the output buffer" , FALSE,
188
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ));
182
189
}
183
190
184
191
static guint gst_mtl_st40_rx_parse_port_arguments (struct st40_rx_ops * ops_rx ,
@@ -319,6 +326,9 @@ static void gst_mtl_st40_rx_set_property(GObject* object, guint prop_id,
319
326
case PROP_ST40_RX_TIMEOUT_MBUF_GET :
320
327
self -> timeout_mbuf_get_seconds = g_value_get_uint (value );
321
328
break ;
329
+ case PROP_ST40_RX_INCLUDE_METADATA_IN_BUFFER :
330
+ self -> include_metadata_in_buffer = g_value_get_boolean (value );
331
+ break ;
322
332
default :
323
333
G_OBJECT_WARN_INVALID_PROPERTY_ID (object , prop_id , pspec );
324
334
break ;
@@ -342,6 +352,9 @@ static void gst_mtl_st40_rx_get_property(GObject* object, guint prop_id, GValue*
342
352
case PROP_ST40_RX_TIMEOUT_MBUF_GET :
343
353
g_value_set_uint (value , src -> timeout_mbuf_get_seconds );
344
354
break ;
355
+ case PROP_ST40_RX_INCLUDE_METADATA_IN_BUFFER :
356
+ g_value_set_boolean (value , src -> include_metadata_in_buffer );
357
+ break ;
345
358
default :
346
359
G_OBJECT_WARN_INVALID_PROPERTY_ID (object , prop_id , pspec );
347
360
break ;
@@ -372,42 +385,100 @@ static void* gst_mtl_st40_rx_get_mbuf_with_timeout(Gst_Mtl_St40_Rx* src,
372
385
return mbuf ;
373
386
}
374
387
388
+ static struct st40_rfc8331_payload_hdr * gst_mtl_st40_rx_shift_payload_hdr (
389
+ struct st40_rfc8331_payload_hdr * payload_hdr , int udw_size ) {
390
+ int package_size ;
391
+ int payload_len ;
392
+
393
+ package_size = ((3 + udw_size + 1 ) * 10 ) / 8 ;
394
+ package_size = (4 - package_size % 4 ) + package_size ;
395
+ payload_len = sizeof (struct st40_rfc8331_payload_hdr ) - 4 + package_size ;
396
+
397
+ return (struct st40_rfc8331_payload_hdr * )((uint8_t * )payload_hdr + payload_len );
398
+ }
399
+
375
400
static GstFlowReturn gst_mtl_st40_rx_fill_buffer (Gst_Mtl_St40_Rx * src , GstBuffer * * buffer ,
376
401
void * usrptr ) {
377
402
struct st40_rfc8331_rtp_hdr * hdr ;
378
- struct st40_rfc8331_payload_hdr * payload_hdr , payload_hdr_swapped ;
403
+ struct st40_rfc8331_payload_hdr * payload_hdr ;
379
404
GstMapInfo dest_info ;
380
- guint16 data , fill_size ;
381
- gint udw_size ;
405
+ guint16 data ;
406
+ gint udw_size , anc_count ;
407
+ guint buffer_size = 0 , meta_offset ;
382
408
383
409
hdr = (struct st40_rfc8331_rtp_hdr * )usrptr ;
410
+ anc_count = hdr -> anc_count ;
411
+
412
+
413
+ if (anc_count == 0 || anc_count > ST40_RFC8331_PAYLOAD_MAX_ANCILLARY_COUNT ) {
414
+ GST_ERROR ("Ancillary data count: %d (must be between 1 and %d)" , anc_count , ST40_RFC8331_PAYLOAD_MAX_ANCILLARY_COUNT );
415
+ return GST_FLOW_ERROR ;
416
+ }
417
+
418
+ /* local is fine anc_count will not be bigger than 20*/
419
+ guint8 * anc_data [anc_count ];
420
+ guint8 anc_data_count [anc_count ];
384
421
385
422
payload_hdr = (struct st40_rfc8331_payload_hdr * )(& hdr [1 ]);
423
+ for (int i = 0 ; i < anc_count ; i ++ ) {
424
+ payload_hdr -> swapped_first_hdr_chunk = ntohl (payload_hdr -> swapped_first_hdr_chunk );
425
+ payload_hdr -> swapped_second_hdr_chunk = ntohl (payload_hdr -> swapped_second_hdr_chunk );
426
+ if (!st40_check_parity_bits (payload_hdr -> second_hdr_chunk .did )) {
427
+ GST_ERROR ("Parity check failed for DID" );
428
+ return GST_FLOW_ERROR ;
429
+ }
430
+ if (!st40_check_parity_bits (payload_hdr -> second_hdr_chunk .sdid )) {
431
+ GST_ERROR ("Parity check failed for SDID" );
432
+ return GST_FLOW_ERROR ;
433
+ }
434
+ if (!st40_check_parity_bits (payload_hdr -> second_hdr_chunk .data_count )) {
435
+ GST_ERROR ("Parity check failed for Data Count" );
436
+ return GST_FLOW_ERROR ;
437
+ }
386
438
387
- hdr -> swapped_first_hdr_chunk = ntohl (hdr -> swapped_first_hdr_chunk );
439
+ udw_size = payload_hdr -> second_hdr_chunk .data_count & 0xff ;
440
+ anc_data_count [i ] = udw_size ;
441
+ meta_offset = 0 ;
442
+ buffer_size += udw_size ;
443
+
444
+ if (src -> include_metadata_in_buffer ) {
445
+ buffer_size += ST40_BYTE_SIZE_OF_PAYLOAD_METADATA ;
446
+ anc_data [i ] = malloc (udw_size + ST40_BYTE_SIZE_OF_PAYLOAD_METADATA );
447
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> first_hdr_chunk .c ;
448
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> first_hdr_chunk .line_number ;
449
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> first_hdr_chunk .horizontal_offset ;
450
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> first_hdr_chunk .s ;
451
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> first_hdr_chunk .stream_num ;
452
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> second_hdr_chunk .did & 0xff ;
453
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> second_hdr_chunk .sdid & 0xff ;
454
+ anc_data [i ][meta_offset ++ ] = payload_hdr -> second_hdr_chunk .data_count & 0xff ;
455
+ } else {
456
+ anc_data [i ] = malloc (udw_size );
457
+ }
388
458
389
- payload_hdr_swapped .swapped_second_hdr_chunk =
390
- ntohl (payload_hdr -> swapped_second_hdr_chunk );
391
- udw_size = payload_hdr_swapped .second_hdr_chunk .data_count & 0xff ;
459
+ payload_hdr -> swapped_second_hdr_chunk = htonl (payload_hdr -> swapped_second_hdr_chunk );
460
+ if (!anc_data [i ]) {
461
+ GST_ERROR ("Failed to allocate memory for ancillary data" );
462
+ for (int j = 0 ; j < i ; j ++ )
463
+ free (anc_data [j ]);
464
+ return GST_FLOW_ERROR ;
465
+ }
392
466
393
- if (udw_size == 0 ) {
394
- GST_ERROR ("Ancillary data size is 0" );
395
- return GST_FLOW_ERROR ;
396
- } else if (src -> udw_size == 0 ) {
397
- src -> udw_size = udw_size ;
398
- src -> anc_data = (char * )malloc (udw_size );
399
- } else if (src -> udw_size != udw_size ) {
400
- GST_INFO ("Size of received ancillary data has changed" );
401
- if (src -> anc_data ) {
402
- free (src -> anc_data );
403
- src -> anc_data = NULL ;
467
+ for (int d = 0 ; d < udw_size ; d ++ ) {
468
+ data = st40_get_udw (d + 3 , (uint8_t * )& payload_hdr -> second_hdr_chunk );
469
+ if (!st40_check_parity_bits (data )) {
470
+ GST_ERROR ("Ancillary data parity bits check failed, data=0x%03x" , data & 0x3FF );
471
+ for (int j = 0 ; j < i ; j ++ )
472
+ free (anc_data [j ]);
473
+ return GST_FLOW_ERROR ;
474
+ }
475
+ anc_data [i ][d + meta_offset ] = data & 0xff ;
404
476
}
405
477
406
- src -> udw_size = udw_size ;
407
- src -> anc_data = (char * )malloc (udw_size );
478
+ payload_hdr = gst_mtl_st40_rx_shift_payload_hdr (payload_hdr , udw_size );
408
479
}
409
480
410
- * buffer = gst_buffer_new_allocate (NULL , src -> udw_size , NULL );
481
+ * buffer = gst_buffer_new_allocate (NULL , buffer_size , NULL );
411
482
if (!* buffer ) {
412
483
GST_ERROR ("Failed to allocate space for the buffer" );
413
484
return GST_FLOW_ERROR ;
@@ -418,21 +489,21 @@ static GstFlowReturn gst_mtl_st40_rx_fill_buffer(Gst_Mtl_St40_Rx* src, GstBuffer
418
489
return GST_FLOW_ERROR ;
419
490
}
420
491
421
- for (int i = 0 ; i < udw_size ; i ++ ) {
422
- data = st40_get_udw (i + 3 , (uint8_t * )& payload_hdr -> second_hdr_chunk );
423
- if (!st40_check_parity_bits (data )) {
424
- GST_ERROR ("Ancillary data parity bits check failed" );
425
- return GST_FLOW_ERROR ;
426
- }
427
- src -> anc_data [i ] = data & 0xff ;
492
+ guint fill_size = 0 ;
493
+ for (int i = 0 ; i < anc_count ; i ++ ) {
494
+ fill_size += gst_buffer_fill (* buffer , fill_size , anc_data [i ], anc_data_count [i ] + meta_offset );
495
+ free (anc_data [i ]);
496
+ }
497
+ /* Print the whole buffer for debugging */
498
+ for (guint i = 0 ; i < buffer_size ; i ++ ) {
499
+ printf ("%02x " , dest_info .data [i ]);
428
500
}
501
+ printf ("\n" );
429
502
430
- fill_size = gst_buffer_fill (* buffer , 0 , src -> anc_data , udw_size );
431
503
gst_buffer_unmap (* buffer , & dest_info );
432
504
433
- if (fill_size != src -> udw_size ) {
434
- GST_ERROR ("Failed to fill buffer" );
435
- return GST_FLOW_ERROR ;
505
+ if (fill_size != buffer_size ) {
506
+ GST_ERROR ("Failed to fill buffer (buffer size = %d, fill size = %d)" , buffer_size , fill_size );;
436
507
}
437
508
438
509
return GST_FLOW_OK ;
@@ -478,8 +549,6 @@ static GstFlowReturn gst_mtl_st40_rx_create(GstBaseSrc* basesrc, guint64 offset,
478
549
static void gst_mtl_st40_rx_finalize (GObject * object ) {
479
550
Gst_Mtl_St40_Rx * src = GST_MTL_ST40_RX (object );
480
551
481
- if (src -> anc_data ) free (src -> anc_data );
482
-
483
552
if (src -> rx_handle ) {
484
553
if (st40_rx_free (src -> rx_handle )) {
485
554
GST_ERROR ("Failed to free rx handle" );
0 commit comments