tor-browser

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

libdav1d.c (24670B)


      1 /*
      2 * Copyright (c) 2018 Ronald S. Bultje <rsbultje gmail com>
      3 * Copyright (c) 2018 James Almer <jamrial gmail com>
      4 *
      5 * This file is part of FFmpeg.
      6 *
      7 * FFmpeg is free software; you can redistribute it and/or
      8 * modify it under the terms of the GNU Lesser General Public
      9 * License as published by the Free Software Foundation; either
     10 * version 2.1 of the License, or (at your option) any later version.
     11 *
     12 * FFmpeg is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * Lesser General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU Lesser General Public
     18 * License along with FFmpeg; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     20 */
     21 
     22 #include <dav1d/dav1d.h>
     23 
     24 #include "libavutil/avassert.h"
     25 #include "libavutil/cpu.h"
     26 #include "libavutil/film_grain_params.h"
     27 #include "libavutil/hdr_dynamic_metadata.h"
     28 #include "libavutil/mastering_display_metadata.h"
     29 #include "libavutil/imgutils.h"
     30 #include "libavutil/opt.h"
     31 
     32 #include "atsc_a53.h"
     33 #include "av1_parse.h"
     34 #include "avcodec.h"
     35 #include "bytestream.h"
     36 #include "codec_internal.h"
     37 #include "decode.h"
     38 #include "dovi_rpu.h"
     39 #include "internal.h"
     40 #include "itut35.h"
     41 
     42 #define FF_DAV1D_VERSION_AT_LEAST(x,y) \
     43    (DAV1D_API_VERSION_MAJOR > (x) || DAV1D_API_VERSION_MAJOR == (x) && DAV1D_API_VERSION_MINOR >= (y))
     44 
     45 typedef struct Libdav1dContext {
     46    AVClass *class;
     47    Dav1dContext *c;
     48    AVBufferPool *pool;
     49    DOVIContext dovi;
     50    int pool_size;
     51 
     52    Dav1dData data;
     53    int tile_threads;
     54    int frame_threads;
     55    int max_frame_delay;
     56    int apply_grain;
     57    int operating_point;
     58    int all_layers;
     59 } Libdav1dContext;
     60 
     61 static const enum AVPixelFormat pix_fmt[][3] = {
     62    [DAV1D_PIXEL_LAYOUT_I400] = { AV_PIX_FMT_GRAY8,   AV_PIX_FMT_GRAY10,    AV_PIX_FMT_GRAY12 },
     63    [DAV1D_PIXEL_LAYOUT_I420] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12 },
     64    [DAV1D_PIXEL_LAYOUT_I422] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12 },
     65    [DAV1D_PIXEL_LAYOUT_I444] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12 },
     66 };
     67 
     68 static const enum AVPixelFormat pix_fmt_rgb[3] = {
     69    AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12,
     70 };
     71 
     72 static void libdav1d_log_callback(void *opaque, const char *fmt, va_list vl)
     73 {
     74    AVCodecContext *c = opaque;
     75 
     76    av_vlog(c, AV_LOG_ERROR, fmt, vl);
     77 }
     78 
     79 static int libdav1d_picture_allocator(Dav1dPicture *p, void *cookie)
     80 {
     81    Libdav1dContext *dav1d = cookie;
     82    enum AVPixelFormat format = pix_fmt[p->p.layout][p->seq_hdr->hbd];
     83    int ret, linesize[4], h = FFALIGN(p->p.h, 128), w = FFALIGN(p->p.w, 128);
     84    uint8_t *aligned_ptr, *data[4];
     85    AVBufferRef *buf;
     86 
     87    ret = av_image_get_buffer_size(format, w, h, DAV1D_PICTURE_ALIGNMENT);
     88    if (ret < 0)
     89        return ret;
     90 
     91    if (ret != dav1d->pool_size) {
     92        av_buffer_pool_uninit(&dav1d->pool);
     93        // Use twice the amount of required padding bytes for aligned_ptr below.
     94        dav1d->pool = av_buffer_pool_init(ret + DAV1D_PICTURE_ALIGNMENT * 2, NULL);
     95        if (!dav1d->pool) {
     96            dav1d->pool_size = 0;
     97            return AVERROR(ENOMEM);
     98        }
     99        dav1d->pool_size = ret;
    100    }
    101    buf = av_buffer_pool_get(dav1d->pool);
    102    if (!buf)
    103        return AVERROR(ENOMEM);
    104 
    105    // libdav1d requires DAV1D_PICTURE_ALIGNMENT aligned buffers, which av_malloc()
    106    // doesn't guarantee for example when AVX is disabled at configure time.
    107    // Use the extra DAV1D_PICTURE_ALIGNMENT padding bytes in the buffer to align it
    108    // if required.
    109    aligned_ptr = (uint8_t *)FFALIGN((uintptr_t)buf->data, DAV1D_PICTURE_ALIGNMENT);
    110    ret = av_image_fill_arrays(data, linesize, aligned_ptr, format, w, h,
    111                               DAV1D_PICTURE_ALIGNMENT);
    112    if (ret < 0) {
    113        av_buffer_unref(&buf);
    114        return ret;
    115    }
    116 
    117    p->data[0] = data[0];
    118    p->data[1] = data[1];
    119    p->data[2] = data[2];
    120    p->stride[0] = linesize[0];
    121    p->stride[1] = linesize[1];
    122    p->allocator_data = buf;
    123 
    124    return 0;
    125 }
    126 
    127 static void libdav1d_picture_release(Dav1dPicture *p, void *cookie)
    128 {
    129    AVBufferRef *buf = p->allocator_data;
    130 
    131    av_buffer_unref(&buf);
    132 }
    133 
    134 static void libdav1d_init_params(AVCodecContext *c, const Dav1dSequenceHeader *seq)
    135 {
    136    c->profile = seq->profile;
    137    c->level = ((seq->operating_points[0].major_level - 2) << 2)
    138               | seq->operating_points[0].minor_level;
    139 
    140    switch (seq->chr) {
    141    case DAV1D_CHR_VERTICAL:
    142        c->chroma_sample_location = AVCHROMA_LOC_LEFT;
    143        break;
    144    case DAV1D_CHR_COLOCATED:
    145        c->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
    146        break;
    147    }
    148    c->colorspace = (enum AVColorSpace) seq->mtrx;
    149    c->color_primaries = (enum AVColorPrimaries) seq->pri;
    150    c->color_trc = (enum AVColorTransferCharacteristic) seq->trc;
    151    c->color_range = seq->color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
    152 
    153    if (seq->layout == DAV1D_PIXEL_LAYOUT_I444 &&
    154        seq->mtrx == DAV1D_MC_IDENTITY &&
    155        seq->pri  == DAV1D_COLOR_PRI_BT709 &&
    156        seq->trc  == DAV1D_TRC_SRGB)
    157        c->pix_fmt = pix_fmt_rgb[seq->hbd];
    158    else
    159        c->pix_fmt = pix_fmt[seq->layout][seq->hbd];
    160 
    161    c->framerate = ff_av1_framerate(seq->num_ticks_per_picture,
    162                                    (unsigned)seq->num_units_in_tick,
    163                                    (unsigned)seq->time_scale);
    164 
    165 #if FF_API_CODEC_PROPS
    166 FF_DISABLE_DEPRECATION_WARNINGS
    167   if (seq->film_grain_present)
    168       c->properties |= FF_CODEC_PROPERTY_FILM_GRAIN;
    169   else
    170       c->properties &= ~FF_CODEC_PROPERTY_FILM_GRAIN;
    171 FF_ENABLE_DEPRECATION_WARNINGS
    172 #endif
    173 }
    174 
    175 static av_cold int libdav1d_parse_extradata(AVCodecContext *c)
    176 {
    177    Dav1dSequenceHeader seq;
    178    size_t offset = 0;
    179    int res;
    180 
    181    if (!c->extradata || c->extradata_size <= 0)
    182        return 0;
    183 
    184    if (c->extradata[0] & 0x80) {
    185        int version = c->extradata[0] & 0x7F;
    186 
    187        if (version != 1 || c->extradata_size < 4) {
    188            int explode = !!(c->err_recognition & AV_EF_EXPLODE);
    189            av_log(c, explode ? AV_LOG_ERROR : AV_LOG_WARNING,
    190                   "Error decoding extradata\n");
    191            return explode ? AVERROR_INVALIDDATA : 0;
    192        }
    193 
    194        // Do nothing if there are no configOBUs to parse
    195        if (c->extradata_size == 4)
    196            return 0;
    197 
    198        offset = 4;
    199    }
    200 
    201    res = dav1d_parse_sequence_header(&seq, c->extradata + offset,
    202                                      c->extradata_size  - offset);
    203    if (res < 0)
    204        return 0; // Assume no seqhdr OBUs are present
    205 
    206    libdav1d_init_params(c, &seq);
    207    res = ff_set_dimensions(c, seq.max_width, seq.max_height);
    208    if (res < 0)
    209        return res;
    210 
    211    return 0;
    212 }
    213 
    214 static av_cold int libdav1d_init(AVCodecContext *c)
    215 {
    216    Libdav1dContext *dav1d = c->priv_data;
    217    Dav1dSettings s;
    218 #if FF_DAV1D_VERSION_AT_LEAST(6,0)
    219    int threads = c->thread_count;
    220 #else
    221    int threads = (c->thread_count ? c->thread_count : av_cpu_count()) * 3 / 2;
    222 #endif
    223    const AVPacketSideData *sd;
    224    int res;
    225 
    226    av_log(c, AV_LOG_VERBOSE, "libdav1d %s\n", dav1d_version());
    227 
    228    dav1d_default_settings(&s);
    229    s.logger.cookie = c;
    230    s.logger.callback = libdav1d_log_callback;
    231    s.allocator.cookie = dav1d;
    232    s.allocator.alloc_picture_callback = libdav1d_picture_allocator;
    233    s.allocator.release_picture_callback = libdav1d_picture_release;
    234    s.frame_size_limit = c->max_pixels;
    235    if (dav1d->apply_grain >= 0)
    236        s.apply_grain = dav1d->apply_grain;
    237    else
    238        s.apply_grain = !(c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
    239 
    240    s.all_layers = dav1d->all_layers;
    241    if (dav1d->operating_point >= 0)
    242        s.operating_point = dav1d->operating_point;
    243 #if FF_DAV1D_VERSION_AT_LEAST(6,2)
    244    s.strict_std_compliance = c->strict_std_compliance > 0;
    245 #endif
    246 
    247 #if FF_DAV1D_VERSION_AT_LEAST(6,0)
    248    if (dav1d->frame_threads || dav1d->tile_threads)
    249        s.n_threads = FFMAX(dav1d->frame_threads, dav1d->tile_threads);
    250    else
    251        s.n_threads = FFMIN(threads, DAV1D_MAX_THREADS);
    252    if (dav1d->max_frame_delay > 0 && (c->flags & AV_CODEC_FLAG_LOW_DELAY))
    253        av_log(c, AV_LOG_WARNING, "Low delay mode requested, forcing max_frame_delay 1\n");
    254    s.max_frame_delay = (c->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : dav1d->max_frame_delay;
    255    av_log(c, AV_LOG_DEBUG, "Using %d threads, %d max_frame_delay\n",
    256           s.n_threads, s.max_frame_delay);
    257 #else
    258    s.n_tile_threads = dav1d->tile_threads
    259                     ? dav1d->tile_threads
    260                     : FFMIN(floor(sqrt(threads)), DAV1D_MAX_TILE_THREADS);
    261    s.n_frame_threads = dav1d->frame_threads
    262                      ? dav1d->frame_threads
    263                      : FFMIN(ceil(threads / s.n_tile_threads), DAV1D_MAX_FRAME_THREADS);
    264    if (dav1d->max_frame_delay > 0)
    265        s.n_frame_threads = FFMIN(s.n_frame_threads, dav1d->max_frame_delay);
    266    av_log(c, AV_LOG_DEBUG, "Using %d frame threads, %d tile threads\n",
    267           s.n_frame_threads, s.n_tile_threads);
    268 #endif
    269 
    270 #if FF_DAV1D_VERSION_AT_LEAST(6,8)
    271    if (c->skip_frame >= AVDISCARD_NONKEY)
    272        s.decode_frame_type = DAV1D_DECODEFRAMETYPE_KEY;
    273    else if (c->skip_frame >= AVDISCARD_NONINTRA)
    274        s.decode_frame_type = DAV1D_DECODEFRAMETYPE_INTRA;
    275    else if (c->skip_frame >= AVDISCARD_NONREF)
    276        s.decode_frame_type = DAV1D_DECODEFRAMETYPE_REFERENCE;
    277 #endif
    278 
    279    res = libdav1d_parse_extradata(c);
    280    if (res < 0)
    281        return res;
    282 
    283    res = dav1d_open(&dav1d->c, &s);
    284    if (res < 0)
    285        return AVERROR(ENOMEM);
    286 
    287 #if FF_DAV1D_VERSION_AT_LEAST(6,7)
    288    res = dav1d_get_frame_delay(&s);
    289    if (res < 0) // Should not happen
    290        return AVERROR_EXTERNAL;
    291 
    292    // When dav1d_get_frame_delay() returns 1, there's no delay whatsoever
    293    c->delay = res > 1 ? res : 0;
    294 #endif
    295 
    296    dav1d->dovi.logctx = c;
    297    dav1d->dovi.cfg.dv_profile = 10; // default for AV1
    298    sd = ff_get_coded_side_data(c, AV_PKT_DATA_DOVI_CONF);
    299    if (sd && sd->size >= sizeof(dav1d->dovi.cfg))
    300        dav1d->dovi.cfg = *(AVDOVIDecoderConfigurationRecord *) sd->data;
    301    return 0;
    302 }
    303 
    304 static void libdav1d_flush(AVCodecContext *c)
    305 {
    306    Libdav1dContext *dav1d = c->priv_data;
    307 
    308    dav1d_data_unref(&dav1d->data);
    309    dav1d_flush(dav1d->c);
    310 }
    311 
    312 static void libdav1d_data_free(const uint8_t *data, void *opaque) {
    313    AVBufferRef *buf = opaque;
    314 
    315    av_buffer_unref(&buf);
    316 }
    317 
    318 static void libdav1d_user_data_free(const uint8_t *data, void *opaque) {
    319    AVPacket *pkt = opaque;
    320    av_assert0(data == opaque);
    321    av_packet_free(&pkt);
    322 }
    323 
    324 static int libdav1d_receive_frame_internal(AVCodecContext *c, Dav1dPicture *p)
    325 {
    326    Libdav1dContext *dav1d = c->priv_data;
    327    Dav1dData *data = &dav1d->data;
    328    int res;
    329 
    330    if (!data->sz) {
    331        AVPacket *pkt = av_packet_alloc();
    332 
    333        if (!pkt)
    334            return AVERROR(ENOMEM);
    335 
    336        res = ff_decode_get_packet(c, pkt);
    337        if (res < 0 && res != AVERROR_EOF) {
    338            av_packet_free(&pkt);
    339            return res;
    340        }
    341 
    342        if (pkt->size) {
    343            res = dav1d_data_wrap(data, pkt->data, pkt->size,
    344                                  libdav1d_data_free, pkt->buf);
    345            if (res < 0) {
    346                av_packet_free(&pkt);
    347                return res;
    348            }
    349 
    350            pkt->buf = NULL;
    351 
    352            res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt,
    353                                            libdav1d_user_data_free, pkt);
    354            if (res < 0) {
    355                av_packet_free(&pkt);
    356                dav1d_data_unref(data);
    357                return res;
    358            }
    359            pkt = NULL;
    360        } else {
    361            av_packet_free(&pkt);
    362            if (res >= 0)
    363                return AVERROR(EAGAIN);
    364        }
    365    }
    366 
    367    res = dav1d_send_data(dav1d->c, data);
    368    if (res < 0) {
    369        if (res == AVERROR(EINVAL))
    370            res = AVERROR_INVALIDDATA;
    371        if (res != AVERROR(EAGAIN)) {
    372            dav1d_data_unref(data);
    373            return res;
    374        }
    375    }
    376 
    377    res = dav1d_get_picture(dav1d->c, p);
    378    if (res < 0) {
    379        if (res == AVERROR(EINVAL)) {
    380            dav1d_data_unref(data);
    381            res = AVERROR_INVALIDDATA;
    382        } else if (res == AVERROR(EAGAIN))
    383            res = c->internal->draining ? AVERROR_EOF : 1;
    384    }
    385 
    386    return res;
    387 }
    388 
    389 static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame)
    390 {
    391    Libdav1dContext *dav1d = c->priv_data;
    392    Dav1dPicture pic = { 0 }, *p = &pic;
    393    const AVPacket *pkt;
    394 #if FF_DAV1D_VERSION_AT_LEAST(5,1)
    395    enum Dav1dEventFlags event_flags = 0;
    396 #endif
    397    int res;
    398 
    399    do {
    400        res = libdav1d_receive_frame_internal(c, p);
    401    } while (res > 0);
    402 
    403    if (res < 0)
    404        return res;
    405 
    406    av_assert0(p->data[0] && p->allocator_data);
    407 
    408    // This requires the custom allocator above
    409    frame->buf[0] = av_buffer_ref(p->allocator_data);
    410    if (!frame->buf[0]) {
    411        dav1d_picture_unref(p);
    412        return AVERROR(ENOMEM);
    413    }
    414 
    415    frame->data[0] = p->data[0];
    416    frame->data[1] = p->data[1];
    417    frame->data[2] = p->data[2];
    418    frame->linesize[0] = p->stride[0];
    419    frame->linesize[1] = p->stride[1];
    420    frame->linesize[2] = p->stride[1];
    421 
    422 #if FF_DAV1D_VERSION_AT_LEAST(5,1)
    423    dav1d_get_event_flags(dav1d->c, &event_flags);
    424    if (c->pix_fmt == AV_PIX_FMT_NONE ||
    425        event_flags & DAV1D_EVENT_FLAG_NEW_SEQUENCE)
    426 #endif
    427    libdav1d_init_params(c, p->seq_hdr);
    428    res = ff_decode_frame_props(c, frame);
    429    if (res < 0)
    430        goto fail;
    431 
    432    frame->width = p->p.w;
    433    frame->height = p->p.h;
    434    if (c->width != p->p.w || c->height != p->p.h) {
    435        res = ff_set_dimensions(c, p->p.w, p->p.h);
    436        if (res < 0)
    437            goto fail;
    438    }
    439 
    440    av_reduce(&frame->sample_aspect_ratio.num,
    441              &frame->sample_aspect_ratio.den,
    442              frame->height * (int64_t)p->frame_hdr->render_width,
    443              frame->width  * (int64_t)p->frame_hdr->render_height,
    444              INT_MAX);
    445    ff_set_sar(c, frame->sample_aspect_ratio);
    446 
    447    pkt = (const AVPacket *)p->m.user_data.data;
    448 
    449    // match timestamps and packet size
    450    res = ff_decode_frame_props_from_pkt(c, frame, pkt);
    451    if (res < 0)
    452        goto fail;
    453 
    454    frame->pkt_dts = pkt->pts;
    455    if (p->frame_hdr->frame_type == DAV1D_FRAME_TYPE_KEY)
    456        frame->flags |= AV_FRAME_FLAG_KEY;
    457    else
    458        frame->flags &= ~AV_FRAME_FLAG_KEY;
    459 
    460    switch (p->frame_hdr->frame_type) {
    461    case DAV1D_FRAME_TYPE_KEY:
    462    case DAV1D_FRAME_TYPE_INTRA:
    463        frame->pict_type = AV_PICTURE_TYPE_I;
    464        break;
    465    case DAV1D_FRAME_TYPE_INTER:
    466        frame->pict_type = AV_PICTURE_TYPE_P;
    467        break;
    468    case DAV1D_FRAME_TYPE_SWITCH:
    469        frame->pict_type = AV_PICTURE_TYPE_SP;
    470        break;
    471    default:
    472        res = AVERROR_INVALIDDATA;
    473        goto fail;
    474    }
    475 
    476    if (p->mastering_display) {
    477        AVMasteringDisplayMetadata *mastering;
    478 
    479        res = ff_decode_mastering_display_new(c, frame, &mastering);
    480        if (res < 0)
    481            goto fail;
    482 
    483        if (mastering) {
    484            for (int i = 0; i < 3; i++) {
    485                mastering->display_primaries[i][0] = av_make_q(p->mastering_display->primaries[i][0], 1 << 16);
    486                mastering->display_primaries[i][1] = av_make_q(p->mastering_display->primaries[i][1], 1 << 16);
    487            }
    488            mastering->white_point[0] = av_make_q(p->mastering_display->white_point[0], 1 << 16);
    489            mastering->white_point[1] = av_make_q(p->mastering_display->white_point[1], 1 << 16);
    490 
    491            mastering->max_luminance = av_make_q(p->mastering_display->max_luminance, 1 << 8);
    492            mastering->min_luminance = av_make_q(p->mastering_display->min_luminance, 1 << 14);
    493 
    494            mastering->has_primaries = 1;
    495            mastering->has_luminance = 1;
    496        }
    497    }
    498    if (p->content_light) {
    499        AVContentLightMetadata *light;
    500 
    501        res = ff_decode_content_light_new(c, frame, &light);
    502        if (res < 0)
    503            goto fail;
    504 
    505        if (light) {
    506            light->MaxCLL = p->content_light->max_content_light_level;
    507            light->MaxFALL = p->content_light->max_frame_average_light_level;
    508        }
    509    }
    510    if (p->itut_t35) {
    511 #if FF_DAV1D_VERSION_AT_LEAST(6,9)
    512        for (size_t i = 0; i < p->n_itut_t35; i++) {
    513            const Dav1dITUTT35 *itut_t35 = &p->itut_t35[i];
    514 #else
    515        const Dav1dITUTT35 *itut_t35 = p->itut_t35;
    516 #endif
    517        GetByteContext gb;
    518        int provider_code;
    519 
    520        bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);
    521 
    522        provider_code = bytestream2_get_be16(&gb);
    523        switch (provider_code) {
    524        case ITU_T_T35_PROVIDER_CODE_ATSC: {
    525            uint32_t user_identifier = bytestream2_get_be32(&gb);
    526            switch (user_identifier) {
    527            case MKBETAG('G', 'A', '9', '4'): { // closed captions
    528                AVBufferRef *buf = NULL;
    529 
    530                res = ff_parse_a53_cc(&buf, gb.buffer, bytestream2_get_bytes_left(&gb));
    531                if (res < 0)
    532                    goto fail;
    533                if (!res)
    534                    break;
    535 
    536                res = ff_frame_new_side_data_from_buf(c, frame, AV_FRAME_DATA_A53_CC, &buf);
    537                if (res < 0)
    538                    goto fail;
    539 
    540 #if FF_API_CODEC_PROPS
    541 FF_DISABLE_DEPRECATION_WARNINGS
    542                c->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
    543 FF_ENABLE_DEPRECATION_WARNINGS
    544 #endif
    545                break;
    546            }
    547            default: // ignore unsupported identifiers
    548                break;
    549            }
    550            break;
    551        }
    552        case ITU_T_T35_PROVIDER_CODE_SMTPE: {
    553            AVDynamicHDRPlus *hdrplus;
    554            int provider_oriented_code = bytestream2_get_be16(&gb);
    555            int application_identifier = bytestream2_get_byte(&gb);
    556 
    557            if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||
    558                provider_oriented_code != 1 || application_identifier != 4)
    559                break;
    560 
    561            hdrplus = av_dynamic_hdr_plus_create_side_data(frame);
    562            if (!hdrplus) {
    563                res = AVERROR(ENOMEM);
    564                goto fail;
    565            }
    566 
    567            res = av_dynamic_hdr_plus_from_t35(hdrplus, gb.buffer,
    568                                               bytestream2_get_bytes_left(&gb));
    569            if (res < 0)
    570                goto fail;
    571            break;
    572        }
    573        case ITU_T_T35_PROVIDER_CODE_DOLBY: {
    574            int provider_oriented_code = bytestream2_get_be32(&gb);
    575            if (itut_t35->country_code != ITU_T_T35_COUNTRY_CODE_US ||
    576                provider_oriented_code != 0x800)
    577                break;
    578 
    579            res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer,
    580                                    c->err_recognition);
    581            if (res < 0) {
    582                av_log(c, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
    583                break; // ignore
    584            }
    585 
    586            res = ff_dovi_attach_side_data(&dav1d->dovi, frame);
    587            if (res < 0)
    588                goto fail;
    589            break;
    590        }
    591        default: // ignore unsupported provider codes
    592            break;
    593        }
    594 #if FF_DAV1D_VERSION_AT_LEAST(6,9)
    595        }
    596 #endif
    597    }
    598    if (p->frame_hdr->film_grain.present && (!dav1d->apply_grain ||
    599        (c->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN))) {
    600        AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame);
    601        const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(frame->format);
    602        av_assert0(pixdesc);
    603        if (!fgp) {
    604            res = AVERROR(ENOMEM);
    605            goto fail;
    606        }
    607 
    608        fgp->type = AV_FILM_GRAIN_PARAMS_AV1;
    609        fgp->seed = p->frame_hdr->film_grain.data.seed;
    610        fgp->width = frame->width;
    611        fgp->height = frame->height;
    612        fgp->color_range = frame->color_range;
    613        fgp->color_primaries = frame->color_primaries;
    614        fgp->color_trc = frame->color_trc;
    615        fgp->color_space = frame->colorspace;
    616        fgp->subsampling_x = pixdesc->log2_chroma_w;
    617        fgp->subsampling_y = pixdesc->log2_chroma_h;
    618        fgp->codec.aom.num_y_points = p->frame_hdr->film_grain.data.num_y_points;
    619        fgp->codec.aom.chroma_scaling_from_luma = p->frame_hdr->film_grain.data.chroma_scaling_from_luma;
    620        fgp->codec.aom.scaling_shift = p->frame_hdr->film_grain.data.scaling_shift;
    621        fgp->codec.aom.ar_coeff_lag = p->frame_hdr->film_grain.data.ar_coeff_lag;
    622        fgp->codec.aom.ar_coeff_shift = p->frame_hdr->film_grain.data.ar_coeff_shift;
    623        fgp->codec.aom.grain_scale_shift = p->frame_hdr->film_grain.data.grain_scale_shift;
    624        fgp->codec.aom.overlap_flag = p->frame_hdr->film_grain.data.overlap_flag;
    625        fgp->codec.aom.limit_output_range = p->frame_hdr->film_grain.data.clip_to_restricted_range;
    626 
    627        memcpy(&fgp->codec.aom.y_points, &p->frame_hdr->film_grain.data.y_points,
    628               sizeof(fgp->codec.aom.y_points));
    629        memcpy(&fgp->codec.aom.num_uv_points, &p->frame_hdr->film_grain.data.num_uv_points,
    630               sizeof(fgp->codec.aom.num_uv_points));
    631        memcpy(&fgp->codec.aom.uv_points, &p->frame_hdr->film_grain.data.uv_points,
    632               sizeof(fgp->codec.aom.uv_points));
    633        memcpy(&fgp->codec.aom.ar_coeffs_y, &p->frame_hdr->film_grain.data.ar_coeffs_y,
    634               sizeof(fgp->codec.aom.ar_coeffs_y));
    635        memcpy(&fgp->codec.aom.ar_coeffs_uv[0], &p->frame_hdr->film_grain.data.ar_coeffs_uv[0],
    636               sizeof(fgp->codec.aom.ar_coeffs_uv[0]));
    637        memcpy(&fgp->codec.aom.ar_coeffs_uv[1], &p->frame_hdr->film_grain.data.ar_coeffs_uv[1],
    638               sizeof(fgp->codec.aom.ar_coeffs_uv[1]));
    639        memcpy(&fgp->codec.aom.uv_mult, &p->frame_hdr->film_grain.data.uv_mult,
    640               sizeof(fgp->codec.aom.uv_mult));
    641        memcpy(&fgp->codec.aom.uv_mult_luma, &p->frame_hdr->film_grain.data.uv_luma_mult,
    642               sizeof(fgp->codec.aom.uv_mult_luma));
    643        memcpy(&fgp->codec.aom.uv_offset, &p->frame_hdr->film_grain.data.uv_offset,
    644               sizeof(fgp->codec.aom.uv_offset));
    645    }
    646 
    647    res = 0;
    648 fail:
    649    dav1d_picture_unref(p);
    650    if (res < 0)
    651        av_frame_unref(frame);
    652    return res;
    653 }
    654 
    655 static av_cold int libdav1d_close(AVCodecContext *c)
    656 {
    657    Libdav1dContext *dav1d = c->priv_data;
    658 
    659    av_buffer_pool_uninit(&dav1d->pool);
    660    ff_dovi_ctx_unref(&dav1d->dovi);
    661    dav1d_data_unref(&dav1d->data);
    662    dav1d_close(&dav1d->c);
    663 
    664    return 0;
    665 }
    666 
    667 #ifndef DAV1D_MAX_FRAME_THREADS
    668 #define DAV1D_MAX_FRAME_THREADS DAV1D_MAX_THREADS
    669 #endif
    670 #ifndef DAV1D_MAX_TILE_THREADS
    671 #define DAV1D_MAX_TILE_THREADS DAV1D_MAX_THREADS
    672 #endif
    673 #ifndef DAV1D_MAX_FRAME_DELAY
    674 #define DAV1D_MAX_FRAME_DELAY DAV1D_MAX_FRAME_THREADS
    675 #endif
    676 
    677 #define OFFSET(x) offsetof(Libdav1dContext, x)
    678 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
    679 static const AVOption libdav1d_options[] = {
    680    { "tilethreads", "Tile threads", OFFSET(tile_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_TILE_THREADS, VD | AV_OPT_FLAG_DEPRECATED },
    681    { "framethreads", "Frame threads", OFFSET(frame_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_FRAME_THREADS, VD | AV_OPT_FLAG_DEPRECATED },
    682    { "max_frame_delay", "Max frame delay", OFFSET(max_frame_delay), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, DAV1D_MAX_FRAME_DELAY, VD },
    683    { "filmgrain", "Apply Film Grain", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD | AV_OPT_FLAG_DEPRECATED },
    684    { "oppoint",  "Select an operating point of the scalable bitstream", OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 31, VD },
    685    { "alllayers", "Output all spatial layers", OFFSET(all_layers), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
    686    { NULL }
    687 };
    688 
    689 static const AVClass libdav1d_class = {
    690    .class_name = "libdav1d decoder",
    691    .item_name  = av_default_item_name,
    692    .option     = libdav1d_options,
    693    .version    = LIBAVUTIL_VERSION_INT,
    694 };
    695 
    696 const FFCodec ff_libdav1d_decoder = {
    697    .p.name         = "libdav1d",
    698    CODEC_LONG_NAME("dav1d AV1 decoder by VideoLAN"),
    699    .p.type         = AVMEDIA_TYPE_VIDEO,
    700    .p.id           = AV_CODEC_ID_AV1,
    701    .priv_data_size = sizeof(Libdav1dContext),
    702    .init           = libdav1d_init,
    703    .close          = libdav1d_close,
    704    .flush          = libdav1d_flush,
    705    FF_CODEC_RECEIVE_FRAME_CB(libdav1d_receive_frame),
    706    .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_OTHER_THREADS,
    707    .caps_internal  = FF_CODEC_CAP_SETS_FRAME_PROPS |
    708                      FF_CODEC_CAP_AUTO_THREADS,
    709    .p.priv_class   = &libdav1d_class,
    710    .p.wrapper_name = "libdav1d",
    711 };