diff options
| author | gnattu <gnattu@users.noreply.github.com> | 2024-07-29 06:11:59 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-29 00:11:59 +0200 |
| commit | 162ea38a95560f19e0a2df8a54c1ac117d6d91bc (patch) | |
| tree | 7aa8f497b2b6ca60e431ad545a5d8df4baa8b7d2 | |
| parent | dea7be5e8ad737d57a7bfc136f5a43f7f44c9a92 (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.cs | 15 | ||||
| -rw-r--r-- | tests/Jellyfin.Model.Tests/Dlna/StreamBuilderTests.cs | 17 |
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)) |
