aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgnattu <gnattu@users.noreply.github.com>2024-07-29 06:11:59 +0800
committerGitHub <noreply@github.com>2024-07-29 00:11:59 +0200
commit162ea38a95560f19e0a2df8a54c1ac117d6d91bc (patch)
tree7aa8f497b2b6ca60e431ad545a5d8df4baa8b7d2
parentdea7be5e8ad737d57a7bfc136f5a43f7f44c9a92 (diff)
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>
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs15
-rw-r--r--tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs17
2 files changed, 25 insertions, 7 deletions
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index d37528ede..4815dcc04 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -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;
if (directAudioStream is not null)
{
@@ -971,7 +982,7 @@ namespace MediaBrowser.Model.Dlna
}
// 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);
playlistItem.AudioBitrate = Math.Min(playlistItem.AudioBitrate ?? audioBitrate, audioBitrate);
diff --git a/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs b/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs
index 6d88dbb8e..31ddd427c 100644
--- a/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs
+++ b/tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs
@@ -51,8 +51,8 @@ namespace Jellyfin.Model.Tests
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-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-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
- [InlineData("SafariNext", "mp4-hevc-ac3-aacExt-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 | TranscodeReason.AudioChannelsNotSupported, "DirectStream", "HLS.mp4")] // #6450
// AndroidPixel
[InlineData("AndroidPixel", "mp4-h264-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-srt-2600k", PlayMethod.DirectPlay)] // #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-aacExt-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 | TranscodeReason.AudioChannelsNotSupported, "DirectStream", "HLS.mp4")] // #6450
// AndroidPixel
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
@@ -432,7 +432,14 @@ namespace Jellyfin.Model.Tests
if (targetAudioStream?.IsExternal == false)
{
// Check expected audio codecs (1)
- Assert.DoesNotContain(targetAudioStream.Codec, streamInfo.AudioCodecs);
+ if ((why & TranscodeReason.AudioChannelsNotSupported) == 0)
+ {
+ Assert.DoesNotContain(targetAudioStream.Codec, streamInfo.AudioCodecs);
+ }
+ else
+ {
+ Assert.Equal(targetAudioStream.Channels, streamInfo.TranscodingMaxAudioChannels);
+ }
}
}
else if (transcodeMode.Equals("Remux", StringComparison.Ordinal))