/* 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. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #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_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; default: offset = 0; break; } return offset; }