mirror of
https://github.com/jellyfin/jellyfin-ffmpeg.git
synced 2026-09-02 21:03:08 +03:00
Merge pull request #741 from nyanmisaka/mft-hw-enc
Add misc enhancements to mfenc hw encoder
This commit is contained in:
+3
-7
@@ -18,7 +18,7 @@ ENV DPKG_INSTALL_LIST=${SOURCE_DIR}/debian/jellyfin-ffmpeg8.install
|
||||
ENV PATH=${TARGET_DIR}/bin:${PATH}
|
||||
ENV PKG_CONFIG_PATH=${TARGET_DIR}/lib/pkgconfig:${PKG_CONFIG_PATH}
|
||||
ENV LD_LIBRARY_PATH=${TARGET_DIR}/lib:${TARGET_DIR}/lib/mfx:${TARGET_DIR}/lib/xorg:${LD_LIBRARY_PATH}
|
||||
ENV LDFLAGS="-Wl,-rpath=${TARGET_DIR}/lib -L${TARGET_DIR}/lib -lm"
|
||||
ENV LDFLAGS="-Wl,--disable-new-dtags -Wl,-rpath=${TARGET_DIR}/lib -L${TARGET_DIR}/lib -lm"
|
||||
ENV CXXFLAGS="-I${TARGET_DIR}/include $CXXFLAGS"
|
||||
ENV CPPFLAGS="-I${TARGET_DIR}/include $CPPFLAGS"
|
||||
ENV CFLAGS="-I${TARGET_DIR}/include $CFLAGS"
|
||||
@@ -28,13 +28,9 @@ ENV CMAKE_POLICY_VERSION_MINIMUM="3.5"
|
||||
RUN apt-get update \
|
||||
&& apt-get dist-upgrade -y \
|
||||
&& apt-get install -y apt-transport-https \
|
||||
curl ninja-build debhelper gnupg wget devscripts \
|
||||
curl ninja-build debhelper gnupg wget devscripts \
|
||||
mmv equivs git nasm pkg-config subversion dh-autoreconf \
|
||||
libpciaccess-dev libwayland-dev libx11-dev libx11-xcb-dev \
|
||||
libxcb-dri2-0-dev libxcb-dri3-dev libxcb-present-dev \
|
||||
libxcb-shm0-dev libxcb-sync-dev libxshmfence-dev libxext-dev \
|
||||
libxfixes-dev libxcb1-dev libxrandr-dev libzstd-dev \
|
||||
libelf-dev python3-pip zip unzip tar flex bison gperf ragel \
|
||||
python3-pip zip unzip tar flex bison gperf ragel \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
---
|
||||
# We just wrap `build` so this is really it
|
||||
name: "jellyfin-ffmpeg"
|
||||
version: "8.1.2-1"
|
||||
version: "8.1.2-2"
|
||||
packages:
|
||||
- bullseye-amd64
|
||||
- bullseye-arm64
|
||||
|
||||
@@ -15,9 +15,9 @@ ffbuild_dockerbuild() {
|
||||
}
|
||||
|
||||
ffbuild_configure() {
|
||||
[[ $TARGET == win* ]] && echo --enable-dxva2 --enable-d3d11va --enable-d3d12va
|
||||
[[ $TARGET == win* ]] && echo --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-mediafoundation
|
||||
}
|
||||
|
||||
ffbuild_unconfigure() {
|
||||
[[ $TARGET == win* ]] && echo --disable-dxva2 --disable-d3d11va --disable-d3d12va
|
||||
[[ $TARGET == win* ]] && echo --disable-dxva2 --disable-d3d11va --disable-d3d12va --disable-mediafoundation
|
||||
}
|
||||
|
||||
Vendored
+10
@@ -1,3 +1,13 @@
|
||||
jellyfin-ffmpeg (8.1.2-2) unstable; urgency=medium
|
||||
|
||||
* Add d3d11 overlay/tonemap/transpose/deint/scale filters
|
||||
* Fix full range input for mjpeg_vaapi encoder
|
||||
* Fix a typo in HDR10 metadata mapping in hevc_nvenc encoder
|
||||
* Add misc enhancements to mfenc hw encoder
|
||||
* Enable Mesa AMD drivers for arm64 builds
|
||||
|
||||
-- nyanmisaka <nst799610810@gmail.com> Sat, 18 Jul 2026 18:39:50 +0800
|
||||
|
||||
jellyfin-ffmpeg (8.1.2-1) unstable; urgency=medium
|
||||
|
||||
* New upstream version 8.1.2
|
||||
|
||||
Vendored
-4
@@ -17,16 +17,12 @@ Build-Depends:
|
||||
libgnutls28-dev | libgnutls-dev,
|
||||
# --enable-libbluray
|
||||
libbluray-dev,
|
||||
# --enable-libdrm
|
||||
libdrm-dev [!amd64],
|
||||
# --enable-gmp
|
||||
libgmp-dev,
|
||||
# --enable-libmp3lame
|
||||
libmp3lame-dev,
|
||||
# --enable-libopus
|
||||
libopus-dev,
|
||||
# --enable-libtheora
|
||||
libtheora-dev,
|
||||
# --enable-libvorbis
|
||||
libvorbis-dev,
|
||||
# --enable-libopenmpt
|
||||
|
||||
@@ -1,3 +1,140 @@
|
||||
Index: FFmpeg/libavcodec/av1dec.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/av1dec.c
|
||||
+++ FFmpeg/libavcodec/av1dec.c
|
||||
@@ -688,8 +688,8 @@ static int get_pixel_format(AVCodecConte
|
||||
|
||||
static void av1_frame_unref(AV1Frame *f)
|
||||
{
|
||||
- ff_progress_frame_unref(&f->pf);
|
||||
av_refstruct_unref(&f->hwaccel_picture_private);
|
||||
+ ff_progress_frame_unref(&f->pf);
|
||||
av_refstruct_unref(&f->header_ref);
|
||||
f->raw_frame_header = NULL;
|
||||
f->spatial_id = f->temporal_id = 0;
|
||||
Index: FFmpeg/libavcodec/h264_picture.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/h264_picture.c
|
||||
+++ FFmpeg/libavcodec/h264_picture.c
|
||||
@@ -44,9 +44,9 @@ void ff_h264_unref_picture(H264Picture *
|
||||
if (!pic->f || !pic->f->buf[0])
|
||||
return;
|
||||
|
||||
+ av_refstruct_unref(&pic->hwaccel_picture_private);
|
||||
ff_thread_release_ext_buffer(&pic->tf);
|
||||
av_frame_unref(pic->f_grain);
|
||||
- av_refstruct_unref(&pic->hwaccel_picture_private);
|
||||
|
||||
av_refstruct_unref(&pic->qscale_table_base);
|
||||
av_refstruct_unref(&pic->mb_type_base);
|
||||
Index: FFmpeg/libavcodec/hevc/refs.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/hevc/refs.c
|
||||
+++ FFmpeg/libavcodec/hevc/refs.c
|
||||
@@ -38,6 +38,8 @@ void ff_hevc_unref_frame(HEVCFrame *fram
|
||||
if (!(frame->flags & ~HEVC_FRAME_FLAG_CORRUPT))
|
||||
frame->flags = 0;
|
||||
if (!frame->flags) {
|
||||
+ av_refstruct_unref(&frame->hwaccel_picture_private);
|
||||
+
|
||||
ff_progress_frame_unref(&frame->tf);
|
||||
av_frame_unref(frame->frame_grain);
|
||||
frame->needs_fg = 0;
|
||||
@@ -49,8 +51,6 @@ void ff_hevc_unref_frame(HEVCFrame *fram
|
||||
frame->nb_rpl_elems = 0;
|
||||
av_refstruct_unref(&frame->rpl_tab);
|
||||
frame->refPicList = NULL;
|
||||
-
|
||||
- av_refstruct_unref(&frame->hwaccel_picture_private);
|
||||
}
|
||||
}
|
||||
|
||||
Index: FFmpeg/libavcodec/vp9.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/vp9.c
|
||||
+++ FFmpeg/libavcodec/vp9.c
|
||||
@@ -97,10 +97,10 @@ static void vp9_tile_data_free(VP9TileDa
|
||||
|
||||
static void vp9_frame_unref(VP9Frame *f)
|
||||
{
|
||||
+ av_refstruct_unref(&f->hwaccel_picture_private);
|
||||
ff_progress_frame_unref(&f->tf);
|
||||
av_refstruct_unref(&f->header_ref);
|
||||
av_refstruct_unref(&f->extradata);
|
||||
- av_refstruct_unref(&f->hwaccel_picture_private);
|
||||
f->segmentation_map = NULL;
|
||||
}
|
||||
|
||||
Index: FFmpeg/libavcodec/vulkan_encode.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/vulkan_encode.c
|
||||
+++ FFmpeg/libavcodec/vulkan_encode.c
|
||||
@@ -28,6 +28,27 @@ const AVCodecHWConfigInternal *const ff_
|
||||
NULL,
|
||||
};
|
||||
|
||||
+static void vulkan_encode_free_pic(FFVulkanEncodeContext *ctx,
|
||||
+ FFHWBaseEncodePicture *pic)
|
||||
+{
|
||||
+ FFVulkanFunctions *vk = &ctx->s.vkfn;
|
||||
+
|
||||
+ FFVulkanEncodePicture *vp = pic->priv;
|
||||
+
|
||||
+ if (vp->in.view)
|
||||
+ vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->in.view,
|
||||
+ ctx->s.hwctx->alloc);
|
||||
+
|
||||
+ if (!ctx->common.layered_dpb && vp->dpb.view)
|
||||
+ vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->dpb.view,
|
||||
+ ctx->s.hwctx->alloc);
|
||||
+
|
||||
+ vp->in.view = VK_NULL_HANDLE;
|
||||
+ vp->dpb.view = VK_NULL_HANDLE;
|
||||
+
|
||||
+ ctx->slots[vp->dpb_slot.slotIndex] = NULL;
|
||||
+}
|
||||
+
|
||||
av_cold void ff_vulkan_encode_uninit(FFVulkanEncodeContext *ctx)
|
||||
{
|
||||
FFVulkanContext *s = &ctx->s;
|
||||
@@ -42,10 +63,15 @@ av_cold void ff_vulkan_encode_uninit(FFV
|
||||
ctx->session_params,
|
||||
s->hwctx->alloc);
|
||||
|
||||
- ff_hw_base_encode_close(&ctx->base);
|
||||
+ /* Destroy the image views of any pictures still in the queue,
|
||||
+ * as ff_hw_base_encode_close() only frees the picture structs */
|
||||
+ for (FFHWBaseEncodePicture *pic = ctx->base.pic_start; pic; pic = pic->next)
|
||||
+ vulkan_encode_free_pic(ctx, pic);
|
||||
|
||||
av_buffer_pool_uninit(&ctx->buf_pool);
|
||||
|
||||
+ ff_hw_base_encode_close(&ctx->base);
|
||||
+
|
||||
ff_vk_video_common_uninit(s, &ctx->common);
|
||||
|
||||
ff_vk_uninit(s);
|
||||
@@ -95,19 +121,8 @@ static int vulkan_encode_init(AVCodecCon
|
||||
static int vulkan_encode_free(AVCodecContext *avctx, FFHWBaseEncodePicture *pic)
|
||||
{
|
||||
FFVulkanEncodeContext *ctx = avctx->priv_data;
|
||||
- FFVulkanFunctions *vk = &ctx->s.vkfn;
|
||||
-
|
||||
- FFVulkanEncodePicture *vp = pic->priv;
|
||||
-
|
||||
- if (vp->in.view)
|
||||
- vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->in.view,
|
||||
- ctx->s.hwctx->alloc);
|
||||
-
|
||||
- if (!ctx->common.layered_dpb && vp->dpb.view)
|
||||
- vk->DestroyImageView(ctx->s.hwctx->act_dev, vp->dpb.view,
|
||||
- ctx->s.hwctx->alloc);
|
||||
|
||||
- ctx->slots[vp->dpb_slot.slotIndex] = NULL;
|
||||
+ vulkan_encode_free_pic(ctx, pic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Index: FFmpeg/libavcodec/vulkan_encode.h
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/vulkan_encode.h
|
||||
@@ -11,11 +148,186 @@ Index: FFmpeg/libavcodec/vulkan_encode.h
|
||||
{ "rc_mode", "Select rate control type", OFFSET(common.opts.rc_mode), AV_OPT_TYPE_INT, { .i64 = FF_VK_RC_MODE_AUTO }, 0, FF_VK_RC_MODE_AUTO, FLAGS, "rc_mode" }, \
|
||||
{ "auto", "Choose mode automatically based on parameters", 0, AV_OPT_TYPE_CONST, { .i64 = FF_VK_RC_MODE_AUTO }, INT_MIN, INT_MAX, FLAGS, "rc_mode" }, \
|
||||
{ "driver", "Driver-specific rate control", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR }, INT_MIN, INT_MAX, FLAGS, "rc_mode" }, \
|
||||
Index: FFmpeg/libavcodec/vulkan_encode_av1.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/vulkan_encode_av1.c
|
||||
+++ FFmpeg/libavcodec/vulkan_encode_av1.c
|
||||
@@ -1023,7 +1023,7 @@ static int init_base_units(AVCodecContex
|
||||
} else {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unable to get feedback for AV1 sequence header = %zu\n",
|
||||
data_size);
|
||||
- return err;
|
||||
+ return AVERROR_EXTERNAL;
|
||||
}
|
||||
|
||||
ret = vk->GetEncodedVideoSessionParametersKHR(s->hwctx->act_dev, ¶ms_info,
|
||||
@@ -1031,7 +1031,8 @@ static int init_base_units(AVCodecContex
|
||||
&data_size, data);
|
||||
if (ret != VK_SUCCESS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error writing feedback units\n");
|
||||
- return err;
|
||||
+ err = AVERROR_EXTERNAL;
|
||||
+ goto end;
|
||||
}
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, "Feedback units written, overrides: %i\n",
|
||||
@@ -1040,20 +1041,21 @@ static int init_base_units(AVCodecContex
|
||||
params_feedback.hasOverrides = 1;
|
||||
|
||||
/* No need to sync any overrides */
|
||||
+ err = 0;
|
||||
if (!params_feedback.hasOverrides)
|
||||
- return 0;
|
||||
+ goto end;
|
||||
|
||||
/* Parse back tne units and override */
|
||||
err = parse_feedback_units(avctx, data, data_size);
|
||||
if (err < 0)
|
||||
- return err;
|
||||
+ goto end;
|
||||
|
||||
/* Create final session parameters */
|
||||
err = create_session_params(avctx);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
|
||||
- return 0;
|
||||
+end:
|
||||
+ av_free(data);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int vulkan_encode_av1_add_obu(AVCodecContext *avctx,
|
||||
@@ -1359,6 +1361,10 @@ static av_cold int vulkan_encode_av1_ini
|
||||
static av_cold int vulkan_encode_av1_close(AVCodecContext *avctx)
|
||||
{
|
||||
VulkanEncodeAV1Context *enc = avctx->priv_data;
|
||||
+
|
||||
+ ff_cbs_fragment_free(&enc->current_access_unit);
|
||||
+ ff_cbs_close(&enc->cbs);
|
||||
+
|
||||
av_free(enc->padding_payload);
|
||||
ff_vulkan_encode_uninit(&enc->common);
|
||||
return 0;
|
||||
Index: FFmpeg/libavcodec/vulkan_encode_h264.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/vulkan_encode_h264.c
|
||||
+++ FFmpeg/libavcodec/vulkan_encode_h264.c
|
||||
@@ -1148,7 +1148,7 @@ static int init_base_units(AVCodecContex
|
||||
return AVERROR(ENOMEM);
|
||||
} else {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unable to get feedback for H.264 units = %zu\n", data_size);
|
||||
- return err;
|
||||
+ return AVERROR_EXTERNAL;
|
||||
}
|
||||
|
||||
ret = vk->GetEncodedVideoSessionParametersKHR(s->hwctx->act_dev, ¶ms_info,
|
||||
@@ -1156,7 +1156,8 @@ static int init_base_units(AVCodecContex
|
||||
&data_size, data);
|
||||
if (ret != VK_SUCCESS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error writing feedback units\n");
|
||||
- return err;
|
||||
+ err = AVERROR_EXTERNAL;
|
||||
+ goto end;
|
||||
}
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, "Feedback units written, overrides: %i (SPS: %i PPS: %i)\n",
|
||||
@@ -1168,22 +1169,23 @@ static int init_base_units(AVCodecContex
|
||||
h264_params_feedback.hasStdPPSOverrides = 1;
|
||||
|
||||
/* No need to sync any overrides */
|
||||
+ err = 0;
|
||||
if (!params_feedback.hasOverrides)
|
||||
- return 0;
|
||||
+ goto end;
|
||||
|
||||
/* Parse back tne units and override */
|
||||
err = parse_feedback_units(avctx, data, data_size,
|
||||
h264_params_feedback.hasStdSPSOverrides,
|
||||
h264_params_feedback.hasStdPPSOverrides);
|
||||
if (err < 0)
|
||||
- return err;
|
||||
+ goto end;
|
||||
|
||||
/* Create final session parameters */
|
||||
err = create_session_params(avctx);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
|
||||
- return 0;
|
||||
+end:
|
||||
+ av_free(data);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int vulkan_encode_h264_add_nal(AVCodecContext *avctx,
|
||||
@@ -1561,6 +1563,13 @@ static av_cold int vulkan_encode_h264_in
|
||||
static av_cold int vulkan_encode_h264_close(AVCodecContext *avctx)
|
||||
{
|
||||
VulkanEncodeH264Context *enc = avctx->priv_data;
|
||||
+
|
||||
+ ff_cbs_fragment_free(&enc->current_access_unit);
|
||||
+ ff_cbs_close(&enc->cbs);
|
||||
+
|
||||
+ av_freep(&enc->sei_a53cc_data);
|
||||
+ av_freep(&enc->sei_identifier_string);
|
||||
+
|
||||
ff_vulkan_encode_uninit(&enc->common);
|
||||
return 0;
|
||||
}
|
||||
Index: FFmpeg/libavcodec/vulkan_encode_h265.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/vulkan_encode_h265.c
|
||||
+++ FFmpeg/libavcodec/vulkan_encode_h265.c
|
||||
@@ -1595,23 +1595,21 @@ static av_cold int vulkan_encode_h265_in
|
||||
@@ -1317,7 +1317,7 @@ static int init_base_units(AVCodecContex
|
||||
return AVERROR(ENOMEM);
|
||||
} else {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unable to get feedback for H.265 units = %zu\n", data_size);
|
||||
- return err;
|
||||
+ return AVERROR_EXTERNAL;
|
||||
}
|
||||
|
||||
ret = vk->GetEncodedVideoSessionParametersKHR(s->hwctx->act_dev, ¶ms_info,
|
||||
@@ -1325,7 +1325,8 @@ static int init_base_units(AVCodecContex
|
||||
&data_size, data);
|
||||
if (ret != VK_SUCCESS) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error writing feedback units\n");
|
||||
- return err;
|
||||
+ err = AVERROR_EXTERNAL;
|
||||
+ goto end;
|
||||
}
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, "Feedback units written, overrides: %i (SPS: %i PPS: %i VPS: %i)\n",
|
||||
@@ -1339,22 +1340,23 @@ static int init_base_units(AVCodecContex
|
||||
h265_params_feedback.hasStdPPSOverrides = 1;
|
||||
|
||||
/* No need to sync any overrides */
|
||||
+ err = 0;
|
||||
if (!params_feedback.hasOverrides)
|
||||
- return 0;
|
||||
+ goto end;
|
||||
|
||||
/* Parse back tne units and override */
|
||||
err = parse_feedback_units(avctx, data, data_size,
|
||||
h265_params_feedback.hasStdSPSOverrides,
|
||||
h265_params_feedback.hasStdPPSOverrides);
|
||||
if (err < 0)
|
||||
- return err;
|
||||
+ goto end;
|
||||
|
||||
/* Create final session parameters */
|
||||
err = create_session_params(avctx);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
|
||||
- return 0;
|
||||
+end:
|
||||
+ av_free(data);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static int vulkan_encode_h265_add_nal(AVCodecContext *avctx,
|
||||
@@ -1595,23 +1597,21 @@ static av_cold int vulkan_encode_h265_in
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, " Capability flags:\n");
|
||||
av_log(avctx, AV_LOG_VERBOSE, " hdr_compliance: %i\n",
|
||||
@@ -47,6 +359,19 @@ Index: FFmpeg/libavcodec/vulkan_encode_h265.c
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, " Capabilities:\n");
|
||||
av_log(avctx, AV_LOG_VERBOSE, " maxLevelIdc: %i\n",
|
||||
@@ -1698,6 +1698,12 @@ static av_cold int vulkan_encode_h265_in
|
||||
static av_cold int vulkan_encode_h265_close(AVCodecContext *avctx)
|
||||
{
|
||||
VulkanEncodeH265Context *enc = avctx->priv_data;
|
||||
+
|
||||
+ ff_cbs_fragment_free(&enc->current_access_unit);
|
||||
+ ff_cbs_close(&enc->cbs);
|
||||
+
|
||||
+ av_freep(&enc->sei_a53cc_data);
|
||||
+
|
||||
ff_vulkan_encode_uninit(&enc->common);
|
||||
return 0;
|
||||
}
|
||||
Index: FFmpeg/libavutil/hwcontext_vulkan.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavutil/hwcontext_vulkan.c
|
||||
@@ -119,7 +444,12 @@ Index: FFmpeg/libavutil/hwcontext_vulkan.c
|
||||
if (use_ded_mem)
|
||||
ded_alloc.image = f->img[img_cnt];
|
||||
|
||||
@@ -2854,7 +2871,8 @@ static void try_export_flags(AVHWFramesC
|
||||
@@ -2850,11 +2867,12 @@ static void try_export_flags(AVHWFramesC
|
||||
VkPhysicalDeviceImageFormatInfo2 pinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
|
||||
.pNext = !exp ? NULL : &enext,
|
||||
- .format = vk_find_format_entry(hwfc->sw_format)->vkf,
|
||||
+ .format = hwctx->format[0],
|
||||
.type = VK_IMAGE_TYPE_2D,
|
||||
.tiling = hwctx->tiling,
|
||||
.usage = hwctx->usage,
|
||||
|
||||
+60
-18
@@ -2,35 +2,77 @@ Index: FFmpeg/fftools/ffmpeg_demux.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/fftools/ffmpeg_demux.c
|
||||
+++ FFmpeg/fftools/ffmpeg_demux.c
|
||||
@@ -1757,10 +1757,26 @@ static int is_windows_reserved_device_na
|
||||
@@ -1770,23 +1770,54 @@ static int is_windows_reserved_device_na
|
||||
{
|
||||
#if HAVE_DOS_PATHS
|
||||
for (const char *p = f; p && *p; ) {
|
||||
- char stem[6], *s;
|
||||
+ char stem[16], *s;
|
||||
- av_strlcpy(stem, p, sizeof(stem));
|
||||
- if ((s = strchr(stem, '.')))
|
||||
- *s = 0;
|
||||
- if ((s = strpbrk(stem, "123456789")))
|
||||
- *s = '1';
|
||||
-
|
||||
- if( !av_strcasecmp(stem, "AUX") ||
|
||||
- !av_strcasecmp(stem, "CON") ||
|
||||
- !av_strcasecmp(stem, "NUL") ||
|
||||
- !av_strcasecmp(stem, "PRN") ||
|
||||
- !av_strcasecmp(stem, "COM1") ||
|
||||
- !av_strcasecmp(stem, "LPT1")
|
||||
- )
|
||||
+ const char *next_slash;
|
||||
+ const char *seg_end;
|
||||
+ const char *dot;
|
||||
+ size_t len;
|
||||
av_strlcpy(stem, p, sizeof(stem));
|
||||
+
|
||||
+ if ((s = strchr(stem, '/')))
|
||||
+ *s = 0;
|
||||
+ next_slash = strchr(p, '/');
|
||||
+ seg_end = next_slash ? next_slash : p + strlen(p);
|
||||
+
|
||||
+ /* Trim trailing spaces and dots */
|
||||
+ len = strlen(stem);
|
||||
+ while (len > 0 && (stem[len - 1] == ' ' || stem[len - 1] == '.'))
|
||||
+ stem[--len] = 0;
|
||||
+ /* Trim trailing spaces and dots of the current component */
|
||||
+ while (seg_end > p && (*(seg_end - 1) == ' ' || *(seg_end - 1) == '.'))
|
||||
+ seg_end--;
|
||||
+
|
||||
if ((s = strchr(stem, '.')))
|
||||
*s = 0;
|
||||
+ /* Discard extension if present (Windows stops checking at first dot) */
|
||||
+ dot = p;
|
||||
+ while (dot < seg_end && *dot != '.')
|
||||
+ dot++;
|
||||
+ if (dot < seg_end)
|
||||
+ seg_end = dot;
|
||||
+
|
||||
+ /* Trim again after stripping extension */
|
||||
+ len = strlen(stem);
|
||||
+ while (len > 0 && (stem[len - 1] == ' ' || stem[len - 1] == '.'))
|
||||
+ stem[--len] = 0;
|
||||
+ while (seg_end > p && (*(seg_end - 1) == ' ' || *(seg_end - 1) == '.'))
|
||||
+ seg_end--;
|
||||
+
|
||||
if ((s = strpbrk(stem, "123456789")))
|
||||
*s = '1';
|
||||
+ len = seg_end - p;
|
||||
+
|
||||
+ /* Match 3-byte legacy device names: AUX, CON, NUL, PRN */
|
||||
+ if (len == 3 && (!av_strncasecmp(p, "AUX", 3) ||
|
||||
+ !av_strncasecmp(p, "CON", 3) ||
|
||||
+ !av_strncasecmp(p, "NUL", 3) ||
|
||||
+ !av_strncasecmp(p, "PRN", 3)))
|
||||
return 1;
|
||||
|
||||
@@ -1789,18 +1805,35 @@ static int safe_filename(const char *f,
|
||||
- p = strchr(p, '/');
|
||||
+ /* Match COM1-9 / LPT1-9 and their UTF-8 superscript aliases */
|
||||
+ if ((len == 4 || len == 5) && (!av_strncasecmp(p, "COM", 3) ||
|
||||
+ !av_strncasecmp(p, "LPT", 3))) {
|
||||
+ /* Standard ASCII digits 1-9 */
|
||||
+ if (len == 4 && *(seg_end - 1) >= '1' && *(seg_end - 1) <= '9')
|
||||
+ return 1;
|
||||
+
|
||||
+ /* UTF-8 superscripts (¹, ², ³) */
|
||||
+ if (len == 5 && (unsigned char)*(seg_end - 2) == 0xC2 &&
|
||||
+ ((unsigned char)*(seg_end - 1) == 0xB9 ||
|
||||
+ (unsigned char)*(seg_end - 1) == 0xB2 ||
|
||||
+ (unsigned char)*(seg_end - 1) == 0xB3))
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ p = next_slash;
|
||||
if (p)
|
||||
p++;
|
||||
}
|
||||
@@ -1802,18 +1833,35 @@ static int safe_filename(const char *f,
|
||||
return 0;
|
||||
|
||||
for (; *f; f++) {
|
||||
@@ -74,7 +116,7 @@ Index: FFmpeg/fftools/ffmpeg_demux.c
|
||||
}
|
||||
|
||||
static int dump_attachment(InputStream *ist, const char *filename)
|
||||
@@ -1817,8 +1850,8 @@ static int dump_attachment(InputStream *
|
||||
@@ -1830,8 +1878,8 @@ static int dump_attachment(InputStream *
|
||||
if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0))) {
|
||||
filename = e->value;
|
||||
if (!safe_filename(filename, 0)) {
|
||||
|
||||
@@ -0,0 +1,651 @@
|
||||
Index: FFmpeg/libavcodec/mf_utils.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/mf_utils.c
|
||||
+++ FFmpeg/libavcodec/mf_utils.c
|
||||
@@ -555,13 +555,14 @@ int ff_instantiate_mf(void *log,
|
||||
MFT_REGISTER_TYPE_INFO *in_type,
|
||||
MFT_REGISTER_TYPE_INFO *out_type,
|
||||
int use_hw,
|
||||
+ const LUID *hw_luid,
|
||||
IMFTransform **res)
|
||||
{
|
||||
HRESULT hr;
|
||||
int n;
|
||||
int ret;
|
||||
- IMFActivate **activate;
|
||||
- UINT32 num_activate;
|
||||
+ IMFActivate **activate = NULL;
|
||||
+ UINT32 num_activate = 0;
|
||||
IMFActivate *winner = 0;
|
||||
UINT32 flags;
|
||||
|
||||
@@ -577,10 +578,26 @@ int ff_instantiate_mf(void *log,
|
||||
flags |= MFT_ENUM_FLAG_SYNCMFT;
|
||||
}
|
||||
|
||||
- hr = f->MFTEnumEx(category, flags, in_type, out_type, &activate,
|
||||
- &num_activate);
|
||||
- if (FAILED(hr))
|
||||
- goto error_uninit_mf;
|
||||
+ // MFTEnum2 is loaded optionally
|
||||
+ if (use_hw && hw_luid && f->MFTEnum2) {
|
||||
+ IMFAttributes *attrs = NULL;
|
||||
+ hr = f->MFCreateAttributes(&attrs, 1);
|
||||
+ if (SUCCEEDED(hr)) {
|
||||
+ hr = IMFAttributes_SetBlob(attrs, &ff_MFT_ENUM_ADAPTER_LUID,
|
||||
+ (const UINT8*)hw_luid, sizeof(*hw_luid));
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ hr = f->MFTEnum2(category, flags, in_type, out_type, attrs,
|
||||
+ &activate, &num_activate);
|
||||
+ IMFAttributes_Release(attrs);
|
||||
+ }
|
||||
+ if (FAILED(hr))
|
||||
+ goto error_uninit_mf;
|
||||
+ } else {
|
||||
+ hr = f->MFTEnumEx(category, flags, in_type, out_type,
|
||||
+ &activate, &num_activate);
|
||||
+ if (FAILED(hr))
|
||||
+ goto error_uninit_mf;
|
||||
+ }
|
||||
|
||||
if (log) {
|
||||
if (!num_activate)
|
||||
Index: FFmpeg/libavcodec/mf_utils.h
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/mf_utils.h
|
||||
+++ FFmpeg/libavcodec/mf_utils.h
|
||||
@@ -51,6 +51,8 @@ typedef struct MFFunctions {
|
||||
HRESULT (WINAPI *MFCreateAlignedMemoryBuffer) (DWORD cbMaxLength,
|
||||
DWORD cbAligment,
|
||||
IMFMediaBuffer **ppBuffer);
|
||||
+ HRESULT (WINAPI *MFCreateAttributes)(IMFAttributes **ppMFAttributes,
|
||||
+ UINT32 cInitialSize);
|
||||
HRESULT (WINAPI *MFCreateSample) (IMFSample **ppIMFSample);
|
||||
HRESULT (WINAPI *MFCreateMediaType) (IMFMediaType **ppMFType);
|
||||
HRESULT (WINAPI *MFCreateDXGISurfaceBuffer) (REFIID riid,
|
||||
@@ -66,6 +68,14 @@ typedef struct MFFunctions {
|
||||
const MFT_REGISTER_TYPE_INFO *pOutputType,
|
||||
IMFActivate ***pppMFTActivate,
|
||||
UINT32 *pnumMFTActivate);
|
||||
+ // MFTEnum2 is missing in pre-Windows 10, version 1703's mfplat.dll.
|
||||
+ // Therefore we load it optionally.
|
||||
+ HRESULT (WINAPI *MFTEnum2)(GUID guidCategory, UINT32 Flags,
|
||||
+ const MFT_REGISTER_TYPE_INFO *pInputType,
|
||||
+ const MFT_REGISTER_TYPE_INFO *pOutputType,
|
||||
+ IMFAttributes *pAttributes,
|
||||
+ IMFActivate ***pppMFTActivate,
|
||||
+ UINT32 *pnumMFTActivate);
|
||||
} MFFunctions;
|
||||
|
||||
// These functions do exist in mfapi.h, but are only available within
|
||||
@@ -122,6 +132,8 @@ DEFINE_MEDIATYPE_GUID(ff_MFVideoFormat_H
|
||||
DEFINE_MEDIATYPE_GUID(ff_MFVideoFormat_HEVC_ES, 0x53564548); // FCC('HEVS')
|
||||
DEFINE_MEDIATYPE_GUID(ff_MFVideoFormat_AV1, 0x31305641); // FCC('AV01')
|
||||
|
||||
+// This enum is missing from mingw-w64's headers
|
||||
+DEFINE_GUID(ff_MFT_ENUM_ADAPTER_LUID, 0x1d39518c, 0xe220, 0x4da8, 0xa0, 0x7f, 0xba, 0x17, 0x25, 0x52, 0xd6, 0xb1);
|
||||
|
||||
// This enum is missing from mingw-w64's codecapi.h by v7.0.0.
|
||||
enum ff_eAVEncCommonRateControlMode {
|
||||
@@ -160,9 +172,19 @@ enum {
|
||||
// header when targeting UWP (where including it with MSVC seems to work,
|
||||
// but fails when built with clang in MSVC mode).
|
||||
enum ff_eAVEncH264VProfile {
|
||||
- ff_eAVEncH264VProfile_Base = 66,
|
||||
- ff_eAVEncH264VProfile_Main = 77,
|
||||
- ff_eAVEncH264VProfile_High = 100,
|
||||
+ ff_eAVEncH264VProfile_Base = 66,
|
||||
+ ff_eAVEncH264VProfile_Main = 77,
|
||||
+ ff_eAVEncH264VProfile_High = 100,
|
||||
+};
|
||||
+
|
||||
+enum ff_eAVEncH265VProfile {
|
||||
+ ff_eAVEncH265VProfile_Main_420_8 = 1,
|
||||
+ ff_eAVEncH265VProfile_Main_420_10 = 2,
|
||||
+};
|
||||
+
|
||||
+enum ff_eAVEncAV1VProfile {
|
||||
+ ff_eAVEncAV1VProfile_Main_420_8 = 1,
|
||||
+ ff_eAVEncAV1VProfile_Main_420_10 = 2,
|
||||
};
|
||||
|
||||
char *ff_hr_str_buf(char *buf, size_t size, HRESULT hr);
|
||||
@@ -188,7 +210,8 @@ const CLSID *ff_codec_to_mf_subtype(enum
|
||||
int ff_instantiate_mf(void *log, MFFunctions *f, GUID category,
|
||||
MFT_REGISTER_TYPE_INFO *in_type,
|
||||
MFT_REGISTER_TYPE_INFO *out_type,
|
||||
- int use_hw, IMFTransform **res);
|
||||
+ int use_hw, const LUID *hw_luid,
|
||||
+ IMFTransform **res);
|
||||
void ff_free_mf(MFFunctions *f, IMFTransform **mft);
|
||||
|
||||
#endif
|
||||
Index: FFmpeg/libavcodec/mfenc.c
|
||||
===================================================================
|
||||
--- FFmpeg.orig/libavcodec/mfenc.c
|
||||
+++ FFmpeg/libavcodec/mfenc.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "encode.h"
|
||||
+#include "hwconfig.h"
|
||||
#include "mf_utils.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/mem.h"
|
||||
@@ -38,10 +39,12 @@
|
||||
typedef struct MFContext {
|
||||
AVClass *av_class;
|
||||
HMODULE library;
|
||||
+#if CONFIG_D3D11VA
|
||||
HMODULE d3d_dll;
|
||||
ID3D11DeviceContext* d3d_context;
|
||||
IMFDXGIDeviceManager *dxgiManager;
|
||||
int resetToken;
|
||||
+#endif
|
||||
|
||||
MFFunctions functions;
|
||||
AVFrame *frame;
|
||||
@@ -64,7 +67,9 @@ typedef struct MFContext {
|
||||
int opt_enc_quality;
|
||||
int opt_enc_scenario;
|
||||
int opt_enc_hw;
|
||||
+#if CONFIG_D3D11VA
|
||||
AVD3D11VADeviceContext* device_hwctx;
|
||||
+#endif
|
||||
} MFContext;
|
||||
|
||||
static int mf_choose_output_type(AVCodecContext *avctx);
|
||||
@@ -327,6 +332,7 @@ static int mf_a_avframe_to_sample(AVCode
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#if CONFIG_D3D11VA
|
||||
static int initialize_dxgi_manager(AVCodecContext *avctx)
|
||||
{
|
||||
MFContext *c = avctx->priv_data;
|
||||
@@ -354,27 +360,65 @@ static int initialize_dxgi_manager(AVCod
|
||||
return 0;
|
||||
}
|
||||
|
||||
+typedef struct MFD3DFrameHolder {
|
||||
+ const IUnknownVtbl *lpVtbl;
|
||||
+ long ref_count;
|
||||
+ AVFrame *frame;
|
||||
+} MFD3DFrameHolder;
|
||||
+
|
||||
+static HRESULT STDMETHODCALLTYPE
|
||||
+MFD3DFrameHolder_QueryInterface(IUnknown *This, REFIID riid, void **ppvObject)
|
||||
+{
|
||||
+ if (!ppvObject)
|
||||
+ return E_POINTER;
|
||||
+ if (IsEqualIID(riid, &IID_IUnknown)) {
|
||||
+ *ppvObject = This;
|
||||
+ This->lpVtbl->AddRef(This);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ *ppvObject = NULL;
|
||||
+ return E_NOINTERFACE;
|
||||
+}
|
||||
+
|
||||
+static ULONG STDMETHODCALLTYPE MFD3DFrameHolder_AddRef(IUnknown *This)
|
||||
+{
|
||||
+ MFD3DFrameHolder *holder = (MFD3DFrameHolder*)This;
|
||||
+ return InterlockedIncrement(&holder->ref_count);
|
||||
+}
|
||||
+
|
||||
+static ULONG STDMETHODCALLTYPE MFD3DFrameHolder_Release(IUnknown *This)
|
||||
+{
|
||||
+ MFD3DFrameHolder *holder = (MFD3DFrameHolder*)This;
|
||||
+ ULONG count = InterlockedDecrement(&holder->ref_count);
|
||||
+ if (!count) {
|
||||
+ av_frame_free(&holder->frame);
|
||||
+ av_free(holder);
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const IUnknownVtbl MFD3DFrameHolder_Vtbl = {
|
||||
+ .QueryInterface = MFD3DFrameHolder_QueryInterface,
|
||||
+ .AddRef = MFD3DFrameHolder_AddRef,
|
||||
+ .Release = MFD3DFrameHolder_Release
|
||||
+};
|
||||
+
|
||||
+static const GUID GUID_MF_D3D_FRAME_HOLDER = {
|
||||
+ 0xd29f874b, 0x370f, 0x402f,
|
||||
+ { 0xa3, 0xaf, 0xb6, 0xd1, 0xed, 0xee, 0xd5, 0xe2 }
|
||||
+};
|
||||
+
|
||||
static int process_d3d11_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
|
||||
{
|
||||
MFContext *c = avctx->priv_data;
|
||||
MFFunctions *func = &c->functions;
|
||||
- AVHWFramesContext *frames_ctx = NULL;
|
||||
ID3D11Texture2D *d3d11_texture = NULL;
|
||||
IMFSample *sample = NULL;
|
||||
IMFMediaBuffer *buffer = NULL;
|
||||
+ MFD3DFrameHolder *holder = NULL;
|
||||
int subIdx = 0;
|
||||
HRESULT hr;
|
||||
|
||||
- frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data;
|
||||
- c->device_hwctx = (AVD3D11VADeviceContext*)frames_ctx->device_ctx->hwctx;
|
||||
-
|
||||
- if (!c->dxgiManager) {
|
||||
- hr = initialize_dxgi_manager(avctx);
|
||||
- if (FAILED(hr)) {
|
||||
- return AVERROR_EXTERNAL;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
d3d11_texture = (ID3D11Texture2D*)frame->data[0];
|
||||
subIdx = (int)(intptr_t)frame->data[1];
|
||||
|
||||
@@ -397,18 +441,41 @@ static int process_d3d11_frame(AVCodecCo
|
||||
}
|
||||
|
||||
hr = IMFSample_AddBuffer(sample, buffer);
|
||||
+ IMFMediaBuffer_Release(buffer);
|
||||
if (FAILED(hr)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Failed to add buffer to sample: %s\n", ff_hr_str(hr));
|
||||
- IMFMediaBuffer_Release(buffer);
|
||||
IMFSample_Release(sample);
|
||||
return AVERROR_EXTERNAL;
|
||||
}
|
||||
|
||||
- IMFMediaBuffer_Release(buffer);
|
||||
+ // Bind the D3D11 frame to the sample to prevent in-flight async
|
||||
+ // frames from being prematurely released back to the frame pool.
|
||||
+ holder = av_mallocz(sizeof(*holder));
|
||||
+ if (!holder) {
|
||||
+ IMFSample_Release(sample);
|
||||
+ return AVERROR(ENOMEM);
|
||||
+ }
|
||||
+ holder->lpVtbl = &MFD3DFrameHolder_Vtbl;
|
||||
+ holder->ref_count = 1;
|
||||
+ holder->frame = av_frame_clone(frame);
|
||||
+ if (!holder->frame) {
|
||||
+ av_free(holder);
|
||||
+ IMFSample_Release(sample);
|
||||
+ return AVERROR(ENOMEM);
|
||||
+ }
|
||||
+
|
||||
+ hr = IMFAttributes_SetUnknown((IMFAttributes*)sample, &GUID_MF_D3D_FRAME_HOLDER, (IUnknown*)holder);
|
||||
+ holder->lpVtbl->Release((IUnknown*)holder);
|
||||
+ if (FAILED(hr)) {
|
||||
+ av_log(avctx, AV_LOG_ERROR, "Failed to bind D3D frame holder to sample: %s\n", ff_hr_str(hr));
|
||||
+ IMFSample_Release(sample);
|
||||
+ return AVERROR_EXTERNAL;
|
||||
+ }
|
||||
|
||||
*out_sample = sample;
|
||||
return 0;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static int process_software_frame(AVCodecContext *avctx, const AVFrame *frame, IMFSample **out_sample)
|
||||
{
|
||||
@@ -464,8 +531,12 @@ static int mf_v_avframe_to_sample(AVCode
|
||||
int ret;
|
||||
|
||||
if (frame->format == AV_PIX_FMT_D3D11) {
|
||||
+#if CONFIG_D3D11VA
|
||||
// Handle D3D11 hardware frames
|
||||
ret = process_d3d11_frame(avctx, frame, &sample);
|
||||
+#else
|
||||
+ ret = AVERROR(ENOSYS);
|
||||
+#endif
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -809,6 +880,8 @@ static int mf_encv_output_adjust(AVCodec
|
||||
{
|
||||
MFContext *c = avctx->priv_data;
|
||||
AVRational framerate;
|
||||
+ enum AVPixelFormat sw_pix_fmt = (avctx->pix_fmt == AV_PIX_FMT_D3D11)
|
||||
+ ? avctx->sw_pix_fmt : avctx->pix_fmt;
|
||||
|
||||
ff_MFSetAttributeSize((IMFAttributes *)type, &MF_MT_FRAME_SIZE, avctx->width, avctx->height);
|
||||
IMFAttributes_SetUINT32(type, &MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive);
|
||||
@@ -821,7 +894,6 @@ static int mf_encv_output_adjust(AVCodec
|
||||
|
||||
ff_MFSetAttributeRatio((IMFAttributes *)type, &MF_MT_FRAME_RATE, framerate.num, framerate.den);
|
||||
|
||||
- // (MS HEVC supports eAVEncH265VProfile_Main_420_8 only.)
|
||||
if (avctx->codec_id == AV_CODEC_ID_H264) {
|
||||
UINT32 profile = ff_eAVEncH264VProfile_Base;
|
||||
switch (avctx->profile) {
|
||||
@@ -833,8 +905,27 @@ static int mf_encv_output_adjust(AVCodec
|
||||
break;
|
||||
}
|
||||
IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
|
||||
+ } else if (avctx->codec_id == AV_CODEC_ID_HEVC) {
|
||||
+ UINT32 profile = ff_eAVEncH265VProfile_Main_420_8;
|
||||
+ switch (sw_pix_fmt) {
|
||||
+ case AV_PIX_FMT_P010:
|
||||
+ profile = ff_eAVEncH265VProfile_Main_420_10;
|
||||
+ break;
|
||||
+ }
|
||||
+ IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
|
||||
+ } else if (avctx->codec_id == AV_CODEC_ID_AV1) {
|
||||
+ UINT32 profile = ff_eAVEncAV1VProfile_Main_420_8;
|
||||
+ switch (sw_pix_fmt) {
|
||||
+ case AV_PIX_FMT_P010:
|
||||
+ profile = ff_eAVEncAV1VProfile_Main_420_10;
|
||||
+ break;
|
||||
+ }
|
||||
+ IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_PROFILE, profile);
|
||||
}
|
||||
|
||||
+ if (avctx->level > 0)
|
||||
+ IMFAttributes_SetUINT32(type, &MF_MT_MPEG2_LEVEL, (UINT32)avctx->level);
|
||||
+
|
||||
IMFAttributes_SetUINT32(type, &MF_MT_AVG_BITRATE, avctx->bit_rate);
|
||||
|
||||
// Note that some of the ICodecAPI options must be set before SetOutputType.
|
||||
@@ -889,11 +980,12 @@ static int64_t mf_encv_input_score(AVCod
|
||||
enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
|
||||
|
||||
if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
|
||||
- if (pix_fmt != AV_PIX_FMT_NV12) {
|
||||
+ if (pix_fmt != avctx->sw_pix_fmt ||
|
||||
+ (pix_fmt != AV_PIX_FMT_NV12 &&
|
||||
+ pix_fmt != AV_PIX_FMT_P010)) {
|
||||
return -1; // can not use
|
||||
}
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
if (pix_fmt != avctx->pix_fmt)
|
||||
return -1; // can not use
|
||||
}
|
||||
@@ -905,7 +997,9 @@ static int mf_encv_input_adjust(AVCodecC
|
||||
{
|
||||
enum AVPixelFormat pix_fmt = ff_media_type_to_pix_fmt((IMFAttributes *)type);
|
||||
if (avctx->pix_fmt == AV_PIX_FMT_D3D11) {
|
||||
- if (pix_fmt != AV_PIX_FMT_NV12 && pix_fmt != AV_PIX_FMT_D3D11) {
|
||||
+ if (pix_fmt != avctx->sw_pix_fmt ||
|
||||
+ (pix_fmt != AV_PIX_FMT_NV12 &&
|
||||
+ pix_fmt != AV_PIX_FMT_P010)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "unsupported input pixel format set\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
@@ -1202,13 +1296,62 @@ err:
|
||||
return res;
|
||||
}
|
||||
|
||||
-static int mf_create(void *log, MFFunctions *f, IMFTransform **mft,
|
||||
+static int get_luid_from_dxgi_adapter(AVCodecContext *avctx, LUID *luid)
|
||||
+{
|
||||
+ int ret = AVERROR_UNKNOWN;
|
||||
+#if CONFIG_D3D11VA
|
||||
+ AVHWFramesContext *frames_ctx = NULL;
|
||||
+ AVHWDeviceContext *dev_ctx = NULL;
|
||||
+ AVD3D11VADeviceContext *hwctx = NULL;
|
||||
+ IDXGIDevice *dxgi_dev = NULL;
|
||||
+ IDXGIAdapter *adapter = NULL;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (!luid)
|
||||
+ return AVERROR(EINVAL);
|
||||
+
|
||||
+ if (avctx->hw_frames_ctx &&
|
||||
+ (frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data))
|
||||
+ dev_ctx = frames_ctx->device_ctx;
|
||||
+
|
||||
+ if (!dev_ctx && avctx->hw_device_ctx)
|
||||
+ dev_ctx = (AVHWDeviceContext *)avctx->hw_device_ctx->data;
|
||||
+
|
||||
+ if (!dev_ctx || dev_ctx->type != AV_HWDEVICE_TYPE_D3D11VA)
|
||||
+ return AVERROR(EINVAL);
|
||||
+
|
||||
+ hwctx = (AVD3D11VADeviceContext *)dev_ctx->hwctx;
|
||||
+
|
||||
+ hr = ID3D11Device_QueryInterface(hwctx->device,
|
||||
+ &IID_IDXGIDevice, (void**)&dxgi_dev);
|
||||
+ if (SUCCEEDED(hr)) {
|
||||
+ hr = IDXGIDevice_GetAdapter(dxgi_dev, &adapter);
|
||||
+ if (SUCCEEDED(hr)) {
|
||||
+ DXGI_ADAPTER_DESC adapter_desc;
|
||||
+ hr = IDXGIAdapter_GetDesc(adapter, &adapter_desc);
|
||||
+ if (SUCCEEDED(hr)) {
|
||||
+ *luid = adapter_desc.AdapterLuid;
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (dxgi_dev)
|
||||
+ IDXGIDevice_Release(dxgi_dev);
|
||||
+ if (adapter)
|
||||
+ IDXGIAdapter_Release(adapter);
|
||||
+#endif
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int mf_create(AVCodecContext *avctx, MFFunctions *f, IMFTransform **mft,
|
||||
const AVCodec *codec, int use_hw)
|
||||
{
|
||||
int is_audio = codec->type == AVMEDIA_TYPE_AUDIO;
|
||||
const CLSID *subtype = ff_codec_to_mf_subtype(codec->id);
|
||||
MFT_REGISTER_TYPE_INFO reg = {0};
|
||||
GUID category;
|
||||
+ const LUID *p_hw_luid = NULL;
|
||||
+ LUID hw_luid = {0};
|
||||
int ret;
|
||||
|
||||
*mft = NULL;
|
||||
@@ -1224,9 +1367,15 @@ static int mf_create(void *log, MFFuncti
|
||||
} else {
|
||||
reg.guidMajorType = MFMediaType_Video;
|
||||
category = MFT_CATEGORY_VIDEO_ENCODER;
|
||||
+
|
||||
+ if (use_hw && avctx->pix_fmt == AV_PIX_FMT_D3D11) {
|
||||
+ ret = get_luid_from_dxgi_adapter(avctx, &hw_luid);
|
||||
+ if (!ret)
|
||||
+ p_hw_luid = &hw_luid;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if ((ret = ff_instantiate_mf(log, f, category, NULL, ®, use_hw, mft)) < 0)
|
||||
+ if ((ret = ff_instantiate_mf(avctx, f, category, NULL, ®, use_hw, p_hw_luid, mft)) < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
@@ -1262,6 +1411,28 @@ static int mf_init_encoder(AVCodecContex
|
||||
if ((ret = mf_unlock_async(avctx)) < 0)
|
||||
return ret;
|
||||
|
||||
+#if CONFIG_D3D11VA
|
||||
+ if (c->is_video && use_hw && avctx->pix_fmt == AV_PIX_FMT_D3D11) {
|
||||
+ AVHWFramesContext *frames_ctx = NULL;
|
||||
+ AVHWDeviceContext *dev_ctx = NULL;
|
||||
+
|
||||
+ if (avctx->hw_frames_ctx &&
|
||||
+ (frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data))
|
||||
+ dev_ctx = frames_ctx->device_ctx;
|
||||
+
|
||||
+ if (!dev_ctx && avctx->hw_device_ctx)
|
||||
+ dev_ctx = (AVHWDeviceContext *)avctx->hw_device_ctx->data;
|
||||
+
|
||||
+ if (!dev_ctx || dev_ctx->type != AV_HWDEVICE_TYPE_D3D11VA)
|
||||
+ return AVERROR(EINVAL);
|
||||
+
|
||||
+ c->device_hwctx = (AVD3D11VADeviceContext *)dev_ctx->hwctx;
|
||||
+
|
||||
+ if ((ret = initialize_dxgi_manager(avctx)) < 0)
|
||||
+ return ret;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
hr = IMFTransform_QueryInterface(c->mft, &IID_ICodecAPI, (void **)&c->codec_api);
|
||||
if (!FAILED(hr))
|
||||
av_log(avctx, AV_LOG_VERBOSE, "MFT supports ICodecAPI.\n");
|
||||
@@ -1309,23 +1480,25 @@ static int mf_init_encoder(AVCodecContex
|
||||
}
|
||||
|
||||
#if !HAVE_UWP
|
||||
-#define LOAD_MF_FUNCTION(context, func_name) \
|
||||
+#define LOAD_MF_FUNCTION(context, func_name, optional) \
|
||||
context->functions.func_name = (void *)dlsym(context->library, #func_name); \
|
||||
if (!context->functions.func_name) { \
|
||||
av_log(context, AV_LOG_ERROR, "DLL mfplat.dll failed to find function "\
|
||||
#func_name "\n"); \
|
||||
- return AVERROR_UNKNOWN; \
|
||||
+ if (!(optional)) \
|
||||
+ return AVERROR_UNKNOWN; \
|
||||
}
|
||||
#else
|
||||
// In UWP (which lacks LoadLibrary), just link directly against
|
||||
// the functions - this requires building with new/complete enough
|
||||
// import libraries.
|
||||
-#define LOAD_MF_FUNCTION(context, func_name) \
|
||||
+#define LOAD_MF_FUNCTION(context, func_name, optional) \
|
||||
context->functions.func_name = func_name; \
|
||||
if (!context->functions.func_name) { \
|
||||
av_log(context, AV_LOG_ERROR, "Failed to find function " #func_name \
|
||||
"\n"); \
|
||||
- return AVERROR_UNKNOWN; \
|
||||
+ if (!(optional)) \
|
||||
+ return AVERROR_UNKNOWN; \
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1338,7 +1511,9 @@ static int mf_load_library(AVCodecContex
|
||||
|
||||
#if !HAVE_UWP
|
||||
c->library = dlopen("mfplat.dll", 0);
|
||||
+#if CONFIG_D3D11VA
|
||||
c->d3d_dll = dlopen("D3D11.dll", 0);
|
||||
+#endif
|
||||
|
||||
if (!c->library) {
|
||||
av_log(c, AV_LOG_ERROR, "DLL mfplat.dll failed to open\n");
|
||||
@@ -1346,15 +1521,23 @@ static int mf_load_library(AVCodecContex
|
||||
}
|
||||
#endif
|
||||
|
||||
- LOAD_MF_FUNCTION(c, MFStartup);
|
||||
- LOAD_MF_FUNCTION(c, MFShutdown);
|
||||
- LOAD_MF_FUNCTION(c, MFCreateAlignedMemoryBuffer);
|
||||
- LOAD_MF_FUNCTION(c, MFCreateSample);
|
||||
- LOAD_MF_FUNCTION(c, MFCreateMediaType);
|
||||
- LOAD_MF_FUNCTION(c, MFCreateDXGISurfaceBuffer);
|
||||
- LOAD_MF_FUNCTION(c, MFCreateDXGIDeviceManager);
|
||||
+ LOAD_MF_FUNCTION(c, MFStartup, 0);
|
||||
+ LOAD_MF_FUNCTION(c, MFShutdown, 0);
|
||||
+ LOAD_MF_FUNCTION(c, MFCreateAlignedMemoryBuffer, 0);
|
||||
+ LOAD_MF_FUNCTION(c, MFCreateAttributes, 0);
|
||||
+ LOAD_MF_FUNCTION(c, MFCreateSample, 0);
|
||||
+ LOAD_MF_FUNCTION(c, MFCreateMediaType, 0);
|
||||
+#if CONFIG_D3D11VA
|
||||
+ LOAD_MF_FUNCTION(c, MFCreateDXGISurfaceBuffer, 0);
|
||||
+ LOAD_MF_FUNCTION(c, MFCreateDXGIDeviceManager, 0);
|
||||
+#endif
|
||||
// MFTEnumEx is missing in Windows Vista's mfplat.dll.
|
||||
- LOAD_MF_FUNCTION(c, MFTEnumEx);
|
||||
+ LOAD_MF_FUNCTION(c, MFTEnumEx, 0);
|
||||
+#if CONFIG_D3D11VA
|
||||
+ // MFTEnum2 is missing in pre-Windows 10, version 1703's mfplat.dll.
|
||||
+ // Therefore we load it optionally.
|
||||
+ LOAD_MF_FUNCTION(c, MFTEnum2, 1);
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1369,15 +1552,19 @@ static int mf_close(AVCodecContext *avct
|
||||
if (c->async_events)
|
||||
IMFMediaEventGenerator_Release(c->async_events);
|
||||
|
||||
+#if CONFIG_D3D11VA
|
||||
if (c->dxgiManager)
|
||||
IMFDXGIDeviceManager_Release(c->dxgiManager);
|
||||
+#endif
|
||||
|
||||
#if !HAVE_UWP
|
||||
if (c->library)
|
||||
ff_free_mf(&c->functions, &c->mft);
|
||||
|
||||
dlclose(c->library);
|
||||
+#if CONFIG_D3D11VA
|
||||
dlclose(c->d3d_dll);
|
||||
+#endif
|
||||
c->library = NULL;
|
||||
#else
|
||||
ff_free_mf(&c->functions, &c->mft);
|
||||
@@ -1404,7 +1591,7 @@ static av_cold int mf_init(AVCodecContex
|
||||
|
||||
#define OFFSET(x) offsetof(MFContext, x)
|
||||
|
||||
-#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS, DEFAULTS) \
|
||||
+#define MF_ENCODER(MEDIATYPE, NAME, ID, OPTS, FMTS, CAPS, DEFAULTS, HWCONFIGS) \
|
||||
static const AVClass ff_ ## NAME ## _mf_encoder_class = { \
|
||||
.class_name = #NAME "_mf", \
|
||||
.item_name = av_default_item_name, \
|
||||
@@ -1425,6 +1612,7 @@ static av_cold int mf_init(AVCodecContex
|
||||
CAPS \
|
||||
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP, \
|
||||
.defaults = DEFAULTS, \
|
||||
+ .hw_configs = HWCONFIGS, \
|
||||
};
|
||||
|
||||
#define AFMTS \
|
||||
@@ -1433,9 +1621,9 @@ static av_cold int mf_init(AVCodecContex
|
||||
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
|
||||
AV_CODEC_CAP_DR1 | AV_CODEC_CAP_VARIABLE_FRAME_SIZE,
|
||||
|
||||
-MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS, ACAPS, NULL);
|
||||
-MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS, ACAPS, NULL);
|
||||
-MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS, ACAPS, NULL);
|
||||
+MF_ENCODER(AUDIO, aac, AAC, NULL, AFMTS, ACAPS, NULL, NULL);
|
||||
+MF_ENCODER(AUDIO, ac3, AC3, NULL, AFMTS, ACAPS, NULL, NULL);
|
||||
+MF_ENCODER(AUDIO, mp3, MP3, NULL, AFMTS, ACAPS, NULL, NULL);
|
||||
|
||||
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
|
||||
static const AVOption venc_opts[] = {
|
||||
@@ -1469,12 +1657,42 @@ static const FFCodecDefault defaults[] =
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
-#define VFMTS \
|
||||
- CODEC_PIXFMTS(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_D3D11),
|
||||
+static const AVCodecHWConfigInternal *const hw_configs[] = {
|
||||
+#if CONFIG_D3D11VA
|
||||
+ HW_CONFIG_ENCODER_FRAMES(D3D11, D3D11VA),
|
||||
+ HW_CONFIG_ENCODER_DEVICE(NONE, D3D11VA),
|
||||
+#endif
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const enum AVPixelFormat pix_fmts_10b_8b[] = {
|
||||
+ AV_PIX_FMT_NV12,
|
||||
+ AV_PIX_FMT_YUV420P,
|
||||
+ AV_PIX_FMT_P010,
|
||||
+#if CONFIG_D3D11VA
|
||||
+ AV_PIX_FMT_D3D11,
|
||||
+#endif
|
||||
+ AV_PIX_FMT_NONE
|
||||
+};
|
||||
+
|
||||
+static const enum AVPixelFormat pix_fmts_8b[] = {
|
||||
+ AV_PIX_FMT_NV12,
|
||||
+ AV_PIX_FMT_YUV420P,
|
||||
+#if CONFIG_D3D11VA
|
||||
+ AV_PIX_FMT_D3D11,
|
||||
+#endif
|
||||
+ AV_PIX_FMT_NONE
|
||||
+};
|
||||
+
|
||||
+#define VFMTS8 \
|
||||
+ CODEC_PIXFMTS_ARRAY(pix_fmts_8b),
|
||||
+#define VFMTS10 \
|
||||
+ CODEC_PIXFMTS_ARRAY(pix_fmts_10b_8b),
|
||||
#define VCAPS \
|
||||
+ .color_ranges = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG, \
|
||||
.p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID | \
|
||||
AV_CODEC_CAP_DR1,
|
||||
|
||||
-MF_ENCODER(VIDEO, h264, H264, venc_opts, VFMTS, VCAPS, defaults);
|
||||
-MF_ENCODER(VIDEO, hevc, HEVC, venc_opts, VFMTS, VCAPS, defaults);
|
||||
-MF_ENCODER(VIDEO, av1, AV1, venc_opts, VFMTS, VCAPS, defaults);
|
||||
+MF_ENCODER(VIDEO, h264, H264, venc_opts, VFMTS8, VCAPS, defaults, hw_configs);
|
||||
+MF_ENCODER(VIDEO, hevc, HEVC, venc_opts, VFMTS10, VCAPS, defaults, hw_configs);
|
||||
+MF_ENCODER(VIDEO, av1, AV1, venc_opts, VFMTS10, VCAPS, defaults, hw_configs);
|
||||
Vendored
+1
@@ -94,3 +94,4 @@
|
||||
0094-add-d3d11-tonemap-filter.patch
|
||||
0095-add-scale-d3d11-p010-shader-fallback.patch
|
||||
0096-fix-full-range-input-for-mjpeg-vaapi-encoder.patch
|
||||
0097-add-misc-enhancements-to-mfenc-hw-encoder.patch
|
||||
|
||||
Vendored
+8
-5
@@ -14,8 +14,11 @@ CONFIG := --prefix=${TARGET_DIR} \
|
||||
--disable-ffplay \
|
||||
--disable-static \
|
||||
--disable-libxcb \
|
||||
--disable-sdl2 \
|
||||
--disable-libxcb-shm \
|
||||
--disable-libxcb-xfixes \
|
||||
--disable-libxcb-shape \
|
||||
--disable-xlib \
|
||||
--disable-sdl2 \
|
||||
--enable-lto=auto \
|
||||
--enable-gpl \
|
||||
--enable-version3 \
|
||||
@@ -46,6 +49,10 @@ CONFIG := --prefix=${TARGET_DIR} \
|
||||
--enable-libzvbi \
|
||||
--enable-libzimg \
|
||||
--enable-libfdk-aac \
|
||||
--enable-libshaderc \
|
||||
--enable-libplacebo \
|
||||
--enable-vulkan \
|
||||
--enable-vaapi \
|
||||
--enable-ffnvcodec \
|
||||
--enable-cuda \
|
||||
--enable-cuda-llvm \
|
||||
@@ -54,10 +61,6 @@ CONFIG := --prefix=${TARGET_DIR} \
|
||||
--enable-nvenc \
|
||||
|
||||
CONFIG_x86 := --arch=amd64 \
|
||||
--enable-libshaderc \
|
||||
--enable-libplacebo \
|
||||
--enable-vulkan \
|
||||
--enable-vaapi \
|
||||
--enable-libvpl \
|
||||
--enable-amf \
|
||||
|
||||
|
||||
@@ -623,6 +623,7 @@ fi
|
||||
--enable-opencl \
|
||||
--enable-dxva2 \
|
||||
--enable-d3d11va \
|
||||
--enable-mediafoundation \
|
||||
--enable-amf \
|
||||
--enable-libvpl \
|
||||
--enable-ffnvcodec \
|
||||
|
||||
+278
-217
@@ -177,6 +177,40 @@ prepare_extra_common() {
|
||||
popd
|
||||
popd
|
||||
|
||||
# OGG
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v1.3.6 --depth=1 https://github.com/xiph/ogg.git
|
||||
pushd ogg
|
||||
./autogen.sh
|
||||
./configure \
|
||||
${CROSS_OPT} \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--disable-static \
|
||||
--enable-shared \
|
||||
--with-pic
|
||||
make -j$(nproc) && make install && make install DESTDIR=${SOURCE_DIR}/ogg
|
||||
echo "ogg${TARGET_DIR}/lib/libogg.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# THEORA
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v1.2.0 --depth=1 https://github.com/xiph/theora.git
|
||||
pushd theora
|
||||
# autotools: relax autoconf requirement to 2.69
|
||||
wget -q -O - https://github.com/xiph/theora/commit/3ae2669.patch | git apply
|
||||
./autogen.sh
|
||||
./configure \
|
||||
${CROSS_OPT} \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--disable-{static,examples,extra-programs,oggtest,vorbistest,spec,doc} \
|
||||
--enable-shared \
|
||||
--with-pic
|
||||
make -j$(nproc) && make install && make install DESTDIR=${SOURCE_DIR}/theora
|
||||
echo "theora${TARGET_DIR}/lib/libtheora{enc,dec}.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# FFTW3
|
||||
pushd ${SOURCE_DIR}
|
||||
mkdir fftw3
|
||||
@@ -208,7 +242,7 @@ prepare_extra_common() {
|
||||
|
||||
# CHROMAPRINT
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone --depth=1 https://github.com/acoustid/chromaprint.git
|
||||
git clone -b v1.6.0 --depth=1 https://github.com/acoustid/chromaprint.git
|
||||
pushd chromaprint
|
||||
echo "Libs.private: -lfftw3f -lstdc++" >> libchromaprint.pc.cmake
|
||||
echo "Cflags.private: -DCHROMAPRINT_NODLL" >> libchromaprint.pc.cmake
|
||||
@@ -230,7 +264,7 @@ prepare_extra_common() {
|
||||
|
||||
# ZIMG
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone --recursive --depth=1 https://github.com/sekrit-twc/zimg.git
|
||||
git clone -b release-3.0.6 --recursive --depth=1 https://github.com/sekrit-twc/zimg.git
|
||||
pushd zimg
|
||||
./autogen.sh
|
||||
./configure --prefix=${TARGET_DIR} ${CROSS_OPT}
|
||||
@@ -300,6 +334,246 @@ prepare_extra_common() {
|
||||
make PREFIX=${TARGET_DIR} install
|
||||
popd
|
||||
popd
|
||||
|
||||
# Install crossbuild dependencies
|
||||
apt-get install -y lib{udev,pciaccess,zstd,elf,expat1}-dev:${ARCH}
|
||||
|
||||
# LIBDRM
|
||||
pushd ${SOURCE_DIR}
|
||||
mkdir libdrm
|
||||
pushd libdrm
|
||||
libdrm_ver="libdrm-2.4.131"
|
||||
libdrm_link="https://gitlab.freedesktop.org/mesa/libdrm/-/archive/${libdrm_ver}/libdrm-${libdrm_ver}.tar.gz"
|
||||
wget ${libdrm_link} -O libdrm.tar.gz
|
||||
tar xaf libdrm.tar.gz
|
||||
meson setup libdrm-${libdrm_ver} drm_build \
|
||||
${MESON_CROSS_OPT} \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--libdir=lib \
|
||||
--buildtype=release \
|
||||
-D{udev,tests,install-test-programs}=false \
|
||||
-D{amdgpu,radeon,intel}=enabled \
|
||||
-D{etnaviv,valgrind,freedreno,vc4,vmwgfx,nouveau,man-pages}=disabled
|
||||
meson configure drm_build
|
||||
ninja -j$(nproc) -C drm_build install
|
||||
cp -a ${TARGET_DIR}/lib/libdrm*.so* ${SOURCE_DIR}/libdrm
|
||||
cp ${TARGET_DIR}/share/libdrm/*.ids ${SOURCE_DIR}/libdrm
|
||||
echo "libdrm/libdrm*.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
echo "libdrm/*.ids usr/lib/jellyfin-ffmpeg/share/libdrm" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# LIBVA
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b 2.24.1 --depth=1 https://github.com/intel/libva.git
|
||||
pushd libva
|
||||
if [ "${ARCH}" = "arm64" ]; then
|
||||
libva_drv_arch_path="/usr/lib/aarch64-linux-gnu/dri"
|
||||
else
|
||||
libva_drv_arch_path="/usr/lib/x86_64-linux-gnu/dri"
|
||||
fi
|
||||
sed -i "s#secure_getenv(\"LIBVA_DRIVERS_PATH\")#\"/usr/lib/jellyfin-ffmpeg/lib/dri:${libva_drv_arch_path}:/usr/lib/dri:/usr/local/lib/dri\"#g" va/va.c
|
||||
sed -i "s#secure_getenv(\"LIBVA_DRIVER_NAME\")#secure_getenv(\"LIBVA_DRIVER_NAME_JELLYFIN\")#g" va/va.c
|
||||
./autogen.sh
|
||||
./configure \
|
||||
${CROSS_OPT} \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--enable-drm \
|
||||
--disable-{glx,x11,wayland,docs}
|
||||
make -j$(nproc) && make install && make install DESTDIR=${SOURCE_DIR}/intel
|
||||
echo "intel${TARGET_DIR}/lib/libva.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
echo "intel${TARGET_DIR}/lib/libva-drm.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# LIBVA-UTILS
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b 2.24.0 --depth=1 https://github.com/intel/libva-utils.git
|
||||
pushd libva-utils
|
||||
./autogen.sh
|
||||
./configure \
|
||||
${CROSS_OPT} \
|
||||
--prefix=${TARGET_DIR}
|
||||
make -j$(nproc) && make install && make install DESTDIR=${SOURCE_DIR}/intel
|
||||
echo "intel${TARGET_DIR}/bin/vainfo usr/lib/jellyfin-ffmpeg" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# Vulkan Headers
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v1.4.355 --depth=1 https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
pushd Vulkan-Headers
|
||||
mkdir build && pushd build
|
||||
cmake \
|
||||
${CMAKE_TOOLCHAIN_OPT} \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${TARGET_DIR} ..
|
||||
make -j$(nproc) && make install
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
# Vulkan ICD Loader
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v1.4.355 --depth=1 https://github.com/KhronosGroup/Vulkan-Loader.git
|
||||
pushd Vulkan-Loader
|
||||
sed -i 's/memset(disable_struct, 0, sizeof.*);/& disable_struct->disable_all_implicit = 1;/' loader/loader_environment.c
|
||||
mkdir build && pushd build
|
||||
cmake \
|
||||
${CMAKE_TOOLCHAIN_OPT} \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \
|
||||
-DVULKAN_HEADERS_INSTALL_DIR="${TARGET_DIR}" \
|
||||
-DCMAKE_INSTALL_SYSCONFDIR=${TARGET_DIR}/share \
|
||||
-DCMAKE_INSTALL_DATADIR=${TARGET_DIR}/share \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DBUILD_TESTS=OFF \
|
||||
-DBUILD_WSI_{XCB,XLIB,XLIB_XRANDR,WAYLAND}_SUPPORT=OFF ..
|
||||
make -j$(nproc) && make install
|
||||
cp -a ${TARGET_DIR}/lib/libvulkan.so* ${SOURCE_DIR}/Vulkan-Loader
|
||||
echo "Vulkan-Loader/libvulkan.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
# SHADERC
|
||||
shaderc_ver="v2026.2"
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b ${shaderc_ver} --depth=1 https://github.com/google/shaderc.git
|
||||
pushd shaderc
|
||||
./utils/git-sync-deps
|
||||
shaderc_conf=$(echo -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DSHADERC_SKIP_{TESTS,EXAMPLES,COPYRIGHT_CHECK}=ON \
|
||||
-DENABLE_EXCEPTIONS=ON \
|
||||
-DSPIRV_SKIP_EXECUTABLES=ON \
|
||||
-DSPIRV_TOOLS_BUILD_STATIC=ON \
|
||||
-DBUILD_SHARED_LIBS=OFF)
|
||||
# Build native glslangValidator for crossbuild
|
||||
if [ "${ARCH}" != "amd64" ]; then
|
||||
mkdir glslang_build && pushd glslang_build
|
||||
cmake $shaderc_conf \
|
||||
-DENABLE_GLSLANG_BINARIES=ON ..
|
||||
ninja -j$(nproc) third_party/glslang/StandAlone/glslang
|
||||
cp third_party/glslang/StandAlone/glslangValidator ${TARGET_DIR}/bin
|
||||
popd
|
||||
fi
|
||||
# Build target shaderc
|
||||
mkdir shaderc_build && pushd shaderc_build
|
||||
cmake $shaderc_conf \
|
||||
${CMAKE_TOOLCHAIN_OPT} \
|
||||
-DENABLE_GLSLANG_BINARIES=$([ "${ARCH}" = "amd64" ] && echo "ON" || echo "OFF") \
|
||||
-DCMAKE_INSTALL_PREFIX=${TARGET_DIR} ..
|
||||
ninja -j$(nproc)
|
||||
ninja install
|
||||
cp -a ${TARGET_DIR}/lib/libshaderc_shared.so* ${SOURCE_DIR}/shaderc
|
||||
echo "shaderc/libshaderc_shared* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
# MESA
|
||||
# Minimal libs for AMD VAAPI, AMD RADV and Intel ANV
|
||||
if [[ ${LLVM_VER} -ge 15 ]]; then
|
||||
if [[ "${ARCH}" = "amd64" && ${LLVMSPIRVLIB_VER} -ge 15 && ${LLVMSPIRVLIB_VER} -le 21 ]]; then
|
||||
# Intel ANV requires llvmspirvlib >= 15 (and <= 21 in mesa 26.0)
|
||||
mesa_vk_drv="amd,intel"
|
||||
mesa_llvm_clc="enabled"
|
||||
apt-get install -y {llvm-,libllvmspirvlib-,libclc-,libclang-,libclang-cpp}${LLVMSPIRVLIB_VER}-dev
|
||||
else
|
||||
mesa_vk_drv="amd"
|
||||
mesa_llvm_clc="disabled"
|
||||
fi
|
||||
pushd ${SOURCE_DIR}
|
||||
mkdir mesa
|
||||
pushd mesa
|
||||
mesa_ver="mesa-26.0.8"
|
||||
mesa_link="https://gitlab.freedesktop.org/mesa/mesa/-/archive/${mesa_ver}/mesa-${mesa_ver}.tar.gz"
|
||||
wget ${mesa_link} -O mesa.tar.gz
|
||||
tar xaf mesa.tar.gz
|
||||
# Enable VAAPI VPP alpha blending support
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41090.patch | \
|
||||
patch -p1 -d mesa-${mesa_ver}
|
||||
# Fix misc CSC issues in VAAPI VPP
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42181.patch | \
|
||||
patch -p1 -d mesa-${mesa_ver}
|
||||
# Fix setting VPE rotation with horizontal flip enabled
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42408.patch | \
|
||||
sed 's#/mm/#/#g' | patch -p1 -d mesa-${mesa_ver}
|
||||
# Fix setting chroma swizzle mode in VK Video on GFX9
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42763.patch | \
|
||||
patch -p1 -d mesa-${mesa_ver}
|
||||
meson setup mesa-${mesa_ver} mesa_build \
|
||||
${MESON_CROSS_OPT} \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--libdir=lib \
|
||||
--buildtype=release \
|
||||
--wrap-mode=nofallback \
|
||||
-Db_ndebug=true \
|
||||
-Db_lto=false \
|
||||
-Dplatforms=[] \
|
||||
-Dgallium-drivers=radeonsi \
|
||||
-Dvulkan-drivers=${mesa_vk_drv} \
|
||||
-Dvulkan-layers=[] \
|
||||
-Dvulkan-manifest-per-architecture=true \
|
||||
-Degl=disabled \
|
||||
-Dgallium-{extra-hud,rusticl}=false \
|
||||
-Dgallium-mediafoundation=disabled \
|
||||
-Dgallium-va=enabled \
|
||||
-Dvideo-codecs=all \
|
||||
-Dgbm=disabled \
|
||||
-Dgles1=disabled \
|
||||
-Dgles2=disabled \
|
||||
-Dopengl=false \
|
||||
-Dglvnd=disabled \
|
||||
-Dglx=disabled \
|
||||
-Dlibunwind=disabled \
|
||||
-Dllvm=${mesa_llvm_clc} \
|
||||
-Damd-use-llvm=false \
|
||||
-Dlmsensors=disabled \
|
||||
-Dvalgrind=disabled \
|
||||
-Dtools=[] \
|
||||
-Dzstd=enabled \
|
||||
-Dmicrosoft-clc=disabled \
|
||||
-Dintel-elk=false
|
||||
meson configure mesa_build
|
||||
ninja -j$(nproc) -C mesa_build install
|
||||
cp -a ${TARGET_DIR}/lib/libvulkan_*.so ${SOURCE_DIR}/mesa
|
||||
# radeonsi_drv_video.so -> libgallium_drv_video.so is soft link
|
||||
cp ${TARGET_DIR}/lib/dri/radeonsi_drv_video.so ${SOURCE_DIR}/mesa
|
||||
echo "mesa/lib*.so usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
echo "mesa/radeonsi_drv_video.so usr/lib/jellyfin-ffmpeg/lib/dri" >> ${DPKG_INSTALL_LIST}
|
||||
cp ${TARGET_DIR}/share/drirc.d/*.conf ${SOURCE_DIR}/mesa
|
||||
echo "mesa/*defaults.conf usr/lib/jellyfin-ffmpeg/share/drirc.d" >> ${DPKG_INSTALL_LIST}
|
||||
cp ${TARGET_DIR}/share/vulkan/icd.d/*.json ${SOURCE_DIR}/mesa
|
||||
echo "mesa/*icd.*.json usr/lib/jellyfin-ffmpeg/share/vulkan/icd.d" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
fi
|
||||
|
||||
# LIBPLACEBO
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v7.360.1 --recursive --depth=1 https://github.com/haasn/libplacebo.git
|
||||
# Fix bit shift when importing P01x non-multiplane image
|
||||
git -C libplacebo apply ${SOURCE_DIR}/builder/patches/libplacebo/*.patch
|
||||
sed -i 's/env: python_env,//g' libplacebo/src/vulkan/meson.build
|
||||
meson setup libplacebo placebo_build \
|
||||
${MESON_CROSS_OPT} \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--libdir=lib \
|
||||
--buildtype=release \
|
||||
--default-library=shared \
|
||||
-Dvulkan=enabled \
|
||||
-Dvk-proc-addr=enabled \
|
||||
-Dvulkan-registry=${TARGET_DIR}/share/vulkan/registry/vk.xml \
|
||||
-Dshaderc=enabled \
|
||||
-Dglslang=disabled \
|
||||
-D{demos,tests,bench,fuzz}=false
|
||||
meson configure placebo_build
|
||||
ninja -j$(nproc) -C placebo_build install
|
||||
cp -a ${TARGET_DIR}/lib/libplacebo.so* ${SOURCE_DIR}/libplacebo
|
||||
echo "libplacebo/libplacebo* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
}
|
||||
|
||||
# Prepare extra headers, libs and drivers for x86_64-linux-gnu
|
||||
@@ -320,58 +594,6 @@ prepare_extra_amd64() {
|
||||
popd
|
||||
popd
|
||||
|
||||
# LIBDRM
|
||||
pushd ${SOURCE_DIR}
|
||||
mkdir libdrm
|
||||
pushd libdrm
|
||||
libdrm_ver="libdrm-2.4.131"
|
||||
libdrm_link="https://gitlab.freedesktop.org/mesa/libdrm/-/archive/${libdrm_ver}/libdrm-${libdrm_ver}.tar.gz"
|
||||
wget ${libdrm_link} -O libdrm.tar.gz
|
||||
tar xaf libdrm.tar.gz
|
||||
meson setup libdrm-${libdrm_ver} drm_build \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--libdir=lib \
|
||||
--buildtype=release \
|
||||
-D{udev,tests,install-test-programs}=false \
|
||||
-D{amdgpu,radeon,intel}=enabled \
|
||||
-D{valgrind,freedreno,vc4,vmwgfx,nouveau,man-pages}=disabled
|
||||
meson configure drm_build
|
||||
ninja -j$(nproc) -C drm_build install
|
||||
cp -a ${TARGET_DIR}/lib/libdrm*.so* ${SOURCE_DIR}/libdrm
|
||||
cp ${TARGET_DIR}/share/libdrm/*.ids ${SOURCE_DIR}/libdrm
|
||||
echo "libdrm/libdrm*.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
echo "libdrm/*.ids usr/lib/jellyfin-ffmpeg/share/libdrm" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# LIBVA
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b 2.24.1 --depth=1 https://github.com/intel/libva.git
|
||||
pushd libva
|
||||
sed -i 's|secure_getenv("LIBVA_DRIVERS_PATH")|"/usr/lib/jellyfin-ffmpeg/lib/dri:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/dri:/usr/local/lib/dri"|g' va/va.c
|
||||
sed -i 's|secure_getenv("LIBVA_DRIVER_NAME")|secure_getenv("LIBVA_DRIVER_NAME_JELLYFIN")|g' va/va.c
|
||||
./autogen.sh
|
||||
./configure \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--enable-drm \
|
||||
--disable-{glx,x11,wayland,docs}
|
||||
make -j$(nproc) && make install && make install DESTDIR=${SOURCE_DIR}/intel
|
||||
echo "intel${TARGET_DIR}/lib/libva.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
echo "intel${TARGET_DIR}/lib/libva-drm.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# LIBVA-UTILS
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b 2.24.0 --depth=1 https://github.com/intel/libva-utils.git
|
||||
pushd libva-utils
|
||||
./autogen.sh
|
||||
./configure --prefix=${TARGET_DIR}
|
||||
make -j$(nproc) && make install && make install DESTDIR=${SOURCE_DIR}/intel
|
||||
echo "intel${TARGET_DIR}/bin/vainfo usr/lib/jellyfin-ffmpeg" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
|
||||
# INTEL-VAAPI-DRIVER
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone --depth=1 https://github.com/intel/intel-vaapi-driver.git
|
||||
@@ -492,169 +714,6 @@ prepare_extra_amd64() {
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
# Vulkan Headers
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v1.4.355 --depth=1 https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
pushd Vulkan-Headers
|
||||
mkdir build && pushd build
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${TARGET_DIR} ..
|
||||
make -j$(nproc) && make install
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
# Vulkan ICD Loader
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v1.4.355 --depth=1 https://github.com/KhronosGroup/Vulkan-Loader.git
|
||||
pushd Vulkan-Loader
|
||||
mkdir build && pushd build
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \
|
||||
-DVULKAN_HEADERS_INSTALL_DIR="${TARGET_DIR}" \
|
||||
-DCMAKE_INSTALL_SYSCONFDIR=${TARGET_DIR}/share \
|
||||
-DCMAKE_INSTALL_DATADIR=${TARGET_DIR}/share \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DBUILD_TESTS=OFF \
|
||||
-DBUILD_WSI_{XCB,XLIB,WAYLAND}_SUPPORT=ON ..
|
||||
make -j$(nproc) && make install
|
||||
cp -a ${TARGET_DIR}/lib/libvulkan.so* ${SOURCE_DIR}/Vulkan-Loader
|
||||
echo "Vulkan-Loader/libvulkan.so* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
# SHADERC
|
||||
shaderc_ver="v2026.2"
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b ${shaderc_ver} --depth=1 https://github.com/google/shaderc.git
|
||||
pushd shaderc
|
||||
./utils/git-sync-deps
|
||||
mkdir build && pushd build
|
||||
cmake \
|
||||
-GNinja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${TARGET_DIR} \
|
||||
-DSHADERC_SKIP_{TESTS,EXAMPLES,COPYRIGHT_CHECK}=ON \
|
||||
-DENABLE_{GLSLANG_BINARIES,EXCEPTIONS}=ON \
|
||||
-DENABLE_CTEST=OFF \
|
||||
-DSPIRV_SKIP_EXECUTABLES=ON \
|
||||
-DSPIRV_TOOLS_BUILD_STATIC=ON \
|
||||
-DBUILD_SHARED_LIBS=OFF ..
|
||||
ninja -j$(nproc)
|
||||
ninja install
|
||||
cp -a ${TARGET_DIR}/lib/libshaderc_shared.so* ${SOURCE_DIR}/shaderc
|
||||
echo "shaderc/libshaderc_shared* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
|
||||
# MESA
|
||||
# Minimal libs for AMD VAAPI, AMD RADV and Intel ANV
|
||||
if [[ ${LLVM_VER} -ge 15 ]]; then
|
||||
if [[ ${LLVMSPIRVLIB_VER} -ge 15 && ${LLVMSPIRVLIB_VER} -le 21 ]]; then
|
||||
# Intel ANV requires llvmspirvlib >= 15 (and <= 21 in mesa 26.0)
|
||||
mesa_vk_drv="amd,intel"
|
||||
mesa_llvm_clc="enabled"
|
||||
apt-get install -y {llvm-,libllvmspirvlib-,libclc-,libclang-,libclang-cpp}${LLVMSPIRVLIB_VER}-dev libudev-dev
|
||||
else
|
||||
mesa_vk_drv="amd"
|
||||
mesa_llvm_clc="disabled"
|
||||
apt-get install -y libudev-dev
|
||||
fi
|
||||
pushd ${SOURCE_DIR}
|
||||
mkdir mesa
|
||||
pushd mesa
|
||||
mesa_ver="mesa-26.0.8"
|
||||
mesa_link="https://gitlab.freedesktop.org/mesa/mesa/-/archive/${mesa_ver}/mesa-${mesa_ver}.tar.gz"
|
||||
wget ${mesa_link} -O mesa.tar.gz
|
||||
tar xaf mesa.tar.gz
|
||||
# Enable VAAPI VPP alpha blending support
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41090.patch | \
|
||||
patch -p1 -d mesa-${mesa_ver}
|
||||
# Fix misc CSC issues in VAAPI VPP
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42181.patch | \
|
||||
patch -p1 -d mesa-${mesa_ver}
|
||||
# Fix setting VPE rotation with horizontal flip enabled
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42408.patch | \
|
||||
sed 's#/mm/#/#g' | patch -p1 -d mesa-${mesa_ver}
|
||||
# Fix setting chroma swizzle mode in VK Video on GFX9
|
||||
wget -q -O - https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42763.patch | \
|
||||
patch -p1 -d mesa-${mesa_ver}
|
||||
meson setup mesa-${mesa_ver} mesa_build \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--libdir=lib \
|
||||
--buildtype=release \
|
||||
--wrap-mode=nofallback \
|
||||
-Db_ndebug=true \
|
||||
-Db_lto=false \
|
||||
-Dplatforms=x11 \
|
||||
-Dgallium-drivers=radeonsi \
|
||||
-Dvulkan-drivers=${mesa_vk_drv} \
|
||||
-Dvulkan-layers=device-select \
|
||||
-Dvulkan-manifest-per-architecture=true \
|
||||
-Degl=disabled \
|
||||
-Dgallium-{extra-hud,rusticl}=false \
|
||||
-Dgallium-mediafoundation=disabled \
|
||||
-Dgallium-va=enabled \
|
||||
-Dvideo-codecs=all \
|
||||
-Dgbm=disabled \
|
||||
-Dgles1=disabled \
|
||||
-Dgles2=disabled \
|
||||
-Dopengl=false \
|
||||
-Dglvnd=disabled \
|
||||
-Dglx=disabled \
|
||||
-Dlibunwind=disabled \
|
||||
-Dllvm=${mesa_llvm_clc} \
|
||||
-Damd-use-llvm=false \
|
||||
-Dlmsensors=disabled \
|
||||
-Dvalgrind=disabled \
|
||||
-Dtools=[] \
|
||||
-Dzstd=enabled \
|
||||
-Dmicrosoft-clc=disabled \
|
||||
-Dintel-elk=false
|
||||
meson configure mesa_build
|
||||
ninja -j$(nproc) -C mesa_build install
|
||||
cp -a ${TARGET_DIR}/lib/libvulkan_*.so ${SOURCE_DIR}/mesa
|
||||
cp -a ${TARGET_DIR}/lib/libVkLayer_MESA_device_select.so ${SOURCE_DIR}/mesa
|
||||
# radeonsi_drv_video.so -> libgallium_drv_video.so is soft link
|
||||
cp ${TARGET_DIR}/lib/dri/radeonsi_drv_video.so ${SOURCE_DIR}/mesa
|
||||
echo "mesa/lib*.so usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
echo "mesa/radeonsi_drv_video.so usr/lib/jellyfin-ffmpeg/lib/dri" >> ${DPKG_INSTALL_LIST}
|
||||
cp ${TARGET_DIR}/share/drirc.d/*.conf ${SOURCE_DIR}/mesa
|
||||
echo "mesa/*defaults.conf usr/lib/jellyfin-ffmpeg/share/drirc.d" >> ${DPKG_INSTALL_LIST}
|
||||
cp ${TARGET_DIR}/share/vulkan/{icd.d,implicit_layer.d}/*.json ${SOURCE_DIR}/mesa
|
||||
echo "mesa/*icd.x86_64.json usr/lib/jellyfin-ffmpeg/share/vulkan/icd.d" >> ${DPKG_INSTALL_LIST}
|
||||
echo "mesa/*device_select.json usr/lib/jellyfin-ffmpeg/share/vulkan/implicit_layer.d" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
popd
|
||||
fi
|
||||
|
||||
# LIBPLACEBO
|
||||
pushd ${SOURCE_DIR}
|
||||
git clone -b v7.360.1 --recursive --depth=1 https://github.com/haasn/libplacebo.git
|
||||
# Fix bit shift when importing P01x non-multiplane image
|
||||
git -C libplacebo apply ${SOURCE_DIR}/builder/patches/libplacebo/*.patch
|
||||
sed -i 's/env: python_env,//g' libplacebo/src/vulkan/meson.build
|
||||
meson setup libplacebo placebo_build \
|
||||
--prefix=${TARGET_DIR} \
|
||||
--libdir=lib \
|
||||
--buildtype=release \
|
||||
--default-library=shared \
|
||||
-Dvulkan=enabled \
|
||||
-Dvk-proc-addr=enabled \
|
||||
-Dvulkan-registry=${TARGET_DIR}/share/vulkan/registry/vk.xml \
|
||||
-Dshaderc=enabled \
|
||||
-Dglslang=disabled \
|
||||
-D{demos,tests,bench,fuzz}=false
|
||||
meson configure placebo_build
|
||||
ninja -j$(nproc) -C placebo_build install
|
||||
cp -a ${TARGET_DIR}/lib/libplacebo.so* ${SOURCE_DIR}/libplacebo
|
||||
echo "libplacebo/libplacebo* usr/lib/jellyfin-ffmpeg/lib" >> ${DPKG_INSTALL_LIST}
|
||||
popd
|
||||
}
|
||||
|
||||
# Prepare extra headers, libs and drivers for {arm,aarch64}-linux-gnu*
|
||||
@@ -733,6 +792,8 @@ EOF
|
||||
for tool in {gcc,g++,gcc-ar,gcc-ranlib,gcc-nm}; do
|
||||
ln -sf "/usr/bin/aarch64-linux-gnu-$tool-${GCC_VER}" "/usr/bin/aarch64-linux-gnu-$tool"
|
||||
done
|
||||
# Update pkgconfig search path
|
||||
export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/usr/lib/aarch64-linux-gnu/pkgconfig
|
||||
}
|
||||
|
||||
# Set the architecture-specific options
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
From 15ee32753c92faddbabbff11676779618fc6db7e Mon Sep 17 00:00:00 2001
|
||||
From: Diego de Souza <ddesouza@nvidia.com>
|
||||
Date: Fri, 26 Jun 2026 22:59:03 +0200
|
||||
Subject: [PATCH] Load nvEncodeAPI.dll for native Windows ARM64
|
||||
|
||||
On Windows on Arm, nvEncodeAPI.dll is an Arm64X dispatch proxy.
|
||||
It routes native ARM64 callers to nvEncodeAPIa64.dll and x64 or
|
||||
ARM64EC callers to nvEncodeAPI64.dll.
|
||||
|
||||
Select the proxy for native ARM64 builds while preserving the existing
|
||||
library name for other 64-bit Windows targets.
|
||||
|
||||
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
|
||||
---
|
||||
include/ffnvcodec/dynlink_loader.h | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/ffnvcodec/dynlink_loader.h b/include/ffnvcodec/dynlink_loader.h
|
||||
index 6d6a0ec..1be0dbf 100644
|
||||
--- a/include/ffnvcodec/dynlink_loader.h
|
||||
+++ b/include/ffnvcodec/dynlink_loader.h
|
||||
@@ -50,7 +50,11 @@
|
||||
# define CUDA_LIBNAME "nvcuda.dll"
|
||||
# define NVCUVID_LIBNAME "nvcuvid.dll"
|
||||
# if defined(_WIN64) || defined(__CYGWIN64__)
|
||||
-# define NVENC_LIBNAME "nvEncodeAPI64.dll"
|
||||
+# if defined(_M_ARM64) || defined(__aarch64__)
|
||||
+# define NVENC_LIBNAME "nvEncodeAPI.dll"
|
||||
+# else
|
||||
+# define NVENC_LIBNAME "nvEncodeAPI64.dll"
|
||||
+# endif
|
||||
# else
|
||||
# define NVENC_LIBNAME "nvEncodeAPI.dll"
|
||||
# endif
|
||||
@@ -12,8 +12,10 @@ url=https://github.com/FFmpeg/nv-codec-headers.git
|
||||
license=('spdx:MIT')
|
||||
makedepends=("git")
|
||||
_tag=451da99614412a7f9526ef301a5ee0c7a6f9ad76
|
||||
source=(git+https://github.com/FFmpeg/nv-codec-headers.git#tag=${_tag})
|
||||
sha256sums=('SKIP')
|
||||
source=("git+https://github.com/FFmpeg/nv-codec-headers.git#tag=${_tag}"
|
||||
"01-Load-nvEncodeAPI-dll-for-native-Windows-ARM64.patch")
|
||||
sha256sums=('SKIP'
|
||||
'43c248049c16e207635a9e56a26365b26014d2dc2d7c0e0688aa09ad649208f9')
|
||||
|
||||
export MINGW_TOOLCHAIN_PREFIX="${MINGW_PREFIX}"
|
||||
export FF_MINGW_PREFIX="${MINGW_TOOLCHAIN_PREFIX}/ffbuild"
|
||||
@@ -24,6 +26,12 @@ pkgver() {
|
||||
git describe --tags | sed 's/^n//'
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd nv-codec-headers
|
||||
|
||||
patch -p1 -i "${srcdir}/01-Load-nvEncodeAPI-dll-for-native-Windows-ARM64.patch"
|
||||
}
|
||||
|
||||
build() {
|
||||
make PREFIX=${FF_MINGW_PREFIX} -C nv-codec-headers
|
||||
sed -n '4,25p' nv-codec-headers/include/ffnvcodec/nvEncodeAPI.h > LICENSE # Extract license
|
||||
|
||||
@@ -89,6 +89,7 @@ PKG_CONFIG_PATH=/clang64/ffbuild/lib/pkgconfig ./configure \
|
||||
--enable-dxva2 \
|
||||
--enable-d3d11va \
|
||||
--enable-d3d12va \
|
||||
--enable-mediafoundation \
|
||||
--enable-amf \
|
||||
--enable-libvpl \
|
||||
--enable-ffnvcodec \
|
||||
|
||||
Reference in New Issue
Block a user