[FFmpeg-devel] [PATCH] Update HDR10+ metadata structure.

James Almer jamrial at gmail.com
Tue Feb 4 04:06:57 EET 2020


On 2/3/2020 11:01 PM, Mohammad Izadi wrote:
> James, I am making another CL to comply with API.
> I have a question about using GetBitContext and PutBitContext. Is there any
> alternative to use in libavutil?

You can use it in libavutil as long as it's not part of the public API.
So you should make the new public functions take size_t and uint8_t*
parameters, then use get/putbits internally in the implementation if needed.

Also, all public functions must use an av_ prefix.

> --
> Best,
> Mohammad
> 
> 
> On Mon, Jan 27, 2020 at 11:50 AM James Almer <jamrial at gmail.com> wrote:
> 
>> On 1/27/2020 4:08 PM, Mohammad Izadi wrote:
>>> From: Mohammad Izadi <izadi at google.com>
>>>
>>> Trying to read HDR10+ metadata from HEVC/SEI and pass it to packet side
>> data in the follow-up CLs.
>>> ---
>>>  libavutil/hdr_dynamic_metadata.c | 386 +++++++++++++++++++++++++++++++
>>>  libavutil/hdr_dynamic_metadata.h |  51 +++-
>>>  libavutil/version.h              |   2 +-
>>>  3 files changed, 431 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/libavutil/hdr_dynamic_metadata.c
>> b/libavutil/hdr_dynamic_metadata.c
>>> index 0fa1ee82de..e321a22af8 100644
>>> --- a/libavutil/hdr_dynamic_metadata.c
>>> +++ b/libavutil/hdr_dynamic_metadata.c
>>> @@ -21,6 +21,19 @@
>>>  #include "hdr_dynamic_metadata.h"
>>>  #include "mem.h"
>>>
>>> +static const uint8_t usa_country_code = 0xB5;
>>> +static const uint16_t smpte_provider_code = 0x003C;
>>> +static const uint16_t smpte2094_40_provider_oriented_code = 0x0001;
>>> +static const uint16_t smpte2094_40_application_identifier = 0x04;
>>> +
>>> +static const int64_t luminance_den = 1;
>>> +static const int32_t peak_luminance_den = 15;
>>> +static const int64_t rgb_den = 100000;
>>> +static const int32_t fraction_pixel_den = 1000;
>>> +static const int32_t knee_point_den = 4095;
>>> +static const int32_t bezier_anchor_den = 1023;
>>> +static const int32_t saturation_weight_den = 8;
>>> +
>>>  AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size)
>>>  {
>>>      AVDynamicHDRPlus *hdr_plus = av_mallocz(sizeof(AVDynamicHDRPlus));
>>> @@ -33,6 +46,48 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t
>> *size)
>>>      return hdr_plus;
>>>  }
>>>
>>> +AVDynamicHDRPlus *av_dynamic_hdr_plus(GetBitContext *gb, size_t *size)
>>> +{
>>> +    uint8_t country_code;
>>> +    uint16_t provider_code;
>>> +    uint16_t provider_oriented_code;
>>> +    uint8_t application_identifier;
>>> +    uint8_t application_version;
>>> +    AVDynamicHDRPlus *hdr_plus;
>>> +    int err;
>>> +
>>> +    if (get_bits_left(gb) < 7)
>>> +        return NULL;
>>> +
>>> +    country_code = get_bits(gb, 8);
>>> +    provider_code = get_bits(gb, 16);
>>> +
>>> +    if (country_code != usa_country_code ||
>>> +        provider_code != smpte_provider_code)
>>> +        return NULL;
>>> +
>>> +    // A/341 Amendment – 2094-40
>>> +    provider_oriented_code = get_bits(gb, 16);
>>> +    application_identifier = get_bits(gb, 8);
>>> +    application_version  = get_bits(gb, 8);
>>> +    if (provider_oriented_code != smpte2094_40_provider_oriented_code ||
>>> +        application_identifier != smpte2094_40_application_identifier)
>>> +        return NULL;
>>> +
>>> +    hdr_plus = av_dynamic_hdr_plus_alloc(size);
>>> +    if (!hdr_plus)
>>> +        return NULL;
>>> +
>>> +    hdr_plus->application_version = application_version;
>>> +    err = decode_itu_t_t35_to_dynamic_hdr_plus(gb, hdr_plus);
>>> +    if (err < 0) {
>>> +        av_freep(&hdr_plus);
>>> +        return NULL;
>>> +    }
>>> +
>>> +    return hdr_plus;
>>> +}
>>> +
>>>  AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
>>>  {
>>>      AVFrameSideData *side_data = av_frame_new_side_data(frame,
>>> @@ -43,5 +98,336 @@ AVDynamicHDRPlus
>> *av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
>>>
>>>      memset(side_data->data, 0, sizeof(AVDynamicHDRPlus));
>>>
>>> +
>>>      return (AVDynamicHDRPlus *)side_data->data;
>>>  }
>>> +
>>> +int decode_itu_t_t35_to_dynamic_hdr_plus(GetBitContext *gb,
>> AVDynamicHDRPlus *s)
>>> +{
>>> +    int w, i, j;
>>> +
>>> +    if (get_bits_left(gb) < 2)
>>> +        return AVERROR_INVALIDDATA;
>>> +    s->num_windows = get_bits(gb, 2);
>>> +
>>> +    if (s->num_windows < 1 || s->num_windows > 3) {
>>> +        return AVERROR_INVALIDDATA;
>>> +    }
>>> +
>>> +    if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
>>> +        return AVERROR_INVALIDDATA;
>>> +    for (w = 1; w < s->num_windows; w++) {
>>> +        s->params[w].window_upper_left_corner_x.num = get_bits(gb, 16);
>>> +        s->params[w].window_upper_left_corner_y.num = get_bits(gb, 16);
>>> +        s->params[w].window_lower_right_corner_x.num = get_bits(gb, 16);
>>> +        s->params[w].window_lower_right_corner_y.num = get_bits(gb, 16);
>>> +        // The corners are set to absolute coordinates here. They
>> should be
>>> +        // converted to the relative coordinates (in [0, 1]) in the
>> decoder.
>>> +        s->params[w].window_upper_left_corner_x.den = 1;
>>> +        s->params[w].window_upper_left_corner_y.den = 1;
>>> +        s->params[w].window_lower_right_corner_x.den = 1;
>>> +        s->params[w].window_lower_right_corner_y.den = 1;
>>> +
>>> +        s->params[w].center_of_ellipse_x = get_bits(gb, 16);
>>> +        s->params[w].center_of_ellipse_y = get_bits(gb, 16);
>>> +        s->params[w].rotation_angle = get_bits(gb, 8);
>>> +        s->params[w].semimajor_axis_internal_ellipse = get_bits(gb, 16);
>>> +        s->params[w].semimajor_axis_external_ellipse = get_bits(gb, 16);
>>> +        s->params[w].semiminor_axis_external_ellipse = get_bits(gb, 16);
>>> +        s->params[w].overlap_process_option = get_bits1(gb);
>>> +    }
>>> +
>>> +    if (get_bits_left(gb) < 28)
>>> +        return AVERROR(EINVAL);
>>> +    s->targeted_system_display_maximum_luminance.num = get_bits(gb, 27);
>>> +    s->targeted_system_display_maximum_luminance.den = luminance_den;
>>> +    s->targeted_system_display_actual_peak_luminance_flag =
>> get_bits1(gb);
>>> +
>>> +    if (s->targeted_system_display_actual_peak_luminance_flag) {
>>> +        int rows, cols;
>>> +        if (get_bits_left(gb) < 10)
>>> +            return AVERROR(EINVAL);
>>> +        rows = get_bits(gb, 5);
>>> +        cols = get_bits(gb, 5);
>>> +        if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25)))
>> {
>>> +            return AVERROR_INVALIDDATA;
>>> +        }
>>> +        s->num_rows_targeted_system_display_actual_peak_luminance =
>> rows;
>>> +        s->num_cols_targeted_system_display_actual_peak_luminance =
>> cols;
>>> +
>>> +        if (get_bits_left(gb) < (rows * cols * 4))
>>> +            return AVERROR(EINVAL);
>>> +
>>> +        for (i = 0; i < rows; i++) {
>>> +            for (j = 0; j < cols; j++) {
>>> +
>> s->targeted_system_display_actual_peak_luminance[i][j].num = get_bits(gb,
>> 4);
>>> +
>> s->targeted_system_display_actual_peak_luminance[i][j].den =
>> peak_luminance_den;
>>> +            }
>>> +        }
>>> +    }
>>> +    for (w = 0; w < s->num_windows; w++) {
>>> +        if (get_bits_left(gb) < (3 * 17 + 17 + 4))
>>> +            return AVERROR(EINVAL);
>>> +        for (i = 0; i < 3; i++) {
>>> +            s->params[w].maxscl[i].num = get_bits(gb, 17);
>>> +            s->params[w].maxscl[i].den = rgb_den;
>>> +        }
>>> +        s->params[w].average_maxrgb.num = get_bits(gb, 17);
>>> +        s->params[w].average_maxrgb.den = rgb_den;
>>> +        s->params[w].num_distribution_maxrgb_percentiles = get_bits(gb,
>> 4);
>>> +
>>> +        if (get_bits_left(gb) <
>>> +            (s->params[w].num_distribution_maxrgb_percentiles * 24))
>>> +            return AVERROR(EINVAL);
>>> +        for (i = 0; i <
>> s->params[w].num_distribution_maxrgb_percentiles; i++) {
>>> +            s->params[w].distribution_maxrgb[i].percentage =
>> get_bits(gb, 7);
>>> +            s->params[w].distribution_maxrgb[i].percentile.num =
>> get_bits(gb, 17);
>>> +            s->params[w].distribution_maxrgb[i].percentile.den =
>> rgb_den;
>>> +        }
>>> +
>>> +        if (get_bits_left(gb) < 10)
>>> +            return AVERROR(EINVAL);
>>> +        s->params[w].fraction_bright_pixels.num = get_bits(gb, 10);
>>> +        s->params[w].fraction_bright_pixels.den = fraction_pixel_den;
>>> +    }
>>> +    if (get_bits_left(gb) < 1)
>>> +        return AVERROR(EINVAL);
>>> +    s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
>>> +    if (s->mastering_display_actual_peak_luminance_flag) {
>>> +        int rows, cols;
>>> +        if (get_bits_left(gb) < 10)
>>> +            return AVERROR(EINVAL);
>>> +        rows = get_bits(gb, 5);
>>> +        cols = get_bits(gb, 5);
>>> +        if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25)))
>> {
>>> +            return AVERROR_INVALIDDATA;
>>> +        }
>>> +        s->num_rows_mastering_display_actual_peak_luminance = rows;
>>> +        s->num_cols_mastering_display_actual_peak_luminance = cols;
>>> +
>>> +        if (get_bits_left(gb) < (rows * cols * 4))
>>> +            return AVERROR(EINVAL);
>>> +
>>> +        for (i = 0; i < rows; i++) {
>>> +            for (j = 0; j < cols; j++) {
>>> +                s->mastering_display_actual_peak_luminance[i][j].num =
>> get_bits(gb, 4);
>>> +                s->mastering_display_actual_peak_luminance[i][j].den =
>> peak_luminance_den;
>>> +            }
>>> +        }
>>> +    }
>>> +
>>> +    for (w = 0; w < s->num_windows; w++) {
>>> +        if (get_bits_left(gb) < 1)
>>> +            return AVERROR(EINVAL);
>>> +        s->params[w].tone_mapping_flag = get_bits1(gb);
>>> +        if (s->params[w].tone_mapping_flag) {
>>> +            if (get_bits_left(gb) < 28)
>>> +                return AVERROR(EINVAL);
>>> +            s->params[w].knee_point_x.num = get_bits(gb, 12);
>>> +            s->params[w].knee_point_x.den = knee_point_den;
>>> +            s->params[w].knee_point_y.num = get_bits(gb, 12);
>>> +            s->params[w].knee_point_y.den = knee_point_den;
>>> +            s->params[w].num_bezier_curve_anchors = get_bits(gb, 4);
>>> +
>>> +            if (get_bits_left(gb) <
>> (s->params[w].num_bezier_curve_anchors * 10))
>>> +                return AVERROR(EINVAL);
>>> +            for (i = 0; i < s->params[w].num_bezier_curve_anchors; i++)
>> {
>>> +                s->params[w].bezier_curve_anchors[i].num = get_bits(gb,
>> 10);
>>> +                s->params[w].bezier_curve_anchors[i].den =
>> bezier_anchor_den;
>>> +            }
>>> +        }
>>> +
>>> +        if (get_bits_left(gb) < 1)
>>> +            return AVERROR(EINVAL);
>>> +        s->params[w].color_saturation_mapping_flag = get_bits1(gb);
>>> +        if (s->params[w].color_saturation_mapping_flag) {
>>> +            if (get_bits_left(gb) < 6)
>>> +                return AVERROR(EINVAL);
>>> +            s->params[w].color_saturation_weight.num = get_bits(gb, 6);
>>> +            s->params[w].color_saturation_weight.den =
>> saturation_weight_den;
>>> +        }
>>> +    }
>>> +
>>> +    skip_bits(gb, get_bits_left(gb));
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +int get_encoded_dynamic_hdr_plus_buffer_size(const AVDynamicHDRPlus *s)
>> {
>>> +    int bit_count = 0;
>>> +    int w, size;
>>> +
>>> +    if (!s)
>>> +        return 0;
>>> +
>>> +    // 7 bytes for country code, provider code, and user identifier.
>>> +    bit_count += 56;
>>> +
>>> +    if (s->num_windows < 1 || s->num_windows > 3)
>>> +        return 0;
>>> +    // Count bits for window params.
>>> +    bit_count += 2 + ((19 * 8 + 1) * (s->num_windows - 1));
>>> +
>>> +    bit_count += 28;
>>> +    if (s->targeted_system_display_actual_peak_luminance_flag) {
>>> +        int rows, cols;
>>> +        rows =
>> s->num_rows_targeted_system_display_actual_peak_luminance;
>>> +        cols =
>> s->num_rows_targeted_system_display_actual_peak_luminance;
>>> +        if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25)))
>>> +            return 0;
>>> +
>>> +        bit_count += (10 + rows * cols * 4);
>>> +    }
>>> +    for (w = 0; w < s->num_windows; w++) {
>>> +        bit_count += (3 * 17 + 17 + 4 + 10) +
>>> +                     (s->params[w].num_distribution_maxrgb_percentiles
>> * 24);
>>> +    }
>>> +    bit_count++;
>>> +
>>> +    if (s->mastering_display_actual_peak_luminance_flag) {
>>> +        int rows, cols;
>>> +        rows = s->num_rows_mastering_display_actual_peak_luminance;
>>> +        cols = s->num_cols_mastering_display_actual_peak_luminance;
>>> +        if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25)))
>>> +            return 0;
>>> +
>>> +        bit_count += (10 + rows * cols * 4);
>>> +    }
>>> +
>>> +    for (w = 0; w < s->num_windows; w++) {
>>> +        bit_count++;
>>> +        if (s->params[w].tone_mapping_flag)
>>> +            bit_count += (28 + s->params[w].num_bezier_curve_anchors *
>> 10);
>>> +
>>> +        bit_count++;
>>> +        if (s->params[w].color_saturation_mapping_flag)
>>> +            bit_count += 6;
>>> +    }
>>> +    size = bit_count / 8;
>>> +    if (bit_count % 8 != 0)
>>> +        size++;
>>> +    return size;
>>> +}
>>> +
>>> +int encode_dynamic_hdr_plus_to_itu_t_t35(const AVDynamicHDRPlus *s,
>> PutBitContext *pb)
>>> +{
>>> +    int w, i, j;
>>> +    if (!s)
>>> +        return AVERROR(EINVAL);
>>> +
>>> +    if (put_bits_left(pb) < get_encoded_dynamic_hdr_plus_buffer_size(s))
>>> +        return AVERROR(EINVAL);
>>> +    put_bits(pb, 8, usa_country_code);
>>> +
>>> +    put_bits(pb, 16, smpte_provider_code);
>>> +    put_bits(pb, 16, smpte2094_40_provider_oriented_code);
>>> +    put_bits(pb, 8, smpte2094_40_application_identifier);
>>> +    put_bits(pb, 8, s->application_version);
>>> +
>>> +    put_bits(pb, 2, s->num_windows);
>>> +
>>> +    for (w = 1; w < s->num_windows; w++) {
>>> +        put_bits(pb, 16, s->params[w].window_upper_left_corner_x.num /
>>> +            s->params[w].window_upper_left_corner_x.den);
>>> +        put_bits(pb, 16, s->params[w].window_upper_left_corner_y.num /
>>> +            s->params[w].window_upper_left_corner_y.den);
>>> +        put_bits(pb, 16, s->params[w].window_lower_right_corner_x.num /
>>> +            s->params[w].window_lower_right_corner_x.den);
>>> +        put_bits(pb, 16, s->params[w].window_lower_right_corner_y.num /
>>> +            s->params[w].window_lower_right_corner_y.den);
>>> +        put_bits(pb, 16, s->params[w].center_of_ellipse_x);
>>> +        put_bits(pb, 16, s->params[w].center_of_ellipse_y);
>>> +        put_bits(pb, 8, s->params[w].rotation_angle);
>>> +        put_bits(pb, 16, s->params[w].semimajor_axis_internal_ellipse);
>>> +        put_bits(pb, 16, s->params[w].semimajor_axis_external_ellipse);
>>> +        put_bits(pb, 16, s->params[w].semiminor_axis_external_ellipse);
>>> +        put_bits(pb, 1, s->params[w].overlap_process_option);
>>> +    }
>>> +    put_bits(pb, 27,
>>> +             s->targeted_system_display_maximum_luminance.num *
>> luminance_den /
>>> +                 s->targeted_system_display_maximum_luminance.den);
>>> +    put_bits(pb, 1,
>> s->targeted_system_display_actual_peak_luminance_flag);
>>> +    if (s->targeted_system_display_actual_peak_luminance_flag) {
>>> +        int rows, cols;
>>> +        rows =
>> s->num_rows_targeted_system_display_actual_peak_luminance;
>>> +        cols =
>> s->num_cols_targeted_system_display_actual_peak_luminance;
>>> +        put_bits(pb, 5, rows);
>>> +        put_bits(pb, 5, cols);
>>> +        for (i = 0; i < rows; i++) {
>>> +            for (j = 0; j < cols; j++) {
>>> +              put_bits(
>>> +                  pb, 4,
>>> +
>> s->targeted_system_display_actual_peak_luminance[i][j].num *
>>> +                      peak_luminance_den /
>>> +
>> s->targeted_system_display_actual_peak_luminance[i][j]
>>> +                          .den);
>>> +            }
>>> +        }
>>> +    }
>>> +    for (w = 0; w < s->num_windows; w++) {
>>> +        for (i = 0; i < 3; i++) {
>>> +          put_bits(pb, 17,
>>> +                   s->params[w].maxscl[i].num * rgb_den /
>>> +                       s->params[w].maxscl[i].den);
>>> +        }
>>> +        put_bits(pb, 17,
>>> +                 s->params[w].average_maxrgb.num * rgb_den /
>>> +                     s->params[w].average_maxrgb.den);
>>> +        put_bits(pb, 4,
>> s->params[w].num_distribution_maxrgb_percentiles);
>>> +
>>> +        for (i = 0; i <
>> s->params[w].num_distribution_maxrgb_percentiles; i++) {
>>> +            put_bits(pb, 7,
>> s->params[w].distribution_maxrgb[i].percentage);
>>> +            put_bits(pb, 17,
>>> +                     s->params[w].distribution_maxrgb[i].percentile.num
>> *
>>> +                         rgb_den /
>>> +
>>  s->params[w].distribution_maxrgb[i].percentile.den);
>>> +        }
>>> +        put_bits(pb, 10,
>>> +                 s->params[w].fraction_bright_pixels.num *
>> fraction_pixel_den /
>>> +                     s->params[w].fraction_bright_pixels.den);
>>> +    }
>>> +    put_bits(pb, 1, s->mastering_display_actual_peak_luminance_flag);
>>> +    if (s->mastering_display_actual_peak_luminance_flag) {
>>> +        int rows, cols;
>>> +        rows = s->num_rows_mastering_display_actual_peak_luminance;
>>> +        cols = s->num_cols_mastering_display_actual_peak_luminance;
>>> +        put_bits(pb, 5, rows);
>>> +        put_bits(pb, 5, cols);
>>> +        for (i = 0; i < rows; i++) {
>>> +            for (j = 0; j < cols; j++) {
>>> +              put_bits(
>>> +                  pb, 4,
>>> +                  s->mastering_display_actual_peak_luminance[i][j].num *
>>> +                      peak_luminance_den /
>>> +
>> s->mastering_display_actual_peak_luminance[i][j].den);
>>> +            }
>>> +        }
>>> +    }
>>> +
>>> +    for (w = 0; w < s->num_windows; w++) {
>>> +        put_bits(pb, 1, s->params[w].tone_mapping_flag);
>>> +        if (s->params[w].tone_mapping_flag) {
>>> +          put_bits(pb, 12,
>>> +                   s->params[w].knee_point_x.num * knee_point_den /
>>> +                       s->params[w].knee_point_x.den);
>>> +          put_bits(pb, 12,
>>> +                   s->params[w].knee_point_y.num * knee_point_den /
>>> +                       s->params[w].knee_point_y.den);
>>> +          put_bits(pb, 4, s->params[w].num_bezier_curve_anchors);
>>> +          for (i = 0; i < s->params[w].num_bezier_curve_anchors; i++) {
>>> +            put_bits(pb, 10,
>>> +                     s->params[w].bezier_curve_anchors[i].num *
>>> +                         bezier_anchor_den /
>>> +                         s->params[w].bezier_curve_anchors[i].den);
>>> +            }
>>> +        }
>>> +        put_bits(pb, 1, s->params[w].color_saturation_mapping_flag);
>>> +        if (s->params[w].color_saturation_mapping_flag)
>>> +          put_bits(pb, 6,
>>> +                   s->params[w].color_saturation_weight.num *
>>> +                       saturation_weight_den /
>>> +                       s->params[w].color_saturation_weight.den);
>>> +    }
>>> +    flush_put_bits(pb);
>>> +    return 0;
>>> +}
>>> diff --git a/libavutil/hdr_dynamic_metadata.h
>> b/libavutil/hdr_dynamic_metadata.h
>>> index 2d72de56ae..4e075f2f58 100644
>>> --- a/libavutil/hdr_dynamic_metadata.h
>>> +++ b/libavutil/hdr_dynamic_metadata.h
>>> @@ -23,6 +23,8 @@
>>>
>>>  #include "frame.h"
>>>  #include "rational.h"
>>> +#include "libavcodec/get_bits.h"
>>> +#include "libavcodec/put_bits.h"
>>>
>>>  /**
>>>   * Option for overlapping elliptical pixel selectors in an image.
>>> @@ -241,11 +243,6 @@ typedef struct AVHDRPlusColorTransformParams {
>>>   * the public ABI.
>>>   */
>>>  typedef struct AVDynamicHDRPlus {
>>> -    /**
>>> -     * Country code by Rec. ITU-T T.35 Annex A. The value shall be 0xB5.
>>> -     */
>>> -    uint8_t itu_t_t35_country_code;
>>
>> This is an API break.
>>
>>> -
>>>      /**
>>>       * Application version in the application defining document in
>> ST-2094
>>>       * suite. The value shall be set to 0.
>>> @@ -265,7 +262,7 @@ typedef struct AVDynamicHDRPlus {
>>>
>>>      /**
>>>       * The nominal maximum display luminance of the targeted system
>> display,
>>> -     * in units of 0.0001 candelas per square metre. The value shall be
>> in
>>> +     * in units of 1 candelas per square metre. The value shall be in
>>>       * the range of 0 to 10000, inclusive.
>>>       */
>>>      AVRational targeted_system_display_maximum_luminance;
>>> @@ -322,14 +319,27 @@ typedef struct AVDynamicHDRPlus {
>>>      AVRational mastering_display_actual_peak_luminance[25][25];
>>>  } AVDynamicHDRPlus;
>>>
>>> +/**
>>> + * Allocate an AVDynamicHDRPlus structure and set its fields to
>>> + * the values decoded from the user data registered ITU-T T.35.
>>> + * The resulting struct can be freed using av_freep().
>>> + *
>>> + * @return An AVDynamicHDRPlus filled with decoded values or NULL
>>> + *         on failure.
>>> + */
>>> +AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size);
>>> +
>>>  /**
>>>   * Allocate an AVDynamicHDRPlus structure and set its fields to
>>>   * default values. The resulting struct can be freed using av_freep().
>>> + * @param gb The input bit stream.
>>> + * @param size The size of allocated memory for the returned
>>> + *        AVDynamicHDRPlus structure.
>>>   *
>>>   * @return An AVDynamicHDRPlus filled with default values or NULL
>>>   *         on failure.
>>>   */
>>> -AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size);
>>> +AVDynamicHDRPlus *av_dynamic_hdr_plus(GetBitContext *gb, size_t *size);
>>
>> As is this. Also, GetBitContext and PutBitContext are internal structs
>> to libavcodec, and can't be used in public headers.
>>
>>>
>>>  /**
>>>   * Allocate a complete AVDynamicHDRPlus and add it to the frame.
>>> @@ -340,4 +350,31 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t
>> *size);
>>>   */
>>>  AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame);
>>>
>>> +/**
>>> + * Decode the user data registered ITU-T T.35 to AVDynamicHDRPlus.
>>> + * @param gb The bit content to be decoded.
>>> + * @param s The decoded AVDynamicHDRPlus structure.
>>> + *
>>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>>> + */
>>> +int decode_itu_t_t35_to_dynamic_hdr_plus(GetBitContext *gb,
>> AVDynamicHDRPlus *s);
>>> +
>>> +/**
>>> + * Get the size of buffer required to save the encoded bit stream of
>>> + * AVDynamicHDRPlus in the form of the user data registered ITU-T T.35.
>>> + * @param s The AVDynamicHDRPlus structure.
>>> + *
>>> + * @return The size of bit stream required for encoding. 0 if the data
>> is invalid.
>>> + */
>>> +int get_encoded_dynamic_hdr_plus_buffer_size(const AVDynamicHDRPlus *s);
>>> +
>>> +/**
>>> + * Encode AVDynamicHDRPlus to the user data registered ITU-T T.35.
>>> + * @param s The AVDynamicHDRPlus structure to be encoded.
>>> + * @param pb The encoded bit stream.
>>> + *
>>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>>> + */
>>> +int encode_dynamic_hdr_plus_to_itu_t_t35(const AVDynamicHDRPlus *s,
>> PutBitContext *pb);
>>> +
>>>  #endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */
>>> diff --git a/libavutil/version.h b/libavutil/version.h
>>> index af8f614aff..2bc1b98615 100644
>>> --- a/libavutil/version.h
>>> +++ b/libavutil/version.h
>>> @@ -79,7 +79,7 @@
>>>   */
>>>
>>>  #define LIBAVUTIL_VERSION_MAJOR  56
>>> -#define LIBAVUTIL_VERSION_MINOR  38
>>> +#define LIBAVUTIL_VERSION_MINOR  39
>>>  #define LIBAVUTIL_VERSION_MICRO 100
>>>
>>>  #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR,
>> \
>>>
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel at ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
> 



More information about the ffmpeg-devel mailing list