From 98b44fdb46059ea540b8f6b41a6174b9c3a7c09c Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Tue, 14 Jul 2020 21:43:56 -0400 Subject: [PATCH] video: Add support for linear 32x32 NV12 tiles This adds linear 32x32 NV12 based tiles. This format is notably used by Allwinner VCU and exposed in V4L2 as being "SUNXI Tiled" format. In this patch we generalize the plane info calculation so we can share this part with the 4L4 variant. Part-of: --- gst-libs/gst/video/video-converter.c | 1 + gst-libs/gst/video/video-format.c | 8 ++++++-- gst-libs/gst/video/video-format.h | 18 ++++++++++++++---- gst-libs/gst/video/video-info.c | 19 +++++++++++++------ tests/check/elements/videoscale.c | 1 + tests/check/libs/video.c | 1 + 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/video/video-converter.c b/gst-libs/gst/video/video-converter.c index 7e4a09738a..c4c976df61 100644 --- a/gst-libs/gst/video/video-converter.c +++ b/gst-libs/gst/video/video-converter.c @@ -5966,6 +5966,7 @@ get_scale_format (GstVideoFormat format, gint plane) case GST_VIDEO_FORMAT_GBRA_12LE: case GST_VIDEO_FORMAT_NV12_64Z32: case GST_VIDEO_FORMAT_NV12_4L4: + case GST_VIDEO_FORMAT_NV12_32L32: case GST_VIDEO_FORMAT_A420_10BE: case GST_VIDEO_FORMAT_A420_10LE: case GST_VIDEO_FORMAT_A422_10BE: diff --git a/gst-libs/gst/video/video-format.c b/gst-libs/gst/video/video-format.c index 30b34b122c..394ad99195 100644 --- a/gst-libs/gst/video/video-format.c +++ b/gst-libs/gst/video/video-format.c @@ -6366,9 +6366,10 @@ typedef struct #define SUB4204 { 0, 1, 1, 0 }, { 0, 1, 1, 0 } #define SUB4224 { 0, 1, 1, 0 }, { 0, 0, 0, 0 } -/* tile_mode, tile_width, tile_height */ -#define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5 +/* tile_mode, tile_ws (width shift), tile_hs (height shift) */ #define TILE_4x4(mode) GST_VIDEO_TILE_MODE_ ##mode, 2, 2 +#define TILE_32x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 5, 5 +#define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5 #define MAKE_YUV_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \ { fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV, depth, pstride, plane, offs, sub, pack } } @@ -6639,6 +6640,9 @@ static const VideoFormat formats[] = { MAKE_YUV_T_FORMAT (NV12_4L4, "raw video", GST_MAKE_FOURCC ('V', 'T', '1', '2'), DPTH888, PSTR122, PLANE011, OFFS001, SUB420, PACK_NV12_TILED, TILE_4x4 (LINEAR)), + MAKE_YUV_T_FORMAT (NV12_32L32, "raw video", + GST_MAKE_FOURCC ('S', 'T', '1', '2'), DPTH888, PSTR122, PLANE011, + OFFS001, SUB420, PACK_NV12_TILED, TILE_32x32 (LINEAR)), }; static GstVideoFormat diff --git a/gst-libs/gst/video/video-format.h b/gst-libs/gst/video/video-format.h index fa9a732af2..bebfceaeb5 100644 --- a/gst-libs/gst/video/video-format.h +++ b/gst-libs/gst/video/video-format.h @@ -130,6 +130,7 @@ G_BEGIN_DECLS * @GST_VIDEO_FORMAT_Y412_BE: packed 4:4:4:4 YUV, 12 bits per channel(U-Y-V-A...) (Since: 1.18) * @GST_VIDEO_FORMAT_Y412_LE: packed 4:4:4:4 YUV, 12 bits per channel(U-Y-V-A...) (Since: 1.18) * @GST_VIDEO_FORMAT_NV12_4L4: NV12 with 4x4 tiles in linear order (Since: 1.18) + * @GST_VIDEO_FORMAT_NV12_32L32: NV12 with 32x32 tiles in linear order (Since: 1.18) * * Enum value describing the most common video formats. * @@ -242,6 +243,15 @@ typedef enum { * Since: 1.18 */ GST_VIDEO_FORMAT_NV12_4L4, + /** + * GST_VIDEO_FORMAT_NV12_32L32: + * + * NV12 with 32x32 tiles in linear order. + * + * Since: 1.18 + */ + GST_VIDEO_FORMAT_NV12_32L32, + } GstVideoFormat; #define GST_VIDEO_MAX_PLANES 4 @@ -616,8 +626,8 @@ gconstpointer gst_video_format_get_palette (GstVideoFormat format, gsi "I422_10BE, I422_10LE, NV16_10LE32, Y210, v210, UYVP, I420_10BE, I420_10LE, " \ "P010_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, Y444, GBR, NV24, xBGR, BGRx, " \ "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \ - "YV12, NV21, NV12, NV12_64Z32, NV12_4L4, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, " \ - "RGB8P, GRAY16_BE, GRAY16_LE, GRAY10_LE32, GRAY8 }" + "YV12, NV21, NV12, NV12_64Z32, NV12_4L4, NV12_32L32, Y41B, IYU1, YVU9, YUV9, RGB16, " \ + "BGR16, RGB15, BGR15, RGB8P, GRAY16_BE, GRAY16_LE, GRAY10_LE32, GRAY8 }" #elif G_BYTE_ORDER == G_LITTLE_ENDIAN #define GST_VIDEO_FORMATS_ALL "{ AYUV64, ARGB64, GBRA_12LE, GBRA_12BE, Y412_LE, " \ "Y412_BE, A444_10LE, GBRA_10LE, A444_10BE, GBRA_10BE, A422_10LE, A422_10BE, " \ @@ -628,8 +638,8 @@ gconstpointer gst_video_format_get_palette (GstVideoFormat format, gsi "I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, " \ "P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, Y444, GBR, NV24, xBGR, BGRx, " \ "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \ - "YV12, NV21, NV12, NV12_64Z32, NV12_4L4, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, " \ - "RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }" + "YV12, NV21, NV12, NV12_64Z32, NV12_4L4, NV12_32L32, Y41B, IYU1, YVU9, YUV9, RGB16, " \ + "BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }" #endif GST_VIDEO_API diff --git a/gst-libs/gst/video/video-info.c b/gst-libs/gst/video/video-info.c index 68d89d0d58..b937e9fde6 100644 --- a/gst-libs/gst/video/video-info.c +++ b/gst-libs/gst/video/video-info.c @@ -1048,17 +1048,24 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES]) GST_ROUND_UP_128 (width) * (GST_ROUND_UP_64 (height) / 2); break; case GST_VIDEO_FORMAT_NV12_4L4: + case GST_VIDEO_FORMAT_NV12_32L32: + { + gint ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info->finfo); + gint hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info->finfo); info->stride[0] = - GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_4 (width) / 4, - GST_ROUND_UP_4 (height) / 4); + GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (width, 1 << ws) >> ws, + GST_ROUND_UP_N (height, 1 << hs) >> hs); info->stride[1] = - GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_4 (width) / 4, - GST_ROUND_UP_8 (height) / 8); + GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (width, 1 << ws) >> ws, + GST_ROUND_UP_N (height, 1 << (hs + 1)) >> (hs + 1)); info->offset[0] = 0; - info->offset[1] = GST_ROUND_UP_4 (width) * GST_ROUND_UP_4 (height); + info->offset[1] = + GST_ROUND_UP_N (width, 1 << ws) * GST_ROUND_UP_N (height, 1 << hs); info->size = info->offset[1] + - GST_ROUND_UP_4 (width) * (GST_ROUND_UP_8 (height) / 2); + GST_ROUND_UP_N (width, 1 << ws) * + (GST_ROUND_UP_N (height, 1 << (hs + 1)) / 2); break; + } case GST_VIDEO_FORMAT_A420_10LE: case GST_VIDEO_FORMAT_A420_10BE: info->stride[0] = GST_ROUND_UP_4 (width * 2); diff --git a/tests/check/elements/videoscale.c b/tests/check/elements/videoscale.c index 2a36618836..36543f3e16 100644 --- a/tests/check/elements/videoscale.c +++ b/tests/check/elements/videoscale.c @@ -124,6 +124,7 @@ check_pad_template (GstPadTemplate * tmpl) case GST_VIDEO_FORMAT_GBR_10LE: case GST_VIDEO_FORMAT_NV12_64Z32: case GST_VIDEO_FORMAT_NV12_4L4: + case GST_VIDEO_FORMAT_NV12_32L32: GST_LOG ("Ignoring lack of support for format %s", fmt_str); break; default: diff --git a/tests/check/libs/video.c b/tests/check/libs/video.c index 0909ce54b3..078762bc5b 100644 --- a/tests/check/libs/video.c +++ b/tests/check/libs/video.c @@ -3049,6 +3049,7 @@ GST_START_TEST (test_video_formats_pstrides) || fmt == GST_VIDEO_FORMAT_GRAY10_LE32 || fmt == GST_VIDEO_FORMAT_NV12_64Z32 || fmt == GST_VIDEO_FORMAT_NV12_4L4 + || fmt == GST_VIDEO_FORMAT_NV12_32L32 || fmt == GST_VIDEO_FORMAT_NV12_10LE32 || fmt == GST_VIDEO_FORMAT_NV16_10LE32 || fmt == GST_VIDEO_FORMAT_NV12_10LE40