Commit f52fd7a6 authored by Nicolas Dufresne's avatar Nicolas Dufresne
Browse files

video: Don't use extra plane and componenent for tile format

Instead of using extra plane, we encode the number of tiles in x and y in the stride of
each planes (i.e. y_tiles << 16 | x_tiles) and introduce tile_mode, tile_width and
tile_height into GstVideoFormatInfo structure.

https://bugzilla.gnome.org/show_bug.cgi?id=707361
parent d899e6df
......@@ -1213,21 +1213,21 @@ Formats
depth 8
pstride: 2
default offset: size (component0)
default rstride: RU128 (width)
default rstride: (y_tiles << 16) | x_tiles
default x_tiles: RU128 (width) >> tile_width
default y_tiles: RU32 (height) >> tile_height
Component 2: V
depth: 8
pstride: 2
default offset: offset (component1) + 1
default rstride: RU128 (width)
Component 3: T
pstride TileMode zigzag
w_sub 6
h_sub 5
default offset: 0
default rstride: y_tiles
default rstride: (y_tiles << 16) | x_tiles
default x_tiles: RU128 (width) >> tile_width
default y_tiles: RU64 (height) >> (tile_height + 1)
Image
default size: RU128 (width) * RU32 (height) * 3 / 2
default size: RU128 (width) * (RU32 (height) + RU64 (height) / 2)
tile mode: ZFLIPZ_2X2
tile width: 6
tile height: 5
......@@ -27,7 +27,6 @@
#include <stdio.h>
#include "video-format.h"
#include "video-tile.h"
/**
* SECTION:gstvideo
......@@ -2084,8 +2083,7 @@ pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
}
static void
get_tile_NV12 (gint tile_width, gint ts, gint tx,
gint ty, gint x_tiles, gint y_tiles,
get_tile_NV12 (gint tile_width, gint ts, 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],
......@@ -2095,13 +2093,15 @@ get_tile_NV12 (gint tile_width, gint ts, gint tx,
/* index of Y tile */
offset = gst_video_tile_get_index (GST_VIDEO_TILE_MODE_ZFLIPZ_2X2,
tx, ty, x_tiles, y_tiles);
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,
tx, ty >> 1, x_tiles, (y_tiles + 1) >> 1);
tx, ty >> 1, GST_VIDEO_TILE_X_TILES (stride[1]),
GST_VIDEO_TILE_Y_TILES (stride[1]));
offset <<= ts;
/* On odd rows we return the second part of the UV tile */
offset |= (ty & 1) << (ts - 1);
......@@ -2118,20 +2118,16 @@ unpack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
{
const GstVideoFormatInfo *unpack_info, *finfo;
guint8 *line = dest;
gint x_tiles, y_tiles;
gint ws, hs, ts, tile_width;
gint ntx, tx, ty;
gint unpack_pstride;
ws = info->w_sub[GST_VIDEO_COMP_TILEINFO];
hs = info->h_sub[GST_VIDEO_COMP_TILEINFO];
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
ts = ws + hs;
tile_width = 1 << ws;
x_tiles = stride[0] >> ws;
y_tiles = stride[2];
/* we reuse these unpack functions */
finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
......@@ -2156,8 +2152,7 @@ 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, x_tiles, y_tiles,
data, stride, tdata, tstride);
get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride);
/* the number of bytes left to unpack */
unpack_width = MIN (width - x, tile_width - x);
......@@ -2178,20 +2173,16 @@ pack_NV12_64Z32 (const GstVideoFormatInfo * info, GstVideoPackFlags flags,
{
const GstVideoFormatInfo *pack_info, *finfo;
guint8 *line = src;
gint x_tiles, y_tiles;
gint ws, hs, ts, tile_width;
gint ntx, tx, ty;
gint pack_pstride;
ws = info->w_sub[GST_VIDEO_COMP_TILEINFO];
hs = info->h_sub[GST_VIDEO_COMP_TILEINFO];
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (info);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (info);
ts = ws + hs;
tile_width = 1 << ws;
x_tiles = stride[0] >> ws;
y_tiles = stride[2];
/* we reuse these pack functions */
finfo = gst_video_format_get_info (GST_VIDEO_FORMAT_NV12);
......@@ -2212,8 +2203,7 @@ 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, x_tiles, y_tiles,
data, stride, tdata, tstride);
get_tile_NV12 (tile_width, ts, tx, ty, data, stride, tdata, tstride);
/* the number of bytes left to pack */
pack_width = MIN (width, tile_width);
......@@ -2253,7 +2243,6 @@ typedef struct
#define PSTR111 { 1, 1, 1, 0 }
#define PSTR1111 { 1, 1, 1, 1 }
#define PSTR122 { 1, 2, 2, 0 }
#define PSTR122T(mode) { 1, 2, 2, GST_VIDEO_TILE_MODE_ ##mode }
#define PSTR2 { 2, 0, 0, 0 }
#define PSTR222 { 2, 2, 2, 0 }
#define PSTR244 { 2, 4, 4, 0 }
......@@ -2268,7 +2257,6 @@ typedef struct
#define PLANE0 1, { 0, 0, 0, 0 }
#define PLANE01 2, { 0, 1, 0, 0 }
#define PLANE011 2, { 0, 1, 1, 0 }
#define PLANE0110 3, { 0, 1, 1, 0 }
#define PLANE012 3, { 0, 1, 2, 0 }
#define PLANE0123 4, { 0, 1, 2, 3 }
#define PLANE021 3, { 0, 2, 1, 0 }
......@@ -2297,7 +2285,6 @@ typedef struct
#define SUB410 { 0, 2, 2, 0 }, { 0, 2, 2, 0 }
#define SUB411 { 0, 2, 2, 0 }, { 0, 0, 0, 0 }
#define SUB420 { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
#define SUB420T64x32 { 0, 1, 1, 6 }, { 0, 1, 1, 5 }
#define SUB422 { 0, 1, 1, 0 }, { 0, 0, 0, 0 }
#define SUB4 { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
#define SUB44 { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
......@@ -2305,6 +2292,9 @@ typedef struct
#define SUB4444 { 0, 0, 0, 0 }, { 0, 0, 0, 0 }
#define SUB4204 { 0, 1, 1, 0 }, { 0, 1, 1, 0 }
/* tile_mode, tile_width, tile_height */
#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 } }
#define MAKE_YUV_LE_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack ) \
......@@ -2317,8 +2307,8 @@ typedef struct
{ fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_ALPHA | GST_VIDEO_FORMAT_FLAG_UNPACK | GST_VIDEO_FORMAT_FLAG_LE, depth, pstride, plane, offs, sub, pack } }
#define MAKE_YUV_C_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
{ fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_COMPLEX, depth, pstride, plane, offs, sub, pack } }
#define MAKE_YUV_T_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack) \
{ fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_COMPLEX | GST_VIDEO_FORMAT_FLAG_TILED, depth, pstride, plane, offs, sub, pack } }
#define MAKE_YUV_T_FORMAT(name, desc, fourcc, depth, pstride, plane, offs, sub, pack, tile) \
{ fourcc, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_YUV | GST_VIDEO_FORMAT_FLAG_COMPLEX | GST_VIDEO_FORMAT_FLAG_TILED, depth, pstride, plane, offs, sub, pack, tile } }
#define MAKE_RGB_FORMAT(name, desc, depth, pstride, plane, offs, sub, pack) \
{ 0x00000000, {GST_VIDEO_FORMAT_ ##name, G_STRINGIFY(name), desc, GST_VIDEO_FORMAT_FLAG_RGB, depth, pstride, plane, offs, sub, pack } }
......@@ -2473,8 +2463,8 @@ static VideoFormat formats[] = {
MAKE_YUV_FORMAT (NV24, "raw video", GST_MAKE_FOURCC ('N', 'V', '2', '4'),
DPTH888, PSTR111, PLANE011, OFFS001, SUB444, PACK_NV24),
MAKE_YUV_T_FORMAT (NV12_64Z32, "raw video",
GST_MAKE_FOURCC ('T', 'M', '1', '2'), DPTH8880, PSTR122T (ZFLIPZ_2X2),
PLANE0110, OFFS001, SUB420T64x32, PACK_NV12_64Z32),
GST_MAKE_FOURCC ('T', 'M', '1', '2'), DPTH8880, PSTR122, PLANE011,
OFFS001, SUB420, PACK_NV12_64Z32, TILE_64x32 (ZFLIPZ_2X2)),
};
static GstVideoFormat
......
......@@ -25,6 +25,7 @@
G_BEGIN_DECLS
#include <gst/video/video-enumtypes.h>
#include <gst/video/video-tile.h>
/**
* GstVideoFormat:
......@@ -203,9 +204,6 @@ typedef enum
#define GST_VIDEO_COMP_INDEX 0
#define GST_VIDEO_COMP_PALETTE 1
/* tile info component, we don't support planar alpha and tiled */
#define GST_VIDEO_COMP_TILEINFO 3
#include <gst/video/video-chroma.h>
/**
......@@ -322,6 +320,9 @@ typedef void (*GstVideoFormatPack) (const GstVideoFormatInfo *info,
* @unpack_func: an unpack function for this format
* @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
*
* Information for a video format.
*/
......@@ -346,6 +347,10 @@ struct _GstVideoFormatInfo {
gint pack_lines;
GstVideoFormatPack pack_func;
GstVideoTileMode tile_mode;
guint tile_ws;
guint tile_hs;
gpointer _gst_reserved[GST_PADDING];
};
......@@ -422,6 +427,10 @@ struct _GstVideoFormatInfo {
#define GST_VIDEO_FORMAT_INFO_OFFSET(info,offsets,comp) \
(((offsets)[(info)->plane[comp]]) + (info)->poffset[comp])
#define GST_VIDEO_FORMAT_INFO_TILE_MODE(info) ((info)->tile_mode)
#define GST_VIDEO_FORMAT_INFO_TILE_WS(info) ((info)->tile_ws)
#define GST_VIDEO_FORMAT_INFO_TILE_HS(info) ((info)->tile_hs)
/* format properties */
GstVideoFormat gst_video_format_from_masks (gint depth, gint bpp, gint endianness,
guint red_mask, guint green_mask,
......
......@@ -221,6 +221,7 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
const GstVideoFormatInfo *finfo;
guint8 *sp, *dp;
guint w, h;
gint ss, ds;
g_return_val_if_fail (dest != NULL, FALSE);
g_return_val_if_fail (src != NULL, FALSE);
......@@ -251,35 +252,28 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
plane) * GST_VIDEO_FRAME_COMP_PSTRIDE (dest, plane);
h = GST_VIDEO_FRAME_COMP_HEIGHT (dest, plane);
ss = GST_VIDEO_INFO_PLANE_STRIDE (sinfo, plane);
ds = GST_VIDEO_INFO_PLANE_STRIDE (dinfo, plane);
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;
GstVideoTileMode mode;
gint tidx;
/* plane index of tile info */
tidx = finfo->n_planes - 1;
/* ignore tile info plane */
if (plane == tidx)
return TRUE;
ws = finfo->w_sub[GST_VIDEO_COMP_TILEINFO];
hs = finfo->h_sub[GST_VIDEO_COMP_TILEINFO];
ws = GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
ts = ws + hs;
tile_size = 1 << ts;
mode = finfo->pixel_stride[GST_VIDEO_COMP_TILEINFO];
mode = GST_VIDEO_FORMAT_INFO_TILE_MODE (finfo);
sx_tiles = sinfo->stride[plane] >> ws;
sy_tiles = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, plane,
sinfo->stride[tidx]);
sx_tiles = GST_VIDEO_TILE_X_TILES (ss);
sy_tiles = GST_VIDEO_TILE_Y_TILES (ss);
dx_tiles = dinfo->stride[plane] >> ws;
dy_tiles = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, plane,
dinfo->stride[tidx]);
dx_tiles = GST_VIDEO_TILE_X_TILES (ds);
dy_tiles = GST_VIDEO_TILE_Y_TILES (ds);
/* this is the amount of tiles to copy */
w = ((w - 1) >> ws) + 1;
......@@ -298,12 +292,8 @@ gst_video_frame_copy_plane (GstVideoFrame * dest, const GstVideoFrame * src,
}
}
} else {
gint ss, ds;
guint j;
ss = sinfo->stride[plane];
ds = dinfo->stride[plane];
GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy plane %d, w:%d h:%d ", plane, w,
h);
......
......@@ -27,6 +27,7 @@
#include <stdio.h>
#include "video-info.h"
#include "video-tile.h"
static int fill_planes (GstVideoInfo * info);
......@@ -574,12 +575,14 @@ fill_planes (GstVideoInfo * info)
info->size = info->stride[0] * height * 3;
break;
case GST_VIDEO_FORMAT_NV12_64Z32:
info->stride[0] = GST_ROUND_UP_128 (width);
info->stride[1] = info->stride[0];
info->stride[2] = GST_ROUND_UP_32 (height) / 32;
info->stride[0] =
GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64,
GST_ROUND_UP_32 (height) / 32);
info->stride[1] =
GST_VIDEO_TILE_MAKE_STRIDE (GST_ROUND_UP_128 (width) / 64,
GST_ROUND_UP_64 (height) / 64);
info->offset[0] = 0;
info->offset[1] = info->stride[0] * GST_ROUND_UP_32 (height);
info->offset[2] = 0;
info->size =
info->offset[1] + info->stride[0] * GST_ROUND_UP_64 (height) / 2;
break;
......
......@@ -22,8 +22,6 @@
#include <gst/gst.h>
#include <gst/video/video-format.h>
G_BEGIN_DECLS
/**
......@@ -68,6 +66,36 @@ typedef enum
*/
#define GST_VIDEO_TILE_MODE_IS_INDEXED(mode) (GST_VIDEO_TILE_MODE_TYPE(mode) == GST_VIDEO_TILE_TYPE_INDEXED)
#define GST_VIDEO_TILE_Y_TILES_SHIFT (16)
#define GST_VIDEO_TILE_X_TILES_MASK ((1 << GST_VIDEO_TILE_Y_TILES_SHIFT) - 1)
/**
* GST_VIDEO_TILE_MAKE_STRIDE:
* @x_tiles: number of tiles in X
* @y_tiles: number of tiles in Y
*
* Encode the number of tile in X and Y into the stride.
*/
#define GST_VIDEO_TILE_MAKE_STRIDE(x_tiles, y_tiles) \
(((y_tiles) << GST_VIDEO_TILE_Y_TILES_SHIFT) | (x_tiles))
/**
* GST_VIDEO_TILE_X_TILES:
* @stride: plane stride
*
* Extract the number of tiles in X from the stride value.
*/
#define GST_VIDEO_TILE_X_TILES(stride) ((stride) & GST_VIDEO_TILE_X_TILES_MASK)
/**
* GST_VIDEO_TILE_Y_TILES:
* @stride: plane stride
*
* Extract the number of tiles in Y from the stride value.
*/
#define GST_VIDEO_TILE_Y_TILES(stride) ((stride) >> GST_VIDEO_TILE_Y_TILES_SHIFT)
/**
* GstVideoTileMode:
* @GST_VIDEO_TILE_MODE_UNKNOWN: Unknown or unset tile mode
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment