1 /*
2  * Copyright (c) 2016 Vittorio Giovara <vittorio.giovara@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * Spherical video
24  */
25 
26 module ffmpeg.libavutil.spherical;
27 
28 extern (C):
29 import ffmpeg; @nogc nothrow:
30 
31 /**
32  * @addtogroup lavu_video
33  * @{
34  *
35  * @defgroup lavu_video_spherical Spherical video mapping
36  * @{
37  */
38 
39 /**
40  * @addtogroup lavu_video_spherical
41  * A spherical video file contains surfaces that need to be mapped onto a
42  * sphere. Depending on how the frame was converted, a different distortion
43  * transformation or surface recomposition function needs to be applied before
44  * the video should be mapped and displayed.
45  */
46 
47 /**
48  * Projection of the video surface(s) on a sphere.
49  */
50 enum AVSphericalProjection
51 {
52     /**
53      * Video represents a sphere mapped on a flat surface using
54      * equirectangular projection.
55      */
56     AV_SPHERICAL_EQUIRECTANGULAR = 0,
57 
58     /**
59      * Video frame is split into 6 faces of a cube, and arranged on a
60      * 3x2 layout. Faces are oriented upwards for the front, left, right,
61      * and back faces. The up face is oriented so the top of the face is
62      * forwards and the down face is oriented so the top of the face is
63      * to the back.
64      */
65     AV_SPHERICAL_CUBEMAP = 1,
66 
67     /**
68      * Video represents a portion of a sphere mapped on a flat surface
69      * using equirectangular projection. The @ref bounding fields indicate
70      * the position of the current video in a larger surface.
71      */
72     AV_SPHERICAL_EQUIRECTANGULAR_TILE = 2
73 }
74 
75 /**
76  * This structure describes how to handle spherical videos, outlining
77  * information about projection, initial layout, and any other view modifier.
78  *
79  * @note The struct must be allocated with av_spherical_alloc() and
80  *       its size is not a part of the public ABI.
81  */
82 struct AVSphericalMapping
83 {
84     /**
85      * Projection type.
86      */
87     AVSphericalProjection projection;
88 
89     /**
90      * @name Initial orientation
91      * @{
92      * There fields describe additional rotations applied to the sphere after
93      * the video frame is mapped onto it. The sphere is rotated around the
94      * viewer, who remains stationary. The order of transformation is always
95      * yaw, followed by pitch, and finally by roll.
96      *
97      * The coordinate system matches the one defined in OpenGL, where the
98      * forward vector (z) is coming out of screen, and it is equivalent to
99      * a rotation matrix of R = r_y(yaw) * r_x(pitch) * r_z(roll).
100      *
101      * A positive yaw rotates the portion of the sphere in front of the viewer
102      * toward their right. A positive pitch rotates the portion of the sphere
103      * in front of the viewer upwards. A positive roll tilts the portion of
104      * the sphere in front of the viewer to the viewer's right.
105      *
106      * These values are exported as 16.16 fixed point.
107      *
108      * See this equirectangular projection as example:
109      *
110      * @code{.unparsed}
111      *                   Yaw
112      *     -180           0           180
113      *   90 +-------------+-------------+  180
114      *      |             |             |                  up
115      * P    |             |             |                 y|    forward
116      * i    |             ^             |                  |   /z
117      * t  0 +-------------X-------------+    0 Roll        |  /
118      * c    |             |             |                  | /
119      * h    |             |             |                 0|/_____right
120      *      |             |             |                        x
121      *  -90 +-------------+-------------+ -180
122      *
123      * X - the default camera center
124      * ^ - the default up vector
125      * @endcode
126      */
127     int yaw; ///< Rotation around the up vector [-180, 180].
128     int pitch; ///< Rotation around the right vector [-90, 90].
129     int roll; ///< Rotation around the forward vector [-180, 180].
130     /**
131      * @}
132      */
133 
134     /**
135      * @name Bounding rectangle
136      * @anchor bounding
137      * @{
138      * These fields indicate the location of the current tile, and where
139      * it should be mapped relative to the original surface. They are
140      * exported as 0.32 fixed point, and can be converted to classic
141      * pixel values with av_spherical_bounds().
142      *
143      * @code{.unparsed}
144      *      +----------------+----------+
145      *      |                |bound_top |
146      *      |            +--------+     |
147      *      | bound_left |tile    |     |
148      *      +<---------->|        |<--->+bound_right
149      *      |            +--------+     |
150      *      |                |          |
151      *      |    bound_bottom|          |
152      *      +----------------+----------+
153      * @endcode
154      *
155      * If needed, the original video surface dimensions can be derived
156      * by adding the current stream or frame size to the related bounds,
157      * like in the following example:
158      *
159      * @code{c}
160      *     original_width  = tile->width  + bound_left + bound_right;
161      *     original_height = tile->height + bound_top  + bound_bottom;
162      * @endcode
163      *
164      * @note These values are valid only for the tiled equirectangular
165      *       projection type (@ref AV_SPHERICAL_EQUIRECTANGULAR_TILE),
166      *       and should be ignored in all other cases.
167      */
168     uint bound_left; ///< Distance from the left edge
169     uint bound_top; ///< Distance from the top edge
170     uint bound_right; ///< Distance from the right edge
171     uint bound_bottom; ///< Distance from the bottom edge
172     /**
173      * @}
174      */
175 
176     /**
177      * Number of pixels to pad from the edge of each cube face.
178      *
179      * @note This value is valid for only for the cubemap projection type
180      *       (@ref AV_SPHERICAL_CUBEMAP), and should be ignored in all other
181      *       cases.
182      */
183     uint padding;
184 }
185 
186 /**
187  * Allocate a AVSphericalVideo structure and initialize its fields to default
188  * values.
189  *
190  * @return the newly allocated struct or NULL on failure
191  */
192 AVSphericalMapping* av_spherical_alloc (size_t* size);
193 
194 /**
195  * Convert the @ref bounding fields from an AVSphericalVideo
196  * from 0.32 fixed point to pixels.
197  *
198  * @param map    The AVSphericalVideo map to read bound values from.
199  * @param width  Width of the current frame or stream.
200  * @param height Height of the current frame or stream.
201  * @param left   Pixels from the left edge.
202  * @param top    Pixels from the top edge.
203  * @param right  Pixels from the right edge.
204  * @param bottom Pixels from the bottom edge.
205  */
206 void av_spherical_tile_bounds (
207     const(AVSphericalMapping)* map,
208     size_t width,
209     size_t height,
210     size_t* left,
211     size_t* top,
212     size_t* right,
213     size_t* bottom);
214 
215 /**
216  * Provide a human-readable name of a given AVSphericalProjection.
217  *
218  * @param projection The input AVSphericalProjection.
219  *
220  * @return The name of the AVSphericalProjection, or "unknown".
221  */
222 const(char)* av_spherical_projection_name (AVSphericalProjection projection);
223 
224 /**
225  * Get the AVSphericalProjection form a human-readable name.
226  *
227  * @param name The input string.
228  *
229  * @return The AVSphericalProjection value, or -1 if not found.
230  */
231 int av_spherical_from_name (const(char)* name);
232 /**
233  * @}
234  * @}
235  */
236 
237 /* AVUTIL_SPHERICAL_H */