From 0fadc89e86cf1750dfb0d3dee7f59dba08b4b2e9 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Wed, 13 Mar 2019 00:48:09 +0000 Subject: [PATCH] multimedia/ffmpeg: backport fixes for libdav1d --- multimedia/ffmpeg/Makefile | 2 +- multimedia/ffmpeg/files/patch-dav1d | 143 ++++++++++++++++++++++++---- 2 files changed, 128 insertions(+), 17 deletions(-) diff --git a/multimedia/ffmpeg/Makefile b/multimedia/ffmpeg/Makefile index 754712fc9821..12f5a0db870d 100644 --- a/multimedia/ffmpeg/Makefile +++ b/multimedia/ffmpeg/Makefile @@ -3,7 +3,7 @@ PORTNAME= ffmpeg PORTVERSION= 4.1.1 -PORTREVISION= 6 +PORTREVISION= 7 PORTEPOCH= 1 CATEGORIES= multimedia audio ipv6 net MASTER_SITES= https://ffmpeg.org/releases/ diff --git a/multimedia/ffmpeg/files/patch-dav1d b/multimedia/ffmpeg/files/patch-dav1d index be546d43e2ec..f9feef0eee97 100644 --- a/multimedia/ffmpeg/files/patch-dav1d +++ b/multimedia/ffmpeg/files/patch-dav1d @@ -7,6 +7,12 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/0fca2f60da https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/e695b0beba https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/0e833f615b https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 +https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/dcf64b599d +https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/2a31bf2a35 +https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/28746a0e20 +https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/36bb2cc200 +https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/38a4132132 +https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/f6803cfbd2 --- configure.orig 2018-11-05 23:22:33 UTC +++ configure @@ -38,7 +44,7 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2 -+enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.0.1" "dav1d/dav1d.h" dav1d_version ++enabled libdav1d && require_pkg_config libdav1d "dav1d >= 0.2.1" "dav1d/dav1d.h" dav1d_version enabled libdavs2 && require_pkg_config libdavs2 "davs2 >= 1.5.115" davs2.h davs2_decoder_open enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new enabled libdrm && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion @@ -77,7 +83,7 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 extern AVCodec ff_libfdk_aac_decoder; --- libavcodec/libdav1d.c.orig 2018-12-16 07:22:28 UTC +++ libavcodec/libdav1d.c -@@ -0,0 +1,251 @@ +@@ -0,0 +1,356 @@ +/* + * Copyright (c) 2018 Ronald S. Bultje + * Copyright (c) 2018 James Almer @@ -102,6 +108,8 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 +#include + +#include "libavutil/avassert.h" ++#include "libavutil/mastering_display_metadata.h" ++#include "libavutil/imgutils.h" +#include "libavutil/opt.h" + +#include "avcodec.h" @@ -111,12 +119,81 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 +typedef struct Libdav1dContext { + AVClass *class; + Dav1dContext *c; ++ AVBufferPool *pool; ++ int pool_size; + + Dav1dData data; + int tile_threads; + int apply_grain; +} Libdav1dContext; + ++static const enum AVPixelFormat pix_fmt[][3] = { ++ [DAV1D_PIXEL_LAYOUT_I400] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12 }, ++ [DAV1D_PIXEL_LAYOUT_I420] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12 }, ++ [DAV1D_PIXEL_LAYOUT_I422] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12 }, ++ [DAV1D_PIXEL_LAYOUT_I444] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12 }, ++}; ++ ++static void libdav1d_log_callback(void *opaque, const char *fmt, va_list vl) ++{ ++ AVCodecContext *c = opaque; ++ ++ av_vlog(c, AV_LOG_ERROR, fmt, vl); ++} ++ ++static int libdav1d_picture_allocator(Dav1dPicture *p, void *cookie) ++{ ++ Libdav1dContext *dav1d = cookie; ++ enum AVPixelFormat format = pix_fmt[p->p.layout][p->seq_hdr->hbd]; ++ int ret, linesize[4], h = FFALIGN(p->p.h, 128); ++ uint8_t *aligned_ptr, *data[4]; ++ AVBufferRef *buf; ++ ++ ret = av_image_fill_arrays(data, linesize, NULL, format, FFALIGN(p->p.w, 128), ++ h, DAV1D_PICTURE_ALIGNMENT); ++ if (ret < 0) ++ return ret; ++ ++ if (ret != dav1d->pool_size) { ++ av_buffer_pool_uninit(&dav1d->pool); ++ // Use twice the amount of required padding bytes for aligned_ptr below. ++ dav1d->pool = av_buffer_pool_init(ret + DAV1D_PICTURE_ALIGNMENT * 2, NULL); ++ if (!dav1d->pool) ++ return AVERROR(ENOMEM); ++ dav1d->pool_size = ret; ++ } ++ buf = av_buffer_pool_get(dav1d->pool); ++ if (!buf) ++ return AVERROR(ENOMEM); ++ ++ // libdav1d requires DAV1D_PICTURE_ALIGNMENT aligned buffers, which av_malloc() ++ // doesn't guarantee for example when AVX is disabled at configure time. ++ // Use the extra DAV1D_PICTURE_ALIGNMENT padding bytes in the buffer to align it ++ // if required. ++ aligned_ptr = (uint8_t *)FFALIGN((uintptr_t)buf->data, DAV1D_PICTURE_ALIGNMENT); ++ ret = av_image_fill_pointers(data, format, h, aligned_ptr, linesize); ++ if (ret < 0) { ++ av_buffer_unref(&buf); ++ return ret; ++ } ++ ++ p->data[0] = data[0]; ++ p->data[1] = data[1]; ++ p->data[2] = data[2]; ++ p->stride[0] = linesize[0]; ++ p->stride[1] = linesize[1]; ++ p->allocator_data = buf; ++ ++ return 0; ++} ++ ++static void libdav1d_picture_release(Dav1dPicture *p, void *cookie) ++{ ++ AVBufferRef *buf = p->allocator_data; ++ ++ av_buffer_unref(&buf); ++} ++ +static av_cold int libdav1d_init(AVCodecContext *c) +{ + Libdav1dContext *dav1d = c->priv_data; @@ -126,6 +203,11 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 + av_log(c, AV_LOG_INFO, "libdav1d %s\n", dav1d_version()); + + dav1d_default_settings(&s); ++ s.logger.cookie = c; ++ s.logger.callback = libdav1d_log_callback; ++ s.allocator.cookie = dav1d; ++ s.allocator.alloc_picture_callback = libdav1d_picture_allocator; ++ s.allocator.release_picture_callback = libdav1d_picture_release; + s.n_tile_threads = dav1d->tile_threads; + s.apply_grain = dav1d->apply_grain; + s.n_frame_threads = FFMIN(c->thread_count ? c->thread_count : av_cpu_count(), DAV1D_MAX_FRAME_THREADS); @@ -158,13 +240,6 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 + av_free(p); +} + -+static const enum AVPixelFormat pix_fmt[][3] = { -+ [DAV1D_PIXEL_LAYOUT_I400] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12 }, -+ [DAV1D_PIXEL_LAYOUT_I420] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV420P12 }, -+ [DAV1D_PIXEL_LAYOUT_I422] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P12 }, -+ [DAV1D_PIXEL_LAYOUT_I444] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12 }, -+}; -+ +static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) +{ + Libdav1dContext *dav1d = c->priv_data; @@ -197,9 +272,9 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 + + res = dav1d_send_data(dav1d->c, data); + if (res < 0) { -+ if (res == -EINVAL) ++ if (res == AVERROR(EINVAL)) + res = AVERROR_INVALIDDATA; -+ if (res != -EAGAIN) ++ if (res != AVERROR(EAGAIN)) + return res; + } + @@ -209,9 +284,9 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 + + res = dav1d_get_picture(dav1d->c, p); + if (res < 0) { -+ if (res == -EINVAL) ++ if (res == AVERROR(EINVAL)) + res = AVERROR_INVALIDDATA; -+ else if (res == -EAGAIN && c->internal->draining) ++ else if (res == AVERROR(EAGAIN) && c->internal->draining) + res = AVERROR_EOF; + + av_free(p); @@ -242,7 +317,7 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 + if (c->width != p->p.w || c->height != p->p.h) { + res = ff_set_dimensions(c, p->p.w, p->p.h); + if (res < 0) -+ return res; ++ goto fail; + } + + switch (p->seq_hdr->chr) { @@ -283,16 +358,52 @@ https://git.ffmpeg.org/gitweb/ffmpeg.git/commitdiff/10931a0661 + frame->pict_type = AV_PICTURE_TYPE_SP; + break; + default: -+ return AVERROR_INVALIDDATA; ++ res = AVERROR_INVALIDDATA; ++ goto fail; + } + -+ return 0; ++ if (p->mastering_display) { ++ AVMasteringDisplayMetadata *mastering = av_mastering_display_metadata_create_side_data(frame); ++ if (!mastering) { ++ res = AVERROR(ENOMEM); ++ goto fail; ++ } ++ ++ for (int i = 0; i < 3; i++) { ++ mastering->display_primaries[i][0] = av_make_q(p->mastering_display->primaries[i][0], 1 << 16); ++ mastering->display_primaries[i][1] = av_make_q(p->mastering_display->primaries[i][1], 1 << 16); ++ } ++ mastering->white_point[0] = av_make_q(p->mastering_display->white_point[0], 1 << 16); ++ mastering->white_point[1] = av_make_q(p->mastering_display->white_point[1], 1 << 16); ++ ++ mastering->max_luminance = av_make_q(p->mastering_display->max_luminance, 1 << 8); ++ mastering->min_luminance = av_make_q(p->mastering_display->min_luminance, 1 << 14); ++ ++ mastering->has_primaries = 1; ++ mastering->has_luminance = 1; ++ } ++ if (p->content_light) { ++ AVContentLightMetadata *light = av_content_light_metadata_create_side_data(frame); ++ if (!light) { ++ res = AVERROR(ENOMEM); ++ goto fail; ++ } ++ light->MaxCLL = p->content_light->max_content_light_level; ++ light->MaxFALL = p->content_light->max_frame_average_light_level; ++ } ++ ++ res = 0; ++fail: ++ if (res < 0) ++ av_frame_unref(frame); ++ return res; +} + +static av_cold int libdav1d_close(AVCodecContext *c) +{ + Libdav1dContext *dav1d = c->priv_data; + ++ av_buffer_pool_uninit(&dav1d->pool); + dav1d_data_unref(&dav1d->data); + dav1d_close(&dav1d->c); +