mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
Backport pull request #13209 from jellyfin/release-10.10.z
Transcode to audio codec satisfied other conditions when copy check failed. Original-merge: 8aa41d59041c792571530c514dd6d21ba22a1881 Merged-by: crobibero <cody@robibe.ro> Backported-by: Bond_009 <bond.009@outlook.com>
This commit is contained in:
parent
533464e186
commit
8cb11692a9
@ -862,18 +862,37 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
if (options.AllowAudioStreamCopy)
|
||||
{
|
||||
if (ContainerHelper.ContainsContainer(transcodingProfile.AudioCodec, audioCodec))
|
||||
// For Audio stream, we prefer the audio codec that can be directly copied, then the codec that can otherwise satisfies
|
||||
// the transcoding conditions, then the one does not satisfy the transcoding conditions.
|
||||
// For example: A client can support both aac and flac, but flac only supports 2 channels while aac supports 6.
|
||||
// When the source audio is 6 channel flac, we should transcode to 6 channel aac, instead of down-mix to 2 channel flac.
|
||||
var transcodingAudioCodecs = ContainerHelper.Split(transcodingProfile.AudioCodec);
|
||||
|
||||
foreach (var transcodingAudioCodec in transcodingAudioCodecs)
|
||||
{
|
||||
var appliedVideoConditions = options.Profile.CodecProfiles
|
||||
.Where(i => i.Type == CodecType.VideoAudio &&
|
||||
i.ContainsAnyCodec(audioCodec, container) &&
|
||||
i.ContainsAnyCodec(transcodingAudioCodec, container) &&
|
||||
i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, false)))
|
||||
.Select(i =>
|
||||
i.Conditions.All(condition => ConditionProcessor.IsVideoAudioConditionSatisfied(condition, audioChannels, audioBitrate, audioSampleRate, audioBitDepth, audioProfile, false)));
|
||||
|
||||
// An empty appliedVideoConditions means that the codec has no conditions for the current audio stream
|
||||
var conditionsSatisfied = appliedVideoConditions.All(satisfied => satisfied);
|
||||
rank.Audio = conditionsSatisfied ? 1 : 2;
|
||||
|
||||
var rankAudio = 3;
|
||||
|
||||
if (conditionsSatisfied)
|
||||
{
|
||||
rankAudio = string.Equals(transcodingAudioCodec, audioCodec, StringComparison.OrdinalIgnoreCase) ? 1 : 2;
|
||||
}
|
||||
|
||||
rank.Audio = Math.Min(rank.Audio, rankAudio);
|
||||
|
||||
if (rank.Audio == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -963,9 +982,26 @@ namespace MediaBrowser.Model.Dlna
|
||||
|
||||
var audioStreamWithSupportedCodec = candidateAudioStreams.Where(stream => ContainerHelper.ContainsContainer(audioCodecs, false, stream.Codec)).FirstOrDefault();
|
||||
|
||||
var directAudioStream = audioStreamWithSupportedCodec?.Channels is not null && audioStreamWithSupportedCodec.Channels.Value <= (playlistItem.TranscodingMaxAudioChannels ?? int.MaxValue) ? audioStreamWithSupportedCodec : null;
|
||||
var channelsExceedsLimit = audioStreamWithSupportedCodec is not null && audioStreamWithSupportedCodec.Channels > (playlistItem.TranscodingMaxAudioChannels ?? int.MaxValue);
|
||||
|
||||
var channelsExceedsLimit = audioStreamWithSupportedCodec is not null && directAudioStream is null;
|
||||
var directAudioStreamSatisfied = audioStreamWithSupportedCodec is not null && !channelsExceedsLimit
|
||||
&& options.Profile.CodecProfiles
|
||||
.Where(i => i.Type == CodecType.VideoAudio
|
||||
&& i.ContainsAnyCodec(audioStreamWithSupportedCodec.Codec, container)
|
||||
&& i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoAudioConditionSatisfied(applyCondition, audioStreamWithSupportedCodec.Channels, audioStreamWithSupportedCodec.BitRate, audioStreamWithSupportedCodec.SampleRate, audioStreamWithSupportedCodec.BitDepth, audioStreamWithSupportedCodec.Profile, false)))
|
||||
.Select(i => i.Conditions.All(condition =>
|
||||
{
|
||||
var satisfied = ConditionProcessor.IsVideoAudioConditionSatisfied(condition, audioStreamWithSupportedCodec.Channels, audioStreamWithSupportedCodec.BitRate, audioStreamWithSupportedCodec.SampleRate, audioStreamWithSupportedCodec.BitDepth, audioStreamWithSupportedCodec.Profile, false);
|
||||
if (!satisfied)
|
||||
{
|
||||
playlistItem.TranscodeReasons |= GetTranscodeReasonForFailedCondition(condition);
|
||||
}
|
||||
|
||||
return satisfied;
|
||||
}))
|
||||
.All(satisfied => satisfied);
|
||||
|
||||
var directAudioStream = directAudioStreamSatisfied ? audioStreamWithSupportedCodec : null;
|
||||
|
||||
if (channelsExceedsLimit && playlistItem.TargetAudioStream is not null)
|
||||
{
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Xml.Serialization;
|
||||
using Jellyfin.Data.Enums;
|
||||
@ -6,6 +7,7 @@ namespace MediaBrowser.Model.Dlna;
|
||||
|
||||
/// <summary>
|
||||
/// A class for transcoding profile information.
|
||||
/// Note for client developers: Conditions defined in <see cref="CodecProfile"/> has higher priority and can override values defined here.
|
||||
/// </summary>
|
||||
public class TranscodingProfile
|
||||
{
|
||||
@ -17,6 +19,33 @@ public class TranscodingProfile
|
||||
Conditions = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TranscodingProfile" /> class copying the values from another instance.
|
||||
/// </summary>
|
||||
/// <param name="other">Another instance of <see cref="TranscodingProfile" /> to be copied.</param>
|
||||
public TranscodingProfile(TranscodingProfile other)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(other);
|
||||
|
||||
Container = other.Container;
|
||||
Type = other.Type;
|
||||
VideoCodec = other.VideoCodec;
|
||||
AudioCodec = other.AudioCodec;
|
||||
Protocol = other.Protocol;
|
||||
EstimateContentLength = other.EstimateContentLength;
|
||||
EnableMpegtsM2TsMode = other.EnableMpegtsM2TsMode;
|
||||
TranscodeSeekInfo = other.TranscodeSeekInfo;
|
||||
CopyTimestamps = other.CopyTimestamps;
|
||||
Context = other.Context;
|
||||
EnableSubtitlesInManifest = other.EnableSubtitlesInManifest;
|
||||
MaxAudioChannels = other.MaxAudioChannels;
|
||||
MinSegments = other.MinSegments;
|
||||
SegmentLength = other.SegmentLength;
|
||||
BreakOnNonKeyFrames = other.BreakOnNonKeyFrames;
|
||||
Conditions = other.Conditions;
|
||||
EnableAudioVbrEncoding = other.EnableAudioVbrEncoding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the container.
|
||||
/// </summary>
|
||||
|
Loading…
x
Reference in New Issue
Block a user