From 7d1028424c427fba7ce5ba3c710806851a82a8e9 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Mon, 13 Jul 2020 16:18:29 -0400 Subject: [PATCH] video: Add NV12_4L4 tile format This format is produced by Verisillicon VC8000D VPU decoder, it is a simple 4x4 tiling layout in a linear way. Part-of: --- gst-libs/gst/video/video-converter.c | 1 + gst-libs/gst/video/video-format.c | 23 +++++++++++++++-------- gst-libs/gst/video/video-format.h | 13 +++++++++++-- gst-libs/gst/video/video-info.c | 14 +++++++++++++- gst-libs/gst/video/video-tile.c | 3 +++ gst-libs/gst/video/video-tile.h | 9 +++++++++ tests/check/elements/videoscale.c | 1 + tests/check/libs/video.c | 1 + 8 files changed, 54 insertions(+), 11 deletions(-) diff --git a/gst-libs/gst/video/video-converter.c b/gst-libs/gst/video/video-converter.c index 32c3bf1..7e4a097 100644 --- a/gst-libs/gst/video/video-converter.c +++ b/gst-libs/gst/video/video-converter.c @@ -5965,6 +5965,7 @@ get_scale_format (GstVideoFormat format, gint plane) case GST_VIDEO_FORMAT_GBRA_12BE: case GST_VIDEO_FORMAT_GBRA_12LE: case GST_VIDEO_FORMAT_NV12_64Z32: + case GST_VIDEO_FORMAT_NV12_4L4: 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 f0c7a6b..30b34b1 100644 --- a/gst-libs/gst/video/video-format.c +++ b/gst-libs/gst/video/video-format.c @@ -4334,6 +4334,7 @@ pack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, static void get_tile_NV12 (gint tile_width, gint ts, gint tx, gint ty, + GstVideoTileMode mode, const gpointer data[GST_VIDEO_MAX_PLANES], const gint stride[GST_VIDEO_MAX_PLANES], gpointer tile_data[GST_VIDEO_MAX_PLANES], @@ -4342,14 +4343,14 @@ get_tile_NV12 (gint tile_width, gint ts, gint tx, gint ty, gsize offset; /* index of Y tile */ - offset = gst_video_tile_get_index (GST_VIDEO_TILE_MODE_ZFLIPZ_2X2, + offset = gst_video_tile_get_index (mode, tx, ty, GST_VIDEO_TILE_X_TILES (stride[0]), GST_VIDEO_TILE_Y_TILES (stride[0])); offset <<= ts; tile_data[0] = ((guint8 *) data[0]) + offset; /* index of UV tile */ - offset = gst_video_tile_get_index (GST_VIDEO_TILE_MODE_ZFLIPZ_2X2, + offset = gst_video_tile_get_index (mode, tx, ty >> 1, GST_VIDEO_TILE_X_TILES (stride[1]), GST_VIDEO_TILE_Y_TILES (stride[1])); offset <<= ts; @@ -4360,9 +4361,9 @@ get_tile_NV12 (gint tile_width, gint ts, gint tx, gint ty, tile_stride[0] = tile_stride[1] = tile_width; } -#define PACK_NV12_64Z32 GST_VIDEO_FORMAT_AYUV, unpack_NV12_64Z32, 1, pack_NV12_64Z32 +#define PACK_NV12_TILED GST_VIDEO_FORMAT_AYUV, unpack_NV12_TILED, 1, pack_NV12_TILED static void -unpack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, +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) { @@ -4402,7 +4403,8 @@ unpack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, gint tstride[GST_VIDEO_MAX_PLANES]; gint unpack_width; - get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride); + get_tile_NV12 (tile_width, ts, tx, ty, info->tile_mode, + data, stride, tdata, tstride); /* the number of bytes left to unpack */ unpack_width = MIN (width - x, tile_width - x); @@ -4416,7 +4418,7 @@ unpack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, } static void -pack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, +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) @@ -4453,7 +4455,8 @@ pack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags, gint tstride[GST_VIDEO_MAX_PLANES]; gint pack_width; - get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride); + get_tile_NV12 (tile_width, ts, tx, ty, info->tile_mode, + data, stride, tdata, tstride); /* the number of bytes left to pack */ pack_width = MIN (width, tile_width); @@ -6365,6 +6368,7 @@ typedef struct /* tile_mode, tile_width, tile_height */ #define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5 +#define TILE_4x4(mode) GST_VIDEO_TILE_MODE_ ##mode, 2, 2 #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 } } @@ -6541,7 +6545,7 @@ static const VideoFormat formats[] = { DPTH888, PSTR122, PLANE011, OFFS001, SUB444, PACK_NV24), MAKE_YUV_T_FORMAT (NV12_64Z32, "raw video", GST_MAKE_FOURCC ('T', 'M', '1', '2'), DPTH888, PSTR122, PLANE011, - OFFS001, SUB420, PACK_NV12_64Z32, TILE_64x32 (ZFLIPZ_2X2)), + OFFS001, SUB420, PACK_NV12_TILED, TILE_64x32 (ZFLIPZ_2X2)), MAKE_YUVA_FORMAT (A420_10BE, "raw video", 0x00000000, DPTH10_10_10_10, PSTR2222, PLANE0123, OFFS0, SUB4204, PACK_A420_10BE), MAKE_YUVA_LE_FORMAT (A420_10LE, "raw video", 0x00000000, DPTH10_10_10_10, @@ -6632,6 +6636,9 @@ static const VideoFormat formats[] = { PSTR8888, PLANE0, OFFS0, SUB4444, PACK_Y412_BE), MAKE_YUV_LE_FORMAT (Y412_LE, "raw video", 0x00000000, DPTH12_12_12_12_HI, PSTR8888, PLANE0, OFFS0, SUB4444, PACK_Y412_LE), + 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)), }; static GstVideoFormat diff --git a/gst-libs/gst/video/video-format.h b/gst-libs/gst/video/video-format.h index ecacb85..fa9a732 100644 --- a/gst-libs/gst/video/video-format.h +++ b/gst-libs/gst/video/video-format.h @@ -129,6 +129,7 @@ G_BEGIN_DECLS * @GST_VIDEO_FORMAT_Y212_LE: packed 4:2:2 YUV, 12 bits per channel (Y-U-Y-V) (Since: 1.18) * @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) * * Enum value describing the most common video formats. * @@ -233,6 +234,14 @@ typedef enum { GST_VIDEO_FORMAT_Y212_LE, GST_VIDEO_FORMAT_Y412_BE, GST_VIDEO_FORMAT_Y412_LE, + /** + * GST_VIDEO_FORMAT_NV12_4L4: + * + * NV12 with 4x4 tiles in linear order. + * + * Since: 1.18 + */ + GST_VIDEO_FORMAT_NV12_4L4, } GstVideoFormat; #define GST_VIDEO_MAX_PLANES 4 @@ -607,7 +616,7 @@ 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, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, " \ + "YV12, NV21, NV12, NV12_64Z32, NV12_4L4, 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, " \ @@ -619,7 +628,7 @@ 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, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, " \ + "YV12, NV21, NV12, NV12_64Z32, NV12_4L4, Y41B, IYU1, YVU9, YUV9, RGB16, BGR16, RGB15, BGR15, " \ "RGB8P, GRAY16_LE, GRAY16_BE, GRAY10_LE32, GRAY8 }" #endif diff --git a/gst-libs/gst/video/video-info.c b/gst-libs/gst/video/video-info.c index 1f4f2ce..68d89d0 100644 --- a/gst-libs/gst/video/video-info.c +++ b/gst-libs/gst/video/video-info.c @@ -1045,7 +1045,19 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES]) info->offset[0] = 0; info->offset[1] = GST_ROUND_UP_128 (width) * GST_ROUND_UP_32 (height); info->size = info->offset[1] + - GST_ROUND_UP_128 (width) * GST_ROUND_UP_64 (height) / 2; + GST_ROUND_UP_128 (width) * (GST_ROUND_UP_64 (height) / 2); + break; + case GST_VIDEO_FORMAT_NV12_4L4: + info->stride[0] = + GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_4 (width) / 4, + GST_ROUND_UP_4 (height) / 4); + info->stride[1] = + GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_4 (width) / 4, + GST_ROUND_UP_8 (height) / 8); + info->offset[0] = 0; + info->offset[1] = GST_ROUND_UP_4 (width) * GST_ROUND_UP_4 (height); + info->size = info->offset[1] + + GST_ROUND_UP_4 (width) * (GST_ROUND_UP_8 (height) / 2); break; case GST_VIDEO_FORMAT_A420_10LE: case GST_VIDEO_FORMAT_A420_10BE: diff --git a/gst-libs/gst/video/video-tile.c b/gst-libs/gst/video/video-tile.c index a54b986..e087365 100644 --- a/gst-libs/gst/video/video-tile.c +++ b/gst-libs/gst/video/video-tile.c @@ -99,6 +99,9 @@ gst_video_tile_get_index (GstVideoTileMode mode, gint x, gint y, offset += GST_ROUND_DOWN_4 (x + 2); } break; + case GST_VIDEO_TILE_MODE_LINEAR: + offset = y * x_tiles + x; + break; default: offset = 0; break; diff --git a/gst-libs/gst/video/video-tile.h b/gst-libs/gst/video/video-tile.h index 6489650..8992bb3 100644 --- a/gst-libs/gst/video/video-tile.h +++ b/gst-libs/gst/video/video-tile.h @@ -112,6 +112,7 @@ typedef enum * horizontally and two vertically are grouped together and are located * in memory in Z or flipped Z order. In case of odd rows, the last row * of blocks is arranged in linear order. + * @GST_VIDEO_TILE_MODE_LINEAR: Tiles are in row order. (Since: 1.18) * * Enum value describing the available tiling modes. */ @@ -119,6 +120,14 @@ typedef enum { GST_VIDEO_TILE_MODE_UNKNOWN = 0, GST_VIDEO_TILE_MODE_ZFLIPZ_2X2 = GST_VIDEO_TILE_MAKE_MODE (1, INDEXED), + /** + * GST_VIDEO_TILE_MODE_LINEAR: + * + * Tiles are in row order. + * + * Since: 1.18 + */ + GST_VIDEO_TILE_MODE_LINEAR = GST_VIDEO_TILE_MAKE_MODE (2, INDEXED), } GstVideoTileMode; GST_VIDEO_API diff --git a/tests/check/elements/videoscale.c b/tests/check/elements/videoscale.c index dc90564..2a36618 100644 --- a/tests/check/elements/videoscale.c +++ b/tests/check/elements/videoscale.c @@ -123,6 +123,7 @@ check_pad_template (GstPadTemplate * tmpl) case GST_VIDEO_FORMAT_GBR_10BE: case GST_VIDEO_FORMAT_GBR_10LE: case GST_VIDEO_FORMAT_NV12_64Z32: + case GST_VIDEO_FORMAT_NV12_4L4: 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 86b79de..0909ce5 100644 --- a/tests/check/libs/video.c +++ b/tests/check/libs/video.c @@ -3048,6 +3048,7 @@ GST_START_TEST (test_video_formats_pstrides) || fmt == GST_VIDEO_FORMAT_IYU1 || fmt == GST_VIDEO_FORMAT_GRAY10_LE32 || fmt == GST_VIDEO_FORMAT_NV12_64Z32 + || fmt == GST_VIDEO_FORMAT_NV12_4L4 || fmt == GST_VIDEO_FORMAT_NV12_10LE32 || fmt == GST_VIDEO_FORMAT_NV16_10LE32 || fmt == GST_VIDEO_FORMAT_NV12_10LE40 -- 2.7.4