mirror of
https://github.com/jellyfin/jellyfin-ffmpeg.git
synced 2026-09-03 05:09:58 +03:00
Update patches for 7.1.1
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
+3
-3
@@ -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
@@ -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, ×tamp_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 {
|
||||
|
||||
+267
-101
@@ -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
@@ -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)
|
||||
|
||||
+15
-15
@@ -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);
|
||||
|
||||
@@ -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
@@ -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, ¶ms,
|
||||
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 }
|
||||
};
|
||||
|
||||
+1
-1
@@ -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));
|
||||
+5
-5
@@ -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
+123
-54
@@ -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);
|
||||
+1
-1
@@ -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) {\
|
||||
+3
-3
@@ -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
|
||||
+12
-9
@@ -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);
|
||||
}
|
||||
|
||||
+7
-6
@@ -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 */
|
||||
+4
-4
@@ -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
-2
@@ -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
-2
@@ -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
|
||||
+148
-164
@@ -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'));
|
||||
+9
-9
@@ -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;
|
||||
|
||||
+16
-16
@@ -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;
|
||||
+12
-3
@@ -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);
|
||||
}
|
||||
|
||||
+28
-10
@@ -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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
-38
@@ -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:
|
||||
+1
-1
@@ -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
-2
@@ -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" },
|
||||
+9
-1
@@ -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
-2
@@ -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;
|
||||
|
||||
+1
-1
@@ -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);
|
||||
+206
-198
File diff suppressed because it is too large
Load Diff
+10
-13
@@ -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 },
|
||||
+25
-18
@@ -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);
|
||||
+29
-19
@@ -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)
|
||||
+68
-18
@@ -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,
|
||||
+};
|
||||
+15
-14
@@ -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,
|
||||
+3
-3
@@ -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:
|
||||
+20
-16
@@ -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;
|
||||
+
|
||||
+3
-3
@@ -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[] = {
|
||||
+1
-1
@@ -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);
|
||||
+56
-25
@@ -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
|
||||
+6
-5
@@ -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) {
|
||||
+1
-1
@@ -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) \
|
||||
+17
-17
@@ -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);
|
||||
+75
-34
@@ -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
-2
@@ -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++) {
|
||||
+14
-12
@@ -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
-2
@@ -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++;
|
||||
+1
-1
@@ -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,
|
||||
+14
-11
@@ -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);
|
||||
+5
-5
@@ -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;
|
||||
+1
-1
@@ -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);
|
||||
+8
-8
@@ -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
-2
@@ -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);
|
||||
}
|
||||
|
||||
+86
-86
@@ -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 }
|
||||
};
|
||||
|
||||
+4
-4
@@ -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,
|
||||
+1
-1
@@ -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);
|
||||
+3
-3
@@ -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
|
||||
|
||||
+146
-144
@@ -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);
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
+7
-7
@@ -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" },
|
||||
+28
@@ -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
|
||||
Vendored
+73
-71
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user