mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-16 21:14:44 +00:00
video: Add support for big endian DRM formats
When a format is big endian, the 8bith of the fourcc is set. Handle this by using a "_BE" suffix in serialization. The patch also update the design document and introduce a unit test. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8404>
This commit is contained in:
parent
a960985d18
commit
9eec7ddf19
3 changed files with 58 additions and 9 deletions
|
@ -121,10 +121,11 @@ format. For example, `NV12:0x0100000000000002` is a new video format
|
|||
combined by video format NV12 and the modifier `0x0100000000000002`. It's
|
||||
not NV12 and it's not its subset either.
|
||||
|
||||
*DRM_FORMAT* can be printed by using
|
||||
`GST_FOURCC_FORMAT` and `GST_FOURCC_ARGS` macros from the
|
||||
`DRM_FORMAT_*` constants, it is NOT a `GstVideoFormat`, so it would be
|
||||
different from the content of the `format` field in a non-dmabuf caps.
|
||||
The 7 least significant bits of *DRM_FORMAT* is a fourcc. That fourcc is used
|
||||
to serialize it into a string. The result is different from the serialization of
|
||||
gstreamer video formats. The 8th bit is used to indicate that tis is a big
|
||||
endian format. In this case, the serializer will postfix the name with `_BE`.
|
||||
|
||||
A modifier must always be present, except if the modifier is linear,
|
||||
then it should not be included, so `NV12:0x0000000000000000` is
|
||||
invalid, it must be `drm-format=NV12`. DRM fourcc are used
|
||||
|
|
|
@ -434,12 +434,18 @@ gst_video_dma_drm_fourcc_from_string (const gchar * format_str,
|
|||
const gchar *mod_str;
|
||||
guint32 fourcc = DRM_FORMAT_INVALID;
|
||||
guint64 m = DRM_FORMAT_MOD_INVALID;
|
||||
gboolean big_endian = FALSE;
|
||||
|
||||
g_return_val_if_fail (format_str != NULL, 0);
|
||||
|
||||
mod_str = strchr (format_str, ':');
|
||||
if (mod_str) {
|
||||
if (mod_str - format_str != 4) {
|
||||
gint fmt_len = mod_str - format_str;
|
||||
|
||||
/* Handle big endian (FOURCC_BE) case */
|
||||
if (fmt_len == 7 && strstr (format_str + 4, "_BE")) {
|
||||
big_endian = TRUE;
|
||||
} else if (fmt_len != 4) {
|
||||
/* fourcc always has 4 characters. */
|
||||
GST_DEBUG ("%s is not a drm string", format_str);
|
||||
return DRM_FORMAT_INVALID;
|
||||
|
@ -458,7 +464,12 @@ gst_video_dma_drm_fourcc_from_string (const gchar * format_str,
|
|||
return DRM_FORMAT_INVALID;
|
||||
}
|
||||
} else {
|
||||
if (strlen (format_str) != 4) {
|
||||
gint fmt_len = strlen (format_str);
|
||||
|
||||
/* Handle big endian (FOURCC_BE) case */
|
||||
if (fmt_len == 7 && strstr (format_str + 4, "_BE")) {
|
||||
big_endian = TRUE;
|
||||
} else if (fmt_len != 4) {
|
||||
/* fourcc always has 4 characters. */
|
||||
GST_DEBUG ("%s is not a drm string", format_str);
|
||||
return DRM_FORMAT_INVALID;
|
||||
|
@ -470,6 +481,9 @@ gst_video_dma_drm_fourcc_from_string (const gchar * format_str,
|
|||
fourcc = GST_MAKE_FOURCC (format_str[0], format_str[1],
|
||||
format_str[2], format_str[3]);
|
||||
|
||||
if (big_endian)
|
||||
fourcc |= DRM_FORMAT_BIG_ENDIAN;
|
||||
|
||||
if (modifier)
|
||||
*modifier = m;
|
||||
|
||||
|
@ -492,16 +506,23 @@ gst_video_dma_drm_fourcc_from_string (const gchar * format_str,
|
|||
gchar *
|
||||
gst_video_dma_drm_fourcc_to_string (guint32 fourcc, guint64 modifier)
|
||||
{
|
||||
gboolean big_endian = FALSE;
|
||||
gchar *s;
|
||||
|
||||
g_return_val_if_fail (fourcc != DRM_FORMAT_INVALID, NULL);
|
||||
g_return_val_if_fail (modifier != DRM_FORMAT_MOD_INVALID, NULL);
|
||||
|
||||
if (fourcc & DRM_FORMAT_BIG_ENDIAN) {
|
||||
big_endian = TRUE;
|
||||
fourcc &= ~DRM_FORMAT_BIG_ENDIAN;
|
||||
}
|
||||
|
||||
if (modifier == DRM_FORMAT_MOD_LINEAR) {
|
||||
s = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
|
||||
s = g_strdup_printf ("%" GST_FOURCC_FORMAT "%s", GST_FOURCC_ARGS (fourcc),
|
||||
big_endian ? "_BE" : "");
|
||||
} else {
|
||||
s = g_strdup_printf ("%" GST_FOURCC_FORMAT ":0x%016" G_GINT64_MODIFIER "x",
|
||||
GST_FOURCC_ARGS (fourcc), modifier);
|
||||
s = g_strdup_printf ("%" GST_FOURCC_FORMAT "%s:0x%016" G_GINT64_MODIFIER
|
||||
"x", GST_FOURCC_ARGS (fourcc), big_endian ? "_BE" : "", modifier);
|
||||
}
|
||||
|
||||
return s;
|
||||
|
|
|
@ -4310,6 +4310,32 @@ GST_START_TEST (test_video_meta_serialize)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_dma_drm_big_engian)
|
||||
{
|
||||
const guint32 fourcc = GST_MAKE_FOURCC ('A', 'B', 'C', 'D') | 1U << 31;
|
||||
|
||||
gchar *fmt = gst_video_dma_drm_fourcc_to_string (fourcc, 0);
|
||||
fail_unless (g_strcmp0 (fmt, "ABCD_BE") == 0);
|
||||
|
||||
gchar *fmt_mod = gst_video_dma_drm_fourcc_to_string (fourcc, 1);
|
||||
fail_unless (g_strcmp0 (fmt_mod, "ABCD_BE:0x0000000000000001") == 0);
|
||||
|
||||
guint64 parsed_mod;
|
||||
guint32 parsed_fourcc =
|
||||
gst_video_dma_drm_fourcc_from_string (fmt, &parsed_mod);
|
||||
g_assert_cmpuint (parsed_fourcc, ==, fourcc);
|
||||
g_assert_cmpuint (parsed_mod, ==, G_GUINT64_CONSTANT (0));
|
||||
|
||||
parsed_fourcc = gst_video_dma_drm_fourcc_from_string (fmt_mod, &parsed_mod);
|
||||
g_assert_cmpuint (parsed_fourcc, ==, fourcc);
|
||||
g_assert_cmpuint (parsed_mod, ==, G_GUINT64_CONSTANT (1));
|
||||
|
||||
g_free (fmt);
|
||||
g_free (fmt_mod);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
video_suite (void)
|
||||
{
|
||||
|
@ -4370,6 +4396,7 @@ video_suite (void)
|
|||
tcase_add_test (tc_chain, test_info_dma_drm);
|
||||
tcase_add_test (tc_chain, test_video_meta_serialize);
|
||||
tcase_add_test (tc_chain, test_video_convert_with_config_update);
|
||||
tcase_add_test (tc_chain, test_dma_drm_big_engian);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue