mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
7d1028424c
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>
110 lines
4.2 KiB
C
110 lines
4.2 KiB
C
/* 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.
|
|
*/
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#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_TYPE_INDEXED.
|
|
*
|
|
* Returns: the index of the tile at @x and @y in the tiled image of
|
|
* @x_tiles by @y_tiles.
|
|
*
|
|
* Since: 1.4
|
|
*/
|
|
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;
|
|
case GST_VIDEO_TILE_MODE_LINEAR:
|
|
offset = y * x_tiles + x;
|
|
break;
|
|
default:
|
|
offset = 0;
|
|
break;
|
|
}
|
|
return offset;
|
|
}
|