• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) <2013> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include <gst/video/video-tile.h>
24 
25 /**
26  * gst_video_tile_get_index:
27  * @mode: a #GstVideoTileMode
28  * @x: x coordinate
29  * @y: y coordinate
30  * @x_tiles: number of horizintal tiles
31  * @y_tiles: number of vertical tiles
32  *
33  * Get the tile index of the tile at coordinates @x and @y in the tiled
34  * image of @x_tiles by @y_tiles.
35  *
36  * Use this method when @mode is of type %GST_VIDEO_TILE_TYPE_INDEXED.
37  *
38  * Returns: the index of the tile at @x and @y in the tiled image of
39  *   @x_tiles by @y_tiles.
40  *
41  * Since: 1.4
42  */
43 guint
gst_video_tile_get_index(GstVideoTileMode mode,gint x,gint y,gint x_tiles,gint y_tiles)44 gst_video_tile_get_index (GstVideoTileMode mode, gint x, gint y,
45     gint x_tiles, gint y_tiles)
46 {
47   gsize offset;
48 
49   g_return_val_if_fail (GST_VIDEO_TILE_MODE_IS_INDEXED (mode), 0);
50 
51   switch (mode) {
52     case GST_VIDEO_TILE_MODE_ZFLIPZ_2X2:
53       /* Due to the zigzag pattern we know that tiles are numbered like:
54        * (see http://linuxtv.org/downloads/v4l-dvb-apis/re31.html)
55        *
56        *         |             Column (x)
57        *         |   0    1    2    3    4    5    6    7
58        *  -------|---------------------------------------
59        *       0 |   0    1    6    7    8    9   14   15
60        *    R  1 |   2    3    4    5   10   11   12   13
61        *    o  2 |  16   17   22   23   24   25   30   31
62        *    w  3 |  18   19   20   21   26   27   28   29
63        *       4 |  32   33   38   39   40   41   46   47
64        *   (y) 5 |  34   35   36   37   42   43   44   45
65        *       6 |  48   49   50   51   52   53   54   55
66        *
67        * From this we can see that:
68        *
69        * For even rows:
70        * - The first block in a row is always mapped to memory block 'y * width'.
71        * - For all even rows, except for the last one when 'y' is odd, from the first
72        *   block number an offset is then added to obtain the block number for
73        *   the other blocks in the row. The offset is 'x' plus the corresponding
74        *   number in the series [0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...], which can be
75        *   expressed as 'GST_ROUND_DOWN_4 (x + 2)'.
76        *       f(x,y,width,height) = y * width + x + GST_ROUND_DOWN_4 (x + 2)
77        *
78        * - For the last row when 'y' is odd the offset is simply 'x'.
79        *       f(x,y,width,height) = y * width + x
80        * - Note that 'y' is even, so 'GST_ROUNDOWN_2 (y) == y' in this case
81        *
82        *  For odd rows:
83        * - The first block in the row is always mapped to memory block
84        *   'GST_ROUND_DOWN_2(y) * width + 2'.
85        * - From the first block number an offset is then added to obtain the block
86        *   number for the other blocks in the row. The offset is 'x' plus the
87        *   corresponding number in the series [0, 0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, ...],
88        *   which can be  expressed as GST_ROUND_DOWN_4 (x).
89        *       f(x,y,width,height) = GST_ROUND_DOWN_2 (y) * width + bx 2 + GST_ROUND_DOWN_4 (x)
90        */
91       /* Common to all cases */
92       offset = GST_ROUND_DOWN_2 (y) * x_tiles + x;
93 
94       if (y & 1) {
95         /* For odd row */
96         offset += 2 + GST_ROUND_DOWN_4 (x);
97       } else if ((y_tiles & 1) == 0 || y != (y_tiles - 1)) {
98         /* For even row except for the last row when odd height */
99         offset += GST_ROUND_DOWN_4 (x + 2);
100       }
101       break;
102     case GST_VIDEO_TILE_MODE_LINEAR:
103       offset = y * x_tiles + x;
104       break;
105     default:
106       offset = 0;
107       break;
108   }
109   return offset;
110 }
111