video: Add arbitrary tile dimensions support

In current tile representation, only tiles with power of two
width and height in bytes are supported. This limitation
prevents adding more complex tiles formats.

In this patch, we deprecate tile_ws and tile_hs from GstVideoFormatInfo and
replace if with an array of GstVideoTileInfo. Each plane tiles are then
described with their pixels width/height, line stride and total size.
The helper gst_video_format_info_get_tile_sizes() that depends on the
deprecated API is also being removed. This can simply be removed as it wasn't
in any stable release yet.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3424>
This commit is contained in:
Nicolas Dufresne 2022-11-15 13:50:13 -05:00 committed by GStreamer Marge Bot
parent 7840db5384
commit 5980fb76e7
14 changed files with 300 additions and 272 deletions

View file

@ -42525,7 +42525,6 @@
"gst_video_format_get_palette",
"gst_video_format_info_component",
"gst_video_format_info_extrapolate_stride",
"gst_video_format_info_get_tile_sizes",
"gst_video_format_to_fourcc",
"gst_video_format_to_string",
"gst_video_formats_raw",
@ -66670,4 +66669,4 @@
"zbar:message",
"zebrastripe",
"zebrastripe:threshold"
]
]

View file

@ -80,16 +80,16 @@ set_stride (GstVideoInfo * info, gint plane, gint stride)
const GstVideoFormatInfo *finfo = info->finfo;
if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
guint x_tiles, y_tiles, ws, hs, padded_height;
guint x_tiles, y_tiles, tile_height, padded_height;
gst_video_format_info_get_tile_sizes (finfo, plane, &ws, &hs);
tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (finfo, plane);
padded_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, plane,
info->height);
padded_height = GST_ROUND_UP_N (padded_height, 1 << hs);
padded_height = (padded_height + tile_height - 1) / tile_height;
x_tiles = stride >> ws;
y_tiles = padded_height >> hs;
x_tiles = stride / GST_VIDEO_FORMAT_INFO_TILE_STRIDE (finfo, plane);
y_tiles = padded_height / tile_height;
info->stride[plane] = GST_VIDEO_TILE_MAKE_STRIDE (x_tiles, y_tiles);
} else {
info->stride[plane] = stride;

View file

@ -615,14 +615,12 @@ get_egl_stride (const GstVideoInfo * info, gint plane)
{
const GstVideoFormatInfo *finfo = info->finfo;
gint stride = info->stride[plane];
guint ws;
if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
return stride;
gst_video_format_info_get_tile_sizes (finfo, plane, &ws, NULL);
return GST_VIDEO_TILE_X_TILES (stride) << ws;
return GST_VIDEO_TILE_X_TILES (stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (finfo, plane);
}
/**

View file

@ -2691,15 +2691,16 @@ _init_convert (GstGLColorConvert * convert)
}
if (GST_VIDEO_FORMAT_INFO_IS_TILED (convert->in_info.finfo)) {
guint ws, hs;
guint tile_width, tile_height;
gsize stride;
gfloat width, height;
stride = GST_VIDEO_INFO_PLANE_STRIDE (&convert->in_info, 0);
gst_video_format_info_get_tile_sizes (convert->in_info.finfo, 0, &ws, &hs);
tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (convert->in_info.finfo, 0);
tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (convert->in_info.finfo, 0);
width = GST_VIDEO_TILE_X_TILES (stride) << ws;
height = GST_VIDEO_TILE_Y_TILES (stride) << hs;
width = GST_VIDEO_TILE_X_TILES (stride) * tile_width;
height = GST_VIDEO_TILE_Y_TILES (stride) * tile_height;
gst_gl_shader_set_uniform_1f (convert->shader, "width", width);
gst_gl_shader_set_uniform_1f (convert->shader, "height", height);

View file

@ -123,13 +123,13 @@ static inline guint
_get_plane_height (const GstVideoInfo * info, guint plane)
{
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo)) {
guint hs;
guint tile_height;
gsize stride;
gst_video_format_info_get_tile_sizes (info->finfo, plane, NULL, &hs);
tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, plane);
stride = GST_VIDEO_INFO_PLANE_STRIDE (info, plane);
return GST_VIDEO_TILE_Y_TILES (stride) << hs;
return GST_VIDEO_TILE_Y_TILES (stride) * tile_height;
}
if (GST_VIDEO_INFO_IS_YUV (info)) {
@ -151,8 +151,8 @@ _get_mem_stride (GstGLMemory * gl_mem)
if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
return stride;
return
GST_VIDEO_TILE_X_TILES (stride) << GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
return GST_VIDEO_TILE_X_TILES (stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (finfo, gl_mem->plane);
}
static inline void

View file

@ -633,11 +633,10 @@ gst_gl_get_plane_data_size (const GstVideoInfo * info,
gint x_tiles, y_tiles;
gint tile_size;
tile_size = gst_video_format_info_get_tile_sizes (finfo, plane, NULL, NULL);
stride = GST_VIDEO_INFO_PLANE_STRIDE (info, plane);
x_tiles = GST_VIDEO_TILE_X_TILES (stride);
y_tiles = GST_VIDEO_TILE_Y_TILES (stride);
tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, plane);
plane_size = x_tiles * y_tiles * tile_size;
} else {

View file

@ -4747,46 +4747,33 @@ pack_A422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
}
static void
get_tile_NV12 (gint tile_width, gint ts, gint tx, gint ty,
GstVideoTileMode mode,
get_tile_NV12 (const GstVideoFormatInfo * info, gint tx, gint ty,
const gpointer data[GST_VIDEO_MAX_PLANES],
const gint stride[GST_VIDEO_MAX_PLANES],
gpointer tile_data[GST_VIDEO_MAX_PLANES],
gint tile_stride[GST_VIDEO_MAX_PLANES])
{
gsize offset;
GstVideoTileMode mode = GST_VIDEO_FORMAT_INFO_TILE_MODE (info);
gsize index, offset;
/* index of Y tile */
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;
index = gst_video_tile_get_index (mode, tx, ty,
GST_VIDEO_TILE_X_TILES (stride[0]), GST_VIDEO_TILE_Y_TILES (stride[0]));
offset = index * GST_VIDEO_FORMAT_INFO_TILE_SIZE (info, 0);
tile_data[0] = ((guint8 *) data[0]) + offset;
/* index of UV tile */
if (stride[0] != stride[1]) {
offset = gst_video_tile_get_index (mode,
tx, ty >> 1, GST_VIDEO_TILE_X_TILES (stride[1]),
GST_VIDEO_TILE_Y_TILES (stride[1]));
index = gst_video_tile_get_index (mode, tx,
GST_VIDEO_FORMAT_INFO_HAS_SUBTILES (info) ? ty : ty / 2,
GST_VIDEO_TILE_X_TILES (stride[1]), GST_VIDEO_TILE_Y_TILES (stride[1]));
offset = index * GST_VIDEO_FORMAT_INFO_TILE_SIZE (info, 1);
offset <<= ts;
/* On odd rows we return the second part of the UV tile */
offset |= (ty & 1) << (ts - 1);
} else {
/* handle subsampled tiles, with type of tiles will have the same number
* of tiles on both planes, but the height of the tiles are half. */
offset = gst_video_tile_get_index (mode,
tx, ty, GST_VIDEO_TILE_X_TILES (stride[1]),
GST_VIDEO_TILE_Y_TILES (stride[1]));
/* For subsampled tile Subsampled tile size */
offset <<= (ts - 1);
}
if (!GST_VIDEO_FORMAT_INFO_HAS_SUBTILES (info) && (ty & 1))
offset += GST_VIDEO_FORMAT_INFO_TILE_SIZE (info, 1) / 2;
tile_data[1] = ((guint8 *) data[1]) + offset;
tile_stride[0] = tile_stride[1] = tile_width;
tile_stride[0] = GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info, 0);
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
@ -4795,49 +4782,46 @@ 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)
{
const GstVideoFormatInfo *unpack_info, *finfo;
const GstVideoFormatInfo *unpack_info, *tile_finfo;
guint8 *line = dest;
gint ws, hs, ts, tile_width;
gint tile_width, tile_height;
gint ntx, tx, ty;
gint unpack_pstride;
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
ts = ws + hs;
tile_width = 1 << ws;
tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info, 0);
tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info, 0);
/* we reuse these unpack functions */
finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
tile_finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
/* get pstride of unpacked format */
unpack_info = gst_video_format_get_info (info->unpack_format);
unpack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (unpack_info, 0);
/* first x tile to convert */
tx = x >> ws;
tx = x / tile_width;
/* Last tile to convert */
ntx = ((x + width - 1) >> ws) + 1;
ntx = ((x + width - 1) / tile_width) + 1;
/* The row we are going to convert */
ty = y >> hs;
ty = y / tile_height;
/* y position in a tile */
y = y & ((1 << hs) - 1);
y = y % tile_height;
/* x position in a tile */
x = x & (tile_width - 1);
x = x % tile_width;
for (; tx < ntx; tx++) {
gpointer tdata[GST_VIDEO_MAX_PLANES];
gint tstride[GST_VIDEO_MAX_PLANES];
gint unpack_width;
get_tile_NV12 (tile_width, ts, tx, ty, info->tile_mode,
data, stride, tdata, tstride);
get_tile_NV12 (info, tx, ty, data, stride, tdata, tstride);
/* the number of bytes left to unpack */
unpack_width = MIN (width - x, tile_width - x);
finfo->unpack_func (finfo, flags, line, tdata, tstride, x, y, unpack_width);
tile_finfo->unpack_func (tile_finfo, flags, line, tdata, tstride, x, y,
unpack_width);
x = 0;
width -= unpack_width;
@ -4851,45 +4835,41 @@ pack_NV12_TILED (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
const gint stride[GST_VIDEO_MAX_PLANES], GstVideoChromaSite chroma_site,
gint y, gint width)
{
const GstVideoFormatInfo *pack_info, *finfo;
const GstVideoFormatInfo *pack_info, *tile_finfo;
guint8 *line = src;
gint ws, hs, ts, tile_width;
gint tile_width, tile_height;
gint ntx, tx, ty;
gint pack_pstride;
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
ts = ws + hs;
tile_width = 1 << ws;
tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info, 0);
tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info, 0);
/* we reuse these pack functions */
finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
tile_finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
/* get pstride of packed format */
pack_info = gst_video_format_get_info (info->unpack_format);
pack_pstride = GST_VIDEO_FORMAT_INFO_PSTRIDE (pack_info, 0);
/* Last tile to convert */
ntx = ((width - 1) >> ws) + 1;
ntx = ((width - 1) / tile_width) + 1;
/* The row we are going to convert */
ty = y >> hs;
ty = y / tile_height;
/* y position in a tile */
y = y & ((1 << hs) - 1);
y = y % tile_height;
for (tx = 0; tx < ntx; tx++) {
gpointer tdata[GST_VIDEO_MAX_PLANES];
gint tstride[GST_VIDEO_MAX_PLANES];
gint pack_width;
get_tile_NV12 (tile_width, ts, tx, ty, info->tile_mode,
data, stride, tdata, tstride);
get_tile_NV12 (info, tx, ty, data, stride, tdata, tstride);
/* the number of bytes left to pack */
/* the number of pixels left to pack */
pack_width = MIN (width, tile_width);
finfo->pack_func (finfo, flags, line, sstride, tdata, tstride,
tile_finfo->pack_func (tile_finfo, flags, line, sstride, tdata, tstride,
chroma_site, y, pack_width);
width -= pack_width;
@ -6820,8 +6800,8 @@ unpack_NV12_10BE_8L128 (const GstVideoFormatInfo * info,
int i;
int j;
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
ws = 3;
hs = 7;
ts = ws + hs;
ty = y >> hs;
y = y & ((1 << hs) - 1);
@ -6874,8 +6854,8 @@ pack_NV12_10BE_8L128 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
guint16 mask[2];
int i;
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
ws = 3;
hs = 7;
ts = ws + hs;
ty = y >> hs;
y = y & ((1 << hs) - 1);
@ -6999,12 +6979,13 @@ 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_ws (width shift), tile_hs (height shift) */
#define TILE_4x4(mode) GST_VIDEO_TILE_MODE_ ##mode, 2, 2
#define TILE_16x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 4, 5
#define TILE_32x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 5, 5
#define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5
#define TILE_8x128(mode) GST_VIDEO_TILE_MODE_ ##mode, 3, 7
/* tile_mode, tile_ws (width shift), tile_hs (height shift), tile_info[] */
#define TILE_4x4(mode) GST_VIDEO_TILE_MODE_ ##mode, 2, 2, { {4, 4, 4, 16}, {4, 4, 4, 16}, }
#define TILE_16x32s(mode) GST_VIDEO_TILE_MODE_ ##mode, 4, 5, { {16, 32, 16, 512}, {16, 16, 16, 256}, }
#define TILE_32x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 5, 5, { {32, 32, 32, 1024}, {32, 32, 32, 1024}, }
#define TILE_64x32(mode) GST_VIDEO_TILE_MODE_ ##mode, 6, 5, { {64, 32, 64, 2048}, {64, 32, 64, 2048}, }
#define TILE_8x128(mode) GST_VIDEO_TILE_MODE_ ##mode, 3, 7, { {8, 128, 8, 1024}, {8, 128, 8, 1024}, }
#define TILE_10bit_8x128(mode) GST_VIDEO_TILE_MODE_ ##mode, 3, 7, { {0, 128, 8, 1024}, {0, 128, 8, 1024}, }
#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 } }
@ -7049,6 +7030,7 @@ typedef struct
#define MAKE_GRAY_C_LE_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
{ 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_GRAY | GST_VIDEO_FORMAT_FLAG_COMPLEX | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
static const VideoFormat formats[] = {
{0x00000000, {GST_VIDEO_FORMAT_UNKNOWN, "UNKNOWN", "unknown video", 0, DPTH0,
PSTR0, PLANE_NA, OFFS0}},
@ -7304,15 +7286,17 @@ static const VideoFormat formats[] = {
OFFS6420, SUB4444, PACK_ABGR64_BE),
MAKE_YUV_ST_FORMAT (NV12_16L32S, "raw video",
GST_MAKE_FOURCC ('M', 'M', '2', '1'), DPTH888, PSTR122, PLANE011,
OFFS001, SUB420, PACK_NV12_TILED, TILE_16x32 (LINEAR)),
OFFS001, SUB420, PACK_NV12_TILED, TILE_16x32s (LINEAR)),
MAKE_YUV_T_FORMAT (NV12_8L128, "raw video",
GST_MAKE_FOURCC ('N', 'A', '1', '2'), DPTH888, PSTR122, PLANE011,
OFFS001, SUB420, PACK_NV12_TILED, TILE_8x128 (LINEAR)),
MAKE_YUV_T_FORMAT (NV12_10BE_8L128, "raw video",
GST_MAKE_FOURCC ('N', 'T', '1', '2'), DPTH10_10_10, PSTR122, PLANE011,
OFFS001, SUB420, PACK_NV12_10BE_8L128, TILE_8x128 (LINEAR)),
GST_MAKE_FOURCC ('N', 'T', '1', '2'), DPTH10_10_10, PSTR0, PLANE011,
OFFS001, SUB420, PACK_NV12_10BE_8L128, TILE_10bit_8x128 (LINEAR)),
};
G_GNUC_END_IGNORE_DEPRECATIONS;
static GstVideoFormat
gst_video_format_from_rgb32_masks (int red_mask, int green_mask, int blue_mask)
{
@ -7898,62 +7882,3 @@ gst_video_make_raw_caps_with_features (const GstVideoFormat formats[],
return caps;
}
static void
scale_tile_shifts (const GstVideoFormatInfo * finfo, gint plane, guint * ws,
guint * hs)
{
gint comp[GST_VIDEO_MAX_COMPONENTS];
gint i;
gst_video_format_info_component (finfo, plane, comp);
/* scale the tile size according to the subsampling */
*ws -= finfo->w_sub[comp[0]];
*hs -= finfo->h_sub[comp[0]];
/* for each additional component in the same plane, double the tile width,
* this should provide the appropriate tile size when the tile size varies
* base on the subsampling. */
for (i = 1; i < GST_VIDEO_MAX_COMPONENTS && comp[i] >= 0; i++)
*ws += 1;
}
/**
* gst_video_format_info_get_tile_sizes:
* @finfo: #GstVideoFormatInfo
* @plane: The plane to read the tile sizes for.
* @out_ws: (nullable): Set to the scaled tile width shift
* @out_hs: (nullable): Set to the scaled tile height shift
*
* This function will read the width and height tile dimension shifts from
* @info and scale it according to the tiling type and @plane. The results
* will written into @out_hs and @out_ws. It also computes the size of a tile
* in bytes.
*
* Returns: The size of a tile in bytes.
*
* Since: 1.22
*/
guint
gst_video_format_info_get_tile_sizes (const GstVideoFormatInfo * finfo,
guint plane, guint * out_ws, guint * out_hs)
{
guint ws, hs;
g_return_val_if_fail (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo), 0);
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
if (GST_VIDEO_FORMAT_INFO_HAS_SUBTILES (finfo))
scale_tile_shifts (finfo, plane, &ws, &hs);
if (out_ws)
*out_ws = ws;
if (out_hs)
*out_hs = hs;
return 1 << (ws + hs);
}

View file

@ -596,8 +596,11 @@ typedef void (*GstVideoFormatPack) (const GstVideoFormatInfo *info,
* @pack_lines: the amount of lines that will be packed
* @pack_func: an pack function for this format
* @tile_mode: The tiling mode
* @tile_ws: The width of a tile, in bytes, represented as a shift
* @tile_hs: The height of a tile, in bytes, represented as a shift
* @tile_ws: The width of a tile, in bytes, represented as a shift. DEPRECATED,
* use tile_info[] array instead.
* @tile_hs: The height of a tile, in bytes, represented as a shift. DEPREACTED,
* use tile_info[] array instead.
* @tile_info: Per-plane tile information
*
* Information for a video format.
*/
@ -623,11 +626,17 @@ struct _GstVideoFormatInfo {
GstVideoFormatPack pack_func;
GstVideoTileMode tile_mode;
guint tile_ws;
guint tile_hs;
G_DEPRECATED_FOR(tile_info) guint tile_ws;
G_DEPRECATED_FOR(tile_info) guint tile_hs;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
/**
* GstVideoFormatInfo.tile_info:
*
* Information about the tiles for each of the planes.
*
* Since: 1.22
*/
GstVideoTileInfo tile_info[GST_VIDEO_MAX_PLANES];
};
#define GST_VIDEO_FORMAT_INFO_FORMAT(info) ((info)->format)
@ -728,6 +737,60 @@ struct _GstVideoFormatInfo {
#define GST_VIDEO_FORMAT_INFO_TILE_WS(info) ((info)->tile_ws)
#define GST_VIDEO_FORMAT_INFO_TILE_HS(info) ((info)->tile_hs)
/**
* GST_VIDEO_FORMAT_INFO_TILE_SIZE:
* @info: a #GstVideoFormatInfo
* @plane: the plane index
*
* Provides the size in bytes of a tile in the specified @plane. This replaces
* the width and height shift, which was limited to power of two dimensions.
*
* Since: 1.22
*/
#define GST_VIDEO_FORMAT_INFO_TILE_SIZE(info,plane) ((info)->tile_info[plane].size)
/**
* GST_VIDEO_FORMAT_INFO_TILE_WIDTH:
* @info: a #GstVideoFormatInfo
* @plane: the plane index
*
* See #GstVideoTileInfo.width.
*
* Return the width of one tile in pixels, zero if its not an integer.
*
* Since: 1.22
*/
#define GST_VIDEO_FORMAT_INFO_TILE_WIDTH(info,plane) ((info)->tile_info[plane].width)
/**
* GST_VIDEO_FORMAT_INFO_TILE_HEIGHT:
* @info: a #GstVideoFormatInfo
* @plane: the plane index
*
* See #GstVideoTileInfo.height.
*
* Returns the tile height.
*
* Since: 1.22
*/
#define GST_VIDEO_FORMAT_INFO_TILE_HEIGHT(info,plane) ((info)->tile_info[plane].height)
/**
* GST_VIDEO_FORMAT_INFO_TILE_STRIDE:
* @info: a #GstVideoFormatInfo
* @plane: the plane index
*
* See #GstVideoTileInfo.stride.
*
* Returns the stride of one tile, regardless of the internal details of the
* tile (could be a complex system with subtile) the tiles size should alway
* match the tile width multiplied by the tile stride.
*
* Since: 1.22
*/
#define GST_VIDEO_FORMAT_INFO_TILE_STRIDE(info,plane) ((info)->tile_info[plane].stride)
GST_VIDEO_API
void gst_video_format_info_component (const GstVideoFormatInfo *info, guint plane, gint components[GST_VIDEO_MAX_COMPONENTS]);
@ -861,12 +924,6 @@ GST_VIDEO_API
GstCaps * gst_video_make_raw_caps_with_features (const GstVideoFormat formats[], guint len,
GstCapsFeatures * features);
GST_VIDEO_API
guint gst_video_format_info_get_tile_sizes (const GstVideoFormatInfo * finfo,
guint plane,
guint * out_ws, guint * out_hs);
G_END_DECLS

View file

@ -349,11 +349,12 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
gint tile_size;
gint sx_tiles, sy_tiles, dx_tiles, dy_tiles;
guint i, j, ws, hs, ts;
guint i, j, tw, th;
GstVideoTileMode mode;
tile_size = gst_video_format_info_get_tile_sizes (finfo, plane, &ws, &hs);
ts = ws + hs;
tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (finfo, plane);
tw = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (finfo, plane);
th = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (finfo, plane);
mode = GST_VIDEO_FORMAT_INFO_TILE_MODE (finfo);
@ -364,8 +365,8 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
dy_tiles = GST_VIDEO_TILE_Y_TILES (ds);
/* this is the amount of tiles to copy */
w = ((w - 1) >> ws) + 1;
h = ((h - 1) >> hs) + 1;
w = ((w - 1) / tw) + 1;
h = ((h - 1) / th) + 1;
/* FIXME can possibly do better when no retiling is needed, it depends on
* the stride and the tile_size */
@ -376,7 +377,7 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
si = gst_video_tile_get_index (mode, i, j, sx_tiles, sy_tiles);
di = gst_video_tile_get_index (mode, i, j, dx_tiles, dy_tiles);
memcpy (dp + (di << ts), sp + (si << ts), tile_size);
memcpy (dp + (di * tile_size), sp + (si * tile_size), tile_size);
}
}
} else {

View file

@ -1097,39 +1097,40 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
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_N (width, 1 << ws) >> ws,
GST_ROUND_UP_N (height, 1 << hs) >> hs);
info->stride[1] =
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_N (width, 1 << ws) * GST_ROUND_UP_N (height, 1 << hs);
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);
gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0);
gint n_tile_x = GST_ROUND_UP_N (info->width, tile_width) / tile_width;
gint n_tile_y = GST_ROUND_UP_N (info->height, tile_height) / tile_height;
info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, n_tile_y);
info->stride[1] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x,
GST_ROUND_UP_2 (n_tile_y) / 2);
info->offset[1] = n_tile_x * n_tile_y * tile_size;
info->size = info->offset[1] +
GST_ROUND_UP_N (width, 1 << ws) *
(GST_ROUND_UP_N (height, 1 << (hs + 1)) / 2);
n_tile_x * GST_ROUND_UP_2 (n_tile_y) / 2 * tile_size;
break;
}
case GST_VIDEO_FORMAT_NV12_16L32S:
{
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_N (width, 1 << ws) >> ws,
GST_ROUND_UP_N (height, 1 << hs) >> hs);
const gsize y_tile_size =
GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0);
const gsize uv_tile_size =
GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0);
gint tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info->finfo, 0);
gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0);
gint n_tile_x = GST_ROUND_UP_N (info->width, tile_width) / tile_width;
gint n_tile_y = GST_ROUND_UP_N (info->height, tile_height) / tile_height;
info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, n_tile_y);
/*
* size of UV plane tiles is subsample, hence have the same number of
* tiles in both directions.
*/
info->stride[1] = info->stride[0];
info->offset[0] = 0;
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_N (width, 1 << ws) *
GST_ROUND_UP_N (height, 1 << hs) / 2;
info->offset[1] = n_tile_x * n_tile_y * y_tile_size;
info->size = info->offset[1] + n_tile_x * n_tile_y * uv_tile_size;
break;
}
case GST_VIDEO_FORMAT_A420_10LE:
@ -1220,47 +1221,49 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
break;
case GST_VIDEO_FORMAT_NV12_8L128:
{
gint ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info->finfo);
gint hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info->finfo);
gint ALIGN_W = 1 << ws;
gint ALIGN_H = 1 << hs;
gint tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0);
gint tile_width = GST_VIDEO_FORMAT_INFO_TILE_WIDTH (info->finfo, 0);
gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0);
gint ALIGN_W = tile_width;
gint ALIGN_H = tile_height;
guint n_tile_x, y_n_tile_y, uv_n_tile_y;
if (GST_VIDEO_INFO_IS_INTERLACED (info))
ALIGN_H = (ALIGN_H << 1);
info->stride[0] =
GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (width, ALIGN_W) >> ws,
GST_ROUND_UP_N (height, ALIGN_H) >> hs);
info->stride[1] =
GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (width, ALIGN_W) >> ws,
GST_ROUND_UP_N (height, ALIGN_H << 1) >> (hs + 1));
ALIGN_H *= 2;
n_tile_x = GST_ROUND_UP_N (width, ALIGN_W) / tile_width;
y_n_tile_y = GST_ROUND_UP_N (height, ALIGN_H) / tile_height;
uv_n_tile_y = GST_ROUND_UP_2 (y_n_tile_y) / 2;
info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, y_n_tile_y);
info->stride[1] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, uv_n_tile_y);
info->offset[0] = 0;
info->offset[1] =
GST_ROUND_UP_N (width, ALIGN_W) * GST_ROUND_UP_N (height, ALIGN_H);
cr_h = GST_ROUND_UP_N (height, ALIGN_H << 1) / 2;
info->size = info->offset[1] + GST_ROUND_UP_N (width, ALIGN_W) * cr_h;
info->offset[1] = n_tile_x * y_n_tile_y * tile_size;
info->size = info->offset[1] + n_tile_x * uv_n_tile_y * tile_size;
break;
}
case GST_VIDEO_FORMAT_NV12_10BE_8L128:
{
gint ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info->finfo);
gint hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info->finfo);
gint ALIGN_W = 1 << ws;
gint ALIGN_H = 1 << hs;
gint tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, 0);
gint tile_stride = GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info->finfo, 0);
gint tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (info->finfo, 0);
gint stride = GST_ROUND_UP_8 (width * 10) >> 3;
gint ALIGN_W = tile_stride;
gint ALIGN_H = tile_height;
guint n_tile_x, y_n_tile_y, uv_n_tile_y;
if (GST_VIDEO_INFO_IS_INTERLACED (info))
ALIGN_H = (ALIGN_H << 1);
info->stride[0] =
GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (stride, ALIGN_W) >> ws,
GST_ROUND_UP_N (height, ALIGN_H) >> hs);
info->stride[1] =
GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_N (stride, ALIGN_W) >> ws,
GST_ROUND_UP_N (height, ALIGN_H << 1) >> (hs + 1));
ALIGN_H *= 2;
n_tile_x = GST_ROUND_UP_N (stride, ALIGN_W) / tile_stride;
y_n_tile_y = GST_ROUND_UP_N (height, ALIGN_H) / tile_height;
uv_n_tile_y = GST_ROUND_UP_2 (y_n_tile_y) / 2;
info->stride[0] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, y_n_tile_y);
info->stride[1] = GST_VIDEO_TILE_MAKE_STRIDE (n_tile_x, uv_n_tile_y);
info->offset[0] = 0;
info->offset[1] =
GST_ROUND_UP_N (stride, ALIGN_W) * GST_ROUND_UP_N (height, ALIGN_H);
cr_h = GST_ROUND_UP_N (height, ALIGN_H << 1) / 2;
info->size = info->offset[1] + GST_ROUND_UP_N (stride, ALIGN_W) * cr_h;
info->offset[1] = n_tile_x * y_n_tile_y * tile_size;
info->size = info->offset[1] + n_tile_x * uv_n_tile_y * tile_size;
break;
}
case GST_VIDEO_FORMAT_ENCODED:
@ -1275,15 +1278,22 @@ fill_planes (GstVideoInfo * info, gsize plane_size[GST_VIDEO_MAX_PLANES])
if (plane_size) {
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
if (i < GST_VIDEO_INFO_N_PLANES (info)) {
gint comp[GST_VIDEO_MAX_COMPONENTS];
guint plane_height;
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo)) {
guint x_tiles = GST_VIDEO_TILE_X_TILES (info->stride[i]);
guint y_tiles = GST_VIDEO_TILE_Y_TILES (info->stride[i]);
plane_size[i] = x_tiles * y_tiles *
GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, i);
} else {
gint comp[GST_VIDEO_MAX_COMPONENTS];
guint plane_height;
/* Convert plane index to component index */
gst_video_format_info_component (info->finfo, i, comp);
plane_height =
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0],
GST_VIDEO_INFO_FIELD_HEIGHT (info));
plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i);
/* Convert plane index to component index */
gst_video_format_info_component (info->finfo, i, comp);
plane_height =
GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (info->finfo, comp[0],
GST_VIDEO_INFO_FIELD_HEIGHT (info));
plane_size[i] = plane_height * GST_VIDEO_INFO_PLANE_STRIDE (info, i);
}
} else {
plane_size[i] = 0;
}

View file

@ -105,6 +105,8 @@ typedef enum
*/
#define GST_VIDEO_TILE_Y_TILES(stride) ((stride) >> GST_VIDEO_TILE_Y_TILES_SHIFT)
typedef struct _GstVideoTileInfo GstVideoTileInfo;
/**
* GstVideoTileMode:
* @GST_VIDEO_TILE_MODE_UNKNOWN: Unknown or unset tile mode
@ -132,6 +134,63 @@ typedef enum
GST_VIDEO_TILE_MODE_LINEAR = GST_VIDEO_TILE_MAKE_MODE (2, INDEXED),
} GstVideoTileMode;
/**
* GstVideoTileInfo:
*
* Description of a tile. This structure allow to describe arbitrary tile
* dimensions and sizes.
*
* Since: 1.22
*/
struct _GstVideoTileInfo
{
/**
* GstVideoTileInfo.width:
*
* The width in pixels of a tile. This value can be zero if the number of
* pixels per line is not an integer value.
*
* Since: 1.22
*/
guint width;
/**
* GstVideoTileInfo::height:
*
* The width in pixels of a tile. This value can be zero if the number of
* pixels per line is not an integer value.
*
* Since: 1.22
*/
guint height;
/**
* GstVideoTileInfo.stride:
*
* The stride (in bytes) of a tile line. Regardless if the tile have sub-tiles
* this stride multiplied by the height should be equal to
* #GstVideoTileInfo.size. This value is used to translate into linear stride
* when older APIs are being used to expose this format.
*
* Since: 1.22
*/
guint stride;
/**
* GstVideoTileInfo.size:
*
* The size in bytes of a tile. This value must be divisible by
* #GstVideoTileInfo.stride.
*
* Since: 1.22
*/
guint size;
/* <private> */
guint32 padding[GST_PADDING];
};
GST_VIDEO_API
guint gst_video_tile_get_index (GstVideoTileMode mode, gint x, gint y,
gint x_tiles, gint y_tiles);

View file

@ -1161,13 +1161,9 @@ gst_raw_video_parse_update_info (GstRawVideoParseConfig * config)
gint stride = GST_VIDEO_INFO_PLANE_STRIDE (info, last_plane);
gint x_tiles = GST_VIDEO_TILE_X_TILES (stride);
gint y_tiles = GST_VIDEO_TILE_Y_TILES (stride);
gint tile_width = 1 << GST_VIDEO_FORMAT_INFO_TILE_WS (info->finfo);
gint tile_height = 1 << GST_VIDEO_FORMAT_INFO_TILE_HS (info->finfo);
guint tile_size = GST_VIDEO_FORMAT_INFO_TILE_SIZE (info->finfo, last_plane);
if (GST_VIDEO_FORMAT_INFO_HAS_SUBTILES (info->finfo))
tile_height /= 2;
last_plane_size = x_tiles * y_tiles * tile_width * tile_height;
last_plane_size = x_tiles * y_tiles * tile_size;
} else {
gint comp[GST_VIDEO_MAX_COMPONENTS];
gst_video_format_info_component (info->finfo, last_plane, comp);

View file

@ -259,16 +259,9 @@ gst_v4l2_buffer_pool_import_userptr (GstV4l2BufferPool * pool,
for (i = 0; i < GST_VIDEO_FORMAT_INFO_N_PLANES (finfo); i++) {
if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
gint tinfo = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i);
gint pstride;
guint pheight;
pstride = GST_VIDEO_TILE_X_TILES (tinfo) <<
GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
pheight = GST_VIDEO_TILE_Y_TILES (tinfo) <<
GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
size[i] = pstride * pheight;
size[i] = GST_VIDEO_TILE_X_TILES (tinfo) *
GST_VIDEO_TILE_Y_TILES (tinfo) *
GST_VIDEO_FORMAT_INFO_TILE_SIZE (finfo, i);
} else {
size[i] = GST_VIDEO_FRAME_PLANE_STRIDE (&data->frame, i) *
GST_VIDEO_FRAME_COMP_HEIGHT (&data->frame, i);

View file

@ -3245,23 +3245,16 @@ gst_v4l2_object_set_stride (GstVideoInfo * info, GstVideoAlignment * align,
const GstVideoFormatInfo *finfo = info->finfo;
if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
gint x_tiles, y_tiles, ws, hs, tile_height, padded_height;
gint x_tiles, y_tiles, tile_height, padded_height;
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
/* this only works for what we support, NV12 subsampled tiles */
if (GST_VIDEO_FORMAT_INFO_HAS_SUBTILES (finfo) && plane == 1)
hs -= 1;
tile_height = 1 << hs;
tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (finfo, plane);
padded_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, plane,
info->height + align->padding_top + align->padding_bottom);
padded_height = GST_ROUND_UP_N (padded_height, tile_height);
padded_height = (padded_height + tile_height - 1) / tile_height;
x_tiles = stride >> ws;
y_tiles = padded_height >> hs;
x_tiles = stride / GST_VIDEO_FORMAT_INFO_TILE_STRIDE (finfo, plane);
y_tiles = padded_height / tile_height;
info->stride[plane] = GST_VIDEO_TILE_MAKE_STRIDE (x_tiles, y_tiles);
} else {
info->stride[plane] = stride;
@ -3348,12 +3341,9 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
padded_height = format->fmt.pix.height;
if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
guint hs, tile_height;
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
tile_height = 1 << hs;
padded_height = GST_ROUND_UP_N (padded_height, tile_height);
guint tile_height;
tile_height = GST_VIDEO_FORMAT_INFO_TILE_HEIGHT (finfo, 0);
padded_height = (padded_height + tile_height - 1) / tile_height;
}
align->padding_bottom =
@ -3764,8 +3754,8 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, i);
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo))
stride = GST_VIDEO_TILE_X_TILES (stride) <<
GST_VIDEO_FORMAT_INFO_TILE_WS (info.finfo);
stride = GST_VIDEO_TILE_X_TILES (stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info.finfo, i);
format.fmt.pix_mp.plane_fmt[i].bytesperline = stride;
}
@ -3783,8 +3773,8 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
format.fmt.pix.field = field;
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo))
stride = GST_VIDEO_TILE_X_TILES (stride) <<
GST_VIDEO_FORMAT_INFO_TILE_WS (info.finfo);
stride = GST_VIDEO_TILE_X_TILES (stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info.finfo, i);
/* try to ask our preferred stride */
format.fmt.pix.bytesperline = stride;
@ -4804,8 +4794,8 @@ gst_v4l2_object_match_buffer_layout (GstV4l2Object * obj, guint n_planes,
gint plane_stride = stride[i];
if (GST_VIDEO_FORMAT_INFO_IS_TILED (obj->info.finfo))
plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) <<
GST_VIDEO_FORMAT_INFO_TILE_WS (obj->info.finfo);
plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (obj->info.finfo, i);
format.fmt.pix_mp.plane_fmt[i].bytesperline = plane_stride;
format.fmt.pix_mp.height = padded_height;
@ -4818,8 +4808,8 @@ gst_v4l2_object_match_buffer_layout (GstV4l2Object * obj, guint n_planes,
GST_DEBUG_OBJECT (obj->dbg_obj, "Wanted stride: %i", plane_stride);
if (GST_VIDEO_FORMAT_INFO_IS_TILED (obj->info.finfo))
plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) <<
GST_VIDEO_FORMAT_INFO_TILE_WS (obj->info.finfo);
plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (obj->info.finfo, 0);
format.fmt.pix.bytesperline = plane_stride;
format.fmt.pix.height = padded_height;