< Summary - Jellyfin

Information
Class: MediaBrowser.Model.Dlna.ConditionProcessor
Assembly: MediaBrowser.Model
File(s): /srv/git/jellyfin/MediaBrowser.Model/Dlna/ConditionProcessor.cs
Line coverage
40%
Covered lines: 44
Uncovered lines: 66
Coverable lines: 110
Total lines: 376
Line coverage: 40%
Branch coverage
33%
Covered branches: 42
Total branches: 126
Branch coverage: 33.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
IsVideoConditionSatisfied(...)46.15%692660%
IsImageConditionSatisfied(...)0%2040%
IsAudioConditionSatisfied(...)0%110100%
IsVideoAudioConditionSatisfied(...)33.33%471237.5%
IsConditionSatisfied(...)29.41%881737.5%
IsConditionSatisfied(...)25%16850%
IsConditionSatisfied(...)75%9875%
IsConditionSatisfied(...)23.52%1111731.25%
IsConditionSatisfied(...)0%4260%
IsConditionSatisfied(...)50%661847.05%

File(s)

/srv/git/jellyfin/MediaBrowser.Model/Dlna/ConditionProcessor.cs

#LineLine coverage
 1using System;
 2using System.Globalization;
 3using Jellyfin.Data.Enums;
 4using Jellyfin.Extensions;
 5using MediaBrowser.Model.MediaInfo;
 6
 7namespace MediaBrowser.Model.Dlna
 8{
 9    /// <summary>
 10    /// The condition processor.
 11    /// </summary>
 12    public static class ConditionProcessor
 13    {
 14        /// <summary>
 15        /// Checks if a video condition is satisfied.
 16        /// </summary>
 17        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 18        /// <param name="width">The width.</param>
 19        /// <param name="height">The height.</param>
 20        /// <param name="videoBitDepth">The bit depth.</param>
 21        /// <param name="videoBitrate">The bitrate.</param>
 22        /// <param name="videoProfile">The video profile.</param>
 23        /// <param name="videoRangeType">The <see cref="VideoRangeType"/>.</param>
 24        /// <param name="videoLevel">The video level.</param>
 25        /// <param name="videoFramerate">The framerate.</param>
 26        /// <param name="packetLength">The packet length.</param>
 27        /// <param name="timestamp">The <see cref="TransportStreamTimestamp"/>.</param>
 28        /// <param name="isAnamorphic">A value indicating whether the video is anamorphic.</param>
 29        /// <param name="isInterlaced">A value indicating whether the video is interlaced.</param>
 30        /// <param name="refFrames">The reference frames.</param>
 31        /// <param name="numStreams">The number of streams.</param>
 32        /// <param name="numVideoStreams">The number of video streams.</param>
 33        /// <param name="numAudioStreams">The number of audio streams.</param>
 34        /// <param name="videoCodecTag">The video codec tag.</param>
 35        /// <param name="isAvc">A value indicating whether the video is AVC.</param>
 36        /// <returns><b>True</b> if the condition is satisfied.</returns>
 37        public static bool IsVideoConditionSatisfied(
 38            ProfileCondition condition,
 39            int? width,
 40            int? height,
 41            int? videoBitDepth,
 42            int? videoBitrate,
 43            string? videoProfile,
 44            VideoRangeType? videoRangeType,
 45            double? videoLevel,
 46            float? videoFramerate,
 47            int? packetLength,
 48            TransportStreamTimestamp? timestamp,
 49            bool? isAnamorphic,
 50            bool? isInterlaced,
 51            int? refFrames,
 52            int numStreams,
 53            int? numVideoStreams,
 54            int? numAudioStreams,
 55            string? videoCodecTag,
 56            bool? isAvc)
 57        {
 134558            switch (condition.Property)
 59            {
 60                case ProfileConditionValue.IsInterlaced:
 16861                    return IsConditionSatisfied(condition, isInterlaced);
 62                case ProfileConditionValue.IsAnamorphic:
 23863                    return IsConditionSatisfied(condition, isAnamorphic);
 64                case ProfileConditionValue.IsAvc:
 065                    return IsConditionSatisfied(condition, isAvc);
 66                case ProfileConditionValue.VideoFramerate:
 1967                    return IsConditionSatisfied(condition, videoFramerate);
 68                case ProfileConditionValue.VideoLevel:
 25169                    return IsConditionSatisfied(condition, videoLevel);
 70                case ProfileConditionValue.VideoProfile:
 25971                    return IsConditionSatisfied(condition, videoProfile);
 72                case ProfileConditionValue.VideoRangeType:
 24073                    return IsConditionSatisfied(condition, videoRangeType);
 74                case ProfileConditionValue.VideoCodecTag:
 1975                    return IsConditionSatisfied(condition, videoCodecTag);
 76                case ProfileConditionValue.PacketLength:
 077                    return IsConditionSatisfied(condition, packetLength);
 78                case ProfileConditionValue.VideoBitDepth:
 079                    return IsConditionSatisfied(condition, videoBitDepth);
 80                case ProfileConditionValue.VideoBitrate:
 6881                    return IsConditionSatisfied(condition, videoBitrate);
 82                case ProfileConditionValue.Height:
 083                    return IsConditionSatisfied(condition, height);
 84                case ProfileConditionValue.Width:
 1885                    return IsConditionSatisfied(condition, width);
 86                case ProfileConditionValue.RefFrames:
 787                    return IsConditionSatisfied(condition, refFrames);
 88                case ProfileConditionValue.NumStreams:
 5889                    return IsConditionSatisfied(condition, numStreams);
 90                case ProfileConditionValue.NumAudioStreams:
 091                    return IsConditionSatisfied(condition, numAudioStreams);
 92                case ProfileConditionValue.NumVideoStreams:
 093                    return IsConditionSatisfied(condition, numVideoStreams);
 94                case ProfileConditionValue.VideoTimestamp:
 095                    return IsConditionSatisfied(condition, timestamp);
 96                default:
 097                    return true;
 98            }
 99        }
 100
 101        /// <summary>
 102        /// Checks if a image condition is satisfied.
 103        /// </summary>
 104        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 105        /// <param name="width">The width.</param>
 106        /// <param name="height">The height.</param>
 107        /// <returns><b>True</b> if the condition is satisfied.</returns>
 108        public static bool IsImageConditionSatisfied(ProfileCondition condition, int? width, int? height)
 109        {
 0110            switch (condition.Property)
 111            {
 112                case ProfileConditionValue.Height:
 0113                    return IsConditionSatisfied(condition, height);
 114                case ProfileConditionValue.Width:
 0115                    return IsConditionSatisfied(condition, width);
 116                default:
 0117                    throw new ArgumentException("Unexpected condition on image file: " + condition.Property);
 118            }
 119        }
 120
 121        /// <summary>
 122        /// Checks if an audio condition is satisfied.
 123        /// </summary>
 124        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 125        /// <param name="audioChannels">The channel count.</param>
 126        /// <param name="audioBitrate">The bitrate.</param>
 127        /// <param name="audioSampleRate">The sample rate.</param>
 128        /// <param name="audioBitDepth">The bit depth.</param>
 129        /// <returns><b>True</b> if the condition is satisfied.</returns>
 130        public static bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, 
 131        {
 0132            switch (condition.Property)
 133            {
 134                case ProfileConditionValue.AudioBitrate:
 0135                    return IsConditionSatisfied(condition, audioBitrate);
 136                case ProfileConditionValue.AudioChannels:
 0137                    return IsConditionSatisfied(condition, audioChannels);
 138                case ProfileConditionValue.AudioSampleRate:
 0139                    return IsConditionSatisfied(condition, audioSampleRate);
 140                case ProfileConditionValue.AudioBitDepth:
 0141                    return IsConditionSatisfied(condition, audioBitDepth);
 142                default:
 0143                    throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
 144            }
 145        }
 146
 147        /// <summary>
 148        /// Checks if an audio condition is satisfied for a video.
 149        /// </summary>
 150        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 151        /// <param name="audioChannels">The channel count.</param>
 152        /// <param name="audioBitrate">The bitrate.</param>
 153        /// <param name="audioSampleRate">The sample rate.</param>
 154        /// <param name="audioBitDepth">The bit depth.</param>
 155        /// <param name="audioProfile">The profile.</param>
 156        /// <param name="isSecondaryTrack">A value indicating whether the audio is a secondary track.</param>
 157        /// <returns><b>True</b> if the condition is satisfied.</returns>
 158        public static bool IsVideoAudioConditionSatisfied(
 159            ProfileCondition condition,
 160            int? audioChannels,
 161            int? audioBitrate,
 162            int? audioSampleRate,
 163            int? audioBitDepth,
 164            string? audioProfile,
 165            bool? isSecondaryTrack)
 166        {
 982167            switch (condition.Property)
 168            {
 169                case ProfileConditionValue.AudioProfile:
 0170                    return IsConditionSatisfied(condition, audioProfile);
 171                case ProfileConditionValue.AudioBitrate:
 0172                    return IsConditionSatisfied(condition, audioBitrate);
 173                case ProfileConditionValue.AudioChannels:
 194174                    return IsConditionSatisfied(condition, audioChannels);
 175                case ProfileConditionValue.IsSecondaryAudio:
 788176                    return IsConditionSatisfied(condition, isSecondaryTrack);
 177                case ProfileConditionValue.AudioSampleRate:
 0178                    return IsConditionSatisfied(condition, audioSampleRate);
 179                case ProfileConditionValue.AudioBitDepth:
 0180                    return IsConditionSatisfied(condition, audioBitDepth);
 181                default:
 0182                    throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
 183            }
 184        }
 185
 186        private static bool IsConditionSatisfied(ProfileCondition condition, int? currentValue)
 187        {
 345188            if (!currentValue.HasValue)
 189            {
 190                // If the value is unknown, it satisfies if not marked as required
 0191                return !condition.IsRequired;
 192            }
 193
 345194            var conditionType = condition.Condition;
 345195            if (condition.Condition == ProfileConditionType.EqualsAny)
 196            {
 0197                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 198                {
 0199                    if (int.TryParse(singleConditionString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int 
 0200                        && conditionValue.Equals(currentValue))
 201                    {
 0202                        return true;
 203                    }
 204                }
 205
 0206                return false;
 207            }
 208
 345209            if (int.TryParse(condition.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var expected))
 210            {
 211                switch (conditionType)
 212                {
 213                    case ProfileConditionType.Equals:
 0214                        return currentValue.Value.Equals(expected);
 215                    case ProfileConditionType.GreaterThanEqual:
 18216                        return currentValue.Value >= expected;
 217                    case ProfileConditionType.LessThanEqual:
 327218                        return currentValue.Value <= expected;
 219                    case ProfileConditionType.NotEquals:
 0220                        return !currentValue.Value.Equals(expected);
 221                    default:
 0222                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 223                }
 224            }
 225
 0226            return false;
 227        }
 228
 229        private static bool IsConditionSatisfied(ProfileCondition condition, string? currentValue)
 230        {
 278231            if (string.IsNullOrEmpty(currentValue))
 232            {
 233                // If the value is unknown, it satisfies if not marked as required
 0234                return !condition.IsRequired;
 235            }
 236
 278237            string expected = condition.Value;
 238
 278239            switch (condition.Condition)
 240            {
 241                case ProfileConditionType.EqualsAny:
 278242                    return expected.Split('|').Contains(currentValue, StringComparison.OrdinalIgnoreCase);
 243                case ProfileConditionType.Equals:
 0244                    return string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
 245                case ProfileConditionType.NotEquals:
 0246                    return !string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
 247                default:
 0248                    throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 249            }
 250        }
 251
 252        private static bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue)
 253        {
 1194254            if (!currentValue.HasValue)
 255            {
 256                // If the value is unknown, it satisfies if not marked as required
 185257                return !condition.IsRequired;
 258            }
 259
 1009260            if (bool.TryParse(condition.Value, out var expected))
 261            {
 1009262                switch (condition.Condition)
 263                {
 264                    case ProfileConditionType.Equals:
 788265                        return currentValue.Value == expected;
 266                    case ProfileConditionType.NotEquals:
 221267                        return currentValue.Value != expected;
 268                    default:
 0269                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 270                }
 271            }
 272
 0273            return false;
 274        }
 275
 276        private static bool IsConditionSatisfied(ProfileCondition condition, double? currentValue)
 277        {
 270278            if (!currentValue.HasValue)
 279            {
 280                // If the value is unknown, it satisfies if not marked as required
 0281                return !condition.IsRequired;
 282            }
 283
 270284            var conditionType = condition.Condition;
 270285            if (condition.Condition == ProfileConditionType.EqualsAny)
 286            {
 0287                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 288                {
 0289                    if (double.TryParse(singleConditionString, NumberStyles.Float | NumberStyles.AllowThousands, Culture
 0290                        && conditionValue.Equals(currentValue))
 291                    {
 0292                        return true;
 293                    }
 294                }
 295
 0296                return false;
 297            }
 298
 270299            if (double.TryParse(condition.Value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.Invariant
 300            {
 301                switch (conditionType)
 302                {
 303                    case ProfileConditionType.Equals:
 0304                        return currentValue.Value.Equals(expected);
 305                    case ProfileConditionType.GreaterThanEqual:
 0306                        return currentValue.Value >= expected;
 307                    case ProfileConditionType.LessThanEqual:
 270308                        return currentValue.Value <= expected;
 309                    case ProfileConditionType.NotEquals:
 0310                        return !currentValue.Value.Equals(expected);
 311                    default:
 0312                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 313                }
 314            }
 315
 0316            return false;
 317        }
 318
 319        private static bool IsConditionSatisfied(ProfileCondition condition, TransportStreamTimestamp? timestamp)
 320        {
 0321            if (!timestamp.HasValue)
 322            {
 323                // If the value is unknown, it satisfies if not marked as required
 0324                return !condition.IsRequired;
 325            }
 326
 0327            var expected = (TransportStreamTimestamp)Enum.Parse(typeof(TransportStreamTimestamp), condition.Value, true)
 328
 0329            switch (condition.Condition)
 330            {
 331                case ProfileConditionType.Equals:
 0332                    return timestamp == expected;
 333                case ProfileConditionType.NotEquals:
 0334                    return timestamp != expected;
 335                default:
 0336                    throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 337            }
 338        }
 339
 340        private static bool IsConditionSatisfied(ProfileCondition condition, VideoRangeType? currentValue)
 341        {
 240342            if (!currentValue.HasValue || currentValue.Equals(VideoRangeType.Unknown))
 343            {
 344                // If the value is unknown, it satisfies if not marked as required
 0345                return !condition.IsRequired;
 346            }
 347
 240348            var conditionType = condition.Condition;
 240349            if (conditionType == ProfileConditionType.EqualsAny)
 350            {
 1108351                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 352                {
 420353                    if (Enum.TryParse(singleConditionString, true, out VideoRangeType conditionValue)
 420354                        && conditionValue.Equals(currentValue))
 355                    {
 212356                        return true;
 357                    }
 358                }
 359
 28360                return false;
 361            }
 362
 0363            if (Enum.TryParse(condition.Value, true, out VideoRangeType expected))
 364            {
 0365                return conditionType switch
 0366                {
 0367                    ProfileConditionType.Equals => currentValue.Value == expected,
 0368                    ProfileConditionType.NotEquals => currentValue.Value != expected,
 0369                    _ => throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition)
 0370                };
 371            }
 372
 0373            return false;
 374        }
 375    }
 376}

Methods/Properties

IsVideoConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.String,System.Nullable`1<Jellyfin.Data.Enums.VideoRangeType>,System.Nullable`1<System.Double>,System.Nullable`1<System.Single>,System.Nullable`1<System.Int32>,System.Nullable`1<MediaBrowser.Model.MediaInfo.TransportStreamTimestamp>,System.Nullable`1<System.Boolean>,System.Nullable`1<System.Boolean>,System.Nullable`1<System.Int32>,System.Int32,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.String,System.Nullable`1<System.Boolean>)
IsImageConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>)
IsAudioConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>)
IsVideoAudioConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.Nullable`1<System.Int32>,System.String,System.Nullable`1<System.Boolean>)
IsConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<System.Int32>)
IsConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.String)
IsConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<System.Boolean>)
IsConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<System.Double>)
IsConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<MediaBrowser.Model.MediaInfo.TransportStreamTimestamp>)
IsConditionSatisfied(MediaBrowser.Model.Dlna.ProfileCondition,System.Nullable`1<Jellyfin.Data.Enums.VideoRangeType>)