aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/MediaEncoding
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-06-15 09:29:24 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-06-15 09:29:24 +0200
commit1dd5a850807bc4269fce66d2d4191e67027285c8 (patch)
treecb216ec930d2953747ac42444b3acc617194b6d3 /MediaBrowser.Controller/MediaEncoding
parentf5c3e2c65a90e4a73c0a9079a8008ce4cacd55f7 (diff)
Extend TranscodingReason reporting
Diffstat (limited to 'MediaBrowser.Controller/MediaEncoding')
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs77
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs9
2 files changed, 57 insertions, 29 deletions
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 320e65231c..650eaa404e 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -25,6 +25,7 @@ using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Session;
using Microsoft.Extensions.Configuration;
using IConfigurationManager = MediaBrowser.Common.Configuration.IConfigurationManager;
@@ -2611,56 +2612,66 @@ namespace MediaBrowser.Controller.MediaEncoding
}
public bool CanStreamCopyAudio(EncodingJobInfo state, MediaStream audioStream, IEnumerable<string> supportedAudioCodecs)
+ => CanStreamCopyAudio(state, audioStream, supportedAudioCodecs, out _);
+
+ /// <summary>
+ /// Determines whether the given audio stream can be stream-copied and, regardless of the outcome,
+ /// reports the codec/parameter incompatibilities that would force a re-encode via <paramref name="failureReasons"/>.
+ /// </summary>
+ /// <param name="state">The encoding job state.</param>
+ /// <param name="audioStream">The source audio stream.</param>
+ /// <param name="supportedAudioCodecs">The audio codecs the target supports.</param>
+ /// <param name="failureReasons">The codec/parameter incompatibilities preventing a copy, or <c>0</c> if the stream is copy-compatible.</param>
+ /// <returns><c>true</c> if the audio stream can be stream-copied; otherwise, <c>false</c>.</returns>
+ public bool CanStreamCopyAudio(EncodingJobInfo state, MediaStream audioStream, IEnumerable<string> supportedAudioCodecs, out TranscodeReason failureReasons)
{
var request = state.BaseRequest;
- if (!request.AllowAudioStreamCopy)
- {
- return false;
- }
+ // Policy-independent compatibility check, so the reasons are reported even when a policy gate is what ultimately prevents the copy.
+ failureReasons = GetAudioStreamCopyFailureReasons(state, audioStream, supportedAudioCodecs);
+
+ return request.AllowAudioStreamCopy
+ && request.EnableAutoStreamCopy
+ && failureReasons == 0;
+ }
+
+ private static TranscodeReason GetAudioStreamCopyFailureReasons(EncodingJobInfo state, MediaStream audioStream, IEnumerable<string> supportedAudioCodecs)
+ {
+ var request = state.BaseRequest;
+ TranscodeReason reasons = 0;
var maxBitDepth = state.GetRequestedAudioBitDepth(audioStream.Codec);
if (maxBitDepth.HasValue
&& audioStream.BitDepth.HasValue
&& audioStream.BitDepth.Value > maxBitDepth.Value)
{
- return false;
+ reasons |= TranscodeReason.AudioBitDepthNotSupported;
}
// Source and target codecs must match
if (string.IsNullOrEmpty(audioStream.Codec)
|| !supportedAudioCodecs.Contains(audioStream.Codec, StringComparison.OrdinalIgnoreCase))
{
- return false;
+ reasons |= TranscodeReason.AudioCodecNotSupported;
}
// Channels must fall within requested value
var channels = state.GetRequestedAudioChannels(audioStream.Codec);
- if (channels.HasValue)
+ if (channels.HasValue
+ && (!audioStream.Channels.HasValue
+ || audioStream.Channels.Value <= 0
+ || audioStream.Channels.Value > channels.Value))
{
- if (!audioStream.Channels.HasValue || audioStream.Channels.Value <= 0)
- {
- return false;
- }
-
- if (audioStream.Channels.Value > channels.Value)
- {
- return false;
- }
+ reasons |= TranscodeReason.AudioChannelsNotSupported;
}
// Sample rate must fall within requested value
- if (request.AudioSampleRate.HasValue)
+ if (request.AudioSampleRate.HasValue
+ && (!audioStream.SampleRate.HasValue
+ || audioStream.SampleRate.Value <= 0
+ || audioStream.SampleRate.Value > request.AudioSampleRate.Value))
{
- if (!audioStream.SampleRate.HasValue || audioStream.SampleRate.Value <= 0)
- {
- return false;
- }
-
- if (audioStream.SampleRate.Value > request.AudioSampleRate.Value)
- {
- return false;
- }
+ reasons |= TranscodeReason.AudioSampleRateNotSupported;
}
// Audio bitrate must fall within requested value
@@ -2668,10 +2679,10 @@ namespace MediaBrowser.Controller.MediaEncoding
&& audioStream.BitRate.HasValue
&& audioStream.BitRate.Value > request.AudioBitRate.Value)
{
- return false;
+ reasons |= TranscodeReason.AudioBitrateNotSupported;
}
- return request.EnableAutoStreamCopy;
+ return reasons;
}
public int GetVideoBitrateParamValue(BaseEncodingJobOptions request, MediaStream videoStream, string outputVideoCodec)
@@ -7217,8 +7228,9 @@ namespace MediaBrowser.Controller.MediaEncoding
&& !IsCopyCodec(state.OutputVideoCodec)
&& options.HlsAudioSeekStrategy is HlsAudioSeekStrategy.TranscodeAudio;
+ TranscodeReason audioCopyFailureReasons = 0;
if (state.AudioStream is not null
- && CanStreamCopyAudio(state, state.AudioStream, state.SupportedAudioCodecs)
+ && CanStreamCopyAudio(state, state.AudioStream, state.SupportedAudioCodecs, out audioCopyFailureReasons)
&& !preventHlsAudioCopy)
{
state.OutputAudioCodec = "copy";
@@ -7232,6 +7244,13 @@ namespace MediaBrowser.Controller.MediaEncoding
{
state.OutputAudioCodec = "copy";
}
+ else if (state.AudioStream is not null && !IsCopyCodec(state.OutputAudioCodec))
+ {
+ // Audio is actually being re-encoded although the playback determination may have considered the source copyable.
+ // Only carry the primary "cannot be passed through" cause - the codec mismatch.
+ // Bitrate/channels/sample-rate/bit-depth copy refusals are consequences of the chosen transcode target.
+ state.AddTranscodeReason(audioCopyFailureReasons & TranscodeReason.AudioCodecNotSupported);
+ }
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index 3a1897a244..314cd32903 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -515,6 +515,15 @@ namespace MediaBrowser.Controller.MediaEncoding
public int HlsListSize => 0;
+ /// <summary>
+ /// Adds the specified reason(s) to <see cref="TranscodeReasons"/>.
+ /// </summary>
+ /// <param name="reason">The transcode reason(s) to add.</param>
+ public void AddTranscodeReason(TranscodeReason reason)
+ {
+ _transcodeReasons = TranscodeReasons | reason;
+ }
+
private int? GetMediaStreamCount(MediaStreamType type, int limit)
{
var count = MediaSource.GetStreamCount(type);