diff mbox series

[FFmpeg-devel] lavu/stereo3d: change baseline and horizontal FOV to rationals

Message ID 20240622201116.403924-1-dev@lynne.ee
State New
Headers show
Series [FFmpeg-devel] lavu/stereo3d: change baseline and horizontal FOV to rationals | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Lynne June 22, 2024, 8:11 p.m. UTC
This avoids hardcoding any implementation-specific limitiations as
part of the API, and allows for future expandability.

This also allows API users to more conveniently convert the
values into floats without hardcoding specific conversion constants.

The draft implementation of this mechanism for the draft of
AVTransport uses rationals for these particular fields.

The API was committed 2 days ago, so changing these fields now
is within the realms of acceptable.
---
 fftools/ffprobe.c                            |  4 ++--
 libavformat/dump.c                           |  9 +++++----
 libavformat/mov.c                            |  9 ++++++---
 libavutil/stereo3d.h                         |  8 ++++----
 tests/ref/fate/matroska-spherical-mono       |  4 ++--
 tests/ref/fate/matroska-spherical-mono-remux |  8 ++++----
 tests/ref/fate/matroska-stereo_mode          | 16 ++++++++--------
 tests/ref/fate/matroska-vp8-alpha-remux      |  4 ++--
 tests/ref/fate/mov-spherical-mono            |  4 ++--
 9 files changed, 35 insertions(+), 31 deletions(-)

Comments

James Almer June 22, 2024, 8:19 p.m. UTC | #1
On 6/22/2024 5:11 PM, Lynne via ffmpeg-devel wrote:
> This avoids hardcoding any implementation-specific limitiations as
> part of the API, and allows for future expandability.
> 
> This also allows API users to more conveniently convert the
> values into floats without hardcoding specific conversion constants.
> 
> The draft implementation of this mechanism for the draft of
> AVTransport uses rationals for these particular fields.
> 
> The API was committed 2 days ago, so changing these fields now
> is within the realms of acceptable.
> ---
>   fftools/ffprobe.c                            |  4 ++--
>   libavformat/dump.c                           |  9 +++++----
>   libavformat/mov.c                            |  9 ++++++---
>   libavutil/stereo3d.h                         |  8 ++++----
>   tests/ref/fate/matroska-spherical-mono       |  4 ++--
>   tests/ref/fate/matroska-spherical-mono-remux |  8 ++++----
>   tests/ref/fate/matroska-stereo_mode          | 16 ++++++++--------
>   tests/ref/fate/matroska-vp8-alpha-remux      |  4 ++--
>   tests/ref/fate/mov-spherical-mono            |  4 ++--
>   9 files changed, 35 insertions(+), 31 deletions(-)
> 
> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
> index d7ba980ff9..2da928b7c3 100644
> --- a/fftools/ffprobe.c
> +++ b/fftools/ffprobe.c
> @@ -2546,9 +2546,9 @@ static void print_pkt_side_data(WriterContext *w,
>               print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
>               print_str("view", av_stereo3d_view_name(stereo->view));
>               print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye));
> -            print_int("baseline", stereo->baseline);
> +            print_q("baseline", stereo->baseline, '/');
>               print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/');
> -            print_int("horizontal_field_of_view", stereo->horizontal_field_of_view);
> +            print_q("horizontal_field_of_view", stereo->horizontal_field_of_view, '/');
>           } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
>               const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
>               print_str("projection", av_spherical_projection_name(spherical->projection));
> diff --git a/libavformat/dump.c b/libavformat/dump.c
> index 61a2c6a29f..ac7d3038ab 100644
> --- a/libavformat/dump.c
> +++ b/libavformat/dump.c
> @@ -262,13 +262,14 @@ static void dump_stereo3d(void *ctx, const AVPacketSideData *sd, int log_level)
>       av_log(ctx, log_level, "%s, view: %s, primary eye: %s",
>              av_stereo3d_type_name(stereo->type), av_stereo3d_view_name(stereo->view),
>              av_stereo3d_primary_eye_name(stereo->primary_eye));
> -    if (stereo->baseline)
> -        av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo->baseline);
> +    if (stereo->baseline.num && stereo->baseline.den)
> +        av_log(ctx, log_level, ", baseline: %d/%d", stereo->baseline.num, stereo->baseline.den);
>       if (stereo->horizontal_disparity_adjustment.num && stereo->horizontal_disparity_adjustment.den)
>           av_log(ctx, log_level, ", horizontal_disparity_adjustment: %d/%d",
>                  stereo->horizontal_disparity_adjustment.num, stereo->horizontal_disparity_adjustment.den);
> -    if (stereo->horizontal_field_of_view)
> -        av_log(ctx, log_level, ", horizontal_field_of_view: %"PRIu32"", stereo->horizontal_field_of_view);
> +    if (stereo->horizontal_field_of_view.num && stereo->horizontal_field_of_view.den)
> +        av_log(ctx, log_level, ", horizontal_field_of_view: %d/%d", stereo->horizontal_field_of_view.num,
> +               stereo->horizontal_field_of_view.den);
>   
>       if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
>           av_log(ctx, log_level, " (inverted)");
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index f08fec3fb6..64cd17e770 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -6545,7 +6545,8 @@ static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>       MOVStreamContext *sc;
>       int size, flags = 0;
>       int64_t remaining;
> -    uint32_t tag, baseline = 0;
> +    uint32_t tag;
> +    AVRational baseline = av_make_q(0, 0);
>       enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED;
>       enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
>       AVRational horizontal_disparity_adjustment = { 0, 1 };
> @@ -6642,7 +6643,8 @@ static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>               avio_skip(pb, 1); // version
>               avio_skip(pb, 3); // flags
>   
> -            baseline = avio_rb32(pb);
> +            baseline.num = avio_rb32(pb);
> +            baseline.den = 1000000; // micrometers
>   
>               break;
>           }
> @@ -6782,7 +6784,8 @@ static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>               return AVERROR(ENOMEM);
>       }
>   
> -    sc->stereo3d->horizontal_field_of_view = avio_rb32(pb);
> +    sc->stereo3d->horizontal_field_of_view.num = avio_rb32(pb);
> +    sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
>   
>       return 0;
>   }
> diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
> index 00a5c3900e..097f6c9455 100644
> --- a/libavutil/stereo3d.h
> +++ b/libavutil/stereo3d.h
> @@ -213,9 +213,9 @@ typedef struct AVStereo3D {
>   
>       /**
>        * The distance between the centres of the lenses of the camera system,
> -     * in micrometers. Zero if unset.
> +     * in meters. Zero if unset.
>        */
> -    uint32_t baseline;
> +    AVRational baseline;

This is not ok. No reason for distance be a soft float, or allow 
negative values. In the case of the blin box, it's a 32bit unsigned 
value, which will not fit in AVRational.

You can easily convert this in your code by using a 1000000 denominator 
if you wish.

>   
>       /**
>        * Relative shift of the left and right images, which changes the zero parallax plane.
> @@ -224,9 +224,9 @@ typedef struct AVStereo3D {
>       AVRational horizontal_disparity_adjustment;
>   
>       /**
> -     * Horizontal field of view in thousanths of a degree. Zero if unset.
> +     * Horizontal field of view, in degrees. Zero if unset.
>        */
> -    uint32_t horizontal_field_of_view;
> +    AVRational horizontal_field_of_view;

This one i can't say. Would for example Matroska implement degrees as a 
float, or uint?
Lynne June 22, 2024, 9:26 p.m. UTC | #2
On 22/06/2024 22:19, James Almer wrote:
> On 6/22/2024 5:11 PM, Lynne via ffmpeg-devel wrote:
>> This avoids hardcoding any implementation-specific limitiations as
>> part of the API, and allows for future expandability.
>>
>> This also allows API users to more conveniently convert the
>> values into floats without hardcoding specific conversion constants.
>>
>> The draft implementation of this mechanism for the draft of
>> AVTransport uses rationals for these particular fields.
>>
>> The API was committed 2 days ago, so changing these fields now
>> is within the realms of acceptable.
>> ---
>>   fftools/ffprobe.c                            |  4 ++--
>>   libavformat/dump.c                           |  9 +++++----
>>   libavformat/mov.c                            |  9 ++++++---
>>   libavutil/stereo3d.h                         |  8 ++++----
>>   tests/ref/fate/matroska-spherical-mono       |  4 ++--
>>   tests/ref/fate/matroska-spherical-mono-remux |  8 ++++----
>>   tests/ref/fate/matroska-stereo_mode          | 16 ++++++++--------
>>   tests/ref/fate/matroska-vp8-alpha-remux      |  4 ++--
>>   tests/ref/fate/mov-spherical-mono            |  4 ++--
>>   9 files changed, 35 insertions(+), 31 deletions(-)
>>
>> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
>> index d7ba980ff9..2da928b7c3 100644
>> --- a/fftools/ffprobe.c
>> +++ b/fftools/ffprobe.c
>> @@ -2546,9 +2546,9 @@ static void print_pkt_side_data(WriterContext *w,
>>               print_int("inverted", !!(stereo->flags & 
>> AV_STEREO3D_FLAG_INVERT));
>>               print_str("view", av_stereo3d_view_name(stereo->view));
>>               print_str("primary_eye", 
>> av_stereo3d_primary_eye_name(stereo->primary_eye));
>> -            print_int("baseline", stereo->baseline);
>> +            print_q("baseline", stereo->baseline, '/');
>>               print_q("horizontal_disparity_adjustment", stereo- 
>> >horizontal_disparity_adjustment, '/');
>> -            print_int("horizontal_field_of_view", stereo- 
>> >horizontal_field_of_view);
>> +            print_q("horizontal_field_of_view", stereo- 
>> >horizontal_field_of_view, '/');
>>           } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
>>               const AVSphericalMapping *spherical = 
>> (AVSphericalMapping *)sd->data;
>>               print_str("projection", 
>> av_spherical_projection_name(spherical->projection));
>> diff --git a/libavformat/dump.c b/libavformat/dump.c
>> index 61a2c6a29f..ac7d3038ab 100644
>> --- a/libavformat/dump.c
>> +++ b/libavformat/dump.c
>> @@ -262,13 +262,14 @@ static void dump_stereo3d(void *ctx, const 
>> AVPacketSideData *sd, int log_level)
>>       av_log(ctx, log_level, "%s, view: %s, primary eye: %s",
>>              av_stereo3d_type_name(stereo->type), 
>> av_stereo3d_view_name(stereo->view),
>>              av_stereo3d_primary_eye_name(stereo->primary_eye));
>> -    if (stereo->baseline)
>> -        av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo- 
>> >baseline);
>> +    if (stereo->baseline.num && stereo->baseline.den)
>> +        av_log(ctx, log_level, ", baseline: %d/%d", stereo- 
>> >baseline.num, stereo->baseline.den);
>>       if (stereo->horizontal_disparity_adjustment.num && stereo- 
>> >horizontal_disparity_adjustment.den)
>>           av_log(ctx, log_level, ", horizontal_disparity_adjustment: 
>> %d/%d",
>>                  stereo->horizontal_disparity_adjustment.num, stereo- 
>> >horizontal_disparity_adjustment.den);
>> -    if (stereo->horizontal_field_of_view)
>> -        av_log(ctx, log_level, ", horizontal_field_of_view: 
>> %"PRIu32"", stereo->horizontal_field_of_view);
>> +    if (stereo->horizontal_field_of_view.num && stereo- 
>> >horizontal_field_of_view.den)
>> +        av_log(ctx, log_level, ", horizontal_field_of_view: %d/%d", 
>> stereo->horizontal_field_of_view.num,
>> +               stereo->horizontal_field_of_view.den);
>>       if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
>>           av_log(ctx, log_level, " (inverted)");
>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>> index f08fec3fb6..64cd17e770 100644
>> --- a/libavformat/mov.c
>> +++ b/libavformat/mov.c
>> @@ -6545,7 +6545,8 @@ static int mov_read_eyes(MOVContext *c, 
>> AVIOContext *pb, MOVAtom atom)
>>       MOVStreamContext *sc;
>>       int size, flags = 0;
>>       int64_t remaining;
>> -    uint32_t tag, baseline = 0;
>> +    uint32_t tag;
>> +    AVRational baseline = av_make_q(0, 0);
>>       enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED;
>>       enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
>>       AVRational horizontal_disparity_adjustment = { 0, 1 };
>> @@ -6642,7 +6643,8 @@ static int mov_read_eyes(MOVContext *c, 
>> AVIOContext *pb, MOVAtom atom)
>>               avio_skip(pb, 1); // version
>>               avio_skip(pb, 3); // flags
>> -            baseline = avio_rb32(pb);
>> +            baseline.num = avio_rb32(pb);
>> +            baseline.den = 1000000; // micrometers
>>               break;
>>           }
>> @@ -6782,7 +6784,8 @@ static int mov_read_hfov(MOVContext *c, 
>> AVIOContext *pb, MOVAtom atom)
>>               return AVERROR(ENOMEM);
>>       }
>> -    sc->stereo3d->horizontal_field_of_view = avio_rb32(pb);
>> +    sc->stereo3d->horizontal_field_of_view.num = avio_rb32(pb);
>> +    sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands 
>> of a degree
>>       return 0;
>>   }
>> diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
>> index 00a5c3900e..097f6c9455 100644
>> --- a/libavutil/stereo3d.h
>> +++ b/libavutil/stereo3d.h
>> @@ -213,9 +213,9 @@ typedef struct AVStereo3D {
>>       /**
>>        * The distance between the centres of the lenses of the camera 
>> system,
>> -     * in micrometers. Zero if unset.
>> +     * in meters. Zero if unset.
>>        */
>> -    uint32_t baseline;
>> +    AVRational baseline;
> 
> This is not ok. No reason for distance be a soft float, or allow 
> negative values. In the case of the blin box, it's a 32bit unsigned 
> value, which will not fit in AVRational.

Added an (int32_t) cast locally. This is also how 
horizontal_disparity_adjustment is handled, with a uint32_t converted 
into a rational.

> 
> You can easily convert this in your code by using a 1000000 denominator 
> if you wish.
> 
>>       /**
>>        * Relative shift of the left and right images, which changes 
>> the zero parallax plane.
>> @@ -224,9 +224,9 @@ typedef struct AVStereo3D {
>>       AVRational horizontal_disparity_adjustment;
>>       /**
>> -     * Horizontal field of view in thousanths of a degree. Zero if 
>> unset.
>> +     * Horizontal field of view, in degrees. Zero if unset.
>>        */
>> -    uint32_t horizontal_field_of_view;
>> +    AVRational horizontal_field_of_view;
> 
> This one i can't say. Would for example Matroska implement degrees as a 
> float, or uint?

Likely a float (EBML_FLOAT). This is how mastering metadata and video 
projection are handled.
James Almer June 22, 2024, 9:30 p.m. UTC | #3
On 6/22/2024 6:26 PM, Lynne via ffmpeg-devel wrote:
> On 22/06/2024 22:19, James Almer wrote:
>> On 6/22/2024 5:11 PM, Lynne via ffmpeg-devel wrote:
>>> This avoids hardcoding any implementation-specific limitiations as
>>> part of the API, and allows for future expandability.
>>>
>>> This also allows API users to more conveniently convert the
>>> values into floats without hardcoding specific conversion constants.
>>>
>>> The draft implementation of this mechanism for the draft of
>>> AVTransport uses rationals for these particular fields.
>>>
>>> The API was committed 2 days ago, so changing these fields now
>>> is within the realms of acceptable.
>>> ---
>>>   fftools/ffprobe.c                            |  4 ++--
>>>   libavformat/dump.c                           |  9 +++++----
>>>   libavformat/mov.c                            |  9 ++++++---
>>>   libavutil/stereo3d.h                         |  8 ++++----
>>>   tests/ref/fate/matroska-spherical-mono       |  4 ++--
>>>   tests/ref/fate/matroska-spherical-mono-remux |  8 ++++----
>>>   tests/ref/fate/matroska-stereo_mode          | 16 ++++++++--------
>>>   tests/ref/fate/matroska-vp8-alpha-remux      |  4 ++--
>>>   tests/ref/fate/mov-spherical-mono            |  4 ++--
>>>   9 files changed, 35 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
>>> index d7ba980ff9..2da928b7c3 100644
>>> --- a/fftools/ffprobe.c
>>> +++ b/fftools/ffprobe.c
>>> @@ -2546,9 +2546,9 @@ static void print_pkt_side_data(WriterContext *w,
>>>               print_int("inverted", !!(stereo->flags & 
>>> AV_STEREO3D_FLAG_INVERT));
>>>               print_str("view", av_stereo3d_view_name(stereo->view));
>>>               print_str("primary_eye", 
>>> av_stereo3d_primary_eye_name(stereo->primary_eye));
>>> -            print_int("baseline", stereo->baseline);
>>> +            print_q("baseline", stereo->baseline, '/');
>>>               print_q("horizontal_disparity_adjustment", stereo- 
>>> >horizontal_disparity_adjustment, '/');
>>> -            print_int("horizontal_field_of_view", stereo- 
>>> >horizontal_field_of_view);
>>> +            print_q("horizontal_field_of_view", stereo- 
>>> >horizontal_field_of_view, '/');
>>>           } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
>>>               const AVSphericalMapping *spherical = 
>>> (AVSphericalMapping *)sd->data;
>>>               print_str("projection", 
>>> av_spherical_projection_name(spherical->projection));
>>> diff --git a/libavformat/dump.c b/libavformat/dump.c
>>> index 61a2c6a29f..ac7d3038ab 100644
>>> --- a/libavformat/dump.c
>>> +++ b/libavformat/dump.c
>>> @@ -262,13 +262,14 @@ static void dump_stereo3d(void *ctx, const 
>>> AVPacketSideData *sd, int log_level)
>>>       av_log(ctx, log_level, "%s, view: %s, primary eye: %s",
>>>              av_stereo3d_type_name(stereo->type), 
>>> av_stereo3d_view_name(stereo->view),
>>>              av_stereo3d_primary_eye_name(stereo->primary_eye));
>>> -    if (stereo->baseline)
>>> -        av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo- 
>>> >baseline);
>>> +    if (stereo->baseline.num && stereo->baseline.den)
>>> +        av_log(ctx, log_level, ", baseline: %d/%d", stereo- 
>>> >baseline.num, stereo->baseline.den);
>>>       if (stereo->horizontal_disparity_adjustment.num && stereo- 
>>> >horizontal_disparity_adjustment.den)
>>>           av_log(ctx, log_level, ", horizontal_disparity_adjustment: 
>>> %d/%d",
>>>                  stereo->horizontal_disparity_adjustment.num, stereo- 
>>> >horizontal_disparity_adjustment.den);
>>> -    if (stereo->horizontal_field_of_view)
>>> -        av_log(ctx, log_level, ", horizontal_field_of_view: 
>>> %"PRIu32"", stereo->horizontal_field_of_view);
>>> +    if (stereo->horizontal_field_of_view.num && stereo- 
>>> >horizontal_field_of_view.den)
>>> +        av_log(ctx, log_level, ", horizontal_field_of_view: %d/%d", 
>>> stereo->horizontal_field_of_view.num,
>>> +               stereo->horizontal_field_of_view.den);
>>>       if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
>>>           av_log(ctx, log_level, " (inverted)");
>>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>>> index f08fec3fb6..64cd17e770 100644
>>> --- a/libavformat/mov.c
>>> +++ b/libavformat/mov.c
>>> @@ -6545,7 +6545,8 @@ static int mov_read_eyes(MOVContext *c, 
>>> AVIOContext *pb, MOVAtom atom)
>>>       MOVStreamContext *sc;
>>>       int size, flags = 0;
>>>       int64_t remaining;
>>> -    uint32_t tag, baseline = 0;
>>> +    uint32_t tag;
>>> +    AVRational baseline = av_make_q(0, 0);
>>>       enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED;
>>>       enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
>>>       AVRational horizontal_disparity_adjustment = { 0, 1 };
>>> @@ -6642,7 +6643,8 @@ static int mov_read_eyes(MOVContext *c, 
>>> AVIOContext *pb, MOVAtom atom)
>>>               avio_skip(pb, 1); // version
>>>               avio_skip(pb, 3); // flags
>>> -            baseline = avio_rb32(pb);
>>> +            baseline.num = avio_rb32(pb);
>>> +            baseline.den = 1000000; // micrometers
>>>               break;
>>>           }
>>> @@ -6782,7 +6784,8 @@ static int mov_read_hfov(MOVContext *c, 
>>> AVIOContext *pb, MOVAtom atom)
>>>               return AVERROR(ENOMEM);
>>>       }
>>> -    sc->stereo3d->horizontal_field_of_view = avio_rb32(pb);
>>> +    sc->stereo3d->horizontal_field_of_view.num = avio_rb32(pb);
>>> +    sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands 
>>> of a degree
>>>       return 0;
>>>   }
>>> diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
>>> index 00a5c3900e..097f6c9455 100644
>>> --- a/libavutil/stereo3d.h
>>> +++ b/libavutil/stereo3d.h
>>> @@ -213,9 +213,9 @@ typedef struct AVStereo3D {
>>>       /**
>>>        * The distance between the centres of the lenses of the camera 
>>> system,
>>> -     * in micrometers. Zero if unset.
>>> +     * in meters. Zero if unset.
>>>        */
>>> -    uint32_t baseline;
>>> +    AVRational baseline;
>>
>> This is not ok. No reason for distance be a soft float, or allow 
>> negative values. In the case of the blin box, it's a 32bit unsigned 
>> value, which will not fit in AVRational.
> 
> Added an (int32_t) cast locally. This is also how 
> horizontal_disparity_adjustment is handled, with a uint32_t converted 
> into a rational.

No, that one is an int32_t as it can be negative (Ranges -1.0 to 1.0), 
thus it works fine as AVRational. baseline does not, so it should stay 
an uint32_t.

> 
>>
>> You can easily convert this in your code by using a 1000000 
>> denominator if you wish.
>>
>>>       /**
>>>        * Relative shift of the left and right images, which changes 
>>> the zero parallax plane.
>>> @@ -224,9 +224,9 @@ typedef struct AVStereo3D {
>>>       AVRational horizontal_disparity_adjustment;
>>>       /**
>>> -     * Horizontal field of view in thousanths of a degree. Zero if 
>>> unset.
>>> +     * Horizontal field of view, in degrees. Zero if unset.
>>>        */
>>> -    uint32_t horizontal_field_of_view;
>>> +    AVRational horizontal_field_of_view;
>>
>> This one i can't say. Would for example Matroska implement degrees as 
>> a float, or uint?
> 
> Likely a float (EBML_FLOAT). This is how mastering metadata and video 
> projection are handled.

But Mastering metadata is not in degrees.

Wait for Derek to comment. He knows this field better than me.

> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Lynne June 22, 2024, 10:07 p.m. UTC | #4
On 22/06/2024 23:30, James Almer wrote:
> On 6/22/2024 6:26 PM, Lynne via ffmpeg-devel wrote:
>> On 22/06/2024 22:19, James Almer wrote:
>>> On 6/22/2024 5:11 PM, Lynne via ffmpeg-devel wrote:
>>>> This avoids hardcoding any implementation-specific limitiations as
>>>> part of the API, and allows for future expandability.
>>>>
>>>> This also allows API users to more conveniently convert the
>>>> values into floats without hardcoding specific conversion constants.
>>>>
>>>> The draft implementation of this mechanism for the draft of
>>>> AVTransport uses rationals for these particular fields.
>>>>
>>>> The API was committed 2 days ago, so changing these fields now
>>>> is within the realms of acceptable.
>>>> ---
>>>>   fftools/ffprobe.c                            |  4 ++--
>>>>   libavformat/dump.c                           |  9 +++++----
>>>>   libavformat/mov.c                            |  9 ++++++---
>>>>   libavutil/stereo3d.h                         |  8 ++++----
>>>>   tests/ref/fate/matroska-spherical-mono       |  4 ++--
>>>>   tests/ref/fate/matroska-spherical-mono-remux |  8 ++++----
>>>>   tests/ref/fate/matroska-stereo_mode          | 16 ++++++++--------
>>>>   tests/ref/fate/matroska-vp8-alpha-remux      |  4 ++--
>>>>   tests/ref/fate/mov-spherical-mono            |  4 ++--
>>>>   9 files changed, 35 insertions(+), 31 deletions(-)
>>>>
>>>> diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
>>>> index d7ba980ff9..2da928b7c3 100644
>>>> --- a/fftools/ffprobe.c
>>>> +++ b/fftools/ffprobe.c
>>>> @@ -2546,9 +2546,9 @@ static void print_pkt_side_data(WriterContext *w,
>>>>               print_int("inverted", !!(stereo->flags & 
>>>> AV_STEREO3D_FLAG_INVERT));
>>>>               print_str("view", av_stereo3d_view_name(stereo->view));
>>>>               print_str("primary_eye", 
>>>> av_stereo3d_primary_eye_name(stereo->primary_eye));
>>>> -            print_int("baseline", stereo->baseline);
>>>> +            print_q("baseline", stereo->baseline, '/');
>>>>               print_q("horizontal_disparity_adjustment", stereo- 
>>>> >horizontal_disparity_adjustment, '/');
>>>> -            print_int("horizontal_field_of_view", stereo- 
>>>> >horizontal_field_of_view);
>>>> +            print_q("horizontal_field_of_view", stereo- 
>>>> >horizontal_field_of_view, '/');
>>>>           } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
>>>>               const AVSphericalMapping *spherical = 
>>>> (AVSphericalMapping *)sd->data;
>>>>               print_str("projection", 
>>>> av_spherical_projection_name(spherical->projection));
>>>> diff --git a/libavformat/dump.c b/libavformat/dump.c
>>>> index 61a2c6a29f..ac7d3038ab 100644
>>>> --- a/libavformat/dump.c
>>>> +++ b/libavformat/dump.c
>>>> @@ -262,13 +262,14 @@ static void dump_stereo3d(void *ctx, const 
>>>> AVPacketSideData *sd, int log_level)
>>>>       av_log(ctx, log_level, "%s, view: %s, primary eye: %s",
>>>>              av_stereo3d_type_name(stereo->type), 
>>>> av_stereo3d_view_name(stereo->view),
>>>>              av_stereo3d_primary_eye_name(stereo->primary_eye));
>>>> -    if (stereo->baseline)
>>>> -        av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo- 
>>>> >baseline);
>>>> +    if (stereo->baseline.num && stereo->baseline.den)
>>>> +        av_log(ctx, log_level, ", baseline: %d/%d", stereo- 
>>>> >baseline.num, stereo->baseline.den);
>>>>       if (stereo->horizontal_disparity_adjustment.num && stereo- 
>>>> >horizontal_disparity_adjustment.den)
>>>>           av_log(ctx, log_level, ", horizontal_disparity_adjustment: 
>>>> %d/%d",
>>>>                  stereo->horizontal_disparity_adjustment.num, 
>>>> stereo- >horizontal_disparity_adjustment.den);
>>>> -    if (stereo->horizontal_field_of_view)
>>>> -        av_log(ctx, log_level, ", horizontal_field_of_view: 
>>>> %"PRIu32"", stereo->horizontal_field_of_view);
>>>> +    if (stereo->horizontal_field_of_view.num && stereo- 
>>>> >horizontal_field_of_view.den)
>>>> +        av_log(ctx, log_level, ", horizontal_field_of_view: %d/%d", 
>>>> stereo->horizontal_field_of_view.num,
>>>> +               stereo->horizontal_field_of_view.den);
>>>>       if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
>>>>           av_log(ctx, log_level, " (inverted)");
>>>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>>>> index f08fec3fb6..64cd17e770 100644
>>>> --- a/libavformat/mov.c
>>>> +++ b/libavformat/mov.c
>>>> @@ -6545,7 +6545,8 @@ static int mov_read_eyes(MOVContext *c, 
>>>> AVIOContext *pb, MOVAtom atom)
>>>>       MOVStreamContext *sc;
>>>>       int size, flags = 0;
>>>>       int64_t remaining;
>>>> -    uint32_t tag, baseline = 0;
>>>> +    uint32_t tag;
>>>> +    AVRational baseline = av_make_q(0, 0);
>>>>       enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED;
>>>>       enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
>>>>       AVRational horizontal_disparity_adjustment = { 0, 1 };
>>>> @@ -6642,7 +6643,8 @@ static int mov_read_eyes(MOVContext *c, 
>>>> AVIOContext *pb, MOVAtom atom)
>>>>               avio_skip(pb, 1); // version
>>>>               avio_skip(pb, 3); // flags
>>>> -            baseline = avio_rb32(pb);
>>>> +            baseline.num = avio_rb32(pb);
>>>> +            baseline.den = 1000000; // micrometers
>>>>               break;
>>>>           }
>>>> @@ -6782,7 +6784,8 @@ static int mov_read_hfov(MOVContext *c, 
>>>> AVIOContext *pb, MOVAtom atom)
>>>>               return AVERROR(ENOMEM);
>>>>       }
>>>> -    sc->stereo3d->horizontal_field_of_view = avio_rb32(pb);
>>>> +    sc->stereo3d->horizontal_field_of_view.num = avio_rb32(pb);
>>>> +    sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands 
>>>> of a degree
>>>>       return 0;
>>>>   }
>>>> diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
>>>> index 00a5c3900e..097f6c9455 100644
>>>> --- a/libavutil/stereo3d.h
>>>> +++ b/libavutil/stereo3d.h
>>>> @@ -213,9 +213,9 @@ typedef struct AVStereo3D {
>>>>       /**
>>>>        * The distance between the centres of the lenses of the 
>>>> camera system,
>>>> -     * in micrometers. Zero if unset.
>>>> +     * in meters. Zero if unset.
>>>>        */
>>>> -    uint32_t baseline;
>>>> +    AVRational baseline;
>>>
>>> This is not ok. No reason for distance be a soft float, or allow 
>>> negative values. In the case of the blin box, it's a 32bit unsigned 
>>> value, which will not fit in AVRational.
>>
>> Added an (int32_t) cast locally. This is also how 
>> horizontal_disparity_adjustment is handled, with a uint32_t converted 
>> into a rational.
> 
> No, that one is an int32_t as it can be negative (Ranges -1.0 to 1.0), 
> thus it works fine as AVRational. baseline does not, so it should stay 
> an uint32_t.

I doubt that anyone will use a baseline greater than 2.1 (2^31/2*10^6) 
kilometers, but sure, this part is dropped. I more strongly doubt anyone 
will use a baseline of less than a micrometer, mechanics start to play 
with dice, and atomic force microscopy has coarser resolution than this.

>>
>>>
>>> You can easily convert this in your code by using a 1000000 
>>> denominator if you wish.
>>>
>>>>       /**
>>>>        * Relative shift of the left and right images, which changes 
>>>> the zero parallax plane.
>>>> @@ -224,9 +224,9 @@ typedef struct AVStereo3D {
>>>>       AVRational horizontal_disparity_adjustment;
>>>>       /**
>>>> -     * Horizontal field of view in thousanths of a degree. Zero if 
>>>> unset.
>>>> +     * Horizontal field of view, in degrees. Zero if unset.
>>>>        */
>>>> -    uint32_t horizontal_field_of_view;
>>>> +    AVRational horizontal_field_of_view;
>>>
>>> This one i can't say. Would for example Matroska implement degrees as 
>>> a float, or uint?
>>
>> Likely a float (EBML_FLOAT). This is how mastering metadata and video 
>> projection are handled.
> 
> But Mastering metadata is not in degrees.

We use rationals for everything, not just framerates and ratios.

> Wait for Derek to comment. He knows this field better than me.

Yup, that's the plan.
Derek Buitenhuis June 23, 2024, 11:05 a.m. UTC | #5
On 6/22/2024 9:11 PM, Lynne via ffmpeg-devel wrote:
> The API was committed 2 days ago, so changing these fields now
> is within the realms of acceptable.
> ---

You also had weeks to comment on 3 revisions of the set, and it would
have been nice to hear about this then instead of changing it after I've
already pushed and integrated it in my own downstream work.

If I sound grumpy, it's because I am... the set sat commentless. 

> diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
> index 00a5c3900e..097f6c9455 100644
> --- a/libavutil/stereo3d.h
> +++ b/libavutil/stereo3d.h
> @@ -213,9 +213,9 @@ typedef struct AVStereo3D {
>  
>      /**
>       * The distance between the centres of the lenses of the camera system,
> -     * in micrometers. Zero if unset.
> +     * in meters. Zero if unset.
>       */
> -    uint32_t baseline;
> +    AVRational baseline;

Can't be AVRational for the reason James mentioned, uint32_t can't be put in an int,
and can't be negative.

Also, in terms of units, using meters here is silly, it's the distance between two
lenses, meters is an crazy unit to measure that in, not idiomatic at all, and I
would argue violates the principal of least surprise (both in terms of units, and
being a distance as a rational).

>      /**
> -     * Horizontal field of view in thousanths of a degree. Zero if unset.
> +     * Horizontal field of view, in degrees. Zero if unset.
>       */
> -    uint32_t horizontal_field_of_view;
> +    AVRational horizontal_field_of_view;
>  } AVStereo3D;

This one is more reasonable. I am not happy about the post-push change, but
if the community wants this one, I am not going to block it.

> +horizontal_field_of_view=0/0

If it is changed, this should be initialized to 0/1, as that is what James
last set did for the rest of all side data.

- Derek
Derek Buitenhuis June 23, 2024, 12:03 p.m. UTC | #6
On 6/23/2024 12:05 PM, Derek Buitenhuis wrote:
> If I sound grumpy, it's because I am... the set sat commentless. 

The tone was unnecessary, sorry about that.

- Derek
Lynne June 23, 2024, 2:23 p.m. UTC | #7
On 23/06/2024 13:05, Derek Buitenhuis wrote:
> On 6/22/2024 9:11 PM, Lynne via ffmpeg-devel wrote:
>> The API was committed 2 days ago, so changing these fields now
>> is within the realms of acceptable.
>> ---
> 
> You also had weeks to comment on 3 revisions of the set, and it would
> have been nice to hear about this then instead of changing it after I've
> already pushed and integrated it in my own downstream work.
> 
> If I sound grumpy, it's because I am... the set sat commentless.

Sorry. I somehow missed this patchset, both when it was sent for review 
and when it was merged.
I did mention that I don't have strong feelings about changing this, it 
is just being pedantic, so I can drop it if you'd prefer. There's no 
need to argue over thousands of a degree here.

>> diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
>> index 00a5c3900e..097f6c9455 100644
>> --- a/libavutil/stereo3d.h
>> +++ b/libavutil/stereo3d.h
>> @@ -213,9 +213,9 @@ typedef struct AVStereo3D {
>>   
>>       /**
>>        * The distance between the centres of the lenses of the camera system,
>> -     * in micrometers. Zero if unset.
>> +     * in meters. Zero if unset.
>>        */
>> -    uint32_t baseline;
>> +    AVRational baseline;
> 
> Can't be AVRational for the reason James mentioned, uint32_t can't be put in an int,
> and can't be negative.
> 
> Also, in terms of units, using meters here is silly, it's the distance between two
> lenses, meters is an crazy unit to measure that in, not idiomatic at all, and I
> would argue violates the principal of least surprise (both in terms of units, and
> being a distance as a rational).

Fair enough, dropped.

> 
>>       /**
>> -     * Horizontal field of view in thousanths of a degree. Zero if unset.
>> +     * Horizontal field of view, in degrees. Zero if unset.
>>        */
>> -    uint32_t horizontal_field_of_view;
>> +    AVRational horizontal_field_of_view;
>>   } AVStereo3D;
> 
> This one is more reasonable. I am not happy about the post-push change, but
> if the community wants this one, I am not going to block it.
> 
>> +horizontal_field_of_view=0/0
> 
> If it is changed, this should be initialized to 0/1, as that is what James
> last set did for the rest of all side data.

Thanks, changed, and set a v2.
diff mbox series

Patch

diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c
index d7ba980ff9..2da928b7c3 100644
--- a/fftools/ffprobe.c
+++ b/fftools/ffprobe.c
@@ -2546,9 +2546,9 @@  static void print_pkt_side_data(WriterContext *w,
             print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
             print_str("view", av_stereo3d_view_name(stereo->view));
             print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye));
-            print_int("baseline", stereo->baseline);
+            print_q("baseline", stereo->baseline, '/');
             print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/');
-            print_int("horizontal_field_of_view", stereo->horizontal_field_of_view);
+            print_q("horizontal_field_of_view", stereo->horizontal_field_of_view, '/');
         } else if (sd->type == AV_PKT_DATA_SPHERICAL) {
             const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
             print_str("projection", av_spherical_projection_name(spherical->projection));
diff --git a/libavformat/dump.c b/libavformat/dump.c
index 61a2c6a29f..ac7d3038ab 100644
--- a/libavformat/dump.c
+++ b/libavformat/dump.c
@@ -262,13 +262,14 @@  static void dump_stereo3d(void *ctx, const AVPacketSideData *sd, int log_level)
     av_log(ctx, log_level, "%s, view: %s, primary eye: %s",
            av_stereo3d_type_name(stereo->type), av_stereo3d_view_name(stereo->view),
            av_stereo3d_primary_eye_name(stereo->primary_eye));
-    if (stereo->baseline)
-        av_log(ctx, log_level, ", baseline: %"PRIu32"", stereo->baseline);
+    if (stereo->baseline.num && stereo->baseline.den)
+        av_log(ctx, log_level, ", baseline: %d/%d", stereo->baseline.num, stereo->baseline.den);
     if (stereo->horizontal_disparity_adjustment.num && stereo->horizontal_disparity_adjustment.den)
         av_log(ctx, log_level, ", horizontal_disparity_adjustment: %d/%d",
                stereo->horizontal_disparity_adjustment.num, stereo->horizontal_disparity_adjustment.den);
-    if (stereo->horizontal_field_of_view)
-        av_log(ctx, log_level, ", horizontal_field_of_view: %"PRIu32"", stereo->horizontal_field_of_view);
+    if (stereo->horizontal_field_of_view.num && stereo->horizontal_field_of_view.den)
+        av_log(ctx, log_level, ", horizontal_field_of_view: %d/%d", stereo->horizontal_field_of_view.num,
+               stereo->horizontal_field_of_view.den);
 
     if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
         av_log(ctx, log_level, " (inverted)");
diff --git a/libavformat/mov.c b/libavformat/mov.c
index f08fec3fb6..64cd17e770 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -6545,7 +6545,8 @@  static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     MOVStreamContext *sc;
     int size, flags = 0;
     int64_t remaining;
-    uint32_t tag, baseline = 0;
+    uint32_t tag;
+    AVRational baseline = av_make_q(0, 0);
     enum AVStereo3DView view = AV_STEREO3D_VIEW_PACKED;
     enum AVStereo3DPrimaryEye primary_eye = AV_PRIMARY_EYE_NONE;
     AVRational horizontal_disparity_adjustment = { 0, 1 };
@@ -6642,7 +6643,8 @@  static int mov_read_eyes(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             avio_skip(pb, 1); // version
             avio_skip(pb, 3); // flags
 
-            baseline = avio_rb32(pb);
+            baseline.num = avio_rb32(pb);
+            baseline.den = 1000000; // micrometers
 
             break;
         }
@@ -6782,7 +6784,8 @@  static int mov_read_hfov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             return AVERROR(ENOMEM);
     }
 
-    sc->stereo3d->horizontal_field_of_view = avio_rb32(pb);
+    sc->stereo3d->horizontal_field_of_view.num = avio_rb32(pb);
+    sc->stereo3d->horizontal_field_of_view.den = 1000; // thousands of a degree
 
     return 0;
 }
diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
index 00a5c3900e..097f6c9455 100644
--- a/libavutil/stereo3d.h
+++ b/libavutil/stereo3d.h
@@ -213,9 +213,9 @@  typedef struct AVStereo3D {
 
     /**
      * The distance between the centres of the lenses of the camera system,
-     * in micrometers. Zero if unset.
+     * in meters. Zero if unset.
      */
-    uint32_t baseline;
+    AVRational baseline;
 
     /**
      * Relative shift of the left and right images, which changes the zero parallax plane.
@@ -224,9 +224,9 @@  typedef struct AVStereo3D {
     AVRational horizontal_disparity_adjustment;
 
     /**
-     * Horizontal field of view in thousanths of a degree. Zero if unset.
+     * Horizontal field of view, in degrees. Zero if unset.
      */
-    uint32_t horizontal_field_of_view;
+    AVRational horizontal_field_of_view;
 } AVStereo3D;
 
 /**
diff --git a/tests/ref/fate/matroska-spherical-mono b/tests/ref/fate/matroska-spherical-mono
index b108596350..87f10cd879 100644
--- a/tests/ref/fate/matroska-spherical-mono
+++ b/tests/ref/fate/matroska-spherical-mono
@@ -5,9 +5,9 @@  type=2D
 inverted=0
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [SIDE_DATA]
 side_data_type=Spherical Mapping
diff --git a/tests/ref/fate/matroska-spherical-mono-remux b/tests/ref/fate/matroska-spherical-mono-remux
index eec41b77f3..1239013185 100644
--- a/tests/ref/fate/matroska-spherical-mono-remux
+++ b/tests/ref/fate/matroska-spherical-mono-remux
@@ -29,9 +29,9 @@  type=2D
 inverted=0
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [SIDE_DATA]
 side_data_type=Spherical Mapping
@@ -58,9 +58,9 @@  type=2D
 inverted=0
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [SIDE_DATA]
 side_data_type=Spherical Mapping
diff --git a/tests/ref/fate/matroska-stereo_mode b/tests/ref/fate/matroska-stereo_mode
index 26c325b20e..46e8563f13 100644
--- a/tests/ref/fate/matroska-stereo_mode
+++ b/tests/ref/fate/matroska-stereo_mode
@@ -134,9 +134,9 @@  type=side by side
 inverted=0
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [/STREAM]
 [STREAM]
@@ -154,9 +154,9 @@  type=top and bottom
 inverted=1
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [/STREAM]
 [STREAM]
@@ -172,9 +172,9 @@  type=interleaved lines
 inverted=1
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [/STREAM]
 [STREAM]
@@ -191,9 +191,9 @@  type=interleaved columns
 inverted=1
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [/STREAM]
 [STREAM]
diff --git a/tests/ref/fate/matroska-vp8-alpha-remux b/tests/ref/fate/matroska-vp8-alpha-remux
index 06bcc4b4ba..ec1ad884b0 100644
--- a/tests/ref/fate/matroska-vp8-alpha-remux
+++ b/tests/ref/fate/matroska-vp8-alpha-remux
@@ -37,8 +37,8 @@  type=2D
 inverted=0
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [/STREAM]
diff --git a/tests/ref/fate/mov-spherical-mono b/tests/ref/fate/mov-spherical-mono
index b108596350..87f10cd879 100644
--- a/tests/ref/fate/mov-spherical-mono
+++ b/tests/ref/fate/mov-spherical-mono
@@ -5,9 +5,9 @@  type=2D
 inverted=0
 view=packed
 primary_eye=none
-baseline=0
+baseline=0/0
 horizontal_disparity_adjustment=0/1
-horizontal_field_of_view=0
+horizontal_field_of_view=0/0
 [/SIDE_DATA]
 [SIDE_DATA]
 side_data_type=Spherical Mapping