/* GStreamer * Copyright (C) 2022 Intel Corporation * Author: He Junyan * Author: Liu Yinhang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ /** * SECTION:video-info-dma-drm * @title: GstVideoInfoDmaDrm * @short_description: Structures and enumerations to describe DMA video * format in DRM mode. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "video-info-dma.h" #include /* * To avoid header file dependency, some of the FOURCC and MODIFIER * are copied here. All these values are const and will not changes. * The full authoritative list of format modifier codes is found in * `include/uapi/drm/drm_fourcc.h` */ #define fourcc_code(a, b, c, d) ((guint32)(a) | ((guint32)(b) << 8) | \ ((guint32)(c) << 16) | ((guint32)(d) << 24)) /* Reserve 0 for the invalid format specifier */ #define DRM_FORMAT_INVALID 0 /* packed YCbCr */ #define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ #define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ #define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ #define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ #define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ /* * 2 plane YCbCr * index 0 = Y plane, [7:0] Y * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian * or * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian */ #define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */ #define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */ #define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */ #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ #define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */ /* * 3 plane YCbCr * index 0: Y plane, [7:0] Y * index 1: Cb plane, [7:0] Cb * index 2: Cr plane, [7:0] Cr * or * index 1: Cr plane, [7:0] Cr * index 2: Cb plane, [7:0] Cb */ #define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */ #define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */ #define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */ #define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */ #define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */ #define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */ #define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ /* 16 bpp RGB */ #define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */ #define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */ /* 24 bpp RGB */ #define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */ #define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */ /* 32 bpp RGB */ #define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */ #define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */ #define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */ #define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */ #define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ #define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */ #define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */ #define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */ #define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */ /* * packed Y4xx indicate for each component, xx valid data occupy msb * 16-xx padding occupy lsb except Y410 */ #define DRM_FORMAT_Y410 fourcc_code('Y', '4', '1', '0') /* [31:0] A:Cr:Y:Cb 2:10:10:10 little endian */ #define DRM_FORMAT_Y412 fourcc_code('Y', '4', '1', '2') /* [63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian */ /* * packed Y2xx indicate for each component, xx valid data occupy msb * 16-xx padding occupy lsb */ #define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels */ #define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels */ /* * 2 plane YCbCr MSB aligned * index 0 = Y plane, [15:0] Y:x [10:6] little endian * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [10:6:10:6] little endian */ #define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel */ /* * 2 plane YCbCr MSB aligned * index 0 = Y plane, [15:0] Y:x [12:4] little endian * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [12:4:12:4] little endian */ #define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2') /* 2x2 subsampled Cr:Cb plane 12 bits per channel */ /* * Linear Layout * * Just plain linear layout. Note that this is different from no specifying any * modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl), * which tells the driver to also take driver-internal information into account * and so might actually result in a tiled framebuffer. */ #define DRM_FORMAT_MOD_LINEAR 0ULL /* * Invalid Modifier * * This modifier can be used as a sentinel to terminate the format modifiers * list, or to initialize a variable with an invalid modifier. It might also be * used to report an error back to userspace for certain APIs. */ #define DRM_FORMAT_MOD_INVALID 0xffffffffffffff #ifndef GST_DISABLE_GST_DEBUG #define GST_CAT_DEFAULT ensure_debug_category() static GstDebugCategory * ensure_debug_category (void) { static gsize cat_gonce = 0; if (g_once_init_enter (&cat_gonce)) { gsize cat_done; cat_done = (gsize) _gst_debug_category_new ("video-info-dma-drm", 0, "video-info-dma-drm structure"); g_once_init_leave (&cat_gonce, cat_done); } return (GstDebugCategory *) cat_gonce; } #else #define ensure_debug_category() /* NOOP */ #endif /* GST_DISABLE_GST_DEBUG */ static GstVideoInfoDmaDrm * gst_video_info_dma_drm_copy (const GstVideoInfoDmaDrm * drm_info) { return g_memdup2 (drm_info, sizeof (GstVideoInfoDmaDrm)); } /** * gst_video_info_dma_drm_free: * @drm_info: a #GstVideoInfoDmaDrm * * Free a #GstVideoInfoDmaDrm structure previously allocated with * gst_video_info_dma_drm_new() * * Since: 1.24 */ void gst_video_info_dma_drm_free (GstVideoInfoDmaDrm * drm_info) { g_free (drm_info); } G_DEFINE_BOXED_TYPE (GstVideoInfoDmaDrm, gst_video_info_dma_drm, (GBoxedCopyFunc) gst_video_info_dma_drm_copy, (GBoxedFreeFunc) gst_video_info_dma_drm_free); /** * gst_video_info_dma_drm_init: * @drm_info: (out caller-allocates): a #GstVideoInfoDmaDrm * * Initialize @drm_info with default values. * * Since: 1.24 */ void gst_video_info_dma_drm_init (GstVideoInfoDmaDrm * drm_info) { g_return_if_fail (drm_info != NULL); gst_video_info_init (&drm_info->vinfo); drm_info->drm_fourcc = DRM_FORMAT_INVALID; drm_info->drm_modifier = DRM_FORMAT_MOD_INVALID; } /** * gst_video_info_dma_drm_new: * * Allocate a new #GstVideoInfoDmaDrm that is also initialized with * gst_video_info_dma_drm_init(). * * Returns: (transfer full): a new #GstVideoInfoDmaDrm. * Free it with gst_video_info_dma_drm_free(). * * Since: 1.24 */ GstVideoInfoDmaDrm * gst_video_info_dma_drm_new (void) { GstVideoInfoDmaDrm *info; info = g_new (GstVideoInfoDmaDrm, 1); gst_video_info_dma_drm_init (info); return info; } /** * gst_video_is_dma_drm_caps: * @caps: a #GstCaps * * Check whether the @caps is a dma drm kind caps. Please note that * the caps should be fixed. * * Returns: %TRUE if the caps is a dma drm caps. * * Since: 1.24 */ gboolean gst_video_is_dma_drm_caps (const GstCaps * caps) { GstStructure *structure; g_return_val_if_fail (caps != NULL, FALSE); if (!gst_caps_is_fixed (caps)) return FALSE; if (!gst_caps_features_contains (gst_caps_get_features (caps, 0), GST_CAPS_FEATURE_MEMORY_DMABUF)) return FALSE; structure = gst_caps_get_structure (caps, 0); if (g_strcmp0 (gst_structure_get_string (structure, "format"), "DMA_DRM") != 0) return FALSE; return TRUE; } /** * gst_video_info_dma_drm_to_caps: * @drm_info: a #GstVideoInfoDmaDrm * * Convert the values of @drm_info into a #GstCaps. Please note that the * @caps returned will be a dma drm caps which sets format field to DMA_DRM, * and contains a new drm-format field. The value of drm-format field is * composed of a drm fourcc and a modifier, such as NV12:0x0100000000000002. * * Returns: (transfer full) (nullable): a new #GstCaps containing the * info in @drm_info. * * Since: 1.24 */ GstCaps * gst_video_info_dma_drm_to_caps (const GstVideoInfoDmaDrm * drm_info) { GstCaps *caps; GstStructure *structure; gchar *str; g_return_val_if_fail (drm_info != NULL, NULL); g_return_val_if_fail (drm_info->drm_fourcc != DRM_FORMAT_INVALID, NULL); g_return_val_if_fail (drm_info->drm_modifier != DRM_FORMAT_MOD_INVALID, NULL); caps = gst_video_info_to_caps (&drm_info->vinfo); if (!caps) { GST_DEBUG ("Failed to create caps from video info"); return NULL; } gst_caps_set_features_simple (caps, gst_caps_features_new_single_static_str (GST_CAPS_FEATURE_MEMORY_DMABUF)); str = gst_video_dma_drm_fourcc_to_string (drm_info->drm_fourcc, drm_info->drm_modifier); structure = gst_caps_get_structure (caps, 0); gst_structure_set (structure, "format", G_TYPE_STRING, "DMA_DRM", "drm-format", G_TYPE_STRING, str, NULL); g_free (str); return caps; } /** * gst_video_info_dma_drm_from_caps: * @drm_info: (out caller-allocates): #GstVideoInfoDmaDrm * @caps: a #GstCaps * * Parse @caps and update @info. Please note that the @caps should be * a dma drm caps. The gst_video_is_dma_drm_caps() can be used to verify * it before calling this function. * * Returns: TRUE if @caps could be parsed * * Since: 1.24 */ gboolean gst_video_info_dma_drm_from_caps (GstVideoInfoDmaDrm * drm_info, const GstCaps * caps) { GstStructure *structure; const gchar *str; guint32 fourcc; guint64 modifier; GstVideoFormat format; GstCaps *tmp_caps = NULL; gboolean ret; g_return_val_if_fail (drm_info != NULL, FALSE); g_return_val_if_fail (caps != NULL, FALSE); if (!gst_video_is_dma_drm_caps (caps)) return FALSE; GST_DEBUG ("parsing caps %" GST_PTR_FORMAT, caps); tmp_caps = gst_caps_copy (caps); structure = gst_caps_get_structure (tmp_caps, 0); str = gst_structure_get_string (structure, "drm-format"); if (!str) { GST_DEBUG ("drm caps %" GST_PTR_FORMAT "has no drm-format field", caps); ret = FALSE; goto out; } fourcc = gst_video_dma_drm_fourcc_from_string (str, &modifier); if (fourcc == DRM_FORMAT_INVALID) { GST_DEBUG ("Can not parse fourcc in caps %" GST_PTR_FORMAT, caps); ret = FALSE; goto out; } if (modifier == DRM_FORMAT_MOD_INVALID) { GST_DEBUG ("Can not parse modifier in caps %" GST_PTR_FORMAT, caps); ret = FALSE; goto out; } /* If the modifier is linear, set the according format in video info, * otherwise, just let the format to be GST_VIDEO_FORMAT_DMA_DRM. */ format = gst_video_dma_drm_format_to_gst_format (fourcc, modifier); if (format != GST_VIDEO_FORMAT_UNKNOWN) { gst_structure_set (structure, "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL); } gst_structure_remove_field (structure, "drm-format"); if (!gst_video_info_from_caps (&drm_info->vinfo, tmp_caps)) { GST_DEBUG ("Can not parse video info for caps %" GST_PTR_FORMAT, tmp_caps); ret = FALSE; goto out; } drm_info->drm_fourcc = fourcc; drm_info->drm_modifier = modifier; ret = TRUE; out: gst_clear_caps (&tmp_caps); return ret; } /** * gst_video_info_dma_drm_new_from_caps: * @caps: a #GstCaps * * Parse @caps to generate a #GstVideoInfoDmaDrm. Please note that the * @caps should be a dma drm caps. The gst_video_is_dma_drm_caps() can * be used to verify it before calling this function. * * Returns: (transfer full) (nullable): A #GstVideoInfoDmaDrm, * or %NULL if @caps couldn't be parsed. * * Since: 1.24 */ GstVideoInfoDmaDrm * gst_video_info_dma_drm_new_from_caps (const GstCaps * caps) { GstVideoInfoDmaDrm *ret; g_return_val_if_fail (caps != NULL, NULL); if (!gst_video_is_dma_drm_caps (caps)) return NULL; ret = gst_video_info_dma_drm_new (); if (gst_video_info_dma_drm_from_caps (ret, caps)) { return ret; } else { gst_video_info_dma_drm_free (ret); return NULL; } } /** * gst_video_info_dma_drm_from_video_info: * @drm_info: (out caller-allocates): #GstVideoInfoDmaDrm * @info: a #GstVideoInfo * @modifier: the associated modifier value. * * Fills @drm_info if @info's format has a valid drm format and @modifier is also * valid * * Returns: %TRUE if @drm_info is filled correctly. * * Since: 1.24 */ gboolean gst_video_info_dma_drm_from_video_info (GstVideoInfoDmaDrm * drm_info, const GstVideoInfo * info, guint64 modifier) { GstVideoFormat format; guint32 fourcc; g_return_val_if_fail (drm_info != NULL, FALSE); g_return_val_if_fail (info != NULL, FALSE); if (modifier == DRM_FORMAT_MOD_INVALID) return FALSE; format = GST_VIDEO_INFO_FORMAT (info); fourcc = gst_video_dma_drm_fourcc_from_format (format); if (fourcc == DRM_FORMAT_INVALID) return FALSE; drm_info->vinfo = *info; drm_info->drm_fourcc = fourcc; drm_info->drm_modifier = modifier; /* no need to change format to GST_VIDEO_INFO_DMA_DRM since its modifier is * linear */ if (modifier == DRM_FORMAT_MOD_LINEAR) return TRUE; return gst_video_info_set_interlaced_format (&drm_info->vinfo, GST_VIDEO_FORMAT_DMA_DRM, GST_VIDEO_INFO_INTERLACE_MODE (info), GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info)); } /** * gst_video_info_dma_drm_to_video_info: * @drm_info: a #GstVideoInfoDmaDrm * @info: (out caller-allocates): #GstVideoInfo * * Convert the #GstVideoInfoDmaDrm into a traditional #GstVideoInfo with * recognized video format. For DMA kind memory, the non linear DMA format * should be recognized as #GST_VIDEO_FORMAT_DMA_DRM. This helper function * sets @info's video format into the default value according to @drm_info's * drm_fourcc field. * * Returns: %TRUE if @info is converted correctly. * * Since: 1.24 */ gboolean gst_video_info_dma_drm_to_video_info (const GstVideoInfoDmaDrm * drm_info, GstVideoInfo * info) { GstVideoFormat video_format; GstVideoInfo tmp_info; guint i; g_return_val_if_fail (drm_info, FALSE); g_return_val_if_fail (info, FALSE); if (GST_VIDEO_INFO_FORMAT (&drm_info->vinfo) != GST_VIDEO_FORMAT_DMA_DRM) { *info = drm_info->vinfo; return TRUE; } video_format = gst_video_dma_drm_fourcc_to_format (drm_info->drm_fourcc); if (video_format == GST_VIDEO_FORMAT_UNKNOWN) return FALSE; if (!gst_video_info_set_format (&tmp_info, video_format, GST_VIDEO_INFO_WIDTH (&drm_info->vinfo), GST_VIDEO_INFO_HEIGHT (&drm_info->vinfo))) return FALSE; *info = drm_info->vinfo; info->finfo = tmp_info.finfo; for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) info->stride[i] = tmp_info.stride[i]; for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) info->offset[i] = tmp_info.offset[i]; info->size = tmp_info.size; return TRUE; } /** * gst_video_dma_drm_fourcc_from_string: * @format_str: a drm format string * @modifier: (out) (optional): Return the modifier in @format or %NULL * to ignore. * * Convert the @format_str string into the drm fourcc value. The @modifier is * also parsed if we want. Please note that the @format_str should follow the * fourcc:modifier kind style, such as NV12:0x0100000000000002 * * Returns: The drm fourcc value or DRM_FORMAT_INVALID if @format_str is * invalid. * * Since: 1.24 */ guint32 gst_video_dma_drm_fourcc_from_string (const gchar * format_str, guint64 * modifier) { const gchar *mod_str; guint32 fourcc = DRM_FORMAT_INVALID; guint64 m = DRM_FORMAT_MOD_INVALID; g_return_val_if_fail (format_str != NULL, 0); mod_str = strchr (format_str, ':'); if (mod_str) { if (mod_str - format_str != 4) { /* fourcc always has 4 characters. */ GST_DEBUG ("%s is not a drm string", format_str); return DRM_FORMAT_INVALID; } mod_str++; /* modifier should in hex mode. */ if (!(mod_str[0] == '0' && (mod_str[1] == 'X' || mod_str[1] == 'x'))) { GST_DEBUG ("Invalid modifier string"); return DRM_FORMAT_INVALID; } m = g_ascii_strtoull (mod_str, NULL, 16); if (m == DRM_FORMAT_MOD_LINEAR) { GST_DEBUG ("Unrecognized modifier string %s", mod_str); return DRM_FORMAT_INVALID; } } else { if (strlen (format_str) != 4) { /* fourcc always has 4 characters. */ GST_DEBUG ("%s is not a drm string", format_str); return DRM_FORMAT_INVALID; } m = DRM_FORMAT_MOD_LINEAR; } fourcc = GST_MAKE_FOURCC (format_str[0], format_str[1], format_str[2], format_str[3]); if (modifier) *modifier = m; return fourcc; } /** * gst_video_dma_drm_fourcc_to_string: * @fourcc: a drm fourcc value. * @modifier: the associated modifier value. * * Returns a string containing drm kind format, such as * NV12:0x0100000000000002, or NULL otherwise. * * Returns: (transfer full) (nullable): the drm kind string composed * of to @fourcc and @modifier. * * Since: 1.24 */ gchar * gst_video_dma_drm_fourcc_to_string (guint32 fourcc, guint64 modifier) { gchar *s; g_return_val_if_fail (fourcc != DRM_FORMAT_INVALID, NULL); g_return_val_if_fail (modifier != DRM_FORMAT_MOD_INVALID, NULL); if (modifier == DRM_FORMAT_MOD_LINEAR) { s = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc)); } else { s = g_strdup_printf ("%" GST_FOURCC_FORMAT ":0x%016" G_GINT64_MODIFIER "x", GST_FOURCC_ARGS (fourcc), modifier); } return s; } /* *INDENT-OFF* */ static const struct FormatMap { GstVideoFormat format; guint32 fourcc; guint64 modifier; } format_map[] = { {GST_VIDEO_FORMAT_YUY2, DRM_FORMAT_YUYV, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_YVYU, DRM_FORMAT_YVYU, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_UYVY, DRM_FORMAT_UYVY, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_VYUY, DRM_FORMAT_VYUY, DRM_FORMAT_MOD_LINEAR}, /* No VUYA fourcc define, just mapping it as AYUV. */ {GST_VIDEO_FORMAT_VUYA, DRM_FORMAT_AYUV, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_NV12, DRM_FORMAT_NV12, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_NV21, DRM_FORMAT_NV21, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_NV16, DRM_FORMAT_NV16, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_NV61, DRM_FORMAT_NV61, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_NV24, DRM_FORMAT_NV24, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_YUV9, DRM_FORMAT_YUV410, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_YVU9, DRM_FORMAT_YVU410, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_Y41B, DRM_FORMAT_YUV411, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_I420, DRM_FORMAT_YUV420, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_YV12, DRM_FORMAT_YVU420, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_Y42B, DRM_FORMAT_YUV422, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_Y444, DRM_FORMAT_YUV444, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_RGB16, DRM_FORMAT_RGB565, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_BGR16, DRM_FORMAT_BGR565, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_RGB, DRM_FORMAT_BGR888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_BGR, DRM_FORMAT_RGB888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_RGBA, DRM_FORMAT_ABGR8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_RGBx, DRM_FORMAT_XBGR8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_BGRA, DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_BGRx, DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_ARGB, DRM_FORMAT_BGRA8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_xRGB, DRM_FORMAT_BGRX8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_ABGR, DRM_FORMAT_RGBA8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_xBGR, DRM_FORMAT_RGBX8888, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_Y410, DRM_FORMAT_Y410, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_Y412_LE, DRM_FORMAT_Y412, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_Y210, DRM_FORMAT_Y210, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_Y212_LE, DRM_FORMAT_Y212, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_P010_10LE, DRM_FORMAT_P010, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_P012_LE, DRM_FORMAT_P012, DRM_FORMAT_MOD_LINEAR}, {GST_VIDEO_FORMAT_BGR10A2_LE, DRM_FORMAT_ARGB2101010, DRM_FORMAT_MOD_LINEAR}, }; /* *INDENT-ON* */ /** * gst_video_dma_drm_fourcc_from_format: * @format: a #GstVideoFormat * * Converting the video format into dma drm fourcc. If no * matching fourcc found, then DRM_FORMAT_INVALID is returned. * * Returns: the DRM_FORMAT_* corresponding to the @format. * * Since: 1.24 */ guint32 gst_video_dma_drm_fourcc_from_format (GstVideoFormat format) { guint64 modifier; guint32 fourcc; fourcc = gst_video_dma_drm_format_from_gst_format (format, &modifier); if (fourcc == DRM_FORMAT_INVALID) return DRM_FORMAT_INVALID; if (modifier != DRM_FORMAT_MOD_LINEAR) return DRM_FORMAT_INVALID; return fourcc; } /** * gst_video_dma_drm_format_from_gst_format: * @format: a #GstVideoFormat * @modifier: (nullable): return location for the modifier * * Converting the video format into dma drm fourcc/modifier pair. * If no matching fourcc found, then DRM_FORMAT_INVALID is returned * and @modifier will be set to DRM_FORMAT_MOD_INVALID. * * Returns: the DRM_FORMAT_* corresponding to @format. * * Since: 1.26 */ guint32 gst_video_dma_drm_format_from_gst_format (GstVideoFormat format, guint64 * modifier) { guint i; for (i = 0; i < G_N_ELEMENTS (format_map); i++) { if (format_map[i].format == format) { if (modifier) *modifier = format_map[i].modifier; return format_map[i].fourcc; } } GST_INFO ("No supported fourcc/modifier for video format %s", gst_video_format_to_string (format)); *modifier = DRM_FORMAT_MOD_INVALID; return DRM_FORMAT_INVALID; } /** * gst_video_dma_drm_fourcc_to_format: * @fourcc: the dma drm value. * * Converting a dma drm fourcc into the video format. If no matching * video format found, then GST_VIDEO_FORMAT_UNKNOWN is returned. * * Returns: the GST_VIDEO_FORMAT_* corresponding to the @fourcc. * * Since: 1.24 */ GstVideoFormat gst_video_dma_drm_fourcc_to_format (guint32 fourcc) { guint i; for (i = 0; i < G_N_ELEMENTS (format_map); i++) { if (format_map[i].fourcc == fourcc) return format_map[i].format; } GST_INFO ("No supported video format for fourcc %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc)); return GST_VIDEO_FORMAT_UNKNOWN; } /** * gst_video_dma_drm_format_to_gst_format: * @fourcc: the dma drm fourcc value. * @modifier: the dma drm modifier. * * Converting a dma drm fourcc and modifier pair into a #GstVideoFormat. If * no matching video format is found, then GST_VIDEO_FORMAT_UNKNOWN is returned. * * Returns: the GST_VIDEO_FORMAT_* corresponding to the @fourcc and @modifier * pair. * * Since: 1.26 */ GstVideoFormat gst_video_dma_drm_format_to_gst_format (guint32 fourcc, guint64 modifier) { guint i; for (i = 0; i < G_N_ELEMENTS (format_map); i++) { if (format_map[i].fourcc == fourcc && format_map[i].modifier == modifier) return format_map[i].format; } gchar *drm_format_str = gst_video_dma_drm_fourcc_to_string (fourcc, modifier); GST_INFO ("No support for DRM format %s", drm_format_str); g_free (drm_format_str); return GST_VIDEO_FORMAT_UNKNOWN; }