Check MaxAudioChannels for directAudioStream candidates (#12319)
* Check MaxAudioChannels for directAudioStream candidates The current stream builder logic does not check the channel limit when determining if the audio stream can be directly used, and this can cause some undesired effects: - A high channel count surround sound stream might be picked even if a stereo one exists when the user requires stereo audio. - The user's preferred audio codec might not be respected during the downmix because the requested codec is now forced to be the same as the original source. Signed-off-by: gnattu <gnattuoc@me.com> * Fix unit test Signed-off-by: gnattu <gnattuoc@me.com> * Set correct transcode reason and target channels for unit test Signed-off-by: gnattu <gnattuoc@me.com> * Match old stream selection behavior Signed-off-by: gnattu <gnattuoc@me.com> * Fix reason matching Signed-off-by: gnattu <gnattuoc@me.com> --------- Signed-off-by: gnattu <gnattuoc@me.com>
This commit is contained in:
parent
dea7be5e8a
commit
162ea38a95
|
@ -908,7 +908,18 @@ namespace MediaBrowser.Model.Dlna
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var directAudioStream = candidateAudioStreams.FirstOrDefault(stream => ContainerProfile.ContainsContainer(audioCodecs, stream.Codec));
|
var audioStreamWithSupportedCodec = candidateAudioStreams.Where(stream => ContainerProfile.ContainsContainer(audioCodecs, 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 && directAudioStream is null;
|
||||||
|
|
||||||
|
if (channelsExceedsLimit && playlistItem.TargetAudioStream is not null)
|
||||||
|
{
|
||||||
|
playlistItem.TranscodeReasons |= TranscodeReason.AudioChannelsNotSupported;
|
||||||
|
playlistItem.TargetAudioStream.Channels = playlistItem.TranscodingMaxAudioChannels;
|
||||||
|
}
|
||||||
|
|
||||||
playlistItem.AudioCodecs = audioCodecs;
|
playlistItem.AudioCodecs = audioCodecs;
|
||||||
if (directAudioStream is not null)
|
if (directAudioStream is not null)
|
||||||
{
|
{
|
||||||
|
@ -971,7 +982,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
}
|
}
|
||||||
|
|
||||||
// Honor requested max channels
|
// Honor requested max channels
|
||||||
playlistItem.GlobalMaxAudioChannels = options.MaxAudioChannels;
|
playlistItem.GlobalMaxAudioChannels = channelsExceedsLimit ? playlistItem.TranscodingMaxAudioChannels : options.MaxAudioChannels;
|
||||||
|
|
||||||
int audioBitrate = GetAudioBitrate(options.GetMaxBitrate(true) ?? 0, playlistItem.TargetAudioCodec, audioStream, playlistItem);
|
int audioBitrate = GetAudioBitrate(options.GetMaxBitrate(true) ?? 0, playlistItem.TargetAudioCodec, audioStream, playlistItem);
|
||||||
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
|
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
|
||||||
|
|
|
@ -51,8 +51,8 @@ namespace Jellyfin.Model.Tests
|
||||||
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
||||||
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioChannelsNotSupported, "DirectStream", "HLS.mp4")] // #6450
|
||||||
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioChannelsNotSupported, "DirectStream", "HLS.mp4")] // #6450
|
||||||
// AndroidPixel
|
// AndroidPixel
|
||||||
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
[InlineData("AndroidPixel", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("AndroidPixel", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
|
@ -205,8 +205,8 @@ namespace Jellyfin.Model.Tests
|
||||||
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
||||||
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioChannelsNotSupported, "DirectStream", "HLS.mp4")] // #6450
|
||||||
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
|
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioChannelsNotSupported, "DirectStream", "HLS.mp4")] // #6450
|
||||||
// AndroidPixel
|
// AndroidPixel
|
||||||
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
[InlineData("AndroidPixel", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
[InlineData("AndroidPixel", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
|
||||||
|
@ -432,8 +432,15 @@ namespace Jellyfin.Model.Tests
|
||||||
if (targetAudioStream?.IsExternal == false)
|
if (targetAudioStream?.IsExternal == false)
|
||||||
{
|
{
|
||||||
// Check expected audio codecs (1)
|
// Check expected audio codecs (1)
|
||||||
|
if ((why & TranscodeReason.AudioChannelsNotSupported) == 0)
|
||||||
|
{
|
||||||
Assert.DoesNotContain(targetAudioStream.Codec, streamInfo.AudioCodecs);
|
Assert.DoesNotContain(targetAudioStream.Codec, streamInfo.AudioCodecs);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert.Equal(targetAudioStream.Channels, streamInfo.TranscodingMaxAudioChannels);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (transcodeMode.Equals("Remux", StringComparison.Ordinal))
|
else if (transcodeMode.Equals("Remux", StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user