mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-18 05:30:34 +01:00
Extend TranscodingReason reporting
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -951,6 +951,10 @@ namespace MediaBrowser.Model.Dlna
|
||||
}
|
||||
|
||||
playlistItem.VideoCodecs = videoCodecs;
|
||||
if (videoStream is not null && !ContainerHelper.ContainsContainer(videoCodecs, false, videoStream.Codec))
|
||||
{
|
||||
playlistItem.TranscodeReasons |= TranscodeReason.VideoCodecNotSupported;
|
||||
}
|
||||
|
||||
// Copy video codec options as a starting point, this applies to transcode and direct-stream
|
||||
playlistItem.MaxFramerate = videoStream?.ReferenceFrameRate;
|
||||
@@ -999,6 +1003,10 @@ namespace MediaBrowser.Model.Dlna
|
||||
var directAudioFailures = audioStreamWithSupportedCodec is null ? default : GetCompatibilityAudioCodec(options, item, container ?? string.Empty, audioStreamWithSupportedCodec, null, true, false);
|
||||
|
||||
playlistItem.TranscodeReasons |= directAudioFailures;
|
||||
if (audioStream is not null && audioStreamWithSupportedCodec is null)
|
||||
{
|
||||
playlistItem.TranscodeReasons |= TranscodeReason.AudioCodecNotSupported;
|
||||
}
|
||||
|
||||
var directAudioStreamSatisfied = audioStreamWithSupportedCodec is not null && !channelsExceedsLimit
|
||||
&& directAudioFailures == 0;
|
||||
|
||||
Reference in New Issue
Block a user