Blame gst-libs/gst/video/video-tile.c

Packit 971217
/* GStreamer
Packit 971217
 * Copyright (C) <2013> Wim Taymans <wim.taymans@gmail.com>
Packit 971217
 *
Packit 971217
 * This library is free software; you can redistribute it and/or
Packit 971217
 * modify it under the terms of the GNU Library General Public
Packit 971217
 * License as published by the Free Software Foundation; either
Packit 971217
 * version 2 of the License, or (at your option) any later version.
Packit 971217
 *
Packit 971217
 * This library is distributed in the hope that it will be useful,
Packit 971217
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 971217
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 971217
 * Library General Public License for more details.
Packit 971217
 *
Packit 971217
 * You should have received a copy of the GNU Library General Public
Packit 971217
 * License along with this library; if not, write to the
Packit 971217
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 971217
 * Boston, MA 02110-1301, USA.
Packit 971217
 */
Packit 971217
Packit 971217
#include <gst/video/video-tile.h>
Packit 971217
Packit 971217
/**
Packit 971217
 * gst_video_tile_get_index:
Packit 971217
 * @mode: a #GstVideoTileMode
Packit 971217
 * @x: x coordinate
Packit 971217
 * @y: y coordinate
Packit 971217
 * @x_tiles: number of horizintal tiles
Packit 971217
 * @y_tiles: number of vertical tiles
Packit 971217
 *
Packit 971217
 * Get the tile index of the tile at coordinates @x and @y in the tiled
Packit 971217
 * image of @x_tiles by @y_tiles.
Packit 971217
 *
Packit 971217
 * Use this method when @mode is of type %GST_VIDEO_TILE_MODE_INDEXED.
Packit 971217
 *
Packit 971217
 * Returns: the index of the tile at @x and @y in the tiled image of
Packit 971217
 *   @x_tiles by @y_tiles.
Packit 971217
 *
Packit 971217
 * Since: 1.4
Packit 971217
 */
Packit 971217
guint
Packit 971217
gst_video_tile_get_index (GstVideoTileMode mode, gint x, gint y,
Packit 971217
    gint x_tiles, gint y_tiles)
Packit 971217
{
Packit 971217
  gsize offset;
Packit 971217
Packit 971217
  g_return_val_if_fail (GST_VIDEO_TILE_MODE_IS_INDEXED (mode), 0);
Packit 971217
Packit 971217
  switch (mode) {
Packit 971217
    case GST_VIDEO_TILE_MODE_ZFLIPZ_2X2:
Packit 971217
      /* Due to the zigzag pattern we know that tiles are numbered like:
Packit 971217
       * (see http://linuxtv.org/downloads/v4l-dvb-apis/re31.html)
Packit 971217
       *
Packit 971217
       *         |             Column (x)
Packit 971217
       *         |   0    1    2    3    4    5    6    7
Packit 971217
       *  -------|---------------------------------------
Packit 971217
       *       0 |   0    1    6    7    8    9   14   15
Packit 971217
       *    R  1 |   2    3    4    5   10   11   12   13
Packit 971217
       *    o  2 |  16   17   22   23   24   25   30   31
Packit 971217
       *    w  3 |  18   19   20   21   26   27   28   29
Packit 971217
       *       4 |  32   33   38   39   40   41   46   47
Packit 971217
       *   (y) 5 |  34   35   36   37   42   43   44   45
Packit 971217
       *       6 |  48   49   50   51   52   53   54   55
Packit 971217
       *
Packit 971217
       * From this we can see that:
Packit 971217
       *
Packit 971217
       * For even rows:
Packit 971217
       * - The first block in a row is always mapped to memory block 'y * width'.
Packit 971217
       * - For all even rows, except for the last one when 'y' is odd, from the first
Packit 971217
       *   block number an offset is then added to obtain the block number for
Packit 971217
       *   the other blocks in the row. The offset is 'x' plus the corresponding
Packit 971217
       *   number in the series [0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...], which can be
Packit 971217
       *   expressed as 'GST_ROUND_DOWN_4 (x + 2)'.
Packit 971217
       *       f(x,y,width,height) = y * width + x + GST_ROUND_DOWN_4 (x + 2)
Packit 971217
       *
Packit 971217
       * - For the last row when 'y' is odd the offset is simply 'x'.
Packit 971217
       *       f(x,y,width,height) = y * width + x
Packit 971217
       * - Note that 'y' is even, so 'GST_ROUNDOWN_2 (y) == y' in this case
Packit 971217
       *
Packit 971217
       *  For odd rows:
Packit 971217
       * - The first block in the row is always mapped to memory block
Packit 971217
       *   'GST_ROUND_DOWN_2(y) * width + 2'.
Packit 971217
       * - From the first block number an offset is then added to obtain the block
Packit 971217
       *   number for the other blocks in the row. The offset is 'x' plus the
Packit 971217
       *   corresponding number in the series [0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...],
Packit 971217
       *   which can be  expressed as GST_ROUND_DOWN_4 (x).
Packit 971217
       *       f(x,y,width,height) = GST_ROUND_DOWN_2 (y) * width + bx 2 + GST_ROUND_DOWN_4 (x)
Packit 971217
       */
Packit 971217
      /* Common to all cases */
Packit 971217
      offset = GST_ROUND_DOWN_2 (y) * x_tiles + x;
Packit 971217
Packit 971217
      if (y & 1) {
Packit 971217
        /* For odd row */
Packit 971217
        offset += 2 + GST_ROUND_DOWN_4 (x);
Packit 971217
      } else if ((y_tiles & 1) == 0 || y != (y_tiles - 1)) {
Packit 971217
        /* For even row except for the last row when odd height */
Packit 971217
        offset += GST_ROUND_DOWN_4 (x + 2);
Packit 971217
      }
Packit 971217
      break;
Packit 971217
    default:
Packit 971217
      offset = 0;
Packit 971217
      break;
Packit 971217
  }
Packit 971217
  return offset;
Packit 971217
}