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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/753>
This commit is contained in:
Nicolas Dufresne 2020-07-13 16:18:29 -04:00 committed by GStreamer Merge Bot
parent c770f0b68e
commit 7d1028424c
8 changed files with 54 additions and 11 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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:

View file

@ -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;

View file

@ -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

View file

@ -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:

View file

@ -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