video: Add support for linear 32x32 NV12 tiles
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Wed, 15 Jul 2020 01:43:56 +0000 (21:43 -0400)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Wed, 15 Jul 2020 01:43:56 +0000 (21:43 -0400)
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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/754>

gst-libs/gst/video/video-converter.c
gst-libs/gst/video/video-format.c
gst-libs/gst/video/video-format.h
gst-libs/gst/video/video-info.c
tests/check/elements/videoscale.c
tests/check/libs/video.c

index 7e4a097..c4c976d 100644 (file)
@@ -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:
index 30b34b1..394ad99 100644 (file)
@@ -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
index fa9a732..bebfcea 100644 (file)
@@ -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
index 68d89d0..b937e9f 100644 (file)
@@ -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);
index 2a36618..36543f3 100644 (file)
@@ -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:
index 0909ce5..078762b 100644 (file)
@@ -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