tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hdr_dynamic_metadata.c (15755B)


      1 /**
      2 * Copyright (c) 2018 Mohammad Izadi <moh.izadi at gmail.com>
      3 *
      4 * This file is part of FFmpeg.
      5 *
      6 * FFmpeg is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * FFmpeg is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with FFmpeg; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     19 */
     20 
     21 #include "avassert.h"
     22 #include "hdr_dynamic_metadata.h"
     23 #include "mem.h"
     24 #include "libavcodec/defs.h"
     25 #include "libavcodec/get_bits.h"
     26 #include "libavcodec/put_bits.h"
     27 
     28 static const int64_t luminance_den = 1;
     29 static const int32_t peak_luminance_den = 15;
     30 static const int64_t rgb_den = 100000;
     31 static const int32_t fraction_pixel_den = 1000;
     32 static const int32_t knee_point_den = 4095;
     33 static const int32_t bezier_anchor_den = 1023;
     34 static const int32_t saturation_weight_den = 8;
     35 
     36 AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size)
     37 {
     38    AVDynamicHDRPlus *hdr_plus = av_mallocz(sizeof(AVDynamicHDRPlus));
     39    if (!hdr_plus)
     40        return NULL;
     41 
     42    if (size)
     43        *size = sizeof(*hdr_plus);
     44 
     45    return hdr_plus;
     46 }
     47 
     48 AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
     49 {
     50    AVFrameSideData *side_data = av_frame_new_side_data(frame,
     51                                                        AV_FRAME_DATA_DYNAMIC_HDR_PLUS,
     52                                                        sizeof(AVDynamicHDRPlus));
     53    if (!side_data)
     54        return NULL;
     55 
     56    memset(side_data->data, 0, sizeof(AVDynamicHDRPlus));
     57 
     58    return (AVDynamicHDRPlus *)side_data->data;
     59 }
     60 
     61 int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data,
     62                                 size_t size)
     63 {
     64    uint8_t padded_buf[AV_HDR_PLUS_MAX_PAYLOAD_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
     65    GetBitContext gbc, *gb = &gbc;
     66    int ret;
     67 
     68    if (!s)
     69        return AVERROR(ENOMEM);
     70 
     71    if (size > AV_HDR_PLUS_MAX_PAYLOAD_SIZE)
     72        return AVERROR(EINVAL);
     73 
     74    memcpy(padded_buf, data, size);
     75    // Zero-initialize the buffer padding to avoid overreads into uninitialized data.
     76    memset(padded_buf + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
     77 
     78    ret = init_get_bits8(gb, padded_buf, size);
     79    if (ret < 0)
     80        return ret;
     81 
     82    if (get_bits_left(gb) < 10)
     83        return AVERROR_INVALIDDATA;
     84 
     85    s->application_version = get_bits(gb, 8);
     86    s->num_windows = get_bits(gb, 2);
     87 
     88    if (s->num_windows < 1 || s->num_windows > 3) {
     89        return AVERROR_INVALIDDATA;
     90    }
     91 
     92    if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
     93        return AVERROR_INVALIDDATA;
     94 
     95    for (int w = 1; w < s->num_windows; w++) {
     96        // The corners are set to absolute coordinates here. They should be
     97        // converted to the relative coordinates (in [0, 1]) in the decoder.
     98        AVHDRPlusColorTransformParams *params = &s->params[w];
     99        params->window_upper_left_corner_x =
    100            (AVRational){get_bits(gb, 16), 1};
    101        params->window_upper_left_corner_y =
    102            (AVRational){get_bits(gb, 16), 1};
    103        params->window_lower_right_corner_x =
    104            (AVRational){get_bits(gb, 16), 1};
    105        params->window_lower_right_corner_y =
    106            (AVRational){get_bits(gb, 16), 1};
    107 
    108        params->center_of_ellipse_x = get_bits(gb, 16);
    109        params->center_of_ellipse_y = get_bits(gb, 16);
    110        params->rotation_angle = get_bits(gb, 8);
    111        params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
    112        params->semimajor_axis_external_ellipse = get_bits(gb, 16);
    113        params->semiminor_axis_external_ellipse = get_bits(gb, 16);
    114        params->overlap_process_option = get_bits1(gb);
    115    }
    116 
    117    if (get_bits_left(gb) < 28)
    118        return AVERROR_INVALIDDATA;
    119 
    120    s->targeted_system_display_maximum_luminance =
    121        (AVRational){get_bits_long(gb, 27), luminance_den};
    122    s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
    123 
    124    if (s->targeted_system_display_actual_peak_luminance_flag) {
    125        int rows, cols;
    126        if (get_bits_left(gb) < 10)
    127            return AVERROR_INVALIDDATA;
    128        rows = get_bits(gb, 5);
    129        cols = get_bits(gb, 5);
    130        if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
    131            return AVERROR_INVALIDDATA;
    132        }
    133        s->num_rows_targeted_system_display_actual_peak_luminance = rows;
    134        s->num_cols_targeted_system_display_actual_peak_luminance = cols;
    135 
    136        if (get_bits_left(gb) < (rows * cols * 4))
    137            return AVERROR_INVALIDDATA;
    138 
    139        for (int i = 0; i < rows; i++) {
    140            for (int j = 0; j < cols; j++) {
    141                s->targeted_system_display_actual_peak_luminance[i][j] =
    142                    (AVRational){get_bits(gb, 4), peak_luminance_den};
    143            }
    144        }
    145    }
    146    for (int w = 0; w < s->num_windows; w++) {
    147        AVHDRPlusColorTransformParams *params = &s->params[w];
    148        if (get_bits_left(gb) < (3 * 17 + 17 + 4))
    149            return AVERROR_INVALIDDATA;
    150 
    151        for (int i = 0; i < 3; i++) {
    152            params->maxscl[i] =
    153                (AVRational){get_bits(gb, 17), rgb_den};
    154        }
    155        params->average_maxrgb =
    156            (AVRational){get_bits(gb, 17), rgb_den};
    157        params->num_distribution_maxrgb_percentiles = get_bits(gb, 4);
    158 
    159        if (get_bits_left(gb) <
    160            (params->num_distribution_maxrgb_percentiles * 24))
    161            return AVERROR_INVALIDDATA;
    162 
    163        for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
    164            params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
    165            params->distribution_maxrgb[i].percentile =
    166                (AVRational){get_bits(gb, 17), rgb_den};
    167        }
    168 
    169        if (get_bits_left(gb) < 10)
    170            return AVERROR_INVALIDDATA;
    171 
    172        params->fraction_bright_pixels = (AVRational){get_bits(gb, 10), fraction_pixel_den};
    173    }
    174    if (get_bits_left(gb) < 1)
    175        return AVERROR_INVALIDDATA;
    176    s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
    177    if (s->mastering_display_actual_peak_luminance_flag) {
    178        int rows, cols;
    179        if (get_bits_left(gb) < 10)
    180            return AVERROR_INVALIDDATA;
    181        rows = get_bits(gb, 5);
    182        cols = get_bits(gb, 5);
    183        if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
    184            return AVERROR_INVALIDDATA;
    185        }
    186        s->num_rows_mastering_display_actual_peak_luminance = rows;
    187        s->num_cols_mastering_display_actual_peak_luminance = cols;
    188 
    189        if (get_bits_left(gb) < (rows * cols * 4))
    190            return AVERROR_INVALIDDATA;
    191 
    192        for (int i = 0; i < rows; i++) {
    193            for (int j = 0; j < cols; j++) {
    194                s->mastering_display_actual_peak_luminance[i][j] =
    195                    (AVRational){get_bits(gb, 4), peak_luminance_den};
    196            }
    197        }
    198    }
    199 
    200    for (int w = 0; w < s->num_windows; w++) {
    201        AVHDRPlusColorTransformParams *params = &s->params[w];
    202        if (get_bits_left(gb) < 1)
    203            return AVERROR_INVALIDDATA;
    204 
    205        params->tone_mapping_flag = get_bits1(gb);
    206        if (params->tone_mapping_flag) {
    207            if (get_bits_left(gb) < 28)
    208                return AVERROR_INVALIDDATA;
    209 
    210            params->knee_point_x =
    211                (AVRational){get_bits(gb, 12), knee_point_den};
    212            params->knee_point_y =
    213                (AVRational){get_bits(gb, 12), knee_point_den};
    214            params->num_bezier_curve_anchors = get_bits(gb, 4);
    215 
    216            if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10))
    217                return AVERROR_INVALIDDATA;
    218 
    219            for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
    220                params->bezier_curve_anchors[i] =
    221                    (AVRational){get_bits(gb, 10), bezier_anchor_den};
    222            }
    223        }
    224 
    225        if (get_bits_left(gb) < 1)
    226            return AVERROR_INVALIDDATA;
    227        params->color_saturation_mapping_flag = get_bits1(gb);
    228        if (params->color_saturation_mapping_flag) {
    229            if (get_bits_left(gb) < 6)
    230                return AVERROR_INVALIDDATA;
    231            params->color_saturation_weight =
    232                (AVRational){get_bits(gb, 6), saturation_weight_den};
    233        }
    234    }
    235 
    236    return 0;
    237 }
    238 
    239 int av_dynamic_hdr_plus_to_t35(const AVDynamicHDRPlus *s, uint8_t **data, size_t *size)
    240 {
    241    uint8_t *buf;
    242    size_t size_bits, size_bytes;
    243    PutBitContext pbc, *pb = &pbc;
    244 
    245    if (!s)
    246        return AVERROR(EINVAL);
    247    if ((!data || *data) && !size)
    248       return AVERROR(EINVAL);
    249 
    250    /**
    251     * Buffer size per CTA-861-H p.253-254:
    252     * 48 header bits (excluded from the serialized payload)
    253     * 8 bits for application_mode
    254     * 2 bits for num_windows
    255     * 153 bits for window geometry, for each window above 1
    256     * 27 bits for targeted_system_display_maximum_luminance
    257     * 1-2511 bits for targeted system display peak luminance information
    258     * 82-442 bits per window for pixel distribution information
    259     * 1-2511 bits for mastering display peak luminance information
    260     * 1-179 bits per window for tonemapping information
    261     * 1-7 bits per window for color saturation mapping information
    262     * Total: 123-7249 bits, excluding trimmed header bits
    263     */
    264    size_bits = 8;
    265 
    266    size_bits += 2;
    267 
    268    for (int w = 1; w < s->num_windows; w++)
    269        size_bits += 153;
    270 
    271    size_bits += 27;
    272 
    273    size_bits += 1;
    274    if (s->targeted_system_display_actual_peak_luminance_flag)
    275        size_bits += 10 +
    276                     s->num_rows_targeted_system_display_actual_peak_luminance *
    277                     s->num_cols_targeted_system_display_actual_peak_luminance * 4;
    278 
    279    for (int w = 0; w < s->num_windows; w++)
    280        size_bits += 72 + s->params[w].num_distribution_maxrgb_percentiles * 24 + 10;
    281 
    282    size_bits += 1;
    283    if (s->mastering_display_actual_peak_luminance_flag)
    284        size_bits += 10 +
    285                     s->num_rows_mastering_display_actual_peak_luminance *
    286                     s->num_cols_mastering_display_actual_peak_luminance * 4;
    287 
    288    for (int w = 0; w < s->num_windows; w++) {
    289        size_bits += 1;
    290        if (s->params[w].tone_mapping_flag)
    291            size_bits += 28 + s->params[w].num_bezier_curve_anchors * 10;
    292 
    293        size_bits += 1;
    294        if (s->params[w].color_saturation_mapping_flag)
    295            size_bits += 6;
    296    }
    297 
    298    size_bytes = (size_bits + 7) / 8;
    299 
    300    av_assert0(size_bytes <= AV_HDR_PLUS_MAX_PAYLOAD_SIZE);
    301 
    302    if (!data) {
    303        *size = size_bytes;
    304        return 0;
    305    } else if (*data) {
    306        if (*size < size_bytes)
    307            return AVERROR_BUFFER_TOO_SMALL;
    308        buf = *data;
    309    } else {
    310        buf = av_malloc(size_bytes);
    311        if (!buf)
    312            return AVERROR(ENOMEM);
    313    }
    314 
    315    init_put_bits(pb, buf, size_bytes);
    316 
    317    // application_mode is set to Application Version 1
    318    put_bits(pb, 8, 1);
    319 
    320    // Payload as per CTA-861-H p.253-254
    321    put_bits(pb, 2, s->num_windows);
    322 
    323    for (int w = 1; w < s->num_windows; w++) {
    324        put_bits(pb, 16, s->params[w].window_upper_left_corner_x.num / s->params[w].window_upper_left_corner_x.den);
    325        put_bits(pb, 16, s->params[w].window_upper_left_corner_y.num / s->params[w].window_upper_left_corner_y.den);
    326        put_bits(pb, 16, s->params[w].window_lower_right_corner_x.num / s->params[w].window_lower_right_corner_x.den);
    327        put_bits(pb, 16, s->params[w].window_lower_right_corner_y.num / s->params[w].window_lower_right_corner_y.den);
    328        put_bits(pb, 16, s->params[w].center_of_ellipse_x);
    329        put_bits(pb, 16, s->params[w].center_of_ellipse_y);
    330        put_bits(pb, 8, s->params[w].rotation_angle);
    331        put_bits(pb, 16, s->params[w].semimajor_axis_internal_ellipse);
    332        put_bits(pb, 16, s->params[w].semimajor_axis_external_ellipse);
    333        put_bits(pb, 16, s->params[w].semiminor_axis_external_ellipse);
    334        put_bits(pb, 1, s->params[w].overlap_process_option);
    335    }
    336 
    337    put_bits(pb, 27, s->targeted_system_display_maximum_luminance.num * luminance_den /
    338        s->targeted_system_display_maximum_luminance.den);
    339    put_bits(pb, 1, s->targeted_system_display_actual_peak_luminance_flag);
    340    if (s->targeted_system_display_actual_peak_luminance_flag) {
    341        put_bits(pb, 5, s->num_rows_targeted_system_display_actual_peak_luminance);
    342        put_bits(pb, 5, s->num_cols_targeted_system_display_actual_peak_luminance);
    343        for (int i = 0; i < s->num_rows_targeted_system_display_actual_peak_luminance; i++) {
    344            for (int j = 0; j < s->num_cols_targeted_system_display_actual_peak_luminance; j++)
    345                put_bits(pb, 4, s->targeted_system_display_actual_peak_luminance[i][j].num * peak_luminance_den /
    346                    s->targeted_system_display_actual_peak_luminance[i][j].den);
    347        }
    348    }
    349 
    350    for (int w = 0; w < s->num_windows; w++) {
    351        for (int i = 0; i < 3; i++)
    352            put_bits(pb, 17, s->params[w].maxscl[i].num * rgb_den / s->params[w].maxscl[i].den);
    353        put_bits(pb, 17, s->params[w].average_maxrgb.num * rgb_den / s->params[w].average_maxrgb.den);
    354        put_bits(pb, 4, s->params[w].num_distribution_maxrgb_percentiles);
    355        for (int i = 0; i < s->params[w].num_distribution_maxrgb_percentiles; i++) {
    356            put_bits(pb, 7, s->params[w].distribution_maxrgb[i].percentage);
    357            put_bits(pb, 17, s->params[w].distribution_maxrgb[i].percentile.num * rgb_den /
    358                s->params[w].distribution_maxrgb[i].percentile.den);
    359        }
    360        put_bits(pb, 10, s->params[w].fraction_bright_pixels.num * fraction_pixel_den /
    361            s->params[w].fraction_bright_pixels.den);
    362    }
    363 
    364    put_bits(pb, 1, s->mastering_display_actual_peak_luminance_flag);
    365    if (s->mastering_display_actual_peak_luminance_flag) {
    366        put_bits(pb, 5, s->num_rows_mastering_display_actual_peak_luminance);
    367        put_bits(pb, 5, s->num_cols_mastering_display_actual_peak_luminance);
    368        for (int i = 0; i < s->num_rows_mastering_display_actual_peak_luminance; i++) {
    369            for (int j = 0; j < s->num_cols_mastering_display_actual_peak_luminance; j++)
    370                put_bits(pb, 4, s->mastering_display_actual_peak_luminance[i][j].num * peak_luminance_den /
    371                    s->mastering_display_actual_peak_luminance[i][j].den);
    372        }
    373    }
    374 
    375    for (int w = 0; w < s->num_windows; w++) {
    376        put_bits(pb, 1, s->params[w].tone_mapping_flag);
    377        if (s->params[w].tone_mapping_flag) {
    378            put_bits(pb, 12, s->params[w].knee_point_x.num * knee_point_den / s->params[w].knee_point_x.den);
    379            put_bits(pb, 12, s->params[w].knee_point_y.num * knee_point_den / s->params[w].knee_point_y.den);
    380            put_bits(pb, 4, s->params[w].num_bezier_curve_anchors);
    381            for (int i = 0; i < s->params[w].num_bezier_curve_anchors; i++)
    382                put_bits(pb, 10, s->params[w].bezier_curve_anchors[i].num * bezier_anchor_den /
    383                    s->params[w].bezier_curve_anchors[i].den);
    384            put_bits(pb, 1, s->params[w].color_saturation_mapping_flag);
    385            if (s->params[w].color_saturation_mapping_flag)
    386                put_bits(pb, 6, s->params[w].color_saturation_weight.num * saturation_weight_den /
    387                    s->params[w].color_saturation_weight.den);
    388        }
    389    }
    390 
    391    flush_put_bits(pb);
    392 
    393    *data = buf;
    394    if (size)
    395        *size = size_bytes;
    396    return 0;
    397 }