From c17e648fcfd7d842242c326ded113e77bdf6a0b3 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 11 Nov 2022 15:10:02 -0500 Subject: [PATCH] video: Add NV12_10LE32_4L4 tiled format This 10bit format is identical to NV12_4L4, but uses NV12_10LE40 format internally. In show, the tiles is made af 4 rows of 5 bytes, which contains 4 fully packed 10bit values. Part-of: --- .../gst-libs/gst/video/video-converter.c | 1 + .../gst-libs/gst/video/video-format.c | 66 ++++++++++++++++--- .../gst-libs/gst/video/video-format.h | 15 ++++- .../gst-libs/gst/video/video-info.c | 1 + .../tests/check/elements/videoscale.c | 1 + .../gst-plugins-base/tests/check/libs/video.c | 3 +- 6 files changed, 76 insertions(+), 11 deletions(-) diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c b/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c index 84a91976ff..f573015f1d 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-converter.c @@ -7358,6 +7358,7 @@ get_scale_format (GstVideoFormat format, gint plane) case GST_VIDEO_FORMAT_Y412_LE: case GST_VIDEO_FORMAT_NV12_8L128: case GST_VIDEO_FORMAT_NV12_10BE_8L128: + case GST_VIDEO_FORMAT_NV12_10LE40_4L4: res = format; g_assert_not_reached (); break; diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.c b/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.c index 24158fe2c1..74d2cab35c 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.c @@ -4746,6 +4746,7 @@ pack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, } } +/* Helpers for the most common tile format */ static void get_tile_NV12 (const GstVideoFormatInfo * info, gint tx, gint ty, const gpointer data[GST_VIDEO_MAX_PLANES], @@ -4776,9 +4777,9 @@ get_tile_NV12 (const GstVideoFormatInfo * info, gint tx, gint ty, tile_stride[1] = GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info, 1); } -#define PACK_NV12_TILED GST_VIDEO_FORMAT_AYUV, unpack_NV12_TILED, 1, pack_NV12_TILED -static void -unpack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, +static inline void +unpack_TILED (GstVideoFormat inner_format, + const GstVideoFormatInfo * info, GstVideoPackFlags flags, gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES], const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width) { @@ -4792,7 +4793,7 @@ unpack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info, 0); /* we reuse these unpack functions */ - tile_finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12); + tile_finfo = gst_video_format_get_info (inner_format); /* get pstride of unpacked format */ unpack_info = gst_video_format_get_info (info->unpack_format); @@ -4817,7 +4818,7 @@ unpack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, get_tile_NV12 (info, tx, ty, data, stride, tdata, tstride); - /* the number of bytes left to unpack */ + /* the number of pixels left to unpack */ unpack_width = MIN (width - x, tile_width - x); tile_finfo->unpack_func (tile_finfo, flags, line, tdata, tstride, x, y, @@ -4829,8 +4830,9 @@ unpack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, } } -static void -pack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, +static inline void +pack_TILED (GstVideoFormat inner_format, + const GstVideoFormatInfo * info, GstVideoPackFlags flags, const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES], const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site, gint y, gint width) @@ -4845,7 +4847,7 @@ pack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info, 0); /* we reuse these pack functions */ - tile_finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12); + tile_finfo = gst_video_format_get_info (inner_format); /* get pstride of packed format */ pack_info = gst_video_format_get_info (info->unpack_format); @@ -4877,6 +4879,27 @@ pack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, } } +#define PACK_NV12_TILED GST_VIDEO_FORMAT_AYUV, unpack_NV12_TILED, 1, pack_NV12_TILED +static void +unpack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, + gpointer dest, const gpointer data[GST_VIDEO_MAX_PLANES], + const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width) +{ + unpack_TILED (GST_VIDEO_FORMAT_NV12, info, flags, dest, data, stride, + x, y, width); +} + +static void +pack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags, + const gpointer src, gint sstride, gpointer data[GST_VIDEO_MAX_PLANES], + const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site, + gint y, gint width) +{ + pack_TILED (GST_VIDEO_FORMAT_NV12, info, flags, src, sstride, data, stride, + chroma_site, y, width); +} + + #define PACK_P010_10BE GST_VIDEO_FORMAT_AYUV64, unpack_P010_10BE, 1, pack_P010_10BE static void unpack_P010_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, @@ -6886,6 +6909,29 @@ pack_NV12_10BE_8L128 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, } } +#define PACK_NV12_10LE40_TILED GST_VIDEO_FORMAT_AYUV64, unpack_NV12_10LE40_TILED, 1, pack_NV12_10LE40_TILED +static void +unpack_NV12_10LE40_TILED (const GstVideoFormatInfo * info, + GstVideoPackFlags flags, gpointer dest, + const gpointer data[GST_VIDEO_MAX_PLANES], + const gint stride[GST_VIDEO_MAX_PLANES], gint x, gint y, gint width) +{ + unpack_TILED (GST_VIDEO_FORMAT_NV12_10LE40, info, flags, dest, data, stride, + x, y, width); +} + +static void +pack_NV12_10LE40_TILED (const GstVideoFormatInfo * info, + GstVideoPackFlags flags, const gpointer src, gint sstride, + gpointer data[GST_VIDEO_MAX_PLANES], + const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site, + gint y, gint width) +{ + pack_TILED (GST_VIDEO_FORMAT_NV12_10LE40, info, flags, src, sstride, data, + stride, chroma_site, y, width); +} + + typedef struct { guint32 fourcc; @@ -6986,6 +7032,7 @@ typedef struct #define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5, { {64, 32, 64, 2048}, {32, 32, 64, 2048}, } #define TILE_8x128(mode) GST_VIDEO_TILE_MODE_ ##mode, 3, 7, { {8, 128, 8, 1024}, {4, 128, 8, 1024}, } #define TILE_10bit_8x128(mode) GST_VIDEO_TILE_MODE_ ##mode, 3, 7, { {0, 128, 8, 1024}, {0, 128, 8, 1024}, } +#define TILE_10bit_4x4(mode) GST_VIDEO_TILE_MODE_ ##mode, 2, 2, { {4, 4, 5, 20}, {2, 4, 5, 20}, } #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 } } @@ -7293,6 +7340,9 @@ static const VideoFormat formats[] = { MAKE_YUV_T_FORMAT (NV12_10BE_8L128, "raw video", GST_MAKE_FOURCC ('N', 'T', '1', '2'), DPTH10_10_10, PSTR0, PLANE011, OFFS001, SUB420, PACK_NV12_10BE_8L128, TILE_10bit_8x128 (LINEAR)), + MAKE_YUV_T_FORMAT (NV12_10LE40_4L4, "raw video", + GST_MAKE_FOURCC ('M', 'H', '2', '1'), DPTH10_10_10, PSTR0, PLANE011, + OFFS001, SUB420, PACK_NV12_10LE40_TILED, TILE_10bit_4x4 (LINEAR)), }; G_GNUC_END_IGNORE_DEPRECATIONS; diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.h b/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.h index 7a645ccaab..ee7bfc0251 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-format.h @@ -145,6 +145,7 @@ G_BEGIN_DECLS * @GST_VIDEO_FORMAT_NV12_16L32S: NV12 with 16x32 Y tiles and 16x16 UV tiles. (Since: 1.22) * @GST_VIDEO_FORMAT_NV12_8L128 : NV12 with 8x128 tiles in linear order (Since: 1.22) * @GST_VIDEO_FORMAT_NV12_10BE_8L128 : NV12 10bit big endian with 8x128 tiles in linear order (Since: 1.22) + * @GST_VIDEO_FORMAT_NV12_10LE40_4L4: @GST_VIDEO_FORMAT_NV12_10LE40 with 4x4 pixels tiles (5 bytes per tile row) (Since: 1.24) * * Enum value describing the most common video formats. * @@ -400,6 +401,16 @@ typedef enum { * Since: 1.22 */ GST_VIDEO_FORMAT_NV12_10BE_8L128, + + /** + * GST_VIDEO_FORMAT_NV12_10LE40_4L4: + * + * @GST_VIDEO_FORMAT_NV12_10LE40 with 4x4 pixels tiles (5 bytes + * per tile row). This format is produced by Verisilicon/Hantro decoders. + * + * Since: 1.24 + */ + GST_VIDEO_FORMAT_NV12_10LE40_4L4, } GstVideoFormat; #define GST_VIDEO_MAX_PLANES 4 @@ -874,7 +885,7 @@ gconstpointer gst_video_format_get_palette (GstVideoFormat format, gsi "GBR_12BE, Y444_12LE, GBR_12LE, I422_12BE, I422_12LE, Y212_BE, Y212_LE, I420_12BE, " \ "I420_12LE, P012_BE, P012_LE, Y444_10BE, GBR_10BE, Y444_10LE, GBR_10LE, r210, " \ "I422_10BE, I422_10LE, NV16_10LE32, Y210, v210, UYVP, I420_10BE, I420_10LE, " \ - "P010_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \ + "P010_10BE, P010_10LE, NV12_10LE32, NV12_10LE40, NV12_10BE_8L128, NV12_10LE40_4L4, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \ "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \ "YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, " \ "BGR16, RGB15, BGR15, RGB8P, GRAY16_BE, GRAY16_LE, GRAY10_LE32, GRAY8 }" @@ -887,7 +898,7 @@ gconstpointer gst_video_format_get_palette (GstVideoFormat format, gsi "GBR_12LE, Y444_12BE, GBR_12BE, I422_12LE, I422_12BE, Y212_LE, Y212_BE, I420_12LE, " \ "I420_12BE, P012_LE, P012_BE, Y444_10LE, GBR_10LE, Y444_10BE, GBR_10BE, r210, " \ "I422_10LE, I422_10BE, NV16_10LE32, Y210, v210, UYVP, I420_10LE, I420_10BE, " \ - "P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \ + "P010_10LE, NV12_10LE32, NV12_10LE40, P010_10BE, NV12_10BE_8L128, NV12_10LE40_4L4, Y444, RGBP, GBR, BGRP, NV24, xBGR, BGRx, " \ "xRGB, RGBx, BGR, IYU2, v308, RGB, Y42B, NV61, NV16, VYUY, UYVY, YVYU, YUY2, I420, " \ "YV12, NV21, NV12, NV12_8L128, NV12_64Z32, NV12_4L4, NV12_32L32, NV12_16L32S, Y41B, IYU1, YVU9, YUV9, RGB16, " \ "BGR16, RGB15, BGR15, RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }" diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c b/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c index 03a2f477d0..f363e86731 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/video-info.c @@ -1096,6 +1096,7 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES]) break; case GST_VIDEO_FORMAT_NV12_4L4: case GST_VIDEO_FORMAT_NV12_32L32: + case GST_VIDEO_FORMAT_NV12_10LE40_4L4: { const gsize tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0); gint tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info->finfo, 0); diff --git a/subprojects/gst-plugins-base/tests/check/elements/videoscale.c b/subprojects/gst-plugins-base/tests/check/elements/videoscale.c index aaa3555302..86e0555880 100644 --- a/subprojects/gst-plugins-base/tests/check/elements/videoscale.c +++ b/subprojects/gst-plugins-base/tests/check/elements/videoscale.c @@ -130,6 +130,7 @@ check_pad_template (GstPadTemplate * tmpl) case GST_VIDEO_FORMAT_NV12_16L32S: case GST_VIDEO_FORMAT_NV12_8L128: case GST_VIDEO_FORMAT_NV12_10BE_8L128: + case GST_VIDEO_FORMAT_NV12_10LE40_4L4: GST_LOG ("Ignoring lack of support for format %s", fmt_str); break; default: diff --git a/subprojects/gst-plugins-base/tests/check/libs/video.c b/subprojects/gst-plugins-base/tests/check/libs/video.c index 1c6049ed7b..a061a47449 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/video.c +++ b/subprojects/gst-plugins-base/tests/check/libs/video.c @@ -3216,7 +3216,8 @@ GST_START_TEST (test_video_formats_pstrides) || fmt == GST_VIDEO_FORMAT_NV12_10LE40 || fmt == GST_VIDEO_FORMAT_Y410 || fmt == GST_VIDEO_FORMAT_NV12_8L128 - || fmt == GST_VIDEO_FORMAT_NV12_10BE_8L128) { + || fmt == GST_VIDEO_FORMAT_NV12_10BE_8L128 + || fmt == GST_VIDEO_FORMAT_NV12_10LE40_4L4) { fmt++; continue; }