From 3ceb7dfe22c0f4247fd4e4949223cfa1e3ace33c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 25 Dec 2013 14:11:57 +0100 Subject: [PATCH] video-tile: add tile mode and helper functions Move the tile helper functions to their own file. Make it possible to make other tiling modes later. https://bugzilla.gnome.org/show_bug.cgi?id=707361 --- gst-libs/gst/video/Makefile.am | 2 + gst-libs/gst/video/video-format.c | 93 +-------------------------- gst-libs/gst/video/video-tile.c | 102 ++++++++++++++++++++++++++++++ gst-libs/gst/video/video-tile.h | 92 +++++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 92 deletions(-) create mode 100644 gst-libs/gst/video/video-tile.c create mode 100644 gst-libs/gst/video/video-tile.h diff --git a/gst-libs/gst/video/Makefile.am b/gst-libs/gst/video/Makefile.am index 292415e490..7ba12e4665 100644 --- a/gst-libs/gst/video/Makefile.am +++ b/gst-libs/gst/video/Makefile.am @@ -27,6 +27,7 @@ libgstvideo_@GST_API_VERSION@_la_SOURCES = \ video-color.c \ video-info.c \ video-frame.c \ + video-tile.c \ gstvideosink.c \ gstvideofilter.c \ convertframe.c \ @@ -54,6 +55,7 @@ libgstvideo_@GST_API_VERSION@include_HEADERS = \ video-color.h \ video-info.h \ video-frame.h \ + video-tile.h \ gstvideosink.h \ gstvideofilter.h \ gstvideometa.h \ diff --git a/gst-libs/gst/video/video-format.c b/gst-libs/gst/video/video-format.c index 85977a2924..126218722c 100644 --- a/gst-libs/gst/video/video-format.c +++ b/gst-libs/gst/video/video-format.c @@ -27,6 +27,7 @@ #include #include "video-format.h" +#include "video-tile.h" /** * SECTION:gstvideo @@ -2082,98 +2083,6 @@ pack_I422_10BE (const GstVideoFormatInfo * info, GstVideoPackFlags flags, } } -/** - * GstVideoTileMode: - * @GST_VIDEO_TILE_MODE_UNKNOWN: Unknown or unset video format id - * @GST_VIDEO_TILE_MODE_ZFLIPZ_2X2: Every four adjacent buffers - two - * horizontally and two vertically are grouped together and are located - * in memory in Z or flipped Z order. - * - * Enum value describing the most common video formats. - */ -typedef enum -{ - GST_VIDEO_TILE_MODE_NONE, - GST_VIDEO_TILE_MODE_ZFLIPZ_2X2, -} GstVideoTileMode; - -/** - * gst_video_tile_get_index: - * @mode: a #GstVideoTileMode - * @x: x coordinate - * @y: y coordinate - * @x_tiles: number of horizintal tiles - * @y_tiles: number of vertical tiles - * - * Get the tile index of the tile at coordinates @x and @y. - * - * Returns: the index of the tile at @x and @y in the tiled image of - * @x_tiles by @y_tiles. - */ -static gsize -gst_video_tile_get_index (GstVideoTileMode mode, gint x, gint y, - gint x_tiles, gint y_tiles) -{ - gsize offset; - - switch (mode) { - case GST_VIDEO_TILE_MODE_ZFLIPZ_2X2: - /* Due to the zigzag pattern we know that tiles are numbered like: - * (see http://linuxtv.org/downloads/v4l-dvb-apis/re31.html) - * - * | Column (x) - * | 0 1 2 3 4 5 6 7 - * -------|--------------------------------------- - * 0 | 0 1 6 7 8 9 14 15 - * R 1 | 2 3 4 5 10 11 12 13 - * o 2 | 16 17 22 23 24 25 30 31 - * w 3 | 18 19 20 21 26 27 28 29 - * 4 | 32 33 38 39 40 41 46 47 - * (y) 5 | 34 35 36 37 42 43 44 45 - * 6 | 48 49 50 51 52 53 54 55 - * - * From this we can see that: - * - * For even rows: - * - The first block in a row is always mapped to memory block 'y * width'. - * - For all even rows, except for the last one when 'y' is odd, from the first - * block number an offset is then added to obtain the block number for - * the other blocks in the row. The offset is 'x' plus the corresponding - * number in the series [0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...], which can be - * expressed as 'GST_ROUND_DOWN_4 (x + 2)'. - * f(x,y,width,height) = y * width + x + GST_ROUND_DOWN_4 (x + 2) - * - * - For the last row when 'y' is odd the offset is simply 'x'. - * f(x,y,width,height) = y * width + x - * - Note that 'y' is even, so 'GST_ROUNDOWN_2 (y) == y' in this case - * - * For odd rows: - * - The first block in the row is always mapped to memory block - * 'GST_ROUND_DOWN_2(y) * width + 2'. - * - From the first block number an offset is then added to obtain the block - * number for the other blocks in the row. The offset is 'x' plus the - * corresponding number in the series [0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...], - * which can be expressed as GST_ROUND_DOWN_4 (x). - * f(x,y,width,height) = GST_ROUND_DOWN_2 (y) * width + bx 2 + GST_ROUND_DOWN_4 (x) - */ - /* Common to all cases */ - offset = GST_ROUND_DOWN_2 (y) * x_tiles + x; - - if (y & 1) { - /* For odd row */ - offset += 2 + GST_ROUND_DOWN_4 (x); - } else if ((y_tiles & 1) == 0 || y != (y_tiles - 1)) { - /* For even row except for the last row when odd height */ - offset += GST_ROUND_DOWN_4 (x + 2); - } - break; - default: - offset = 0; - break; - } - return offset; -} - static void get_tile_NV12 (gint tile_width, gint tile_height, gint tile_size, gint tx, gint ty, gint x_tiles, gint y_tiles, diff --git a/gst-libs/gst/video/video-tile.c b/gst-libs/gst/video/video-tile.c new file mode 100644 index 0000000000..10954a5e19 --- /dev/null +++ b/gst-libs/gst/video/video-tile.c @@ -0,0 +1,102 @@ +/* GStreamer + * Copyright (C) <2013> Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include + +/** + * gst_video_tile_get_index: + * @mode: a #GstVideoTileMode + * @x: x coordinate + * @y: y coordinate + * @x_tiles: number of horizintal tiles + * @y_tiles: number of vertical tiles + * + * Get the tile index of the tile at coordinates @x and @y in the tiled + * image of @x_tiles by @y_tiles. + * + * Use this method when @mode is of type #GST_VIDEO_TILE_MODE_INDEXED. + * + * Returns: the index of the tile at @x and @y in the tiled image of + * @x_tiles by @y_tiles. + */ +guint +gst_video_tile_get_index (GstVideoTileMode mode, gint x, gint y, + gint x_tiles, gint y_tiles) +{ + gsize offset; + + g_return_val_if_fail (GST_VIDEO_TILE_MODE_IS_INDEXED (mode), 0); + + switch (mode) { + case GST_VIDEO_TILE_MODE_ZFLIPZ_2X2: + /* Due to the zigzag pattern we know that tiles are numbered like: + * (see http://linuxtv.org/downloads/v4l-dvb-apis/re31.html) + * + * | Column (x) + * | 0 1 2 3 4 5 6 7 + * -------|--------------------------------------- + * 0 | 0 1 6 7 8 9 14 15 + * R 1 | 2 3 4 5 10 11 12 13 + * o 2 | 16 17 22 23 24 25 30 31 + * w 3 | 18 19 20 21 26 27 28 29 + * 4 | 32 33 38 39 40 41 46 47 + * (y) 5 | 34 35 36 37 42 43 44 45 + * 6 | 48 49 50 51 52 53 54 55 + * + * From this we can see that: + * + * For even rows: + * - The first block in a row is always mapped to memory block 'y * width'. + * - For all even rows, except for the last one when 'y' is odd, from the first + * block number an offset is then added to obtain the block number for + * the other blocks in the row. The offset is 'x' plus the corresponding + * number in the series [0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...], which can be + * expressed as 'GST_ROUND_DOWN_4 (x + 2)'. + * f(x,y,width,height) = y * width + x + GST_ROUND_DOWN_4 (x + 2) + * + * - For the last row when 'y' is odd the offset is simply 'x'. + * f(x,y,width,height) = y * width + x + * - Note that 'y' is even, so 'GST_ROUNDOWN_2 (y) == y' in this case + * + * For odd rows: + * - The first block in the row is always mapped to memory block + * 'GST_ROUND_DOWN_2(y) * width + 2'. + * - From the first block number an offset is then added to obtain the block + * number for the other blocks in the row. The offset is 'x' plus the + * corresponding number in the series [0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...], + * which can be expressed as GST_ROUND_DOWN_4 (x). + * f(x,y,width,height) = GST_ROUND_DOWN_2 (y) * width + bx 2 + GST_ROUND_DOWN_4 (x) + */ + /* Common to all cases */ + offset = GST_ROUND_DOWN_2 (y) * x_tiles + x; + + if (y & 1) { + /* For odd row */ + offset += 2 + GST_ROUND_DOWN_4 (x); + } else if ((y_tiles & 1) == 0 || y != (y_tiles - 1)) { + /* For even row except for the last row when odd height */ + offset += GST_ROUND_DOWN_4 (x + 2); + } + break; + default: + offset = 0; + break; + } + return offset; +} diff --git a/gst-libs/gst/video/video-tile.h b/gst-libs/gst/video/video-tile.h new file mode 100644 index 0000000000..e52183b504 --- /dev/null +++ b/gst-libs/gst/video/video-tile.h @@ -0,0 +1,92 @@ +/* GStreamer + * Copyright (C) <2013> Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __GST_VIDEO_TILE_H__ +#define __GST_VIDEO_TILE_H__ + +#include + +#include + +G_BEGIN_DECLS + +/** + * GstVideoTileType: + * @GST_VIDEO_TILE_TYPE_INDEXED: Tiles are indexed. Use + * gst_video_tile_get_index () to retrieve the tile at the requested + * coordinates. + * + * Enum value describing the most common tiling types. + */ +typedef enum +{ + GST_VIDEO_TILE_TYPE_INDEXED = 0 +} GstVideoTileType; + +#define GST_VIDEO_TILE_TYPE_SHIFT (16) +#define GST_VIDEO_TILE_TYPE_MASK ((1 << GST_VIDEO_TILE_TYPE_SHIFT) - 1) + +/** + * GST_VIDEO_TILE_MAKE_MODE: + * @num: the mode number to create + * @type: the tile mode type + * + * use this macro to create new tile modes. + */ +#define GST_VIDEO_TILE_MAKE_MODE(num, type) \ + (((num) << GST_VIDEO_TILE_TYPE_SHIFT) | (GST_VIDEO_TILE_TYPE_ ##type)) + +/** + * GST_VIDEO_TILE_MODE_TYPE: + * @mode: the tile mode + * + * Get the tile mode type of @mode + */ +#define GST_VIDEO_TILE_MODE_TYPE(mode) ((mode) & GST_VIDEO_TILE_TYPE_MASK) + +/** + * GST_VIDEO_TILE_MODE_IS_INDEXED: + * @mode: a tile mode + * + * Check if @mode is an indexed tile type + */ +#define GST_VIDEO_TILE_MODE_IS_INDEXED(mode) (GST_VIDEO_TILE_MODE_TYPE(mode) == GST_VIDEO_TILE_TYPE_INDEXED) + +/** + * GstVideoTileMode: + * @GST_VIDEO_TILE_MODE_UNKNOWN: Unknown or unset tile mode + * @GST_VIDEO_TILE_MODE_ZFLIPZ_2X2: Every four adjacent buffers - two + * horizontally and two vertically are grouped together and are located + * in memory in Z or flipped Z order. + * + * Enum value describing the available tiling modes. + */ +typedef enum +{ + GST_VIDEO_TILE_MODE_UNKNOWN = 0, + GST_VIDEO_TILE_MODE_ZFLIPZ_2X2 = GST_VIDEO_TILE_MAKE_MODE (1, INDEXED), +} GstVideoTileMode; + +guint gst_video_tile_get_index (GstVideoTileMode mode, gint x, gint y, + gint x_tiles, gint y_tiles); + + +G_END_DECLS + +#endif /* __GST_VIDEO_TILE_H__ */