Backport upstream qsvenc fixes

Signed-off-by: nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
nyanmisaka 2023-05-24 16:42:43 +08:00
parent c9cdf980e9
commit c79c963a61
2 changed files with 142 additions and 0 deletions

View File

@ -0,0 +1,141 @@
Index: jellyfin-ffmpeg/libavcodec/qsv.c
===================================================================
--- jellyfin-ffmpeg.orig/libavcodec/qsv.c
+++ jellyfin-ffmpeg/libavcodec/qsv.c
@@ -685,18 +685,31 @@ static int qsv_create_mfx_session(AVCode
int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
const char *load_plugins, int gpu_copy)
{
+ mfxIMPL impls[] = {
#if CONFIG_D3D11VA
- mfxIMPL impl = MFX_IMPL_AUTO_ANY | MFX_IMPL_VIA_D3D11;
-#else
- mfxIMPL impl = MFX_IMPL_AUTO_ANY;
+ MFX_IMPL_AUTO_ANY | MFX_IMPL_VIA_D3D11,
#endif
+ MFX_IMPL_AUTO_ANY
+ };
+ mfxIMPL impl;
mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
const char *desc;
- int ret = qsv_create_mfx_session(avctx, impl, &ver, gpu_copy, &qs->session,
+ int ret;
+
+ for (int i = 0; i < FF_ARRAY_ELEMS(impls); i++) {
+ ret = qsv_create_mfx_session(avctx, impls[i], &ver, gpu_copy, &qs->session,
&qs->loader);
- if (ret)
- return ret;
+
+ if (ret == 0)
+ break;
+
+ if (i == FF_ARRAY_ELEMS(impls) - 1)
+ return ret;
+ else
+ av_log(avctx, AV_LOG_ERROR, "The current mfx implementation is not "
+ "supported, try next mfx implementation.\n");
+ }
#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
ret = ff_qsv_set_display_handle(avctx, qs);
Index: jellyfin-ffmpeg/libavcodec/qsvenc.c
===================================================================
--- jellyfin-ffmpeg.orig/libavcodec/qsvenc.c
+++ jellyfin-ffmpeg/libavcodec/qsvenc.c
@@ -838,7 +838,9 @@ static int init_video_param(AVCodecConte
// for progressive video, the height should be aligned to 16 for
// H.264. For HEVC, depending on the version of MFX, it should be
// either 32 or 16. The lower number is better if possible.
- q->height_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
+ // For AV1, it is 32
+ q->height_align = (avctx->codec_id == AV_CODEC_ID_HEVC ||
+ avctx->codec_id == AV_CODEC_ID_AV1) ? 32 : 16;
}
q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, q->height_align);
@@ -1913,6 +1915,62 @@ static int qsvenc_fill_padding_area(AVFr
return 0;
}
+/* frame width / height have been aligned with the alignment */
+static int qsvenc_get_continuous_buffer(AVFrame *frame)
+{
+ int total_size;
+
+ switch (frame->format) {
+ case AV_PIX_FMT_NV12:
+ frame->linesize[0] = frame->width;
+ frame->linesize[1] = frame->linesize[0];
+ total_size = frame->linesize[0] * frame->height + frame->linesize[1] * frame->height / 2;
+ break;
+
+ case AV_PIX_FMT_P010:
+ case AV_PIX_FMT_P012:
+ frame->linesize[0] = 2 * frame->width;
+ frame->linesize[1] = frame->linesize[0];
+ total_size = frame->linesize[0] * frame->height + frame->linesize[1] * frame->height / 2;
+ break;
+
+ case AV_PIX_FMT_YUYV422:
+ frame->linesize[0] = 2 * frame->width;
+ frame->linesize[1] = 0;
+ total_size = frame->linesize[0] * frame->height;
+ break;
+
+ case AV_PIX_FMT_Y210:
+ case AV_PIX_FMT_VUYX:
+ case AV_PIX_FMT_XV30:
+ case AV_PIX_FMT_BGRA:
+ case AV_PIX_FMT_X2RGB10:
+ frame->linesize[0] = 4 * frame->width;
+ frame->linesize[1] = 0;
+ total_size = frame->linesize[0] * frame->height;
+ break;
+
+ default:
+ // This should never be reached
+ av_assert0(0);
+ return AVERROR(EINVAL);
+ }
+
+ frame->buf[0] = av_buffer_alloc(total_size);
+ if (!frame->buf[0])
+ return AVERROR(ENOMEM);
+
+ frame->data[0] = frame->buf[0]->data;
+ frame->extended_data = frame->data;
+
+ if (frame->format == AV_PIX_FMT_NV12 ||
+ frame->format == AV_PIX_FMT_P010 ||
+ frame->format == AV_PIX_FMT_P012)
+ frame->data[1] = frame->data[0] + frame->linesize[0] * frame->height;
+
+ return 0;
+}
+
static int submit_frame(QSVEncContext *q, const AVFrame *frame,
QSVFrame **new_frame)
{
@@ -1963,8 +2021,9 @@ static int submit_frame(QSVEncContext *q
} else {
/* make a copy if the input is not padded as libmfx requires */
/* and to make allocation continious for data[0]/data[1] */
- if ((frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) ||
- (frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align))) {
+ if ((frame->height & (q->height_align - 1) || frame->linesize[0] & (q->width_align - 1)) ||
+ ((frame->format == AV_PIX_FMT_NV12 || frame->format == AV_PIX_FMT_P010 || frame->format == AV_PIX_FMT_P012) &&
+ (frame->data[1] - frame->data[0] != frame->linesize[0] * FFALIGN(qf->frame->height, q->height_align)))) {
int tmp_w, tmp_h;
qf->frame->height = tmp_h = FFALIGN(frame->height, q->height_align);
qf->frame->width = tmp_w = FFALIGN(frame->width, q->width_align);
@@ -1972,7 +2031,7 @@ static int submit_frame(QSVEncContext *q
qf->frame->format = frame->format;
if (!qf->frame->data[0]) {
- ret = av_frame_get_buffer(qf->frame, q->width_align);
+ ret = qsvenc_get_continuous_buffer(qf->frame);
if (ret < 0)
return ret;
}

View File

@ -49,3 +49,4 @@
0049-add-queued-key-fixes-from-upstream.patch
0050-revert-libplacebo-to-ad-hoc-mode.patch
0051-add-av1-vaapi-encoder-from-upstream-intel.patch
0052-backport-upstream-qsvenc-fixes.patch