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
This commit is contained in:
Wim Taymans 2013-12-25 14:11:57 +01:00 committed by Nicolas Dufresne
parent f8d3b9b4fc
commit 3ceb7dfe22
4 changed files with 197 additions and 92 deletions

View file

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

View file

@ -27,6 +27,7 @@
#include <stdio.h>
#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,

View file

@ -0,0 +1,102 @@
/* GStreamer
* Copyright (C) <2013> Wim Taymans <wim.taymans@gmail.com>
*
* 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/video-tile.h>
/**
* 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;
}

View file

@ -0,0 +1,92 @@
/* GStreamer
* Copyright (C) <2013> Wim Taymans <wim.taymans@gmail.com>
*
* 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 <gst/gst.h>
#include <gst/video/video-format.h>
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__ */