diff options
| author | crobibero <cody@robibe.ro> | 2020-11-20 10:35:46 -0700 |
|---|---|---|
| committer | crobibero <cody@robibe.ro> | 2020-11-20 10:35:46 -0700 |
| commit | 8f58f63b0886670922aa77431e69b80b969d675a (patch) | |
| tree | 9436313b2c5ca856f72eabba4606099c68665475 /MediaBrowser.Model/Dlna | |
| parent | 53697ac39a624d3a32b79883f4e0321b3a7ecb49 (diff) | |
| parent | d2cef78db3c6f5c1063f8205ed5309f5243be66b (diff) | |
Merge remote-tracking branch 'upstream/master' into split-api
Diffstat (limited to 'MediaBrowser.Model/Dlna')
| -rw-r--r-- | MediaBrowser.Model/Dlna/DeviceIdentification.cs | 23 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/DeviceProfile.cs | 217 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/ResolutionNormalizer.cs | 12 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamBuilder.cs | 98 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamInfo.cs | 13 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/XmlAttribute.cs | 9 |
6 files changed, 315 insertions, 57 deletions
diff --git a/MediaBrowser.Model/Dlna/DeviceIdentification.cs b/MediaBrowser.Model/Dlna/DeviceIdentification.cs index 43407383a8..c511801f4f 100644 --- a/MediaBrowser.Model/Dlna/DeviceIdentification.cs +++ b/MediaBrowser.Model/Dlna/DeviceIdentification.cs @@ -11,59 +11,54 @@ namespace MediaBrowser.Model.Dlna /// Gets or sets the name of the friendly. /// </summary> /// <value>The name of the friendly.</value> - public string FriendlyName { get; set; } + public string FriendlyName { get; set; } = string.Empty; /// <summary> /// Gets or sets the model number. /// </summary> /// <value>The model number.</value> - public string ModelNumber { get; set; } + public string ModelNumber { get; set; } = string.Empty; /// <summary> /// Gets or sets the serial number. /// </summary> /// <value>The serial number.</value> - public string SerialNumber { get; set; } + public string SerialNumber { get; set; } = string.Empty; /// <summary> /// Gets or sets the name of the model. /// </summary> /// <value>The name of the model.</value> - public string ModelName { get; set; } + public string ModelName { get; set; } = string.Empty; /// <summary> /// Gets or sets the model description. /// </summary> /// <value>The model description.</value> - public string ModelDescription { get; set; } + public string ModelDescription { get; set; } = string.Empty; /// <summary> /// Gets or sets the model URL. /// </summary> /// <value>The model URL.</value> - public string ModelUrl { get; set; } + public string ModelUrl { get; set; } = string.Empty; /// <summary> /// Gets or sets the manufacturer. /// </summary> /// <value>The manufacturer.</value> - public string Manufacturer { get; set; } + public string Manufacturer { get; set; } = string.Empty; /// <summary> /// Gets or sets the manufacturer URL. /// </summary> /// <value>The manufacturer URL.</value> - public string ManufacturerUrl { get; set; } + public string ManufacturerUrl { get; set; } = string.Empty; /// <summary> /// Gets or sets the headers. /// </summary> /// <value>The headers.</value> - public HttpHeaderInfo[] Headers { get; set; } - - public DeviceIdentification() - { - Headers = Array.Empty<HttpHeaderInfo>(); - } + public HttpHeaderInfo[] Headers { get; set; } = Array.Empty<HttpHeaderInfo>(); } } diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index e842efead9..ff51866587 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -1,6 +1,5 @@ #nullable disable -#pragma warning disable CS1591 - +#pragma warning disable CA1819 // Properties should not return arrays using System; using System.Linq; using System.Xml.Serialization; @@ -8,129 +7,243 @@ using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Model.Dlna { + /// <summary> + /// Defines the <see cref="DeviceProfile" />. + /// </summary> [XmlRoot("Profile")] public class DeviceProfile { /// <summary> - /// Gets or sets the name. + /// Initializes a new instance of the <see cref="DeviceProfile"/> class. + /// </summary> + public DeviceProfile() + { + DirectPlayProfiles = Array.Empty<DirectPlayProfile>(); + TranscodingProfiles = Array.Empty<TranscodingProfile>(); + ResponseProfiles = Array.Empty<ResponseProfile>(); + CodecProfiles = Array.Empty<CodecProfile>(); + ContainerProfiles = Array.Empty<ContainerProfile>(); + SubtitleProfiles = Array.Empty<SubtitleProfile>(); + + XmlRootAttributes = Array.Empty<XmlAttribute>(); + + SupportedMediaTypes = "Audio,Photo,Video"; + MaxStreamingBitrate = 8000000; + MaxStaticBitrate = 8000000; + MusicStreamingTranscodingBitrate = 128000; + } + + /// <summary> + /// Gets or sets the Name. /// </summary> - /// <value>The name.</value> public string Name { get; set; } + /// <summary> + /// Gets or sets the Id. + /// </summary> [XmlIgnore] public string Id { get; set; } /// <summary> - /// Gets or sets the identification. + /// Gets or sets the Identification. /// </summary> - /// <value>The identification.</value> public DeviceIdentification Identification { get; set; } + /// <summary> + /// Gets or sets the FriendlyName. + /// </summary> public string FriendlyName { get; set; } + /// <summary> + /// Gets or sets the Manufacturer. + /// </summary> public string Manufacturer { get; set; } + /// <summary> + /// Gets or sets the ManufacturerUrl. + /// </summary> public string ManufacturerUrl { get; set; } + /// <summary> + /// Gets or sets the ModelName. + /// </summary> public string ModelName { get; set; } + /// <summary> + /// Gets or sets the ModelDescription. + /// </summary> public string ModelDescription { get; set; } + /// <summary> + /// Gets or sets the ModelNumber. + /// </summary> public string ModelNumber { get; set; } + /// <summary> + /// Gets or sets the ModelUrl. + /// </summary> public string ModelUrl { get; set; } + /// <summary> + /// Gets or sets the SerialNumber. + /// </summary> public string SerialNumber { get; set; } + /// <summary> + /// Gets or sets a value indicating whether EnableAlbumArtInDidl. + /// </summary> public bool EnableAlbumArtInDidl { get; set; } + /// <summary> + /// Gets or sets a value indicating whether EnableSingleAlbumArtLimit. + /// </summary> public bool EnableSingleAlbumArtLimit { get; set; } + /// <summary> + /// Gets or sets a value indicating whether EnableSingleSubtitleLimit. + /// </summary> public bool EnableSingleSubtitleLimit { get; set; } + /// <summary> + /// Gets or sets the SupportedMediaTypes. + /// </summary> public string SupportedMediaTypes { get; set; } + /// <summary> + /// Gets or sets the UserId. + /// </summary> public string UserId { get; set; } + /// <summary> + /// Gets or sets the AlbumArtPn. + /// </summary> public string AlbumArtPn { get; set; } + /// <summary> + /// Gets or sets the MaxAlbumArtWidth. + /// </summary> public int MaxAlbumArtWidth { get; set; } + /// <summary> + /// Gets or sets the MaxAlbumArtHeight. + /// </summary> public int MaxAlbumArtHeight { get; set; } + /// <summary> + /// Gets or sets the MaxIconWidth. + /// </summary> public int? MaxIconWidth { get; set; } + /// <summary> + /// Gets or sets the MaxIconHeight. + /// </summary> public int? MaxIconHeight { get; set; } + /// <summary> + /// Gets or sets the MaxStreamingBitrate. + /// </summary> public int? MaxStreamingBitrate { get; set; } + /// <summary> + /// Gets or sets the MaxStaticBitrate. + /// </summary> public int? MaxStaticBitrate { get; set; } + /// <summary> + /// Gets or sets the MusicStreamingTranscodingBitrate. + /// </summary> public int? MusicStreamingTranscodingBitrate { get; set; } + /// <summary> + /// Gets or sets the MaxStaticMusicBitrate. + /// </summary> public int? MaxStaticMusicBitrate { get; set; } /// <summary> - /// Controls the content of the aggregationFlags element in the urn:schemas-sonycom:av namespace. + /// Gets or sets the content of the aggregationFlags element in the urn:schemas-sonycom:av namespace. /// </summary> public string SonyAggregationFlags { get; set; } + /// <summary> + /// Gets or sets the ProtocolInfo. + /// </summary> public string ProtocolInfo { get; set; } + /// <summary> + /// Gets or sets the TimelineOffsetSeconds. + /// </summary> public int TimelineOffsetSeconds { get; set; } + /// <summary> + /// Gets or sets a value indicating whether RequiresPlainVideoItems. + /// </summary> public bool RequiresPlainVideoItems { get; set; } + /// <summary> + /// Gets or sets a value indicating whether RequiresPlainFolders. + /// </summary> public bool RequiresPlainFolders { get; set; } + /// <summary> + /// Gets or sets a value indicating whether EnableMSMediaReceiverRegistrar. + /// </summary> public bool EnableMSMediaReceiverRegistrar { get; set; } + /// <summary> + /// Gets or sets a value indicating whether IgnoreTranscodeByteRangeRequests. + /// </summary> public bool IgnoreTranscodeByteRangeRequests { get; set; } + /// <summary> + /// Gets or sets the XmlRootAttributes. + /// </summary> public XmlAttribute[] XmlRootAttributes { get; set; } /// <summary> /// Gets or sets the direct play profiles. /// </summary> - /// <value>The direct play profiles.</value> public DirectPlayProfile[] DirectPlayProfiles { get; set; } /// <summary> /// Gets or sets the transcoding profiles. /// </summary> - /// <value>The transcoding profiles.</value> public TranscodingProfile[] TranscodingProfiles { get; set; } + /// <summary> + /// Gets or sets the ContainerProfiles. + /// </summary> public ContainerProfile[] ContainerProfiles { get; set; } + /// <summary> + /// Gets or sets the CodecProfiles. + /// </summary> public CodecProfile[] CodecProfiles { get; set; } + /// <summary> + /// Gets or sets the ResponseProfiles. + /// </summary> public ResponseProfile[] ResponseProfiles { get; set; } + /// <summary> + /// Gets or sets the SubtitleProfiles. + /// </summary> public SubtitleProfile[] SubtitleProfiles { get; set; } - public DeviceProfile() - { - DirectPlayProfiles = Array.Empty<DirectPlayProfile>(); - TranscodingProfiles = Array.Empty<TranscodingProfile>(); - ResponseProfiles = Array.Empty<ResponseProfile>(); - CodecProfiles = Array.Empty<CodecProfile>(); - ContainerProfiles = Array.Empty<ContainerProfile>(); - SubtitleProfiles = Array.Empty<SubtitleProfile>(); - - XmlRootAttributes = Array.Empty<XmlAttribute>(); - - SupportedMediaTypes = "Audio,Photo,Video"; - MaxStreamingBitrate = 8000000; - MaxStaticBitrate = 8000000; - MusicStreamingTranscodingBitrate = 128000; - } - + /// <summary> + /// The GetSupportedMediaTypes. + /// </summary> + /// <returns>The .</returns> public string[] GetSupportedMediaTypes() { return ContainerProfile.SplitValue(SupportedMediaTypes); } + /// <summary> + /// Gets the audio transcoding profile. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="audioCodec">The audio Codec.</param> + /// <returns>A <see cref="TranscodingProfile"/>.</returns> public TranscodingProfile GetAudioTranscodingProfile(string container, string audioCodec) { container = (container ?? string.Empty).TrimStart('.'); @@ -158,6 +271,13 @@ namespace MediaBrowser.Model.Dlna return null; } + /// <summary> + /// Gets the video transcoding profile. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="audioCodec">The audio Codec.</param> + /// <param name="videoCodec">The video Codec.</param> + /// <returns>The <see cref="TranscodingProfile"/>.</returns> public TranscodingProfile GetVideoTranscodingProfile(string container, string audioCodec, string videoCodec) { container = (container ?? string.Empty).TrimStart('.'); @@ -190,6 +310,16 @@ namespace MediaBrowser.Model.Dlna return null; } + /// <summary> + /// Gets the audio media profile. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="audioCodec">The audio codec.</param> + /// <param name="audioChannels">The audio channels.</param> + /// <param name="audioBitrate">The audio bitrate.</param> + /// <param name="audioSampleRate">The audio sample rate.</param> + /// <param name="audioBitDepth">The audio bit depth.</param> + /// <returns>The <see cref="ResponseProfile"/>.</returns> public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth) { foreach (var i in ResponseProfiles) @@ -231,6 +361,11 @@ namespace MediaBrowser.Model.Dlna return null; } + /// <summary> + /// Gets the model profile condition. + /// </summary> + /// <param name="c">The c<see cref="ProfileCondition"/>.</param> + /// <returns>The <see cref="ProfileCondition"/>.</returns> private ProfileCondition GetModelProfileCondition(ProfileCondition c) { return new ProfileCondition @@ -242,6 +377,13 @@ namespace MediaBrowser.Model.Dlna }; } + /// <summary> + /// Gets the image media profile. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="width">The width.</param> + /// <param name="height">The height.</param> + /// <returns>The <see cref="ResponseProfile"/>.</returns> public ResponseProfile GetImageMediaProfile(string container, int? width, int? height) { foreach (var i in ResponseProfiles) @@ -277,6 +419,29 @@ namespace MediaBrowser.Model.Dlna return null; } + /// <summary> + /// Gets the video media profile. + /// </summary> + /// <param name="container">The container.</param> + /// <param name="audioCodec">The audio codec.</param> + /// <param name="videoCodec">The video codec.</param> + /// <param name="width">The width.</param> + /// <param name="height">The height.</param> + /// <param name="bitDepth">The bit depth.</param> + /// <param name="videoBitrate">The video bitrate.</param> + /// <param name="videoProfile">The video profile.</param> + /// <param name="videoLevel">The video level.</param> + /// <param name="videoFramerate">The video framerate.</param> + /// <param name="packetLength">The packet length.</param> + /// <param name="timestamp">The timestamp<see cref="TransportStreamTimestamp"/>.</param> + /// <param name="isAnamorphic">True if anamorphic.</param> + /// <param name="isInterlaced">True if interlaced.</param> + /// <param name="refFrames">The ref frames.</param> + /// <param name="numVideoStreams">The number of video streams.</param> + /// <param name="numAudioStreams">The number of audio streams.</param> + /// <param name="videoCodecTag">The video Codec tag.</param> + /// <param name="isAvc">True if Avc.</param> + /// <returns>The <see cref="ResponseProfile"/>.</returns> public ResponseProfile GetVideoMediaProfile( string container, string audioCodec, diff --git a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs index a4305c8104..65fccbdd41 100644 --- a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs +++ b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Model.Dlna new ResolutionConfiguration(720, 950000), new ResolutionConfiguration(1280, 2500000), new ResolutionConfiguration(1920, 4000000), - new ResolutionConfiguration(2560, 8000000), + new ResolutionConfiguration(2560, 20000000), new ResolutionConfiguration(3840, 35000000) }; @@ -29,7 +29,7 @@ namespace MediaBrowser.Model.Dlna int? maxWidth, int? maxHeight) { - // If the bitrate isn't changing, then don't downlscale the resolution + // If the bitrate isn't changing, then don't downscale the resolution if (inputBitrate.HasValue && outputBitrate >= inputBitrate.Value) { if (maxWidth.HasValue || maxHeight.HasValue) @@ -80,11 +80,11 @@ namespace MediaBrowser.Model.Dlna private static double GetVideoBitrateScaleFactor(string codec) { - if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase) || - string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase) || - string.Equals(codec, "vp9", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase) + || string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase) + || string.Equals(codec, "vp9", StringComparison.OrdinalIgnoreCase)) { - return .5; + return .6; } return 1; diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 13234c3813..59c9810009 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -872,11 +872,34 @@ namespace MediaBrowser.Model.Dlna return playlistItem; } - private static int GetDefaultAudioBitrateIfUnknown(MediaStream audioStream) + private static int GetDefaultAudioBitrate(string audioCodec, int? audioChannels) { - if ((audioStream.Channels ?? 0) >= 6) + if (!string.IsNullOrEmpty(audioCodec)) { - return 384000; + // Default to a higher bitrate for stream copy + if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase) + || string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase) + || string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase) + || string.Equals(audioCodec, "eac3", StringComparison.OrdinalIgnoreCase)) + { + if ((audioChannels ?? 0) < 2) + { + return 128000; + } + + return (audioChannels ?? 0) >= 6 ? 640000 : 384000; + } + + if (string.Equals(audioCodec, "flac", StringComparison.OrdinalIgnoreCase) + || string.Equals(audioCodec, "alac", StringComparison.OrdinalIgnoreCase)) + { + if ((audioChannels ?? 0) < 2) + { + return 768000; + } + + return (audioChannels ?? 0) >= 6 ? 3584000 : 1536000; + } } return 192000; @@ -897,14 +920,27 @@ namespace MediaBrowser.Model.Dlna } else { - if (targetAudioChannels.HasValue && audioStream.Channels.HasValue && targetAudioChannels.Value < audioStream.Channels.Value) + if (targetAudioChannels.HasValue + && audioStream.Channels.HasValue + && audioStream.Channels.Value > targetAudioChannels.Value) { - // Reduce the bitrate if we're downmixing - defaultBitrate = targetAudioChannels.Value < 2 ? 128000 : 192000; + // Reduce the bitrate if we're downmixing. + defaultBitrate = GetDefaultAudioBitrate(targetAudioCodec, targetAudioChannels); + } + else if (targetAudioChannels.HasValue + && audioStream.Channels.HasValue + && audioStream.Channels.Value <= targetAudioChannels.Value + && !string.IsNullOrEmpty(audioStream.Codec) + && targetAudioCodecs != null + && targetAudioCodecs.Length > 0 + && !Array.Exists(targetAudioCodecs, elem => string.Equals(audioStream.Codec, elem, StringComparison.OrdinalIgnoreCase))) + { + // Shift the bitrate if we're transcoding to a different audio codec. + defaultBitrate = GetDefaultAudioBitrate(targetAudioCodec, audioStream.Channels.Value); } else { - defaultBitrate = audioStream.BitRate ?? GetDefaultAudioBitrateIfUnknown(audioStream); + defaultBitrate = audioStream.BitRate ?? GetDefaultAudioBitrate(targetAudioCodec, targetAudioChannels); } // Seeing webm encoding failures when source has 1 audio channel and 22k bitrate. @@ -938,8 +974,28 @@ namespace MediaBrowser.Model.Dlna { return 448000; } + else if (totalBitrate <= 4000000) + { + return 640000; + } + else if (totalBitrate <= 5000000) + { + return 768000; + } + else if (totalBitrate <= 10000000) + { + return 1536000; + } + else if (totalBitrate <= 15000000) + { + return 2304000; + } + else if (totalBitrate <= 20000000) + { + return 3584000; + } - return 640000; + return 7168000; } private (PlayMethod?, List<TranscodeReason>) GetVideoDirectPlayProfile( @@ -1438,6 +1494,32 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.AudioSampleRate: + { + if (!enableNonQualifiedConditions) + { + continue; + } + + if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var num)) + { + if (condition.Condition == ProfileConditionType.Equals) + { + item.AudioSampleRate = num; + } + else if (condition.Condition == ProfileConditionType.LessThanEqual) + { + item.AudioSampleRate = Math.Min(num, item.AudioSampleRate ?? num); + } + else if (condition.Condition == ProfileConditionType.GreaterThanEqual) + { + item.AudioSampleRate = Math.Max(num, item.AudioSampleRate ?? num); + } + } + + break; + } + case ProfileConditionValue.AudioChannels: { if (string.IsNullOrEmpty(qualifier)) diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 9399d21f16..55b12ae810 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -110,6 +110,8 @@ namespace MediaBrowser.Model.Dlna public int? AudioBitrate { get; set; } + public int? AudioSampleRate { get; set; } + public int? VideoBitrate { get; set; } public int? MaxWidth { get; set; } @@ -183,8 +185,10 @@ namespace MediaBrowser.Model.Dlna continue; } + // Be careful, IsDirectStream==true by default (Static != false or not in query). + // See initialization of StreamingRequestDto in AudioController.GetAudioStream() method : Static = @static ?? true. if (string.Equals(pair.Name, "Static", StringComparison.OrdinalIgnoreCase) && - string.Equals(pair.Value, "false", StringComparison.OrdinalIgnoreCase)) + string.Equals(pair.Value, "true", StringComparison.OrdinalIgnoreCase)) { continue; } @@ -250,6 +254,7 @@ namespace MediaBrowser.Model.Dlna list.Add(new NameValuePair("SubtitleStreamIndex", item.SubtitleStreamIndex.HasValue && item.SubtitleDeliveryMethod != SubtitleDeliveryMethod.External ? item.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture) : string.Empty)); list.Add(new NameValuePair("VideoBitrate", item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty)); list.Add(new NameValuePair("AudioBitrate", item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty)); + list.Add(new NameValuePair("AudioSampleRate", item.AudioSampleRate.HasValue ? item.AudioSampleRate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty)); list.Add(new NameValuePair("MaxFramerate", item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(CultureInfo.InvariantCulture) : string.Empty)); list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(CultureInfo.InvariantCulture) : string.Empty)); @@ -521,7 +526,9 @@ namespace MediaBrowser.Model.Dlna get { var stream = TargetAudioStream; - return stream == null ? null : stream.SampleRate; + return AudioSampleRate.HasValue && !IsDirectStream + ? AudioSampleRate + : stream == null ? null : stream.SampleRate; } } @@ -787,7 +794,7 @@ namespace MediaBrowser.Model.Dlna public int? GetTargetAudioChannels(string codec) { - var defaultValue = GlobalMaxAudioChannels; + var defaultValue = GlobalMaxAudioChannels ?? TranscodingMaxAudioChannels; var value = GetOption(codec, "audiochannels"); if (string.IsNullOrEmpty(value)) diff --git a/MediaBrowser.Model/Dlna/XmlAttribute.cs b/MediaBrowser.Model/Dlna/XmlAttribute.cs index 3a8939a797..03bb2e4b11 100644 --- a/MediaBrowser.Model/Dlna/XmlAttribute.cs +++ b/MediaBrowser.Model/Dlna/XmlAttribute.cs @@ -5,11 +5,20 @@ using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna { + /// <summary> + /// Defines the <see cref="XmlAttribute" />. + /// </summary> public class XmlAttribute { + /// <summary> + /// Gets or sets the name of the attribute. + /// </summary> [XmlAttribute("name")] public string Name { get; set; } + /// <summary> + /// Gets or sets the value of the attribute. + /// </summary> [XmlAttribute("value")] public string Value { get; set; } } |
