scale_opencl does not support rgba output in this jellyfin-ffmpeg build.
Rewrite the OpenCL kernel to accept and emit NV12 planes directly
(src_y, src_uv, dst_y, dst_uv) doing YCbCr↔RGB conversion internally.
Remove the scale_opencl=format=rgba and scale_opencl=format=nv12
wrappers from GetCrtShaderOclFilters — program_opencl alone is enough.
VAAPI decoder path: hwdownload+hwupload to QSV (safe; program_opencl
creates new output frames without a VAAPI reverse link).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All previous hwmap changes were based on diagnosing exit code 8 as a
mapping failure, but the real cause was always build_opts. Now that
build_opts is removed, use the same VAAPI→OpenCL→reverse(VAAPI)→QSV
pattern that Jellyfin already uses for the doOclTonemap+isVaInVaOut
path instead of the unnecessary QSV intermediate.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
program_opencl in this jellyfin-ffmpeg version does not have a build_opts
option. This caused FFmpeg to exit with code 8 before even running.
The shader already has #ifndef SHADOW_MASK / #define SHADOW_MASK 2 / #endif
as defaults, so removing build_opts keeps the same Aperture Grille mask.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
hwmap reverse=1 only works back to the device the OpenCL context was
derived from. When using a VAAPI decoder, go VAAPI→QSV first (zero-copy
on Intel, they share the same libva surfaces), so the OpenCL context is
then QSV-derived and reverse=1 back to QSV works correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
hwmap=derive_device=vaapi:mode=write:reverse=1 after scale_opencl fails
because scale_opencl creates a new OpenCL surface that has no association
with the original VAAPI surface. reverse=1 requires an existing mapping.
On Intel, VAAPI and QSV share the same libva surfaces, so mapping the
post-CRT OpenCL frame directly to QSV (mode=write:reverse=1) works the
same way it does in the doOclTonemap path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The SDR case (QSV decoder + QSV encoder, no OCL tonemap) was never
handled — the frame stayed in QSV VRAM with no OpenCL round-trip,
so the CRT filter was simply never applied.
Add else-if (isQsvDecoder) branch that maps QSV→OpenCL, applies the
CRT kernel, then reverse-maps back to QSV.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Inject ILogger<EncodingHelper> and log all conditions individually
so we can see exactly which check is failing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Insert VAAPI→OpenCL→CRT→VAAPI round-trip (isVaapiDecoder path) and
inline OCL filters (doOclTonemap path) into GetIntelQsvVaapiVidFiltersPrefered
so the CRT Lottes shader is applied when the h264_qsv encoder is active.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- IsCrtShaderEnabled now guards on SupportsHwaccel("opencl"),
SupportsFilter("program_opencl") and SupportsFilter("scale_opencl")
so the filter is silently skipped instead of causing an FFmpeg error
when OpenCL is unavailable
- Drop w=iw:h=ih from scale_opencl (iw/ih are not valid expressions in
the OpenCL scale filter; omitting them defaults to input dimensions)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- FFmpeg suppresses progress output (fps, time, bitrate) when loglevel is set to error
- Add -stats flag to force progress updates regardless of log level
- Fixes dashboard not showing transcode info (codec, progress, etc.)
- Add FfmpegLogLevel property to EncodingOptions (default: 'error')
- Use configuration value in GetInputModifier instead of hardcoded value
- Allows changing log verbosity without rebuild via encoding.xml
- Possible values: quiet, panic, fatal, error, warning, info, verbose, debug, trace
- Set FFmpeg loglevel to 'error' to suppress repetitive warnings like 'Skipping NAL unit'
- Add client IP and User-Agent to exception middleware logging for better debugging
* Cleanup extracted files
* Pagination and fixes
* Add migration for attachments to MigrateLibraryDb
* Unify attachment handling
* Don't extract again if files were already extracted
* Fix MKS attachment extraction
* Always run full extraction on mks
* Don't try to extract mjpeg streams as attachments
* Fallback to check if attachments were extracted to cache folder
* Fixup
* Add support for bitstream filter to remove dynamic hdr metadata
* Add support for ffprobe's only_first_vframe for HDR10+ detection
* Add BitStreamFilterOptionType for metadata removal check
* Map HDR10+ metadata to VideoRangeType.cs
Current implementation uses a hack that abuses the EL flag to avoid database schema changes. Should add proper field once EFCore migration is merged.
* Add more Dolby Vision Range types
Out of spec ones are problematic and should be marked as a dedicated invalid type and handled by the server to not crash the player.
Profile 7 videos should not be treated as normal HDR10 videos at all and should remove the metadata before serving.
* Remove dynamic hdr metadata when necessary
* Allow direct playback of HDR10+ videos on HDR10 clients
* Only use dovi codec tag when dovi metadata is not removed
* Handle DV Profile 7 Videos better
* Fix HDR10+ with new bitmask
* Indicate the presence of HDR10+ in HLS SUPPLEMENTAL-CODECS
* Fix Dovi 8.4 not labeled as HLG in HLS
* Fallback to dovi_rpu bsf for av1 when possible
* Fix dovi_rpu cli for av1
* Use correct EFCore db column for HDR10+
* Undo outdated migration
* Add proper hdr10+ migration
* Remove outdated migration
* Rebase to new db code
* Add migrations for Hdr10PlusPresentFlag
* Directly use bsf enum
* Add xmldocs for SupportsBitStreamFilterWithOption
* Make `VideoRangeType.Unknown` explicitly default on api models.
* Unset default for non-api model class
* Use tuples for bsf dictionary for now