diff mbox

[FFmpeg-devel,1/3] lavu: Add AVSphericalMapping type and frame side data

Message ID 20161111224902.83581-1-vittorio.giovara@gmail.com
State Superseded
Headers show

Commit Message

Vittorio Giovara Nov. 11, 2016, 10:49 p.m. UTC
While no decoder currently exports spherical information, this type
represents a frame property that has to be passed through from container
to frames.

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
---
Missing version bump (do so when pushing).
Please CC.
Vittorio

 libavutil/Makefile    |   2 +
 libavutil/avutil.h    |   6 +++
 libavutil/frame.h     |   8 ++-
 libavutil/spherical.c |  34 ++++++++++++
 libavutil/spherical.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 193 insertions(+), 1 deletion(-)
 create mode 100644 libavutil/spherical.c
 create mode 100644 libavutil/spherical.h

Comments

Michael Niedermayer Nov. 12, 2016, 1:39 a.m. UTC | #1
On Fri, Nov 11, 2016 at 05:49:00PM -0500, Vittorio Giovara wrote:
[...]
> +/**
> + * This structure describes how to handle spherical videos, outlining
> + * information about projection, initial layout, and any other view modifier.
> + *
> + * @note The struct must be allocated with av_spherical_alloc() and
> + *       its size is not a part of the public ABI.
> + */
> +typedef struct AVSphericalMapping {
> +    /**
> +     * Projection type.
> +     */
> +    enum AVSphericalProjection projection;
> +
> +    /**
> +     * @name Initial orientation
> +     * @{
> +     * These fields represent the pose values that measure the rotation
> +     * transformation (in degrees) to be applied to the projection.
> +     * See this equirectangular projection as example:
> +     *
> +     * @code{.unparsed}
> +     *                   Yaw
> +     *     -180           0           180
> +     *   90 +-------------+-------------+  180
> +     *      |             |             |
> +     * P    |             |      o>     |
> +     * i    |             ^             |
> +     * t  0 +-------------X-------------+    0 Roll
> +     * c    |             |             |
> +     * h    |             |             |
> +     *      |             |             |
> +     *  -90 +-------------+-------------+ -180
> +     *
> +     * X - the default camera center
> +     * ^ - the default up vector
> +     * > - the up vector for a rotation of 90 degrees
> +     * o - the image center for yaw = 90, pitch = 45, roll = 0
> +     * @endcode
> +     *
> +     * The order of transformation is always yaw, followed by pitch, and
> +     * finally by roll.
> +     */

> +    double yaw;   ///< Clockwise rotation around the up vector [-180, 180].
> +    double pitch; ///< Counter-clockwise rotation around the right vector [-90, 90].
> +    double roll;  ///< Counter-clockwise rotation around the forward vector [-180, 180].

please use intXY (64 or 32 as preferred) so there are no platform
rounding dependancies


[...]
James Almer Nov. 12, 2016, 2:41 p.m. UTC | #2
On 11/11/2016 10:39 PM, Michael Niedermayer wrote:
> On Fri, Nov 11, 2016 at 05:49:00PM -0500, Vittorio Giovara wrote:
> [...]
>> +/**
>> + * This structure describes how to handle spherical videos, outlining
>> + * information about projection, initial layout, and any other view modifier.
>> + *
>> + * @note The struct must be allocated with av_spherical_alloc() and
>> + *       its size is not a part of the public ABI.
>> + */
>> +typedef struct AVSphericalMapping {
>> +    /**
>> +     * Projection type.
>> +     */
>> +    enum AVSphericalProjection projection;
>> +
>> +    /**
>> +     * @name Initial orientation
>> +     * @{
>> +     * These fields represent the pose values that measure the rotation
>> +     * transformation (in degrees) to be applied to the projection.
>> +     * See this equirectangular projection as example:
>> +     *
>> +     * @code{.unparsed}
>> +     *                   Yaw
>> +     *     -180           0           180
>> +     *   90 +-------------+-------------+  180
>> +     *      |             |             |
>> +     * P    |             |      o>     |
>> +     * i    |             ^             |
>> +     * t  0 +-------------X-------------+    0 Roll
>> +     * c    |             |             |
>> +     * h    |             |             |
>> +     *      |             |             |
>> +     *  -90 +-------------+-------------+ -180
>> +     *
>> +     * X - the default camera center
>> +     * ^ - the default up vector
>> +     * > - the up vector for a rotation of 90 degrees
>> +     * o - the image center for yaw = 90, pitch = 45, roll = 0
>> +     * @endcode
>> +     *
>> +     * The order of transformation is always yaw, followed by pitch, and
>> +     * finally by roll.
>> +     */
> 
>> +    double yaw;   ///< Clockwise rotation around the up vector [-180, 180].
>> +    double pitch; ///< Counter-clockwise rotation around the right vector [-90, 90].
>> +    double roll;  ///< Counter-clockwise rotation around the forward vector [-180, 180].
> 
> please use intXY (64 or 32 as preferred) so there are no platform
> rounding dependancies
> 

CCing Vittorio so he can see this.
Vittorio Giovara Nov. 12, 2016, 5:30 p.m. UTC | #3
On Sat, Nov 12, 2016 at 9:41 AM, James Almer <jamrial@gmail.com> wrote:
> On 11/11/2016 10:39 PM, Michael Niedermayer wrote:
>> On Fri, Nov 11, 2016 at 05:49:00PM -0500, Vittorio Giovara wrote:
>> [...]
>>> +/**
>>> + * This structure describes how to handle spherical videos, outlining
>>> + * information about projection, initial layout, and any other view modifier.
>>> + *
>>> + * @note The struct must be allocated with av_spherical_alloc() and
>>> + *       its size is not a part of the public ABI.
>>> + */
>>> +typedef struct AVSphericalMapping {
>>> +    /**
>>> +     * Projection type.
>>> +     */
>>> +    enum AVSphericalProjection projection;
>>> +
>>> +    /**
>>> +     * @name Initial orientation
>>> +     * @{
>>> +     * These fields represent the pose values that measure the rotation
>>> +     * transformation (in degrees) to be applied to the projection.
>>> +     * See this equirectangular projection as example:
>>> +     *
>>> +     * @code{.unparsed}
>>> +     *                   Yaw
>>> +     *     -180           0           180
>>> +     *   90 +-------------+-------------+  180
>>> +     *      |             |             |
>>> +     * P    |             |      o>     |
>>> +     * i    |             ^             |
>>> +     * t  0 +-------------X-------------+    0 Roll
>>> +     * c    |             |             |
>>> +     * h    |             |             |
>>> +     *      |             |             |
>>> +     *  -90 +-------------+-------------+ -180
>>> +     *
>>> +     * X - the default camera center
>>> +     * ^ - the default up vector
>>> +     * > - the up vector for a rotation of 90 degrees
>>> +     * o - the image center for yaw = 90, pitch = 45, roll = 0
>>> +     * @endcode
>>> +     *
>>> +     * The order of transformation is always yaw, followed by pitch, and
>>> +     * finally by roll.
>>> +     */
>>
>>> +    double yaw;   ///< Clockwise rotation around the up vector [-180, 180].
>>> +    double pitch; ///< Counter-clockwise rotation around the right vector [-90, 90].
>>> +    double roll;  ///< Counter-clockwise rotation around the forward vector [-180, 180].
>>
>> please use intXY (64 or 32 as preferred) so there are no platform
>> rounding dependancies

These are rotation angles which are inherently floating point, and
consistent with what other rotation-related APIs export (eg.
av_display_matrix_rotation_get()). Besides using intXX would lose
precision that the original specification offers.
Michael Niedermayer Nov. 12, 2016, 11:11 p.m. UTC | #4
Hi

On Sat, Nov 12, 2016 at 12:30:52PM -0500, Vittorio Giovara wrote:
> On Sat, Nov 12, 2016 at 9:41 AM, James Almer <jamrial@gmail.com> wrote:
> > On 11/11/2016 10:39 PM, Michael Niedermayer wrote:
> >> On Fri, Nov 11, 2016 at 05:49:00PM -0500, Vittorio Giovara wrote:
[...]
> >>
> >>> +    double yaw;   ///< Clockwise rotation around the up vector [-180, 180].
> >>> +    double pitch; ///< Counter-clockwise rotation around the right vector [-90, 90].
> >>> +    double roll;  ///< Counter-clockwise rotation around the forward vector [-180, 180].
> >>
> >> please use intXY (64 or 32 as preferred) so there are no platform
> >> rounding dependancies
> 
> These are rotation angles which are inherently floating point, and

Theres nothing inherently floating point on an angle.


> consistent with what other rotation-related APIs export (eg.
> av_display_matrix_rotation_get()).

> Besides using intXX would lose
> precision that the original specification offers.

int64_t has about a thousand times higher precission than a double
for storing general -180°..+180° angles. This is because doubles have
11 bits for a exponent which is exactly the same value for most of the
angles

[...]
Vittorio Giovara Nov. 13, 2016, 3:05 a.m. UTC | #5
On Sat, Nov 12, 2016 at 6:11 PM, Michael Niedermayer
<michael@niedermayer.cc> wrote:
> Hi
>
> On Sat, Nov 12, 2016 at 12:30:52PM -0500, Vittorio Giovara wrote:
>> On Sat, Nov 12, 2016 at 9:41 AM, James Almer <jamrial@gmail.com> wrote:
>> > On 11/11/2016 10:39 PM, Michael Niedermayer wrote:
>> >> On Fri, Nov 11, 2016 at 05:49:00PM -0500, Vittorio Giovara wrote:
> [...]
>> >>
>> >>> +    double yaw;   ///< Clockwise rotation around the up vector [-180, 180].
>> >>> +    double pitch; ///< Counter-clockwise rotation around the right vector [-90, 90].
>> >>> +    double roll;  ///< Counter-clockwise rotation around the forward vector [-180, 180].
>> >>
>> >> please use intXY (64 or 32 as preferred) so there are no platform
>> >> rounding dependancies
>>
>> These are rotation angles which are inherently floating point, and
>
> Theres nothing inherently floating point on an angle.

Err not sure where you get that from, but it is very common for
rotation to be represented in floating point, whether you express it
in degrees (and thus real numbers, which include fractional values
such as 90.5º, expressed as floating point in computing) and in
radians where you literally use PI (which is an irrational numerical
constant, again expressed as floating point in computing).

>> consistent with what other rotation-related APIs export (eg.
>> av_display_matrix_rotation_get()).
>
>> Besides using intXX would lose
>> precision that the original specification offers.
>
> int64_t has about a thousand times higher precission than a double
> for storing general -180°..+180° angles. This is because doubles have
> 11 bits for a exponent which is exactly the same value for most of the
> angles

How much precision is too precision? double values are extremely well
suited for the kind of angles they have to represent: 11 bits are way
more than enough to express values between 180 and -180, and the rest
can be used for the mantissa (bearing a value between 0 and
0.999999..) good enough.

So I really do not see a use case for using int64 here.
Michael Niedermayer Nov. 13, 2016, 9:18 a.m. UTC | #6
On Sat, Nov 12, 2016 at 10:05:22PM -0500, Vittorio Giovara wrote:
[...]
> So I really do not see a use case for using int64 here.

then you can use int32, less than int32 is too little if for example
you wnat the precission to be sufficient to know where a tele lens
points with pixel precission and have a bit precission headroom

[...]
Michael Niedermayer Nov. 13, 2016, 4:57 p.m. UTC | #7
On Sun, Nov 13, 2016 at 10:18:18AM +0100, Michael Niedermayer wrote:
> On Sat, Nov 12, 2016 at 10:05:22PM -0500, Vittorio Giovara wrote:
> [...]
> > So I really do not see a use case for using int64 here.
> 
> then you can use int32, less than int32 is too little if for example
> you wnat the precission to be sufficient to know where a tele lens
> points with pixel precission and have a bit precission headroom

and it seems i lost the CC again :(

[...]
Vittorio Giovara Nov. 14, 2016, 9:55 p.m. UTC | #8
On Sun, Nov 13, 2016 at 11:57 AM, Michael Niedermayer
<michael@niedermayer.cc> wrote:
> On Sun, Nov 13, 2016 at 10:18:18AM +0100, Michael Niedermayer wrote:
>> On Sat, Nov 12, 2016 at 10:05:22PM -0500, Vittorio Giovara wrote:
>> [...]
>> > So I really do not see a use case for using int64 here.
>>
>> then you can use int32, less than int32 is too little if for example
>> you wnat the precission to be sufficient to know where a tele lens
>> points with pixel precission and have a bit precission headroom

Hi Michael, thanks for keeping me in CC.
I understand the problem, but this is a solution for a issue that is
non-existent. There is no application or usecase for "pixel perfect"
precision, the rendering of a spherical video will distort the video
surface in order to map the flat surface to a sphere, and it is
impossible to predict where this operation will move pixels to. I
believe this is why this specification describes the initial
orientation as rotation degrees rather than pixel offsets.

As I said, I believe the use case of a rotation calls in the use of
double, exactly as it happens for other rotation APIs in the codebase.
Secondly I am against exporting the data as fixed point since that
would be burden to the end user and would tie this API to the google
specification too much. Finally I don't see what is wrong about these
fields being platform-specific, the whole structure is bound to be
platform specific, and the API mandates that a structure is used all
the time.
Michael Niedermayer Nov. 15, 2016, 1:55 a.m. UTC | #9
On Mon, Nov 14, 2016 at 04:55:36PM -0500, Vittorio Giovara wrote:
> On Sun, Nov 13, 2016 at 11:57 AM, Michael Niedermayer
> <michael@niedermayer.cc> wrote:
> > On Sun, Nov 13, 2016 at 10:18:18AM +0100, Michael Niedermayer wrote:
> >> On Sat, Nov 12, 2016 at 10:05:22PM -0500, Vittorio Giovara wrote:
> >> [...]
> >> > So I really do not see a use case for using int64 here.
> >>
> >> then you can use int32, less than int32 is too little if for example
> >> you wnat the precission to be sufficient to know where a tele lens
> >> points with pixel precission and have a bit precission headroom
> 
> Hi Michael, thanks for keeping me in CC.
> I understand the problem, but this is a solution for a issue that is
> non-existent.

The problem of difficut to test code is real and existing in general.
Encoders&muxers using floats/doubles can not be tested as completely as
Encoders&muxers not using floats unless they by chance give binary
identical results on all platforms.

Muxers&encoders would use/write the rotation side data

Similarly ffprobe would at some point print this data, the text
printout of doubles has a good chance to not match exactly between
platforms.


> There is no application or usecase for "pixel perfect"
> precision, the rendering of a spherical video will distort the video
> surface in order to map the flat surface to a sphere, and it is
> impossible to predict where this operation will move pixels to. I
> believe this is why this specification describes the initial
> orientation as rotation degrees rather than pixel offsets.

I referred to pixels only to show that 32bit floats are insufficiently
precisse in some cases.


[...]
Vittorio Giovara Nov. 15, 2016, 3:57 p.m. UTC | #10
On Mon, Nov 14, 2016 at 8:55 PM, Michael Niedermayer
<michael@niedermayer.cc> wrote:
> On Mon, Nov 14, 2016 at 04:55:36PM -0500, Vittorio Giovara wrote:
>> On Sun, Nov 13, 2016 at 11:57 AM, Michael Niedermayer
>> <michael@niedermayer.cc> wrote:
>> > On Sun, Nov 13, 2016 at 10:18:18AM +0100, Michael Niedermayer wrote:
>> >> On Sat, Nov 12, 2016 at 10:05:22PM -0500, Vittorio Giovara wrote:
>> >> [...]
>> >> > So I really do not see a use case for using int64 here.
>> >>
>> >> then you can use int32, less than int32 is too little if for example
>> >> you wnat the precission to be sufficient to know where a tele lens
>> >> points with pixel precission and have a bit precission headroom
>>
>> Hi Michael, thanks for keeping me in CC.
>> I understand the problem, but this is a solution for a issue that is
>> non-existent.
>
> The problem of difficut to test code is real and existing in general.
> Encoders&muxers using floats/doubles can not be tested as completely as
> Encoders&muxers not using floats unless they by chance give binary
> identical results on all platforms.

That's not the problem you referred to in the previous email.

> Muxers&encoders would use/write the rotation side data
>
> Similarly ffprobe would at some point print this data, the text
> printout of doubles has a good chance to not match exactly between
> platforms.

ffprobe does that in 2/3, but right now it's limited to int.

>> There is no application or usecase for "pixel perfect"
>> precision, the rendering of a spherical video will distort the video
>> surface in order to map the flat surface to a sphere, and it is
>> impossible to predict where this operation will move pixels to. I
>> believe this is why this specification describes the initial
>> orientation as rotation degrees rather than pixel offsets.
>
> I referred to pixels only to show that 32bit floats are insufficiently
> precisse in some cases.

I still don't like it, but I'll just export the original 16.16 fixed
point value and let the user deal with it then.
Thanks for the reviews.
diff mbox

Patch

diff --git a/libavutil/Makefile b/libavutil/Makefile
index 0fa90fe..c5af79a 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -63,6 +63,7 @@  HEADERS = adler32.h                                                     \
           samplefmt.h                                                   \
           sha.h                                                         \
           sha512.h                                                      \
+          spherical.h                                                   \
           stereo3d.h                                                    \
           threadmessage.h                                               \
           time.h                                                        \
@@ -140,6 +141,7 @@  OBJS = adler32.o                                                        \
        samplefmt.o                                                      \
        sha.o                                                            \
        sha512.o                                                         \
+       spherical.o                                                      \
        stereo3d.o                                                       \
        threadmessage.o                                                  \
        time.o                                                           \
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index 29dd830..e9aaa03 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -118,6 +118,12 @@ 
  *
  * @}
  *
+ * @defgroup lavu_video Video related
+ *
+ * @{
+ *
+ * @}
+ *
  * @defgroup lavu_audio Audio related
  *
  * @{
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 8e51361..b450092 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -120,7 +120,13 @@  enum AVFrameSideDataType {
      * The GOP timecode in 25 bit timecode format. Data format is 64-bit integer.
      * This is set on the first frame of a GOP that has a temporal reference of 0.
      */
-    AV_FRAME_DATA_GOP_TIMECODE
+    AV_FRAME_DATA_GOP_TIMECODE,
+
+    /**
+     * The data represents the AVSphericalMapping structure defined in
+     * libavutil/spherical.h.
+     */
+    AV_FRAME_DATA_SPHERICAL,
 };
 
 enum AVActiveFormatDescription {
diff --git a/libavutil/spherical.c b/libavutil/spherical.c
new file mode 100644
index 0000000..816452c
--- /dev/null
+++ b/libavutil/spherical.c
@@ -0,0 +1,34 @@ 
+/*
+ * Copyright (c) 2016 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "mem.h"
+#include "spherical.h"
+
+AVSphericalMapping *av_spherical_alloc(size_t *size)
+{
+    AVSphericalMapping *spherical = av_mallocz(sizeof(AVSphericalMapping));
+    if (!spherical)
+        return NULL;
+
+    if (size)
+        *size = sizeof(*spherical);
+
+    return spherical;
+}
diff --git a/libavutil/spherical.h b/libavutil/spherical.h
new file mode 100644
index 0000000..57cd36b
--- /dev/null
+++ b/libavutil/spherical.h
@@ -0,0 +1,144 @@ 
+/*
+ * Copyright (c) 2016 Vittorio Giovara <vittorio.giovara@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Spherical video
+ */
+
+#ifndef AVUTIL_SPHERICAL_H
+#define AVUTIL_SPHERICAL_H
+
+/**
+ * @addtogroup lavu_video
+ * @{
+ *
+ * @defgroup lavu_video_spherical Spherical video mapping
+ * @{
+ */
+
+/**
+ * @addtogroup lavu_video_spherical
+ * A spherical video file contains surfaces that need to be mapped onto a
+ * sphere. Depending on how the frame was converted, a different distortion
+ * transformation or surface recomposition function needs to be applied before
+ * the video should be mapped and displayed.
+ */
+
+/**
+ * Projection of the video surface(s) on a sphere.
+ */
+enum AVSphericalProjection {
+    /**
+     * Video represents a sphere mapped on a flat surface.
+     */
+    AV_SPHERICAL_EQUIRECTANGULAR,
+
+    /**
+     * Video frame is split into 6 faces of a cube, and arranged on a
+     * 3x2 layout. Faces are oriented upwards for the front, left, right,
+     * and back faces. The up face is oriented so the top of the face is
+     * forwards and the down face is oriented so the top of the face is
+     * to the back.
+     */
+    AV_SPHERICAL_CUBEMAP,
+};
+
+/**
+ * This structure describes how to handle spherical videos, outlining
+ * information about projection, initial layout, and any other view modifier.
+ *
+ * @note The struct must be allocated with av_spherical_alloc() and
+ *       its size is not a part of the public ABI.
+ */
+typedef struct AVSphericalMapping {
+    /**
+     * Projection type.
+     */
+    enum AVSphericalProjection projection;
+
+    /**
+     * @name Initial orientation
+     * @{
+     * These fields represent the pose values that measure the rotation
+     * transformation (in degrees) to be applied to the projection.
+     * See this equirectangular projection as example:
+     *
+     * @code{.unparsed}
+     *                   Yaw
+     *     -180           0           180
+     *   90 +-------------+-------------+  180
+     *      |             |             |
+     * P    |             |      o>     |
+     * i    |             ^             |
+     * t  0 +-------------X-------------+    0 Roll
+     * c    |             |             |
+     * h    |             |             |
+     *      |             |             |
+     *  -90 +-------------+-------------+ -180
+     *
+     * X - the default camera center
+     * ^ - the default up vector
+     * > - the up vector for a rotation of 90 degrees
+     * o - the image center for yaw = 90, pitch = 45, roll = 0
+     * @endcode
+     *
+     * The order of transformation is always yaw, followed by pitch, and
+     * finally by roll.
+     */
+    double yaw;   ///< Clockwise rotation around the up vector [-180, 180].
+    double pitch; ///< Counter-clockwise rotation around the right vector [-90, 90].
+    double roll;  ///< Counter-clockwise rotation around the forward vector [-180, 180].
+    /**
+     * @}
+     */
+
+    /**
+     * @name Bounding rectangle
+     * @{
+     * These fields are the amount of pixels to crop from the edge
+     * of the video surface.
+     *
+     * @note For cubemap projections these values apply to each
+     *       face of the cube.
+     */
+    unsigned int left_offset;   ///< Pixels to crop from the left edge.
+    unsigned int top_offset;    ///< Pixels to crop from the top edge.
+    unsigned int right_offset;  ///< Pixels to crop from the right edge.
+    unsigned int bottom_offset; ///< Pixels to crop from the bottom edge.
+    /**
+     * @}
+     */
+} AVSphericalMapping;
+
+/**
+ * Allocate a AVSphericalVideo structure and initialize its fields to default
+ * values.
+ *
+ * @return the newly allocated struct or NULL on failure
+ */
+AVSphericalMapping *av_spherical_alloc(size_t *size);
+
+/**
+ * @}
+ * @}
+ */
+
+#endif /* AVUTIL_SPHERICAL_H */