Update patches for 7.1.1

Signed-off-by: nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
nyanmisaka
2025-04-17 22:34:15 +08:00
parent 2b6eb39e5e
commit 9017eaad8f
96 changed files with 3213 additions and 9945 deletions
+3 -3
View File
@@ -2,7 +2,7 @@ Index: FFmpeg/libavformat/segment.c
===================================================================
--- FFmpeg.orig/libavformat/segment.c
+++ FFmpeg/libavformat/segment.c
@@ -88,6 +88,7 @@ typedef struct SegmentContext {
@@ -89,6 +89,7 @@ typedef struct SegmentContext {
int64_t last_val; ///< remember last time for wrap around detection
int cut_pending;
int header_written; ///< whether we've already called avformat_write_header
@@ -10,7 +10,7 @@ Index: FFmpeg/libavformat/segment.c
char *entry_prefix; ///< prefix to add to list entry filenames
int list_type; ///< set the list type
@@ -707,6 +708,7 @@ static int seg_init(AVFormatContext *s)
@@ -708,6 +709,7 @@ static int seg_init(AVFormatContext *s)
if ((ret = parse_frames(s, &seg->frames, &seg->nb_frames, seg->frames_str)) < 0)
return ret;
} else {
@@ -18,7 +18,7 @@ Index: FFmpeg/libavformat/segment.c
if (seg->use_clocktime) {
if (seg->time <= 0) {
av_log(s, AV_LOG_ERROR, "Invalid negative segment_time with segment_atclocktime option set\n");
@@ -890,7 +892,15 @@ calc_times:
@@ -891,7 +893,15 @@ calc_times:
seg->cut_pending = 1;
seg->last_val = wrapped_val;
} else {
@@ -292,7 +292,7 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
#include "avfilter.h"
+#include "dither_matrix.h"
#include "internal.h"
#include "filters.h"
#include "scale_eval.h"
#include "video.h"
@@ -108,6 +110,9 @@ typedef struct CUDAScaleContext {
@@ -300,8 +300,8 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
float param;
+
+ CUdeviceptr ditherBuffer;
+ CUtexObject ditherTex;
+ CUdeviceptr dither_buffer;
+ CUtexObject dither_tex;
} CUDAScaleContext;
static av_cold int cudascale_init(AVFilterContext *ctx)
@@ -317,13 +317,13 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
CHECK_CU(cu->cuCtxPushCurrent(s->hwctx->cuda_ctx));
- CHECK_CU(cu->cuModuleUnload(s->cu_module));
- s->cu_module = NULL;
+ if (s->ditherTex) {
+ CHECK_CU(cu->cuTexObjectDestroy(s->ditherTex));
+ s->ditherTex = 0;
+ if (s->dither_tex) {
+ CHECK_CU(cu->cuTexObjectDestroy(s->dither_tex));
+ s->dither_tex = 0;
+ }
+ if (s->ditherBuffer) {
+ CHECK_CU(cu->cuMemFree(s->ditherBuffer));
+ s->ditherBuffer = 0;
+ if (s->dither_buffer) {
+ CHECK_CU(cu->cuMemFree(s->dither_buffer));
+ s->dither_buffer = 0;
+ }
+ if (s->cu_module) {
+ CHECK_CU(cu->cuModuleUnload(s->cu_module));
@@ -332,7 +332,7 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
CHECK_CU(cu->cuCtxPopCurrent(&dummy));
}
@@ -273,6 +288,67 @@ static av_cold int init_processing_chain
@@ -275,6 +290,68 @@ static av_cold int init_processing_chain
return 0;
}
@@ -340,7 +340,8 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
+{
+ CUDAScaleContext *s = ctx->priv;
+ AVFilterLink *inlink = ctx->inputs[0];
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ FilterLink *inl = ff_filter_link(inlink);
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ AVCUDADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
+ CudaFunctions *cu = device_hwctx->internal->cuda_dl;
+ CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
@@ -381,15 +382,15 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
+ if ((ret = CHECK_CU(cu->cuCtxPushCurrent(cuda_ctx))) < 0)
+ return ret;
+
+ if ((ret = CHECK_CU(cu->cuMemAlloc(&s->ditherBuffer, sizeof(ff_fruit_dither_matrix)))) < 0)
+ if ((ret = CHECK_CU(cu->cuMemAlloc(&s->dither_buffer, sizeof(ff_fruit_dither_matrix)))) < 0)
+ goto fail;
+
+ res_desc.res.pitch2D.devPtr = cpy.dstDevice = s->ditherBuffer;
+ res_desc.res.pitch2D.devPtr = cpy.dstDevice = s->dither_buffer;
+
+ if ((ret = CHECK_CU(cu->cuMemcpy2D(&cpy))) < 0)
+ goto fail;
+
+ if ((ret = CHECK_CU(cu->cuTexObjectCreate(&s->ditherTex, &res_desc, &tex_desc, NULL))) < 0)
+ if ((ret = CHECK_CU(cu->cuTexObjectCreate(&s->dither_tex, &res_desc, &tex_desc, NULL))) < 0)
+ goto fail;
+
+fail:
@@ -400,9 +401,9 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
static av_cold int cudascale_load_functions(AVFilterContext *ctx)
{
CUDAScaleContext *s = ctx->priv;
@@ -377,6 +453,11 @@ static av_cold int cudascale_config_prop
if (ret < 0)
return ret;
@@ -383,6 +460,11 @@ static av_cold int cudascale_config_prop
s->hwctx = device_hwctx;
s->cu_stream = s->hwctx->stream;
+ if (s->in_desc->comp[0].depth > s->out_desc->comp[0].depth) {
+ if ((ret = cudascale_setup_dither(ctx)) < 0)
@@ -412,7 +413,7 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
if (inlink->sample_aspect_ratio.num) {
outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
outlink->w*inlink->h},
@@ -412,11 +493,15 @@ static int call_resize_kernel(AVFilterCo
@@ -418,11 +500,15 @@ static int call_resize_kernel(AVFilterCo
(CUdeviceptr)out_frame->data[2], (CUdeviceptr)out_frame->data[3]
};
@@ -425,11 +426,11 @@ Index: FFmpeg/libavfilter/vf_scale_cuda.c
&dst_width, &dst_height, &dst_pitch,
- &src_width, &src_height, &s->param
+ &src_width, &src_height, &s->param,
+ &s->ditherTex, &dither_size, &dither_quantization
+ &s->dither_tex, &dither_size, &dither_quantization
};
return CHECK_CU(cu->cuLaunchKernel(func,
@@ -440,6 +525,7 @@ static int scalecuda_resize(AVFilterCont
@@ -446,6 +532,7 @@ static int scalecuda_resize(AVFilterCont
for (i = 0; i < s->in_planes; i++) {
CUDA_TEXTURE_DESC tex_desc = {
+219 -64
View File
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3291,6 +3291,8 @@ scale_cuda_filter_deps="ffnvcodec"
@@ -3312,6 +3312,8 @@ scale_cuda_filter_deps="ffnvcodec"
scale_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
thumbnail_cuda_filter_deps="ffnvcodec"
thumbnail_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
@@ -11,25 +11,31 @@ Index: FFmpeg/configure
transpose_npp_filter_deps="ffnvcodec libnpp"
overlay_cuda_filter_deps="ffnvcodec"
overlay_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
@@ -4082,7 +4084,7 @@ enable doc
enable faan faandct faanidct
enable large_tests
enable optimizations
-enable ptx_compression
+disable ptx_compression
enable runtime_cpudetect
enable safe_bitstream_reader
enable static
@@ -4630,7 +4632,7 @@ if enabled cuda_nvcc; then
@@ -4690,8 +4692,10 @@ if enabled cuda_nvcc; then
nvcc_default="nvcc"
nvccflags_default="-gencode arch=compute_30,code=sm_30 -O2"
else
+ # clang-20 emits ptx60 instruction 'brx.idx' even for ptx32 target (llvm/llvm-project@ccc3127)
+ # default to ptx60/sm_30 to follow the changes made in clang-16+ (llvm/llvm-project@d677505)
nvcc_default="clang"
- nvccflags_default="--cuda-gpu-arch=sm_30 -O2"
+ nvccflags_default="--cuda-gpu-arch=sm_30 -O2 -ffast-math"
+ nvccflags_default="--cuda-feature=+ptx60 --cuda-gpu-arch=sm_30 -O2 -ffast-math"
NVCC_C=""
fi
@@ -6711,7 +6713,7 @@ fi
@@ -4701,6 +4705,11 @@ if enabled cuda_nvcc; then
if $nvcc $nvccflags_default 2>&1 | grep -qi unsupported; then
nvccflags_default="-gencode arch=compute_60,code=sm_60 -O2"
fi
+else
+ # '--cuda-feature=+ptx*' option is not available before clang-15
+ if $nvcc $nvccflags_default 2>&1 | grep -qi unsupported; then
+ nvccflags_default="--cuda-gpu-arch=sm_30 -O2 -ffast-math"
+ fi
fi
set_default arch cc cxx doxygen pkg_config ranlib strip sysinclude \
@@ -6753,7 +6762,7 @@ fi
if enabled cuda_nvcc; then
nvccflags="$nvccflags -ptx"
else
@@ -54,12 +60,12 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -522,6 +522,8 @@ OBJS-$(CONFIG_TMEDIAN_FILTER)
@@ -524,6 +524,8 @@ OBJS-$(CONFIG_TMEDIAN_FILTER)
OBJS-$(CONFIG_TMIDEQUALIZER_FILTER) += vf_tmidequalizer.o
OBJS-$(CONFIG_TMIX_FILTER) += vf_mix.o framesync.o
OBJS-$(CONFIG_TONEMAP_FILTER) += vf_tonemap.o
+OBJS-$(CONFIG_TONEMAP_CUDA_FILTER) += vf_tonemap_cuda.o cuda/tonemap.ptx.o \
+ cuda/host_util.o
+ cuda/host_util.o cuda/load_helper.o
OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER) += vf_tonemap_opencl.o opencl.o \
opencl/tonemap.o opencl/colorspace_common.o
OBJS-$(CONFIG_TONEMAP_VAAPI_FILTER) += vf_tonemap_vaapi.o vaapi_vpp.o
@@ -67,7 +73,7 @@ Index: FFmpeg/libavfilter/allfilters.c
===================================================================
--- FFmpeg.orig/libavfilter/allfilters.c
+++ FFmpeg/libavfilter/allfilters.c
@@ -493,6 +493,7 @@ extern const AVFilter ff_vf_tmedian;
@@ -494,6 +494,7 @@ extern const AVFilter ff_vf_tmedian;
extern const AVFilter ff_vf_tmidequalizer;
extern const AVFilter ff_vf_tmix;
extern const AVFilter ff_vf_tonemap;
@@ -814,6 +820,96 @@ Index: FFmpeg/libavfilter/cuda/host_util.h
+ FFCUDAFrame *dst, const AVFrame *src, const AVPixFmtDescriptor *src_desc);
+
+#endif /* AVFILTER_CUDA_HOST_UTIL_H */
Index: FFmpeg/libavfilter/cuda/load_helper.c
===================================================================
--- FFmpeg.orig/libavfilter/cuda/load_helper.c
+++ FFmpeg/libavfilter/cuda/load_helper.c
@@ -32,11 +32,9 @@
#define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, cu, x)
-int ff_cuda_load_module(void *avctx, AVCUDADeviceContext *hwctx, CUmodule *cu_module,
- const unsigned char *data, const unsigned int length)
+static int decompress_cuda_ptx(void *avctx, uint8_t **data_out, uint64_t *length_out,
+ const unsigned char *data, const unsigned int length)
{
- CudaFunctions *cu = hwctx->internal->cuda_dl;
-
#if CONFIG_PTX_COMPRESSION
z_stream stream = { 0 };
uint8_t *buf, *tmp;
@@ -88,10 +86,51 @@ int ff_cuda_load_module(void *avctx, AVC
inflateEnd(&stream);
- ret = CHECK_CU(cu->cuModuleLoadData(cu_module, buf));
- av_free(buf);
- return ret;
+ *data_out = buf;
+ *length_out = stream.total_out;
#else
- return CHECK_CU(cu->cuModuleLoadData(cu_module, data));
+ *data_out = NULL;
+ *length_out = 0;
#endif
+ return 0;
+}
+
+int ff_cuda_load_module(void *avctx, AVCUDADeviceContext *hwctx, CUmodule *cu_module,
+ const unsigned char *data, const unsigned int length)
+{
+ CudaFunctions *cu = hwctx->internal->cuda_dl;
+ uint8_t *data_out = NULL;
+ uint64_t length_out = 0;
+ int ret;
+
+ if ((ret = decompress_cuda_ptx(avctx, &data_out, &length_out, data, length)) < 0)
+ goto exit;
+
+ ret = CHECK_CU(cu->cuModuleLoadData(cu_module, (data_out ? data_out : data)));
+exit:
+ if (data_out)
+ av_free(data_out);
+ return ret;
+}
+
+int ff_cuda_link_add_data(void *avctx, AVCUDADeviceContext *hwctx,
+ CUlinkState state, const char* name,
+ const unsigned char *data, const unsigned int length)
+{
+ CudaFunctions *cu = hwctx->internal->cuda_dl;
+ uint8_t *data_out = NULL;
+ uint64_t length_out = 0;
+ int ret;
+
+ if ((ret = decompress_cuda_ptx(avctx, &data_out, &length_out, data, length)) < 0)
+ goto exit;
+
+ ret = CHECK_CU(cu->cuLinkAddData(state, CU_JIT_INPUT_PTX,
+ (void *)(data_out ? data_out : data),
+ (size_t)(data_out ? length_out : length),
+ name, 0, NULL, NULL));
+exit:
+ if (data_out)
+ av_free(data_out);
+ return ret;
}
Index: FFmpeg/libavfilter/cuda/load_helper.h
===================================================================
--- FFmpeg.orig/libavfilter/cuda/load_helper.h
+++ FFmpeg/libavfilter/cuda/load_helper.h
@@ -25,4 +25,11 @@
int ff_cuda_load_module(void *avctx, AVCUDADeviceContext *hwctx, CUmodule *cu_module,
const unsigned char *data, const unsigned int length);
+/**
+ * Adds a PTX data to a pending linker invocation and applies any decompression, if necessary.
+ */
+int ff_cuda_link_add_data(void *avctx, AVCUDADeviceContext *hwctx,
+ CUlinkState state, const char* name,
+ const unsigned char *data, const unsigned int length);
+
#endif /* AVFILTER_CUDA_LOAD_HELPER_H */
Index: FFmpeg/libavfilter/cuda/pixfmt.h
===================================================================
--- /dev/null
@@ -1648,7 +1744,7 @@ Index: FFmpeg/libavfilter/cuda/tonemap.cu
+TONEMAP_VARIANT(_itp, _READER, , _YUV2RGB_S, _TONEMAP_ITP, _RGB2YUV_S, , _WRITER)
+TONEMAP_VARIANT(_itp_d, _READER, , _YUV2RGB_S, _TONEMAP_ITP, _RGB2YUV_S, _DITHER, _WRITER)
+
+TONEMAP_VARIANT(_dovi_max, _READER, _RESHAPE, _YCC2RGB, _TONEMAP_MAX, _RGB2YUV, , _WRITER)
+TONEMAP_VARIANT(_dovi_max, _READER, _RESHAPE, _YCC2RGB, _TONEMAP_MAX, _RGB2YUV, , _WRITER)
+TONEMAP_VARIANT(_dovi_max_d, _READER, _RESHAPE, _YCC2RGB, _TONEMAP_MAX, _RGB2YUV, _DITHER, _WRITER)
+TONEMAP_VARIANT(_dovi_rgb, _READER, _RESHAPE, _YCC2RGB, _TONEMAP_RGB, _RGB2YUV, , _WRITER)
+TONEMAP_VARIANT(_dovi_rgb_d, _READER, _RESHAPE, _YCC2RGB, _TONEMAP_RGB, _RGB2YUV, _DITHER, _WRITER)
@@ -1813,7 +1909,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_tonemap_cuda.c
@@ -0,0 +1,1174 @@
@@ -0,0 +1,1233 @@
+/*
+ * This file is part of FFmpeg.
+ *
@@ -1839,10 +1935,10 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/common.h"
+#include "libavutil/cuda_check.h"
+#include "libavutil/hwcontext.h"
+#include "libavutil/hwcontext_cuda_internal.h"
+#include "libavutil/cuda_check.h"
+#include "libavutil/mem.h"
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
@@ -1850,9 +1946,10 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+#include "avfilter.h"
+#include "colorspace.h"
+#include "cuda/host_util.h"
+#include "cuda/load_helper.h"
+#include "cuda/shared.h"
+#include "cuda/tonemap.h"
+#include "internal.h"
+#include "formats.h"
+#include "scale_eval.h"
+#include "video.h"
+#include "dither_matrix.h"
@@ -1864,6 +1961,13 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ AV_PIX_FMT_P016
+};
+
+static const int colorspaces_out[] = {
+ AVCOL_SPC_UNSPECIFIED,
+ AVCOL_SPC_BT709,
+ AVCOL_SPC_BT2020_NCL,
+ -1
+};
+
+#define DIV_UP(a, b) ( ((a) + (b) - 1) / (b) )
+#define ALIGN_UP(a, b) (((a) + (b) - 1) & ~((b) - 1))
+#define NUM_BUFFERS 2
@@ -1903,8 +2007,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ CUfunction cu_func_dovi;
+ CUfunction cu_func_dovi_pq;
+
+ CUdeviceptr ditherBuffer;
+ CUtexObject ditherTex;
+ CUdeviceptr dither_buffer;
+ CUtexObject dither_tex;
+
+#define params_cnt 8
+#define pivots_cnt (7+1)
@@ -1914,7 +2018,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+#define pivots_sz pivots_cnt*sizeof(float)
+#define coeffs_sz coeffs_cnt*sizeof(float)
+#define mmr_sz mmr_cnt*sizeof(float)
+ CUdeviceptr doviBuffer;
+ CUdeviceptr dovi_buffer;
+ struct DoviMetadata *dovi;
+ float *dovi_pbuf;
+
@@ -1963,7 +2067,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ return AVERROR(ENOMEM);
+
+ s->dovi = NULL;
+ s->doviBuffer = 0;
+ s->dovi_buffer = 0;
+
+ return 0;
+}
@@ -1978,9 +2082,9 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+
+ CHECK_CU(cu->cuCtxPushCurrent(cuda_ctx));
+
+ if (s->doviBuffer) {
+ CHECK_CU(cu->cuMemFree(s->doviBuffer));
+ s->doviBuffer = 0;
+ if (s->dovi_buffer) {
+ CHECK_CU(cu->cuMemFree(s->dovi_buffer));
+ s->dovi_buffer = 0;
+ }
+
+ CHECK_CU(cu->cuCtxPopCurrent(&dummy));
@@ -2004,13 +2108,13 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+
+ CHECK_CU(cu->cuCtxPushCurrent(cuda_ctx));
+
+ if (s->ditherTex) {
+ CHECK_CU(cu->cuTexObjectDestroy(s->ditherTex));
+ s->ditherTex = 0;
+ if (s->dither_tex) {
+ CHECK_CU(cu->cuTexObjectDestroy(s->dither_tex));
+ s->dither_tex = 0;
+ }
+ if (s->ditherBuffer) {
+ CHECK_CU(cu->cuMemFree(s->ditherBuffer));
+ s->ditherBuffer = 0;
+ if (s->dither_buffer) {
+ CHECK_CU(cu->cuMemFree(s->dither_buffer));
+ s->dither_buffer = 0;
+ }
+ if (s->cu_module) {
+ CHECK_CU(cu->cuModuleUnload(s->cu_module));
@@ -2040,7 +2144,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+{
+ TonemapCUDAContext *s = ctx->priv;
+ AVFilterLink *inlink = ctx->inputs[0];
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ FilterLink *inl = ff_filter_link(inlink);
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ AVCUDADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
+ CudaFunctions *cu = device_hwctx->internal->cuda_dl;
+ CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
@@ -2081,15 +2186,15 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ if ((ret = CHECK_CU(cu->cuCtxPushCurrent(cuda_ctx))) < 0)
+ return ret;
+
+ if ((ret = CHECK_CU(cu->cuMemAlloc(&s->ditherBuffer, sizeof(ff_fruit_dither_matrix)))) < 0)
+ if ((ret = CHECK_CU(cu->cuMemAlloc(&s->dither_buffer, sizeof(ff_fruit_dither_matrix)))) < 0)
+ goto fail;
+
+ res_desc.res.pitch2D.devPtr = cpy.dstDevice = s->ditherBuffer;
+ res_desc.res.pitch2D.devPtr = cpy.dstDevice = s->dither_buffer;
+
+ if ((ret = CHECK_CU(cu->cuMemcpy2D(&cpy))) < 0)
+ goto fail;
+
+ if ((ret = CHECK_CU(cu->cuTexObjectCreate(&s->ditherTex, &res_desc, &tex_desc, NULL))) < 0)
+ if ((ret = CHECK_CU(cu->cuTexObjectCreate(&s->dither_tex, &res_desc, &tex_desc, NULL))) < 0)
+ goto fail;
+
+fail:
@@ -2097,8 +2202,9 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ return ret;
+}
+
+static av_cold int init_stage(TonemapCUDAContext *s, AVBufferRef *device_ctx,
+ AVFilterLink *outlink)
+static av_cold int init_hwframe_ctx(TonemapCUDAContext *s,
+ AVBufferRef *device_ctx,
+ int out_width, int out_height)
+{
+ AVBufferRef *out_ref = NULL;
+ AVHWFramesContext *out_ctx;
@@ -2111,8 +2217,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+
+ out_ctx->format = AV_PIX_FMT_CUDA;
+ out_ctx->sw_format = s->out_fmt;
+ out_ctx->width = FFALIGN(outlink->w, 32);
+ out_ctx->height = FFALIGN(outlink->h, 32);
+ out_ctx->width = FFALIGN(out_width, 32);
+ out_ctx->height = FFALIGN(out_height, 32);
+
+ ret = av_hwframe_ctx_init(out_ref);
+ if (ret < 0)
@@ -2123,8 +2229,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ if (ret < 0)
+ goto fail;
+
+ s->frame->width = outlink->w;
+ s->frame->height = outlink->h;
+ s->frame->width = out_width;
+ s->frame->height = out_height;
+
+ av_buffer_unref(&s->frames_ctx);
+ s->frames_ctx = out_ref;
@@ -2145,9 +2251,12 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ return 0;
+}
+
+static av_cold int init_processing_chain(AVFilterContext *ctx, AVFilterLink *outlink)
+static av_cold int init_processing_chain(AVFilterContext *ctx,
+ int out_width, int out_height)
+{
+ TonemapCUDAContext *s = ctx->priv;
+ FilterLink *inl = ff_filter_link(ctx->inputs[0]);
+ FilterLink *outl = ff_filter_link(ctx->outputs[0]);
+
+ AVHWFramesContext *in_frames_ctx;
+
@@ -2158,11 +2267,11 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ int ret;
+
+ /* check that we have a hw context */
+ if (!ctx->inputs[0]->hw_frames_ctx) {
+ if (!inl->hw_frames_ctx) {
+ av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n");
+ return AVERROR(EINVAL);
+ }
+ in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data;
+ in_frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ in_format = in_frames_ctx->sw_format;
+ out_format = (s->format == AV_PIX_FMT_NONE) ? in_format : s->format;
+ in_desc = av_pix_fmt_desc_get(in_format);
@@ -2190,12 +2299,12 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ s->in_desc = in_desc;
+ s->out_desc = out_desc;
+
+ ret = init_stage(s, in_frames_ctx->device_ref, outlink);
+ ret = init_hwframe_ctx(s, in_frames_ctx->device_ref, out_width, out_height);
+ if (ret < 0)
+ return ret;
+
+ ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->frames_ctx);
+ if (!ctx->outputs[0]->hw_frames_ctx)
+ outl->hw_frames_ctx = av_buffer_ref(s->frames_ctx);
+ if (!outl->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+
+ return 0;
@@ -2332,7 +2441,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ enum AVColorSpace in_spc = s->in_spc, out_spc = s->out_spc;
+ enum AVColorPrimaries in_pri = s->in_pri, out_pri = s->out_pri;
+ enum AVColorRange in_range = s->in_range, out_range = s->out_range;
+ int d = s->in_desc->comp[0].depth > s->out_desc->comp[0].depth && s->ditherTex;
+ int d = s->in_desc->comp[0].depth > s->out_desc->comp[0].depth && s->dither_tex;
+ float input_quantization_offset = 0.0f;
+ float output_quantization_offset = 0.0f;
+ float input_y_scale = 1.0f;
@@ -2527,7 +2636,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+
+ if (s->dovi) {
+ s->dovi_pbuf = av_mallocz(3*(params_sz+pivots_sz+coeffs_sz+mmr_sz));
+ ret = CHECK_CU(cu->cuMemAlloc(&s->doviBuffer, 3*(params_sz+pivots_sz+coeffs_sz+mmr_sz)));
+ ret = CHECK_CU(cu->cuMemAlloc(&s->dovi_buffer, 3*(params_sz+pivots_sz+coeffs_sz+mmr_sz)));
+ if (ret < 0)
+ goto fail;
+ }
@@ -2594,8 +2703,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ if (ret < 0)
+ goto fail2;
+
+ ret = CHECK_CU(cu->cuLinkAddData(link_state, CU_JIT_INPUT_PTX, (void *)ff_tonemap_ptx_data,
+ (size_t)ff_tonemap_ptx_len, "ff_tonemap_ptx_data", 0, NULL, NULL));
+ ret = ff_cuda_link_add_data(ctx, s->hwctx, link_state, "ff_tonemap_ptx_data",
+ ff_tonemap_ptx_data, ff_tonemap_ptx_len);
+ if (ret < 0)
+ goto fail2;
+
@@ -2670,20 +2779,24 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+{
+ AVFilterContext *ctx = outlink->src;
+ AVFilterLink *inlink = outlink->src->inputs[0];
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ AVCUDADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
+ FilterLink *inl = ff_filter_link(inlink);
+ AVHWFramesContext *frames_ctx;
+ AVCUDADeviceContext *device_hwctx;
+ TonemapCUDAContext *s = ctx->priv;
+ int ret;
+
+ s->hwctx = device_hwctx;
+
+ outlink->w = inlink->w;
+ outlink->h = inlink->h;
+
+ ret = init_processing_chain(ctx, outlink);
+ ret = init_processing_chain(ctx, outlink->w, outlink->h);
+ if (ret < 0)
+ return ret;
+
+ frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ device_hwctx = frames_ctx->device_ctx->hwctx;
+
+ s->hwctx = device_hwctx;
+
+ if (s->in_desc->comp[0].depth > s->out_desc->comp[0].depth) {
+ if ((ret = setup_dither(ctx)) < 0)
+ return ret;
@@ -2700,7 +2813,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ TonemapCUDAContext *s = ctx->priv;
+ CudaFunctions *cu = s->hwctx->internal->cuda_dl;
+ FFCUDAFrame src, dst;
+ void *args[] = { &src, &dst, &s->ditherTex, &s->doviBuffer };
+ void *args[] = { &src, &dst, &s->dither_tex, &s->dovi_buffer };
+ int ret, pq_out = s->out_trc == AVCOL_TRC_SMPTE2084;
+
+ ret = ff_make_cuda_frame(ctx, cu, 1,
@@ -2727,6 +2840,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+static int do_tonemap(AVFilterContext *ctx, AVFrame *out, AVFrame *in)
+{
+ TonemapCUDAContext *s = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFrame *src = in;
+ int ret;
+
@@ -2843,9 +2957,9 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ s->in_chroma_loc = in->chroma_location;
+
+ s->out_trc = s->trc == -1 ? AVCOL_TRC_UNSPECIFIED : s->trc;
+ s->out_spc = s->spc == -1 ? AVCOL_SPC_UNSPECIFIED : s->spc;
+ s->out_spc = outlink->colorspace;
+ s->out_pri = s->pri == -1 ? AVCOL_PRI_UNSPECIFIED : s->pri;
+ s->out_range = s->range == -1 ? s->in_range : s->range;
+ s->out_range = outlink->color_range;
+ s->out_chroma_loc = s->in_chroma_loc;
+
+ if ((ret = compile(link)) < 0)
@@ -2861,7 +2975,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ if (s->dovi) {
+ update_dovi_buf(ctx);
+
+ ret = CHECK_CU(cu->cuMemcpyHtoDAsync(s->doviBuffer, s->dovi_pbuf,
+ ret = CHECK_CU(cu->cuMemcpyHtoDAsync(s->dovi_buffer, s->dovi_pbuf,
+ 3*(params_sz+pivots_sz+coeffs_sz+mmr_sz), s->hwctx->stream));
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to update dovi buf.\n");
@@ -2897,6 +3011,47 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ return ret;
+}
+
+static int query_formats(AVFilterContext *avctx)
+{
+ TonemapCUDAContext *s = avctx->priv;
+ AVFilterFormats *formats;
+ int ret;
+ const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE };
+
+ // single format
+ formats = ff_make_format_list(pix_fmts);
+ ret = ff_formats_ref(formats, &avctx->inputs[0]->outcfg.formats);
+ if (ret < 0)
+ return ret;
+
+ ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.formats);
+ if (ret < 0)
+ return ret;
+
+ // colorspaces and ranges
+ if ((ret = ff_formats_ref(ff_all_color_spaces(),
+ &avctx->inputs[0]->outcfg.color_spaces)) < 0)
+ return ret;
+
+ if ((ret = ff_formats_ref(ff_all_color_ranges(),
+ &avctx->inputs[0]->outcfg.color_ranges)) < 0)
+ return ret;
+
+ formats = s->spc != -1
+ ? ff_make_formats_list_singleton(s->spc)
+ : ff_make_format_list(colorspaces_out);
+ if ((ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.color_spaces)) < 0)
+ return ret;
+
+ formats = s->range != -1
+ ? ff_make_formats_list_singleton(s->range)
+ : ff_all_color_ranges();
+ if ((ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.color_ranges)) < 0)
+ return ret;
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(TonemapCUDAContext, x)
+#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM)
+static const AVOption options[] = {
@@ -2984,7 +3139,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_cuda.c
+ FILTER_INPUTS(tonemap_cuda_inputs),
+ FILTER_OUTPUTS(tonemap_cuda_outputs),
+
+ FILTER_SINGLE_PIXFMT(AV_PIX_FMT_CUDA),
+ FILTER_QUERY_FUNC(query_formats),
+
+ .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
+};
@@ -0,0 +1,772 @@
Index: FFmpeg/libavcodec/amfenc.c
===================================================================
--- FFmpeg.orig/libavcodec/amfenc.c
+++ FFmpeg/libavcodec/amfenc.c
@@ -102,19 +102,6 @@ static int amf_save_hdr_metadata(AVCodec
#define PTS_PROP L"PtsProp"
-const enum AVPixelFormat ff_amf_pix_fmts[] = {
- AV_PIX_FMT_NV12,
- AV_PIX_FMT_YUV420P,
-#if CONFIG_D3D11VA
- AV_PIX_FMT_D3D11,
-#endif
-#if CONFIG_DXVA2
- AV_PIX_FMT_DXVA2_VLD,
-#endif
- AV_PIX_FMT_P010,
- AV_PIX_FMT_NONE
-};
-
typedef struct FormatMap {
enum AVPixelFormat av_format;
enum AMF_SURFACE_FORMAT amf_format;
@@ -125,7 +112,9 @@ static const FormatMap format_map[] =
{ AV_PIX_FMT_NONE, AMF_SURFACE_UNKNOWN },
{ AV_PIX_FMT_NV12, AMF_SURFACE_NV12 },
{ AV_PIX_FMT_P010, AMF_SURFACE_P010 },
+ { AV_PIX_FMT_BGRA, AMF_SURFACE_BGRA },
{ AV_PIX_FMT_BGR0, AMF_SURFACE_BGRA },
+ { AV_PIX_FMT_RGBA, AMF_SURFACE_RGBA },
{ AV_PIX_FMT_RGB0, AMF_SURFACE_RGBA },
{ AV_PIX_FMT_GRAY8, AMF_SURFACE_GRAY8 },
{ AV_PIX_FMT_YUV420P, AMF_SURFACE_YUV420P },
@@ -274,7 +263,6 @@ static int amf_init_context(AVCodecConte
av_unused int ret;
ctx->hwsurfaces_in_queue = 0;
- ctx->hwsurfaces_in_queue_max = 16;
// configure AMF logger
// the return of these functions indicates old state and do not affect behaviour
@@ -329,7 +317,7 @@ static int amf_init_context(AVCodecConte
return AVERROR(ENOMEM);
if (frames_ctx->initial_pool_size > 0)
- ctx->hwsurfaces_in_queue_max = frames_ctx->initial_pool_size - 1;
+ ctx->hwsurfaces_in_queue_max = FFMIN(ctx->hwsurfaces_in_queue_max, frames_ctx->initial_pool_size - 1);
} else if (avctx->hw_device_ctx) {
AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data;
@@ -415,10 +403,6 @@ static int amf_init_encoder(AVCodecConte
else
pix_fmt = avctx->pix_fmt;
- if (pix_fmt == AV_PIX_FMT_P010) {
- AMF_RETURN_IF_FALSE(ctx, ctx->version >= AMF_MAKE_FULL_VERSION(1, 4, 32, 0), AVERROR_UNKNOWN, "10-bit encoder is not supported by AMD GPU drivers versions lower than 23.30.\n");
- }
-
ctx->format = amf_av_to_amf_format(pix_fmt);
AMF_RETURN_IF_FALSE(ctx, ctx->format != AMF_SURFACE_UNKNOWN, AVERROR(EINVAL),
"Format %s is not supported\n", av_get_pix_fmt_name(pix_fmt));
@@ -426,6 +410,8 @@ static int amf_init_encoder(AVCodecConte
res = ctx->factory->pVtbl->CreateComponent(ctx->factory, ctx->context, codec_id, &ctx->encoder);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_ENCODER_NOT_FOUND, "CreateComponent(%ls) failed with error %d\n", codec_id, res);
+ ctx->submitted_frame = 0;
+
return 0;
}
@@ -541,7 +527,6 @@ static int amf_copy_buffer(AVCodecContex
if ((ctx->max_b_frames > 0 || ((ctx->pa_adaptive_mini_gop == 1) ? true : false)) && ctx->dts_delay == 0) {
int64_t timestamp_last = AV_NOPTS_VALUE;
size_t can_read = av_fifo_can_read(ctx->timestamp_list);
-
AMF_RETURN_IF_FALSE(ctx, can_read > 0, AVERROR_UNKNOWN,
"timestamp_list is empty while max_b_frames = %d\n", avctx->max_b_frames);
av_fifo_peek(ctx->timestamp_list, &timestamp_last, 1, can_read - 1);
@@ -766,11 +751,50 @@ int ff_amf_receive_packet(AVCodecContext
switch (avctx->codec->id) {
case AV_CODEC_ID_H264:
AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_AUD, !!ctx->aud);
+ switch (frame->pict_type) {
+ case AV_PICTURE_TYPE_I:
+ if (ctx->forced_idr) {
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_SPS, 1);
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_INSERT_PPS, 1);
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_IDR);
+ } else {
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_I);
+ }
+ break;
+ case AV_PICTURE_TYPE_P:
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_P);
+ break;
+ case AV_PICTURE_TYPE_B:
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_PICTURE_TYPE_B);
+ break;
+ }
break;
case AV_CODEC_ID_HEVC:
AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, !!ctx->aud);
+ switch (frame->pict_type) {
+ case AV_PICTURE_TYPE_I:
+ if (ctx->forced_idr) {
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_INSERT_HEADER, 1);
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_IDR);
+ } else {
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_I);
+ }
+ break;
+ case AV_PICTURE_TYPE_P:
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_HEVC_FORCE_PICTURE_TYPE, AMF_VIDEO_ENCODER_HEVC_PICTURE_TYPE_P);
+ break;
+ }
+ break;
+ case AV_CODEC_ID_AV1:
+ if (frame->pict_type == AV_PICTURE_TYPE_I) {
+ if (ctx->forced_idr) {
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_INSERT_SEQUENCE_HEADER, 1);
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_KEY);
+ } else {
+ AMF_ASSIGN_PROPERTY_INT64(res, surface, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE, AMF_VIDEO_ENCODER_AV1_FORCE_FRAME_TYPE_INTRA_ONLY);
+ }
+ }
break;
- //case AV_CODEC_ID_AV1 not supported
default:
break;
}
@@ -787,6 +811,13 @@ int ff_amf_receive_packet(AVCodecContext
av_frame_unref(frame);
ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
+
+ if (ctx->submitted_frame == 0)
+ {
+ ctx->use_b_frame = (ctx->max_b_frames > 0 || ((ctx->pa_adaptive_mini_gop == 1) ? true : false));
+ }
+ ctx->submitted_frame++;
+
if (ret < 0)
return ret;
}
@@ -796,7 +827,7 @@ int ff_amf_receive_packet(AVCodecContext
do {
block_and_wait = 0;
// poll data
- if (!avpkt->data && !avpkt->buf) {
+ if (!avpkt->data && !avpkt->buf && (ctx->use_b_frame ? (ctx->submitted_frame >= 2) : true) ) {
res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder, &data);
if (data) {
// copy data to packet
@@ -806,6 +837,7 @@ int ff_amf_receive_packet(AVCodecContext
data->pVtbl->QueryInterface(data, &guid, (void**)&buffer); // query for buffer interface
ret = amf_copy_buffer(avctx, avpkt, buffer);
+ ctx->submitted_frame++;
buffer->pVtbl->Release(buffer);
if (data->pVtbl->HasProperty(data, L"av_frame_ref")) {
@@ -845,6 +877,7 @@ int ff_amf_receive_packet(AVCodecContext
av_frame_unref(ctx->delayed_frame);
AMF_RETURN_IF_FALSE(ctx, res_resubmit == AMF_OK, AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n", res_resubmit);
+ ctx->submitted_frame++;
ret = av_fifo_write(ctx->timestamp_list, &pts, 1);
if (ret < 0)
return ret;
@@ -863,7 +896,12 @@ int ff_amf_receive_packet(AVCodecContext
if (query_output_data_flag == 0) {
if (res_resubmit == AMF_INPUT_FULL || ctx->delayed_drain || (ctx->eof && res_query != AMF_EOF) || (ctx->hwsurfaces_in_queue >= ctx->hwsurfaces_in_queue_max)) {
block_and_wait = 1;
- av_usleep(1000);
+
+ // Only sleep if the driver doesn't support waiting in QueryOutput()
+ // or if we already have output data so we will skip calling it.
+ if (!ctx->query_timeout_supported || avpkt->data || avpkt->buf) {
+ av_usleep(1000);
+ }
}
}
} while (block_and_wait);
Index: FFmpeg/libavcodec/amfenc.h
===================================================================
--- FFmpeg.orig/libavcodec/amfenc.h
+++ FFmpeg/libavcodec/amfenc.h
@@ -68,6 +68,7 @@ typedef struct AmfContext {
int hwsurfaces_in_queue;
int hwsurfaces_in_queue_max;
+ int query_timeout_supported;
// helpers to handle async calls
int delayed_drain;
@@ -77,6 +78,8 @@ typedef struct AmfContext {
// shift dts back by max_b_frames in timing
AVFifo *timestamp_list;
int64_t dts_delay;
+ int submitted_frame;
+ amf_bool use_b_frame;
// common encoder option options
@@ -114,6 +117,7 @@ typedef struct AmfContext {
int max_b_frames;
int qvbr_quality_level;
int hw_high_motion_quality_boost;
+ int forced_idr;
// HEVC - specific options
Index: FFmpeg/libavcodec/amfenc_av1.c
===================================================================
--- FFmpeg.orig/libavcodec/amfenc_av1.c
+++ FFmpeg/libavcodec/amfenc_av1.c
@@ -28,6 +28,22 @@
#define OFFSET(x) offsetof(AmfContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+
+static const enum AVPixelFormat ff_amfenc_av1_pix_fmts[] = {
+ AV_PIX_FMT_NV12,
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_P010,
+ AV_PIX_FMT_BGRA,
+ AV_PIX_FMT_BGR0,
+#if CONFIG_D3D11VA
+ AV_PIX_FMT_D3D11,
+#endif
+#if CONFIG_DXVA2
+ AV_PIX_FMT_DXVA2_VLD,
+#endif
+ AV_PIX_FMT_NONE
+};
+
static const AVOption options[] = {
{ "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_VIDEO_ENCODER_AV1_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, .unit = "usage" },
@@ -97,10 +113,16 @@ static const AVOption options[] = {
{ "gop", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, .unit = "hdrmode" },
{ "frame", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_HEADER_INSERTION_MODE_KEY_FRAME_ALIGNED }, 0, 0, VE, .unit = "hdrmode" },
+ { "async_depth", "Set maximum encoding parallelism. Higher values increase output latency.", OFFSET(hwsurfaces_in_queue_max), AV_OPT_TYPE_INT, {.i64 = 16 }, 1, 16, VE },
+
{ "preencode", "Enable preencode", OFFSET(preencode), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE},
{ "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE},
{ "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE},
+ /// B-Frames
+ { "max_b_frames", "Maximum number of consecutive B Pictures", OFFSET(max_consecutive_b_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 3, VE },
+ { "bf", "B Picture Pattern", OFFSET(max_b_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 3, VE },
+
{ "high_motion_quality_boost_enable", "Enable High motion quality boost mode", OFFSET(hw_high_motion_quality_boost), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
// min_qp_i -> min_qp_intra, min_qp_p -> min_qp_inter
@@ -116,6 +138,7 @@ static const AVOption options[] = {
{ "none", "no adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_AQ_MODE_NONE }, 0, 0, VE, .unit = "adaptive_quantisation_mode" },
{ "caq", "context adaptive quantization", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_AQ_MODE_CAQ }, 0, 0, VE, .unit = "adaptive_quantisation_mode" },
+ { "forced_idr", "Force I frames to be IDR frames", OFFSET(forced_idr), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "align", "alignment mode", OFFSET(align), AV_OPT_TYPE_INT, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY, AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS, VE, .unit = "align" },
{ "64x16", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_ONLY }, 0, 0, VE, .unit = "align" },
@@ -169,6 +192,9 @@ static const AVOption options[] = {
{ "pa_high_motion_quality_boost_mode", "Sets the PA high motion quality boost mode", OFFSET(pa_high_motion_quality_boost_mode), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_AUTO, VE , .unit = "high_motion_quality_boost_mode" },
{ "none", "no high motion quality boost", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_NONE }, 0, 0, VE, .unit = "high_motion_quality_boost_mode" },
{ "auto", "auto high motion quality boost", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_PA_HIGH_MOTION_QUALITY_BOOST_MODE_AUTO }, 0, 0, VE, .unit = "high_motion_quality_boost_mode" },
+
+ { "pa_adaptive_mini_gop", "Enable Adaptive B-frame", OFFSET(pa_adaptive_mini_gop), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
+
{ NULL }
};
@@ -241,6 +267,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
color_profile = ff_amf_get_color_profile(avctx);
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
+#ifndef AMF_VIDEO_ENCODER_AV1_NOMINAL_RANGE // Not available before AMF 1.4.36.0
+ #define AMF_VIDEO_ENCODER_AV1_NOMINAL_RANGE L"Av1NominalRange"
+#endif
+ /// Color Range
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_NOMINAL_RANGE, !!(avctx->color_range == AVCOL_RANGE_JPEG));
+
/// Color Depth
pix_fmt = avctx->hw_frames_ctx ? ((AVHWFramesContext*)avctx->hw_frames_ctx->data)->sw_format
: avctx->pix_fmt;
@@ -251,15 +283,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_COLOR_BIT_DEPTH, color_depth);
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
- if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
- /// Color Transfer Characteristics (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
- /// Color Primaries (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
- } else {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
- }
+ /// Color Transfer Characteristics (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, avctx->color_trc);
+ /// Color Primaries (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, avctx->color_primaries);
profile_level = avctx->level;
if (profile_level == AV_LEVEL_UNKNOWN) {
@@ -280,7 +307,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
// Picture control properties
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_GOP_SIZE, avctx->gop_size);
+ if (avctx->gop_size != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_GOP_SIZE, avctx->gop_size);
+ }
// Setup header insertion mode only if this option was defined explicitly
if (ctx->header_insertion_mode != -1) {
@@ -367,7 +396,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_PEAK_BITRATE, avctx->rc_max_rate);
}
else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
- av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
+ av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate is not set, default max_rate will be applied.\n");
}
if (avctx->bit_rate > 0) {
ctx->rate_control_mode = AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CBR;
@@ -456,6 +485,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ctx->pa_taq_mode != -1) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_TAQ_MODE, ctx->pa_taq_mode);
}
+ if (ctx->pa_adaptive_mini_gop != -1) {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ADAPTIVE_MINIGOP, ((ctx->pa_adaptive_mini_gop == 0) ? false : true));
+ }
if (ctx->pa_ltr != -1) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_PA_LTR_ENABLE, ((ctx->pa_ltr == 0) ? false : true));
}
@@ -467,6 +499,67 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
+ // B-Frames
+ AMFVariantStruct is_adaptive_b_frames = { 0 };
+ res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_ADAPTIVE_MINIGOP, &is_adaptive_b_frames);
+ if (ctx->max_consecutive_b_frames != -1 || ctx->max_b_frames != -1 || is_adaptive_b_frames.boolValue == true) {
+
+ //Get the capability of encoder
+ AMFCaps *encoder_caps = NULL;
+ ctx->encoder->pVtbl->GetCaps(ctx->encoder, &encoder_caps);
+ if (encoder_caps != NULL)
+ {
+ res = encoder_caps->pVtbl->GetProperty(encoder_caps, AMF_VIDEO_ENCODER_AV1_CAP_BFRAMES, &var);
+ if (res == AMF_OK) {
+
+ //encoder supports AV1 B-frame
+ if(var.boolValue == true){
+ //adaptive b-frames is higher priority than max_b_frames
+ if (is_adaptive_b_frames.boolValue == true)
+ {
+ //force AMF_VIDEO_ENCODER_AV1_MAX_CONSECUTIVE_BPICTURES to 3
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_CONSECUTIVE_BPICTURES, 3);
+
+ if(ctx->pa_lookahead_buffer_depth < 1)
+ {
+ //force AMF_PA_LOOKAHEAD_BUFFER_DEPTH to 1 if not set or smaller than 1
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_PA_LOOKAHEAD_BUFFER_DEPTH, 1);
+ }
+ }
+ else {
+ if (ctx->max_b_frames != -1) {
+ //in case user sets B-frames
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_B_PIC_PATTERN, ctx->max_b_frames);
+ if (res != AMF_OK) {
+ res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_B_PIC_PATTERN, &var);
+ av_log(ctx, AV_LOG_WARNING, "B-frames=%d is not supported by this GPU, switched to %d\n", ctx->max_b_frames, (int)var.int64Value);
+ ctx->max_b_frames = (int)var.int64Value;
+ }
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_MAX_CONSECUTIVE_BPICTURES, ctx->max_b_frames);
+ }
+ }
+
+ }
+ //encoder doesn't support AV1 B-frame
+ else {
+ av_log(ctx, AV_LOG_WARNING, "The current GPU in use does not support AV1 B-frame encoding, there will be no B-frame in bitstream.\n");
+ }
+ } else {
+ //Can't get the capability of encoder
+ av_log(ctx, AV_LOG_WARNING, "Unable to get AV1 B-frame capability.\n");
+ av_log(ctx, AV_LOG_WARNING, "There will be no B-frame in bitstream.\n");
+ }
+
+ encoder_caps->pVtbl->Release(encoder_caps);
+ encoder_caps = NULL;
+ }
+ }
+
+ // Wait inside QueryOutput() if supported by the driver
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_QUERY_TIMEOUT, 1);
+ res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_AV1_QUERY_TIMEOUT, &var);
+ ctx->query_timeout_supported = res == AMF_OK && var.int64Value;
+
// init encoder
res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res);
@@ -628,8 +721,8 @@ const FFCodec ff_av1_amf_encoder = {
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE |
AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
- .p.pix_fmts = ff_amf_pix_fmts,
- .color_ranges = AVCOL_RANGE_MPEG, /* FIXME: implement tagging */
+ .p.pix_fmts = ff_amfenc_av1_pix_fmts,
+ .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
.p.wrapper_name = "amf",
.hw_configs = ff_amfenc_hw_configs,
};
Index: FFmpeg/libavcodec/amfenc_h264.c
===================================================================
--- FFmpeg.orig/libavcodec/amfenc_h264.c
+++ FFmpeg/libavcodec/amfenc_h264.c
@@ -27,6 +27,20 @@
#define OFFSET(x) offsetof(AmfContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const enum AVPixelFormat ff_amfenc_h264_pix_fmts[] = {
+ AV_PIX_FMT_NV12,
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_BGRA,
+ AV_PIX_FMT_BGR0,
+#if CONFIG_D3D11VA
+ AV_PIX_FMT_D3D11,
+#endif
+#if CONFIG_DXVA2
+ AV_PIX_FMT_DXVA2_VLD,
+#endif
+ AV_PIX_FMT_NONE
+};
+
static const AVOption options[] = {
// Static
/// Usage
@@ -110,6 +124,9 @@ static const AVOption options[] = {
/// Header Insertion Spacing
{ "header_spacing", "Header Insertion Spacing", OFFSET(header_spacing), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1000, VE },
+ /// Maximum queued frames
+ { "async_depth", "Set maximum encoding parallelism. Higher values increase output latency.", OFFSET(hwsurfaces_in_queue_max), AV_OPT_TYPE_INT, {.i64 = 16 }, 1, 16, VE },
+
/// B-Frames
// BPicturesPattern=bf
{ "bf_delta_qp", "B-Picture Delta QP", OFFSET(b_frame_delta_qp), AV_OPT_TYPE_INT, { .i64 = 4 }, -10, 10, VE },
@@ -133,6 +150,7 @@ static const AVOption options[] = {
{ "me_half_pel", "Enable ME Half Pixel", OFFSET(me_half_pel), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
{ "me_quarter_pel", "Enable ME Quarter Pixel", OFFSET(me_quarter_pel),AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
+ { "forced_idr", "Force I frames to be IDR frames", OFFSET(forced_idr) , AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "aud", "Inserts AU Delimiter NAL unit", OFFSET(aud) , AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
@@ -360,7 +378,22 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, 0);
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_QP, 51);
- } else {
+ } else if (ctx->rate_control_mode != AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_QUALITY_VBR) {
+ /* Custom tuning */
+ if (avctx->qmin == -1 && avctx->qmax == -1) {
+ switch (ctx->usage) {
+ case AMF_VIDEO_ENCODER_USAGE_TRANSCONDING:
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, 18);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_QP, 46);
+ break;
+ case AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY:
+ case AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY:
+ case AMF_VIDEO_ENCODER_USAGE_WEBCAM:
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, 22);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MAX_QP, 48);
+ break;
+ }
+ }
if (avctx->qmin != -1) {
int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_MIN_QP, qval);
@@ -391,7 +424,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (avctx->rc_max_rate) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_PEAK_BITRATE, avctx->rc_max_rate);
} else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
- av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
+ av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate is not set, default max_rate will be applied.\n");
}
if (ctx->latency != -1) {
@@ -482,6 +515,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP, ctx->ref_b_frame_delta_qp);
}
+ if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
+ if (ctx->enable_vbaq)
+ av_log(ctx, AV_LOG_WARNING, "VBAQ is not supported by cqp Rate Control Method, automatically disabled\n");
+ } else {
+ if (ctx->enable_vbaq != -1) {
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, !!ctx->enable_vbaq);
+ }
+ }
+
+ // Wait inside QueryOutput() if supported by the driver
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QUERY_TIMEOUT, 1);
+ res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_QUERY_TIMEOUT, &var);
+ ctx->query_timeout_supported = res == AMF_OK && var.int64Value;
+
// Initialize Encoder
res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res);
@@ -499,19 +547,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, ((ctx->skip_frame == 0) ? false : true));
}
- if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
- AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
- if (ctx->enable_vbaq)
- av_log(ctx, AV_LOG_WARNING, "VBAQ is not supported by cqp Rate Control Method, automatically disabled\n");
- } else {
- if (ctx->enable_vbaq != -1) {
- AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, !!ctx->enable_vbaq);
- }
- }
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_DE_BLOCKING_FILTER, !!deblocking_filter);
// Keyframe Interval
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_IDR_PERIOD, avctx->gop_size);
+ if (avctx->gop_size != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_IDR_PERIOD, avctx->gop_size);
+ }
// Header Insertion Spacing
if (ctx->header_spacing >= 0)
@@ -601,7 +642,7 @@ const FFCodec ff_h264_amf_encoder = {
AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
FF_CODEC_CAP_INIT_CLEANUP,
- .p.pix_fmts = ff_amf_pix_fmts,
+ .p.pix_fmts = ff_amfenc_h264_pix_fmts,
.color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
.p.wrapper_name = "amf",
.hw_configs = ff_amfenc_hw_configs,
Index: FFmpeg/libavcodec/amfenc_hevc.c
===================================================================
--- FFmpeg.orig/libavcodec/amfenc_hevc.c
+++ FFmpeg/libavcodec/amfenc_hevc.c
@@ -26,6 +26,21 @@
#define OFFSET(x) offsetof(AmfContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const enum AVPixelFormat ff_amfenc_hevc_pix_fmts[] = {
+ AV_PIX_FMT_NV12,
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_P010,
+ AV_PIX_FMT_BGRA,
+ AV_PIX_FMT_BGR0,
+#if CONFIG_D3D11VA
+ AV_PIX_FMT_D3D11,
+#endif
+#if CONFIG_DXVA2
+ AV_PIX_FMT_DXVA2_VLD,
+#endif
+ AV_PIX_FMT_NONE
+};
+
static const AVOption options[] = {
{ "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, .unit = "usage" },
{ "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING }, 0, 0, VE, .unit = "usage" },
@@ -83,6 +98,8 @@ static const AVOption options[] = {
{ "gop", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, .unit = "hdrmode" },
{ "idr", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED }, 0, 0, VE, .unit = "hdrmode" },
+ { "async_depth", "Set maximum encoding parallelism. Higher values increase output latency.", OFFSET(hwsurfaces_in_queue_max), AV_OPT_TYPE_INT, {.i64 = 16 }, 1, 16, VE },
+
{ "high_motion_quality_boost_enable", "Enable High motion quality boost mode", OFFSET(hw_high_motion_quality_boost), AV_OPT_TYPE_BOOL, {.i64 = -1 }, -1, 1, VE },
{ "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE },
{ "preencode", "Enable preencode", OFFSET(preencode), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE},
@@ -100,6 +117,7 @@ static const AVOption options[] = {
{ "me_half_pel", "Enable ME Half Pixel", OFFSET(me_half_pel), AV_OPT_TYPE_BOOL,{ .i64 = -1 }, -1, 1, VE },
{ "me_quarter_pel", "Enable ME Quarter Pixel ", OFFSET(me_quarter_pel),AV_OPT_TYPE_BOOL,{ .i64 = -1 }, -1, 1, VE },
+ { "forced_idr", "Force I frames to be IDR frames", OFFSET(forced_idr) ,AV_OPT_TYPE_BOOL,{ .i64 = 1 }, 0, 1, VE },
{ "aud", "Inserts AU Delimiter NAL unit", OFFSET(aud) ,AV_OPT_TYPE_BOOL,{ .i64 = -1 }, -1, 1, VE },
@@ -193,7 +211,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_SIZE(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_FRAMESIZE, framesize);
AMF_ASSIGN_PROPERTY_RATE(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_FRAMERATE, framerate);
-
+#if 0
switch (avctx->profile) {
case AV_PROFILE_HEVC_MAIN:
profile = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN;
@@ -213,7 +231,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (profile != 0) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_PROFILE, profile);
}
-
+#endif
if (ctx->tier != -1) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_TIER, ctx->tier);
}
@@ -247,29 +265,32 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, !!(avctx->color_range == AVCOL_RANGE_JPEG));
/// Color Depth
color_depth = AMF_COLOR_BIT_DEPTH_8;
+ profile = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN;
+ avctx->profile = AV_PROFILE_HEVC_MAIN;
pix_fmt = avctx->hw_frames_ctx ? ((AVHWFramesContext*)avctx->hw_frames_ctx->data)->sw_format
: avctx->pix_fmt;
if (pix_fmt == AV_PIX_FMT_P010) {
color_depth = AMF_COLOR_BIT_DEPTH_10;
+ profile = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10;
+ avctx->profile = AV_PROFILE_HEVC_MAIN_10;
}
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, color_depth);
- if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
- /// Color Transfer Characteristics (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
- /// Color Primaries (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
- } else {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
- }
+ /// HEVC Profile
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_PROFILE, profile);
+ /// Color Transfer Characteristics (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, avctx->color_trc);
+ /// Color Primaries (AMF matches ISO/IEC)
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, avctx->color_primaries);
// Picture control properties
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, avctx->gop_size);
+ if (avctx->gop_size != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, avctx->gop_size);
+ }
if (avctx->slices > 1) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_SLICES_PER_FRAME, avctx->slices);
}
- AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_DE_BLOCKING_FILTER_DISABLE, deblocking_filter);
+ AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_DE_BLOCKING_FILTER_DISABLE, !deblocking_filter);
if (ctx->header_insertion_mode != -1) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE, ctx->header_insertion_mode);
@@ -369,7 +390,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (avctx->rc_max_rate) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE, avctx->rc_max_rate);
} else if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR) {
- av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
+ av_log(ctx, AV_LOG_DEBUG, "rate control mode is vbr_peak but max_rate is not set, default max_rate will be applied.\n");
}
if (ctx->latency != -1) {
@@ -429,6 +450,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
+ // Wait inside QueryOutput() if supported by the driver
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_QUERY_TIMEOUT, 1);
+ res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, AMF_VIDEO_ENCODER_HEVC_QUERY_TIMEOUT, &var);
+ ctx->query_timeout_supported = res == AMF_OK && var.int64Value;
+
// init encoder
res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, avctx->width, avctx->height);
AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() failed with error %d\n", res);
@@ -438,29 +464,56 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_AU_SIZE, ctx->max_au_size);
}
- if (ctx->min_qp_i != -1) {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, ctx->min_qp_i);
- } else if (avctx->qmin != -1) {
- int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, qval);
- }
- if (ctx->max_qp_i != -1) {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, ctx->max_qp_i);
- } else if (avctx->qmax != -1) {
- int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, qval);
- }
- if (ctx->min_qp_p != -1) {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, ctx->min_qp_p);
- } else if (avctx->qmin != -1) {
- int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, qval);
- }
- if (ctx->max_qp_p != -1) {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, ctx->max_qp_p);
- } else if (avctx->qmax != -1) {
- int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, qval);
+ if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, 0);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, 51);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, 0);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, 51);
+ } else {
+ if (ctx->min_qp_i != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, ctx->min_qp_i);
+ } else if (avctx->qmin != -1) {
+ int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, qval);
+ }
+ if (ctx->max_qp_i != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, ctx->max_qp_i);
+ } else if (avctx->qmax != -1) {
+ int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, qval);
+ }
+ if (ctx->min_qp_p != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, ctx->min_qp_p);
+ } else if (avctx->qmin != -1) {
+ int qval = avctx->qmin > 51 ? 51 : avctx->qmin;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, qval);
+ }
+ if (ctx->max_qp_p != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, ctx->max_qp_p);
+ } else if (avctx->qmax != -1) {
+ int qval = avctx->qmax > 51 ? 51 : avctx->qmax;
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, qval);
+ }
+ /* Custom tuning */
+ if (ctx->min_qp_i == -1 && ctx->max_qp_i == -1 && ctx->min_qp_p == -1 && ctx->max_qp_p == -1 &&
+ avctx->qmin == -1 && avctx->qmax == -1) {
+ switch (ctx->usage) {
+ case AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING:
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, 18);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, 46);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, 18);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, 46);
+ break;
+ case AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY:
+ case AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY:
+ case AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM:
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_I, 22);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, 48);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MIN_QP_P, 22);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MAX_QP_P, 48);
+ break;
+ }
+ }
}
if (ctx->qp_p != -1) {
@@ -511,6 +564,7 @@ static const FFCodecDefault defaults[] =
{ "slices", "1" },
{ "qmin", "-1" },
{ "qmax", "-1" },
+ { "flags", "+loop"},
{ NULL },
};
static const AVClass hevc_amf_class = {
@@ -535,8 +589,8 @@ const FFCodec ff_hevc_amf_encoder = {
AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
FF_CODEC_CAP_INIT_CLEANUP,
- .p.pix_fmts = ff_amf_pix_fmts,
- .color_ranges = AVCOL_RANGE_MPEG, /* FIXME: implement tagging */
+ .p.pix_fmts = ff_amfenc_hevc_pix_fmts,
+ .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
.p.wrapper_name = "amf",
.hw_configs = ff_amfenc_hw_configs,
};
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3889,6 +3889,7 @@ rubberband_filter_deps="librubberband"
@@ -3935,6 +3935,7 @@ rubberband_filter_deps="librubberband"
sab_filter_deps="gpl swscale"
scale2ref_filter_deps="swscale"
scale_filter_deps="swscale"
@@ -14,7 +14,7 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -459,6 +459,7 @@ OBJS-$(CONFIG_SCALE_FILTER)
@@ -461,6 +461,7 @@ OBJS-$(CONFIG_SCALE_FILTER)
OBJS-$(CONFIG_SCALE_CUDA_FILTER) += vf_scale_cuda.o scale_eval.o \
vf_scale_cuda.ptx.o cuda/load_helper.o
OBJS-$(CONFIG_SCALE_NPP_FILTER) += vf_scale_npp.o scale_eval.o
@@ -26,7 +26,7 @@ Index: FFmpeg/libavfilter/allfilters.c
===================================================================
--- FFmpeg.orig/libavfilter/allfilters.c
+++ FFmpeg/libavfilter/allfilters.c
@@ -432,6 +432,7 @@ extern const AVFilter ff_vf_sab;
@@ -433,6 +433,7 @@ extern const AVFilter ff_vf_sab;
extern const AVFilter ff_vf_scale;
extern const AVFilter ff_vf_scale_cuda;
extern const AVFilter ff_vf_scale_npp;
@@ -331,7 +331,7 @@ Index: FFmpeg/libavfilter/vf_scale_opencl.c
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_scale_opencl.c
@@ -0,0 +1,777 @@
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 2018 Gabriel Machado
+ * Copyright (c) 2021 NyanMisaka
@@ -354,13 +354,13 @@ Index: FFmpeg/libavfilter/vf_scale_opencl.c
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "filters.h"
+#include "opencl.h"
+#include "opencl_source.h"
+#include "scale_eval.h"
@@ -762,8 +762,10 @@ Index: FFmpeg/libavfilter/vf_scale_opencl.c
+
+static int scale_opencl_config_output(AVFilterLink *outlink)
+{
+ FilterLink *outl = ff_filter_link(outlink);
+ AVFilterContext *avctx = outlink->src;
+ AVFilterLink *inlink = avctx->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ ScaleOpenCLContext *ctx = avctx->priv;
+ AVHWFramesContext *in_frames_ctx;
+ enum AVPixelFormat in_format;
@@ -772,9 +774,9 @@ Index: FFmpeg/libavfilter/vf_scale_opencl.c
+ const AVPixFmtDescriptor *out_desc;
+ int ret;
+
+ if (!inlink->hw_frames_ctx)
+ if (!inl->hw_frames_ctx)
+ return AVERROR(EINVAL);
+ in_frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ in_frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ in_format = in_frames_ctx->sw_format;
+ out_format = (ctx->format == AV_PIX_FMT_NONE) ? in_format : ctx->format;
+ in_desc = av_pix_fmt_desc_get(in_format);
@@ -818,9 +820,9 @@ Index: FFmpeg/libavfilter/vf_scale_opencl.c
+ ctx->ocf.output_height = ctx->dst_h;
+
+ if (ctx->passthrough && ctx->src_w == ctx->dst_w && ctx->src_h == ctx->dst_h && ctx->in_fmt == ctx->out_fmt) {
+ av_buffer_unref(&outlink->hw_frames_ctx);
+ outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
+ if (!outlink->hw_frames_ctx)
+ av_buffer_unref(&outl->hw_frames_ctx);
+ outl->hw_frames_ctx = av_buffer_ref(inl->hw_frames_ctx);
+ if (!outl->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+ return 0;
+ } else {
@@ -2,16 +2,89 @@ Index: FFmpeg/libavfilter/opencl.c
===================================================================
--- FFmpeg.orig/libavfilter/opencl.c
+++ FFmpeg/libavfilter/opencl.c
@@ -169,7 +169,7 @@ int ff_opencl_filter_load_program(AVFilt
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <string.h>
+#include "libavutil/avassert.h"
#include "libavutil/file_open.h"
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
@@ -156,6 +157,29 @@ void ff_opencl_filter_uninit(AVFilterCon
av_buffer_unref(&ctx->device_ref);
}
+#if ARCH_AARCH64 && (defined(__linux__) || defined(__ANDROID__))
+static char *check_opencl_device_str(cl_device_id device_id,
+ cl_device_info key)
+{
+ char *str;
+ size_t size;
+ cl_int cle;
+ cle = clGetDeviceInfo(device_id, key, 0, NULL, &size);
+ if (cle != CL_SUCCESS)
+ return NULL;
+ str = av_malloc(size);
+ if (!str)
+ return NULL;
+ cle = clGetDeviceInfo(device_id, key, size, str, &size);
+ if (cle != CL_SUCCESS) {
+ av_free(str);
+ return NULL;
+ }
+ av_assert0(strlen(str) + 1== size);
+ return str;
+}
+#endif
+
int ff_opencl_filter_load_program(AVFilterContext *avctx,
const char **program_source_array,
int nb_strings)
@@ -171,8 +195,42 @@ int ff_opencl_filter_load_program(AVFilt
return AVERROR(EIO);
}
+#if ARCH_AARCH64 && (defined(__linux__) || defined(__ANDROID__))
+ /* Try aggressive heuristics for the kernel vectorizer & unroller on libMali */
+ {
+ char *device_vendor = check_opencl_device_str(ctx->hwctx->device_id, CL_DEVICE_VENDOR);
+ char *device_name = check_opencl_device_str(ctx->hwctx->device_id, CL_DEVICE_NAME);
+
+ if (strstr(device_vendor, "ARM") &&
+ (strstr(device_name, "Mali") || strstr(device_name, "Immortalis"))) {
+ av_free(device_vendor);
+ av_free(device_name);
+
+ cle = clBuildProgram(ctx->program, 1, &ctx->hwctx->device_id,
+ "-cl-finite-math-only -cl-unsafe-math-optimizations "
+ "-fkernel-vectorizer -fkernel-unroller", NULL, NULL);
+ if (cle == CL_SUCCESS)
+ return 0;
+
+ /* Fall-back to standard build options */
+ clReleaseProgram(ctx->program);
+ ctx->program = clCreateProgramWithSource(ctx->hwctx->context, nb_strings,
+ program_source_array,
+ NULL, &cle);
+ if (!ctx->program) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create program: %d.\n", cle);
+ return AVERROR(EIO);
+ }
+ }
+ if (device_vendor)
+ av_free(device_vendor);
+ if (device_name)
+ av_free(device_name);
+ }
+#endif
+
cle = clBuildProgram(ctx->program, 1, &ctx->hwctx->device_id,
- NULL, NULL, NULL);
+ "-cl-finite-math-only -cl-unsafe-math-optimizations", NULL, NULL);
if (cle != CL_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to build program: %d.\n", cle);
@@ -330,7 +330,7 @@ void ff_opencl_print_const_matrix_3x3(AV
@@ -333,7 +391,7 @@ void ff_opencl_print_const_matrix_3x3(AV
av_bprintf(buf, "__constant float %s[9] = {\n", name_str);
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
@@ -84,7 +157,7 @@ Index: FFmpeg/libavfilter/opencl/colorspace_common.cl
#if chroma_loc == 1
#define chroma_sample(a,b,c,d) (((a) + (c)) * 0.5f)
@@ -33,88 +43,134 @@
@@ -33,88 +43,128 @@
#define chroma_sample(a,b,c,d) (((a) + (b) + (c) + (d)) * 0.25f)
#endif
@@ -213,8 +286,10 @@ Index: FFmpeg/libavfilter/opencl/colorspace_common.cl
+
+float inverse_ootf_1_2(float x) {
+ return x > 0.0f ? native_powr(x, 1.0f / 1.2f) : x;
+}
+
}
-float inverse_eotf_bt1886(float c) {
- return c < 0.0f ? 0.0f : powr(c, 1.0f / 2.4f);
+float oetf_arib_b67(float x) {
+ x = fmax(x, 0.0f);
+ return x <= (1.0f / 12.0f)
@@ -222,15 +297,6 @@ Index: FFmpeg/libavfilter/opencl/colorspace_common.cl
+ : (ARIB_B67_A * native_log(12.0f * x - ARIB_B67_B) + ARIB_B67_C);
}
-float inverse_eotf_bt1886(float c) {
- return c < 0.0f ? 0.0f : powr(c, 1.0f / 2.4f);
+float inverse_oetf_arib_b67(float x) {
+ x = fmax(x, 0.0f);
+ return x <= 0.5f
+ ? (x * x) * (1.0f / 3.0f)
+ : (native_exp((x - ARIB_B67_C) / ARIB_B67_A) + ARIB_B67_B) * (1.0f / 12.0f);
}
-float oetf_bt709(float c) {
- c = c < 0.0f ? 0.0f : c;
- float r1 = 4.5f * c;
@@ -241,11 +307,18 @@ Index: FFmpeg/libavfilter/opencl/colorspace_common.cl
- float r1 = c / 4.5f;
- float r2 = powr((c + 0.099f) / 1.099f, 1.0f / 0.45f);
- return c < 0.081f ? r1 : r2;
+float inverse_oetf_arib_b67(float x) {
+ x = fmax(x, 0.0f);
+ return x <= 0.5f
+ ? (x * x) * (1.0f / 3.0f)
+ : (native_exp((x - ARIB_B67_C) / ARIB_B67_A) + ARIB_B67_B) * (1.0f / 12.0f);
+}
+
+// linearizer for HLG/ARIB-B67
+float eotf_arib_b67(float x) {
+ return ootf_1_2(inverse_oetf_arib_b67(x)) * 5.0f;
}
+}
+
+// delinearizer for HLG/ARIB-B67
+float inverse_eotf_arib_b67(float x) {
+ return oetf_arib_b67(inverse_ootf_1_2(x / 5.0f));
@@ -254,14 +327,8 @@ Index: FFmpeg/libavfilter/opencl/colorspace_common.cl
+// delinearizer for BT709, BT2020-10
+float inverse_eotf_bt1886(float x) {
+ return x > 0.0f ? native_powr(x, 1.0f / 2.4f) : 0.0f;
+}
+
+#ifdef LUT_TRC
+float linearize_lut(float x) {
+ return lin_lut[clamp((int)(x * LUT_TRC), 0, LUT_TRC)];
+}
+#endif
+
}
float3 yuv2rgb(float y, float u, float v) {
-#ifdef FULL_RANGE_IN
- u -= 0.5f; v -= 0.5f;
@@ -280,7 +347,7 @@ Index: FFmpeg/libavfilter/opencl/colorspace_common.cl
#endif
float r = y * rgb_matrix[0] + u * rgb_matrix[1] + v * rgb_matrix[2];
float g = y * rgb_matrix[3] + u * rgb_matrix[4] + v * rgb_matrix[5];
@@ -138,19 +194,35 @@ float3 rgb2yuv(float r, float g, float b
@@ -138,19 +188,35 @@ float3 rgb2yuv(float r, float g, float b
float y = r*yuv_matrix[0] + g*yuv_matrix[1] + b*yuv_matrix[2];
float u = r*yuv_matrix[3] + g*yuv_matrix[4] + b*yuv_matrix[5];
float v = r*yuv_matrix[6] + g*yuv_matrix[7] + b*yuv_matrix[8];
@@ -322,7 +389,7 @@ Index: FFmpeg/libavfilter/opencl/colorspace_common.cl
return y;
}
@@ -188,18 +260,101 @@ float3 lrgb2lrgb(float3 c) {
@@ -188,18 +254,101 @@ float3 lrgb2lrgb(float3 c) {
#endif
}
@@ -526,7 +593,7 @@ Index: FFmpeg/libavfilter/opencl/tonemap.cl
float j = tone_param;
float a, b;
@@ -71,202 +85,611 @@ float mobius(float s, float peak) {
@@ -71,202 +85,618 @@ float mobius(float s, float peak) {
return s;
a = -j * j * (peak - 1.0f) / (j * j - 2.0f * j + peak);
@@ -769,10 +836,8 @@ Index: FFmpeg/libavfilter/opencl/tonemap.cl
+ float3 c = yuv2lrgb(yuv);
+#endif
+ return c;
}
-float3 map_one_pixel_rgb(float3 rgb, float peak, float average) {
- float sig = max(max(rgb.x, max(rgb.y, rgb.z)), 1e-6f);
+}
+
+// Map from source space YUV to destination space RGB
+float3 map_to_dst_space_from_yuv(float3 yuv) {
+#ifdef DOVI_RESHAPE
@@ -785,8 +850,10 @@ Index: FFmpeg/libavfilter/opencl/tonemap.cl
+ c = lrgb2lrgb(c);
+#endif
+ return c;
+}
+
}
-float3 map_one_pixel_rgb(float3 rgb, float peak, float average) {
- float sig = max(max(rgb.x, max(rgb.y, rgb.z)), 1e-6f);
+#ifdef DOVI_RESHAPE
+float reshape_poly(float s, float4 coeffs) {
+ return (coeffs.z * s + coeffs.y) * s + coeffs.x;
@@ -1072,7 +1139,7 @@ Index: FFmpeg/libavfilter/opencl/tonemap.cl
+ c1 = lrgb2lrgb(c1);
+ c2 = lrgb2lrgb(c2);
+ c3 = lrgb2lrgb(c3);
+ #if !defined(RGB2RGB_PASSTHROUGH) && !defined(DOVI_PERF_TRADEOFF)
+ #if !defined(RGB2RGB_PASSTHROUGH)
+ c0 = gamut_compress(c0);
+ c1 = gamut_compress(c1);
+ c2 = gamut_compress(c2);
@@ -1123,6 +1190,8 @@ Index: FFmpeg/libavfilter/opencl/tonemap.cl
+
+float3 apply_lut3d(__global float3 *lut, float3 color)
+{
+ color = clamp(color, 0.0f, 1.0f);
+
+ // Scale the color to the LUT grid.
+ float3 pos = color * (float)(LUT_SIZE - 1);
+
@@ -1132,17 +1201,22 @@ Index: FFmpeg/libavfilter/opencl/tonemap.cl
+ float3 f = pos - convert_float3(base);
+
+ // Compute the base linear index.
+ int baseIndex = base.x + base.y * LUT_SIZE + base.z * LUT_SIZE * LUT_SIZE;
+ unsigned base_idx = base.x + base.y * LUT_SIZE + base.z * LUT_SIZE * LUT_SIZE;
+
+#define LUT_IDX_MAX (LUT_SIZE * LUT_SIZE * LUT_SIZE - 1)
+#define LUT_IDX_OFFSET_MAX (1 + LUT_SIZE + LUT_SIZE * LUT_SIZE)
+
+ base_idx = min(base_idx, (unsigned)(LUT_IDX_MAX - LUT_IDX_OFFSET_MAX));
+
+ // Fetch the eight corner values of the current cube cell.
+ float3 c000 = lut[baseIndex];
+ float3 c100 = lut[baseIndex + 1];
+ float3 c010 = lut[baseIndex + LUT_SIZE];
+ float3 c110 = lut[baseIndex + 1 + LUT_SIZE];
+ float3 c001 = lut[baseIndex + LUT_SIZE * LUT_SIZE];
+ float3 c101 = lut[baseIndex + 1 + LUT_SIZE * LUT_SIZE];
+ float3 c011 = lut[baseIndex + LUT_SIZE + LUT_SIZE * LUT_SIZE];
+ float3 c111 = lut[baseIndex + 1 + LUT_SIZE + LUT_SIZE * LUT_SIZE];
+ float3 c000 = lut[base_idx];
+ float3 c100 = lut[base_idx + 1];
+ float3 c010 = lut[base_idx + LUT_SIZE];
+ float3 c110 = lut[base_idx + 1 + LUT_SIZE];
+ float3 c001 = lut[base_idx + LUT_SIZE * LUT_SIZE];
+ float3 c101 = lut[base_idx + 1 + LUT_SIZE * LUT_SIZE];
+ float3 c011 = lut[base_idx + LUT_SIZE + LUT_SIZE * LUT_SIZE];
+ float3 c111 = lut[base_idx + 1 + LUT_SIZE + LUT_SIZE * LUT_SIZE];
+
+ // Determine the tetrahedron within the cube cell.
+ // The tetrahedron selection is based on the ordering of the fractional parts.
@@ -1264,7 +1338,7 @@ Index: FFmpeg/libavfilter/opencl/tonemap.cl
+#endif
+}
+
+__kernel void build_lut(__global float3* lut, float peak)
+__kernel void build_lut(__global float3 *lut, float peak)
+{
+ const int total_entries = LUT_SIZE * LUT_SIZE * LUT_SIZE;
+ int idx = get_global_id(0);
@@ -1313,7 +1387,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
@@ -15,8 +15,15 @@
@@ -15,27 +15,46 @@
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -1327,32 +1401,46 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+#endif
+
#include "libavutil/avassert.h"
#include "libavutil/common.h"
-#include "libavutil/common.h"
#include "libavutil/imgutils.h"
@@ -29,13 +36,17 @@
+#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avfilter.h"
#include "filters.h"
+#include "formats.h"
#include "opencl.h"
#include "opencl_source.h"
#include "video.h"
#include "colorspace.h"
+#include "dither_matrix.h"
+
+#define OPENCL_SOURCE_NB 3
-// TODO:
-// - separate peak-detection from tone-mapping kernel to solve
-// one-frame-delay issue.
-// - more format support
+#define OPENCL_SOURCE_NB 3
-#define DETECTION_FRAMES 63
+static const enum AVPixelFormat supported_formats[] = {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_YUV420P16,
+ AV_PIX_FMT_NV12,
+ AV_PIX_FMT_P010,
+ AV_PIX_FMT_P016,
+};
-#define DETECTION_FRAMES 63
+static const int colorspaces_out[] = {
+ AVCOL_SPC_UNSPECIFIED,
+ AVCOL_SPC_BT709,
+ AVCOL_SPC_BT2020_NCL,
+ -1
+};
enum TonemapAlgorithm {
TONEMAP_NONE,
@@ -45,7 +56,17 @@ enum TonemapAlgorithm {
@@ -45,7 +64,17 @@ enum TonemapAlgorithm {
TONEMAP_REINHARD,
TONEMAP_HABLE,
TONEMAP_MOBIUS,
@@ -1371,7 +1459,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
};
typedef struct TonemapOpenCLContext {
@@ -56,23 +77,44 @@ typedef struct TonemapOpenCLContext {
@@ -56,23 +85,45 @@ typedef struct TonemapOpenCLContext {
enum AVColorPrimaries primaries, primaries_in, primaries_out;
enum AVColorRange range, range_in, range_out;
enum AVChromaLocation chroma_loc;
@@ -1389,6 +1477,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+#define mmr_sz mmr_cnt*sizeof(float)
+ struct DoviMetadata *dovi;
+ cl_mem dovi_buf;
+ int is_pure_dovi;
enum TonemapAlgorithm tonemap;
+ enum TonemapMode tonemap_mode;
@@ -1420,7 +1509,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
};
static const char *const delinearize_funcs[AVCOL_TRC_NB] = {
@@ -80,7 +122,7 @@ static const char *const delinearize_fun
@@ -80,7 +131,7 @@ static const char *const delinearize_fun
[AVCOL_TRC_BT2020_10] = "inverse_eotf_bt1886",
};
@@ -1429,26 +1518,26 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
[TONEMAP_NONE] = "direct",
[TONEMAP_LINEAR] = "linear",
[TONEMAP_GAMMA] = "gamma",
@@ -88,8 +130,18 @@ static const char *const tonemap_func[TO
@@ -88,8 +139,18 @@ static const char *const tonemap_func[TO
[TONEMAP_REINHARD] = "reinhard",
[TONEMAP_HABLE] = "hable",
[TONEMAP_MOBIUS] = "mobius",
+ [TONEMAP_BT2390] = "bt2390",
};
+};
+
+static const double dovi_lms2rgb_matrix[3][3] =
+{
+ { 3.06441879, -2.16597676, 0.10155818},
+ {-0.65612108, 1.78554118, -0.12943749},
+ { 0.01736321, -0.04725154, 1.03004253},
+};
+
};
+#define LUT_SIZE (65 * 65 * 65)
+
static int get_rgb2rgb_matrix(enum AVColorPrimaries in, enum AVColorPrimaries out,
double rgb2rgb[3][3]) {
double rgb2xyz[3][3], xyz2rgb[3][3];
@@ -108,90 +160,361 @@ static int get_rgb2rgb_matrix(enum AVCol
@@ -108,90 +169,368 @@ static int get_rgb2rgb_matrix(enum AVCol
return 0;
}
@@ -1466,7 +1555,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ cl_int cle;
+
+ pbuf = (float *)clEnqueueMapBuffer(ctx->command_queue, ctx->dovi_buf,
+ CL_TRUE, CL_MAP_WRITE, 0,
+ CL_TRUE, CL_MAP_WRITE_INVALIDATE_REGION, 0,
+ 3*(params_sz+pivots_sz+coeffs_sz+mmr_sz),
+ 0, NULL, NULL, &cle);
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to map dovi buf: %d.\n", cle);
@@ -1600,7 +1689,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
- const char *opencl_sources[OPENCL_SOURCE_NB];
-
- av_bprint_init(&header, 1024, AV_BPRINT_SIZE_AUTOMATIC);
+ cl_mem_flags dovi_buf_flags = CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR;
+ cl_mem_flags dovi_buf_flags = CL_MEM_ALLOC_HOST_PTR | CL_MEM_HOST_WRITE_ONLY | CL_MEM_READ_ONLY;
+ char *device_vendor = NULL;
+ char *device_name = NULL;
+ char *device_exts = NULL;
@@ -1705,6 +1794,13 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ ctx->tonemap_mode = TONEMAP_MODE_ITP;
+ }
+
+ // for low perf device, only do reshaping for pure dovi
+ if (ctx->tradeoff && ctx->dovi && !ctx->is_pure_dovi) {
+ av_freep(&ctx->dovi);
+ ctx->dovi = NULL;
+ ctx->apply_dovi = 0;
+ }
+
+ av_log(ctx, AV_LOG_DEBUG, "Tonemapping transfer from %s to %s\n",
av_color_transfer_name(ctx->trc_in),
av_color_transfer_name(ctx->trc_out));
@@ -1840,7 +1936,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
av_bprintf(&header, "#define chroma_loc %d\n", (int)ctx->chroma_loc);
if (rgb2rgb_passthrough)
@@ -199,19 +522,41 @@ static int tonemap_opencl_init(AVFilterC
@@ -199,19 +538,41 @@ static int tonemap_opencl_init(AVFilterC
else
ff_opencl_print_const_matrix_3x3(&header, "rgb2rgb", rgb2rgb);
@@ -1889,7 +1985,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
ctx->colorspace_out, av_color_space_name(ctx->colorspace_out));
goto fail;
}
@@ -219,24 +564,13 @@ static int tonemap_opencl_init(AVFilterC
@@ -219,24 +580,13 @@ static int tonemap_opencl_init(AVFilterC
ff_fill_rgb2yuv_table(luma_dst, rgb2yuv);
ff_opencl_print_const_matrix_3x3(&header, "yuv_matrix", rgb2yuv);
@@ -1919,7 +2015,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
av_log(avctx, AV_LOG_DEBUG, "Generated OpenCL header:\n%s\n", header.str);
opencl_sources[0] = header.str;
@@ -254,46 +588,213 @@ static int tonemap_opencl_init(AVFilterC
@@ -254,46 +604,216 @@ static int tonemap_opencl_init(AVFilterC
CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create OpenCL "
"command queue %d.\n", cle);
@@ -1973,7 +2069,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ ctx->lut_generation_kernel = clCreateKernel(ctx->ocf.program, "build_lut", &cle);
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create kernel %d.\n", cle);
+
+ CL_CREATE_BUFFER_FLAGS(ctx, lut_buffer, CL_MEM_READ_WRITE, lut_buffer_size, NULL);
+ CL_CREATE_BUFFER_FLAGS(ctx, lut_buffer, CL_MEM_HOST_NO_ACCESS | CL_MEM_READ_WRITE, lut_buffer_size, NULL);
+ CL_SET_KERNEL_ARG(ctx->lut_generation_kernel, 0, cl_mem, &ctx->lut_buffer);
+ CL_SET_KERNEL_ARG(ctx->lut_generation_kernel, 1, cl_float, &peak);
+
@@ -1982,6 +2078,8 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ 0, NULL, NULL);
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to enqueue build_lut kernel: %d.\n", cle);
+
+ cle = clFinish(ctx->command_queue);
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to finish command queue: %d.\n", cle);
+
+ ctx->kernel = clCreateKernel(ctx->ocf.program, "tonemap_lut", &cle);
+ CL_FAIL_ON_ERROR(AVERROR(EIO), "Failed to create kernel %d.\n", cle);
@@ -2080,12 +2178,12 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ ctx->initialised = 0;
+}
+
+ static av_cold int tonemap_opencl_preinit(AVFilterContext *avctx)
+ {
+ TonemapOpenCLContext *ctx = avctx->priv;
+ ctx->final_param = NAN;
+ return 0;
+ }
+static av_cold int tonemap_opencl_preinit(AVFilterContext *avctx)
+{
+ TonemapOpenCLContext *ctx = avctx->priv;
+ ctx->final_param = NAN;
+ return 0;
+}
+
+static int format_is_supported(enum AVPixelFormat fmt)
+{
@@ -2101,6 +2199,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
- TonemapOpenCLContext *s = avctx->priv;
+ AVFilterContext *avctx = outlink->src;
+ AVFilterLink *inlink = avctx->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ TonemapOpenCLContext *ctx = avctx->priv;
+ AVHWFramesContext *in_frames_ctx;
+ enum AVPixelFormat in_format;
@@ -2116,10 +2215,10 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
- av_log(avctx, AV_LOG_ERROR, "unsupported output format,"
- "only p010/nv12 supported now\n");
+
+ if (!inlink->hw_frames_ctx)
+ if (!inl->hw_frames_ctx)
return AVERROR(EINVAL);
- }
+ in_frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ in_frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ in_format = in_frames_ctx->sw_format;
+ out_format = (ctx->format == AV_PIX_FMT_NONE) ? in_format : ctx->format;
+ in_desc = av_pix_fmt_desc_get(in_format);
@@ -2134,13 +2233,14 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ av_log(ctx, AV_LOG_ERROR, "Unsupported output format: %s\n",
+ av_get_pix_fmt_name(out_format));
+ return AVERROR(ENOSYS);
}
+ }
+ if (in_desc->comp[0].depth != 10 && in_desc->comp[0].depth != 16) {
+ av_log(ctx, AV_LOG_ERROR, "Unsupported input format depth: %d\n",
+ in_desc->comp[0].depth);
+ return AVERROR(ENOSYS);
+ }
+
}
- s->ocf.output_format = s->format == AV_PIX_FMT_NONE ? AV_PIX_FMT_NV12 : s->format;
+ ctx->in_fmt = in_format;
+ ctx->out_fmt = out_format;
+ ctx->in_desc = in_desc;
@@ -2148,23 +2248,16 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ ctx->in_planes = av_pix_fmt_count_planes(in_format);
+ ctx->out_planes = av_pix_fmt_count_planes(out_format);
+ ctx->ocf.output_format = out_format;
- s->ocf.output_format = s->format == AV_PIX_FMT_NONE ? AV_PIX_FMT_NV12 : s->format;
+
ret = ff_opencl_filter_config_output(outlink);
if (ret < 0)
return ret;
@@ -308,13 +809,49 @@ static int launch_kernel(AVFilterContext
@@ -308,13 +828,49 @@ static int launch_kernel(AVFilterContext
size_t global_work[2];
size_t local_work[2];
cl_int cle;
+ int idx_arg;
- CL_SET_KERNEL_ARG(kernel, 0, cl_mem, &output->data[0]);
- CL_SET_KERNEL_ARG(kernel, 1, cl_mem, &input->data[0]);
- CL_SET_KERNEL_ARG(kernel, 2, cl_mem, &output->data[1]);
- CL_SET_KERNEL_ARG(kernel, 3, cl_mem, &input->data[1]);
- CL_SET_KERNEL_ARG(kernel, 4, cl_mem, &ctx->util_mem);
- CL_SET_KERNEL_ARG(kernel, 5, cl_float, &peak);
+
+ if (!output->data[0] || !input->data[0] || !output->data[1] || !input->data[1]) {
+ err = AVERROR(EIO);
+ goto fail;
@@ -2204,12 +2297,18 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ if (ctx->dovi_buf) {
+ CL_SET_KERNEL_ARG(kernel, idx_arg++, cl_mem, &ctx->dovi_buf);
+ }
+
- CL_SET_KERNEL_ARG(kernel, 0, cl_mem, &output->data[0]);
- CL_SET_KERNEL_ARG(kernel, 1, cl_mem, &input->data[0]);
- CL_SET_KERNEL_ARG(kernel, 2, cl_mem, &output->data[1]);
- CL_SET_KERNEL_ARG(kernel, 3, cl_mem, &input->data[1]);
- CL_SET_KERNEL_ARG(kernel, 4, cl_mem, &ctx->util_mem);
- CL_SET_KERNEL_ARG(kernel, 5, cl_float, &peak);
+ CL_SET_KERNEL_ARG(kernel, idx_arg++, cl_float, &peak);
local_work[0] = 16;
local_work[1] = 16;
@@ -338,13 +875,10 @@ static int tonemap_opencl_filter_frame(A
@@ -338,12 +894,10 @@ static int tonemap_opencl_filter_frame(A
AVFilterContext *avctx = inlink->dst;
AVFilterLink *outlink = avctx->outputs[0];
TonemapOpenCLContext *ctx = avctx->priv;
@@ -2219,12 +2318,19 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
int err;
- double peak = ctx->peak;
-
- AVHWFramesContext *input_frames_ctx =
- (AVHWFramesContext*)input->hw_frames_ctx->data;
- AVHWFramesContext *input_frames_ctx;
av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
av_get_pix_fmt_name(input->format),
@@ -363,8 +897,49 @@ static int tonemap_opencl_filter_frame(A
@@ -351,7 +905,6 @@ static int tonemap_opencl_filter_frame(A
if (!input->hw_frames_ctx)
return AVERROR(EINVAL);
- input_frames_ctx = (AVHWFramesContext*)input->hw_frames_ctx->data;
output = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!output) {
@@ -363,17 +916,59 @@ static int tonemap_opencl_filter_frame(A
if (err < 0)
goto fail;
@@ -2265,18 +2371,32 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
+ if (!ctx->dovi)
+ goto fail;
+
+ ctx->is_pure_dovi = rpu->vdr_rpu_profile == 0;
+
+ ff_map_dovi_metadata(ctx->dovi, metadata);
+ output->color_trc = input->color_trc = AVCOL_TRC_SMPTE2084;
+ output->colorspace = input->colorspace = AVCOL_SPC_BT2020_NCL;
+ output->color_primaries = input->color_primaries = AVCOL_PRI_BT2020;
+ if (rpu->bl_video_full_range_flag)
+ output->color_range = input->color_range = AVCOL_RANGE_JPEG;
+ input->color_range = AVCOL_RANGE_JPEG;
+ }
+ }
if (ctx->trc != -1)
output->color_trc = ctx->trc;
@@ -385,72 +960,50 @@ static int tonemap_opencl_filter_frame(A
if (ctx->primaries != -1)
output->color_primaries = ctx->primaries;
- if (ctx->colorspace != -1)
- output->colorspace = ctx->colorspace;
- if (ctx->range != -1)
- output->color_range = ctx->range;
+
+ output->colorspace = outlink->colorspace;
+ output->color_range = outlink->color_range;
ctx->trc_in = input->color_trc;
ctx->trc_out = output->color_trc;
@@ -385,72 +980,50 @@ static int tonemap_opencl_filter_frame(A
ctx->range_out = output->color_range;
ctx->chroma_loc = output->chroma_location;
@@ -2372,13 +2492,24 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
av_frame_free(&input);
av_frame_free(&output);
return err;
@@ -458,24 +1011,9 @@ fail:
@@ -458,62 +1031,101 @@ fail:
static av_cold void tonemap_opencl_uninit(AVFilterContext *avctx)
{
- TonemapOpenCLContext *ctx = avctx->priv;
- cl_int cle;
+ tonemap_opencl_uninit_common(avctx);
+
+ tonemap_opencl_uninit_dovi(avctx);
+
+ ff_opencl_filter_uninit(avctx);
+}
+
+static int tonemap_opencl_query_formats(AVFilterContext *avctx)
+{
TonemapOpenCLContext *ctx = avctx->priv;
- cl_int cle;
+ AVFilterFormats *formats;
+ int ret;
+ const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_OPENCL, AV_PIX_FMT_NONE };
- if (ctx->util_mem)
- clReleaseMemObject(ctx->util_mem);
@@ -2388,18 +2519,47 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
- av_log(avctx, AV_LOG_ERROR, "Failed to release "
- "kernel: %d.\n", cle);
- }
-
+ // single format
+ formats = ff_make_format_list(pix_fmts);
+ ret = ff_formats_ref(formats, &avctx->inputs[0]->outcfg.formats);
+ if (ret < 0)
+ return ret;
- if (ctx->command_queue) {
- cle = clReleaseCommandQueue(ctx->command_queue);
- if (cle != CL_SUCCESS)
- av_log(avctx, AV_LOG_ERROR, "Failed to release "
- "command queue: %d.\n", cle);
- }
+ tonemap_opencl_uninit_dovi(avctx);
+ ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.formats);
+ if (ret < 0)
+ return ret;
ff_opencl_filter_uninit(avctx);
- ff_opencl_filter_uninit(avctx);
+ // colorspaces and ranges
+ if ((ret = ff_formats_ref(ff_all_color_spaces(),
+ &avctx->inputs[0]->outcfg.color_spaces)) < 0)
+ return ret;
+
+ if ((ret = ff_formats_ref(ff_all_color_ranges(),
+ &avctx->inputs[0]->outcfg.color_ranges)) < 0)
+ return ret;
+
+ formats = ctx->colorspace != -1
+ ? ff_make_formats_list_singleton(ctx->colorspace)
+ : ff_make_format_list(colorspaces_out);
+ if ((ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.color_spaces)) < 0)
+ return ret;
+
+ formats = ctx->range != -1
+ ? ff_make_formats_list_singleton(ctx->range)
+ : ff_all_color_ranges();
+ if ((ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.color_ranges)) < 0)
+ return ret;
+
+ return 0;
}
@@ -483,37 +1021,50 @@ static av_cold void tonemap_opencl_unini
#define OFFSET(x) offsetof(TonemapOpenCLContext, x)
#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
static const AVOption tonemap_opencl_options[] = {
@@ -2481,7 +2641,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
{ NULL }
};
@@ -541,6 +1092,7 @@ const AVFilter ff_vf_tonemap_opencl = {
@@ -541,11 +1153,12 @@ const AVFilter ff_vf_tonemap_opencl = {
.description = NULL_IF_CONFIG_SMALL("Perform HDR to SDR conversion with tonemapping."),
.priv_size = sizeof(TonemapOpenCLContext),
.priv_class = &tonemap_opencl_class,
@@ -2489,3 +2649,9 @@ Index: FFmpeg/libavfilter/vf_tonemap_opencl.c
.init = &ff_opencl_filter_init,
.uninit = &tonemap_opencl_uninit,
FILTER_INPUTS(tonemap_opencl_inputs),
FILTER_OUTPUTS(tonemap_opencl_outputs),
- FILTER_SINGLE_PIXFMT(AV_PIX_FMT_OPENCL),
+ FILTER_QUERY_FUNC(tonemap_opencl_query_formats),
.flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
.flags = AVFILTER_FLAG_HWDEVICE,
};
+11 -9
View File
@@ -453,12 +453,12 @@ Index: FFmpeg/libavfilter/vf_overlay_opencl.c
- (AVHWFramesContext*)input_overlay->hw_frames_ctx->data;
+ if (!input_main)
+ return AVERROR_BUG;
+
+ if (!input_overlay)
+ passthrough = 1;
- err = overlay_opencl_load(avctx, main_fc->sw_format,
- overlay_fc->sw_format);
+ if (!input_overlay)
+ passthrough = 1;
+
+ if (!ctx->initialised) {
+ err = overlay_opencl_load(avctx);
if (err < 0)
@@ -532,16 +532,18 @@ Index: FFmpeg/libavfilter/vf_overlay_opencl.c
av_frame_free(&output);
return err;
}
@@ -224,8 +330,49 @@ static int overlay_opencl_config_output(
@@ -224,8 +330,51 @@ static int overlay_opencl_config_output(
{
AVFilterContext *avctx = outlink->src;
OverlayOpenCLContext *ctx = avctx->priv;
+
+ AVFilterLink *inlink = avctx->inputs[0];
+ AVHWFramesContext *frames_ctx_main = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ FilterLink *inl = ff_filter_link(inlink);
+ AVHWFramesContext *frames_ctx_main = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+
+ AVFilterLink *inlink_overlay = avctx->inputs[1];
+ AVHWFramesContext *frames_ctx_overlay = (AVHWFramesContext*)inlink_overlay->hw_frames_ctx->data;
+ FilterLink *inl_overlay = ff_filter_link(inlink_overlay);
+ AVHWFramesContext *frames_ctx_overlay = (AVHWFramesContext*)inl_overlay->hw_frames_ctx->data;
+
int err;
@@ -582,7 +584,7 @@ Index: FFmpeg/libavfilter/vf_overlay_opencl.c
err = ff_opencl_filter_config_output(outlink);
if (err < 0)
return err;
@@ -234,6 +381,11 @@ static int overlay_opencl_config_output(
@@ -234,6 +383,11 @@ static int overlay_opencl_config_output(
if (err < 0)
return err;
@@ -594,7 +596,7 @@ Index: FFmpeg/libavfilter/vf_overlay_opencl.c
return ff_framesync_configure(&ctx->fs);
}
@@ -265,6 +417,20 @@ static av_cold void overlay_opencl_unini
@@ -265,6 +419,20 @@ static av_cold void overlay_opencl_unini
"kernel: %d.\n", cle);
}
@@ -615,7 +617,7 @@ Index: FFmpeg/libavfilter/vf_overlay_opencl.c
if (ctx->command_queue) {
cle = clReleaseCommandQueue(ctx->command_queue);
if (cle != CL_SUCCESS)
@@ -279,11 +445,20 @@ static av_cold void overlay_opencl_unini
@@ -279,11 +447,20 @@ static av_cold void overlay_opencl_unini
#define OFFSET(x) offsetof(OverlayOpenCLContext, x)
#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/avfilter.h
===================================================================
--- FFmpeg.orig/libavfilter/avfilter.h
+++ FFmpeg/libavfilter/avfilter.h
@@ -564,6 +564,8 @@ struct AVFilterLink {
@@ -579,6 +579,8 @@ struct AVFilterLink {
enum AVColorSpace colorspace; ///< agreed upon YUV color space
enum AVColorRange color_range; ///< agreed upon YUV color range
@@ -15,7 +15,7 @@ Index: FFmpeg/libavfilter/opencl.c
===================================================================
--- FFmpeg.orig/libavfilter/opencl.c
+++ FFmpeg/libavfilter/opencl.c
@@ -75,6 +75,9 @@ int ff_opencl_filter_config_input(AVFilt
@@ -77,6 +77,9 @@ int ff_opencl_filter_config_input(AVFilt
if (!ctx->output_height)
ctx->output_height = inlink->h;
@@ -25,7 +25,7 @@ Index: FFmpeg/libavfilter/opencl.c
return 0;
}
@@ -123,6 +126,9 @@ int ff_opencl_filter_config_output(AVFil
@@ -126,6 +129,9 @@ int ff_opencl_filter_config_output(AVFil
outlink->w = ctx->output_width;
outlink->h = ctx->output_height;
@@ -48,9 +48,9 @@ Index: FFmpeg/libavfilter/vf_hwmap.c
+#endif
+
#include "avfilter.h"
#include "filters.h"
#include "formats.h"
#include "internal.h"
@@ -122,6 +126,12 @@ static int hwmap_config_output(AVFilterL
@@ -124,6 +128,12 @@ static int hwmap_config_output(AVFilterL
goto fail;
}
@@ -63,7 +63,7 @@ Index: FFmpeg/libavfilter/vf_hwmap.c
} else if (inlink->format == hwfc->format &&
(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
ctx->reverse) {
@@ -131,6 +141,9 @@ static int hwmap_config_output(AVFilterL
@@ -133,6 +143,9 @@ static int hwmap_config_output(AVFilterL
// mapped from that back to the source type.
AVBufferRef *source;
AVHWFramesContext *frames;
@@ -73,7 +73,7 @@ Index: FFmpeg/libavfilter/vf_hwmap.c
ctx->hwframes_ref = av_hwframe_ctx_alloc(device);
if (!ctx->hwframes_ref) {
@@ -144,8 +157,19 @@ static int hwmap_config_output(AVFilterL
@@ -146,8 +159,19 @@ static int hwmap_config_output(AVFilterL
frames->width = hwfc->width;
frames->height = hwfc->height;
@@ -84,8 +84,8 @@ Index: FFmpeg/libavfilter/vf_hwmap.c
+
+ if (frames->initial_pool_size == 0) {
+ // Dynamic allocation.
+ } else if (avctx->extra_hw_frames) {
+ frames->initial_pool_size += avctx->extra_hw_frames;
+ } else {
+ frames->initial_pool_size += (avctx->extra_hw_frames > 2 ? avctx->extra_hw_frames : 2);
+ }
+
+#if HAVE_OPENCL_D3D11
@@ -108,10 +108,10 @@ Index: FFmpeg/libavfilter/vf_hwupload.c
+#endif
+
#include "avfilter.h"
#include "filters.h"
#include "formats.h"
#include "internal.h"
@@ -110,6 +114,9 @@ static int hwupload_config_output(AVFilt
AVFilterLink *inlink = avctx->inputs[0];
@@ -112,6 +116,9 @@ static int hwupload_config_output(AVFilt
FilterLink *inl = ff_filter_link(inlink);
HWUploadContext *ctx = avctx->priv;
int err;
+#if HAVE_OPENCL_D3D11
@@ -120,7 +120,7 @@ Index: FFmpeg/libavfilter/vf_hwupload.c
av_buffer_unref(&ctx->hwframes_ref);
@@ -151,6 +158,11 @@ static int hwupload_config_output(AVFilt
@@ -153,6 +160,11 @@ static int hwupload_config_output(AVFilt
if (avctx->extra_hw_frames >= 0)
ctx->hwframes->initial_pool_size = 2 + avctx->extra_hw_frames;
@@ -136,7 +136,7 @@ Index: FFmpeg/libavutil/hwcontext_d3d11va.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_d3d11va.c
+++ FFmpeg/libavutil/hwcontext_d3d11va.c
@@ -227,7 +227,7 @@ static AVBufferRef *d3d11va_alloc_single
@@ -229,7 +229,7 @@ static AVBufferRef *d3d11va_alloc_single
.ArraySize = 1,
.Usage = D3D11_USAGE_DEFAULT,
.BindFlags = hwctx->BindFlags,
@@ -145,7 +145,7 @@ Index: FFmpeg/libavutil/hwcontext_d3d11va.c
};
hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc, NULL, &tex);
@@ -291,9 +291,17 @@ static int d3d11va_frames_init(AVHWFrame
@@ -293,9 +293,17 @@ static int d3d11va_frames_init(AVHWFrame
.ArraySize = ctx->initial_pool_size,
.Usage = D3D11_USAGE_DEFAULT,
.BindFlags = hwctx->BindFlags,
@@ -145,7 +145,7 @@ Index: FFmpeg/libavutil/hwcontext_qsv.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_qsv.c
+++ FFmpeg/libavutil/hwcontext_qsv.c
@@ -369,7 +369,7 @@ static void qsv_frames_uninit(AVHWFrames
@@ -379,7 +379,7 @@ static void qsv_frames_uninit(AVHWFrames
av_buffer_unref(&s->child_frames_ref);
}
@@ -154,7 +154,7 @@ Index: FFmpeg/libavutil/hwcontext_qsv.c
{
}
@@ -382,7 +382,7 @@ static AVBufferRef *qsv_pool_alloc(void
@@ -417,7 +417,7 @@ static AVBufferRef *qsv_fixed_pool_alloc
if (s->nb_surfaces_used < hwctx->nb_surfaces) {
s->nb_surfaces_used++;
return av_buffer_create((uint8_t*)(s->surfaces_internal + s->nb_surfaces_used - 1),
@@ -163,7 +163,7 @@ Index: FFmpeg/libavutil/hwcontext_qsv.c
}
return NULL;
@@ -2272,8 +2272,17 @@ static int qsv_device_create(AVHWDeviceC
@@ -2617,8 +2617,17 @@ static int qsv_device_create(AVHWDeviceC
child_device = (AVHWDeviceContext*)priv->child_device_ctx->data;
impl = choose_implementation(device, child_device_type);
+1 -1
View File
@@ -2,7 +2,7 @@ Index: FFmpeg/libavutil/hwcontext_d3d11va.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_d3d11va.c
+++ FFmpeg/libavutil/hwcontext_d3d11va.c
@@ -638,6 +638,8 @@ static int d3d11va_device_create(AVHWDev
@@ -640,6 +640,8 @@ static int d3d11va_device_create(AVHWDev
adapter = atoi(device);
} else {
AVDictionaryEntry *e = av_dict_get(opts, "vendor_id", NULL, 0);
+11 -9
View File
@@ -2,19 +2,19 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3840,6 +3840,7 @@ gblur_vulkan_filter_deps="vulkan spirv_c
@@ -3884,6 +3884,7 @@ gblur_vulkan_filter_deps="vulkan spirv_c
hflip_vulkan_filter_deps="vulkan spirv_compiler"
histeq_filter_deps="gpl"
hqdn3d_filter_deps="gpl"
+hwupload_vaapi_filter_deps="vaapi"
iccdetect_filter_deps="lcms2"
iccgen_filter_deps="lcms2"
interlace_filter_deps="gpl"
identity_filter_select="scene_sad"
Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -346,6 +346,7 @@ OBJS-$(CONFIG_HUESATURATION_FILTER)
@@ -347,6 +347,7 @@ OBJS-$(CONFIG_HUESATURATION_FILTER)
OBJS-$(CONFIG_HWDOWNLOAD_FILTER) += vf_hwdownload.o
OBJS-$(CONFIG_HWMAP_FILTER) += vf_hwmap.o
OBJS-$(CONFIG_HWUPLOAD_CUDA_FILTER) += vf_hwupload_cuda.o
@@ -38,7 +38,7 @@ Index: FFmpeg/libavfilter/vf_hwupload_vaapi.c
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_hwupload_vaapi.c
@@ -0,0 +1,193 @@
@@ -0,0 +1,195 @@
+/*
+ * This file is part of FFmpeg.
+ *
@@ -63,8 +63,8 @@ Index: FFmpeg/libavfilter/vf_hwupload_vaapi.c
+#include "libavutil/opt.h"
+
+#include "avfilter.h"
+#include "filters.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct VaapiUploadContext {
@@ -123,8 +123,10 @@ Index: FFmpeg/libavfilter/vf_hwupload_vaapi.c
+
+static int vaapiupload_config_output(AVFilterLink *outlink)
+{
+ FilterLink *outl = ff_filter_link(outlink);
+ AVFilterContext *ctx = outlink->src;
+ AVFilterLink *inlink = ctx->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ VaapiUploadContext *s = ctx->priv;
+
+ AVHWFramesContext *hwframe_ctx;
@@ -137,8 +139,8 @@ Index: FFmpeg/libavfilter/vf_hwupload_vaapi.c
+
+ hwframe_ctx = (AVHWFramesContext*)s->hwframe->data;
+ hwframe_ctx->format = AV_PIX_FMT_VAAPI;
+ if (inlink->hw_frames_ctx) {
+ AVHWFramesContext *in_hwframe_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ if (inl->hw_frames_ctx) {
+ AVHWFramesContext *in_hwframe_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ hwframe_ctx->sw_format = in_hwframe_ctx->sw_format;
+ } else {
+ hwframe_ctx->sw_format = inlink->format;
@@ -150,8 +152,8 @@ Index: FFmpeg/libavfilter/vf_hwupload_vaapi.c
+ if (ret < 0)
+ return ret;
+
+ outlink->hw_frames_ctx = av_buffer_ref(s->hwframe);
+ if (!outlink->hw_frames_ctx)
+ outl->hw_frames_ctx = av_buffer_ref(s->hwframe);
+ if (!outl->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+
+ return 0;
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vaapi.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_overlay_vaapi.c
+++ FFmpeg/libavfilter/vf_overlay_vaapi.c
@@ -311,8 +311,12 @@ static int overlay_vaapi_config_input_ov
@@ -312,8 +312,12 @@ static int overlay_vaapi_config_input_ov
ctx->blend_alpha = ctx->alpha;
}
@@ -1,311 +0,0 @@
Index: FFmpeg/libavfilter/vf_tonemap_vaapi.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_tonemap_vaapi.c
+++ FFmpeg/libavfilter/vf_tonemap_vaapi.c
@@ -39,7 +39,11 @@ typedef struct HDRVAAPIContext {
enum AVColorTransferCharacteristic color_transfer;
enum AVColorSpace color_matrix;
+ char *mastering_display;
+ char *content_light;
+
VAHdrMetaDataHDR10 in_metadata;
+ VAHdrMetaDataHDR10 out_metadata;
AVFrameSideData *src_display;
AVFrameSideData *src_light;
@@ -52,7 +56,7 @@ static int tonemap_vaapi_save_metadata(A
AVContentLightMetadata *light_meta;
if (input_frame->color_trc != AVCOL_TRC_SMPTE2084) {
- av_log(avctx, AV_LOG_WARNING, "Only support HDR10 as input for vaapi tone-mapping\n");
+ av_log(avctx, AV_LOG_DEBUG, "Only support HDR10 as input for vaapi tone-mapping\n");
}
ctx->src_display = av_frame_get_side_data(input_frame,
@@ -60,8 +64,7 @@ static int tonemap_vaapi_save_metadata(A
if (ctx->src_display) {
hdr_meta = (AVMasteringDisplayMetadata *)ctx->src_display->data;
if (!hdr_meta) {
- av_log(avctx, AV_LOG_ERROR, "No mastering display data\n");
- return AVERROR(EINVAL);
+ av_log(avctx, AV_LOG_DEBUG, "No mastering display data\n");
}
if (hdr_meta->has_luminance) {
@@ -118,8 +121,7 @@ static int tonemap_vaapi_save_metadata(A
ctx->in_metadata.white_point_y);
}
} else {
- av_log(avctx, AV_LOG_ERROR, "No mastering display data from input\n");
- return AVERROR(EINVAL);
+ av_log(avctx, AV_LOG_DEBUG, "No mastering display data from input\n");
}
ctx->src_light = av_frame_get_side_data(input_frame,
@@ -127,8 +129,7 @@ static int tonemap_vaapi_save_metadata(A
if (ctx->src_light) {
light_meta = (AVContentLightMetadata *)ctx->src_light->data;
if (!light_meta) {
- av_log(avctx, AV_LOG_ERROR, "No light metadata\n");
- return AVERROR(EINVAL);
+ av_log(avctx, AV_LOG_DEBUG, "No light metadata\n");
}
ctx->in_metadata.max_content_light_level = light_meta->MaxCLL;
@@ -146,6 +147,87 @@ static int tonemap_vaapi_save_metadata(A
return 0;
}
+static int tonemap_vaapi_update_sidedata(AVFilterContext *avctx, AVFrame *output_frame)
+{
+ HDRVAAPIContext *ctx = avctx->priv;
+ AVFrameSideData *metadata;
+ AVMasteringDisplayMetadata *hdr_meta;
+ AVFrameSideData *metadata_lt;
+ AVContentLightMetadata *hdr_meta_lt;
+ int i;
+ const int mapping[3] = {1, 2, 0}; //green, blue, red
+ const int chroma_den = 50000;
+ const int luma_den = 10000;
+
+ metadata = av_frame_new_side_data(output_frame,
+ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA,
+ sizeof(AVMasteringDisplayMetadata));
+ if (!metadata)
+ return AVERROR(ENOMEM);
+
+ hdr_meta = (AVMasteringDisplayMetadata *)metadata->data;
+
+ for (i = 0; i < 3; i++) {
+ const int j = mapping[i];
+ hdr_meta->display_primaries[j][0].num = ctx->out_metadata.display_primaries_x[i];
+ hdr_meta->display_primaries[j][0].den = chroma_den;
+
+ hdr_meta->display_primaries[j][1].num = ctx->out_metadata.display_primaries_y[i];
+ hdr_meta->display_primaries[j][1].den = chroma_den;
+ }
+
+ hdr_meta->white_point[0].num = ctx->out_metadata.white_point_x;
+ hdr_meta->white_point[0].den = chroma_den;
+
+ hdr_meta->white_point[1].num = ctx->out_metadata.white_point_y;
+ hdr_meta->white_point[1].den = chroma_den;
+ hdr_meta->has_primaries = 1;
+
+ hdr_meta->max_luminance.num = ctx->out_metadata.max_display_mastering_luminance;
+ hdr_meta->max_luminance.den = luma_den;
+
+ hdr_meta->min_luminance.num = ctx->out_metadata.min_display_mastering_luminance;
+ hdr_meta->min_luminance.den = luma_den;
+ hdr_meta->has_luminance = 1;
+
+ av_log(avctx, AV_LOG_DEBUG,
+ "Mastering display colour volume(out):\n");
+ av_log(avctx, AV_LOG_DEBUG,
+ "G(%u,%u) B(%u,%u) R(%u,%u) WP(%u,%u)\n",
+ ctx->out_metadata.display_primaries_x[0],
+ ctx->out_metadata.display_primaries_y[0],
+ ctx->out_metadata.display_primaries_x[1],
+ ctx->out_metadata.display_primaries_y[1],
+ ctx->out_metadata.display_primaries_x[2],
+ ctx->out_metadata.display_primaries_y[2],
+ ctx->out_metadata.white_point_x,
+ ctx->out_metadata.white_point_y);
+ av_log(avctx, AV_LOG_DEBUG,
+ "max_display_mastering_luminance=%u, min_display_mastering_luminance=%u\n",
+ ctx->out_metadata.max_display_mastering_luminance,
+ ctx->out_metadata.min_display_mastering_luminance);
+
+ metadata_lt = av_frame_new_side_data(output_frame,
+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ sizeof(AVContentLightMetadata));
+ if (!metadata_lt)
+ return AVERROR(ENOMEM);
+
+ hdr_meta_lt = (AVContentLightMetadata *)metadata_lt->data;
+
+ hdr_meta_lt->MaxCLL = FFMIN(ctx->out_metadata.max_content_light_level, 65535);
+ hdr_meta_lt->MaxFALL = FFMIN(ctx->out_metadata.max_pic_average_light_level, 65535);
+
+ av_log(avctx, AV_LOG_DEBUG,
+ "Content light level information(out):\n");
+ av_log(avctx, AV_LOG_DEBUG,
+ "MaxCLL(%u) MaxFALL(%u)\n",
+ ctx->out_metadata.max_content_light_level,
+ ctx->out_metadata.max_pic_average_light_level);
+
+ return 0;
+}
+
static int tonemap_vaapi_set_filter_params(AVFilterContext *avctx, AVFrame *input_frame)
{
VAAPIVPPContext *vpp_ctx = avctx->priv;
@@ -208,15 +290,26 @@ static int tonemap_vaapi_build_filter_pa
return AVERROR(EINVAL);
}
- for (i = 0; i < num_query_caps; i++) {
- if (VA_TONE_MAPPING_HDR_TO_SDR & hdr_cap[i].caps_flag)
- break;
- }
-
- if (i >= num_query_caps) {
- av_log(avctx, AV_LOG_ERROR,
- "VAAPI driver doesn't support HDR to SDR\n");
- return AVERROR(EINVAL);
+ if (ctx->mastering_display) {
+ for (i = 0; i < num_query_caps; i++) {
+ if (VA_TONE_MAPPING_HDR_TO_HDR & hdr_cap[i].caps_flag)
+ break;
+ }
+ if (i >= num_query_caps) {
+ av_log(avctx, AV_LOG_ERROR,
+ "VAAPI driver doesn't support HDR to HDR\n");
+ return AVERROR(EINVAL);
+ }
+ } else {
+ for (i = 0; i < num_query_caps; i++) {
+ if (VA_TONE_MAPPING_HDR_TO_SDR & hdr_cap[i].caps_flag)
+ break;
+ }
+ if (i >= num_query_caps) {
+ av_log(avctx, AV_LOG_ERROR,
+ "VAAPI driver doesn't support HDR to SDR\n");
+ return AVERROR(EINVAL);
+ }
}
hdrtm_param.type = VAProcFilterHighDynamicRangeToneMapping;
@@ -241,6 +334,8 @@ static int tonemap_vaapi_filter_frame(AV
VAProcPipelineParameterBuffer params;
int err;
+ VAHdrMetaData out_hdr_metadata;
+
av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
av_get_pix_fmt_name(input_frame->format),
input_frame->width, input_frame->height, input_frame->pts);
@@ -278,22 +373,43 @@ static int tonemap_vaapi_filter_frame(AV
if (err < 0)
goto fail;
+ av_frame_remove_side_data(output_frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+ av_frame_remove_side_data(output_frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+
+ if (!ctx->mastering_display) {
+ /* Use BT709 by default for HDR to SDR output frame */
+ output_frame->color_primaries = AVCOL_PRI_BT709;
+ output_frame->color_trc = AVCOL_TRC_BT709;
+ output_frame->colorspace = AVCOL_SPC_BT709;
+ }
+
if (ctx->color_primaries != AVCOL_PRI_UNSPECIFIED)
output_frame->color_primaries = ctx->color_primaries;
if (ctx->color_transfer != AVCOL_TRC_UNSPECIFIED)
output_frame->color_trc = ctx->color_transfer;
- else
- output_frame->color_trc = AVCOL_TRC_BT709;
if (ctx->color_matrix != AVCOL_SPC_UNSPECIFIED)
output_frame->colorspace = ctx->color_matrix;
+ if (ctx->mastering_display) {
+ err = tonemap_vaapi_update_sidedata(avctx, output_frame);
+ if (err < 0)
+ goto fail;
+ }
+
err = ff_vaapi_vpp_init_params(avctx, &params,
input_frame, output_frame);
if (err < 0)
goto fail;
+ if (ctx->mastering_display) {
+ out_hdr_metadata.metadata_type = VAProcHighDynamicRangeMetadataHDR10;
+ out_hdr_metadata.metadata = &ctx->out_metadata;
+ out_hdr_metadata.metadata_size = sizeof(VAHdrMetaDataHDR10);
+ params.output_hdr_metadata = &out_hdr_metadata;
+ }
+
if (vpp_ctx->nb_filter_buffers) {
params.filters = &vpp_ctx->filter_buffers[0];
params.num_filters = vpp_ctx->nb_filter_buffers;
@@ -309,9 +425,6 @@ static int tonemap_vaapi_filter_frame(AV
av_get_pix_fmt_name(output_frame->format),
output_frame->width, output_frame->height, output_frame->pts);
- av_frame_remove_side_data(output_frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
- av_frame_remove_side_data(output_frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
-
return ff_filter_frame(outlink, output_frame);
fail:
@@ -332,8 +445,13 @@ static av_cold int tonemap_vaapi_init(AV
if (ctx->output_format_string) {
vpp_ctx->output_format = av_get_pix_fmt(ctx->output_format_string);
} else {
- vpp_ctx->output_format = AV_PIX_FMT_NV12;
- av_log(avctx, AV_LOG_WARNING, "Output format not set, use default format NV12\n");
+ if (ctx->mastering_display) {
+ vpp_ctx->output_format = AV_PIX_FMT_P010;
+ av_log(avctx, AV_LOG_VERBOSE, "Output format not set, use default format P010 for HDR to HDR tone mapping.\n");
+ } else {
+ vpp_ctx->output_format = AV_PIX_FMT_NV12;
+ av_log(avctx, AV_LOG_VERBOSE, "Output format not set, use default format NV12 for HDR to SDR tone mapping.\n");
+ }
}
#define STRING_OPTION(var_name, func_name, default_value) do { \
@@ -353,6 +471,37 @@ static av_cold int tonemap_vaapi_init(AV
STRING_OPTION(color_transfer, color_transfer, AVCOL_TRC_UNSPECIFIED);
STRING_OPTION(color_matrix, color_space, AVCOL_SPC_UNSPECIFIED);
+ if (ctx->mastering_display) {
+ if (10 != sscanf(ctx->mastering_display,
+ "%hu %hu|%hu %hu|%hu %hu|%hu %hu|%u %u",
+ &ctx->out_metadata.display_primaries_x[0],
+ &ctx->out_metadata.display_primaries_y[0],
+ &ctx->out_metadata.display_primaries_x[1],
+ &ctx->out_metadata.display_primaries_y[1],
+ &ctx->out_metadata.display_primaries_x[2],
+ &ctx->out_metadata.display_primaries_y[2],
+ &ctx->out_metadata.white_point_x,
+ &ctx->out_metadata.white_point_y,
+ &ctx->out_metadata.min_display_mastering_luminance,
+ &ctx->out_metadata.max_display_mastering_luminance)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Option mastering-display input invalid\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (!ctx->content_light) {
+ ctx->out_metadata.max_content_light_level = 0;
+ ctx->out_metadata.max_pic_average_light_level = 0;
+ } else if (2 != sscanf(ctx->content_light,
+ "%hu %hu",
+ &ctx->out_metadata.max_content_light_level,
+ &ctx->out_metadata.max_pic_average_light_level)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Option content-light input invalid\n");
+ return AVERROR(EINVAL);
+ }
+ }
+
return 0;
}
@@ -378,6 +527,12 @@ static const AVOption tonemap_vaapi_opti
{ "t", "Output color transfer characteristics set",
OFFSET(color_transfer_string), AV_OPT_TYPE_STRING,
{ .str = NULL }, .flags = FLAGS, .unit = "transfer" },
+ { "display", "set mastering display colour volume",
+ OFFSET(mastering_display), AV_OPT_TYPE_STRING,
+ { .str = NULL }, .flags = FLAGS },
+ { "light", "set content light level information",
+ OFFSET(content_light), AV_OPT_TYPE_STRING,
+ { .str = NULL }, .flags = FLAGS },
{ NULL }
};
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/nvdec.c
===================================================================
--- FFmpeg.orig/libavcodec/nvdec.c
+++ FFmpeg/libavcodec/nvdec.c
@@ -299,8 +299,10 @@ static int nvdec_init_hwframes(AVCodecCo
@@ -300,8 +300,10 @@ static int nvdec_init_hwframes(AVCodecCo
frames_ctx = (AVHWFramesContext*)(*out_frames_ref)->data;
if (dummy) {
@@ -0,0 +1,116 @@
Index: FFmpeg/libavcodec/vaapi_encode.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode.c
+++ FFmpeg/libavcodec/vaapi_encode.c
@@ -1133,6 +1133,68 @@ fail:
return err;
}
+static av_cold int vaapi_encode_surface_alignment(av_unused AVCodecContext *avctx)
+{
+#if VA_CHECK_VERSION(1, 21, 0)
+ VAAPIEncodeContext *ctx = avctx->priv_data;
+ VASurfaceAttrib *attr_list = NULL;
+ unsigned int attr_count = 0;
+ VAConfigID va_config;
+ VAStatus vas;
+ int err = 0;
+
+ vas = vaCreateConfig(ctx->hwctx->display,
+ ctx->va_profile, ctx->va_entrypoint,
+ NULL, 0, &va_config);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create temp encode pipeline "
+ "configuration: %d (%s).\n", vas, vaErrorStr(vas));
+ return AVERROR(EIO);
+ }
+
+ vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
+ 0, &attr_count);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
+ "%d (%s).\n", vas, vaErrorStr(vas));
+ err = AVERROR_EXTERNAL;
+ goto fail;
+ }
+
+ attr_list = av_malloc(attr_count * sizeof(*attr_list));
+ if (!attr_list) {
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ vas = vaQuerySurfaceAttributes(ctx->hwctx->display, va_config,
+ attr_list, &attr_count);
+ if (vas != VA_STATUS_SUCCESS) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
+ "%d (%s).\n", vas, vaErrorStr(vas));
+ err = AVERROR_EXTERNAL;
+ goto fail;
+ }
+
+ for (unsigned int i = 0; i < attr_count; i++) {
+ if (attr_list[i].type == VASurfaceAttribAlignmentSize) {
+ ctx->surface_alignment_width =
+ 1 << (attr_list[i].value.value.i & 0xf);
+ ctx->surface_alignment_height =
+ 1 << ((attr_list[i].value.value.i & 0xf0) >> 4);
+ break;
+ }
+ }
+
+fail:
+ av_freep(&attr_list);
+ vaDestroyConfig(ctx->hwctx->display, va_config);
+ return err;
+#else
+ return 0;
+#endif
+}
+
static const VAAPIEncodeRCMode vaapi_encode_rc_modes[] = {
// Bitrate Quality
// | Maxrate | HRD/VBV
@@ -2111,6 +2173,10 @@ av_cold int ff_vaapi_encode_init(AVCodec
if (err < 0)
goto fail;
+ err = vaapi_encode_surface_alignment(avctx);
+ if (err < 0)
+ goto fail;
+
if (ctx->codec->get_encoder_caps) {
err = ctx->codec->get_encoder_caps(avctx);
if (err < 0)
Index: FFmpeg/libavcodec/vaapi_encode.h
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode.h
+++ FFmpeg/libavcodec/vaapi_encode.h
@@ -260,6 +260,10 @@ typedef struct VAAPIEncodeContext {
* This is a RefStruct reference.
*/
VABufferID *coded_buffer_ref;
+
+ // Surface alignment required by driver.
+ int surface_alignment_width;
+ int surface_alignment_height;
} VAAPIEncodeContext;
typedef struct VAAPIEncodeType {
Index: FFmpeg/libavcodec/vaapi_encode_h265.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode_h265.c
+++ FFmpeg/libavcodec/vaapi_encode_h265.c
@@ -951,8 +951,10 @@ static av_cold int vaapi_encode_h265_get
"min CB size %dx%d.\n", priv->ctu_size, priv->ctu_size,
priv->min_cb_size, priv->min_cb_size);
- base_ctx->surface_width = FFALIGN(avctx->width, priv->min_cb_size);
- base_ctx->surface_height = FFALIGN(avctx->height, priv->min_cb_size);
+ base_ctx->surface_width = FFALIGN(avctx->width,
+ FFMAX(priv->min_cb_size, priv->common.surface_alignment_width));
+ base_ctx->surface_height = FFALIGN(avctx->height,
+ FFMAX(priv->min_cb_size, priv->common.surface_alignment_height));
base_ctx->slice_block_width = base_ctx->slice_block_height = priv->ctu_size;
@@ -0,0 +1,55 @@
Index: FFmpeg/libavfilter/qsvvpp.c
===================================================================
--- FFmpeg.orig/libavfilter/qsvvpp.c
+++ FFmpeg/libavfilter/qsvvpp.c
@@ -471,7 +471,8 @@ static QSVFrame *submit_frame(QSVVPPCont
}
/* get the output surface */
-static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink, const AVFrame *in)
+static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink, const AVFrame *in,
+ const AVFrame *propref)
{
FilterLink *l = ff_filter_link(outlink);
AVFilterContext *ctx = outlink->src;
@@ -513,6 +514,15 @@ static QSVFrame *query_frame(QSVVPPConte
return NULL;
}
+ if (propref) {
+ ret = av_frame_copy_props(out_frame->frame, propref);
+ if (ret < 0) {
+ av_frame_free(&out_frame->frame);
+ av_log(ctx, AV_LOG_ERROR, "Failed to copy metadata fields from src to dst.\n");
+ return NULL;
+ }
+ }
+
if (l->frame_rate.num && l->frame_rate.den)
out_frame->frame->duration = av_rescale_q(1, av_inv_q(l->frame_rate), outlink->time_base);
else
@@ -985,7 +995,7 @@ int ff_qsvvpp_filter_frame(QSVVPPContext
}
do {
- out_frame = query_frame(s, outlink, in_frame->frame);
+ out_frame = query_frame(s, outlink, in_frame->frame, propref);
if (!out_frame) {
av_log(ctx, AV_LOG_ERROR, "Failed to query an output frame.\n");
return AVERROR(ENOMEM);
@@ -1009,15 +1019,6 @@ int ff_qsvvpp_filter_frame(QSVVPPContext
break;
}
- if (propref) {
- ret1 = av_frame_copy_props(out_frame->frame, propref);
- if (ret1 < 0) {
- av_frame_free(&out_frame->frame);
- av_log(ctx, AV_LOG_ERROR, "Failed to copy metadata fields from src to dst.\n");
- return ret1;
- }
- }
-
out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp,
default_tb, outlink->time_base);
@@ -1,607 +0,0 @@
Index: FFmpeg/libavcodec/vaapi_av1.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_av1.c
+++ FFmpeg/libavcodec/vaapi_av1.c
@@ -19,6 +19,7 @@
*/
#include "libavutil/frame.h"
+#include "libavutil/mem.h"
#include "hwaccel_internal.h"
#include "vaapi_decode.h"
#include "internal.h"
@@ -42,6 +43,9 @@ typedef struct VAAPIAV1DecContext {
*/
VAAPIAV1FrameRef ref_tab[AV1_NUM_REF_FRAMES];
AVFrame *tmp_frame;
+
+ int nb_slice_params;
+ VASliceParameterBufferAV1 *slice_params;
} VAAPIAV1DecContext;
static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf)
@@ -97,6 +101,8 @@ static int vaapi_av1_decode_uninit(AVCod
for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++)
av_frame_free(&ctx->ref_tab[i].frame);
+ av_freep(&ctx->slice_params);
+
return ff_vaapi_decode_uninit(avctx);
}
@@ -393,13 +399,25 @@ static int vaapi_av1_decode_slice(AVCode
{
const AV1DecContext *s = avctx->priv_data;
VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private;
- VASliceParameterBufferAV1 slice_param;
- int err = 0;
+ VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data;
+ int err, nb_params;
- for (int i = s->tg_start; i <= s->tg_end; i++) {
- memset(&slice_param, 0, sizeof(VASliceParameterBufferAV1));
+ nb_params = s->tg_end - s->tg_start + 1;
+ if (ctx->nb_slice_params < nb_params) {
+ VASliceParameterBufferAV1 *tmp = av_realloc_array(ctx->slice_params,
+ nb_params,
+ sizeof(*ctx->slice_params));
+ if (!tmp) {
+ ctx->nb_slice_params = 0;
+ err = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ctx->slice_params = tmp;
+ ctx->nb_slice_params = nb_params;
+ }
- slice_param = (VASliceParameterBufferAV1) {
+ for (int i = s->tg_start; i <= s->tg_end; i++) {
+ ctx->slice_params[i - s->tg_start] = (VASliceParameterBufferAV1) {
.slice_data_size = s->tile_group_info[i].tile_size,
.slice_data_offset = s->tile_group_info[i].tile_offset,
.slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
@@ -408,18 +426,20 @@ static int vaapi_av1_decode_slice(AVCode
.tg_start = s->tg_start,
.tg_end = s->tg_end,
};
-
- err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &slice_param,
- sizeof(VASliceParameterBufferAV1),
- buffer,
- size);
- if (err) {
- ff_vaapi_decode_cancel(avctx, pic);
- return err;
- }
}
+ err = ff_vaapi_decode_make_slice_buffer(avctx, pic, ctx->slice_params, nb_params,
+ sizeof(VASliceParameterBufferAV1),
+ buffer,
+ size);
+ if (err)
+ goto fail;
+
return 0;
+
+fail:
+ ff_vaapi_decode_cancel(avctx, pic);
+ return err;
}
const FFHWAccel ff_av1_vaapi_hwaccel = {
Index: FFmpeg/libavcodec/vaapi_decode.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_decode.c
+++ FFmpeg/libavcodec/vaapi_decode.c
@@ -62,6 +62,7 @@ int ff_vaapi_decode_make_param_buffer(AV
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
VAAPIDecodePicture *pic,
const void *params_data,
+ int nb_params,
size_t params_size,
const void *slice_data,
size_t slice_size)
@@ -72,13 +73,14 @@ int ff_vaapi_decode_make_slice_buffer(AV
av_assert0(pic->nb_slices <= pic->slices_allocated);
if (pic->nb_slices == pic->slices_allocated) {
- pic->slice_buffers =
+ VABufferID *tmp =
av_realloc_array(pic->slice_buffers,
pic->slices_allocated ? pic->slices_allocated * 2 : 64,
2 * sizeof(*pic->slice_buffers));
- if (!pic->slice_buffers)
+ if (!tmp)
return AVERROR(ENOMEM);
+ pic->slice_buffers = tmp;
pic->slices_allocated = pic->slices_allocated ? pic->slices_allocated * 2 : 64;
}
av_assert0(pic->nb_slices + 1 <= pic->slices_allocated);
@@ -87,7 +89,7 @@ int ff_vaapi_decode_make_slice_buffer(AV
vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
VASliceParameterBufferType,
- params_size, 1, (void*)params_data,
+ params_size, nb_params, (void*)params_data,
&pic->slice_buffers[index]);
if (vas != VA_STATUS_SUCCESS) {
av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
@@ -155,6 +157,11 @@ int ff_vaapi_decode_issue(AVCodecContext
VAStatus vas;
int err;
+ if (pic->nb_slices <= 0) {
+ err = AVERROR(EINVAL);
+ goto fail;
+ }
+
av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n",
pic->output_surface);
@@ -598,22 +605,26 @@ static int vaapi_decode_make_config(AVCo
if (err < 0)
goto fail;
- frames->initial_pool_size = 1;
- // Add per-codec number of surfaces used for storing reference frames.
- switch (avctx->codec_id) {
- case AV_CODEC_ID_H264:
- case AV_CODEC_ID_HEVC:
- case AV_CODEC_ID_AV1:
- frames->initial_pool_size += 16;
- break;
- case AV_CODEC_ID_VP9:
- frames->initial_pool_size += 8;
- break;
- case AV_CODEC_ID_VP8:
- frames->initial_pool_size += 3;
- break;
- default:
- frames->initial_pool_size += 2;
+ if (CONFIG_VAAPI_1)
+ frames->initial_pool_size = 0;
+ else {
+ frames->initial_pool_size = 1;
+ // Add per-codec number of surfaces used for storing reference frames.
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_H264:
+ case AV_CODEC_ID_HEVC:
+ case AV_CODEC_ID_AV1:
+ frames->initial_pool_size += 16;
+ break;
+ case AV_CODEC_ID_VP9:
+ frames->initial_pool_size += 8;
+ break;
+ case AV_CODEC_ID_VP8:
+ frames->initial_pool_size += 3;
+ break;
+ default:
+ frames->initial_pool_size += 2;
+ }
}
}
Index: FFmpeg/libavcodec/vaapi_decode.h
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_decode.h
+++ FFmpeg/libavcodec/vaapi_decode.h
@@ -73,6 +73,7 @@ int ff_vaapi_decode_make_param_buffer(AV
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx,
VAAPIDecodePicture *pic,
const void *params_data,
+ int nb_params,
size_t params_size,
const void *slice_data,
size_t slice_size);
Index: FFmpeg/libavcodec/vaapi_encode_av1.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode_av1.c
+++ FFmpeg/libavcodec/vaapi_encode_av1.c
@@ -23,6 +23,7 @@
#include "libavutil/pixdesc.h"
#include "libavutil/opt.h"
+#include "libavutil/mastering_display_metadata.h"
#include "cbs_av1.h"
#include "put_bits.h"
@@ -41,6 +42,8 @@ typedef struct VAAPIEncodeAV1Context {
VAAPIEncodeContext common;
AV1RawOBU sh; /**< sequence header.*/
AV1RawOBU fh; /**< frame header.*/
+ AV1RawOBU mh[4]; /**< metadata header.*/
+ int nb_mh;
CodedBitstreamContext *cbc;
CodedBitstreamFragment current_obu;
VAConfigAttribValEncAV1 attr;
@@ -155,6 +158,8 @@ static av_cold int vaapi_encode_av1_conf
priv->q_idx_idr = priv->q_idx_p = priv->q_idx_b = 128;
}
+ ctx->roi_quant_range = AV1_MAX_QUANT;
+
return 0;
}
@@ -657,6 +662,68 @@ static int vaapi_encode_av1_init_picture
2 : 1));
}
+ priv->nb_mh = 0;
+
+ if (pic->type == PICTURE_TYPE_IDR) {
+ AVFrameSideData *sd =
+ av_frame_get_side_data(pic->input_image,
+ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+ if (sd) {
+ AVMasteringDisplayMetadata *mdm =
+ (AVMasteringDisplayMetadata *)sd->data;
+ if (mdm->has_primaries && mdm->has_luminance) {
+ AV1RawOBU *obu = &priv->mh[priv->nb_mh++];
+ AV1RawMetadata *md = &obu->obu.metadata;
+ AV1RawMetadataHDRMDCV *mdcv = &md->metadata.hdr_mdcv;
+ const int chroma_den = 1 << 16;
+ const int max_luma_den = 1 << 8;
+ const int min_luma_den = 1 << 14;
+
+ memset(obu, 0, sizeof(*obu));
+ obu->header.obu_type = AV1_OBU_METADATA;
+ md->metadata_type = AV1_METADATA_TYPE_HDR_MDCV;
+
+ for (i = 0; i < 3; i++) {
+ mdcv->primary_chromaticity_x[i] =
+ av_rescale(mdm->display_primaries[i][0].num, chroma_den,
+ mdm->display_primaries[i][0].den);
+ mdcv->primary_chromaticity_y[i] =
+ av_rescale(mdm->display_primaries[i][1].num, chroma_den,
+ mdm->display_primaries[i][1].den);
+ }
+
+ mdcv->white_point_chromaticity_x =
+ av_rescale(mdm->white_point[0].num, chroma_den,
+ mdm->white_point[0].den);
+ mdcv->white_point_chromaticity_y =
+ av_rescale(mdm->white_point[1].num, chroma_den,
+ mdm->white_point[1].den);
+
+ mdcv->luminance_max =
+ av_rescale(mdm->max_luminance.num, max_luma_den,
+ mdm->max_luminance.den);
+ mdcv->luminance_min =
+ av_rescale(mdm->min_luminance.num, min_luma_den,
+ mdm->min_luminance.den);
+ }
+ }
+
+ sd = av_frame_get_side_data(pic->input_image,
+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+ if (sd) {
+ AVContentLightMetadata *cllm = (AVContentLightMetadata *)sd->data;
+ AV1RawOBU *obu = &priv->mh[priv->nb_mh++];
+ AV1RawMetadata *md = &obu->obu.metadata;
+ AV1RawMetadataHDRCLL *cll = &md->metadata.hdr_cll;
+
+ memset(obu, 0, sizeof(*obu));
+ obu->header.obu_type = AV1_OBU_METADATA;
+ md->metadata_type = AV1_METADATA_TYPE_HDR_CLL;
+ cll->max_cll = cllm->MaxCLL;
+ cll->max_fall = cllm->MaxFALL;
+ }
+ }
+
end:
ff_cbs_fragment_reset(obu);
return ret;
@@ -733,6 +800,39 @@ end:
return ret;
}
+static int vaapi_encode_av1_write_extra_header(AVCodecContext *avctx,
+ VAAPIEncodePicture *pic,
+ int index, int *type,
+ char *data, size_t *data_len)
+{
+ VAAPIEncodeAV1Context *priv = avctx->priv_data;
+ CodedBitstreamFragment *obu = &priv->current_obu;
+ AV1RawOBU *mh_obu;
+ char mh_data[MAX_PARAM_BUFFER_SIZE];
+ size_t mh_data_len;
+ int ret = 0;
+
+ if (index >= priv->nb_mh)
+ return AVERROR_EOF;
+
+ mh_obu = &priv->mh[index];
+ ret = vaapi_encode_av1_add_obu(avctx, obu, AV1_OBU_METADATA, mh_obu);
+ if (ret < 0)
+ goto end;
+
+ ret = vaapi_encode_av1_write_obu(avctx, mh_data, &mh_data_len, obu);
+ if (ret < 0)
+ goto end;
+
+ memcpy(data, mh_data, MAX_PARAM_BUFFER_SIZE * sizeof(char));
+ *data_len = mh_data_len;
+ *type = VAEncPackedHeaderRawData;
+
+end:
+ ff_cbs_fragment_reset(obu);
+ return ret;
+}
+
static const VAAPIEncodeProfile vaapi_encode_av1_profiles[] = {
{ AV_PROFILE_AV1_MAIN, 8, 3, 1, 1, VAProfileAV1Profile0 },
{ AV_PROFILE_AV1_MAIN, 10, 3, 1, 1, VAProfileAV1Profile0 },
@@ -760,6 +860,8 @@ static const VAAPIEncodeType vaapi_encod
.slice_params_size = sizeof(VAEncTileGroupBufferAV1),
.init_slice_params = &vaapi_encode_av1_init_slice_params,
+
+ .write_extra_header = &vaapi_encode_av1_write_extra_header,
};
static av_cold int vaapi_encode_av1_init(AVCodecContext *avctx)
@@ -774,7 +876,8 @@ static av_cold int vaapi_encode_av1_init
ctx->desired_packed_headers =
VA_ENC_PACKED_HEADER_SEQUENCE |
- VA_ENC_PACKED_HEADER_PICTURE;
+ VA_ENC_PACKED_HEADER_PICTURE |
+ VA_ENC_PACKED_HEADER_MISC; // Metadata
if (avctx->profile == AV_PROFILE_UNKNOWN)
avctx->profile = priv->profile;
Index: FFmpeg/libavcodec/vaapi_encode_h264.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode_h264.c
+++ FFmpeg/libavcodec/vaapi_encode_h264.c
@@ -759,7 +759,7 @@ static int vaapi_encode_h264_init_pictur
vpic->frame_num = hpic->frame_num;
vpic->pic_fields.bits.idr_pic_flag = (pic->type == PICTURE_TYPE_IDR);
- vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B);
+ vpic->pic_fields.bits.reference_pic_flag = pic->is_reference;
return 0;
}
Index: FFmpeg/libavcodec/vaapi_encode_h265.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode_h265.c
+++ FFmpeg/libavcodec/vaapi_encode_h265.c
@@ -945,26 +945,23 @@ static int vaapi_encode_h265_init_pictur
vpic->nal_unit_type = hpic->slice_nal_unit;
+ vpic->pic_fields.bits.reference_pic_flag = pic->is_reference;
switch (pic->type) {
case PICTURE_TYPE_IDR:
vpic->pic_fields.bits.idr_pic_flag = 1;
vpic->pic_fields.bits.coding_type = 1;
- vpic->pic_fields.bits.reference_pic_flag = 1;
break;
case PICTURE_TYPE_I:
vpic->pic_fields.bits.idr_pic_flag = 0;
vpic->pic_fields.bits.coding_type = 1;
- vpic->pic_fields.bits.reference_pic_flag = 1;
break;
case PICTURE_TYPE_P:
vpic->pic_fields.bits.idr_pic_flag = 0;
vpic->pic_fields.bits.coding_type = 2;
- vpic->pic_fields.bits.reference_pic_flag = 1;
break;
case PICTURE_TYPE_B:
vpic->pic_fields.bits.idr_pic_flag = 0;
vpic->pic_fields.bits.coding_type = 3;
- vpic->pic_fields.bits.reference_pic_flag = 0;
break;
default:
av_assert0(0 && "invalid picture type");
Index: FFmpeg/libavcodec/vaapi_h264.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_h264.c
+++ FFmpeg/libavcodec/vaapi_h264.c
@@ -93,14 +93,19 @@ typedef struct DPB {
*/
static int dpb_add(DPB *dpb, const H264Picture *pic)
{
- int i;
+ int i, pic_frame_idx, merged = 0;
if (dpb->size >= dpb->max_size)
return -1;
+ pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
+
for (i = 0; i < dpb->size; i++) {
VAPictureH264 * const va_pic = &dpb->va_pics[i];
- if (va_pic->picture_id == ff_vaapi_get_surface_id(pic->f)) {
+ int va_pic_long_ref = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
+ if (va_pic->picture_id == ff_vaapi_get_surface_id(pic->f) &&
+ va_pic_long_ref == pic->long_ref &&
+ va_pic->frame_idx == pic_frame_idx) {
VAPictureH264 temp_va_pic;
fill_vaapi_pic(&temp_va_pic, pic, 0);
@@ -112,11 +117,14 @@ static int dpb_add(DPB *dpb, const H264P
} else {
va_pic->BottomFieldOrderCnt = temp_va_pic.BottomFieldOrderCnt;
}
+ merged = 1;
}
- return 0;
}
}
+ if (merged)
+ return 0;
+
fill_vaapi_pic(&dpb->va_pics[dpb->size++], pic, 0);
return 0;
}
@@ -375,7 +383,7 @@ static int vaapi_h264_decode_slice(AVCod
slice_param.chroma_offset_l1);
err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
- &slice_param, sizeof(slice_param),
+ &slice_param, 1, sizeof(slice_param),
buffer, size);
if (err) {
ff_vaapi_decode_cancel(avctx, pic);
Index: FFmpeg/libavcodec/vaapi_hevc.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_hevc.c
+++ FFmpeg/libavcodec/vaapi_hevc.c
@@ -353,7 +353,7 @@ static int vaapi_hevc_end_frame(AVCodecC
if (pic->last_size) {
last_slice_param->LongSliceFlags.fields.LastSliceOfPic = 1;
ret = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
- &pic->last_slice_param, slice_param_size,
+ &pic->last_slice_param, 1, slice_param_size,
pic->last_buffer, pic->last_size);
if (ret < 0)
goto fail;
@@ -471,7 +471,7 @@ static int vaapi_hevc_decode_slice(AVCod
if (!sh->first_slice_in_pic_flag) {
err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
- &pic->last_slice_param, slice_param_size,
+ &pic->last_slice_param, 1, slice_param_size,
pic->last_buffer, pic->last_size);
pic->last_buffer = NULL;
pic->last_size = 0;
Index: FFmpeg/libavcodec/vaapi_mjpeg.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_mjpeg.c
+++ FFmpeg/libavcodec/vaapi_mjpeg.c
@@ -131,7 +131,7 @@ static int vaapi_mjpeg_decode_slice(AVCo
sp.components[i].ac_table_selector = s->ac_index[i];
}
- err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, sizeof(sp), buffer, size);
+ err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, 1, sizeof(sp), buffer, size);
if (err)
goto fail;
Index: FFmpeg/libavcodec/vaapi_mpeg2.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_mpeg2.c
+++ FFmpeg/libavcodec/vaapi_mpeg2.c
@@ -162,7 +162,7 @@ static int vaapi_mpeg2_decode_slice(AVCo
};
err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
- &slice_param, sizeof(slice_param),
+ &slice_param, 1, sizeof(slice_param),
buffer, size);
if (err < 0) {
ff_vaapi_decode_cancel(avctx, pic);
Index: FFmpeg/libavcodec/vaapi_mpeg4.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_mpeg4.c
+++ FFmpeg/libavcodec/vaapi_mpeg4.c
@@ -169,7 +169,7 @@ static int vaapi_mpeg4_decode_slice(AVCo
};
err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
- &slice_param, sizeof(slice_param),
+ &slice_param, 1, sizeof(slice_param),
buffer, size);
if (err < 0) {
ff_vaapi_decode_cancel(avctx, pic);
Index: FFmpeg/libavcodec/vaapi_vc1.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_vc1.c
+++ FFmpeg/libavcodec/vaapi_vc1.c
@@ -489,7 +489,7 @@ static int vaapi_vc1_decode_slice(AVCode
};
err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
- &slice_param, sizeof(slice_param),
+ &slice_param, 1, sizeof(slice_param),
buffer, size);
if (err < 0) {
ff_vaapi_decode_cancel(avctx, pic);
Index: FFmpeg/libavcodec/vaapi_vp8.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_vp8.c
+++ FFmpeg/libavcodec/vaapi_vp8.c
@@ -209,7 +209,7 @@ static int vaapi_vp8_decode_slice(AVCode
for (i = 0; i < 8; i++)
sp.partition_size[i+1] = s->coeff_partition_size[i];
- err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, sizeof(sp), data, data_size);
+ err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &sp, 1, sizeof(sp), data, data_size);
if (err)
goto fail;
Index: FFmpeg/libavcodec/vaapi_vp9.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_vp9.c
+++ FFmpeg/libavcodec/vaapi_vp9.c
@@ -158,7 +158,7 @@ static int vaapi_vp9_decode_slice(AVCode
}
err = ff_vaapi_decode_make_slice_buffer(avctx, pic,
- &slice_param, sizeof(slice_param),
+ &slice_param, 1, sizeof(slice_param),
buffer, size);
if (err) {
ff_vaapi_decode_cancel(avctx, pic);
Index: FFmpeg/libavfilter/vaapi_vpp.c
===================================================================
--- FFmpeg.orig/libavfilter/vaapi_vpp.c
+++ FFmpeg/libavfilter/vaapi_vpp.c
@@ -203,7 +203,10 @@ int ff_vaapi_vpp_config_output(AVFilterL
output_frames->width = ctx->output_width;
output_frames->height = ctx->output_height;
- output_frames->initial_pool_size = 4;
+ if (CONFIG_VAAPI_1)
+ output_frames->initial_pool_size = 0;
+ else
+ output_frames->initial_pool_size = 4;
err = ff_filter_init_hw_frames(avctx, outlink, 10);
if (err < 0)
@@ -219,6 +222,8 @@ int ff_vaapi_vpp_config_output(AVFilterL
va_frames = output_frames->hwctx;
av_assert0(ctx->va_context == VA_INVALID_ID);
+ av_assert0(output_frames->initial_pool_size ||
+ (va_frames->surface_ids == NULL && va_frames->nb_surfaces == 0));
vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
ctx->output_width, ctx->output_height,
VA_PROGRESSIVE,
Index: FFmpeg/libavutil/hwcontext_vaapi.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_vaapi.c
+++ FFmpeg/libavutil/hwcontext_vaapi.c
@@ -809,6 +809,9 @@ static int vaapi_map_frame(AVHWFramesCon
VAStatus vas;
void *address = NULL;
int err, i;
+#if VA_CHECK_VERSION(1, 21, 0)
+ uint32_t vaflags = 0;
+#endif
surface_id = (VASurfaceID)(uintptr_t)src->data[3];
av_log(hwfc, AV_LOG_DEBUG, "Map surface %#x.\n", surface_id);
@@ -892,7 +895,16 @@ static int vaapi_map_frame(AVHWFramesCon
}
}
+#if VA_CHECK_VERSION(1, 21, 0)
+ if (flags & AV_HWFRAME_MAP_READ)
+ vaflags |= VA_MAPBUFFER_FLAG_READ;
+ if (flags & AV_HWFRAME_MAP_WRITE)
+ vaflags |= VA_MAPBUFFER_FLAG_WRITE;
+ // On drivers not implementing vaMapBuffer2 libva calls vaMapBuffer instead.
+ vas = vaMapBuffer2(hwctx->display, map->image.buf, &address, vaflags);
+#else
vas = vaMapBuffer(hwctx->display, map->image.buf, &address);
+#endif
if (vas != VA_STATUS_SUCCESS) {
av_log(hwfc, AV_LOG_ERROR, "Failed to map image from surface "
"%#x: %d (%s).\n", surface_id, vas, vaErrorStr(vas));
@@ -205,7 +205,7 @@ Index: FFmpeg/libavcodec/qsvdec.c
frame->pts = MFX_PTS_TO_PTS(outsurf->Data.TimeStamp, avctx->pkt_timebase);
#if QSV_VERSION_ATLEAST(1, 34)
if ((avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
@@ -985,6 +1138,8 @@ static void qsv_decode_close_qsvcontext(
@@ -986,6 +1139,8 @@ static void qsv_decode_close_qsvcontext(
av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
ff_refstruct_unref(&q->frames_ctx.mids);
av_buffer_pool_uninit(&q->pool);
@@ -300,7 +300,7 @@ Index: FFmpeg/libavcodec/qsvenc.h
===================================================================
--- FFmpeg.orig/libavcodec/qsvenc.h
+++ FFmpeg/libavcodec/qsvenc.h
@@ -177,6 +177,7 @@ typedef struct QSVEncContext {
@@ -175,6 +175,7 @@ typedef struct QSVEncContext {
mfxExtMultiFrameControl extmfc;
#endif
mfxExtHEVCTiles exthevctiles;
@@ -308,7 +308,7 @@ Index: FFmpeg/libavcodec/qsvenc.h
mfxExtVP9Param extvp9param;
#if QSV_HAVE_EXT_AV1_PARAM
mfxExtAV1TileParam extav1tileparam;
@@ -193,7 +194,7 @@ typedef struct QSVEncContext {
@@ -191,7 +192,7 @@ typedef struct QSVEncContext {
mfxExtVideoSignalInfo extvsi;
@@ -317,7 +317,7 @@ Index: FFmpeg/libavcodec/qsvenc.h
int nb_extparam_internal;
mfxExtBuffer **extparam_str;
@@ -321,6 +322,9 @@ typedef struct QSVEncContext {
@@ -319,6 +320,9 @@ typedef struct QSVEncContext {
int dual_gfx;
AVDictionary *qsv_params;
@@ -331,7 +331,7 @@ Index: FFmpeg/libavcodec/qsvenc_hevc.c
===================================================================
--- FFmpeg.orig/libavcodec/qsvenc_hevc.c
+++ FFmpeg/libavcodec/qsvenc_hevc.c
@@ -363,6 +363,9 @@ static const AVOption options[] = {
@@ -365,6 +365,9 @@ static const AVOption options[] = {
{ "int_ref_qp_delta", "QP difference for the refresh MBs", OFFSET(qsv.int_ref_qp_delta), AV_OPT_TYPE_INT, { .i64 = INT16_MIN }, INT16_MIN, INT16_MAX, VE },
{ "int_ref_cycle_dist", "Distance between the beginnings of the intra-refresh cycles in frames", OFFSET(qsv.int_ref_cycle_dist), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/qsvvpp.c
===================================================================
--- FFmpeg.orig/libavfilter/qsvvpp.c
+++ FFmpeg/libavfilter/qsvvpp.c
@@ -167,7 +167,7 @@ int ff_qsvvpp_print_warning(void *log_ct
@@ -168,7 +168,7 @@ int ff_qsvvpp_print_warning(void *log_ct
const char *desc;
int ret;
ret = qsv_map_error(err, &desc);
@@ -11,7 +11,7 @@ Index: FFmpeg/libavfilter/qsvvpp.c
return ret;
}
@@ -458,8 +458,12 @@ static QSVFrame *submit_frame(QSVVPPCont
@@ -460,8 +460,12 @@ static QSVFrame *submit_frame(QSVVPPCont
!(qsv_frame->frame->flags & AV_FRAME_FLAG_INTERLACED) ? MFX_PICSTRUCT_PROGRESSIVE :
((qsv_frame->frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? MFX_PICSTRUCT_FIELD_TFF :
MFX_PICSTRUCT_FIELD_BFF);
@@ -25,51 +25,27 @@ Index: FFmpeg/libavfilter/qsvvpp.c
else if (qsv_frame->frame->repeat_pict == 2)
qsv_frame->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_DOUBLING;
else if (qsv_frame->frame->repeat_pict == 4)
@@ -986,6 +990,23 @@ int ff_qsvvpp_filter_frame(QSVVPPContext
return AVERROR(ENOMEM);
}
@@ -913,8 +917,13 @@ static int qsvvpp_init_vpp_session(AVFil
+ /* Copy metadata before initializing vpp session,
+ * which contains callback to drop the HDR metadata */
+ if (propref) {
+ int flags = out_frame->frame->flags;
+ int64_t duration = out_frame->frame->duration;
+
+ ret1 = av_frame_copy_props(out_frame->frame, propref);
+ if (ret1 < 0) {
+ av_frame_free(&out_frame->frame);
+ av_log(ctx, AV_LOG_ERROR, "Failed to copy metadata fields from src to dst.\n");
+ return ret1;
+ }
+
+ out_frame->frame->flags = flags;
+ out_frame->frame->duration = duration;
/* Query VPP params again, including params for frame */
ret = MFXVideoVPP_Query(s->session, &s->vpp_param, &s->vpp_param);
- if (ret < 0)
- return ff_qsvvpp_print_error(avctx, ret, "Error querying VPP params");
+ if (ret < 0) {
+ /* Wa a PicStruct validation issue in VPL/MSDK RT */
+ if (s->vpp_param.vpp.In.PicStruct != in->surface.Info.PicStruct)
+ s->vpp_param.vpp.In.PicStruct = in->surface.Info.PicStruct;
+ else
+ return ff_qsvvpp_print_error(avctx, ret, "Error querying VPP params");
+ }
+
ret = qsvvpp_init_vpp_session(ctx, s, in_frame, out_frame);
if (ret)
return ret;
@@ -1004,15 +1025,6 @@ int ff_qsvvpp_filter_frame(QSVVPPContext
break;
}
- if (propref) {
- ret1 = av_frame_copy_props(out_frame->frame, propref);
- if (ret1 < 0) {
- av_frame_free(&out_frame->frame);
- av_log(ctx, AV_LOG_ERROR, "Failed to copy metadata fields from src to dst.\n");
- return ret1;
- }
- }
-
out_frame->frame->pts = av_rescale_q(out_frame->surface.Data.TimeStamp,
default_tb, outlink->time_base);
else if (ret > 0)
ff_qsvvpp_print_warning(avctx, ret, "Warning When querying VPP params");
Index: FFmpeg/libavfilter/vf_overlay_qsv.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_overlay_qsv.c
+++ FFmpeg/libavfilter/vf_overlay_qsv.c
@@ -228,43 +228,47 @@ static int config_overlay_input(AVFilter
@@ -227,43 +227,47 @@ static int config_overlay_input(AVFilter
static int process_frame(FFFrameSync *fs)
{
@@ -145,11 +121,19 @@ Index: FFmpeg/libavfilter/vf_overlay_qsv.c
return ff_framesync_configure(&s->fs);
}
@@ -285,12 +289,6 @@ static int config_output(AVFilterLink *o
@@ -275,7 +279,6 @@ static int config_output(AVFilterLink *o
AVFilterLink *in0 = ctx->inputs[0];
AVFilterLink *in1 = ctx->inputs[1];
FilterLink *l0 = ff_filter_link(in0);
- FilterLink *l1 = ff_filter_link(in1);
FilterLink *ol = ff_filter_link(outlink);
int ret;
@@ -287,12 +290,6 @@ static int config_output(AVFilterLink *o
return AVERROR(EINVAL);
} else if (in0->format == AV_PIX_FMT_QSV) {
AVHWFramesContext *hw_frame0 = (AVHWFramesContext *)in0->hw_frames_ctx->data;
- AVHWFramesContext *hw_frame1 = (AVHWFramesContext *)in1->hw_frames_ctx->data;
AVHWFramesContext *hw_frame0 = (AVHWFramesContext *)l0->hw_frames_ctx->data;
- AVHWFramesContext *hw_frame1 = (AVHWFramesContext *)l1->hw_frames_ctx->data;
-
- if (hw_frame0->device_ctx != hw_frame1->device_ctx) {
- av_log(ctx, AV_LOG_ERROR, "Inputs with different underlying QSV devices are forbidden.\n");
@@ -158,7 +142,7 @@ Index: FFmpeg/libavfilter/vf_overlay_qsv.c
vpp->qsv_param.out_sw_format = hw_frame0->sw_format;
}
@@ -372,6 +370,7 @@ static int overlay_qsv_query_formats(AVF
@@ -374,6 +371,7 @@ static int overlay_qsv_query_formats(AVF
static const enum AVPixelFormat main_in_fmts[] = {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NV12,
@@ -166,7 +150,7 @@ Index: FFmpeg/libavfilter/vf_overlay_qsv.c
AV_PIX_FMT_YUYV422,
AV_PIX_FMT_RGB32,
AV_PIX_FMT_QSV,
@@ -379,6 +378,7 @@ static int overlay_qsv_query_formats(AVF
@@ -381,6 +379,7 @@ static int overlay_qsv_query_formats(AVF
};
static const enum AVPixelFormat out_pix_fmts[] = {
AV_PIX_FMT_NV12,
@@ -184,13 +168,13 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
+static mfxStatus get_mfx_platform(const AVFilterContext *ctx, mfxPlatform *mfx_platform)
+{
+ const AVFilterLink *inlink = ctx->inputs[0];
+ const FilterLink *l = ff_filter_link(ctx->inputs[0]);
+ AVBufferRef *device_ref;
+ AVHWDeviceContext *device_ctx;
+ AVQSVDeviceContext *device_hwctx;
+
+ if (inlink->hw_frames_ctx) {
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
+ if (l->hw_frames_ctx) {
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext *)l->hw_frames_ctx->data;
+ device_ref = frames_ctx->device_ref;
+ } else if (ctx->hw_device_ctx) {
+ device_ref = ctx->hw_device_ctx;
@@ -249,7 +233,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
outvsi_conf.ColourDescriptionPresent = 1;
if (memcmp(&vpp->invsi_conf, &invsi_conf, sizeof(mfxExtVideoSignalInfo)) ||
@@ -686,12 +715,24 @@ static int config_output(AVFilterLink *o
@@ -689,12 +718,23 @@ static int config_output(AVFilterLink *o
if (inlink->w != outlink->w || inlink->h != outlink->h || in_format != vpp->out_format) {
if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 19)) {
@@ -267,7 +251,6 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
+ int code_name = mfx_platform.CodeName;
+ compute = code_name >= 45 &&
+ code_name <= 54 &&
+ code_name != 55 &&
+ code_name != 50;
+ }
+
@@ -278,7 +261,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
INIT_MFX_EXTBUF(scale_conf, MFX_EXTBUFF_VPP_SCALING);
SET_MFX_PARAM_FIELD(scale_conf, ScalingMode, mode);
@@ -880,19 +921,13 @@ static const AVOption vpp_options[] = {
@@ -884,19 +924,13 @@ static const AVOption vpp_options[] = {
{ "height", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
{ "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
{ "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(qsv.async_depth), AV_OPT_TYPE_INT, { .i64 = 4 }, 0, INT_MAX, .flags = FLAGS },
@@ -299,7 +282,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
{ "rate", "Generate output at frame rate or field rate, available only for deinterlace mode",
OFFSET(field_rate), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, .unit = "rate" },
@@ -923,8 +958,9 @@ static const AVOption vpp_options[] = {
@@ -927,8 +961,9 @@ static const AVOption vpp_options[] = {
{ "out_color_transfer", "Output color transfer characteristics",
OFFSET(color_transfer_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
@@ -310,7 +293,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
{ NULL }
};
@@ -978,19 +1014,14 @@ static const AVOption qsvscale_options[]
@@ -982,19 +1017,14 @@ static const AVOption qsvscale_options[]
{ "h", "Output video height(0=input video height, -1=keep input video aspect)", OFFSET(oh), AV_OPT_TYPE_STRING, { .str = "ih" }, .flags = FLAGS },
{ "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
@@ -332,7 +315,7 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
{ NULL },
};
@@ -1015,6 +1046,7 @@ static const AVOption qsvdeint_options[]
@@ -1019,6 +1049,7 @@ static const AVOption qsvdeint_options[]
{ "bob", "bob algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, .unit = "mode"},
{ "advanced", "Motion adaptive algorithm", 0, AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, FLAGS, .unit = "mode"},
@@ -340,3 +323,89 @@ Index: FFmpeg/libavfilter/vf_vpp_qsv.c
{ NULL },
};
Index: FFmpeg/libavutil/hwcontext_qsv.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_qsv.c
+++ FFmpeg/libavutil/hwcontext_qsv.c
@@ -1706,13 +1706,47 @@ static int qsv_transfer_data_child(AVHWF
dummy->width = src->width;
dummy->height = src->height;
dummy->buf[0] = download ? src->buf[0] : dst->buf[0];
- dummy->data[3] = surf->Data.MemId;
dummy->hw_frames_ctx = s->child_frames_ref;
+ switch (child_frames_ctx->device_ctx->type) {
+#if CONFIG_VAAPI
+ case AV_HWDEVICE_TYPE_VAAPI:
+ {
+ mfxHDLPair *pair = (mfxHDLPair *)surf->Data.MemId;
+ dummy->data[3] = (uint8_t *)(intptr_t)*(VASurfaceID *)pair->first;
+ break;
+ }
+#endif
+#if CONFIG_D3D11VA
+ case AV_HWDEVICE_TYPE_D3D11VA:
+ {
+ mfxHDLPair *pair = (mfxHDLPair *)surf->Data.MemId;
+ dummy->data[0] = (uint8_t *)pair->first;
+ dummy->data[1] = pair->second == (mfxMemId)MFX_INFINITE ?
+ (uint8_t *)0 : (uint8_t *)pair->second;
+ break;
+ }
+#endif
+#if CONFIG_DXVA2
+ case AV_HWDEVICE_TYPE_DXVA2:
+ {
+ mfxHDLPair *pair = (mfxHDLPair *)surf->Data.MemId;
+ dummy->data[3] = (uint8_t *)pair->first;
+ break;
+ }
+#endif
+ default:
+ ret = AVERROR(ENOSYS);
+ goto exit;
+ }
+
ret = download ? av_hwframe_transfer_data(dst, dummy, 0) :
av_hwframe_transfer_data(dummy, src, 0);
+exit:
dummy->buf[0] = NULL;
+ dummy->data[0] = NULL;
+ dummy->data[1] = NULL;
dummy->data[3] = NULL;
dummy->hw_frames_ctx = NULL;
@@ -1902,6 +1936,9 @@ static int qsv_transfer_data_from(AVHWFr
static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst,
const AVFrame *src)
{
+#if CONFIG_D3D11VA
+ QSVDeviceContext *device_priv = ctx->device_ctx->hwctx;
+#endif
QSVFramesContext *s = ctx->hwctx;
mfxFrameSurface1 in = {{ 0 }};
mfxFrameSurface1 *out = (mfxFrameSurface1*)dst->data[3];
@@ -1954,9 +1991,20 @@ static int qsv_transfer_data_to(AVHWFram
src_frame = realigned ? tmp_frame : src;
- if (!s->session_upload) {
- if (s->child_frames_ref)
+ if (!s->session_upload
+#if CONFIG_D3D11VA /* Wa an out of sync issue in MSDK RT on Windows */
+ || ((src_frame->format == AV_PIX_FMT_BGRA) &&
+ !QSV_RUNTIME_VERSION_ATLEAST(device_priv->ver, 1, 255) &&
+ (device_priv->handle_type == MFX_HANDLE_D3D11_DEVICE))
+#endif
+ ) {
+ if (s->child_frames_ref) {
+ if (realigned) {
+ out->Info.CropW = tmp_info.CropW;
+ out->Info.CropH = tmp_info.CropH;
+ }
return qsv_transfer_data_child(ctx, dst, src_frame);
+ }
av_log(ctx, AV_LOG_ERROR, "Surface upload not possible\n");
return AVERROR(ENOSYS);
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/buffersrc.c
===================================================================
--- FFmpeg.orig/libavfilter/buffersrc.c
+++ FFmpeg/libavfilter/buffersrc.c
@@ -75,7 +75,7 @@ typedef struct BufferSourceContext {
@@ -74,7 +74,7 @@ typedef struct BufferSourceContext {
c->prev_delta = c->prev_w != width || c->prev_h != height || c->prev_pix_fmt != format ||\
c->prev_color_space != csp || c->prev_color_range != range;\
if (c->link_delta) {\
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/bsf/hevc_mp4toannexb.c
===================================================================
--- FFmpeg.orig/libavcodec/bsf/hevc_mp4toannexb.c
+++ FFmpeg/libavcodec/bsf/hevc_mp4toannexb.c
@@ -126,6 +126,7 @@ static int hevc_mp4toannexb_filter(AVBSF
@@ -127,6 +127,7 @@ static int hevc_mp4toannexb_filter(AVBSF
int got_irap = 0;
int i, ret = 0;
@@ -10,7 +10,7 @@ Index: FFmpeg/libavcodec/bsf/hevc_mp4toannexb.c
ret = ff_bsf_get_packet(ctx, &in);
if (ret < 0)
@@ -157,11 +158,14 @@ static int hevc_mp4toannexb_filter(AVBSF
@@ -158,11 +159,14 @@ static int hevc_mp4toannexb_filter(AVBSF
}
nalu_type = (bytestream2_peek_byte(&gb) >> 1) & 0x3f;
@@ -30,7 +30,7 @@ Index: FFmpeg/tests/fate/hevc.mak
===================================================================
--- FFmpeg.orig/tests/fate/hevc.mak
+++ FFmpeg/tests/fate/hevc.mak
@@ -222,7 +222,7 @@ FATE_HEVC-$(call ALLYES, HEVC_DEMUXER MO
@@ -233,7 +233,7 @@ FATE_HEVC-$(call ALLYES, HEVC_DEMUXER MO
fate-hevc-bsf-mp4toannexb: tests/data/hevc-mp4.mov
fate-hevc-bsf-mp4toannexb: CMD = md5 -i $(TARGET_PATH)/tests/data/hevc-mp4.mov -c:v copy -fflags +bitexact -f hevc
fate-hevc-bsf-mp4toannexb: CMP = oneline
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_subtitles.c
+++ FFmpeg/libavfilter/vf_subtitles.c
@@ -65,6 +65,9 @@ typedef struct AssContext {
@@ -64,6 +64,9 @@ typedef struct AssContext {
int shaping;
FFDrawContext draw;
int wrap_unicode;
@@ -12,7 +12,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
} AssContext;
#define OFFSET(x) offsetof(AssContext, x)
@@ -75,7 +78,12 @@ typedef struct AssContext {
@@ -74,7 +77,12 @@ typedef struct AssContext {
{"f", "set the filename of file to read", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, \
{"original_size", "set the size of the original video (used to scale fonts)", OFFSET(original_w), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS }, \
{"fontsdir", "set the directory containing the fonts to read", OFFSET(fontsdir), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, \
@@ -26,7 +26,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
/* libass supports a log level ranging from 0 to 7 */
static const int ass_libavfilter_log_level_map[] = {
@@ -162,6 +170,8 @@ static int config_input(AVFilterLink *in
@@ -161,6 +169,8 @@ static int config_input(AVFilterLink *in
if (ass->shaping != -1)
ass_set_shaper(ass->renderer, ass->shaping);
@@ -35,8 +35,11 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
return 0;
}
@@ -192,18 +202,41 @@ static int filter_frame(AVFilterLink *in
@@ -189,20 +199,44 @@ static int filter_frame(AVFilterLink *in
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = ctx->outputs[0];
+ FilterLink *outl = ff_filter_link(outlink);
AssContext *ass = ctx->priv;
int detect_change = 0;
- double time_ms = picref->pts * av_q2d(inlink->time_base) * 1000;
@@ -45,7 +48,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
time_ms, &detect_change);
+ if (ass->sub2video) {
+ if (!image && !ass->last_image && picref->pts <= ass->max_pts && outlink->current_pts != AV_NOPTS_VALUE) {
+ if (!image && !ass->last_image && picref->pts <= ass->max_pts && outl->current_pts != AV_NOPTS_VALUE) {
+ av_log(ctx, AV_LOG_DEBUG, "sub2video skip pts:%"PRId64"\n", picref->pts);
+ av_frame_free(&picref);
+ return 0;
@@ -79,7 +82,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
static const AVFilterPad ass_inputs[] = {
{
.name = "default",
@@ -218,10 +251,6 @@ static const AVFilterPad ass_inputs[] =
@@ -217,10 +251,6 @@ static const AVFilterPad ass_inputs[] =
static const AVOption ass_options[] = {
COMMON_OPTIONS
@@ -90,7 +93,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
{NULL},
};
@@ -245,6 +274,9 @@ static av_cold int init_ass(AVFilterCont
@@ -244,6 +274,9 @@ static av_cold int init_ass(AVFilterCont
ass->filename);
return AVERROR(EINVAL);
}
@@ -100,7 +103,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
return 0;
}
@@ -266,8 +298,8 @@ const AVFilter ff_vf_ass = {
@@ -265,8 +298,8 @@ const AVFilter ff_vf_ass = {
static const AVOption subtitles_options[] = {
COMMON_OPTIONS
{"charenc", "set input character encoding", OFFSET(charenc), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS},
@@ -111,7 +114,7 @@ Index: FFmpeg/libavfilter/vf_subtitles.c
{"force_style", "force subtitle style", OFFSET(force_style), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS},
#if FF_ASS_FEATURE_WRAP_UNICODE
{"wrap_unicode", "break lines according to the Unicode Line Breaking Algorithm", OFFSET(wrap_unicode), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, FLAGS },
@@ -496,6 +528,8 @@ static av_cold int init_subtitles(AVFilt
@@ -495,6 +528,8 @@ static av_cold int init_subtitles(AVFilt
avsubtitle_free(&sub);
}
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -588,6 +588,7 @@ OBJS-$(CONFIG_XSTACK_QSV_FILTER)
@@ -593,6 +593,7 @@ OBJS-$(CONFIG_DRAWBOX_VAAPI_FILTER)
OBJS-$(CONFIG_ALLRGB_FILTER) += vsrc_testsrc.o
OBJS-$(CONFIG_ALLYUV_FILTER) += vsrc_testsrc.o
@@ -14,7 +14,7 @@ Index: FFmpeg/libavfilter/allfilters.c
===================================================================
--- FFmpeg.orig/libavfilter/allfilters.c
+++ FFmpeg/libavfilter/allfilters.c
@@ -552,6 +552,7 @@ extern const AVFilter ff_vf_xstack_qsv;
@@ -556,6 +556,7 @@ extern const AVFilter ff_vf_drawbox_vaap
extern const AVFilter ff_vsrc_allrgb;
extern const AVFilter ff_vsrc_allyuv;
@@ -26,7 +26,7 @@ Index: FFmpeg/libavfilter/vsrc_alphasrc.c
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vsrc_alphasrc.c
@@ -0,0 +1,164 @@
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2021 NyanMisaka
+ *
@@ -54,11 +54,11 @@ Index: FFmpeg/libavfilter/vsrc_alphasrc.c
+
+#include "libavutil/avstring.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "filters.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "filters.h"
+#include "formats.h"
+#include "video.h"
+
@@ -99,6 +99,7 @@ Index: FFmpeg/libavfilter/vsrc_alphasrc.c
+
+static int alphasrc_config_output(AVFilterLink *outlink)
+{
+ FilterLink *outl = ff_filter_link(outlink);
+ AVFilterContext *ctx = outlink->src;
+ AlphaSrc *s = ctx->priv;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format);
@@ -118,7 +119,7 @@ Index: FFmpeg/libavfilter/vsrc_alphasrc.c
+
+ outlink->w = s->out_w;
+ outlink->h = s->out_h;
+ outlink->frame_rate = s->frame_rate;
+ outl->frame_rate = s->frame_rate;
+ outlink->time_base = s->time_base;
+ outlink->sample_aspect_ratio = (AVRational){1, 1};
+
@@ -0,0 +1,12 @@
Index: FFmpeg/libavcodec/hw_base_encode.h
===================================================================
--- FFmpeg.orig/libavcodec/hw_base_encode.h
+++ FFmpeg/libavcodec/hw_base_encode.h
@@ -248,6 +248,6 @@ int ff_hw_base_encode_close(FFHWBaseEnco
{ "async_depth", "Maximum processing parallelism. " \
"Increase this to improve single channel performance.", \
OFFSET(common.base.async_depth), AV_OPT_TYPE_INT, \
- { .i64 = 2 }, 1, MAX_ASYNC_DEPTH, FLAGS }
+ { .i64 = 4 }, 1, MAX_ASYNC_DEPTH, FLAGS }
#endif /* AVCODEC_HW_BASE_ENCODE_H */
@@ -1,8 +1,8 @@
Index: FFmpeg/libavcodec/vaapi_encode_h265.c
Index: FFmpeg/libavcodec/hw_base_encode_h265.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode_h265.c
+++ FFmpeg/libavcodec/vaapi_encode_h265.c
@@ -452,8 +452,9 @@ static int vaapi_encode_h265_init_sequen
--- FFmpeg.orig/libavcodec/hw_base_encode_h265.c
+++ FFmpeg/libavcodec/hw_base_encode_h265.c
@@ -216,8 +216,9 @@ int ff_hw_base_encode_init_params_h265(F
sps->log2_min_luma_transform_block_size_minus2 = 0;
sps->log2_diff_max_min_luma_transform_block_size = 3;
// Full transform hierarchy allowed (2-5).
@@ -1,13 +0,0 @@
Index: FFmpeg/libavcodec/vaapi_encode.h
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode.h
+++ FFmpeg/libavcodec/vaapi_encode.h
@@ -520,7 +520,7 @@ int ff_vaapi_encode_close(AVCodecContext
"Increase this to improve single channel performance. This option " \
"doesn't work if driver doesn't implement vaSyncBuffer function.", \
OFFSET(common.async_depth), AV_OPT_TYPE_INT, \
- { .i64 = 2 }, 1, MAX_ASYNC_DEPTH, FLAGS }, \
+ { .i64 = 4 }, 1, MAX_ASYNC_DEPTH, FLAGS }, \
{ "max_frame_size", \
"Maximum frame size (in bytes)",\
OFFSET(common.max_frame_size), AV_OPT_TYPE_INT, \
@@ -2,7 +2,7 @@ Index: FFmpeg/libavformat/id3v2.c
===================================================================
--- FFmpeg.orig/libavformat/id3v2.c
+++ FFmpeg/libavformat/id3v2.c
@@ -136,6 +136,7 @@ const CodecMime ff_id3v2_mime_tags[] = {
@@ -137,6 +137,7 @@ const CodecMime ff_id3v2_mime_tags[] = {
{ "image/png", AV_CODEC_ID_PNG },
{ "image/tiff", AV_CODEC_ID_TIFF },
{ "image/bmp", AV_CODEC_ID_BMP },
@@ -10,7 +10,7 @@ Index: FFmpeg/libavformat/id3v2.c
{ "JPG", AV_CODEC_ID_MJPEG }, /* ID3v2.2 */
{ "PNG", AV_CODEC_ID_PNG }, /* ID3v2.2 */
{ "", AV_CODEC_ID_NONE },
@@ -325,39 +326,54 @@ static void read_ttag(AVFormatContext *s
@@ -326,39 +327,54 @@ static void read_ttag(AVFormatContext *s
AVDictionary **metadata, const char *key)
{
uint8_t *dst;
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -1872,7 +1872,6 @@ EXTERNAL_LIBRARY_GPL_LIST="
@@ -1876,7 +1876,6 @@ EXTERNAL_LIBRARY_GPL_LIST="
EXTERNAL_LIBRARY_NONFREE_LIST="
decklink
@@ -10,7 +10,7 @@ Index: FFmpeg/configure
libtls
"
@@ -1912,6 +1911,7 @@ EXTERNAL_LIBRARY_LIST="
@@ -1916,6 +1915,7 @@ EXTERNAL_LIBRARY_LIST="
libcodec2
libdav1d
libdc1394
@@ -1,168 +1,10 @@
Index: FFmpeg/libavformat/hlsenc.c
===================================================================
--- FFmpeg.orig/libavformat/hlsenc.c
+++ FFmpeg/libavformat/hlsenc.c
@@ -850,7 +850,7 @@ static int hls_mux_init(AVFormatContext
AVFormatContext *vtt_oc = NULL;
int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
int remaining_options;
- int i, ret;
+ int i, j, ret;
ret = avformat_alloc_output_context2(&vs->avf, vs->oformat, NULL, NULL);
if (ret < 0)
@@ -896,6 +896,20 @@ static int hls_mux_init(AVFormatContext
st->codecpar->codec_tag = 0;
}
+ // copy side data
+ for (j = 0; j < vs->streams[i]->codecpar->nb_coded_side_data; j++) {
+ const AVPacketSideData *sd_src = &vs->streams[i]->codecpar->coded_side_data[j];
+ AVPacketSideData *sd_dst;
+
+ sd_dst = av_packet_side_data_new(&st->codecpar->coded_side_data,
+ &st->codecpar->nb_coded_side_data,
+ sd_src->type, sd_src->size, 0);
+ if (!sd_dst)
+ return AVERROR(ENOMEM);
+
+ memcpy(sd_dst->data, sd_src->data, sd_src->size);
+ }
+
st->sample_aspect_ratio = vs->streams[i]->sample_aspect_ratio;
st->time_base = vs->streams[i]->time_base;
av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
Index: FFmpeg/libavformat/movenc.c
===================================================================
--- FFmpeg.orig/libavformat/movenc.c
+++ FFmpeg/libavformat/movenc.c
@@ -2538,8 +2538,9 @@ static int mov_write_video_tag(AVFormatC
mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
if (spherical_mapping)
mov_write_sv3d_tag(mov->fc, pb, (AVSphericalMapping*)spherical_mapping->data);
- if (dovi)
+ if (dovi && !ff_isom_validate_dovi_config((AVDOVIDecoderConfigurationRecord *)dovi->data, track->par, track->tag)) {
mov_write_dvcc_dvvc_tag(s, pb, (AVDOVIDecoderConfigurationRecord *)dovi->data);
+ }
}
if (track->par->sample_aspect_ratio.den && track->par->sample_aspect_ratio.num) {
@@ -8128,6 +8129,7 @@ static const AVCodecTag codec_mp4_tags[]
{ AV_CODEC_ID_HEVC, MKTAG('h', 'e', 'v', '1') },
{ AV_CODEC_ID_HEVC, MKTAG('h', 'v', 'c', '1') },
{ AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', '1') },
+ { AV_CODEC_ID_HEVC, MKTAG('d', 'v', 'h', 'e') },
{ AV_CODEC_ID_VVC, MKTAG('v', 'v', 'c', '1') },
{ AV_CODEC_ID_VVC, MKTAG('v', 'v', 'i', '1') },
{ AV_CODEC_ID_EVC, MKTAG('e', 'v', 'c', '1') },
@@ -8141,6 +8143,7 @@ static const AVCodecTag codec_mp4_tags[]
{ AV_CODEC_ID_TSCC2, MKTAG('m', 'p', '4', 'v') },
{ AV_CODEC_ID_VP9, MKTAG('v', 'p', '0', '9') },
{ AV_CODEC_ID_AV1, MKTAG('a', 'v', '0', '1') },
+ { AV_CODEC_ID_AV1, MKTAG('d', 'a', 'v', '1') },
{ AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
{ AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') },
{ AV_CODEC_ID_MP4ALS, MKTAG('m', 'p', '4', 'a') },
Index: FFmpeg/libavformat/mpegtsenc.c
===================================================================
--- FFmpeg.orig/libavformat/mpegtsenc.c
+++ FFmpeg/libavformat/mpegtsenc.c
@@ -23,6 +23,7 @@
#include "libavutil/bswap.h"
#include "libavutil/crc.h"
#include "libavutil/dict.h"
+#include "libavutil/dovi_meta.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
@@ -40,6 +41,7 @@
#include "internal.h"
#include "mpegts.h"
#include "mux.h"
+#include "dovi_isom.h"
#define PCR_TIME_BASE 27000000
@@ -350,6 +352,52 @@ static void put_registration_descriptor(
*q_ptr = q;
}
+static int put_dovi_descriptor(AVFormatContext *s, uint8_t **q_ptr,
+ const AVDOVIDecoderConfigurationRecord *dovi)
+{
+ uint16_t val16;
+ uint8_t *q = *q_ptr;
+
+ if (!dovi)
+ return AVERROR(ENOMEM);
+
+ if (!dovi->bl_present_flag) {
+ av_log(s, AV_LOG_ERROR,
+ "EL only DOVI stream is not supported!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ put_registration_descriptor(&q, MKTAG('D', 'O', 'V', 'I')); // format_identifier
+
+ /* DOVI Video Stream Descriptor Syntax */
+ *q++ = 0xb0; // descriptor_tag
+ *q++ = 0x05; // descriptor_length
+ *q++ = dovi->dv_version_major;
+ *q++ = dovi->dv_version_minor;
+
+ val16 = (dovi->dv_profile & 0x7f) << 9 | // 7 bits
+ (dovi->dv_level & 0x3f) << 3 | // 6 bits
+ (dovi->rpu_present_flag & 0x01) << 2 | // 1 bits
+ (dovi->el_present_flag & 0x01) << 1 | // 1 bits
+ (dovi->bl_present_flag & 0x01); // 1 bits
+ put16(&q, val16);
+
+#if 0
+ // TODO: support dependency_pid (EL only stream)
+ // descriptor_length: 0x05->0x07
+ if (!bl_present_flag) {
+ val16 = (dependency_pid & 0x1fff) << 3; // 13+3 bits
+ put16(&q, val16);
+ }
+#endif
+
+ *q++ = (dovi->dv_bl_signal_compatibility_id & 0x0f) << 4; // 4+4 bits
+
+ *q_ptr = q;
+
+ return 0;
+}
+
static int get_dvb_stream_type(AVFormatContext *s, AVStream *st)
{
MpegTSWrite *ts = s->priv_data;
@@ -803,7 +851,18 @@ static int mpegts_write_pmt(AVFormatCont
} else if (stream_type == STREAM_TYPE_VIDEO_VC1) {
put_registration_descriptor(&q, MKTAG('V', 'C', '-', '1'));
} else if (stream_type == STREAM_TYPE_VIDEO_HEVC && s->strict_std_compliance <= FF_COMPLIANCE_NORMAL) {
- put_registration_descriptor(&q, MKTAG('H', 'E', 'V', 'C'));
+ const AVPacketSideData *sd = av_packet_side_data_get(st->codecpar->coded_side_data,
+ st->codecpar->nb_coded_side_data, AV_PKT_DATA_DOVI_CONF);
+ const AVDOVIDecoderConfigurationRecord *dovi = sd ? (const AVDOVIDecoderConfigurationRecord *)sd->data : NULL;
+ if (dovi &&
+ dovi->bl_present_flag &&
+ s->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL &&
+ !ff_isom_validate_dovi_config(dovi, st->codecpar, MKTAG('d', 'v', 'h', '1'))) { // always assume tag is valid
+ if (put_dovi_descriptor(s, &q, dovi) < 0)
+ break;
+ } else {
+ put_registration_descriptor(&q, MKTAG('H', 'E', 'V', 'C'));
+ }
} else if (stream_type == STREAM_TYPE_VIDEO_CAVS || stream_type == STREAM_TYPE_VIDEO_AVS2 ||
stream_type == STREAM_TYPE_VIDEO_AVS3) {
put_registration_descriptor(&q, MKTAG('A', 'V', 'S', 'V'));
Index: FFmpeg/libavformat/dovi_isom.c
===================================================================
--- FFmpeg.orig/libavformat/dovi_isom.c
+++ FFmpeg/libavformat/dovi_isom.c
@@ -116,3 +116,74 @@ void ff_isom_put_dvcc_dvvc(void *logctx,
dovi->bl_present_flag,
dovi->dv_bl_signal_compatibility_id);
@@ -124,3 +124,74 @@ void ff_isom_put_dvcc_dvvc(void *logctx,
dovi->dv_bl_signal_compatibility_id,
dovi->dv_md_compression);
}
+
+int ff_isom_validate_dovi_config(const AVDOVIDecoderConfigurationRecord *dovi,
@@ -242,7 +84,7 @@ Index: FFmpeg/libavformat/dovi_isom.h
@@ -33,4 +33,12 @@ int ff_isom_parse_dvcc_dvvc(void *logctx
void ff_isom_put_dvcc_dvvc(void *logctx, uint8_t out[ISOM_DVCC_DVVC_SIZE],
const AVDOVIDecoderConfigurationRecord *dovi);
+/*
+ * Check if the AVDOVIDecoderConfigurationRecord is spec-compliant for current codec parameters
+ * Used by muxers to determine if the configuration record should be copied into the container
@@ -252,13 +94,47 @@ Index: FFmpeg/libavformat/dovi_isom.h
+ const AVCodecParameters *codec_par, int codec_tag);
+
#endif /* AVFORMAT_DOVI_ISOM_H */
Index: FFmpeg/libavformat/hlsenc.c
===================================================================
--- FFmpeg.orig/libavformat/hlsenc.c
+++ FFmpeg/libavformat/hlsenc.c
@@ -850,7 +850,7 @@ static int hls_mux_init(AVFormatContext
AVFormatContext *vtt_oc = NULL;
int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
int remaining_options;
- int i, ret;
+ int i, j, ret;
ret = avformat_alloc_output_context2(&vs->avf, vs->oformat, NULL, NULL);
if (ret < 0)
@@ -898,6 +898,20 @@ static int hls_mux_init(AVFormatContext
st->codecpar->codec_tag = 0;
}
+ // copy side data
+ for (j = 0; j < vs->streams[i]->codecpar->nb_coded_side_data; j++) {
+ const AVPacketSideData *sd_src = &vs->streams[i]->codecpar->coded_side_data[j];
+ AVPacketSideData *sd_dst;
+
+ sd_dst = av_packet_side_data_new(&st->codecpar->coded_side_data,
+ &st->codecpar->nb_coded_side_data,
+ sd_src->type, sd_src->size, 0);
+ if (!sd_dst)
+ return AVERROR(ENOMEM);
+
+ memcpy(sd_dst->data, sd_src->data, sd_src->size);
+ }
+
st->sample_aspect_ratio = vs->streams[i]->sample_aspect_ratio;
st->time_base = vs->streams[i]->time_base;
av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
Index: FFmpeg/libavformat/matroskaenc.c
===================================================================
--- FFmpeg.orig/libavformat/matroskaenc.c
+++ FFmpeg/libavformat/matroskaenc.c
@@ -1718,7 +1718,8 @@ static void mkv_write_blockadditionmappi
@@ -1724,7 +1724,8 @@ static void mkv_write_blockadditionmappi
return;
dovi = (const AVDOVIDecoderConfigurationRecord *)sd->data;
- if (dovi->dv_profile <= 10) {
+ if (dovi->dv_profile <= 10 &&
@@ -266,3 +142,111 @@ Index: FFmpeg/libavformat/matroskaenc.c
ebml_master mapping;
uint8_t buf[ISOM_DVCC_DVVC_SIZE];
uint32_t type;
Index: FFmpeg/libavformat/movenc.c
===================================================================
--- FFmpeg.orig/libavformat/movenc.c
+++ FFmpeg/libavformat/movenc.c
@@ -2809,7 +2809,9 @@ static int mov_write_video_tag(AVFormatC
track->st->codecpar->nb_coded_side_data,
AV_PKT_DATA_DOVI_CONF);
if (dovi && mov->fc->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
- mov_write_dvcc_dvvc_tag(s, pb, (AVDOVIDecoderConfigurationRecord *)dovi->data);
+ if (!ff_isom_validate_dovi_config((AVDOVIDecoderConfigurationRecord *)dovi->data, track->par, track->tag)) {
+ mov_write_dvcc_dvvc_tag(s, pb, (AVDOVIDecoderConfigurationRecord *)dovi->data);
+ }
} else if (dovi) {
av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. Requires -strict unofficial.\n");
}
Index: FFmpeg/libavformat/mpegtsenc.c
===================================================================
--- FFmpeg.orig/libavformat/mpegtsenc.c
+++ FFmpeg/libavformat/mpegtsenc.c
@@ -23,6 +23,7 @@
#include "libavutil/bswap.h"
#include "libavutil/crc.h"
#include "libavutil/dict.h"
+#include "libavutil/dovi_meta.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/mem.h"
@@ -38,6 +39,7 @@
#include "avformat.h"
#include "avio_internal.h"
+#include "dovi_isom.h"
#include "internal.h"
#include "mpegts.h"
#include "mux.h"
@@ -351,6 +353,52 @@ static void put_registration_descriptor(
*q_ptr = q;
}
+static int put_dovi_descriptor(AVFormatContext *s, uint8_t **q_ptr,
+ const AVDOVIDecoderConfigurationRecord *dovi)
+{
+ uint16_t val16;
+ uint8_t *q = *q_ptr;
+
+ if (!dovi)
+ return AVERROR(ENOMEM);
+
+ if (!dovi->bl_present_flag) {
+ av_log(s, AV_LOG_ERROR,
+ "EL only DOVI stream is not supported!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ put_registration_descriptor(&q, MKTAG('D', 'O', 'V', 'I')); // format_identifier
+
+ /* DOVI Video Stream Descriptor Syntax */
+ *q++ = 0xb0; // descriptor_tag
+ *q++ = 0x05; // descriptor_length
+ *q++ = dovi->dv_version_major;
+ *q++ = dovi->dv_version_minor;
+
+ val16 = (dovi->dv_profile & 0x7f) << 9 | // 7 bits
+ (dovi->dv_level & 0x3f) << 3 | // 6 bits
+ (dovi->rpu_present_flag & 0x01) << 2 | // 1 bit
+ (dovi->el_present_flag & 0x01) << 1 | // 1 bit
+ (dovi->bl_present_flag & 0x01); // 1 bit
+ put16(&q, val16);
+
+#if 0
+ // TODO: support dependency_pid (EL only stream)
+ // descriptor_length: 0x05->0x07
+ if (!bl_present_flag) {
+ val16 = (dependency_pid & 0x1fff) << 3; // 13+3 bits
+ put16(&q, val16);
+ }
+#endif
+
+ *q++ = (dovi->dv_bl_signal_compatibility_id & 0x0f) << 4; // 4+4 bits
+
+ *q_ptr = q;
+
+ return 0;
+}
+
static int get_dvb_stream_type(AVFormatContext *s, AVStream *st)
{
MpegTSWrite *ts = s->priv_data;
@@ -804,7 +852,18 @@ static int mpegts_write_pmt(AVFormatCont
} else if (stream_type == STREAM_TYPE_VIDEO_VC1) {
put_registration_descriptor(&q, MKTAG('V', 'C', '-', '1'));
} else if (stream_type == STREAM_TYPE_VIDEO_HEVC && s->strict_std_compliance <= FF_COMPLIANCE_NORMAL) {
- put_registration_descriptor(&q, MKTAG('H', 'E', 'V', 'C'));
+ const AVPacketSideData *sd = av_packet_side_data_get(st->codecpar->coded_side_data,
+ st->codecpar->nb_coded_side_data, AV_PKT_DATA_DOVI_CONF);
+ const AVDOVIDecoderConfigurationRecord *dovi = sd ? (const AVDOVIDecoderConfigurationRecord *)sd->data : NULL;
+ if (dovi &&
+ dovi->bl_present_flag &&
+ s->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL &&
+ !ff_isom_validate_dovi_config(dovi, st->codecpar, MKTAG('d', 'v', 'h', '1'))) { // always assume tag is valid
+ if (put_dovi_descriptor(s, &q, dovi) < 0)
+ break;
+ } else {
+ put_registration_descriptor(&q, MKTAG('H', 'E', 'V', 'C'));
+ }
} else if (stream_type == STREAM_TYPE_VIDEO_CAVS || stream_type == STREAM_TYPE_VIDEO_AVS2 ||
stream_type == STREAM_TYPE_VIDEO_AVS3) {
put_registration_descriptor(&q, MKTAG('A', 'V', 'S', 'V'));
@@ -2,7 +2,7 @@ Index: FFmpeg/fftools/ffmpeg.c
===================================================================
--- FFmpeg.orig/fftools/ffmpeg.c
+++ FFmpeg/fftools/ffmpeg.c
@@ -116,6 +116,9 @@ typedef struct BenchmarkTimeStamps {
@@ -95,6 +95,9 @@ typedef struct BenchmarkTimeStamps {
static BenchmarkTimeStamps get_benchmark_time_stamps(void);
static int64_t getmaxrss(void);
@@ -12,7 +12,7 @@ Index: FFmpeg/fftools/ffmpeg.c
atomic_uint nb_output_dumped = 0;
@@ -134,6 +137,9 @@ int nb_filtergraphs;
@@ -113,6 +116,9 @@ int nb_filtergraphs;
Decoder **decoders;
int nb_decoders;
@@ -22,7 +22,7 @@ Index: FFmpeg/fftools/ffmpeg.c
#if HAVE_TERMIOS_H
/* init terminal so that we can grab keys */
@@ -773,12 +779,28 @@ static void set_tty_echo(int on)
@@ -785,12 +791,28 @@ static void set_tty_echo(int on)
#endif
}
@@ -52,7 +52,7 @@ Index: FFmpeg/fftools/ffmpeg.c
/* read_key() returns 0 on EOF */
if (cur_time - last_time >= 100000) {
key = read_key();
@@ -791,6 +813,11 @@ static int check_keyboard_interaction(in
@@ -803,6 +825,11 @@ static int check_keyboard_interaction(in
}
if (key == '+') av_log_set_level(av_log_get_level()+10);
if (key == '-') av_log_set_level(av_log_get_level()-10);
@@ -64,7 +64,7 @@ Index: FFmpeg/fftools/ffmpeg.c
if (key == 'c' || key == 'C'){
char buf[4096], target[64], command[256], arg[256] = {0};
double time;
@@ -825,7 +852,9 @@ static int check_keyboard_interaction(in
@@ -842,7 +869,9 @@ static int check_keyboard_interaction(in
"c Send command to first matching filter supporting it\n"
"C Send/Queue command to all matching filters\n"
"h dump packets/hex press to cycle through the 3 states\n"
@@ -74,7 +74,7 @@ Index: FFmpeg/fftools/ffmpeg.c
"s Show QP histogram\n"
);
}
@@ -855,12 +884,15 @@ static int transcode(Scheduler *sch)
@@ -872,12 +901,15 @@ static int transcode(Scheduler *sch)
timer_start = av_gettime_relative();
while (!sch_wait(sch, stats_period, &transcode_ts)) {
@@ -93,7 +93,7 @@ Index: FFmpeg/fftools/ffmpeg.c
/* dump report by using the output first video and audio streams */
print_report(0, timer_start, cur_time, transcode_ts);
@@ -877,11 +909,17 @@ static int transcode(Scheduler *sch)
@@ -894,11 +926,17 @@ static int transcode(Scheduler *sch)
term_exit();
/* dump report by using the first video and audio streams */
@@ -116,7 +116,7 @@ Index: FFmpeg/fftools/ffmpeg.h
===================================================================
--- FFmpeg.orig/fftools/ffmpeg.h
+++ FFmpeg/fftools/ffmpeg.h
@@ -667,6 +667,9 @@ extern int recast_media;
@@ -748,6 +748,9 @@ extern int recast_media;
extern FILE *vstats_file;
@@ -130,7 +130,7 @@ Index: FFmpeg/fftools/ffmpeg_demux.c
===================================================================
--- FFmpeg.orig/fftools/ffmpeg_demux.c
+++ FFmpeg/fftools/ffmpeg_demux.c
@@ -699,6 +699,11 @@ static int input_thread(void *arg)
@@ -703,6 +703,11 @@ static int input_thread(void *arg)
DemuxStream *ds;
unsigned send_flags = 0;
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -5558,7 +5558,7 @@ elif enabled x86; then
@@ -5601,7 +5601,7 @@ elif enabled x86; then
;;
# everything else should support nopl and conditional mov (cmov)
*)
@@ -11,7 +11,7 @@ Index: FFmpeg/configure
enable i686
enable fast_cmov
;;
@@ -7539,7 +7539,9 @@ if enabled icc; then
@@ -7592,7 +7592,9 @@ if enabled icc; then
disable aligned_stack
fi
elif enabled gcc; then
@@ -22,20 +22,6 @@ Index: FFmpeg/configure
check_cflags -Werror=format-security
check_cflags -Werror=implicit-function-declaration
check_cflags -Werror=missing-prototypes
Index: FFmpeg/libavcodec/x86/cabac.h
===================================================================
--- FFmpeg.orig/libavcodec/x86/cabac.h
+++ FFmpeg/libavcodec/x86/cabac.h
@@ -183,6 +183,9 @@ av_noinline
#else
av_always_inline
#endif
+#ifdef __GNUC__
+__attribute__((optimize("-fno-tree-vectorize")))
+#endif
int get_cabac_inline_x86(CABACContext *c, uint8_t *const state)
{
int bit, tmp;
Index: FFmpeg/libavcodec/huffyuvdsp.c
===================================================================
--- FFmpeg.orig/libavcodec/huffyuvdsp.c
@@ -72,3 +58,17 @@ Index: FFmpeg/libavcodec/huffyuvenc.c
#include "config_components.h"
#include "avcodec.h"
Index: FFmpeg/libavcodec/x86/cabac.h
===================================================================
--- FFmpeg.orig/libavcodec/x86/cabac.h
+++ FFmpeg/libavcodec/x86/cabac.h
@@ -183,6 +183,9 @@ av_noinline
#else
av_always_inline
#endif
+#ifdef __GNUC__
+__attribute__((optimize("-fno-tree-vectorize")))
+#endif
int get_cabac_inline_x86(CABACContext *c, uint8_t *const state)
{
int bit, tmp;
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/dxva2.c
===================================================================
--- FFmpeg.orig/libavcodec/dxva2.c
+++ FFmpeg/libavcodec/dxva2.c
@@ -615,6 +615,16 @@ int ff_dxva2_common_frame_params(AVCodec
@@ -616,6 +616,16 @@ int ff_dxva2_common_frame_params(AVCodec
else
surface_alignment = 16;
@@ -19,11 +19,20 @@ Index: FFmpeg/libavcodec/dxva2.c
/* 1 base work surface */
num_surfaces = 1;
@@ -625,7 +635,7 @@ int ff_dxva2_common_frame_params(AVCodec
else if (avctx->codec_id == AV_CODEC_ID_VP9 || avctx->codec_id == AV_CODEC_ID_AV1)
num_surfaces += 8;
else
- num_surfaces += 2;
+ num_surfaces += 2 + 4; /* 4 base work surface in vpp async */
frames_ctx->sw_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;
Index: FFmpeg/libavutil/hwcontext_d3d11va.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_d3d11va.c
+++ FFmpeg/libavutil/hwcontext_d3d11va.c
@@ -609,6 +609,35 @@ static int d3d11va_device_find_adapter_b
@@ -611,6 +611,35 @@ static int d3d11va_device_find_adapter_b
return -1;
}
@@ -59,7 +68,7 @@ Index: FFmpeg/libavutil/hwcontext_d3d11va.c
static int d3d11va_device_create(AVHWDeviceContext *ctx, const char *device,
AVDictionary *opts, int flags)
{
@@ -686,6 +715,9 @@ static int d3d11va_device_create(AVHWDev
@@ -688,6 +717,9 @@ static int d3d11va_device_create(AVHWDev
ID3D10Multithread_Release(pMultithread);
}
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_overlay_cuda.c
+++ FFmpeg/libavfilter/vf_overlay_cuda.c
@@ -50,6 +50,8 @@
@@ -49,6 +49,8 @@
static const enum AVPixelFormat supported_main_formats[] = {
AV_PIX_FMT_NV12,
AV_PIX_FMT_YUV420P,
@@ -11,7 +11,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
AV_PIX_FMT_NONE,
};
@@ -105,12 +107,15 @@ typedef struct OverlayCUDAContext {
@@ -104,12 +106,14 @@ typedef struct OverlayCUDAContext {
enum AVPixelFormat in_format_overlay;
enum AVPixelFormat in_format_main;
@@ -20,7 +20,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
AVBufferRef *hw_device_ctx;
AVCUDADeviceContext *hwctx;
CUcontext cu_ctx;
- CUcontext cu_ctx;
CUmodule cu_module;
- CUfunction cu_func;
+ CUfunction cu_func_uchar;
@@ -28,7 +28,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
CUstream cu_stream;
FFFrameSync fs;
@@ -185,7 +190,10 @@ static int set_expr(AVExpr **pexpr, cons
@@ -184,7 +188,10 @@ static int set_expr(AVExpr **pexpr, cons
static int formats_match(const enum AVPixelFormat format_main, const enum AVPixelFormat format_overlay) {
switch(format_main) {
case AV_PIX_FMT_NV12:
@@ -40,7 +40,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
case AV_PIX_FMT_YUV420P:
return format_overlay == AV_PIX_FMT_YUV420P ||
format_overlay == AV_PIX_FMT_YUVA420P;
@@ -200,11 +208,13 @@ static int formats_match(const enum AVPi
@@ -199,11 +206,13 @@ static int formats_match(const enum AVPi
static int overlay_cuda_call_kernel(
OverlayCUDAContext *ctx,
int x_position, int y_position,
@@ -57,7 +57,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
int alpha_adj_x, int alpha_adj_y) {
CudaFunctions *cu = ctx->hwctx->internal->cuda_dl;
@@ -212,14 +222,18 @@ static int overlay_cuda_call_kernel(
@@ -211,14 +220,18 @@ static int overlay_cuda_call_kernel(
void* kernel_args[] = {
&x_position, &y_position,
&main_data, &main_linesize,
@@ -77,7 +77,16 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
DIV_UP(main_width, BLOCK_X), DIV_UP(main_height, BLOCK_Y), 1,
BLOCK_X, BLOCK_Y, 1,
0, ctx->cu_stream, kernel_args, NULL));
@@ -300,11 +314,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
@@ -242,8 +255,6 @@ static int overlay_cuda_blend(FFFrameSyn
AVFrame *input_main, *input_overlay;
- ctx->cu_ctx = cuda_ctx;
-
// read main and overlay frames from inputs
ret = ff_framesync_dualinput_get(fs, &input_main, &input_overlay);
if (ret < 0)
@@ -300,11 +311,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
overlay_cuda_call_kernel(ctx,
ctx->x_position, ctx->y_position,
@@ -94,7 +103,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
// overlay rest planes depending on pixel format
@@ -312,29 +328,42 @@ FF_ENABLE_DEPRECATION_WARNINGS
@@ -312,29 +325,42 @@ FF_ENABLE_DEPRECATION_WARNINGS
case AV_PIX_FMT_NV12:
overlay_cuda_call_kernel(ctx,
ctx->x_position, ctx->y_position / 2,
@@ -154,7 +163,16 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
break;
default:
av_log(ctx, AV_LOG_ERROR, "Passed unsupported overlay pixel format\n");
@@ -462,6 +491,8 @@ static int overlay_cuda_config_output(AV
@@ -406,7 +432,7 @@ static av_cold void overlay_cuda_uninit(
if (ctx->hwctx && ctx->cu_module) {
CUcontext dummy;
CudaFunctions *cu = ctx->hwctx->internal->cuda_dl;
- CHECK_CU(cu->cuCtxPushCurrent(ctx->cu_ctx));
+ CHECK_CU(cu->cuCtxPushCurrent(ctx->hwctx->cuda_ctx));
CHECK_CU(cu->cuModuleUnload(ctx->cu_module));
CHECK_CU(cu->cuCtxPopCurrent(&dummy));
}
@@ -465,6 +491,8 @@ static int overlay_cuda_config_output(AV
return AVERROR(ENOSYS);
}
@@ -163,7 +181,7 @@ Index: FFmpeg/libavfilter/vf_overlay_cuda.c
// check overlay input formats
if (!frames_ctx_overlay) {
@@ -515,7 +546,13 @@ static int overlay_cuda_config_output(AV
@@ -518,7 +546,13 @@ static int overlay_cuda_config_output(AV
return err;
}
@@ -5,7 +5,7 @@ Index: FFmpeg/libavcodec/nvenc.c
@@ -24,6 +24,7 @@
#include "nvenc.h"
#include "hevc_sei.h"
#include "hevc/sei.h"
+#include "put_bits.h"
#if CONFIG_AV1_NVENC_ENCODER
#include "av1.h"
@@ -18,7 +18,7 @@ Index: FFmpeg/libavcodec/nvenc.c
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
#include "libavutil/mathematics.h"
@@ -2506,6 +2508,80 @@ static int prepare_sei_data_array(AVCode
@@ -2639,6 +2641,80 @@ static int prepare_sei_data_array(AVCode
}
}
}
@@ -13,7 +13,7 @@ Index: FFmpeg/libavcodec/d3d12va_hevc.c
DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
@@ -151,12 +151,12 @@ static int d3d12va_hevc_end_frame(AVCode
HEVCContext *h = avctx->priv_data;
HEVCDecodePictureContext *ctx_pic = h->ref->hwaccel_picture_private;
HEVCDecodePictureContext *ctx_pic = h->cur_frame->hwaccel_picture_private;
- int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
+ int scale = ctx_pic->pp.main.dwCodingParamToolFlags & 1;
@@ -21,8 +21,8 @@ Index: FFmpeg/libavcodec/d3d12va_hevc.c
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
return -1;
- return ff_d3d12va_common_end_frame(avctx, h->ref->frame, &ctx_pic->pp, sizeof(ctx_pic->pp),
+ return ff_d3d12va_common_end_frame(avctx, h->ref->frame, &ctx_pic->pp.main, sizeof(ctx_pic->pp.main),
- return ff_d3d12va_common_end_frame(avctx, h->cur_frame->f, &ctx_pic->pp, sizeof(ctx_pic->pp),
+ return ff_d3d12va_common_end_frame(avctx, h->cur_frame->f, &ctx_pic->pp.main, sizeof(ctx_pic->pp.main),
scale ? &ctx_pic->qm : NULL, scale ? sizeof(ctx_pic->qm) : 0, update_input_arguments);
}
@@ -30,7 +30,7 @@ Index: FFmpeg/libavcodec/dxva2.c
===================================================================
--- FFmpeg.orig/libavcodec/dxva2.c
+++ FFmpeg/libavcodec/dxva2.c
@@ -43,6 +43,12 @@ DEFINE_GUID(ff_DXVA2_ModeVC1_D,
@@ -44,6 +44,12 @@ DEFINE_GUID(ff_DXVA2_ModeVC1_D,
DEFINE_GUID(ff_DXVA2_ModeVC1_D2010, 0x1b81beA4, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main, 0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0xf2,0xa1,0x16,0x0c,0xc0);
DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main10,0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13);
@@ -43,7 +43,7 @@ Index: FFmpeg/libavcodec/dxva2.c
DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_Profile0,0x463707f8,0xa1d0,0x4585,0x87,0x6d,0x83,0xaa,0x6d,0x60,0xb8,0x9e);
DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_10bit_Profile2,0xa4c749ef,0x6ecf,0x48aa,0x84,0x48,0x50,0xa7,0xa1,0x16,0x5f,0xf7);
DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_Profile0,0xb8be4ccb,0xcf53,0x46ba,0x8d,0x59,0xd6,0xb8,0xa6,0xda,0x5d,0x2a);
@@ -69,6 +75,8 @@ static const int prof_hevc_main[] = {
@@ -70,6 +76,8 @@ static const int prof_hevc_main[] = {
AV_PROFILE_UNKNOWN};
static const int prof_hevc_main10[] = {AV_PROFILE_HEVC_MAIN_10,
AV_PROFILE_UNKNOWN};
@@ -52,7 +52,7 @@ Index: FFmpeg/libavcodec/dxva2.c
static const int prof_vp9_profile0[] = {AV_PROFILE_VP9_0,
AV_PROFILE_UNKNOWN};
static const int prof_vp9_profile2[] = {AV_PROFILE_VP9_2,
@@ -97,6 +105,14 @@ static const dxva_mode dxva_modes[] = {
@@ -98,6 +106,14 @@ static const dxva_mode dxva_modes[] = {
{ &ff_DXVA2_ModeHEVC_VLD_Main10, AV_CODEC_ID_HEVC, prof_hevc_main10 },
{ &ff_DXVA2_ModeHEVC_VLD_Main, AV_CODEC_ID_HEVC, prof_hevc_main },
@@ -67,7 +67,7 @@ Index: FFmpeg/libavcodec/dxva2.c
/* VP8/9 */
{ &ff_DXVA2_ModeVP9_VLD_Profile0, AV_CODEC_ID_VP9, prof_vp9_profile0 },
{ &ff_DXVA2_ModeVP9_VLD_10bit_Profile2, AV_CODEC_ID_VP9, prof_vp9_profile2 },
@@ -107,6 +123,22 @@ static const dxva_mode dxva_modes[] = {
@@ -108,6 +124,22 @@ static const dxva_mode dxva_modes[] = {
{ NULL, 0 },
};
@@ -90,7 +90,7 @@ Index: FFmpeg/libavcodec/dxva2.c
static int dxva_get_decoder_configuration(AVCodecContext *avctx,
const void *cfg_list,
unsigned cfg_count)
@@ -245,7 +277,14 @@ static void dxva_list_guids_debug(AVCode
@@ -246,7 +278,14 @@ static void dxva_list_guids_debug(AVCode
#if CONFIG_DXVA2
if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
const D3DFORMAT formats[] = {MKTAG('N', 'V', '1', '2'),
@@ -106,7 +106,7 @@ Index: FFmpeg/libavcodec/dxva2.c
int i;
for (i = 0; i < FF_ARRAY_ELEMS(formats); i++) {
if (dxva2_validate_output(service, *guid, &formats[i]))
@@ -339,14 +378,28 @@ static int dxva2_get_decoder_configurati
@@ -340,14 +379,28 @@ static int dxva2_get_decoder_configurati
return ret;
}
@@ -137,7 +137,7 @@ Index: FFmpeg/libavcodec/dxva2.c
DXVA2_VideoDesc desc = { 0 };
DXVA2_ConfigPictureDecode config;
HRESULT hr;
@@ -355,6 +408,7 @@ static int dxva2_create_decoder(AVCodecC
@@ -356,6 +409,7 @@ static int dxva2_create_decoder(AVCodecC
AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
AVDXVA2DeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
@@ -145,7 +145,7 @@ Index: FFmpeg/libavcodec/dxva2.c
hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr,
&device_handle);
@@ -455,10 +509,17 @@ static int d3d11va_get_decoder_configura
@@ -456,10 +510,17 @@ static int d3d11va_get_decoder_configura
static DXGI_FORMAT d3d11va_map_sw_to_hw_format(enum AVPixelFormat pix_fmt)
{
switch (pix_fmt) {
@@ -167,9 +167,9 @@ Index: FFmpeg/libavcodec/dxva2.c
}
}
@@ -636,8 +697,7 @@ int ff_dxva2_common_frame_params(AVCodec
@@ -627,8 +688,7 @@ int ff_dxva2_common_frame_params(AVCodec
else
num_surfaces += 2;
num_surfaces += 2 + 4; /* 4 base work surface in vpp async */
- frames_ctx->sw_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
- AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;
@@ -190,7 +190,7 @@ Index: FFmpeg/libavcodec/dxva2_hevc.c
DXVA_Qmatrix_HEVC qm;
unsigned slice_count;
DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
@@ -58,19 +58,49 @@ static int get_refpic_index(const DXVA_P
@@ -58,7 +58,7 @@ static int get_refpic_index(const DXVA_P
}
void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx,
@@ -198,9 +198,10 @@ Index: FFmpeg/libavcodec/dxva2_hevc.c
+ ff_DXVA_PicParams_HEVC_Rext *ppext)
{
const HEVCContext *h = avctx->priv_data;
const HEVCFrame *current_picture = h->ref;
const HEVCSPS *sps = h->ps.sps;
const HEVCPPS *pps = h->ps.pps;
const HEVCLayerContext *l = &h->layers[h->cur_layer];
@@ -66,12 +66,42 @@ void ff_dxva2_hevc_fill_picture_paramete
const HEVCPPS *pps = h->pps;
const HEVCSPS *sps = pps->sps;
int i, j;
+ DXVA_PicParams_HEVC *pp = &ppext->main;
@@ -210,16 +211,16 @@ Index: FFmpeg/libavcodec/dxva2_hevc.c
pp->PicWidthInMinCbsY = sps->min_cb_width;
pp->PicHeightInMinCbsY = sps->min_cb_height;
+ if (sps->sps_range_extension_flag) {
+ ppext->dwRangeExtensionFlags |= (sps->transform_skip_rotation_enabled_flag << 0) |
+ (sps->transform_skip_context_enabled_flag << 1) |
+ (sps->implicit_rdpcm_enabled_flag << 2) |
+ (sps->explicit_rdpcm_enabled_flag << 3) |
+ (sps->extended_precision_processing_flag << 4) |
+ (sps->intra_smoothing_disabled_flag << 5) |
+ (sps->high_precision_offsets_enabled_flag << 5) |
+ (sps->persistent_rice_adaptation_enabled_flag << 7) |
+ (sps->cabac_bypass_alignment_enabled_flag << 8);
+ if (sps->range_extension) {
+ ppext->dwRangeExtensionFlags |= (sps->transform_skip_rotation_enabled << 0) |
+ (sps->transform_skip_context_enabled << 1) |
+ (sps->implicit_rdpcm_enabled << 2) |
+ (sps->explicit_rdpcm_enabled << 3) |
+ (sps->extended_precision_processing << 4) |
+ (sps->intra_smoothing_disabled << 5) |
+ (sps->high_precision_offsets_enabled << 6) |
+ (sps->persistent_rice_adaptation_enabled << 7) |
+ (sps->cabac_bypass_alignment_enabled << 8);
+ }
+ if (pps->pps_range_extensions_flag) {
+ ppext->dwRangeExtensionFlags |= (pps->cross_component_prediction_enabled_flag << 9) |
@@ -240,12 +241,12 @@ Index: FFmpeg/libavcodec/dxva2_hevc.c
+ }
+
pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc << 0) |
(sps->separate_colour_plane_flag << 2) |
(sps->separate_colour_plane << 2) |
((sps->bit_depth - 8) << 3) |
@@ -409,14 +439,15 @@ static int dxva2_hevc_end_frame(AVCodecC
@@ -413,14 +443,15 @@ static int dxva2_hevc_end_frame(AVCodecC
{
HEVCContext *h = avctx->priv_data;
struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
struct hevc_dxva2_picture_context *ctx_pic = h->cur_frame->hwaccel_picture_private;
- int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
+ int scale = ctx_pic->pp.main.dwCodingParamToolFlags & 1;
+ int rext = avctx->profile == AV_PROFILE_HEVC_REXT;
@@ -254,7 +255,7 @@ Index: FFmpeg/libavcodec/dxva2_hevc.c
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
return -1;
ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
ret = ff_dxva2_common_end_frame(avctx, h->cur_frame->f,
- &ctx_pic->pp, sizeof(ctx_pic->pp),
+ &ctx_pic->pp, rext ? sizeof(ctx_pic->pp) : sizeof(ctx_pic->pp.main),
scale ? &ctx_pic->qm : NULL, scale ? sizeof(ctx_pic->qm) : 0,
@@ -334,11 +335,11 @@ Index: FFmpeg/libavcodec/dxva2_internal.h
void ff_dxva2_hevc_fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext *ctx, DXVA_Qmatrix_HEVC *qm);
Index: FFmpeg/libavcodec/hevcdec.c
Index: FFmpeg/libavcodec/hevc/hevcdec.c
===================================================================
--- FFmpeg.orig/libavcodec/hevcdec.c
+++ FFmpeg/libavcodec/hevcdec.c
@@ -465,6 +465,13 @@ static enum AVPixelFormat get_format(HEV
--- FFmpeg.orig/libavcodec/hevc/hevcdec.c
+++ FFmpeg/libavcodec/hevc/hevcdec.c
@@ -592,6 +592,13 @@ static enum AVPixelFormat get_format(HEV
#endif
break;
case AV_PIX_FMT_YUV444P:
@@ -352,7 +353,7 @@ Index: FFmpeg/libavcodec/hevcdec.c
#if CONFIG_HEVC_VAAPI_HWACCEL
*fmt++ = AV_PIX_FMT_VAAPI;
#endif
@@ -483,6 +490,13 @@ static enum AVPixelFormat get_format(HEV
@@ -610,6 +617,13 @@ static enum AVPixelFormat get_format(HEV
break;
case AV_PIX_FMT_YUV422P:
case AV_PIX_FMT_YUV422P10LE:
@@ -366,7 +367,7 @@ Index: FFmpeg/libavcodec/hevcdec.c
#if CONFIG_HEVC_VAAPI_HWACCEL
*fmt++ = AV_PIX_FMT_VAAPI;
#endif
@@ -500,6 +514,13 @@ static enum AVPixelFormat get_format(HEV
@@ -627,6 +641,13 @@ static enum AVPixelFormat get_format(HEV
/* NOTE: fallthrough */
case AV_PIX_FMT_YUV420P12:
case AV_PIX_FMT_YUV444P12:
@@ -380,7 +381,7 @@ Index: FFmpeg/libavcodec/hevcdec.c
#if CONFIG_HEVC_VAAPI_HWACCEL
*fmt++ = AV_PIX_FMT_VAAPI;
#endif
@@ -514,6 +535,13 @@ static enum AVPixelFormat get_format(HEV
@@ -641,6 +662,13 @@ static enum AVPixelFormat get_format(HEV
#endif
break;
case AV_PIX_FMT_YUV422P12:
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/qsv.c
===================================================================
--- FFmpeg.orig/libavcodec/qsv.c
+++ FFmpeg/libavcodec/qsv.c
@@ -406,9 +406,17 @@ static int qsv_load_plugins(mfxSession s
@@ -409,9 +409,17 @@ static int qsv_load_plugins(mfxSession s
void *logctx)
{
#if QSV_HAVE_USER_PLUGIN
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/qsvenc_av1.c
===================================================================
--- FFmpeg.orig/libavcodec/qsvenc_av1.c
+++ FFmpeg/libavcodec/qsvenc_av1.c
@@ -203,8 +203,8 @@ static const AVClass class = {
@@ -201,8 +201,8 @@ static const AVClass class = {
static const FFCodecDefault qsv_enc_defaults[] = {
{ "b", "0" },
@@ -32,7 +32,7 @@ Index: FFmpeg/libavcodec/qsvenc_hevc.c
===================================================================
--- FFmpeg.orig/libavcodec/qsvenc_hevc.c
+++ FFmpeg/libavcodec/qsvenc_hevc.c
@@ -379,8 +379,8 @@ static const AVClass class = {
@@ -381,8 +381,8 @@ static const AVClass class = {
static const FFCodecDefault qsv_enc_defaults[] = {
{ "b", "0" },
{ "refs", "0" },
@@ -2,7 +2,15 @@ Index: FFmpeg/libavcodec/vaapi_encode_h265.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode_h265.c
+++ FFmpeg/libavcodec/vaapi_encode_h265.c
@@ -691,7 +691,25 @@ static int vaapi_encode_h265_init_sequen
@@ -264,6 +264,7 @@ static int vaapi_encode_h265_init_sequen
H265RawVPS *vps = &priv->units.raw_vps;
H265RawSPS *sps = &priv->units.raw_sps;
H265RawPPS *pps = &priv->units.raw_pps;
+ H265RawVUI *vui = &sps->vui;
VAEncSequenceParameterBufferHEVC *vseq = ctx->codec_sequence_params;
VAEncPictureParameterBufferHEVC *vpic = ctx->codec_picture_params;
int i, err;
@@ -391,7 +392,25 @@ static int vaapi_encode_h265_init_sequen
sps->log2_min_pcm_luma_coding_block_size_minus3 +
sps->log2_diff_max_min_pcm_luma_coding_block_size,
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/dxva2.c
===================================================================
--- FFmpeg.orig/libavcodec/dxva2.c
+++ FFmpeg/libavcodec/dxva2.c
@@ -714,8 +714,10 @@ int ff_dxva2_common_frame_params(AVCodec
@@ -715,8 +715,10 @@ int ff_dxva2_common_frame_params(AVCodec
#if CONFIG_D3D11VA
if (frames_ctx->format == AV_PIX_FMT_D3D11) {
AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
@@ -17,7 +17,7 @@ Index: FFmpeg/libavfilter/qsvvpp.c
===================================================================
--- FFmpeg.orig/libavfilter/qsvvpp.c
+++ FFmpeg/libavfilter/qsvvpp.c
@@ -641,6 +641,9 @@ static int init_vpp_session(AVFilterCont
@@ -657,6 +657,9 @@ static int init_vpp_session(AVFilterCont
out_frames_hwctx->frame_type = s->out_mem_mode;
@@ -2,7 +2,7 @@ Index: FFmpeg/libavformat/movenc.c
===================================================================
--- FFmpeg.orig/libavformat/movenc.c
+++ FFmpeg/libavformat/movenc.c
@@ -2908,7 +2908,7 @@ static int mov_write_stbl_tag(AVFormatCo
@@ -3202,7 +3202,7 @@ static int mov_write_stbl_tag(AVFormatCo
track->par->codec_tag == MKTAG('r','t','p',' ')) &&
track->has_keyframes && track->has_keyframes < track->entry)
mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/vf_scale_vt.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_scale_vt.c
+++ FFmpeg/libavfilter/vf_scale_vt.c
@@ -40,11 +40,26 @@ typedef struct ScaleVtContext {
@@ -41,11 +41,26 @@ typedef struct ScaleVtContext {
enum AVColorPrimaries colour_primaries;
enum AVColorTransferCharacteristic colour_transfer;
enum AVColorSpace colour_matrix;
@@ -29,17 +29,17 @@ Index: FFmpeg/libavfilter/vf_scale_vt.c
static av_cold int scale_vt_init(AVFilterContext *avctx)
{
ScaleVtContext *s = avctx->priv;
@@ -179,6 +194,7 @@ static int scale_vt_config_output(AVFilt
AVFilterLink *inlink = outlink->src->inputs[0];
@@ -182,6 +197,7 @@ static int scale_vt_config_output(AVFilt
FilterLink *inl = ff_filter_link(inlink);
AVHWFramesContext *hw_frame_ctx_in;
AVHWFramesContext *hw_frame_ctx_out;
+ enum AVPixelFormat out_format;
err = ff_scale_eval_dimensions(s, s->w_expr, s->h_expr, inlink, outlink,
&s->output_width,
@@ -198,13 +214,21 @@ static int scale_vt_config_output(AVFilt
@@ -201,11 +217,18 @@ static int scale_vt_config_output(AVFilt
hw_frame_ctx_in = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
hw_frame_ctx_in = (AVHWFramesContext *)inl->hw_frames_ctx->data;
+ out_format = (s->format == AV_PIX_FMT_NONE) ? hw_frame_ctx_in->sw_format : s->format;
+ if (!format_is_supported(s->format)) {
@@ -48,19 +48,16 @@ Index: FFmpeg/libavfilter/vf_scale_vt.c
+ return AVERROR(ENOSYS);
+ }
+
av_buffer_unref(&outlink->hw_frames_ctx);
outlink->hw_frames_ctx = av_hwframe_ctx_alloc(hw_frame_ctx_in->device_ref);
hw_frame_ctx_out = (AVHWFramesContext *)outlink->hw_frames_ctx->data;
av_buffer_unref(&outl->hw_frames_ctx);
outl->hw_frames_ctx = av_hwframe_ctx_alloc(hw_frame_ctx_in->device_ref);
hw_frame_ctx_out = (AVHWFramesContext *)outl->hw_frames_ctx->data;
hw_frame_ctx_out->format = AV_PIX_FMT_VIDEOTOOLBOX;
- hw_frame_ctx_out->sw_format = hw_frame_ctx_in->sw_format;
+ hw_frame_ctx_out->sw_format = out_format;
hw_frame_ctx_out->width = outlink->w;
hw_frame_ctx_out->height = outlink->h;
+ ((AVVTFramesContext *)hw_frame_ctx_out->hwctx)->color_range = ((AVVTFramesContext *)hw_frame_ctx_in->hwctx)->color_range;
err = ff_filter_init_hw_frames(avctx, outlink, 1);
if (err < 0)
@@ -234,6 +258,8 @@ static const AVOption scale_vt_options[]
((AVVTFramesContext *)hw_frame_ctx_out->hwctx)->color_range = ((AVVTFramesContext *)hw_frame_ctx_in->hwctx)->color_range;
@@ -238,6 +261,8 @@ static const AVOption scale_vt_options[]
OFFSET(colour_primaries_string), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
{ "color_transfer", "Output colour transfer characteristics",
OFFSET(colour_transfer_string), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3883,6 +3883,7 @@ overlay_opencl_filter_deps="opencl"
@@ -3928,6 +3928,7 @@ overlay_opencl_filter_deps="opencl"
overlay_qsv_filter_deps="libmfx"
overlay_qsv_filter_select="qsvvpp"
overlay_vaapi_filter_deps="vaapi VAProcPipelineCaps_blend_flags"
@@ -14,7 +14,7 @@ Index: FFmpeg/doc/filters.texi
===================================================================
--- FFmpeg.orig/doc/filters.texi
+++ FFmpeg/doc/filters.texi
@@ -19047,6 +19047,58 @@ See @ref{framesync}.
@@ -19050,6 +19050,58 @@ See @ref{framesync}.
This filter also supports the @ref{framesync} options.
@@ -77,7 +77,7 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -414,6 +414,9 @@ OBJS-$(CONFIG_OVERLAY_OPENCL_FILTER)
@@ -416,6 +416,9 @@ OBJS-$(CONFIG_OVERLAY_OPENCL_FILTER)
opencl/overlay.o framesync.o
OBJS-$(CONFIG_OVERLAY_QSV_FILTER) += vf_overlay_qsv.o framesync.o
OBJS-$(CONFIG_OVERLAY_VAAPI_FILTER) += vf_overlay_vaapi.o framesync.o vaapi_vpp.o
@@ -91,7 +91,7 @@ Index: FFmpeg/libavfilter/allfilters.c
===================================================================
--- FFmpeg.orig/libavfilter/allfilters.c
+++ FFmpeg/libavfilter/allfilters.c
@@ -388,6 +388,7 @@ extern const AVFilter ff_vf_overlay;
@@ -389,6 +389,7 @@ extern const AVFilter ff_vf_overlay;
extern const AVFilter ff_vf_overlay_opencl;
extern const AVFilter ff_vf_overlay_qsv;
extern const AVFilter ff_vf_overlay_vaapi;
@@ -232,7 +232,7 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_overlay_videotoolbox.m
@@ -0,0 +1,751 @@
@@ -0,0 +1,758 @@
+/*
+ * Copyright (C) 2024 Gnattu OC <gnattuoc@me.com>
+ *
@@ -255,7 +255,7 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
+
+#include <CoreImage/CoreImage.h>
+#include <VideoToolbox/VideoToolbox.h>
+#include "internal.h"
+#include "filters.h"
+#include "metal/utils.h"
+#include "framesync.h"
+#include "libavutil/hwcontext.h"
@@ -430,10 +430,12 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
+ AVFilterLink *outlink = avctx->outputs[0];
+ AVFilterLink *inlink_main = avctx->inputs[0];
+ AVFilterLink *inlink_overlay = avctx->inputs[1];
+ FilterLink *inl_main = ff_filter_link(inlink_main);
+ FilterLink *inl_overlay = ff_filter_link(inlink_overlay);
+ AVFrame *input_main, *input_overlay;
+ AVFrame *output;
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inlink_main->hw_frames_ctx->data;
+ AVHWFramesContext *frames_ctx_overlay = (AVHWFramesContext*)inlink_overlay->hw_frames_ctx->data;
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inl_main->hw_frames_ctx->data;
+ AVHWFramesContext *frames_ctx_overlay = (AVHWFramesContext*)inl_overlay->hw_frames_ctx->data;
+ const AVPixFmtDescriptor *in_overlay_desc;
+
+ CVMetalTextureRef main, dst, overlay;
@@ -571,10 +573,12 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
+ AVFilterLink *outlink = avctx->outputs[0];
+ AVFilterLink *inlink_main = avctx->inputs[0];
+ AVFilterLink *inlink_overlay = avctx->inputs[1];
+ FilterLink *inl_main = ff_filter_link(inlink_main);
+ FilterLink *inl_overlay = ff_filter_link(inlink_overlay);
+ AVFrame *input_main, *input_overlay;
+ AVFrame *output;
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inlink_main->hw_frames_ctx->data;
+ AVHWFramesContext *frames_ctx_overlay = (AVHWFramesContext*)inlink_overlay->hw_frames_ctx->data;
+ AVHWFramesContext *frames_ctx = (AVHWFramesContext*)inl_main->hw_frames_ctx->data;
+ AVHWFramesContext *frames_ctx_overlay = (AVHWFramesContext*)inl_overlay->hw_frames_ctx->data;
+ const AVPixFmtDescriptor *in_main_desc;
+
+ CVMetalTextureRef main_y, main_uv, dst_y, dst_uv, overlay;
@@ -802,23 +806,26 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
+
+static int do_config_output(AVFilterLink *link) API_AVAILABLE(macos(10.11), ios(9.0))
+{
+ FilterLink *outl = ff_filter_link(link);
+ AVFilterContext *avctx = link->src;
+ AVFilterLink *inlink_main = avctx->inputs[0];
+ AVFilterLink *inlink_overlay = avctx->inputs[1];
+ FilterLink *inl_main = ff_filter_link(inlink_main);
+ FilterLink *inl_overlay = ff_filter_link(inlink_overlay);
+ OverlayVideoToolboxContext *ctx = avctx->priv;
+ AVHWFramesContext *main_frames, *output_frames, *overlay_frames;
+ AVBufferRef *input_ref, *overlay_ref;
+ int ret = 0;
+
+ if (!inlink_main->hw_frames_ctx ||
+ !inlink_overlay->hw_frames_ctx) {
+ if (!inl_main->hw_frames_ctx ||
+ !inl_overlay->hw_frames_ctx) {
+ av_log(avctx, AV_LOG_ERROR, "An input HW frames reference is "
+ "required to associate the processing device.\n");
+ return AVERROR(EINVAL);
+ }
+
+ input_ref = inlink_main->hw_frames_ctx;
+ overlay_ref = inlink_overlay->hw_frames_ctx;
+ input_ref = inl_main->hw_frames_ctx;
+ overlay_ref = inl_overlay->hw_frames_ctx;
+ main_frames = (AVHWFramesContext*)input_ref->data;
+ overlay_frames = (AVHWFramesContext*)overlay_ref->data;
+ av_assert0(main_frames);
@@ -874,8 +881,8 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
+ return AVERROR(ENOMEM);
+ }
+
+ link->hw_frames_ctx = av_hwframe_ctx_alloc(ctx->device_ref);
+ if (!link->hw_frames_ctx) {
+ outl->hw_frames_ctx = av_hwframe_ctx_alloc(ctx->device_ref);
+ if (!outl->hw_frames_ctx) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create HW frame context "
+ "for output.\n");
+ ret = AVERROR(ENOMEM);
@@ -883,7 +890,7 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
+ }
+ ctx->hwframe_ctx_allocated = 1;
+
+ output_frames = (AVHWFramesContext*)link->hw_frames_ctx->data;
+ output_frames = (AVHWFramesContext*)outl->hw_frames_ctx->data;
+
+ output_frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
+ output_frames->sw_format = main_frames->sw_format;
@@ -895,7 +902,7 @@ Index: FFmpeg/libavfilter/vf_overlay_videotoolbox.m
+ if (ret < 0)
+ return ret;
+
+ ret = av_hwframe_ctx_init(link->hw_frames_ctx);
+ ret = av_hwframe_ctx_init(outl->hw_frames_ctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to initialise VideoToolbox frame "
+ "context for output: %d\n", ret);
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3934,7 +3934,7 @@ tonemap_vaapi_filter_deps="vaapi VAProcF
@@ -3979,7 +3979,7 @@ tonemap_vaapi_filter_deps="vaapi VAProcF
tonemap_opencl_filter_deps="opencl const_nan"
transpose_opencl_filter_deps="opencl"
transpose_vaapi_filter_deps="vaapi VAProcPipelineCaps_rotation_flags"
@@ -15,7 +15,7 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_transpose_vt.c
+++ /dev/null
@@ -1,285 +0,0 @@
@@ -1,291 +0,0 @@
-/*
- * Copyright (c) 2023 Zhao Zhili <zhilizhao@tencent.com>
- *
@@ -42,7 +42,8 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.c
-#include "libavutil/hwcontext_videotoolbox.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-#include "internal.h"
-
-#include "filters.h"
-#include "transpose.h"
-#include "video.h"
-
@@ -123,27 +124,30 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.c
-
-static int transpose_vt_recreate_hw_ctx(AVFilterLink *outlink)
-{
- FilterLink *outl = ff_filter_link(outlink);
- AVFilterContext *avctx = outlink->src;
- AVFilterLink *inlink = outlink->src->inputs[0];
- FilterLink *inl = ff_filter_link(inlink);
- AVHWFramesContext *hw_frame_ctx_in;
- AVHWFramesContext *hw_frame_ctx_out;
- int err;
-
- av_buffer_unref(&outlink->hw_frames_ctx);
- av_buffer_unref(&outl->hw_frames_ctx);
-
- hw_frame_ctx_in = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
- outlink->hw_frames_ctx = av_hwframe_ctx_alloc(hw_frame_ctx_in->device_ref);
- hw_frame_ctx_out = (AVHWFramesContext *)outlink->hw_frames_ctx->data;
- hw_frame_ctx_in = (AVHWFramesContext *)inl->hw_frames_ctx->data;
- outl->hw_frames_ctx = av_hwframe_ctx_alloc(hw_frame_ctx_in->device_ref);
- hw_frame_ctx_out = (AVHWFramesContext *)outl->hw_frames_ctx->data;
- hw_frame_ctx_out->format = AV_PIX_FMT_VIDEOTOOLBOX;
- hw_frame_ctx_out->sw_format = hw_frame_ctx_in->sw_format;
- hw_frame_ctx_out->width = outlink->w;
- hw_frame_ctx_out->height = outlink->h;
- ((AVVTFramesContext *)hw_frame_ctx_out->hwctx)->color_range = ((AVVTFramesContext *)hw_frame_ctx_in->hwctx)->color_range;
-
- err = ff_filter_init_hw_frames(avctx, outlink, 1);
- if (err < 0)
- return err;
-
- err = av_hwframe_ctx_init(outlink->hw_frames_ctx);
- err = av_hwframe_ctx_init(outl->hw_frames_ctx);
- if (err < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "Failed to init videotoolbox frame context, %s\n",
@@ -157,16 +161,18 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.c
-static int transpose_vt_config_output(AVFilterLink *outlink)
-{
- int err;
- FilterLink *outl = ff_filter_link(outlink);
- AVFilterContext *avctx = outlink->src;
- TransposeVtContext *s = avctx->priv;
- AVFilterLink *inlink = outlink->src->inputs[0];
- FilterLink *inl = ff_filter_link(inlink);
- CFStringRef rotation = kVTRotation_0;
- CFBooleanRef vflip = kCFBooleanFalse;
- CFBooleanRef hflip = kCFBooleanFalse;
- int swap_w_h = 0;
-
- av_buffer_unref(&outlink->hw_frames_ctx);
- outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
- av_buffer_unref(&outl->hw_frames_ctx);
- outl->hw_frames_ctx = av_buffer_ref(inl->hw_frames_ctx);
-
- if ((inlink->w >= inlink->h && s->passthrough == TRANSPOSE_PT_TYPE_LANDSCAPE) ||
- (inlink->w <= inlink->h && s->passthrough == TRANSPOSE_PT_TYPE_PORTRAIT)) {
@@ -305,7 +311,7 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.m
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_transpose_vt.m
@@ -0,0 +1,379 @@
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2023 Zhao Zhili <zhilizhao@tencent.com>
+ * Copyright (c) 2024 Gnattu OC <gnattuoc@me.com>
@@ -334,7 +340,7 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.m
+#include "libavutil/hwcontext_videotoolbox.h"
+#include "libavutil/opt.h"
+#include "libavutil/objc.h"
+#include "internal.h"
+#include "filters.h"
+#include "transpose.h"
+#include "video.h"
+
@@ -468,17 +474,19 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.m
+
+static int transpose_vt_recreate_hw_ctx(AVFilterLink *outlink)
+{
+ FilterLink *outl = ff_filter_link(outlink);
+ AVFilterContext *avctx = outlink->src;
+ AVFilterLink *inlink = outlink->src->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ AVHWFramesContext *hw_frame_ctx_in;
+ AVHWFramesContext *hw_frame_ctx_out;
+ int err;
+
+ av_buffer_unref(&outlink->hw_frames_ctx);
+ av_buffer_unref(&outl->hw_frames_ctx);
+
+ hw_frame_ctx_in = (AVHWFramesContext *)inlink->hw_frames_ctx->data;
+ outlink->hw_frames_ctx = av_hwframe_ctx_alloc(hw_frame_ctx_in->device_ref);
+ hw_frame_ctx_out = (AVHWFramesContext *)outlink->hw_frames_ctx->data;
+ hw_frame_ctx_in = (AVHWFramesContext *)inl->hw_frames_ctx->data;
+ outl->hw_frames_ctx = av_hwframe_ctx_alloc(hw_frame_ctx_in->device_ref);
+ hw_frame_ctx_out = (AVHWFramesContext *)outl->hw_frames_ctx->data;
+ hw_frame_ctx_out->format = AV_PIX_FMT_VIDEOTOOLBOX;
+ hw_frame_ctx_out->sw_format = hw_frame_ctx_in->sw_format;
+ hw_frame_ctx_out->width = outlink->w;
@@ -489,7 +497,7 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.m
+ if (err < 0)
+ return err;
+
+ err = av_hwframe_ctx_init(outlink->hw_frames_ctx);
+ err = av_hwframe_ctx_init(outl->hw_frames_ctx);
+ if (err < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to init videotoolbox frame context, %s\n",
@@ -503,13 +511,15 @@ Index: FFmpeg/libavfilter/vf_transpose_vt.m
+static int transpose_vt_config_output(AVFilterLink *outlink)
+{
+ int err;
+ FilterLink *outl = ff_filter_link(outlink);
+ AVFilterContext *avctx = outlink->src;
+ TransposeVtContext *s = avctx->priv;
+ AVFilterLink *inlink = outlink->src->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ int swap_w_h = 0;
+
+ av_buffer_unref(&outlink->hw_frames_ctx);
+ outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
+ av_buffer_unref(&outl->hw_frames_ctx);
+ outl->hw_frames_ctx = av_buffer_ref(inl->hw_frames_ctx);
+
+ if ((inlink->w >= inlink->h && s->passthrough == TRANSPOSE_PT_TYPE_LANDSCAPE) ||
+ (inlink->w <= inlink->h && s->passthrough == TRANSPOSE_PT_TYPE_PORTRAIT)) {
@@ -1,568 +0,0 @@
Index: FFmpeg/libavcodec/videotoolboxenc.c
===================================================================
--- FFmpeg.orig/libavcodec/videotoolboxenc.c
+++ FFmpeg/libavcodec/videotoolboxenc.c
@@ -226,9 +226,9 @@ typedef struct ExtraSEI {
typedef struct BufNode {
CMSampleBufferRef cm_buffer;
- ExtraSEI *sei;
+ ExtraSEI sei;
+ AVBufferRef *frame_buf;
struct BufNode* next;
- int error;
} BufNode;
typedef struct VTEncContext {
@@ -261,7 +261,7 @@ typedef struct VTEncContext {
int realtime;
int frames_before;
int frames_after;
- bool constant_bit_rate;
+ int constant_bit_rate;
int allow_sw;
int require_sw;
@@ -280,6 +280,18 @@ typedef struct VTEncContext {
int max_ref_frames;
} VTEncContext;
+static void vtenc_free_buf_node(BufNode *info)
+{
+ if (!info)
+ return;
+
+ av_free(info->sei.data);
+ if (info->cm_buffer)
+ CFRelease(info->cm_buffer);
+ av_buffer_unref(&info->frame_buf);
+ av_free(info);
+}
+
static int vt_dump_encoder(AVCodecContext *avctx)
{
VTEncContext *vtctx = avctx->priv_data;
@@ -347,8 +359,7 @@ static void set_async_error(VTEncContext
while (info) {
BufNode *next = info->next;
- CFRelease(info->cm_buffer);
- av_free(info);
+ vtenc_free_buf_node(info);
info = next;
}
@@ -388,7 +399,7 @@ static void vtenc_reset(VTEncContext *vt
}
}
-static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, ExtraSEI **sei)
+static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, ExtraSEI *sei)
{
BufNode *info;
@@ -426,31 +437,18 @@ static int vtenc_q_pop(VTEncContext *vtc
pthread_mutex_unlock(&vtctx->lock);
*buf = info->cm_buffer;
+ info->cm_buffer = NULL;
if (sei && *buf) {
*sei = info->sei;
- } else if (info->sei) {
- if (info->sei->data) av_free(info->sei->data);
- av_free(info->sei);
+ info->sei = (ExtraSEI) {0};
}
- av_free(info);
-
+ vtenc_free_buf_node(info);
return 0;
}
-static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer, ExtraSEI *sei)
+static void vtenc_q_push(VTEncContext *vtctx, BufNode *info)
{
- BufNode *info = av_malloc(sizeof(BufNode));
- if (!info) {
- set_async_error(vtctx, AVERROR(ENOMEM));
- return;
- }
-
- CFRetain(buffer);
- info->cm_buffer = buffer;
- info->sei = sei;
- info->next = NULL;
-
pthread_mutex_lock(&vtctx->lock);
if (!vtctx->q_head) {
@@ -735,13 +733,16 @@ static void vtenc_output_callback(
{
AVCodecContext *avctx = ctx;
VTEncContext *vtctx = avctx->priv_data;
- ExtraSEI *sei = sourceFrameCtx;
+ BufNode *info = sourceFrameCtx;
+ av_buffer_unref(&info->frame_buf);
if (vtctx->async_error) {
+ vtenc_free_buf_node(info);
return;
}
if (status) {
+ vtenc_free_buf_node(info);
av_log(avctx, AV_LOG_ERROR, "Error encoding frame: %d\n", (int)status);
set_async_error(vtctx, AVERROR_EXTERNAL);
return;
@@ -751,15 +752,19 @@ static void vtenc_output_callback(
return;
}
+ CFRetain(sample_buffer);
+ info->cm_buffer = sample_buffer;
+
if (!avctx->extradata && (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
int set_status = set_extradata(avctx, sample_buffer);
if (set_status) {
+ vtenc_free_buf_node(info);
set_async_error(vtctx, set_status);
return;
}
}
- vtenc_q_push(vtctx, sample_buffer, sei);
+ vtenc_q_push(vtctx, info);
}
static int get_length_code_size(
@@ -2449,7 +2454,8 @@ static int copy_avframe_to_pixel_buffer(
static int create_cv_pixel_buffer(AVCodecContext *avctx,
const AVFrame *frame,
- CVPixelBufferRef *cv_img)
+ CVPixelBufferRef *cv_img,
+ BufNode *node)
{
int plane_count;
int color;
@@ -2468,6 +2474,12 @@ static int create_cv_pixel_buffer(AVCode
av_assert0(*cv_img);
CFRetain(*cv_img);
+ if (frame->buf[0]) {
+ node->frame_buf = av_buffer_ref(frame->buf[0]);
+ if (!node->frame_buf)
+ return AVERROR(ENOMEM);
+ }
+
return 0;
}
@@ -2565,33 +2577,29 @@ static int vtenc_send_frame(AVCodecConte
const AVFrame *frame)
{
CMTime time;
- CFDictionaryRef frame_dict;
+ CFDictionaryRef frame_dict = NULL;
CVPixelBufferRef cv_img = NULL;
AVFrameSideData *side_data = NULL;
- ExtraSEI *sei = NULL;
- int status = create_cv_pixel_buffer(avctx, frame, &cv_img);
+ BufNode *node = av_mallocz(sizeof(*node));
+ int status;
- if (status) return status;
+ if (!node)
+ return AVERROR(ENOMEM);
+
+ status = create_cv_pixel_buffer(avctx, frame, &cv_img, node);
+ if (status)
+ goto out;
status = create_encoder_dict_h264(frame, &frame_dict);
- if (status) {
- CFRelease(cv_img);
- return status;
- }
+ if (status)
+ goto out;
#if CONFIG_ATSC_A53
side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC);
if (vtctx->a53_cc && side_data && side_data->size) {
- sei = av_mallocz(sizeof(*sei));
- if (!sei) {
- av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
- } else {
- int ret = ff_alloc_a53_sei(frame, 0, &sei->data, &sei->size);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
- av_free(sei);
- sei = NULL;
- }
+ status = ff_alloc_a53_sei(frame, 0, &node->sei.data, &node->sei.size);
+ if (status < 0) {
+ goto out;
}
}
#endif
@@ -2603,19 +2611,26 @@ static int vtenc_send_frame(AVCodecConte
time,
kCMTimeInvalid,
frame_dict,
- sei,
+ node,
NULL
);
- if (frame_dict) CFRelease(frame_dict);
- CFRelease(cv_img);
-
if (status) {
av_log(avctx, AV_LOG_ERROR, "Error: cannot encode frame: %d\n", status);
- return AVERROR_EXTERNAL;
+ status = AVERROR_EXTERNAL;
+ // Not necessary, just in case new code put after here
+ goto out;
}
- return 0;
+out:
+ if (frame_dict)
+ CFRelease(frame_dict);
+ if (cv_img)
+ CFRelease(cv_img);
+ if (status)
+ vtenc_free_buf_node(node);
+
+ return status;
}
static av_cold int vtenc_frame(
@@ -2628,7 +2643,7 @@ static av_cold int vtenc_frame(
bool get_frame;
int status;
CMSampleBufferRef buf = NULL;
- ExtraSEI *sei = NULL;
+ ExtraSEI sei = {0};
if (frame) {
status = vtenc_send_frame(avctx, vtctx, frame);
@@ -2669,11 +2684,8 @@ static av_cold int vtenc_frame(
if (status) goto end_nopkt;
if (!buf) goto end_nopkt;
- status = vtenc_cm_to_avpacket(avctx, buf, pkt, sei);
- if (sei) {
- if (sei->data) av_free(sei->data);
- av_free(sei);
- }
+ status = vtenc_cm_to_avpacket(avctx, buf, pkt, sei.data ? &sei : NULL);
+ av_free(sei.data);
CFRelease(buf);
if (status) goto end_nopkt;
@@ -2698,6 +2710,10 @@ static int vtenc_populate_extradata(AVCo
CVPixelBufferRef pix_buf = NULL;
CMTime time;
CMSampleBufferRef buf = NULL;
+ BufNode *node = av_mallocz(sizeof(*node));
+
+ if (!node)
+ return AVERROR(ENOMEM);
status = vtenc_create_encoder(avctx,
codec_type,
@@ -2733,7 +2749,7 @@ static int vtenc_populate_extradata(AVCo
time,
kCMTimeInvalid,
NULL,
- NULL,
+ node,
NULL);
if (status) {
@@ -2744,6 +2760,7 @@ static int vtenc_populate_extradata(AVCo
status = AVERROR_EXTERNAL;
goto pe_cleanup;
}
+ node = NULL;
//Populates extradata - output frames are flushed and param sets are available.
status = VTCompressionSessionCompleteFrames(vtctx->session,
@@ -2766,10 +2783,26 @@ static int vtenc_populate_extradata(AVCo
pe_cleanup:
CVPixelBufferRelease(pix_buf);
- vtenc_reset(vtctx);
+
+ if (status) {
+ vtenc_reset(vtctx);
+ } else {
+ if (vtctx->session) {
+ CFRelease(vtctx->session);
+ vtctx->session = NULL;
+ }
+
+ if (vtctx->supported_props) {
+ CFRelease(vtctx->supported_props);
+ vtctx->supported_props = NULL;
+ }
+ }
+
vtctx->frame_ct_out = 0;
av_assert0(status != 0 || (avctx->extradata && avctx->extradata_size > 0));
+ if (!status)
+ vtenc_free_buf_node(node);
return status;
}
Index: FFmpeg/libavutil/hwcontext_videotoolbox.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_videotoolbox.c
+++ FFmpeg/libavutil/hwcontext_videotoolbox.c
@@ -342,8 +342,10 @@ static int vt_pixbuf_set_par(void *log_c
CFNumberRef num = NULL, den = NULL;
AVRational avpar = src->sample_aspect_ratio;
- if (avpar.num == 0)
+ if (avpar.num == 0) {
+ CVBufferRemoveAttachment(pixbuf, kCVImageBufferPixelAspectRatioKey);
return 0;
+ }
av_reduce(&avpar.num, &avpar.den,
avpar.num, avpar.den,
@@ -423,7 +425,10 @@ static int vt_pixbuf_set_chromaloc(void
kCVImageBufferChromaLocationTopFieldKey,
loc,
kCVAttachmentMode_ShouldPropagate);
- }
+ } else
+ CVBufferRemoveAttachment(
+ pixbuf,
+ kCVImageBufferChromaLocationTopFieldKey);
return 0;
}
@@ -527,59 +532,116 @@ CFStringRef av_map_videotoolbox_color_tr
}
}
+/**
+ * Copy all attachments for the specified mode from the given buffer.
+ */
+static CFDictionaryRef vt_cv_buffer_copy_attachments(CVBufferRef buffer,
+ CVAttachmentMode attachment_mode)
+{
+ CFDictionaryRef dict;
+
+ // Check that our SDK is at least macOS 12 / iOS 15 / tvOS 15
+ #if (TARGET_OS_OSX && defined(__MAC_12_0) && __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_12_0) || \
+ (TARGET_OS_IOS && defined(__IPHONE_15_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0) || \
+ (TARGET_OS_TV && defined(__TVOS_15_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_15_0)
+ // On recent enough versions, just use the respective API
+ if (__builtin_available(macOS 12.0, iOS 15.0, tvOS 15.0, *))
+ return CVBufferCopyAttachments(buffer, attachment_mode);
+ #endif
+
+ // Check that the target is lower than macOS 12 / iOS 15 / tvOS 15
+ // else this would generate a deprecation warning and anyway never run because
+ // the runtime availability check above would be always true.
+ #if (TARGET_OS_OSX && (!defined(__MAC_12_0) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_12_0)) || \
+ (TARGET_OS_IOS && (!defined(__IPHONE_15_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_15_0)) || \
+ (TARGET_OS_TV && (!defined(__TVOS_15_0) || __TV_OS_VERSION_MIN_REQUIRED < __TVOS_15_0))
+ // Fallback on SDKs or runtime versions < macOS 12 / iOS 15 / tvOS 15
+ dict = CVBufferGetAttachments(buffer, attachment_mode);
+ return (dict) ? CFDictionaryCreateCopy(NULL, dict) : NULL;
+ #else
+ return NULL; // Impossible, just make the compiler happy
+ #endif
+}
+
static int vt_pixbuf_set_colorspace(void *log_ctx,
CVPixelBufferRef pixbuf, const AVFrame *src)
{
+ CGColorSpaceRef colorspace = NULL;
CFStringRef colormatrix = NULL, colorpri = NULL, colortrc = NULL;
Float32 gamma = 0;
colormatrix = av_map_videotoolbox_color_matrix_from_av(src->colorspace);
- if (!colormatrix && src->colorspace != AVCOL_SPC_UNSPECIFIED)
- av_log(log_ctx, AV_LOG_WARNING, "Color space %s is not supported.\n", av_color_space_name(src->colorspace));
+ if (colormatrix)
+ CVBufferSetAttachment(pixbuf, kCVImageBufferYCbCrMatrixKey,
+ colormatrix, kCVAttachmentMode_ShouldPropagate);
+ else {
+ CVBufferRemoveAttachment(pixbuf, kCVImageBufferYCbCrMatrixKey);
+ if (src->colorspace != AVCOL_SPC_UNSPECIFIED && src->colorspace != AVCOL_SPC_RGB)
+ av_log(log_ctx, AV_LOG_WARNING,
+ "Color space %s is not supported.\n",
+ av_color_space_name(src->colorspace));
+ }
colorpri = av_map_videotoolbox_color_primaries_from_av(src->color_primaries);
- if (!colorpri && src->color_primaries != AVCOL_PRI_UNSPECIFIED)
- av_log(log_ctx, AV_LOG_WARNING, "Color primaries %s is not supported.\n", av_color_primaries_name(src->color_primaries));
+ if (colorpri)
+ CVBufferSetAttachment(pixbuf, kCVImageBufferColorPrimariesKey,
+ colorpri, kCVAttachmentMode_ShouldPropagate);
+ else {
+ CVBufferRemoveAttachment(pixbuf, kCVImageBufferColorPrimariesKey);
+ if (src->color_primaries != AVCOL_SPC_UNSPECIFIED)
+ av_log(log_ctx, AV_LOG_WARNING,
+ "Color primaries %s is not supported.\n",
+ av_color_primaries_name(src->color_primaries));
+ }
colortrc = av_map_videotoolbox_color_trc_from_av(src->color_trc);
- if (!colortrc && src->color_trc != AVCOL_TRC_UNSPECIFIED)
- av_log(log_ctx, AV_LOG_WARNING, "Color transfer function %s is not supported.\n", av_color_transfer_name(src->color_trc));
+ if (colortrc)
+ CVBufferSetAttachment(pixbuf, kCVImageBufferTransferFunctionKey,
+ colortrc, kCVAttachmentMode_ShouldPropagate);
+ else {
+ CVBufferRemoveAttachment(pixbuf, kCVImageBufferTransferFunctionKey);
+ if (src->color_trc != AVCOL_TRC_UNSPECIFIED)
+ av_log(log_ctx, AV_LOG_WARNING,
+ "Color transfer function %s is not supported.\n",
+ av_color_transfer_name(src->color_trc));
+ }
if (src->color_trc == AVCOL_TRC_GAMMA22)
gamma = 2.2;
else if (src->color_trc == AVCOL_TRC_GAMMA28)
gamma = 2.8;
- if (colormatrix) {
- CVBufferSetAttachment(
- pixbuf,
- kCVImageBufferYCbCrMatrixKey,
- colormatrix,
- kCVAttachmentMode_ShouldPropagate);
- }
- if (colorpri) {
- CVBufferSetAttachment(
- pixbuf,
- kCVImageBufferColorPrimariesKey,
- colorpri,
- kCVAttachmentMode_ShouldPropagate);
- }
- if (colortrc) {
- CVBufferSetAttachment(
- pixbuf,
- kCVImageBufferTransferFunctionKey,
- colortrc,
- kCVAttachmentMode_ShouldPropagate);
- }
if (gamma != 0) {
CFNumberRef gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
- CVBufferSetAttachment(
- pixbuf,
- kCVImageBufferGammaLevelKey,
- gamma_level,
- kCVAttachmentMode_ShouldPropagate);
+ CVBufferSetAttachment(pixbuf, kCVImageBufferGammaLevelKey,
+ gamma_level, kCVAttachmentMode_ShouldPropagate);
CFRelease(gamma_level);
+ } else
+ CVBufferRemoveAttachment(pixbuf, kCVImageBufferGammaLevelKey);
+
+#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MAX_ALLOWED >= 100800) || \
+ (TARGET_OS_IOS && __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000)
+ if (__builtin_available(macOS 10.8, iOS 10, *)) {
+ CFDictionaryRef attachments =
+ vt_cv_buffer_copy_attachments(pixbuf, kCVAttachmentMode_ShouldPropagate);
+
+ if (attachments) {
+ colorspace =
+ CVImageBufferCreateColorSpaceFromAttachments(attachments);
+ CFRelease(attachments);
+ }
}
+#endif
+
+ // Done outside the above preprocessor code and if's so that
+ // in any case a wrong kCVImageBufferCGColorSpaceKey is removed
+ // if the above code is not used or fails.
+ if (colorspace) {
+ CVBufferSetAttachment(pixbuf, kCVImageBufferCGColorSpaceKey,
+ colorspace, kCVAttachmentMode_ShouldPropagate);
+ CFRelease(colorspace);
+ } else
+ CVBufferRemoveAttachment(pixbuf, kCVImageBufferCGColorSpaceKey);
return 0;
}
Index: FFmpeg/libavutil/hwcontext_videotoolbox.h
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_videotoolbox.h
+++ FFmpeg/libavutil/hwcontext_videotoolbox.h
@@ -90,8 +90,15 @@ CFStringRef av_map_videotoolbox_color_pr
CFStringRef av_map_videotoolbox_color_trc_from_av(enum AVColorTransferCharacteristic trc);
/**
- * Update a CVPixelBufferRef's metadata to based on an AVFrame.
- * Returns 0 if no known equivalent was found.
+ * Set CVPixelBufferRef's metadata based on an AVFrame.
+ *
+ * Sets/unsets the CVPixelBuffer attachments to match as closely as possible the
+ * AVFrame metadata. To prevent inconsistent attachments, the attachments for properties
+ * that could not be matched or are unspecified in the given AVFrame are unset. So if
+ * any attachments already covered by AVFrame metadata need to be set to a specific
+ * value, this should happen after calling this function.
+ *
+ * Returns < 0 in case of an error.
*/
int av_vt_pixbuf_set_attachments(void *log_ctx,
CVPixelBufferRef pixbuf, const struct AVFrame *src);
Index: FFmpeg/libavfilter/vf_yadif_videotoolbox.m
===================================================================
--- FFmpeg.orig/libavfilter/vf_yadif_videotoolbox.m
+++ FFmpeg/libavfilter/vf_yadif_videotoolbox.m
@@ -24,6 +24,7 @@
#include "yadif.h"
#include "libavutil/avassert.h"
#include "libavutil/hwcontext.h"
+#include "libavutil/hwcontext_videotoolbox.h"
#include "libavutil/objc.h"
#include <assert.h>
@@ -94,9 +95,6 @@ static void call_kernel(AVFilterContext
[buffer commit];
[buffer waitUntilCompleted];
-
- ff_objc_release(&encoder);
- ff_objc_release(&buffer);
}
static void filter(AVFilterContext *ctx, AVFrame *dst,
@@ -321,8 +319,9 @@ static int config_input(AVFilterLink *in
static int do_config_output(AVFilterLink *link) API_AVAILABLE(macos(10.11), ios(8.0))
{
- AVHWFramesContext *output_frames;
+ AVHWFramesContext *output_frames, *input_frames;
AVFilterContext *ctx = link->src;
+ AVFilterLink *inlink = link->src->inputs[0];
YADIFVTContext *s = ctx->priv;
YADIFContext *y = &s->yadif;
int ret = 0;
@@ -343,12 +342,14 @@ static int do_config_output(AVFilterLink
goto exit;
}
+ input_frames = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
output_frames = (AVHWFramesContext*)link->hw_frames_ctx->data;
output_frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
output_frames->sw_format = s->input_frames->sw_format;
output_frames->width = ctx->inputs[0]->w;
output_frames->height = ctx->inputs[0]->h;
+ ((AVVTFramesContext *)output_frames->hwctx)->color_range = ((AVVTFramesContext *)input_frames->hwctx)->color_range;
ret = ff_filter_init_hw_frames(ctx, link, 10);
if (ret < 0)
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3931,6 +3931,7 @@ tinterlace_merge_test_deps="tinterlace_f
@@ -3976,6 +3976,7 @@ tinterlace_merge_test_deps="tinterlace_f
tinterlace_pad_test_deps="tinterlace_filter"
tonemap_filter_deps="const_nan"
tonemap_vaapi_filter_deps="vaapi VAProcFilterParameterBufferHDRToneMapping"
@@ -14,7 +14,7 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -535,6 +535,9 @@ OBJS-$(CONFIG_TONEMAP_CUDA_FILTER)
@@ -537,6 +537,9 @@ OBJS-$(CONFIG_TONEMAP_CUDA_FILTER)
OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER) += vf_tonemap_opencl.o opencl.o \
opencl/tonemap.o opencl/colorspace_common.o
OBJS-$(CONFIG_TONEMAP_VAAPI_FILTER) += vf_tonemap_vaapi.o vaapi_vpp.o
@@ -28,7 +28,7 @@ Index: FFmpeg/libavfilter/allfilters.c
===================================================================
--- FFmpeg.orig/libavfilter/allfilters.c
+++ FFmpeg/libavfilter/allfilters.c
@@ -501,6 +501,7 @@ extern const AVFilter ff_vf_tonemap;
@@ -502,6 +502,7 @@ extern const AVFilter ff_vf_tonemap;
extern const AVFilter ff_vf_tonemap_cuda;
extern const AVFilter ff_vf_tonemap_opencl;
extern const AVFilter ff_vf_tonemap_vaapi;
@@ -966,7 +966,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
@@ -0,0 +1,1159 @@
@@ -0,0 +1,1209 @@
+/*
+ * Copyright (c) 2024 Gnattu OC <gnattuoc@me.com>
+ *
@@ -990,14 +990,15 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+#include <float.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavutil/objc.h"
+#include "libavutil/hwcontext.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "filters.h"
+#include "formats.h"
+#include "video.h"
+#include "colorspace.h"
+#include "dither_matrix.h"
@@ -1021,6 +1022,13 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ AV_PIX_FMT_P010,
+};
+
+static const int colorspaces_out[] = {
+ AVCOL_SPC_UNSPECIFIED,
+ AVCOL_SPC_BT709,
+ AVCOL_SPC_BT2020_NCL,
+ -1
+};
+
+enum TonemapAlgorithm {
+ TONEMAP_NONE,
+ TONEMAP_LINEAR,
@@ -1693,8 +1701,10 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+
+static int tonemap_videotoolbox_config_output(AVFilterLink *outlink)
+{
+ FilterLink *outl = ff_filter_link(outlink);
+ AVFilterContext *avctx = outlink->src;
+ AVFilterLink *inlink = avctx->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ TonemapVideoToolboxContext *ctx = avctx->priv;
+ AVHWFramesContext *in_frames_ctx, *out_frames_ctx;
+ enum AVPixelFormat in_format;
@@ -1703,9 +1713,9 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ const AVPixFmtDescriptor *out_desc;
+ int ret;
+
+ if (!inlink->hw_frames_ctx)
+ if (!inl->hw_frames_ctx)
+ return AVERROR(EINVAL);
+ in_frames_ctx = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ in_frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ in_format = in_frames_ctx->sw_format;
+ out_format = (ctx->format == AV_PIX_FMT_NONE) ? in_format : ctx->format;
+ in_desc = av_pix_fmt_desc_get(in_format);
@@ -1734,11 +1744,11 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ ctx->in_planes = av_pix_fmt_count_planes(in_format);
+ ctx->out_planes = av_pix_fmt_count_planes(out_format);
+
+ av_buffer_unref(&outlink->hw_frames_ctx);
+ outlink->hw_frames_ctx = av_hwframe_ctx_alloc(in_frames_ctx->device_ref);
+ av_buffer_unref(&outl->hw_frames_ctx);
+ outl->hw_frames_ctx = av_hwframe_ctx_alloc(in_frames_ctx->device_ref);
+ outlink->w = inlink->w;
+ outlink->h = inlink->h;
+ out_frames_ctx = (AVHWFramesContext *)outlink->hw_frames_ctx->data;
+ out_frames_ctx = (AVHWFramesContext *)outl->hw_frames_ctx->data;
+ out_frames_ctx->format = AV_PIX_FMT_VIDEOTOOLBOX;
+ out_frames_ctx->sw_format = out_format;
+ out_frames_ctx->width = outlink->w;
@@ -1754,7 +1764,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ if (ret < 0)
+ return ret;
+
+ ret = av_hwframe_ctx_init(outlink->hw_frames_ctx);
+ ret = av_hwframe_ctx_init(outl->hw_frames_ctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to init videotoolbox frame context, %s\n",
@@ -1881,7 +1891,7 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ output->colorspace = input->colorspace = AVCOL_SPC_BT2020_NCL;
+ output->color_primaries = input->color_primaries = AVCOL_PRI_BT2020;
+ if (rpu->bl_video_full_range_flag)
+ output->color_range = input->color_range = AVCOL_RANGE_JPEG;
+ input->color_range = AVCOL_RANGE_JPEG;
+ }
+ }
+
@@ -1889,10 +1899,9 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ output->color_trc = ctx->trc;
+ if (ctx->primaries != -1)
+ output->color_primaries = ctx->primaries;
+ if (ctx->colorspace != -1)
+ output->colorspace = ctx->colorspace;
+ if (ctx->range != -1)
+ output->color_range = ctx->range;
+
+ output->colorspace = outlink->colorspace;
+ output->color_range = outlink->color_range;
+
+ ctx->trc_in = input->color_trc;
+ ctx->trc_out = output->color_trc;
@@ -2050,6 +2059,47 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ return err;
+}
+
+static int tonemap_videotoolbox_query_formats(AVFilterContext *avctx)
+{
+ TonemapVideoToolboxContext *ctx = avctx->priv;
+ AVFilterFormats *formats;
+ int ret;
+ const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_VIDEOTOOLBOX, AV_PIX_FMT_NONE };
+
+ // single format
+ formats = ff_make_format_list(pix_fmts);
+ ret = ff_formats_ref(formats, &avctx->inputs[0]->outcfg.formats);
+ if (ret < 0)
+ return ret;
+
+ ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.formats);
+ if (ret < 0)
+ return ret;
+
+ // colorspaces and ranges
+ if ((ret = ff_formats_ref(ff_all_color_spaces(),
+ &avctx->inputs[0]->outcfg.color_spaces)) < 0)
+ return ret;
+
+ if ((ret = ff_formats_ref(ff_all_color_ranges(),
+ &avctx->inputs[0]->outcfg.color_ranges)) < 0)
+ return ret;
+
+ formats = ctx->colorspace != -1
+ ? ff_make_formats_list_singleton(ctx->colorspace)
+ : ff_make_format_list(colorspaces_out);
+ if ((ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.color_spaces)) < 0)
+ return ret;
+
+ formats = ctx->range != -1
+ ? ff_make_formats_list_singleton(ctx->range)
+ : ff_all_color_ranges();
+ if ((ret = ff_formats_ref(formats, &avctx->outputs[0]->incfg.color_ranges)) < 0)
+ return ret;
+
+ return 0;
+}
+
+#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
+#define OFFSET(x) offsetof(TonemapVideoToolboxContext, x)
+
@@ -2123,6 +2173,6 @@ Index: FFmpeg/libavfilter/vf_tonemap_videotoolbox.m
+ .uninit = tonemap_videotoolbox_uninit,
+ FILTER_INPUTS(tonemap_videotoolbox_inputs),
+ FILTER_OUTPUTS(tonemap_videotoolbox_outputs),
+ FILTER_SINGLE_PIXFMT(AV_PIX_FMT_VIDEOTOOLBOX),
+ FILTER_QUERY_FUNC(tonemap_videotoolbox_query_formats),
+ .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
+};
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3488,6 +3488,8 @@ h264_videotoolbox_encoder_deps="pthreads
@@ -3524,6 +3524,8 @@ h264_videotoolbox_encoder_deps="pthreads
h264_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder"
hevc_videotoolbox_encoder_deps="pthreads"
hevc_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder"
@@ -15,31 +15,31 @@ Index: FFmpeg/libavcodec/Makefile
===================================================================
--- FFmpeg.orig/libavcodec/Makefile
+++ FFmpeg/libavcodec/Makefile
@@ -508,6 +508,7 @@ OBJS-$(CONFIG_MJPEG_CUVID_DECODER) +
@@ -518,6 +518,7 @@ OBJS-$(CONFIG_MJPEGB_DECODER) +
OBJS-$(CONFIG_MJPEG_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_MJPEG_QSV_ENCODER) += qsvenc_jpeg.o
OBJS-$(CONFIG_MJPEG_RKMPP_ENCODER) += rkmppenc.o
OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o
+OBJS-$(CONFIG_MJPEG_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
OBJS-$(CONFIG_MJPEG_RKMPP_ENCODER) += rkmppenc.o
OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o
OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
Index: FFmpeg/libavcodec/allcodecs.c
===================================================================
--- FFmpeg.orig/libavcodec/allcodecs.c
+++ FFmpeg/libavcodec/allcodecs.c
@@ -876,6 +876,7 @@ extern const FFCodec ff_mjpeg_qsv_encode
@@ -875,6 +875,7 @@ extern const FFCodec ff_mjpeg_cuvid_deco
extern const FFCodec ff_mjpeg_qsv_encoder;
extern const FFCodec ff_mjpeg_qsv_decoder;
extern const FFCodec ff_mjpeg_rkmpp_encoder;
extern const FFCodec ff_mjpeg_vaapi_encoder;
+extern const FFCodec ff_mjpeg_videotoolbox_encoder;
extern const FFCodec ff_mjpeg_rkmpp_encoder;
extern const FFCodec ff_mp3_mediacodec_decoder;
extern const FFCodec ff_mp3_mf_encoder;
extern const FFCodec ff_mpeg1_cuvid_decoder;
extern const FFCodec ff_mpeg2_cuvid_decoder;
Index: FFmpeg/libavcodec/videotoolboxenc.c
===================================================================
--- FFmpeg.orig/libavcodec/videotoolboxenc.c
+++ FFmpeg/libavcodec/videotoolboxenc.c
@@ -545,6 +545,7 @@ static CMVideoCodecType get_cm_codec_typ
@@ -546,6 +546,7 @@ static CMVideoCodecType get_cm_codec_typ
else
return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422
}
@@ -47,7 +47,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
default: return 0;
}
}
@@ -1238,7 +1239,7 @@ static int vtenc_create_encoder(AVCodecC
@@ -1243,7 +1244,7 @@ static int vtenc_create_encoder(AVCodecC
kVTCompressionPropertyKey_Quality,
quality_num);
CFRelease(quality_num);
@@ -56,7 +56,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
kCFNumberSInt32Type,
&bit_rate);
@@ -1352,7 +1353,7 @@ static int vtenc_create_encoder(AVCodecC
@@ -1357,7 +1358,7 @@ static int vtenc_create_encoder(AVCodecC
}
}
@@ -65,7 +65,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
kCFNumberIntType,
&avctx->gop_size);
@@ -1501,7 +1502,7 @@ static int vtenc_create_encoder(AVCodecC
@@ -1506,7 +1507,7 @@ static int vtenc_create_encoder(AVCodecC
}
}
@@ -74,7 +74,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
status = VTSessionSetProperty(vtctx->session,
kVTCompressionPropertyKey_AllowFrameReordering,
kCFBooleanFalse);
@@ -2870,6 +2871,13 @@ static const enum AVPixelFormat prores_p
@@ -2875,6 +2876,13 @@ static const enum AVPixelFormat prores_p
AV_PIX_FMT_NONE
};
@@ -88,7 +88,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
#define COMMON_OPTIONS \
{ "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \
@@ -3039,4 +3047,35 @@ const FFCodec ff_prores_videotoolbox_enc
@@ -3046,4 +3054,36 @@ const FFCodec ff_prores_videotoolbox_enc
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.p.wrapper_name = "videotoolbox",
.hw_configs = vt_encode_hw_configs,
@@ -116,6 +116,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
+ .priv_data_size = sizeof(VTEncContext),
+ .p.pix_fmts = mjpeg_pix_fmts,
+ .defaults = vt_defaults,
+ .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
+ .init = vtenc_init,
+ FF_CODEC_ENCODE_CB(vtenc_frame),
+ .close = vtenc_close,
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/avcodec.h
===================================================================
--- FFmpeg.orig/libavcodec/avcodec.h
+++ FFmpeg/libavcodec/avcodec.h
@@ -2174,6 +2174,13 @@ typedef struct AVHWAccel {
@@ -2185,6 +2185,13 @@ typedef struct AVHWAccel {
#define AV_HWACCEL_FLAG_UNSAFE_OUTPUT (1 << 3)
/**
@@ -20,7 +20,7 @@ Index: FFmpeg/libavcodec/options_table.h
===================================================================
--- FFmpeg.orig/libavcodec/options_table.h
+++ FFmpeg/libavcodec/options_table.h
@@ -407,6 +407,7 @@ static const AVOption avcodec_options[]
@@ -412,6 +412,7 @@ static const AVOption avcodec_options[]
{"mastering_display_metadata", .default_val.i64 = AV_PKT_DATA_MASTERING_DISPLAY_METADATA, .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
{"content_light_level", .default_val.i64 = AV_PKT_DATA_CONTENT_LIGHT_LEVEL, .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
{"icc_profile", .default_val.i64 = AV_PKT_DATA_ICC_PROFILE, .type = AV_OPT_TYPE_CONST, .flags = A|D, .unit = "side_data_pkt" },
@@ -32,7 +32,7 @@ Index: FFmpeg/libavcodec/videotoolbox.c
===================================================================
--- FFmpeg.orig/libavcodec/videotoolbox.c
+++ FFmpeg/libavcodec/videotoolbox.c
@@ -984,6 +984,23 @@ static int videotoolbox_start(AVCodecCon
@@ -985,6 +985,23 @@ static int videotoolbox_start(AVCodecCon
av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox reported invalid data.\n");
return AVERROR_INVALIDDATA;
case 0:
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3297,6 +3297,8 @@ thumbnail_cuda_filter_deps="ffnvcodec"
@@ -3317,6 +3317,8 @@ thumbnail_cuda_filter_deps="ffnvcodec"
thumbnail_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
tonemap_cuda_filter_deps="ffnvcodec const_nan"
tonemap_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
@@ -15,7 +15,7 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -540,6 +540,8 @@ OBJS-$(CONFIG_TONEMAP_VIDEOTOOLBOX_FILTE
@@ -542,6 +542,8 @@ OBJS-$(CONFIG_TONEMAP_VIDEOTOOLBOX_FILTE
metal/utils.o
OBJS-$(CONFIG_TPAD_FILTER) += vf_tpad.o
OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o
@@ -28,7 +28,7 @@ Index: FFmpeg/libavfilter/allfilters.c
===================================================================
--- FFmpeg.orig/libavfilter/allfilters.c
+++ FFmpeg/libavfilter/allfilters.c
@@ -504,6 +504,7 @@ extern const AVFilter ff_vf_tonemap_vaap
@@ -505,6 +505,7 @@ extern const AVFilter ff_vf_tonemap_vaap
extern const AVFilter ff_vf_tonemap_videotoolbox;
extern const AVFilter ff_vf_tpad;
extern const AVFilter ff_vf_transpose;
@@ -40,7 +40,7 @@ Index: FFmpeg/libavfilter/vf_transpose_cuda.c
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_transpose_cuda.c
@@ -0,0 +1,477 @@
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2024 NyanMisaka
+ *
@@ -70,9 +70,9 @@ Index: FFmpeg/libavfilter/vf_transpose_cuda.c
+#include "libavutil/pixdesc.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+#include "filters.h"
+#include "transpose.h"
+#include "video.h"
+
+#include "cuda/load_helper.h"
+
@@ -201,18 +201,20 @@ Index: FFmpeg/libavfilter/vf_transpose_cuda.c
+static int init_processing_chain(AVFilterContext *ctx,
+ int out_width, int out_height)
+{
+ FilterLink *inl = ff_filter_link(ctx->inputs[0]);
+ FilterLink *outl = ff_filter_link(ctx->outputs[0]);
+ TransposeCUDAContext *s = ctx->priv;
+ AVHWFramesContext *in_frames_ctx;
+ enum AVPixelFormat format;
+ int ret;
+
+ /* check that we have a hw context */
+ if (!ctx->inputs[0]->hw_frames_ctx) {
+ if (!inl->hw_frames_ctx) {
+ av_log(ctx, AV_LOG_ERROR, "No hw context provided on input\n");
+ return AVERROR(EINVAL);
+ }
+
+ in_frames_ctx = (AVHWFramesContext*)ctx->inputs[0]->hw_frames_ctx->data;
+ in_frames_ctx = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ format = in_frames_ctx->sw_format;
+ s->pix_desc = av_pix_fmt_desc_get(format);
+
@@ -230,8 +232,8 @@ Index: FFmpeg/libavfilter/vf_transpose_cuda.c
+ s->hwctx = in_frames_ctx->device_ctx->hwctx;
+ s->cu_stream = s->hwctx->stream;
+
+ ctx->outputs[0]->hw_frames_ctx = av_buffer_ref(s->frames_ctx);
+ if (!ctx->outputs[0]->hw_frames_ctx)
+ outl->hw_frames_ctx = av_buffer_ref(s->frames_ctx);
+ if (!outl->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+
+ return 0;
@@ -241,8 +243,10 @@ Index: FFmpeg/libavfilter/vf_transpose_cuda.c
+{
+ extern const unsigned char ff_vf_transpose_cuda_ptx_data[];
+ extern const unsigned int ff_vf_transpose_cuda_ptx_len;
+ AVFilterContext *ctx = outlink->src;
+ AVFilterLink *inlink = ctx->inputs[0];
+ FilterLink *outl = ff_filter_link(outlink);
+ AVFilterContext *ctx = outlink->src;
+ AVFilterLink *inlink = ctx->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ TransposeCUDAContext *s = ctx->priv;
+ CUcontext dummy, cuda_ctx;
+ CudaFunctions *cu;
@@ -250,9 +254,9 @@ Index: FFmpeg/libavfilter/vf_transpose_cuda.c
+
+ if ((inlink->w >= inlink->h && s->passthrough == TRANSPOSE_PT_TYPE_LANDSCAPE) ||
+ (inlink->w <= inlink->h && s->passthrough == TRANSPOSE_PT_TYPE_PORTRAIT)) {
+ if (inlink->hw_frames_ctx) {
+ outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
+ if (!outlink->hw_frames_ctx)
+ if (inl->hw_frames_ctx) {
+ outl->hw_frames_ctx = av_buffer_ref(inl->hw_frames_ctx);
+ if (!outl->hw_frames_ctx)
+ return AVERROR(ENOMEM);
+ }
+
@@ -390,7 +394,7 @@ Index: FFmpeg/libavfilter/vf_transpose_cuda.c
+ AVFrame *out, AVFrame *in)
+{
+ TransposeCUDAContext *s = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFrame *src = in;
+ int ret;
+
@@ -19,7 +19,7 @@ Index: FFmpeg/libavfilter/vf_transpose_opencl.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_transpose_opencl.c
+++ FFmpeg/libavfilter/vf_transpose_opencl.c
@@ -101,8 +101,20 @@ static int transpose_opencl_config_outpu
@@ -103,8 +103,20 @@ static int transpose_opencl_config_outpu
return AVERROR(EINVAL);
}
@@ -42,7 +42,7 @@ Index: FFmpeg/libavfilter/vf_transpose_opencl.c
ret = ff_opencl_filter_config_output(outlink);
if (ret < 0)
return ret;
@@ -114,10 +126,8 @@ static int transpose_opencl_config_outpu
@@ -116,10 +128,8 @@ static int transpose_opencl_config_outpu
outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
av_log(avctx, AV_LOG_VERBOSE,
@@ -55,7 +55,7 @@ Index: FFmpeg/libavfilter/vf_transpose_opencl.c
return 0;
}
@@ -235,11 +245,14 @@ static av_cold void transpose_opencl_uni
@@ -237,11 +247,14 @@ static av_cold void transpose_opencl_uni
#define OFFSET(x) offsetof(TransposeOpenCLContext, x)
#define FLAGS (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
static const AVOption transpose_opencl_options[] = {
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/libopusenc.c
===================================================================
--- FFmpeg.orig/libavcodec/libopusenc.c
+++ FFmpeg/libavcodec/libopusenc.c
@@ -196,6 +196,10 @@ static int libopus_check_vorbis_layout(A
@@ -197,6 +197,10 @@ static int libopus_check_vorbis_layout(A
av_log(avctx, AV_LOG_WARNING,
"No channel layout specified. Opus encoder will use Vorbis "
"channel layout for %d channels.\n", avctx->ch_layout.nb_channels);
@@ -2,28 +2,27 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -2314,6 +2314,9 @@ HEADERS_LIST="
@@ -2316,6 +2316,9 @@ HEADERS_LIST="
INTRINSICS_LIST="
intrinsics_neon
intrinsics_sse2
+ intrinsics_sse42
+ intrinsics_fma3
+ intrinsics_avx2
"
MATH_FUNCS="
@@ -2797,6 +2800,10 @@ avx2_deps="avx"
avx512_deps="avx2"
avx512icl_deps="avx512"
@@ -2750,6 +2753,9 @@ armv8_deps="aarch64"
neon_deps_any="aarch64 arm"
intrinsics_neon_deps="neon"
intrinsics_sse2_deps="sse2"
+intrinsics_sse42_deps="sse42"
+intrinsics_fma3_deps="fma3"
+intrinsics_avx2_deps="avx2"
+
mmx_external_deps="x86asm"
mmx_inline_deps="inline_asm x86"
mmx_suggest="mmx_external mmx_inline"
@@ -3934,6 +3941,7 @@ tinterlace_filter_deps="gpl"
vfp_deps="arm"
vfpv3_deps="vfp"
setend_deps="arm"
@@ -3979,6 +3985,7 @@ tinterlace_filter_deps="gpl"
tinterlace_merge_test_deps="tinterlace_filter"
tinterlace_pad_test_deps="tinterlace_filter"
tonemap_filter_deps="const_nan"
@@ -31,9 +30,9 @@ Index: FFmpeg/configure
tonemap_vaapi_filter_deps="vaapi VAProcFilterParameterBufferHDRToneMapping"
tonemap_videotoolbox_filter_deps="metal corevideo videotoolbox const_nan"
tonemap_opencl_filter_deps="opencl const_nan"
@@ -6464,6 +6472,19 @@ fi
@@ -6510,6 +6517,19 @@ fi
check_cc intrinsics_neon arm_neon.h "int16x8_t test = vdupq_n_s16(0)"
check_cc intrinsics_sse2 emmintrin.h "__m128i test = _mm_setzero_si128()"
+disable intrinsics_sse42 && test_cc -msse4.2 <<EOF && enable intrinsics_sse42
+#include <immintrin.h>
@@ -51,7 +50,7 @@ Index: FFmpeg/configure
check_ldflags -Wl,--as-needed
check_ldflags -Wl,-z,noexecstack
@@ -7586,6 +7607,16 @@ elif enabled gcc; then
@@ -7639,6 +7659,16 @@ elif enabled gcc; then
check_cflags -mpreferred-stack-boundary=4
;;
esac
@@ -72,13 +71,13 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -530,6 +530,7 @@ OBJS-$(CONFIG_TMEDIAN_FILTER)
@@ -532,6 +532,7 @@ OBJS-$(CONFIG_TMEDIAN_FILTER)
OBJS-$(CONFIG_TMIDEQUALIZER_FILTER) += vf_tmidequalizer.o
OBJS-$(CONFIG_TMIX_FILTER) += vf_mix.o framesync.o
OBJS-$(CONFIG_TONEMAP_FILTER) += vf_tonemap.o
+OBJS-$(CONFIG_TONEMAPX_FILTER) += vf_tonemapx.o
OBJS-$(CONFIG_TONEMAP_CUDA_FILTER) += vf_tonemap_cuda.o cuda/tonemap.ptx.o \
cuda/host_util.o
cuda/host_util.o cuda/load_helper.o
OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER) += vf_tonemap_opencl.o opencl.o \
Index: FFmpeg/libavfilter/aarch64/Makefile
===================================================================
@@ -2546,7 +2545,7 @@ Index: FFmpeg/libavfilter/allfilters.c
===================================================================
--- FFmpeg.orig/libavfilter/allfilters.c
+++ FFmpeg/libavfilter/allfilters.c
@@ -498,6 +498,7 @@ extern const AVFilter ff_vf_tmedian;
@@ -499,6 +499,7 @@ extern const AVFilter ff_vf_tmedian;
extern const AVFilter ff_vf_tmidequalizer;
extern const AVFilter ff_vf_tmix;
extern const AVFilter ff_vf_tonemap;
@@ -2635,7 +2634,7 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_tonemapx.c
@@ -0,0 +1,1886 @@
@@ -0,0 +1,1918 @@
+/*
+ * This file is part of FFmpeg.
+ *
@@ -2665,6 +2664,7 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
+#include "libavutil/avassert.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
+#include "libavutil/mem.h"
+#include "libavutil/mem_internal.h"
+#include "libavutil/opt.h"
+#include "libavutil/cpu.h"
@@ -2690,8 +2690,8 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
+#endif // CC_SUPPORTS_TONEMAPX_INTRINSICS
+
+#include "avfilter.h"
+#include "filters.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#define MIX(x, y, a) ((x) + ((y) - (x)) * (a))
@@ -2806,6 +2806,13 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
+ AV_PIX_FMT_P010,
+};
+
+static const int colorspaces_out[] = {
+ AVCOL_SPC_UNSPECIFIED,
+ AVCOL_SPC_BT709,
+ AVCOL_SPC_BT2020_NCL,
+ -1
+};
+
+const double dovi_lms2rgb_matrix[3][3] =
+{
+ { 3.06441879, -2.16597676, 0.10155818},
@@ -4164,9 +4171,9 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
+ }
+
+ out->color_trc = s->trc == -1 ? AVCOL_TRC_UNSPECIFIED : s->trc;
+ out->colorspace = s->spc == -1 ? AVCOL_SPC_UNSPECIFIED : s->spc;
+ out->colorspace = outlink->colorspace;
+ out->color_primaries = s->pri == -1 ? AVCOL_PRI_UNSPECIFIED : s->pri;
+ out->color_range = s->range == -1 ? in->color_range : s->range;
+ out->color_range = outlink->color_range;
+
+ if (in->color_trc == AVCOL_TRC_UNSPECIFIED)
+ in->color_trc = AVCOL_TRC_SMPTE2084;
@@ -4254,9 +4261,9 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
+ AVFilterFormats *formats;
+ const AVPixFmtDescriptor *desc;
+ TonemapxContext *s = ctx->priv;
+ int res;
+
+ if (!strcmp(s->format_str, "same")) {
+ int res;
+ formats = ff_make_format_list(in_pix_fmts);
+ res = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats);
+ if (res < 0)
@@ -4264,7 +4271,6 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
+ s->format = AV_PIX_FMT_NONE;
+ } else {
+ int i, j = 0;
+ int res;
+ formats = ff_make_format_list(in_pix_fmts);
+ res = ff_formats_ref(formats, &ctx->inputs[0]->outcfg.formats);
+ if (res < 0)
@@ -4306,7 +4312,32 @@ Index: FFmpeg/libavfilter/vf_tonemapx.c
+ }
+ }
+
+ return ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats);
+ res = ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats);
+ if (res < 0)
+ return res;
+
+ // colorspaces and ranges
+ if ((res = ff_formats_ref(ff_all_color_spaces(),
+ &ctx->inputs[0]->outcfg.color_spaces)) < 0)
+ return res;
+
+ if ((res = ff_formats_ref(ff_all_color_ranges(),
+ &ctx->inputs[0]->outcfg.color_ranges)) < 0)
+ return res;
+
+ formats = s->spc != -1
+ ? ff_make_formats_list_singleton(s->spc)
+ : ff_make_format_list(colorspaces_out);
+ if ((res = ff_formats_ref(formats, &ctx->outputs[0]->incfg.color_spaces)) < 0)
+ return res;
+
+ formats = s->range != -1
+ ? ff_make_formats_list_singleton(s->range)
+ : ff_all_color_ranges();
+ if ((res = ff_formats_ref(formats, &ctx->outputs[0]->incfg.color_ranges)) < 0)
+ return res;
+
+ return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx)
@@ -4675,7 +4706,7 @@ Index: FFmpeg/libavfilter/x86/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/x86/Makefile
+++ FFmpeg/libavfilter/x86/Makefile
@@ -34,6 +34,8 @@ OBJS-$(CONFIG_STEREO3D_FILTER)
@@ -36,6 +36,8 @@ OBJS-$(CONFIG_STEREO3D_FILTER)
OBJS-$(CONFIG_TBLEND_FILTER) += x86/vf_blend_init.o
OBJS-$(CONFIG_THRESHOLD_FILTER) += x86/vf_threshold_init.o
OBJS-$(CONFIG_TINTERLACE_FILTER) += x86/vf_tinterlace_init.o
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/Makefile
===================================================================
--- FFmpeg.orig/libavcodec/Makefile
+++ FFmpeg/libavcodec/Makefile
@@ -203,6 +203,7 @@ OBJS-$(CONFIG_AC3_ENCODER) +
@@ -210,6 +210,7 @@ OBJS-$(CONFIG_AC3_ENCODER) +
ac3.o kbdwin.o
OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o kbdwin.o
OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o
@@ -14,7 +14,7 @@ Index: FFmpeg/libavcodec/ac4dec.c
===================================================================
--- /dev/null
+++ FFmpeg/libavcodec/ac4dec.c
@@ -0,0 +1,5924 @@
@@ -0,0 +1,5925 @@
+/*
+ * AC-4 Audio Decoder
+ *
@@ -43,6 +43,7 @@ Index: FFmpeg/libavcodec/ac4dec.c
+#include "libavutil/tx.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/mem.h"
+#include "libavutil/mem_internal.h"
+#include "libavutil/qsort.h"
+#include "libavutil/opt.h"
@@ -7612,7 +7613,7 @@ Index: FFmpeg/libavcodec/allcodecs.c
===================================================================
--- FFmpeg.orig/libavcodec/allcodecs.c
+++ FFmpeg/libavcodec/allcodecs.c
@@ -431,6 +431,7 @@ extern const FFCodec ff_ac3_encoder;
@@ -430,6 +430,7 @@ extern const FFCodec ff_ac3_encoder;
extern const FFCodec ff_ac3_decoder;
extern const FFCodec ff_ac3_fixed_encoder;
extern const FFCodec ff_ac3_fixed_decoder;
@@ -7637,7 +7638,7 @@ Index: FFmpeg/libavcodec/utils.c
===================================================================
--- FFmpeg.orig/libavcodec/utils.c
+++ FFmpeg/libavcodec/utils.c
@@ -598,7 +598,8 @@ static int get_audio_frame_duration(enum
@@ -601,7 +601,8 @@ static int get_audio_frame_duration(enum
case AV_CODEC_ID_ATRAC3P: return 2048;
case AV_CODEC_ID_MP2:
case AV_CODEC_ID_MUSEPACK7: return 1152;
@@ -7651,7 +7652,7 @@ Index: FFmpeg/libavformat/isom_tags.c
===================================================================
--- FFmpeg.orig/libavformat/isom_tags.c
+++ FFmpeg/libavformat/isom_tags.c
@@ -308,6 +308,7 @@ const AVCodecTag ff_codec_movaudio_tags[
@@ -310,6 +310,7 @@ const AVCodecTag ff_codec_movaudio_tags[
{ AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'e') }, /* DTS Express */
{ AV_CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */
{ AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F (only valid in ISOBMFF) */
@@ -1,59 +0,0 @@
Index: FFmpeg/libavcodec/vaapi_encode.c
===================================================================
--- FFmpeg.orig/libavcodec/vaapi_encode.c
+++ FFmpeg/libavcodec/vaapi_encode.c
@@ -2728,6 +2728,17 @@ static av_cold int vaapi_encode_create_r
av_log(avctx, AV_LOG_DEBUG, "Using %s as format of "
"reconstructed frames.\n", av_get_pix_fmt_name(recon_format));
+ if (constraints->width_align || constraints->height_align) {
+ if (constraints->width_align) {
+ ctx->surface_width = FFALIGN(avctx->width, constraints->width_align);
+ }
+ if (constraints->height_align) {
+ ctx->surface_height = FFALIGN(avctx->height, constraints->height_align);
+ }
+ av_log(avctx, AV_LOG_VERBOSE, "Using customized alignment size "
+ "[%dx%d].\n", constraints->width_align, constraints->height_align);
+ }
+
if (ctx->surface_width < constraints->min_width ||
ctx->surface_height < constraints->min_height ||
ctx->surface_width > constraints->max_width ||
Index: FFmpeg/libavutil/hwcontext.h
===================================================================
--- FFmpeg.orig/libavutil/hwcontext.h
+++ FFmpeg/libavutil/hwcontext.h
@@ -467,6 +467,13 @@ typedef struct AVHWFramesConstraints {
*/
int max_width;
int max_height;
+
+ /**
+ * The frame width/height alignment when available
+ * (Zero is not applied, use the default value.)
+ */
+ int width_align;
+ int height_align;
} AVHWFramesConstraints;
/**
Index: FFmpeg/libavutil/hwcontext_vaapi.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_vaapi.c
+++ FFmpeg/libavutil/hwcontext_vaapi.c
@@ -297,6 +297,14 @@ static int vaapi_frames_get_constraints(
case VASurfaceAttribMaxHeight:
constraints->max_height = attr_list[i].value.value.i;
break;
+#if VA_CHECK_VERSION(1, 21, 0)
+ case VASurfaceAttribAlignmentSize:
+ if (attr_list[i].value.value.i) {
+ constraints->width_align = 1 << (attr_list[i].value.value.i & 0xf);
+ constraints->height_align = 1 << ((attr_list[i].value.value.i & 0xf0) >> 4);
+ }
+ break;
+#endif
}
}
if (pix_fmt_count == 0) {
@@ -2,7 +2,7 @@ Index: FFmpeg/fftools/ffmpeg_sched.h
===================================================================
--- FFmpeg.orig/fftools/ffmpeg_sched.h
+++ FFmpeg/fftools/ffmpeg_sched.h
@@ -243,7 +243,10 @@ int sch_add_mux(Scheduler *sch, SchThrea
@@ -257,7 +257,10 @@ int sch_add_mux(Scheduler *sch, SchThrea
/**
* Default size of a frame thread queue.
*/
@@ -0,0 +1,185 @@
Index: FFmpeg/libavutil/hwcontext_vulkan.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_vulkan.c
+++ FFmpeg/libavutil/hwcontext_vulkan.c
@@ -90,6 +90,9 @@ typedef struct VulkanDevicePriv {
VkPhysicalDeviceMemoryProperties mprops;
VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops;
+ /* Opaque FD external semaphore properties */
+ VkExternalSemaphoreProperties ext_sem_props_opaque;
+
/* Features */
VkPhysicalDeviceVulkan11Features device_features_1_1;
VkPhysicalDeviceVulkan12Features device_features_1_2;
@@ -1212,7 +1215,7 @@ static int setup_queue_families(AVHWDevi
};
qf[i] = (VkQueueFamilyProperties2) {
.sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
- .pNext = &qf_vid[i],
+ .pNext = p->vkctx.extensions & FF_VK_EXT_VIDEO_QUEUE ? &qf_vid[i] : NULL,
};
}
@@ -1642,6 +1645,7 @@ static int vulkan_device_init(AVHWDevice
FFVulkanFunctions *vk = &p->vkctx.vkfn;
VkQueueFamilyProperties2 *qf;
VkQueueFamilyVideoPropertiesKHR *qf_vid;
+ VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
int graph_index, comp_index, tx_index, enc_index, dec_index;
/* Set device extension flags */
@@ -1687,6 +1691,24 @@ static int vulkan_device_init(AVHWDevice
return AVERROR_EXTERNAL;
}
+ ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
+ };
+
+ /* Opaque FD semaphore properties */
+ ext_sem_props_info.handleType =
+#ifdef _WIN32
+ IsWindows8OrGreater()
+ ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
+ : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
+#else
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
+#endif
+ p->ext_sem_props_opaque.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
+ vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->phys_dev,
+ &ext_sem_props_info,
+ &p->ext_sem_props_opaque);
+
qf = av_malloc_array(qf_num, sizeof(VkQueueFamilyProperties2));
if (!qf)
return AVERROR(ENOMEM);
@@ -1703,7 +1725,7 @@ static int vulkan_device_init(AVHWDevice
};
qf[i] = (VkQueueFamilyProperties2) {
.sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
- .pNext = &qf_vid[i],
+ .pNext = p->vkctx.extensions & FF_VK_EXT_VIDEO_QUEUE ? &qf_vid[i] : NULL,
};
}
@@ -1980,7 +2002,7 @@ static int vulkan_frames_get_constraints
count += vkfmt_from_pixfmt2(ctx, vk_formats_list[i].pixfmt,
p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
VK_IMAGE_TILING_OPTIMAL,
- NULL, NULL, NULL, NULL, 0, 0) >= 0;
+ NULL, NULL, NULL, NULL, p->disable_multiplane, 1) >= 0;
}
constraints->valid_sw_formats = av_malloc_array(count + 1,
@@ -1993,7 +2015,7 @@ static int vulkan_frames_get_constraints
if (vkfmt_from_pixfmt2(ctx, vk_formats_list[i].pixfmt,
p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
VK_IMAGE_TILING_OPTIMAL,
- NULL, NULL, NULL, NULL, 0, 0) >= 0) {
+ NULL, NULL, NULL, NULL, p->disable_multiplane, 1) >= 0) {
constraints->valid_sw_formats[count++] = vk_formats_list[i].pixfmt;
}
}
@@ -2346,8 +2368,19 @@ static int create_frame(AVHWFramesContex
VulkanDevicePriv *p = ctx->hwctx;
AVVulkanDeviceContext *hwctx = &p->p;
FFVulkanFunctions *vk = &p->vkctx.vkfn;
+ AVVkFrame *f;
- VkExportSemaphoreCreateInfo ext_sem_info = {
+ VkSemaphoreTypeCreateInfo sem_type_info = {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+ .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
+ .initialValue = 0,
+ };
+ VkSemaphoreCreateInfo sem_spawn = {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ .pNext = &sem_type_info,
+ };
+
+ VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
#ifdef _WIN32
.handleTypes = IsWindows8OrGreater()
@@ -2358,23 +2391,13 @@ static int create_frame(AVHWFramesContex
#endif
};
- VkSemaphoreTypeCreateInfo sem_type_info = {
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
-#ifdef _WIN32
- .pNext = p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM ? &ext_sem_info : NULL,
-#else
- .pNext = p->vkctx.extensions & FF_VK_EXT_EXTERNAL_FD_SEM ? &ext_sem_info : NULL,
-#endif
- .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
- .initialValue = 0,
- };
-
- VkSemaphoreCreateInfo sem_spawn = {
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
- .pNext = &sem_type_info,
- };
+ /* Check if exporting is supported before chaining any structs */
+ if (p->ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
+ if (p->vkctx.extensions & (FF_VK_EXT_EXTERNAL_WIN32_SEM | FF_VK_EXT_EXTERNAL_FD_SEM))
+ ff_vk_link_struct(&sem_type_info, &ext_sem_info_opaque);
+ }
- AVVkFrame *f = av_vk_frame_alloc();
+ f = av_vk_frame_alloc();
if (!f) {
av_log(ctx, AV_LOG_ERROR, "Unable to allocate memory for AVVkFrame!\n");
return AVERROR(ENOMEM);
@@ -2689,11 +2712,11 @@ static int vulkan_frames_init(AVHWFrames
!(hwctx->usage & VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR)));
int sampleable = hwctx->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT);
+ hwctx->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
if (sampleable && !is_lone_dpb) {
- hwctx->img_flags = VK_IMAGE_CREATE_ALIAS_BIT;
+ hwctx->img_flags |= VK_IMAGE_CREATE_ALIAS_BIT;
if ((fmt->vk_planes > 1) && (hwctx->format[0] == fmt->vkf))
- hwctx->img_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
- VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
+ hwctx->img_flags |= VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
}
}
Index: FFmpeg/libavutil/vulkan.c
===================================================================
--- FFmpeg.orig/libavutil/vulkan.c
+++ FFmpeg/libavutil/vulkan.c
@@ -185,7 +185,7 @@ int ff_vk_load_props(FFVulkanContext *s)
};
s->qf_props[i] = (VkQueueFamilyProperties2) {
.sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
- .pNext = &s->video_props[i],
+ .pNext = s->extensions & FF_VK_EXT_VIDEO_QUEUE ? &s->video_props[i] : NULL,
};
}
Index: FFmpeg/libavutil/vulkan_functions.h
===================================================================
--- FFmpeg.orig/libavutil/vulkan_functions.h
+++ FFmpeg/libavutil/vulkan_functions.h
@@ -33,10 +33,8 @@ typedef enum FFVulkanExtensions {
FF_VK_EXT_EXTERNAL_FD_SEM = 1ULL << 3, /* VK_KHR_external_semaphore_fd */
FF_VK_EXT_EXTERNAL_HOST_MEMORY = 1ULL << 4, /* VK_EXT_external_memory_host */
FF_VK_EXT_DEBUG_UTILS = 1ULL << 5, /* VK_EXT_debug_utils */
-#ifdef _WIN32
FF_VK_EXT_EXTERNAL_WIN32_MEMORY = 1ULL << 6, /* VK_KHR_external_memory_win32 */
FF_VK_EXT_EXTERNAL_WIN32_SEM = 1ULL << 7, /* VK_KHR_external_semaphore_win32 */
-#endif
FF_VK_EXT_DESCRIPTOR_BUFFER = 1ULL << 8, /* VK_EXT_descriptor_buffer */
FF_VK_EXT_DEVICE_DRM = 1ULL << 9, /* VK_EXT_physical_device_drm */
FF_VK_EXT_VIDEO_QUEUE = 1ULL << 10, /* VK_KHR_video_queue */
@@ -75,6 +73,7 @@ typedef enum FFVulkanExtensions {
MACRO(1, 0, FF_VK_EXT_NO_FLAG, CreateDevice) \
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceFeatures2) \
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceProperties) \
+ MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceExternalSemaphoreProperties) \
MACRO(1, 0, FF_VK_EXT_VIDEO_QUEUE, GetPhysicalDeviceVideoCapabilitiesKHR) \
MACRO(1, 0, FF_VK_EXT_VIDEO_QUEUE, GetPhysicalDeviceVideoFormatPropertiesKHR) \
MACRO(1, 0, FF_VK_EXT_NO_FLAG, DeviceWaitIdle) \
@@ -2,7 +2,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_vulkan.c
+++ FFmpeg/libavutil/hwcontext_vulkan.c
@@ -131,9 +131,6 @@ typedef struct VulkanFramesPriv {
@@ -139,9 +139,6 @@ typedef struct VulkanFramesPriv {
FFVkExecPool upload_exec;
FFVkExecPool download_exec;
@@ -12,7 +12,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
/* Modifier info list to free at uninit */
VkImageDrmFormatModifierListCreateInfoEXT *modifier_info;
} VulkanFramesPriv;
@@ -2561,8 +2558,6 @@ static void vulkan_frames_uninit(AVHWFra
@@ -2622,8 +2619,6 @@ static void vulkan_frames_uninit(AVHWFra
ff_vk_exec_pool_free(&p->vkctx, &fp->compute_exec);
ff_vk_exec_pool_free(&p->vkctx, &fp->upload_exec);
ff_vk_exec_pool_free(&p->vkctx, &fp->download_exec);
@@ -21,7 +21,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
}
static int vulkan_frames_init(AVHWFramesContext *hwfc)
@@ -3611,290 +3606,128 @@ static int vulkan_map_from(AVHWFramesCon
@@ -3809,290 +3804,128 @@ static int vulkan_map_from(AVHWFramesCon
return AVERROR(ENOSYS);
}
@@ -234,6 +234,10 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
- }
-
- get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i);
-
- /* Get the previous point at which mapping was possible and use it */
- offs = (uintptr_t)swf->data[i] % p->hprops.minImportedHostPointerAlignment;
- import_desc.pHostPointer = swf->data[i] - offs;
+ ff_vk_frame_barrier(&p->vkctx, exec, f, img_bar, &nb_img_bar,
+ VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,
@@ -243,10 +247,6 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ VK_QUEUE_FAMILY_IGNORED);
- /* Get the previous point at which mapping was possible and use it */
- offs = (uintptr_t)swf->data[i] % p->hprops.minImportedHostPointerAlignment;
- import_desc.pHostPointer = swf->data[i] - offs;
-
- props = (VkMemoryHostPointerPropertiesEXT) {
- VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
- };
@@ -383,10 +383,10 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
- VK_IMAGE_ASPECT_PLANE_0_BIT,
- VK_IMAGE_ASPECT_PLANE_1_BIT,
- VK_IMAGE_ASPECT_PLANE_2_BIT, };
-
- VkImageMemoryBarrier2 img_bar[AV_NUM_DATA_POINTERS];
- int nb_img_bar = 0;
-
- AVBufferRef *bufs[AV_NUM_DATA_POINTERS];
- int nb_bufs = 0;
+ int host_mapped[AV_NUM_DATA_POINTERS] = { 0 };
@@ -399,7 +399,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
if ((swf->format != AV_PIX_FMT_NONE && !av_vkfmt_from_pixfmt(swf->format))) {
av_log(hwfc, AV_LOG_ERROR, "Unsupported software frame pixel format!\n");
return AVERROR(EINVAL);
@@ -3903,97 +3736,115 @@ static int vulkan_transfer_frame(AVHWFra
@@ -4101,97 +3934,115 @@ static int vulkan_transfer_frame(AVHWFra
if (swf->width > hwfc->width || swf->height > hwfc->height)
return AVERROR(EINVAL);
@@ -412,9 +412,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
+ /* Create buffers */
+ for (int i = 0; i < planes; i++) {
+ size_t req_size;
- if (!host_mapped) {
- err = get_plane_buf(hwfc, &bufs[0], swf, region, upload);
+
+ VkExternalMemoryBufferCreateInfo create_desc = {
+ .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
+ .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
@@ -430,7 +428,9 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
+ };
+
+ get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i);
+
- if (!host_mapped) {
- err = get_plane_buf(hwfc, &bufs[0], swf, region, upload);
+ tmp.linesize[i] = FFABS(swf->linesize[i]);
+
+ /* Do not map images with a negative stride */
@@ -587,7 +587,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
av_buffer_unref(&bufs[i]);
return err;
@@ -4020,7 +3871,7 @@ static int vulkan_transfer_data_to(AVHWF
@@ -4218,7 +4069,7 @@ static int vulkan_transfer_data_to(AVHWF
if (src->hw_frames_ctx)
return AVERROR(ENOSYS);
else
@@ -596,7 +596,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
}
}
@@ -4137,7 +3988,7 @@ static int vulkan_transfer_data_from(AVH
@@ -4335,7 +4186,7 @@ static int vulkan_transfer_data_from(AVH
if (dst->hw_frames_ctx)
return AVERROR(ENOSYS);
else
@@ -609,7 +609,7 @@ Index: FFmpeg/libavutil/vulkan.c
===================================================================
--- FFmpeg.orig/libavutil/vulkan.c
+++ FFmpeg/libavutil/vulkan.c
@@ -819,8 +819,11 @@ int ff_vk_alloc_mem(FFVulkanContext *s,
@@ -887,8 +887,11 @@ int ff_vk_alloc_mem(FFVulkanContext *s,
ret = vk->AllocateMemory(s->hwctx->act_dev, &alloc_info,
s->hwctx->alloc, mem);
@@ -2,7 +2,21 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_vulkan.c
+++ FFmpeg/libavutil/hwcontext_vulkan.c
@@ -1382,6 +1382,7 @@ static void vulkan_device_uninit(AVHWDev
@@ -64,6 +64,13 @@
#if HAVE_LINUX_DMA_BUF_H
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
+#if 0 // ndef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
+#define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file)
+struct dma_buf_export_sync_file {
+ uint32_t flags;
+ int32_t fd;
+};
+#endif
#endif
#if CONFIG_CUDA
@@ -1400,6 +1407,7 @@ static void vulkan_device_uninit(AVHWDev
static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
VulkanDeviceSelection *dev_select,
@@ -10,7 +24,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
int disable_multiplane,
AVDictionary *opts, int flags)
{
@@ -1580,10 +1581,14 @@ static int vulkan_device_create_internal
@@ -1599,10 +1607,14 @@ static int vulkan_device_create_internal
goto end;
}
@@ -29,7 +43,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
/*
* The disable_multiplane argument takes precedent over the option.
@@ -1829,7 +1834,7 @@ static int vulkan_device_create(AVHWDevi
@@ -1882,7 +1894,7 @@ static int vulkan_device_create(AVHWDevi
}
}
@@ -38,7 +52,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
}
static int vulkan_device_derive(AVHWDeviceContext *ctx,
@@ -1853,6 +1858,7 @@ static int vulkan_device_derive(AVHWDevi
@@ -1906,6 +1918,7 @@ static int vulkan_device_derive(AVHWDevi
};
#endif
const char *vendor;
@@ -46,7 +60,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
#if VA_CHECK_VERSION(1, 15, 0)
vas = vaGetDisplayAttributes(dpy, &attr, 1);
@@ -1867,11 +1873,14 @@ static int vulkan_device_derive(AVHWDevi
@@ -1920,11 +1933,14 @@ static int vulkan_device_derive(AVHWDevi
return AVERROR_EXTERNAL;
}
@@ -63,7 +77,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
}
#endif
#if CONFIG_LIBDRM
@@ -1880,6 +1889,7 @@ static int vulkan_device_derive(AVHWDevi
@@ -1933,6 +1949,7 @@ static int vulkan_device_derive(AVHWDevi
struct stat drm_node_info;
drmDevice *drm_dev_info;
AVDRMDeviceContext *src_hwctx = src_ctx->hwctx;
@@ -71,7 +85,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
err = fstat(src_hwctx->fd, &drm_node_info);
if (err) {
@@ -1899,12 +1909,15 @@ static int vulkan_device_derive(AVHWDevi
@@ -1952,12 +1969,15 @@ static int vulkan_device_derive(AVHWDevi
return AVERROR_EXTERNAL;
}
@@ -89,7 +103,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
}
#endif
#if CONFIG_CUDA
@@ -1927,7 +1940,7 @@ static int vulkan_device_derive(AVHWDevi
@@ -1980,7 +2000,7 @@ static int vulkan_device_derive(AVHWDevi
* CUDA is not able to import multiplane images, so always derive a
* Vulkan device with multiplane disabled.
*/
@@ -98,18 +112,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
}
#endif
default:
@@ -2774,6 +2787,10 @@ static const struct {
{ DRM_FORMAT_XRGB8888, VK_FORMAT_B8G8R8A8_UNORM },
{ DRM_FORMAT_ABGR8888, VK_FORMAT_R8G8B8A8_UNORM },
{ DRM_FORMAT_XBGR8888, VK_FORMAT_R8G8B8A8_UNORM },
+ { DRM_FORMAT_ARGB2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
+ { DRM_FORMAT_XRGB2101010, VK_FORMAT_A2R10G10B10_UNORM_PACK32 },
+ { DRM_FORMAT_ABGR2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
+ { DRM_FORMAT_XBGR2101010, VK_FORMAT_A2B10G10R10_UNORM_PACK32 },
// All these DRM_FORMATs were added in the same libdrm commit.
#ifdef DRM_FORMAT_XYUV8888
@@ -2808,6 +2825,7 @@ static int vulkan_map_from_drm_frame_des
@@ -2876,6 +2896,7 @@ static int vulkan_map_from_drm_frame_des
const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0];
VkBindImageMemoryInfo bind_info[AV_DRM_MAX_PLANES];
VkBindImagePlaneMemoryInfo plane_info[AV_DRM_MAX_PLANES];
@@ -117,7 +120,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
for (int i = 0; i < desc->nb_layers; i++) {
if (drm_to_vulkan_fmt(desc->layers[i].format) == VK_FORMAT_UNDEFINED) {
@@ -2817,13 +2835,21 @@ static int vulkan_map_from_drm_frame_des
@@ -2885,13 +2906,21 @@ static int vulkan_map_from_drm_frame_des
}
}
@@ -140,25 +143,63 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
for (int i = 0; i < desc->nb_layers; i++) {
const int planes = desc->layers[i].nb_planes;
@@ -2861,7 +2887,7 @@ static int vulkan_map_from_drm_frame_des
@@ -2929,7 +2958,7 @@ static int vulkan_map_from_drm_frame_des
.mipLevels = 1,
.arrayLayers = 1,
.flags = 0x0,
- .tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
+ .tiling = f->tiling,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, /* specs say so */
.usage = VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
@@ -2894,7 +2920,7 @@ static int vulkan_map_from_drm_frame_des
};
VkPhysicalDeviceImageFormatInfo2 fmt_props = {
.usage = 0x0, /* filled in below */
.samples = VK_SAMPLE_COUNT_1_BIT,
@@ -2970,7 +2999,7 @@ static int vulkan_map_from_drm_frame_des
fmt_props = (VkPhysicalDeviceImageFormatInfo2) {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
- .pNext = &props_ext,
+ .pNext = has_modifiers ? &props_ext : NULL,
.format = create_info.format,
.type = create_info.imageType,
.tiling = create_info.tiling,
@@ -3396,22 +3422,14 @@ fail:
@@ -3145,7 +3174,7 @@ static int vulkan_map_from_drm_frame_syn
const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)src->data[0];
-#ifdef DMA_BUF_IOCTL_EXPORT_SYNC_FILE
+#if 0 // def DMA_BUF_IOCTL_EXPORT_SYNC_FILE
if (p->vkctx.extensions & FF_VK_EXT_EXTERNAL_FD_SEM) {
VkCommandBuffer cmd_buf;
FFVkExecContext *exec;
@@ -3171,8 +3200,10 @@ static int vulkan_map_from_drm_frame_syn
if (ioctl(desc->objects[i].fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE,
&implicit_fd_info)) {
err = AVERROR(errno);
- av_log(hwctx, AV_LOG_ERROR, "Failed to retrieve implicit DRM sync file: %s\n",
+ av_log(hwctx, i ? AV_LOG_ERROR : AV_LOG_DEBUG, "Failed to retrieve implicit DRM sync file: %s\n",
av_err2str(err));
+ if (i == 0) /* Bail out from the plane0 if ioctl failed */
+ goto fallback;
for (; i >= 0; i--)
vk->DestroySemaphore(hwctx->act_dev, drm_sync_sem[i], hwctx->alloc);
return err;
@@ -3248,10 +3279,12 @@ static int vulkan_map_from_drm_frame_syn
} else
#endif
{
- AVVkFrame *f = (AVVkFrame *)dst->data[0];
- av_log(hwctx, AV_LOG_WARNING, "No support for synchronization when importing DMA-BUFs, "
- "image may be corrupted.\n");
- err = prepare_frame(hwfc, &fp->compute_exec, f, PREP_MODE_EXTERNAL_IMPORT);
+#if 0 // def DMA_BUF_IOCTL_EXPORT_SYNC_FILE
+fallback:
+#endif
+ av_log(hwctx, AV_LOG_DEBUG, "No support for synchronization when importing DMA-BUFs, "
+ "image may be corrupted.\n");
+ err = prepare_frame(hwfc, &fp->compute_exec, (AVVkFrame *)dst->data[0], PREP_MODE_EXTERNAL_IMPORT);
if (err)
return err;
}
@@ -3594,22 +3627,14 @@ fail:
static int vulkan_map_to(AVHWFramesContext *hwfc, AVFrame *dst,
const AVFrame *src, int flags)
{
@@ -183,7 +224,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
#endif
default:
return AVERROR(ENOSYS);
@@ -3454,13 +3472,14 @@ static int vulkan_map_to_drm(AVHWFramesC
@@ -3652,13 +3677,14 @@ static int vulkan_map_to_drm(AVHWFramesC
VulkanFramesPriv *fp = hwfc->hwctx;
AVVulkanFramesContext *hwfctx = &fp->p;
const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
@@ -199,7 +240,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
};
AVDRMFrameDescriptor *drm_desc = av_mallocz(sizeof(*drm_desc));
@@ -3481,10 +3500,16 @@ static int vulkan_map_to_drm(AVHWFramesC
@@ -3679,10 +3705,16 @@ static int vulkan_map_to_drm(AVHWFramesC
if (err < 0)
goto end;
@@ -220,7 +261,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
err = AVERROR_EXTERNAL;
goto end;
}
@@ -3506,7 +3531,7 @@ static int vulkan_map_to_drm(AVHWFramesC
@@ -3704,7 +3736,7 @@ static int vulkan_map_to_drm(AVHWFramesC
drm_desc->nb_objects++;
drm_desc->objects[i].size = f->size[i];
@@ -229,7 +270,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
}
drm_desc->nb_layers = planes;
@@ -3517,6 +3542,14 @@ static int vulkan_map_to_drm(AVHWFramesC
@@ -3715,6 +3747,14 @@ static int vulkan_map_to_drm(AVHWFramesC
};
VkFormat plane_vkfmt = av_vkfmt_from_pixfmt(hwfc->sw_format)[i];
@@ -244,7 +285,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
drm_desc->layers[i].format = vulkan_fmt_to_drm(plane_vkfmt);
drm_desc->layers[i].nb_planes = 1;
@@ -3531,7 +3564,7 @@ static int vulkan_map_to_drm(AVHWFramesC
@@ -3729,7 +3769,7 @@ static int vulkan_map_to_drm(AVHWFramesC
if (f->tiling == VK_IMAGE_TILING_OPTIMAL)
continue;
@@ -253,7 +294,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
drm_desc->layers[i].planes[0].offset = layout.offset;
drm_desc->layers[i].planes[0].pitch = layout.rowPitch;
@@ -3583,21 +3616,13 @@ fail:
@@ -3781,21 +3821,13 @@ fail:
static int vulkan_map_from(AVHWFramesContext *hwfc, AVFrame *dst,
const AVFrame *src, int flags)
{
@@ -1,78 +0,0 @@
Index: FFmpeg/libavcodec/qsv.c
===================================================================
--- FFmpeg.orig/libavcodec/qsv.c
+++ FFmpeg/libavcodec/qsv.c
@@ -473,8 +473,8 @@ static int ff_qsv_set_display_handle(AVC
AVVAAPIDeviceContext *hwctx;
int ret;
- av_dict_set(&child_device_opts, "kernel_driver", "i915", 0);
- av_dict_set(&child_device_opts, "driver", "iHD", 0);
+ av_dict_set(&child_device_opts, "vendor_id", "0x8086", 0);
+ av_dict_set(&child_device_opts, "driver", "iHD", 0);
ret = av_hwdevice_ctx_create(&qs->va_device_ref, AV_HWDEVICE_TYPE_VAAPI, NULL, child_device_opts, 0);
av_dict_free(&child_device_opts);
Index: FFmpeg/libavutil/hwcontext_qsv.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_qsv.c
+++ FFmpeg/libavutil/hwcontext_qsv.c
@@ -2644,8 +2644,8 @@ static int qsv_device_create(AVHWDeviceC
// used on recent Intel hardware. Set options to the VAAPI device
// creation so that we should pick a usable setup by default if
// possible, even when multiple devices and drivers are available.
- av_dict_set(&child_device_opts, "kernel_driver", "i915", 0);
- av_dict_set(&child_device_opts, "driver", "iHD", 0);
+ av_dict_set(&child_device_opts, "vendor_id", "0x8086", 0);
+ av_dict_set(&child_device_opts, "driver", "iHD", 0);
}
break;
#endif
Index: FFmpeg/libavutil/hwcontext_vaapi.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_vaapi.c
+++ FFmpeg/libavutil/hwcontext_vaapi.c
@@ -1763,7 +1763,9 @@ static int vaapi_device_create(AVHWDevic
#if CONFIG_LIBDRM
drmVersion *info;
const AVDictionaryEntry *kernel_driver;
+ const AVDictionaryEntry *vendor_id;
kernel_driver = av_dict_get(opts, "kernel_driver", NULL, 0);
+ vendor_id = av_dict_get(opts, "vendor_id", NULL, 0);
#endif
for (n = 0; n < max_devices; n++) {
snprintf(path, sizeof(path),
@@ -1818,6 +1820,33 @@ static int vaapi_device_create(AVHWDevic
close(priv->drm_fd);
priv->drm_fd = -1;
continue;
+ } else if (vendor_id) {
+ drmDevicePtr device;
+ char drm_vendor[8];
+ if (drmGetDevice(priv->drm_fd, &device)) {
+ av_log(ctx, AV_LOG_VERBOSE,
+ "Failed to get DRM device info for device %d.\n", n);
+ close(priv->drm_fd);
+ priv->drm_fd = -1;
+ continue;
+ }
+
+ snprintf(drm_vendor, sizeof(drm_vendor), "0x%x", device->deviceinfo.pci->vendor_id);
+ if (strcmp(vendor_id->value, drm_vendor)) {
+ av_log(ctx, AV_LOG_VERBOSE, "Ignoring device %d "
+ "with non-matching vendor id (%s).\n",
+ n, vendor_id->value);
+ drmFreeDevice(&device);
+ close(priv->drm_fd);
+ priv->drm_fd = -1;
+ continue;
+ }
+ av_log(ctx, AV_LOG_VERBOSE, "Trying to use "
+ "DRM render node for device %d, "
+ "with matching vendor id (%s).\n",
+ n, vendor_id->value);
+ drmFreeDevice(&device);
+ break;
}
drmFreeVersion(info);
#endif
@@ -2,7 +2,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
===================================================================
--- FFmpeg.orig/libavutil/hwcontext_vulkan.c
+++ FFmpeg/libavutil/hwcontext_vulkan.c
@@ -950,7 +950,7 @@ static const char *vk_dev_type(enum VkPh
@@ -968,7 +968,7 @@ static const char *vk_dev_type(enum VkPh
static int find_device(AVHWDeviceContext *ctx, VulkanDeviceSelection *select)
{
int err = 0, choice = -1;
@@ -11,7 +11,7 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
VkResult ret;
VulkanDevicePriv *p = ctx->hwctx;
AVVulkanDeviceContext *hwctx = &p->p;
@@ -1017,63 +1017,78 @@ static int find_device(AVHWDeviceContext
@@ -1035,63 +1035,78 @@ static int find_device(AVHWDeviceContext
if (select->has_uuid) {
for (int i = 0; i < num; i++) {
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
===================================================================
--- FFmpeg.orig/libavfilter/vf_overlay_vulkan.c
+++ FFmpeg/libavfilter/vf_overlay_vulkan.c
@@ -32,9 +32,11 @@ typedef struct OverlayVulkanContext {
@@ -33,9 +33,11 @@ typedef struct OverlayVulkanContext {
int initialized;
FFVulkanPipeline pl;
@@ -14,7 +14,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
VkSampler sampler;
/* Push constants / options */
@@ -47,6 +49,10 @@ typedef struct OverlayVulkanContext {
@@ -48,6 +50,10 @@ typedef struct OverlayVulkanContext {
int overlay_y;
int overlay_w;
int overlay_h;
@@ -25,7 +25,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
} OverlayVulkanContext;
static const char overlay_noalpha[] = {
@@ -83,15 +89,16 @@ static const char overlay_alpha[] = {
@@ -84,15 +90,16 @@ static const char overlay_alpha[] = {
static av_cold int init_filter(AVFilterContext *ctx)
{
int err;
@@ -44,7 +44,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@@ -104,90 +111,143 @@ static av_cold int init_filter(AVFilterC
@@ -105,90 +112,143 @@ static av_cold int init_filter(AVFilterC
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
@@ -262,7 +262,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
if (spv)
spv->uninit(&spv);
@@ -209,22 +269,11 @@ static int overlay_vulkan_blend(FFFrameS
@@ -210,22 +270,11 @@ static int overlay_vulkan_blend(FFFrameS
if (err < 0)
goto fail;
@@ -288,7 +288,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!out) {
@@ -232,9 +281,13 @@ static int overlay_vulkan_blend(FFFrameS
@@ -233,9 +282,13 @@ static int overlay_vulkan_blend(FFFrameS
goto fail;
}
@@ -305,14 +305,16 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
err = av_frame_copy_props(out, input_main);
if (err < 0)
@@ -252,6 +305,18 @@ static int overlay_vulkan_config_output(
@@ -253,6 +306,20 @@ static int overlay_vulkan_config_output(
int err;
AVFilterContext *avctx = outlink->src;
OverlayVulkanContext *s = avctx->priv;
+ AVFilterLink *inlink = avctx->inputs[0];
+ AVFilterLink *inlink_overlay = avctx->inputs[1];
+ AVHWFramesContext *main_fc = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ AVHWFramesContext *overlay_fc = (AVHWFramesContext*)inlink_overlay->hw_frames_ctx->data;
+ FilterLink *inl = ff_filter_link(inlink);
+ FilterLink *inl_overlay = ff_filter_link(inlink_overlay);
+ AVHWFramesContext *main_fc = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ AVHWFramesContext *overlay_fc = (AVHWFramesContext*)inl_overlay->hw_frames_ctx->data;
+
+ if (main_fc->sw_format != overlay_fc->sw_format) {
+ av_log(avctx, AV_LOG_ERROR, "Mismatching sw formats!\n");
@@ -324,7 +326,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
err = ff_vk_filter_config_output(outlink);
if (err < 0)
@@ -261,6 +326,11 @@ static int overlay_vulkan_config_output(
@@ -262,6 +329,11 @@ static int overlay_vulkan_config_output(
if (err < 0)
return err;
@@ -336,7 +338,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
return ff_framesync_configure(&s->fs);
}
@@ -288,7 +358,9 @@ static void overlay_vulkan_uninit(AVFilt
@@ -289,7 +361,9 @@ static void overlay_vulkan_uninit(AVFilt
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
@@ -346,7 +348,7 @@ Index: FFmpeg/libavfilter/vf_overlay_vulkan.c
if (s->sampler)
vk->DestroySampler(vkctx->hwctx->act_dev, s->sampler,
@@ -305,6 +377,14 @@ static void overlay_vulkan_uninit(AVFilt
@@ -306,6 +380,14 @@ static void overlay_vulkan_uninit(AVFilt
static const AVOption overlay_vulkan_options[] = {
{ "x", "Set horizontal offset", OFFSET(overlay_x), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, .flags = FLAGS },
{ "y", "Set vertical offset", OFFSET(overlay_y), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, .flags = FLAGS },
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@ Index: FFmpeg/libswscale/swscale_unscaled.c
===================================================================
--- FFmpeg.orig/libswscale/swscale_unscaled.c
+++ FFmpeg/libswscale/swscale_unscaled.c
@@ -352,7 +352,7 @@ static int planar8ToP01xleWrapper(SwsCon
@@ -396,7 +396,7 @@ static int planar8ToP01xleWrapper(SwsCon
const uint8_t *tsrc0 = src[0];
for (x = c->srcW; x > 0; x--) {
t = *tsrc0++;
@@ -11,7 +11,7 @@ Index: FFmpeg/libswscale/swscale_unscaled.c
}
src[0] += srcStride[0];
dstY += dstStride[0] / 2;
@@ -363,9 +363,9 @@ static int planar8ToP01xleWrapper(SwsCon
@@ -407,9 +407,9 @@ static int planar8ToP01xleWrapper(SwsCon
const uint8_t *tsrc2 = src[2];
for (x = c->srcW / 2; x > 0; x--) {
t = *tsrc1++;
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/videotoolbox.c
===================================================================
--- FFmpeg.orig/libavcodec/videotoolbox.c
+++ FFmpeg/libavcodec/videotoolbox.c
@@ -812,9 +812,7 @@ static CFDictionaryRef videotoolbox_deco
@@ -813,9 +813,7 @@ static CFDictionaryRef videotoolbox_deco
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(config_info,
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -3821,6 +3821,7 @@ boxblur_opencl_filter_deps="opencl gpl"
@@ -3863,6 +3863,7 @@ boxblur_opencl_filter_deps="opencl gpl"
bs2b_filter_deps="libbs2b"
bwdif_cuda_filter_deps="ffnvcodec"
bwdif_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
@@ -14,7 +14,7 @@ Index: FFmpeg/libavfilter/Makefile
===================================================================
--- FFmpeg.orig/libavfilter/Makefile
+++ FFmpeg/libavfilter/Makefile
@@ -218,6 +218,10 @@ OBJS-$(CONFIG_BOXBLUR_OPENCL_FILTER)
@@ -219,6 +219,10 @@ OBJS-$(CONFIG_BOXBLUR_OPENCL_FILTER)
OBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o bwdifdsp.o yadif_common.o
OBJS-$(CONFIG_BWDIF_CUDA_FILTER) += vf_bwdif_cuda.o vf_bwdif_cuda.ptx.o \
yadif_common.o
@@ -317,7 +317,7 @@ Index: FFmpeg/libavfilter/vf_bwdif_videotoolbox.m
===================================================================
--- /dev/null
+++ FFmpeg/libavfilter/vf_bwdif_videotoolbox.m
@@ -0,0 +1,445 @@
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2018 Philip Langdale <philipl@overt.org>
+ * 2020 Aman Karmani <aman@tmm1.net>
@@ -340,7 +340,7 @@ Index: FFmpeg/libavfilter/vf_bwdif_videotoolbox.m
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "internal.h"
+#include "filters.h"
+#include "metal/utils.h"
+#include "yadif.h"
+#include "libavutil/avassert.h"
@@ -610,16 +610,17 @@ Index: FFmpeg/libavfilter/vf_bwdif_videotoolbox.m
+
+static int do_config_input(AVFilterLink *inlink) API_AVAILABLE(macos(10.11), ios(8.0))
+{
+ FilterLink *inl = ff_filter_link(inlink);
+ AVFilterContext *ctx = inlink->dst;
+ BWDIFVTContext *s = ctx->priv;
+
+ if (!inlink->hw_frames_ctx) {
+ if (!inl->hw_frames_ctx) {
+ av_log(ctx, AV_LOG_ERROR, "A hardware frames reference is "
+ "required to associate the processing device.\n");
+ return AVERROR(EINVAL);
+ }
+
+ s->input_frames_ref = av_buffer_ref(inlink->hw_frames_ctx);
+ s->input_frames_ref = av_buffer_ref(inl->hw_frames_ctx);
+ if (!s->input_frames_ref) {
+ av_log(ctx, AV_LOG_ERROR, "A input frames reference create "
+ "failed.\n");
@@ -643,9 +644,11 @@ Index: FFmpeg/libavfilter/vf_bwdif_videotoolbox.m
+
+static int do_config_output(AVFilterLink *link) API_AVAILABLE(macos(10.11), ios(8.0))
+{
+ FilterLink *outl = ff_filter_link(link);
+ AVHWFramesContext *output_frames, *input_frames;
+ AVFilterContext *ctx = link->src;
+ AVFilterLink *inlink = link->src->inputs[0];
+ FilterLink *inl = ff_filter_link(inlink);
+ BWDIFVTContext *s = ctx->priv;
+ YADIFContext *y = &s->yadif;
+ int ret = 0;
@@ -658,16 +661,16 @@ Index: FFmpeg/libavfilter/vf_bwdif_videotoolbox.m
+ return AVERROR(ENOMEM);
+ }
+
+ link->hw_frames_ctx = av_hwframe_ctx_alloc(s->device_ref);
+ if (!link->hw_frames_ctx) {
+ outl->hw_frames_ctx = av_hwframe_ctx_alloc(s->device_ref);
+ if (!outl->hw_frames_ctx) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to create HW frame context "
+ "for output.\n");
+ ret = AVERROR(ENOMEM);
+ goto exit;
+ }
+
+ input_frames = (AVHWFramesContext*)inlink->hw_frames_ctx->data;
+ output_frames = (AVHWFramesContext*)link->hw_frames_ctx->data;
+ input_frames = (AVHWFramesContext*)inl->hw_frames_ctx->data;
+ output_frames = (AVHWFramesContext*)outl->hw_frames_ctx->data;
+
+ output_frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
+ output_frames->sw_format = s->input_frames->sw_format;
@@ -679,7 +682,7 @@ Index: FFmpeg/libavfilter/vf_bwdif_videotoolbox.m
+ if (ret < 0)
+ goto exit;
+
+ ret = av_hwframe_ctx_init(link->hw_frames_ctx);
+ ret = av_hwframe_ctx_init(outl->hw_frames_ctx);
+ if (ret < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to initialise VideoToolbox frame "
+ "context for output: %d\n", ret);
@@ -1,8 +1,8 @@
Index: FFmpeg/libavcodec/hevcdec.c
Index: FFmpeg/libavcodec/hevc/hevcdec.c
===================================================================
--- FFmpeg.orig/libavcodec/hevcdec.c
+++ FFmpeg/libavcodec/hevcdec.c
@@ -533,6 +533,9 @@ static enum AVPixelFormat get_format(HEV
--- FFmpeg.orig/libavcodec/hevc/hevcdec.c
+++ FFmpeg/libavcodec/hevc/hevcdec.c
@@ -660,6 +660,9 @@ static enum AVPixelFormat get_format(HEV
#if CONFIG_HEVC_NVDEC_HWACCEL
*fmt++ = AV_PIX_FMT_CUDA;
#endif
@@ -12,7 +12,7 @@ Index: FFmpeg/libavcodec/hevcdec.c
break;
case AV_PIX_FMT_YUV422P12:
#if CONFIG_HEVC_DXVA2_HWACCEL
@@ -548,6 +551,9 @@ static enum AVPixelFormat get_format(HEV
@@ -675,6 +678,9 @@ static enum AVPixelFormat get_format(HEV
#if CONFIG_HEVC_VULKAN_HWACCEL
*fmt++ = AV_PIX_FMT_VULKAN;
#endif
@@ -1,79 +0,0 @@
Index: FFmpeg/libavcodec/libx265.c
===================================================================
--- FFmpeg.orig/libavcodec/libx265.c
+++ FFmpeg/libavcodec/libx265.c
@@ -646,7 +646,13 @@ static int libx265_encode_frame(AVCodecC
{
libx265Context *ctx = avctx->priv_data;
x265_picture x265pic;
- x265_picture x265pic_out = { 0 };
+#if (X265_BUILD >= 210) && (X265_BUILD < 213)
+ x265_picture x265pic_layers_out[MAX_SCALABLE_LAYERS];
+ x265_picture* x265pic_lyrptr_out[MAX_SCALABLE_LAYERS];
+#else
+ x265_picture x265pic_solo_out = { 0 };
+#endif
+ x265_picture* x265pic_out;
x265_nal *nal;
x265_sei *sei;
uint8_t *dst;
@@ -764,8 +770,16 @@ static int libx265_encode_frame(AVCodecC
}
}
+#if (X265_BUILD >= 210) && (X265_BUILD < 213)
+ for (i = 0; i < MAX_SCALABLE_LAYERS; i++)
+ x265pic_lyrptr_out[i] = &x265pic_layers_out[i];
+
+ ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,
+ pic ? &x265pic : NULL, x265pic_lyrptr_out);
+#else
ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal,
- pic ? &x265pic : NULL, &x265pic_out);
+ pic ? &x265pic : NULL, &x265pic_solo_out);
+#endif
for (i = 0; i < sei->numPayloads; i++)
av_free(sei->payloads[i].payload);
@@ -795,10 +809,16 @@ static int libx265_encode_frame(AVCodecC
pkt->flags |= AV_PKT_FLAG_KEY;
}
- pkt->pts = x265pic_out.pts;
- pkt->dts = x265pic_out.dts;
+#if (X265_BUILD >= 210) && (X265_BUILD < 213)
+ x265pic_out = x265pic_lyrptr_out[0];
+#else
+ x265pic_out = &x265pic_solo_out;
+#endif
+
+ pkt->pts = x265pic_out->pts;
+ pkt->dts = x265pic_out->dts;
- switch (x265pic_out.sliceType) {
+ switch (x265pic_out->sliceType) {
case X265_TYPE_IDR:
case X265_TYPE_I:
pict_type = AV_PICTURE_TYPE_I;
@@ -816,16 +836,16 @@ static int libx265_encode_frame(AVCodecC
}
#if X265_BUILD >= 130
- if (x265pic_out.sliceType == X265_TYPE_B)
+ if (x265pic_out->sliceType == X265_TYPE_B)
#else
- if (x265pic_out.frameData.sliceType == 'b')
+ if (x265pic_out->frameData.sliceType == 'b')
#endif
pkt->flags |= AV_PKT_FLAG_DISPOSABLE;
- ff_side_data_set_encoder_stats(pkt, x265pic_out.frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type);
+ ff_side_data_set_encoder_stats(pkt, x265pic_out->frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type);
- if (x265pic_out.userData) {
- int idx = (int)(intptr_t)x265pic_out.userData - 1;
+ if (x265pic_out->userData) {
+ int idx = (int)(intptr_t)x265pic_out->userData - 1;
ReorderedData *rd = &ctx->rd[idx];
pkt->duration = rd->duration;
@@ -2,7 +2,7 @@ Index: FFmpeg/fftools/ffmpeg_filter.c
===================================================================
--- FFmpeg.orig/fftools/ffmpeg_filter.c
+++ FFmpeg/fftools/ffmpeg_filter.c
@@ -2458,7 +2458,8 @@ static void sub2video_heartbeat(InputFil
@@ -2651,7 +2651,8 @@ static void sub2video_heartbeat(InputFil
or if we need to initialize the system, update the
overlayed subpicture and its start/end times */
sub2video_update(ifp, pts2 + 1, NULL);
@@ -2,7 +2,7 @@ Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -2528,6 +2528,7 @@ HAVE_LIST="
@@ -2533,6 +2533,7 @@ HAVE_LIST="
xmllint
zlib_gzip
openvino2
@@ -10,7 +10,7 @@ Index: FFmpeg/configure
"
# options emitted with CONFIG_ prefix but not available on the command line
@@ -6947,6 +6948,9 @@ elif enabled libvpl; then
@@ -6989,6 +6990,9 @@ elif enabled libvpl; then
die "ERROR: libvpl >= 2.6 not found"
add_cflags -DMFX_DEPRECATED_OFF
check_type "vpl/mfxdefs.h vpl/mfxvideo.h" "struct mfxConfigInterface"
@@ -24,7 +24,7 @@ Index: FFmpeg/libavcodec/qsv.c
===================================================================
--- FFmpeg.orig/libavcodec/qsv.c
+++ FFmpeg/libavcodec/qsv.c
@@ -496,6 +496,17 @@ static int ff_qsv_set_display_handle(AVC
@@ -499,6 +499,17 @@ static int ff_qsv_set_display_handle(AVC
}
#endif //AVCODEC_QSV_LINUX_SESSION_HANDLE
@@ -42,7 +42,7 @@ Index: FFmpeg/libavcodec/qsv.c
#if QSV_ONEVPL
static int qsv_new_mfx_loader(AVCodecContext *avctx,
mfxIMPL implementation,
@@ -636,6 +647,16 @@ static int qsv_create_mfx_session(AVCode
@@ -639,6 +650,16 @@ static int qsv_create_mfx_session(AVCode
return 0;
fail:
@@ -59,7 +59,7 @@ Index: FFmpeg/libavcodec/qsv.c
if (!*ploader && loader)
MFXUnload(loader);
@@ -651,6 +672,20 @@ static int qsv_create_mfx_session(AVCode
@@ -654,6 +675,20 @@ static int qsv_create_mfx_session(AVCode
mfxSession *psession,
void **ploader)
{
@@ -106,7 +106,7 @@ Index: FFmpeg/libavfilter/qsvvpp.c
===================================================================
--- FFmpeg.orig/libavfilter/qsvvpp.c
+++ FFmpeg/libavfilter/qsvvpp.c
@@ -1067,6 +1067,16 @@ int ff_qsvvpp_filter_frame(QSVVPPContext
@@ -1065,6 +1065,16 @@ int ff_qsvvpp_filter_frame(QSVVPPContext
return 0;
}
@@ -123,7 +123,7 @@ Index: FFmpeg/libavfilter/qsvvpp.c
#if QSV_ONEVPL
int ff_qsvvpp_create_mfx_session(void *ctx,
@@ -1110,6 +1120,15 @@ int ff_qsvvpp_create_mfx_session(void *c
@@ -1108,6 +1118,15 @@ int ff_qsvvpp_create_mfx_session(void *c
impl_idx++;
}
@@ -139,7 +139,7 @@ Index: FFmpeg/libavfilter/qsvvpp.c
if (sts < 0)
return ff_qsvvpp_print_error(ctx, sts,
"Error creating a MFX session");
@@ -1127,6 +1146,19 @@ int ff_qsvvpp_create_mfx_session(void *c
@@ -1125,6 +1144,19 @@ int ff_qsvvpp_create_mfx_session(void *c
mfxVersion *pver,
mfxSession *psession)
{
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
===================================================================
--- FFmpeg.orig/libavcodec/videotoolboxenc.c
+++ FFmpeg/libavcodec/videotoolboxenc.c
@@ -1034,9 +1034,10 @@ static int create_cv_pixel_buffer_info(A
@@ -1035,9 +1035,10 @@ static int create_cv_pixel_buffer_info(A
CFNumberRef width_num = NULL;
CFNumberRef height_num = NULL;
CFMutableDictionaryRef pixel_buffer_info = NULL;
@@ -14,7 +14,7 @@ Index: FFmpeg/libavcodec/videotoolboxenc.c
avctx->color_range,
&cv_color_format,
NULL);
@@ -1687,11 +1688,9 @@ static int vtenc_configure_encoder(AVCod
@@ -1692,11 +1693,9 @@ static int vtenc_configure_encoder(AVCod
kCFBooleanTrue);
}
@@ -1,89 +1,3 @@
Index: FFmpeg/libavcodec/bsf/h265_metadata.c
===================================================================
--- FFmpeg.orig/libavcodec/bsf/h265_metadata.c
+++ FFmpeg/libavcodec/bsf/h265_metadata.c
@@ -27,6 +27,7 @@
#include "h2645data.h"
#include "hevc.h"
#include "h265_profile_level.h"
+#include "itut35.h"
enum {
LEVEL_UNSET = -2,
@@ -62,6 +63,8 @@ typedef struct H265MetadataContext {
int level;
int level_guess;
int level_warned;
+ int remove_dovi;
+ int remove_hdr10plus;
} H265MetadataContext;
@@ -385,6 +388,38 @@ static int h265_metadata_update_fragment
if (err < 0)
return err;
}
+ if (ctx->remove_hdr10plus) {
+ // This implementation is not strictly correct as it does not decode the entire NAL.
+ // There could be multiple SEIs packed within a single NAL, and some of them may not be HDR10+ metadata.
+ // The current implementation simply removes the entire NAL without further inspection.
+ if (au->units[i].type == HEVC_NAL_SEI_PREFIX && au->units[i].data_size > 8 * sizeof(uint8_t)) {
+ uint8_t *nal_sei = au->units[i].data;
+ // This Matches ITU-T T.35 SMPTE ST 2094-40
+ if (nal_sei[0] == 0x4E && nal_sei[1] == 0x01 && nal_sei[2] == 0x04) {
+ if (nal_sei[4] == ITU_T_T35_COUNTRY_CODE_US && nal_sei[6] == ITU_T_T35_PROVIDER_CODE_SMTPE) {
+ // identifier for HDR10+
+ const uint8_t smpte2094_40_provider_oriented_code = 0x01;
+ const uint8_t smpte2094_40_application_identifier = 0x04;
+ if (nal_sei[8] == smpte2094_40_provider_oriented_code && nal_sei[9] == smpte2094_40_application_identifier) {
+ av_log(bsf, AV_LOG_DEBUG, "Found HDR10+ metadata, removing NAL\n");
+ ff_cbs_delete_unit(au, i);
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ if (ctx->remove_dovi && au->nb_units) {
+ if (au->units[au->nb_units - 1].type == HEVC_NAL_UNSPEC62) { // Dolby Vision RPU
+ ff_cbs_delete_unit(au, au->nb_units - 1);
+ av_log(bsf, AV_LOG_DEBUG, "Removing Dolby Vision RPU\n");
+ }
+ if (au->units[au->nb_units - 1].type == HEVC_NAL_UNSPEC63) { // Dolby Vision EL
+ ff_cbs_delete_unit(au, au->nb_units - 1);
+ av_log(bsf, AV_LOG_DEBUG, "Removing Dolby Vision EL\n");
+ }
}
return 0;
@@ -399,6 +434,11 @@ static const CBSBSFType h265_metadata_ty
static int h265_metadata_init(AVBSFContext *bsf)
{
+ if (((H265MetadataContext *)bsf->priv_data)->remove_dovi) {
+ av_packet_side_data_remove(bsf->par_out->coded_side_data,
+ &bsf->par_out->nb_coded_side_data,
+ AV_PKT_DATA_DOVI_CONF);
+ }
return ff_cbs_bsf_generic_init(bsf, &h265_metadata_type);
}
@@ -478,6 +518,13 @@ static const AVOption h265_metadata_opti
{ LEVEL("8.5", 255) },
#undef LEVEL
+ { "remove_dovi", "Remove Dolby Vision EL and RPU",
+ OFFSET(remove_dovi), AV_OPT_TYPE_BOOL,
+ { .i64 = 0 }, 0, 1, FLAGS },
+ { "remove_hdr10plus", "Remove NALs including HDR10+ metadata",
+ OFFSET(remove_hdr10plus), AV_OPT_TYPE_BOOL,
+ { .i64 = 0 }, 0, 1, FLAGS },
+
{ NULL }
};
Index: FFmpeg/libavcodec/bsf/av1_metadata.c
===================================================================
--- FFmpeg.orig/libavcodec/bsf/av1_metadata.c
@@ -184,3 +98,89 @@ Index: FFmpeg/libavcodec/bsf/av1_metadata.c
{ NULL }
};
Index: FFmpeg/libavcodec/bsf/h265_metadata.c
===================================================================
--- FFmpeg.orig/libavcodec/bsf/h265_metadata.c
+++ FFmpeg/libavcodec/bsf/h265_metadata.c
@@ -26,6 +26,7 @@
#include "cbs_h265.h"
#include "h2645data.h"
#include "h265_profile_level.h"
+#include "itut35.h"
#include "hevc/hevc.h"
@@ -65,6 +66,8 @@ typedef struct H265MetadataContext {
int level;
int level_guess;
int level_warned;
+ int remove_dovi;
+ int remove_hdr10plus;
} H265MetadataContext;
@@ -475,6 +478,38 @@ static int h265_metadata_update_fragment
if (err < 0)
return err;
}
+ if (ctx->remove_hdr10plus) {
+ // This implementation is not strictly correct as it does not decode the entire NAL.
+ // There could be multiple SEIs packed within a single NAL, and some of them may not be HDR10+ metadata.
+ // The current implementation simply removes the entire NAL without further inspection.
+ if (au->units[i].type == HEVC_NAL_SEI_PREFIX && au->units[i].data_size > 8 * sizeof(uint8_t)) {
+ uint8_t *nal_sei = au->units[i].data;
+ // This Matches ITU-T T.35 SMPTE ST 2094-40
+ if (nal_sei[0] == 0x4E && nal_sei[1] == 0x01 && nal_sei[2] == 0x04) {
+ if (nal_sei[4] == ITU_T_T35_COUNTRY_CODE_US && nal_sei[6] == ITU_T_T35_PROVIDER_CODE_SMTPE) {
+ // identifier for HDR10+
+ const uint8_t smpte2094_40_provider_oriented_code = 0x01;
+ const uint8_t smpte2094_40_application_identifier = 0x04;
+ if (nal_sei[8] == smpte2094_40_provider_oriented_code && nal_sei[9] == smpte2094_40_application_identifier) {
+ av_log(bsf, AV_LOG_DEBUG, "Found HDR10+ metadata, removing NAL\n");
+ ff_cbs_delete_unit(au, i);
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ if (ctx->remove_dovi && au->nb_units) {
+ if (au->units[au->nb_units - 1].type == HEVC_NAL_UNSPEC62) { // Dolby Vision RPU
+ ff_cbs_delete_unit(au, au->nb_units - 1);
+ av_log(bsf, AV_LOG_DEBUG, "Removing Dolby Vision RPU\n");
+ }
+ if (au->units[au->nb_units - 1].type == HEVC_NAL_UNSPEC63) { // Dolby Vision EL
+ ff_cbs_delete_unit(au, au->nb_units - 1);
+ av_log(bsf, AV_LOG_DEBUG, "Removing Dolby Vision EL\n");
+ }
}
return 0;
@@ -489,6 +524,11 @@ static const CBSBSFType h265_metadata_ty
static int h265_metadata_init(AVBSFContext *bsf)
{
+ if (((H265MetadataContext *)bsf->priv_data)->remove_dovi) {
+ av_packet_side_data_remove(bsf->par_out->coded_side_data,
+ &bsf->par_out->nb_coded_side_data,
+ AV_PKT_DATA_DOVI_CONF);
+ }
return ff_cbs_bsf_generic_init(bsf, &h265_metadata_type);
}
@@ -574,6 +614,13 @@ static const AVOption h265_metadata_opti
{ LEVEL("8.5", 255) },
#undef LEVEL
+ { "remove_dovi", "Remove Dolby Vision EL and RPU",
+ OFFSET(remove_dovi), AV_OPT_TYPE_BOOL,
+ { .i64 = 0 }, 0, 1, FLAGS },
+ { "remove_hdr10plus", "Remove NALs including HDR10+ metadata",
+ OFFSET(remove_hdr10plus), AV_OPT_TYPE_BOOL,
+ { .i64 = 0 }, 0, 1, FLAGS },
+
{ NULL }
};
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/audiotoolboxenc.c
===================================================================
--- FFmpeg.orig/libavcodec/audiotoolboxenc.c
+++ FFmpeg/libavcodec/audiotoolboxenc.c
@@ -235,8 +235,8 @@ static int get_aac_tag(const AVChannelLa
@@ -236,8 +236,8 @@ static int get_aac_tag(const AVChannelLa
{ AV_CHANNEL_LAYOUT_6POINT0, kAudioChannelLayoutTag_AAC_6_0 },
{ AV_CHANNEL_LAYOUT_6POINT1, kAudioChannelLayoutTag_AAC_6_1 },
{ AV_CHANNEL_LAYOUT_7POINT0, kAudioChannelLayoutTag_AAC_7_0 },
@@ -13,7 +13,7 @@ Index: FFmpeg/libavcodec/audiotoolboxenc.c
};
int i;
@@ -633,7 +633,7 @@ static const AVOption options[] = {
@@ -635,7 +635,7 @@ static const AVOption options[] = {
.version = LIBAVUTIL_VERSION_INT, \
};
@@ -22,7 +22,7 @@ Index: FFmpeg/libavcodec/audiotoolboxenc.c
FFAT_ENC_CLASS(NAME) \
const FFCodec ff_##NAME##_at_encoder = { \
.p.name = #NAME "_at", \
@@ -650,9 +650,10 @@ static const AVOption options[] = {
@@ -652,9 +652,10 @@ static const AVOption options[] = {
AV_CODEC_CAP_ENCODER_FLUSH CAPS, \
.p.ch_layouts = CH_LAYOUTS, \
.p.sample_fmts = (const enum AVSampleFormat[]) { \
@@ -34,7 +34,7 @@ Index: FFmpeg/libavcodec/audiotoolboxenc.c
.p.profiles = PROFILES, \
.p.wrapper_name = "at", \
};
@@ -667,15 +668,25 @@ static const AVChannelLayout aac_at_ch_l
@@ -669,15 +670,25 @@ static const AVChannelLayout aac_at_ch_l
AV_CHANNEL_LAYOUT_6POINT0,
AV_CHANNEL_LAYOUT_6POINT1,
AV_CHANNEL_LAYOUT_7POINT0,
@@ -2,7 +2,7 @@ Index: FFmpeg/libavcodec/videotoolbox.c
===================================================================
--- FFmpeg.orig/libavcodec/videotoolbox.c
+++ FFmpeg/libavcodec/videotoolbox.c
@@ -786,11 +786,6 @@ static CFDictionaryRef videotoolbox_buff
@@ -787,11 +787,6 @@ static CFDictionaryRef videotoolbox_buff
CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
@@ -2,7 +2,7 @@ Index: FFmpeg/libavfilter/qsvvpp.c
===================================================================
--- FFmpeg.orig/libavfilter/qsvvpp.c
+++ FFmpeg/libavfilter/qsvvpp.c
@@ -69,6 +69,36 @@ static const struct {
@@ -70,6 +70,36 @@ static const struct {
#endif
};
@@ -44,7 +44,7 @@ Index: FFmpeg/libavfilter/vf_hwupload.c
--- FFmpeg.orig/libavfilter/vf_hwupload.c
+++ FFmpeg/libavfilter/vf_hwupload.c
@@ -32,6 +32,10 @@
#include "internal.h"
#include "formats.h"
#include "video.h"
+#if CONFIG_QSVVPP
@@ -54,7 +54,7 @@ Index: FFmpeg/libavfilter/vf_hwupload.c
typedef struct HWUploadContext {
const AVClass *class;
@@ -163,6 +167,15 @@ static int hwupload_config_output(AVFilt
@@ -165,6 +169,15 @@ static int hwupload_config_output(AVFilt
ctx->hwframes->user_opaque = &texDesc;
#endif
@@ -1,8 +1,37 @@
Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -2467,6 +2467,7 @@ TYPES_LIST="
kCMVideoCodecType_HEVC
kCMVideoCodecType_HEVCWithAlpha
kCMVideoCodecType_VP9
+ kCMVideoCodecType_AV1
kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange
kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange
@@ -3176,6 +3177,8 @@ av1_vaapi_hwaccel_deps="vaapi VADecPictu
av1_vaapi_hwaccel_select="av1_decoder"
av1_vdpau_hwaccel_deps="vdpau VdpPictureInfoAV1"
av1_vdpau_hwaccel_select="av1_decoder"
+av1_videotoolbox_hwaccel_deps="videotoolbox"
+av1_videotoolbox_hwaccel_select="av1_decoder"
av1_vulkan_hwaccel_deps="vulkan"
av1_vulkan_hwaccel_select="av1_decoder"
h263_vaapi_hwaccel_deps="vaapi"
@@ -6744,6 +6747,7 @@ enabled videotoolbox && {
check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVC "-framework CoreMedia"
check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVCWithAlpha "-framework CoreMedia"
check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_VP9 "-framework CoreMedia"
+ check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_AV1 "-framework CoreMedia"
check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange "-framework CoreVideo"
check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
Index: FFmpeg/libavcodec/Makefile
===================================================================
--- FFmpeg.orig/libavcodec/Makefile
+++ FFmpeg/libavcodec/Makefile
@@ -1010,6 +1010,7 @@ OBJS-$(CONFIG_AV1_D3D12VA_HWACCEL)
@@ -1018,6 +1018,7 @@ OBJS-$(CONFIG_AV1_D3D12VA_HWACCEL)
OBJS-$(CONFIG_AV1_NVDEC_HWACCEL) += nvdec_av1.o
OBJS-$(CONFIG_AV1_VAAPI_HWACCEL) += vaapi_av1.o
OBJS-$(CONFIG_AV1_VDPAU_HWACCEL) += vdpau_av1.o
@@ -14,7 +43,7 @@ Index: FFmpeg/libavcodec/av1dec.c
===================================================================
--- FFmpeg.orig/libavcodec/av1dec.c
+++ FFmpeg/libavcodec/av1dec.c
@@ -540,6 +540,7 @@ static int get_pixel_format(AVCodecConte
@@ -541,6 +541,7 @@ static int get_pixel_format(AVCodecConte
CONFIG_AV1_NVDEC_HWACCEL + \
CONFIG_AV1_VAAPI_HWACCEL + \
CONFIG_AV1_VDPAU_HWACCEL + \
@@ -22,7 +51,7 @@ Index: FFmpeg/libavcodec/av1dec.c
CONFIG_AV1_VULKAN_HWACCEL)
enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;
@@ -567,6 +568,9 @@ static int get_pixel_format(AVCodecConte
@@ -568,6 +569,9 @@ static int get_pixel_format(AVCodecConte
#if CONFIG_AV1_VDPAU_HWACCEL
*fmtp++ = AV_PIX_FMT_VDPAU;
#endif
@@ -32,7 +61,7 @@ Index: FFmpeg/libavcodec/av1dec.c
#if CONFIG_AV1_VULKAN_HWACCEL
*fmtp++ = AV_PIX_FMT_VULKAN;
#endif
@@ -591,6 +595,9 @@ static int get_pixel_format(AVCodecConte
@@ -592,6 +596,9 @@ static int get_pixel_format(AVCodecConte
#if CONFIG_AV1_VDPAU_HWACCEL
*fmtp++ = AV_PIX_FMT_VDPAU;
#endif
@@ -42,7 +71,7 @@ Index: FFmpeg/libavcodec/av1dec.c
#if CONFIG_AV1_VULKAN_HWACCEL
*fmtp++ = AV_PIX_FMT_VULKAN;
#endif
@@ -1479,6 +1486,10 @@ static int av1_receive_frame_internal(AV
@@ -1439,6 +1446,10 @@ static int av1_receive_frame_internal(AV
if (raw_tile_group && (s->tile_num == raw_tile_group->tg_end + 1)) {
int show_frame = s->raw_frame_header->show_frame;
@@ -50,18 +79,19 @@ Index: FFmpeg/libavcodec/av1dec.c
+ // OBUs have been processed for this current frame. (If this
+ // frame gets output, we set nb_unit to this value later too.)
+ s->nb_unit = i + 1;
if (avctx->hwaccel && s->cur_frame.f->buf[0]) {
if (avctx->hwaccel && s->cur_frame.f) {
ret = FF_HW_SIMPLE_CALL(avctx, end_frame);
if (ret < 0) {
@@ -1500,6 +1511,7 @@ static int av1_receive_frame_internal(AV
goto end;
}
}
+ s->start_unit = s->nb_unit;
raw_tile_group = NULL;
@@ -1449,6 +1460,8 @@ static int av1_receive_frame_internal(AV
update_reference_list(avctx);
+ // Set start_unit to indicate the first OBU of the next frame.
+ s->start_unit = s->nb_unit;
raw_tile_group = NULL;
s->raw_frame_header = NULL;
if (show_frame) {
@@ -1519,7 +1531,7 @@ end:
@@ -1478,7 +1491,7 @@ end:
s->raw_frame_header = NULL;
av_packet_unref(s->pkt);
ff_cbs_fragment_reset(&s->current_obu);
@@ -70,7 +100,7 @@ Index: FFmpeg/libavcodec/av1dec.c
}
if (!ret && !frame->buf[0])
ret = AVERROR(EAGAIN);
@@ -1546,7 +1558,7 @@ static int av1_receive_frame(AVCodecCont
@@ -1505,7 +1518,7 @@ static int av1_receive_frame(AVCodecCont
return ret;
}
@@ -79,7 +109,7 @@ Index: FFmpeg/libavcodec/av1dec.c
av_log(avctx, AV_LOG_DEBUG, "Total OBUs on this packet: %d.\n",
s->current_obu.nb_units);
}
@@ -1567,7 +1579,7 @@ static void av1_decode_flush(AVCodecCont
@@ -1526,7 +1539,7 @@ static void av1_decode_flush(AVCodecCont
av1_frame_unref(&s->cur_frame);
s->operating_point_idc = 0;
@@ -88,7 +118,7 @@ Index: FFmpeg/libavcodec/av1dec.c
s->raw_frame_header = NULL;
s->raw_seq = NULL;
s->cll = NULL;
@@ -1633,6 +1645,9 @@ const FFCodec ff_av1_decoder = {
@@ -1594,6 +1607,9 @@ const FFCodec ff_av1_decoder = {
#if CONFIG_AV1_VDPAU_HWACCEL
HWACCEL_VDPAU(av1),
#endif
@@ -98,6 +128,20 @@ Index: FFmpeg/libavcodec/av1dec.c
#if CONFIG_AV1_VULKAN_HWACCEL
HWACCEL_VULKAN(av1),
#endif
Index: FFmpeg/libavcodec/av1dec.h
===================================================================
--- FFmpeg.orig/libavcodec/av1dec.h
+++ FFmpeg/libavcodec/av1dec.h
@@ -114,7 +114,8 @@ typedef struct AV1DecContext {
AV1Frame ref[AV1_NUM_REF_FRAMES];
AV1Frame cur_frame;
- int nb_unit;
+ int nb_unit; ///< The index of the next OBU to be processed.
+ int start_unit; ///< The index of the first OBU of the current frame.
// AVOptions
int operating_point;
Index: FFmpeg/libavcodec/hwaccels.h
===================================================================
--- FFmpeg.orig/libavcodec/hwaccels.h
@@ -110,37 +154,82 @@ Index: FFmpeg/libavcodec/hwaccels.h
extern const struct FFHWAccel ff_av1_vulkan_hwaccel;
extern const struct FFHWAccel ff_h263_vaapi_hwaccel;
extern const struct FFHWAccel ff_h263_videotoolbox_hwaccel;
Index: FFmpeg/libavcodec/vt_internal.h
Index: FFmpeg/libavcodec/videotoolbox.c
===================================================================
--- FFmpeg.orig/libavcodec/vt_internal.h
+++ FFmpeg/libavcodec/vt_internal.h
@@ -56,6 +56,9 @@ int ff_videotoolbox_frame_params(AVCodec
int ff_videotoolbox_buffer_copy(VTContext *vtctx,
const uint8_t *buffer,
uint32_t size);
--- FFmpeg.orig/libavcodec/videotoolbox.c
+++ FFmpeg/libavcodec/videotoolbox.c
@@ -56,6 +56,10 @@ enum { kCMVideoCodecType_HEVC = 'hvc1' }
enum { kCMVideoCodecType_VP9 = 'vp09' };
#endif
+#if !HAVE_KCMVIDEOCODECTYPE_AV1
+enum { kCMVideoCodecType_AV1 = 'av01' };
+#endif
+
#define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
typedef struct VTHWFrame {
@@ -92,6 +96,26 @@ int ff_videotoolbox_buffer_copy(VTContex
return 0;
}
+int ff_videotoolbox_buffer_append(VTContext *vtctx,
+ const uint8_t *buffer,
+ uint32_t size);
int ff_videotoolbox_uninit(AVCodecContext *avctx);
int ff_videotoolbox_h264_start_frame(AVCodecContext *avctx,
const uint8_t *buffer,
@@ -64,6 +67,7 @@ int ff_videotoolbox_h264_decode_slice(AV
const uint8_t *buffer,
uint32_t size);
int ff_videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame);
+CFDataRef ff_videotoolbox_av1c_extradata_create(AVCodecContext *avctx);
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx);
CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx);
CFDataRef ff_videotoolbox_vpcc_extradata_create(AVCodecContext *avctx);
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ void *tmp;
+
+ tmp = av_fast_realloc(vtctx->bitstream,
+ &vtctx->allocated_size,
+ vtctx->bitstream_size + size);
+
+ if (!tmp)
+ return AVERROR(ENOMEM);
+
+ vtctx->bitstream = tmp;
+ memcpy(vtctx->bitstream + vtctx->bitstream_size, buffer, size);
+ vtctx->bitstream_size += size;
+
+ return 0;
+}
+
static int videotoolbox_postproc_frame(void *avctx, AVFrame *frame)
{
int ret;
@@ -840,6 +864,13 @@ static CFDictionaryRef videotoolbox_deco
CFDictionarySetValue(avc_info, CFSTR("vpcC"), data);
break;
#endif
+#if CONFIG_AV1_VIDEOTOOLBOX_HWACCEL
+ case kCMVideoCodecType_AV1 :
+ data = ff_videotoolbox_av1c_extradata_create(avctx);
+ if (data)
+ CFDictionarySetValue(avc_info, CFSTR("av1C"), data);
+ break;
+#endif
default:
break;
}
@@ -905,6 +936,9 @@ static int videotoolbox_start(AVCodecCon
case AV_CODEC_ID_VP9 :
videotoolbox->cm_codec_type = kCMVideoCodecType_VP9;
break;
+ case AV_CODEC_ID_AV1 :
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AV1;
+ break;
default :
break;
}
Index: FFmpeg/libavcodec/videotoolbox_av1.c
===================================================================
--- /dev/null
+++ FFmpeg/libavcodec/videotoolbox_av1.c
@@ -0,0 +1,104 @@
@@ -0,0 +1,105 @@
+/*
+ * Videotoolbox hardware acceleration for AV1
+ * Copyright (c) 2023 Jan Ekström
+ * Copyright (c) 2024 Ruslan Chernenko
+ * Copyright (c) 2024 Martin Storsjö
+ *
+ * This file is part of FFmpeg.
+ *
@@ -241,112 +330,25 @@ Index: FFmpeg/libavcodec/videotoolbox_av1.c
+ .uninit = ff_videotoolbox_uninit,
+ .priv_data_size = sizeof(VTContext),
+};
Index: FFmpeg/libavcodec/av1dec.h
Index: FFmpeg/libavcodec/vt_internal.h
===================================================================
--- FFmpeg.orig/libavcodec/av1dec.h
+++ FFmpeg/libavcodec/av1dec.h
@@ -108,7 +108,8 @@ typedef struct AV1DecContext {
AV1Frame ref[AV1_NUM_REF_FRAMES];
AV1Frame cur_frame;
- int nb_unit;
+ int nb_unit; ///< The index of the next OBU to be processed.
+ int start_unit; ///< The index of the first OBU of the current frame.
// AVOptions
int operating_point;
Index: FFmpeg/configure
===================================================================
--- FFmpeg.orig/configure
+++ FFmpeg/configure
@@ -2463,6 +2463,7 @@ TYPES_LIST="
kCMVideoCodecType_HEVC
kCMVideoCodecType_HEVCWithAlpha
kCMVideoCodecType_VP9
+ kCMVideoCodecType_AV1
kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange
kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange
@@ -3159,6 +3160,8 @@ av1_vaapi_hwaccel_deps="vaapi VADecPictu
av1_vaapi_hwaccel_select="av1_decoder"
av1_vdpau_hwaccel_deps="vdpau VdpPictureInfoAV1"
av1_vdpau_hwaccel_select="av1_decoder"
+av1_videotoolbox_hwaccel_deps="videotoolbox"
+av1_videotoolbox_hwaccel_select="av1_decoder"
av1_vulkan_hwaccel_deps="vulkan"
av1_vulkan_hwaccel_select="av1_decoder"
h263_vaapi_hwaccel_deps="vaapi"
@@ -6707,6 +6710,7 @@ enabled videotoolbox && {
check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVC "-framework CoreMedia"
check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_HEVCWithAlpha "-framework CoreMedia"
check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_VP9 "-framework CoreMedia"
+ check_func_headers CoreMedia/CMFormatDescription.h kCMVideoCodecType_AV1 "-framework CoreMedia"
check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_422YpCbCr8BiPlanarVideoRange "-framework CoreVideo"
check_func_headers CoreVideo/CVPixelBuffer.h kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange "-framework CoreVideo"
Index: FFmpeg/libavcodec/videotoolbox.c
===================================================================
--- FFmpeg.orig/libavcodec/videotoolbox.c
+++ FFmpeg/libavcodec/videotoolbox.c
@@ -55,6 +55,10 @@ enum { kCMVideoCodecType_HEVC = 'hvc1' }
enum { kCMVideoCodecType_VP9 = 'vp09' };
#endif
+#if !HAVE_KCMVIDEOCODECTYPE_AV1
+enum { kCMVideoCodecType_AV1 = 'av01' };
+#endif
+
#define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
typedef struct VTHWFrame {
@@ -91,6 +95,26 @@ int ff_videotoolbox_buffer_copy(VTContex
return 0;
}
--- FFmpeg.orig/libavcodec/vt_internal.h
+++ FFmpeg/libavcodec/vt_internal.h
@@ -56,6 +56,9 @@ int ff_videotoolbox_frame_params(AVCodec
int ff_videotoolbox_buffer_copy(VTContext *vtctx,
const uint8_t *buffer,
uint32_t size);
+int ff_videotoolbox_buffer_append(VTContext *vtctx,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ void *tmp;
+
+ tmp = av_fast_realloc(vtctx->bitstream,
+ &vtctx->allocated_size,
+ vtctx->bitstream_size + size);
+
+ if (!tmp)
+ return AVERROR(ENOMEM);
+
+ vtctx->bitstream = tmp;
+ memcpy(vtctx->bitstream + vtctx->bitstream_size, buffer, size);
+ vtctx->bitstream_size += (int)size;
+
+ return 0;
+}
+
static int videotoolbox_postproc_frame(void *avctx, AVFrame *frame)
{
int ret;
@@ -839,6 +863,13 @@ static CFDictionaryRef videotoolbox_deco
CFDictionarySetValue(avc_info, CFSTR("vpcC"), data);
break;
#endif
+#if CONFIG_AV1_VIDEOTOOLBOX_HWACCEL
+ case kCMVideoCodecType_AV1 :
+ data = ff_videotoolbox_av1c_extradata_create(avctx);
+ if (data)
+ CFDictionarySetValue(avc_info, CFSTR("av1C"), data);
+ break;
+#endif
default:
break;
}
@@ -904,6 +935,9 @@ static int videotoolbox_start(AVCodecCon
case AV_CODEC_ID_VP9 :
videotoolbox->cm_codec_type = kCMVideoCodecType_VP9;
break;
+ case AV_CODEC_ID_AV1 :
+ videotoolbox->cm_codec_type = kCMVideoCodecType_AV1;
+ break;
default :
break;
}
+ uint32_t size);
int ff_videotoolbox_uninit(AVCodecContext *avctx);
int ff_videotoolbox_h264_start_frame(AVCodecContext *avctx,
const uint8_t *buffer,
@@ -64,6 +67,7 @@ int ff_videotoolbox_h264_decode_slice(AV
const uint8_t *buffer,
uint32_t size);
int ff_videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame);
+CFDataRef ff_videotoolbox_av1c_extradata_create(AVCodecContext *avctx);
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx);
CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx);
CFDataRef ff_videotoolbox_vpcc_extradata_create(AVCodecContext *avctx);
@@ -2,7 +2,7 @@ Index: FFmpeg/libavformat/assenc.c
===================================================================
--- FFmpeg.orig/libavformat/assenc.c
+++ FFmpeg/libavformat/assenc.c
@@ -67,7 +67,8 @@ static int write_header(AVFormatContext
@@ -68,7 +68,8 @@ static int write_header(AVFormatContext
ass->trailer = trailer;
}
@@ -35,7 +35,7 @@ Index: FFmpeg/libavutil/hwcontext_vaapi.c
return AVERROR(ENOSYS);
}
@@ -446,6 +453,7 @@ static int vaapi_device_init(AVHWDeviceC
@@ -438,6 +445,7 @@ static int vaapi_device_init(AVHWDeviceC
av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",
fourcc, av_get_pix_fmt_name(pix_fmt));
ctx->formats[ctx->nb_formats].pix_fmt = pix_fmt;
@@ -43,7 +43,7 @@ Index: FFmpeg/libavutil/hwcontext_vaapi.c
ctx->formats[ctx->nb_formats].image_format = image_list[i];
++ctx->nb_formats;
}
@@ -1022,12 +1030,6 @@ static int vaapi_map_to_memory(AVHWFrame
@@ -1014,12 +1022,6 @@ static int vaapi_map_to_memory(AVHWFrame
{
int err;
@@ -2,7 +2,7 @@ Index: FFmpeg/fftools/ffprobe.c
===================================================================
--- FFmpeg.orig/fftools/ffprobe.c
+++ FFmpeg/fftools/ffprobe.c
@@ -146,6 +146,8 @@ static int show_private_data
@@ -147,6 +147,8 @@ static int show_private_data
#define SHOW_OPTIONAL_FIELDS_ALWAYS 1
static int show_optional_fields = SHOW_OPTIONAL_FIELDS_AUTO;
@@ -11,7 +11,7 @@ Index: FFmpeg/fftools/ffprobe.c
static char *output_format;
static char *stream_specifier;
static char *show_data_hash;
@@ -3086,9 +3088,10 @@ static int read_interval_packets(WriterC
@@ -3108,9 +3110,10 @@ static int read_interval_packets(WriterC
AVFormatContext *fmt_ctx = ifile->fmt_ctx;
AVPacket *pkt = NULL;
AVFrame *frame = NULL;
@@ -23,7 +23,7 @@ Index: FFmpeg/fftools/ffprobe.c
av_log(NULL, AV_LOG_VERBOSE, "Processing read interval ");
log_read_interval(interval, NULL, AV_LOG_VERBOSE);
@@ -3127,12 +3130,51 @@ static int read_interval_packets(WriterC
@@ -3149,12 +3152,51 @@ static int read_interval_packets(WriterC
ret = AVERROR(ENOMEM);
goto end;
}
@@ -76,7 +76,7 @@ Index: FFmpeg/fftools/ffprobe.c
}
if (selected_streams[pkt->stream_index]) {
AVRational tb = ifile->streams[pkt->stream_index].st->time_base;
@@ -3159,6 +3201,12 @@ static int read_interval_packets(WriterC
@@ -3181,6 +3223,12 @@ static int read_interval_packets(WriterC
}
frame_count++;
@@ -89,7 +89,7 @@ Index: FFmpeg/fftools/ffprobe.c
if (do_read_packets) {
if (do_show_packets)
show_packet(w, ifile, pkt, i++);
@@ -3179,6 +3227,16 @@ static int read_interval_packets(WriterC
@@ -3201,6 +3249,16 @@ static int read_interval_packets(WriterC
while (process_frame(w, ifile, frame, pkt, &packet_new) > 0);
}
@@ -106,7 +106,7 @@ Index: FFmpeg/fftools/ffprobe.c
}
av_packet_unref(pkt);
}
@@ -3196,6 +3254,9 @@ static int read_interval_packets(WriterC
@@ -3218,6 +3276,9 @@ static int read_interval_packets(WriterC
end:
av_frame_free(&frame);
av_packet_free(&pkt);
@@ -116,7 +116,7 @@ Index: FFmpeg/fftools/ffprobe.c
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval ");
log_read_interval(interval, NULL, AV_LOG_ERROR);
@@ -4587,6 +4648,7 @@ static const OptionDef real_options[] =
@@ -4609,6 +4670,7 @@ static const OptionDef real_options[] =
{ "print_filename", OPT_TYPE_FUNC, OPT_FUNC_ARG, {.func_arg = opt_print_filename}, "override the printed input filename", "print_file"},
{ "find_stream_info", OPT_TYPE_BOOL, OPT_INPUT | OPT_EXPERT, { &find_stream_info },
"read and decode the streams to fill missing information with heuristics" },
@@ -0,0 +1,28 @@
Index: FFmpeg/fftools/ffmpeg_filter.c
===================================================================
--- FFmpeg.orig/fftools/ffmpeg_filter.c
+++ FFmpeg/fftools/ffmpeg_filter.c
@@ -1543,8 +1543,21 @@ static int configure_output_video_filter
ofp->format != AV_PIX_FMT_NONE || !ofp->formats);
av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
choose_pix_fmts(ofp, &bprint);
- choose_color_spaces(ofp, &bprint);
- choose_color_ranges(ofp, &bprint);
+ /* SW filter cannot handle color conversions between HW pixel formats. */
+ {
+ int bprint_color_options = 1;
+ if (ofp->format != AV_PIX_FMT_NONE) {
+ const AVPixFmtDescriptor *ofp_fmt_desc;
+
+ ofp_fmt_desc = av_pix_fmt_desc_get(ofp->format);
+ if (ofp_fmt_desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
+ bprint_color_options = 0;
+ }
+ if (bprint_color_options) {
+ choose_color_spaces(ofp, &bprint);
+ choose_color_ranges(ofp, &bprint);
+ }
+ }
if (!av_bprint_is_complete(&bprint))
return AVERROR(ENOMEM);
@@ -0,0 +1,26 @@
Index: FFmpeg/fftools/ffmpeg_filter.c
===================================================================
--- FFmpeg.orig/fftools/ffmpeg_filter.c
+++ FFmpeg/fftools/ffmpeg_filter.c
@@ -2384,10 +2384,21 @@ static int close_output(OutputFilterPriv
if (!fgt->got_frame) {
AVFrame *frame = fgt->frame;
FrameData *fd;
+ const AVPixFmtDescriptor *ofp_fmt_desc;
frame->time_base = ofp->tb_out;
frame->format = ofp->format;
+ ofp_fmt_desc = av_pix_fmt_desc_get(ofp->format);
+ // a dummy frame with HW pixel format requires a valid hw_frames_ctx
+ if (ofp_fmt_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) {
+ AVFilterContext *sink = ofp->filter;
+ AVBufferRef *hwfc = av_buffersink_get_hw_frames_ctx(sink);
+ ret = av_buffer_replace(&frame->hw_frames_ctx, hwfc);
+ if (ret < 0)
+ return ret;
+ }
+
frame->width = ofp->width;
frame->height = ofp->height;
frame->sample_aspect_ratio = ofp->sample_aspect_ratio;
@@ -0,0 +1,24 @@
Index: FFmpeg/libavcodec/bsf/dovi_rpu.c
===================================================================
--- FFmpeg.orig/libavcodec/bsf/dovi_rpu.c
+++ FFmpeg/libavcodec/bsf/dovi_rpu.c
@@ -84,7 +84,8 @@ static int dovi_rpu_update_fragment_hevc
uint8_t *rpu = NULL;
int rpu_size, ret;
- if (!nal || nal->type != HEVC_NAL_UNSPEC62)
+ // HEVC_NAL_UNSPEC62 is Dolby Vision PRU and HEVC_NAL_UNSPEC63 is Dolby Vision EL
+ if (!nal || (nal->type != HEVC_NAL_UNSPEC62 && nal->type != HEVC_NAL_UNSPEC63))
return 0;
if (s->strip) {
@@ -92,6 +93,9 @@ static int dovi_rpu_update_fragment_hevc
return 0;
}
+ if (nal->type == HEVC_NAL_UNSPEC63)
+ return 0;
+
ret = update_rpu(bsf, pkt, 0, nal->data + 2, nal->data_size - 2, &rpu, &rpu_size);
if (ret < 0)
return ret;
@@ -1,48 +0,0 @@
Index: FFmpeg/fftools/ffmpeg_mux_init.c
===================================================================
--- FFmpeg.orig/fftools/ffmpeg_mux_init.c
+++ FFmpeg/fftools/ffmpeg_mux_init.c
@@ -962,17 +962,12 @@ static int streamcopy_init(const Muxer *
else
ost->st->avg_frame_rate = ist->st->avg_frame_rate;
- ret = avformat_transfer_internal_stream_timing_info(mux->fc->oformat,
- ost->st, ist->st, copy_tb);
- if (ret < 0)
- goto fail;
-
// copy timebase while removing common factors
if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) {
if (fr.num)
ost->st->time_base = av_inv_q(fr);
else
- ost->st->time_base = av_add_q(av_stream_get_codec_timebase(ost->st), (AVRational){0, 1});
+ ost->st->time_base = av_add_q(ist->st->time_base, (AVRational){0, 1});
}
if (!ms->copy_prior_start) {
Index: FFmpeg/tests/fate/ffmpeg.mak
===================================================================
--- FFmpeg.orig/tests/fate/ffmpeg.mak
+++ FFmpeg/tests/fate/ffmpeg.mak
@@ -144,7 +144,7 @@ fate-copy-trac236: CMD = transcode mov $
FATE_STREAMCOPY-$(call TRANSCODE, RAWVIDEO MPEG2VIDEO, MXF, MPEGTS_DEMUXER MPEGVIDEO_PARSER MPEGAUDIO_PARSER MP2_DECODER ARESAMPLE_FILTER PCM_S16LE_DECODER) += fate-copy-trac4914
fate-copy-trac4914: CMD = transcode mpegts $(TARGET_SAMPLES)/mpeg2/xdcam8mp2-1s_small.ts\
- mxf "-c:a pcm_s16le -af aresample -c:v copy"
+ mxf "-c:a pcm_s16le -af aresample -c:v copy -time_base 1001/30000"
FATE_STREAMCOPY-$(call TRANSCODE, RAWVIDEO MPEG2VIDEO, AVI, MPEGTS_DEMUXER MPEGVIDEO_PARSER MPEGAUDIO_PARSER EXTRACT_EXTRADATA_BSF MP2_DECODER ARESAMPLE_FILTER) += fate-copy-trac4914-avi
fate-copy-trac4914-avi: CMD = transcode mpegts $(TARGET_SAMPLES)/mpeg2/xdcam8mp2-1s_small.ts\
Index: FFmpeg/tests/ref/fate/copy-trac4914-avi
===================================================================
--- FFmpeg.orig/tests/ref/fate/copy-trac4914-avi
+++ FFmpeg/tests/ref/fate/copy-trac4914-avi
@@ -1,5 +1,5 @@
-26e4202638bc384b82d2b5eb4d33a5f0 *tests/data/fate/copy-trac4914-avi.avi
-479494 tests/data/fate/copy-trac4914-avi.avi
+3b6f31b806ef421652a066f239536b0d *tests/data/fate/copy-trac4914-avi.avi
+492046 tests/data/fate/copy-trac4914-avi.avi
#tb 0: 1001/30000
#media_type 0: video
#codec_id 0: rawvideo
@@ -0,0 +1,36 @@
Index: FFmpeg/libavformat/hls.c
===================================================================
--- FFmpeg.orig/libavformat/hls.c
+++ FFmpeg/libavformat/hls.c
@@ -746,7 +746,7 @@ static int test_segment(AVFormatContext
+ 2*(ff_match_url_ext(seg->url, c->allowed_extensions) > 0);
if (!matchA) {
- av_log(s, AV_LOG_ERROR, "URL %s is not in allowed_extensions\n", seg->url);
+ av_log(s, AV_LOG_ERROR, "URL %s is not in allowed_extensions, consider updating hls.c and submitting a patch to ffmpeg-devel, if this should be added\n", seg->url);
return AVERROR_INVALIDDATA;
}
@@ -754,7 +754,8 @@ static int test_segment(AVFormatContext
if (in_fmt->extensions) {
matchF = av_match_ext( seg->url, in_fmt->extensions)
+ 2*(ff_match_url_ext(seg->url, in_fmt->extensions) > 0);
- if(av_match_name("mp4", in_fmt->name)) {
+ // Youtube uses aac files with .ts extension
+ if(av_match_name("mp4", in_fmt->name) || av_match_name("aac", in_fmt->name)) {
matchF |= av_match_ext( seg->url, "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts")
+ 2*(ff_match_url_ext(seg->url, "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts") > 0);
}
@@ -2628,7 +2629,11 @@ static const AVOption hls_options[] = {
OFFSET(prefer_x_start), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS},
{"allowed_extensions", "List of file extensions that hls is allowed to access",
OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
- {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"},
+ {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"
+ ",cmfv,cmfa" // Ticket11526 www.nicovideo.jp
+ ",ec3" // part of Ticket11435 (Elisa Viihde (Finnish online recording service))
+ ",fmp4" // https://github.com/yt-dlp/yt-dlp/issues/12700
+ },
INT_MIN, INT_MAX, FLAGS},
{"extension_picky", "Be picky with all extensions matching",
OFFSET(extension_picky), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS},
@@ -0,0 +1,14 @@
Index: FFmpeg/libavcodec/decode.c
===================================================================
--- FFmpeg.orig/libavcodec/decode.c
+++ FFmpeg/libavcodec/decode.c
@@ -207,6 +207,9 @@ static int decode_bsfs_init(AVCodecConte
ret = av_bsf_init(avci->bsf);
if (ret < 0)
goto fail;
+ ret = avcodec_parameters_to_context(avctx, avci->bsf->par_out);
+ if (ret < 0)
+ goto fail;
return 0;
fail:
@@ -0,0 +1,15 @@
Index: FFmpeg/fftools/ffmpeg_filter.c
===================================================================
--- FFmpeg.orig/fftools/ffmpeg_filter.c
+++ FFmpeg/fftools/ffmpeg_filter.c
@@ -1998,6 +1998,10 @@ static int configure_filtergraph(FilterG
if (ifp->type_src == AVMEDIA_TYPE_SUBTITLE) {
sub2video_frame(&ifp->ifilter, tmp, !fgt->graph);
} else {
+ if (ifp->type_src == AVMEDIA_TYPE_VIDEO) {
+ if (ifp->displaymatrix_applied)
+ av_frame_remove_side_data(tmp, AV_FRAME_DATA_DISPLAYMATRIX);
+ }
ret = av_buffersrc_add_frame(ifp->filter, tmp);
}
av_frame_free(&tmp);
@@ -0,0 +1,16 @@
Index: FFmpeg/libavcodec/libsvtav1.c
===================================================================
--- FFmpeg.orig/libavcodec/libsvtav1.c
+++ FFmpeg/libavcodec/libsvtav1.c
@@ -435,7 +435,11 @@ static av_cold int eb_enc_init(AVCodecCo
svt_enc->eos_flag = EOS_NOT_REACHED;
+#if SVT_AV1_CHECK_VERSION(3, 0, 0)
+ svt_ret = svt_av1_enc_init_handle(&svt_enc->svt_handle, &svt_enc->enc_params);
+#else
svt_ret = svt_av1_enc_init_handle(&svt_enc->svt_handle, svt_enc, &svt_enc->enc_params);
+#endif
if (svt_ret != EB_ErrorNone) {
return svt_print_error(avctx, svt_ret, "Error initializing encoder handle");
}
@@ -0,0 +1,13 @@
Index: FFmpeg/libavcodec/Makefile
===================================================================
--- FFmpeg.orig/libavcodec/Makefile
+++ FFmpeg/libavcodec/Makefile
@@ -108,7 +108,7 @@ OBJS-$(CONFIG_H264PARSE) +
h2645data.o h2645_parse.o h2645_vui.o
OBJS-$(CONFIG_H264PRED) += h264pred.o
OBJS-$(CONFIG_H264QPEL) += h264qpel.o
-OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
+OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o aom_film_grain.o
OBJS-$(CONFIG_HEVCPARSE) += h2645data.o h2645_parse.o h2645_vui.o
OBJS-$(CONFIG_HEVC_SEI) += h2645_sei.o aom_film_grain.o \
dynamic_hdr_vivid.o
+73 -71
View File
@@ -2,7 +2,7 @@
0002-update-cuda-func-header.patch
0003-add-enhanced-cuda-pixfmt-converter-impl.patch
0004-add-cuda-tonemap-impl.patch
0005-add-amf-refactor-and-10bit-encoding.patch
0005-add-amf-fixes-from-upstream-and-custom-tunings.patch
0006-add-opencl-scaler-and-pixfmt-converter-impl.patch
0007-add-bt2390-eetf-and-code-refactor-to-opencl-tonemap.patch
0008-add-pgs-support-to-opencl-overlay.patch
@@ -13,73 +13,75 @@
0013-add-vendor-id-option-for-d3d11.patch
0014-add-vaapi-hwupload-filter.patch
0015-disable-the-premultiplied-alpha-in-vaapi-overlay.patch
0016-add-fixes-and-hdr2hdr-for-vaapi-tonemap.patch
0017-add-fixes-for-nvdec-exceed-32-surfaces-error.patch
0018-backport-fixes-for-vaapi-from-upstream.patch
0019-backport-fixes-for-qsv-from-upstream.patch
0020-backport-fixes-for-qsv-from-cartwheel.patch
0021-add-fixes-for-qsv-vpp-filters.patch
0022-add-external-frame-support-for-qsv-enc.patch
0023-suppress-overlay-warning-logs.patch
0024-add-fixes-for-hevc-hdr-decoding-in-bsf.patch
0025-add-sub2video-option-to-subtitles-filter.patch
0026-add-alphasrc-source-video-filter.patch
0027-increase-the-default-async-depth-for-vaapi-encode.patch
0028-add-fixes-for-hevc-vaapi-encoding-on-tgl.patch
0029-add-multiple-values-tags-and-webp-support-for-id3v2.patch
0030-remove-fdk-aac-from-nonfree.patch
0031-pass-dovi-sidedata-to-hlsenc-and-mpegtsenc.patch
0032-add-pause-support-for-ffmpeg-cli.patch
0033-enable-gcc-vectorization-and-fix-cpuflags.patch
0034-tune-dxva-align-for-intel-to-avoid-copy-on-qsv.patch
0035-add-10bit-support-for-cuda-overlay.patch
0036-add-hdr-metadata-for-nvenc-hevc-encoder.patch
0037-add-d3d11va-dxva2-hevc-422-444-decoding-on-intel.patch
0038-default-vaapi-scaler-algorithm-to-fast.patch
0039-dont-fail-on-vaapi-to-drm-export-vasync.patch
0040-skip-loading-plugins-on-vpl-runtime.patch
0041-tune-the-default-bf-for-qsv-enc.patch
0042-allow-vaapi-import-drm-prime2-planar-formats.patch
0043-add-vui-info-to-the-seq-header-of-hevc-vaapi-encoder.patch
0044-sync-intel-d3d11va-textures-before-mapping-to-opencl.patch
0045-add-icon-for-windows-version-ffmpeg.patch
0046-fix-libx265-encoded-fmp4-hls-playback-on-safari.patch
0047-add-full-hwa-pipeline-for-rockchip-rk3588-platform.patch
0048-add-format-option-to-vt-scale-filter.patch
0049-backport-fixes-for-videotoolbox-from-upstream.patch
0050-add-vf-overlay-videotoolbox-filter.patch
0051-add-coreimage-based-vf-transpose-vt-filter.patch
0052-add-vf-tonemap-videotoolbox-filter.patch
0053-add-mjpeg-videotoolbox-encoder.patch
0054-add-vt-low-priority-keyframe-decoding.patch
0055-add-dummy-device-derive-to-videotoolbox-hwcontext.patch
0056-add-cuda-transpose-filter-impl.patch
0057-add-flip-feat-to-opencl-transpose-filter.patch
0058-add-customized-surf-align-for-vaapi-encoder.patch
0059-opus-allow-5point1-side-inputs.patch
0060-add-simd-optimized-tonemapx-filter.patch
0061-add-ac4-decoder-for-atsc-3-0.patch
0062-tune-the-default-inter-thread-queue-sizes.patch
0063-add-vendor-id-option-to-vaapi-hwcontext.patch
0064-backport-fixes-for-vulkan-from-upstream.patch
0065-revert-the-broken-vulkan-hwupload-rewrite.patch
0066-use-linear-contiguous-vulkan-images-for-amd-encoder.patch
0067-prefer-vulkan-device-with-higher-api-version.patch
0068-add-pgs-support-to-vulkan-overlay.patch
0069-add-fixes-x265-build-from-upstream.patch
0070-fix-yuv420p-to-p01x-unscaled-conversion.patch
0071-allow-vt-sw-decoder-for-every-codec.patch
0072-add-bwdif-videotoolbox-filter.patch
0073-add-12bit-decoding-on-videotoolbox.patch
0074-fix-the-sub2video-perf-regressions.patch
0075-allow-vpl-qsv-to-init-with-the-legacy-msdk-path.patch
0076-alway-set-videotoolboxenc-pixel-buffer-info.patch
0077-add-remove-dovi-hdr10plus-bsf.patch
0078-fix-atenc-layout-samplerate.patch
0079-videotoolbox-remove-opengl-compatability.patch
0080-use-dynamic-pool-for-vpl-qsv-hwupload.patch
0081-backport-av1-videotoolbox.patch
0082-fix-ass-incorrect-null-copy.patch
0083-default-to-input-timebase-for-streamcopy.patch
0084-fix-a-race-condition-in-vaapi-csc-to-yuv420p.patch
0085-add-first-vframe-only-to-ffprobe.patch
0016-add-fixes-for-nvdec-exceed-32-surfaces-error.patch
0017-backport-fixes-for-vaapi-from-upstream.patch
0018-backport-fixes-for-qsv-from-upstream.patch
0019-backport-fixes-for-qsv-from-cartwheel.patch
0020-add-fixes-for-qsv-vpp-filters.patch
0021-add-external-frame-support-for-qsv-enc.patch
0022-suppress-overlay-warning-logs.patch
0023-add-fixes-for-hevc-hdr-decoding-in-bsf.patch
0024-add-sub2video-option-to-subtitles-filter.patch
0025-add-alphasrc-source-video-filter.patch
0026-increase-the-default-async-depth-for-vaapi-encode.patch
0027-add-fixes-for-hevc-vaapi-encoding-on-tgl.patch
0028-add-multiple-values-tags-and-webp-support-for-id3v2.patch
0029-remove-fdk-aac-from-nonfree.patch
0030-pass-dovi-sidedata-to-hlsenc-and-mpegtsenc.patch
0031-add-pause-support-for-ffmpeg-cli.patch
0032-enable-gcc-vectorization-and-fix-cpuflags.patch
0033-tune-dxva-align-for-intel-to-avoid-copy-on-qsv.patch
0034-add-10bit-support-for-cuda-overlay.patch
0035-add-hdr-metadata-for-nvenc-hevc-encoder.patch
0036-add-d3d11va-dxva2-hevc-422-444-decoding-on-intel.patch
0037-default-vaapi-scaler-algorithm-to-fast.patch
0038-dont-fail-on-vaapi-to-drm-export-vasync.patch
0039-skip-loading-plugins-on-vpl-runtime.patch
0040-tune-the-default-bf-for-qsv-enc.patch
0041-allow-vaapi-import-drm-prime2-planar-formats.patch
0042-add-vui-info-to-the-seq-header-of-hevc-vaapi-encoder.patch
0043-sync-intel-d3d11va-textures-before-mapping-to-opencl.patch
0044-add-icon-for-windows-version-ffmpeg.patch
0045-fix-libx265-encoded-fmp4-hls-playback-on-safari.patch
0046-add-full-hwa-pipeline-for-rockchip-rk3588-platform.patch
0047-add-format-option-to-vt-scale-filter.patch
0048-add-vf-overlay-videotoolbox-filter.patch
0049-add-coreimage-based-vf-transpose-vt-filter.patch
0050-add-vf-tonemap-videotoolbox-filter.patch
0051-add-mjpeg-videotoolbox-encoder.patch
0052-add-vt-low-priority-keyframe-decoding.patch
0053-add-dummy-device-derive-to-videotoolbox-hwcontext.patch
0054-add-cuda-transpose-filter-impl.patch
0055-add-flip-feat-to-opencl-transpose-filter.patch
0056-opus-allow-5point1-side-inputs.patch
0057-add-simd-optimized-tonemapx-filter.patch
0058-add-ac4-decoder-for-atsc-3-0.patch
0059-tune-the-default-inter-thread-queue-sizes.patch
0060-backport-fixes-for-vulkan-from-upstream.patch
0061-revert-the-broken-vulkan-hwupload-rewrite.patch
0062-use-linear-contiguous-vulkan-images-for-amd-encoder.patch
0063-prefer-vulkan-device-with-higher-api-version.patch
0064-add-pgs-support-to-vulkan-overlay.patch
0065-fix-yuv420p-to-p01x-unscaled-conversion.patch
0066-allow-vt-sw-decoder-for-every-codec.patch
0067-add-bwdif-videotoolbox-filter.patch
0068-add-12bit-decoding-on-videotoolbox.patch
0069-fix-the-sub2video-perf-regressions.patch
0070-allow-vpl-qsv-to-init-with-the-legacy-msdk-path.patch
0071-alway-set-videotoolboxenc-pixel-buffer-info.patch
0072-add-remove-dovi-hdr10plus-bsf.patch
0073-fix-atenc-layout-samplerate.patch
0074-videotoolbox-remove-opengl-compatability.patch
0075-use-dynamic-pool-for-vpl-qsv-hwupload.patch
0076-backport-av1-videotoolbox.patch
0077-fix-ass-incorrect-null-copy.patch
0078-fix-a-race-condition-in-vaapi-csc-to-yuv420p.patch
0079-add-first-vframe-only-to-ffprobe.patch
0080-fix-auto-inserting-sw-color-conv-filters-between-hw-fmts.patch
0081-fix-dummy-hw-frame-missing-hw-frames-ctx.patch
0082-remove-el-when-stripping-dovi-metadata.patch
0083-fix-missing-allowed-extensions-in-hls-demuxer.patch
0084-fix-avcodec-params-when-bsfs-are-enable-by-decoder.patch
0085-fix-display-matrix-not-removed-after-autorotation.patch
0086-unbreak-build-with-latest-svtav1-3-0.patch
0087-backport-fix-for-missing-h264-sei-build-deps.patch