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 };