Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Framerate parsing in gst mtl plugins #1063

Merged
merged 5 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 0 additions & 81 deletions ecosystem/gstreamer_plugin/gst_mtl_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,87 +31,6 @@ gboolean gst_mtl_common_parse_input_finfo(const GstVideoFormatInfo* finfo,
return TRUE;
}

gboolean gst_mtl_common_parse_fps_code(gint fps_code, enum st_fps* fps) {
if (!fps) {
GST_ERROR("Invalid fps pointer");
return FALSE;
}

switch (fps_code) {
case GST_MTL_SUPPORTED_FPS_120:
*fps = ST_FPS_P120;
break;
case GST_MTL_SUPPORTED_FPS_119_88:
*fps = ST_FPS_P119_88;
break;
case GST_MTL_SUPPORTED_FPS_100:
*fps = ST_FPS_P100;
break;
case GST_MTL_SUPPORTED_FPS_60:
*fps = ST_FPS_P60;
break;
case GST_MTL_SUPPORTED_FPS_59_94:
*fps = ST_FPS_P59_94;
break;
case GST_MTL_SUPPORTED_FPS_50:
*fps = ST_FPS_P50;
break;
case GST_MTL_SUPPORTED_FPS_30:
*fps = ST_FPS_P30;
break;
case GST_MTL_SUPPORTED_FPS_29_97:
*fps = ST_FPS_P29_97;
break;
case GST_MTL_SUPPORTED_FPS_25:
*fps = ST_FPS_P25;
break;
case GST_MTL_SUPPORTED_FPS_24:
*fps = ST_FPS_P24;
break;
case GST_MTL_SUPPORTED_FPS_23_98:
*fps = ST_FPS_P23_98;
break;
default:
return FALSE;
}

return TRUE;
}

gboolean gst_mtl_common_parse_fps(GstVideoInfo* info, enum st_fps* fps) {
gint fps_div;
if (info->fps_n <= 0 || info->fps_d <= 0) {
return FALSE;
}

fps_div = info->fps_n / info->fps_d;

switch (fps_div) {
case 24:
*fps = ST_FPS_P24;
break;
case 25:
*fps = ST_FPS_P25;
break;
case 30:
*fps = ST_FPS_P30;
break;
case 50:
*fps = ST_FPS_P50;
break;
case 60:
*fps = ST_FPS_P60;
break;
case 120:
*fps = ST_FPS_P120;
break;
default:
return FALSE;
}

return TRUE;
}

/* includes all formats supported by the library for future support */
gboolean gst_mtl_common_parse_pixel_format(const char* format, enum st_frame_fmt* fmt) {
if (!fmt || !format) {
Expand Down
18 changes: 2 additions & 16 deletions ecosystem/gstreamer_plugin/gst_mtl_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#define NS_PER_S (1000 * NS_PER_MS)
#endif

#define DEFAULT_FRAMERATE 30

enum {
PROP_GENERAL_0,
PROP_GENERAL_LOG_LEVEL,
Expand All @@ -42,20 +44,6 @@ enum {
PROP_GENERAL_MAX
};

enum gst_mtl_supported_fps {
GST_MTL_SUPPORTED_FPS_23_98 = 2398,
GST_MTL_SUPPORTED_FPS_24 = 24,
GST_MTL_SUPPORTED_FPS_25 = 25,
GST_MTL_SUPPORTED_FPS_29_97 = 2997,
GST_MTL_SUPPORTED_FPS_30 = 30,
GST_MTL_SUPPORTED_FPS_50 = 50,
GST_MTL_SUPPORTED_FPS_59_94 = 5994,
GST_MTL_SUPPORTED_FPS_60 = 60,
GST_MTL_SUPPORTED_FPS_100 = 100,
GST_MTL_SUPPORTED_FPS_119_88 = 11988,
GST_MTL_SUPPORTED_FPS_120 = 120
};

enum gst_mtl_supported_audio_sampling {
GST_MTL_SUPPORTED_AUDIO_SAMPLING_44_1K = 44100,
GST_MTL_SUPPORTED_AUDIO_SAMPLING_48K = 48000,
Expand All @@ -79,8 +67,6 @@ typedef struct SessionPortArgs {

gboolean gst_mtl_common_parse_input_finfo(const GstVideoFormatInfo* finfo,
enum st_frame_fmt* fmt);
gboolean gst_mtl_common_parse_fps(GstVideoInfo* info, enum st_fps* fps);
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);
Expand Down
30 changes: 19 additions & 11 deletions ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,9 @@ static void gst_mtl_st20p_rx_class_init(Gst_Mtl_St20p_RxClass* klass) {

g_object_class_install_property(
gobject_class, PROP_ST20P_RX_FRAMERATE,
g_param_spec_uint("rx-fps", "Video framerate", "Framerate of the video.", 0,
G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_param_spec_fraction("rx-fps", "Video framerate", "Framerate of the video", 1, 1,
G_MAXINT, 1, DEFAULT_FRAMERATE, 1,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property(
gobject_class, PROP_ST20P_RX_FRAMEBUFF_NUM,
Expand Down Expand Up @@ -235,8 +236,9 @@ static gboolean gst_mtl_st20p_rx_start(GstBaseSrc* basesrc) {
ops_rx->interlaced = src->interlaced;
ops_rx->flags |= ST20P_RX_FLAG_BLOCK_GET;

if (!src->framerate || !gst_mtl_common_parse_fps_code(src->framerate, &ops_rx->fps)) {
GST_ERROR("Failed to parse custom ops_rx fps code %d", src->framerate);
ops_rx->fps = st_frame_rate_to_st_fps((double)src->fps_n / src->fps_d);
if (ops_rx->fps == ST_FPS_MAX) {
GST_ERROR("Invalid framerate: %d/%d", src->fps_n, src->fps_d);
return FALSE;
}

Expand Down Expand Up @@ -322,7 +324,8 @@ static void gst_mtl_st20p_rx_set_property(GObject* object, guint prop_id,
self->retry_frame = g_value_get_uint(value);
break;
case PROP_ST20P_RX_FRAMERATE:
self->framerate = g_value_get_uint(value);
self->fps_n = gst_value_get_fraction_numerator(value);
self->fps_d = gst_value_get_fraction_denominator(value);
break;
case PROP_ST20P_RX_FRAMEBUFF_NUM:
self->framebuffer_num = g_value_get_uint(value);
Expand Down Expand Up @@ -360,7 +363,7 @@ static void gst_mtl_st20p_rx_get_property(GObject* object, guint prop_id, GValue
g_value_set_uint(value, src->retry_frame);
break;
case PROP_ST20P_RX_FRAMERATE:
g_value_set_uint(value, src->framerate);
gst_value_set_fraction(value, src->fps_n, src->fps_d);
break;
case PROP_ST20P_RX_FRAMEBUFF_NUM:
g_value_set_uint(value, src->framebuffer_num);
Expand Down Expand Up @@ -407,6 +410,11 @@ static gboolean gst_mtl_st20p_rx_negotiate(GstBaseSrc* basesrc) {
*/
info->interlace_mode = src->interlaced;

info->width = src->width;
info->height = src->height;
info->fps_n = src->fps_n;
info->fps_d = src->fps_d;

switch (ops_rx->output_fmt) {
case ST_FRAME_FMT_V210:
info->finfo = gst_video_format_get_info(GST_VIDEO_FORMAT_v210);
Expand All @@ -420,11 +428,11 @@ static gboolean gst_mtl_st20p_rx_negotiate(GstBaseSrc* basesrc) {
return FALSE;
}

caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING,
gst_video_format_to_string(info->finfo->format), "width",
G_TYPE_INT, info->width, "height", G_TYPE_INT, info->height,
"framerate", GST_TYPE_FRACTION, info->fps_n, 1,
"interlace-mode", G_TYPE_BOOLEAN, src->interlaced, NULL);
caps = gst_caps_new_simple(
"video/x-raw", "format", G_TYPE_STRING,
gst_video_format_to_string(info->finfo->format), "width", G_TYPE_INT, info->width,
"height", G_TYPE_INT, info->height, "framerate", GST_TYPE_FRACTION, info->fps_n,
info->fps_d, "interlace-mode", G_TYPE_BOOLEAN, info->interlace_mode, NULL);

if (!caps) caps = gst_pad_get_pad_template_caps(GST_BASE_SRC_PAD(basesrc));

Expand Down
2 changes: 1 addition & 1 deletion ecosystem/gstreamer_plugin/gst_mtl_st20p_rx.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ struct _Gst_Mtl_St20p_Rx {
gboolean interlaced;
gchar pixel_format[MTL_PORT_MAX_LEN];
guint framebuffer_num;
guint framerate;
guint fps_n, fps_d;

/* TODO add support for gpu direct */
#ifdef MTL_GPU_DIRECT_ENABLED
Expand Down
27 changes: 17 additions & 10 deletions ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,9 @@ static void gst_mtl_st20p_tx_class_init(Gst_Mtl_St20p_TxClass* klass) {

g_object_class_install_property(
gobject_class, PROP_ST20P_TX_FRAMERATE,
g_param_spec_uint("tx-fps", "Video framerate", "Framerate of the video.", 0,
G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_param_spec_fraction("tx-fps", "Video framerate", "Framerate of the video.", 1,
1, G_MAXINT, G_MAXINT, 0, 1,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property(
gobject_class, PROP_ST20P_TX_FRAMEBUFF_NUM,
Expand Down Expand Up @@ -226,7 +227,8 @@ static void gst_mtl_st20p_tx_set_property(GObject* object, guint prop_id,
self->retry_frame = g_value_get_uint(value);
break;
case PROP_ST20P_TX_FRAMERATE:
self->framerate = g_value_get_uint(value);
self->fps_n = gst_value_get_fraction_numerator(value);
self->fps_d = gst_value_get_fraction_denominator(value);
break;
case PROP_ST20P_TX_FRAMEBUFF_NUM:
self->framebuffer_num = g_value_get_uint(value);
Expand All @@ -252,7 +254,7 @@ static void gst_mtl_st20p_tx_get_property(GObject* object, guint prop_id, GValue
g_value_set_uint(value, sink->retry_frame);
break;
case PROP_ST20P_TX_FRAMERATE:
g_value_set_uint(value, sink->framerate);
gst_value_set_fraction(value, sink->fps_n, sink->fps_d);
break;
case PROP_ST20P_TX_FRAMEBUFF_NUM:
g_value_set_uint(value, sink->framebuffer_num);
Expand Down Expand Up @@ -304,14 +306,19 @@ static gboolean gst_mtl_st20p_tx_session_create(Gst_Mtl_St20p_Tx* sink, GstCaps*
return FALSE;
}

if (sink->framerate) {
if (!gst_mtl_common_parse_fps_code(sink->framerate, &ops_tx.fps)) {
GST_ERROR("Failed to parse custom ops_tx fps code %d", sink->framerate);
if (sink->fps_n > 0 && sink->fps_d > 0) {
ops_tx.fps = st_frame_rate_to_st_fps((double)sink->fps_n / sink->fps_d);
if (ops_tx.fps == ST_FPS_MAX) {
GST_ERROR("Invalid framerate: %d/%d", sink->fps_n, sink->fps_d);
return FALSE;
}
} else {
ops_tx.fps = st_frame_rate_to_st_fps((double)info->fps_n / info->fps_d);
DawidWesierski4 marked this conversation as resolved.
Show resolved Hide resolved
if (ops_tx.fps == ST_FPS_MAX) {
GST_ERROR("Failed to parse caps fps. Caps fps_n: %d, fps_d: %d", info->fps_n,
info->fps_d);
return FALSE;
}
} else if (!gst_mtl_common_parse_fps(info, &ops_tx.fps)) {
GST_ERROR("Failed to parse fps");
return FALSE;
}

if (inet_pton(AF_INET, sink->portArgs.session_ip_string,
Expand Down
2 changes: 1 addition & 1 deletion ecosystem/gstreamer_plugin/gst_mtl_st20p_tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ struct _Gst_Mtl_St20p_Tx {
StDevArgs devArgs; /* imtl initialization device */
SessionPortArgs portArgs; /* imtl session device */
guint framebuffer_num;
guint framerate;
guint fps_n, fps_d;

/* TODO add support for gpu direct */
#ifdef MTL_GPU_DIRECT_ENABLED
Expand Down
6 changes: 0 additions & 6 deletions ecosystem/gstreamer_plugin/gst_mtl_st30p_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ GST_DEBUG_CATEGORY_STATIC(gst_mtl_st30p_rx_debug);

enum {
PROP_ST30P_RX_RETRY = PROP_GENERAL_MAX,
PROP_ST30P_RX_FRAMERATE,
PROP_ST30P_RX_FRAMEBUFF_NUM,
PROP_ST30P_RX_CHANNEL,
PROP_ST30P_RX_SAMPLING,
Expand Down Expand Up @@ -156,11 +155,6 @@ static void gst_mtl_st30p_rx_class_init(Gst_Mtl_St30p_RxClass* klass) {

gst_mtl_common_init_general_arguments(gobject_class);

g_object_class_install_property(
gobject_class, PROP_ST30P_RX_FRAMERATE,
g_param_spec_uint("rx-fps", "Audio framerate", "Framerate of the audio.", 0,
G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property(
gobject_class, PROP_ST30P_RX_FRAMEBUFF_NUM,
g_param_spec_uint("rx-framebuff-num", "Number of framebuffers",
Expand Down
7 changes: 0 additions & 7 deletions ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ GST_DEBUG_CATEGORY_STATIC(gst_mtl_st30p_tx_debug);

enum {
PROP_ST30P_TX_RETRY = PROP_GENERAL_MAX,
PROP_ST30P_TX_FRAMERATE,
PROP_ST30P_TX_FRAMEBUFF_NUM,
PROP_ST30P_TX_PTIME,
PROP_MAX
Expand Down Expand Up @@ -216,9 +215,6 @@ static void gst_mtl_st30p_tx_set_property(GObject* object, guint prop_id,
case PROP_ST30P_TX_RETRY:
self->retry_frame = g_value_get_uint(value);
break;
case PROP_ST30P_TX_FRAMERATE:
self->framerate = g_value_get_uint(value);
break;
case PROP_ST30P_TX_FRAMEBUFF_NUM:
self->framebuffer_num = g_value_get_uint(value);
break;
Expand All @@ -245,9 +241,6 @@ static void gst_mtl_st30p_tx_get_property(GObject* object, guint prop_id, GValue
case PROP_ST30P_TX_RETRY:
g_value_set_uint(value, sink->retry_frame);
break;
case PROP_ST30P_TX_FRAMERATE:
g_value_set_uint(value, sink->framerate);
break;
case PROP_ST30P_TX_FRAMEBUFF_NUM:
g_value_set_uint(value, sink->framebuffer_num);
break;
Expand Down
1 change: 0 additions & 1 deletion ecosystem/gstreamer_plugin/gst_mtl_st30p_tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ struct _Gst_Mtl_St30p_Tx {
StDevArgs devArgs; /* imtl initialization device */
SessionPortArgs portArgs; /* imtl tx session */
guint framebuffer_num;
guint framerate;
gchar ptime[MTL_PORT_MAX_LEN];
};

Expand Down
23 changes: 11 additions & 12 deletions ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,9 @@ static void gst_mtl_st40p_tx_class_init(Gst_Mtl_St40p_TxClass* klass) {

g_object_class_install_property(
gobject_class, PROP_ST40P_TX_FRAMERATE,
g_param_spec_uint(
"tx-fps", "framerate of the related video",
"Framerate of the video to witch the ancillary data is synchronized.", 0,
G_MAXUINT, 60, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_param_spec_fraction("tx-fps", "Video framerate", "Framerate of the video.", 1,
1, G_MAXINT, 1, DEFAULT_FRAMERATE, 1,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

g_object_class_install_property(
gobject_class, PROP_ST40P_TX_DID,
Expand Down Expand Up @@ -228,7 +227,8 @@ static void gst_mtl_st40p_tx_set_property(GObject* object, guint prop_id,
self->framebuff_cnt = g_value_get_uint(value);
break;
case PROP_ST40P_TX_FRAMERATE:
self->framerate = g_value_get_uint(value);
self->fps_n = gst_value_get_fraction_numerator(value);
self->fps_d = gst_value_get_fraction_denominator(value);
break;
case PROP_ST40P_TX_DID:
self->did = g_value_get_uint(value);
Expand Down Expand Up @@ -257,7 +257,7 @@ static void gst_mtl_st40p_tx_get_property(GObject* object, guint prop_id, GValue
g_value_set_uint(value, sink->framebuff_cnt);
break;
case PROP_ST40P_TX_FRAMERATE:
g_value_set_uint(value, sink->framerate);
gst_value_set_fraction(value, sink->fps_n, sink->fps_d);
break;
case PROP_ST40P_TX_DID:
g_value_set_uint(value, sink->did);
Expand Down Expand Up @@ -330,14 +330,13 @@ static gboolean gst_mtl_st40p_tx_session_create(Gst_Mtl_St40p_Tx* sink) {
GST_ERROR("Invalid SDID value: %d", sink->sdid);
return FALSE;
}
if (sink->framerate == 0) {
GST_INFO("Framerate not set, defaulting to 60");
sink->framerate = 60;
}
if (!gst_mtl_common_parse_fps_code(sink->framerate, &ops_tx.fps)) {
GST_ERROR("Failed to parse custom ops_tx fps code %d", sink->framerate);

ops_tx.fps = st_frame_rate_to_st_fps((double)sink->fps_n / sink->fps_d);
if (ops_tx.fps == ST_FPS_MAX) {
GST_ERROR("Invalid framerate: %d/%d", sink->fps_n, sink->fps_d);
return FALSE;
}

ops_tx.interlaced = false;
/* Only single ANC data packet is possible per frame. ANC_Count = 1 TODO: allow more */
sink->frame_size = MAX_UDW_SIZE;
Expand Down
2 changes: 1 addition & 1 deletion ecosystem/gstreamer_plugin/gst_mtl_st40p_tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct _Gst_Mtl_St40p_Tx {
StDevArgs devArgs; /* imtl initialization device */
SessionPortArgs portArgs; /* imtl session device */
guint framebuff_cnt;
guint framerate;
guint fps_n, fps_d;
guint did;
guint sdid;
};
Expand Down
Loading