From e9ac0c91b35e32776f2d93f3d86cee627bc70bfa Mon Sep 17 00:00:00 2001 From: Kyrylo Mikos Date: Fri, 7 Nov 2025 13:50:21 +0200 Subject: [PATCH] Update VaapiHwDecodeConfig - Drop out_range and format. ffmpeg will figure it out automatically. This should fix slightly wrong color without tonemapping - Always set tonemapping for preview/thumbnail jobs - Fix VaapiSwDecodeConfig without scaling --- server/src/services/media.service.ts | 13 +++++++++++-- server/src/utils/media.ts | 15 ++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index 6caa682f5e..b28c372ad9 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -18,6 +18,7 @@ import { QueueName, RawExtractedFormat, StorageFolder, + ToneMapping, TranscodeHardwareAcceleration, TranscodePolicy, TranscodeTarget, @@ -424,8 +425,16 @@ export class MediaService extends BaseService { } const mainAudioStream = this.getMainStream(audioStreams); - const previewConfig = ThumbnailConfig.create({ ...ffmpeg, targetResolution: image.preview.size.toString() }); - const thumbnailConfig = ThumbnailConfig.create({ ...ffmpeg, targetResolution: image.thumbnail.size.toString() }); + const previewConfig = ThumbnailConfig.create({ + ...ffmpeg, + targetResolution: image.preview.size.toString(), + tonemap: ToneMapping.Hable, + }); + const thumbnailConfig = ThumbnailConfig.create({ + ...ffmpeg, + targetResolution: image.thumbnail.size.toString(), + tonemap: ToneMapping.Hable, + }); const previewOptions = previewConfig.getCommand(TranscodeTarget.Video, mainVideoStream, mainAudioStream, format); const thumbnailOptions = thumbnailConfig.getCommand( TranscodeTarget.Video, diff --git a/server/src/utils/media.ts b/server/src/utils/media.ts index f678a32b0f..4cc6b65680 100644 --- a/server/src/utils/media.ts +++ b/server/src/utils/media.ts @@ -801,10 +801,13 @@ export class VaapiSwDecodeConfig extends BaseHWConfig { } getFilterOptions(videoStream: VideoStreamInfo) { - const options = this.getToneMapping(videoStream); - options.push('hwupload=extra_hw_frames=64'); + const tonemapOptions = this.getToneMapping(videoStream); + const options = [...tonemapOptions, 'hwupload=extra_hw_frames=64']; + const format = videoStream.isHDR && tonemapOptions.length === 0 ? 'p010' : 'nv12'; if (this.shouldScale(videoStream)) { - options.push(`scale_vaapi=${this.getScaling(videoStream)}:mode=hq:out_range=pc:format=nv12`); + options.push(`scale_vaapi=${this.getScaling(videoStream)}:mode=hq:format=${format}`); + } else { + options.push(`scale_vaapi=format=${format}`); } return options; @@ -867,10 +870,8 @@ export class VaapiHwDecodeConfig extends VaapiSwDecodeConfig { getFilterOptions(videoStream: VideoStreamInfo) { const options = []; const tonemapOptions = this.getToneMapping(videoStream); - if (tonemapOptions.length === 0 && !videoStream.pixelFormat.endsWith('420p')) { - options.push(`scale_vaapi=${this.getScaling(videoStream)}:mode=hq:out_range=pc:format=nv12`); - } else if (this.shouldScale(videoStream)) { - options.push(`scale_vaapi=${this.getScaling(videoStream)}:mode=hq:out_range=pc`); + if (this.shouldScale(videoStream)) { + options.push(`scale_vaapi=${this.getScaling(videoStream)}:mode=hq`); } options.push(...tonemapOptions); return options;