< Summary - Jellyfin

Information
Class: MediaBrowser.Model.Dlna.ConditionProcessor
Assembly: MediaBrowser.Model
File(s): /srv/git/jellyfin/MediaBrowser.Model/Dlna/ConditionProcessor.cs
Line coverage
39%
Covered lines: 43
Uncovered lines: 66
Coverable lines: 109
Total lines: 372
Line coverage: 39.4%
Branch coverage
32%
Covered branches: 41
Total branches: 125
Branch coverage: 32.8%
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(...)44%71.672557.89%
IsImageConditionSatisfied(...)0%2040%
IsAudioConditionSatisfied(...)0%110100%
IsVideoAudioConditionSatisfied(...)33.33%47.161237.5%
IsConditionSatisfied(...)29.41%87.561737.5%
IsConditionSatisfied(...)25%16850%
IsConditionSatisfied(...)75%9875%
IsConditionSatisfied(...)23.52%110.911731.25%
IsConditionSatisfied(...)0%4260%
IsConditionSatisfied(...)50%66.11847.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 tthe video is anamorphic.</param>
 29        /// <param name="isInterlaced">A value indicating whether tthe video is interlaced.</param>
 30        /// <param name="refFrames">The reference frames.</param>
 31        /// <param name="numVideoStreams">The number of video streams.</param>
 32        /// <param name="numAudioStreams">The number of audio streams.</param>
 33        /// <param name="videoCodecTag">The video codec tag.</param>
 34        /// <param name="isAvc">A value indicating whether the video is AVC.</param>
 35        /// <returns><b>True</b> if the condition is satisfied.</returns>
 36        public static bool IsVideoConditionSatisfied(
 37            ProfileCondition condition,
 38            int? width,
 39            int? height,
 40            int? videoBitDepth,
 41            int? videoBitrate,
 42            string? videoProfile,
 43            VideoRangeType? videoRangeType,
 44            double? videoLevel,
 45            float? videoFramerate,
 46            int? packetLength,
 47            TransportStreamTimestamp? timestamp,
 48            bool? isAnamorphic,
 49            bool? isInterlaced,
 50            int? refFrames,
 51            int? numVideoStreams,
 52            int? numAudioStreams,
 53            string? videoCodecTag,
 54            bool? isAvc)
 55        {
 110056            switch (condition.Property)
 57            {
 58                case ProfileConditionValue.IsInterlaced:
 15459                    return IsConditionSatisfied(condition, isInterlaced);
 60                case ProfileConditionValue.IsAnamorphic:
 21861                    return IsConditionSatisfied(condition, isAnamorphic);
 62                case ProfileConditionValue.IsAvc:
 063                    return IsConditionSatisfied(condition, isAvc);
 64                case ProfileConditionValue.VideoFramerate:
 1065                    return IsConditionSatisfied(condition, videoFramerate);
 66                case ProfileConditionValue.VideoLevel:
 21967                    return IsConditionSatisfied(condition, videoLevel);
 68                case ProfileConditionValue.VideoProfile:
 23969                    return IsConditionSatisfied(condition, videoProfile);
 70                case ProfileConditionValue.VideoRangeType:
 16671                    return IsConditionSatisfied(condition, videoRangeType);
 72                case ProfileConditionValue.VideoCodecTag:
 1973                    return IsConditionSatisfied(condition, videoCodecTag);
 74                case ProfileConditionValue.PacketLength:
 075                    return IsConditionSatisfied(condition, packetLength);
 76                case ProfileConditionValue.VideoBitDepth:
 077                    return IsConditionSatisfied(condition, videoBitDepth);
 78                case ProfileConditionValue.VideoBitrate:
 5079                    return IsConditionSatisfied(condition, videoBitrate);
 80                case ProfileConditionValue.Height:
 081                    return IsConditionSatisfied(condition, height);
 82                case ProfileConditionValue.Width:
 1883                    return IsConditionSatisfied(condition, width);
 84                case ProfileConditionValue.RefFrames:
 785                    return IsConditionSatisfied(condition, refFrames);
 86                case ProfileConditionValue.NumAudioStreams:
 087                    return IsConditionSatisfied(condition, numAudioStreams);
 88                case ProfileConditionValue.NumVideoStreams:
 089                    return IsConditionSatisfied(condition, numVideoStreams);
 90                case ProfileConditionValue.VideoTimestamp:
 091                    return IsConditionSatisfied(condition, timestamp);
 92                default:
 093                    return true;
 94            }
 95        }
 96
 97        /// <summary>
 98        /// Checks if a image condition is satisfied.
 99        /// </summary>
 100        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 101        /// <param name="width">The width.</param>
 102        /// <param name="height">The height.</param>
 103        /// <returns><b>True</b> if the condition is satisfied.</returns>
 104        public static bool IsImageConditionSatisfied(ProfileCondition condition, int? width, int? height)
 105        {
 0106            switch (condition.Property)
 107            {
 108                case ProfileConditionValue.Height:
 0109                    return IsConditionSatisfied(condition, height);
 110                case ProfileConditionValue.Width:
 0111                    return IsConditionSatisfied(condition, width);
 112                default:
 0113                    throw new ArgumentException("Unexpected condition on image file: " + condition.Property);
 114            }
 115        }
 116
 117        /// <summary>
 118        /// Checks if an audio condition is satisfied.
 119        /// </summary>
 120        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 121        /// <param name="audioChannels">The channel count.</param>
 122        /// <param name="audioBitrate">The bitrate.</param>
 123        /// <param name="audioSampleRate">The sample rate.</param>
 124        /// <param name="audioBitDepth">The bit depth.</param>
 125        /// <returns><b>True</b> if the condition is satisfied.</returns>
 126        public static bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, 
 127        {
 0128            switch (condition.Property)
 129            {
 130                case ProfileConditionValue.AudioBitrate:
 0131                    return IsConditionSatisfied(condition, audioBitrate);
 132                case ProfileConditionValue.AudioChannels:
 0133                    return IsConditionSatisfied(condition, audioChannels);
 134                case ProfileConditionValue.AudioSampleRate:
 0135                    return IsConditionSatisfied(condition, audioSampleRate);
 136                case ProfileConditionValue.AudioBitDepth:
 0137                    return IsConditionSatisfied(condition, audioBitDepth);
 138                default:
 0139                    throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
 140            }
 141        }
 142
 143        /// <summary>
 144        /// Checks if an audio condition is satisfied for a video.
 145        /// </summary>
 146        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 147        /// <param name="audioChannels">The channel count.</param>
 148        /// <param name="audioBitrate">The bitrate.</param>
 149        /// <param name="audioSampleRate">The sample rate.</param>
 150        /// <param name="audioBitDepth">The bit depth.</param>
 151        /// <param name="audioProfile">The profile.</param>
 152        /// <param name="isSecondaryTrack">A value indicating whether the audio is a secondary track.</param>
 153        /// <returns><b>True</b> if the condition is satisfied.</returns>
 154        public static bool IsVideoAudioConditionSatisfied(
 155            ProfileCondition condition,
 156            int? audioChannels,
 157            int? audioBitrate,
 158            int? audioSampleRate,
 159            int? audioBitDepth,
 160            string? audioProfile,
 161            bool? isSecondaryTrack)
 162        {
 353163            switch (condition.Property)
 164            {
 165                case ProfileConditionValue.AudioProfile:
 0166                    return IsConditionSatisfied(condition, audioProfile);
 167                case ProfileConditionValue.AudioBitrate:
 0168                    return IsConditionSatisfied(condition, audioBitrate);
 169                case ProfileConditionValue.AudioChannels:
 73170                    return IsConditionSatisfied(condition, audioChannels);
 171                case ProfileConditionValue.IsSecondaryAudio:
 280172                    return IsConditionSatisfied(condition, isSecondaryTrack);
 173                case ProfileConditionValue.AudioSampleRate:
 0174                    return IsConditionSatisfied(condition, audioSampleRate);
 175                case ProfileConditionValue.AudioBitDepth:
 0176                    return IsConditionSatisfied(condition, audioBitDepth);
 177                default:
 0178                    throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
 179            }
 180        }
 181
 182        private static bool IsConditionSatisfied(ProfileCondition condition, int? currentValue)
 183        {
 148184            if (!currentValue.HasValue)
 185            {
 186                // If the value is unknown, it satisfies if not marked as required
 0187                return !condition.IsRequired;
 188            }
 189
 148190            var conditionType = condition.Condition;
 148191            if (condition.Condition == ProfileConditionType.EqualsAny)
 192            {
 0193                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 194                {
 0195                    if (int.TryParse(singleConditionString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int 
 0196                        && conditionValue.Equals(currentValue))
 197                    {
 0198                        return true;
 199                    }
 200                }
 201
 0202                return false;
 203            }
 204
 148205            if (int.TryParse(condition.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var expected))
 206            {
 207                switch (conditionType)
 208                {
 209                    case ProfileConditionType.Equals:
 0210                        return currentValue.Value.Equals(expected);
 211                    case ProfileConditionType.GreaterThanEqual:
 18212                        return currentValue.Value >= expected;
 213                    case ProfileConditionType.LessThanEqual:
 130214                        return currentValue.Value <= expected;
 215                    case ProfileConditionType.NotEquals:
 0216                        return !currentValue.Value.Equals(expected);
 217                    default:
 0218                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 219                }
 220            }
 221
 0222            return false;
 223        }
 224
 225        private static bool IsConditionSatisfied(ProfileCondition condition, string? currentValue)
 226        {
 258227            if (string.IsNullOrEmpty(currentValue))
 228            {
 229                // If the value is unknown, it satisfies if not marked as required
 0230                return !condition.IsRequired;
 231            }
 232
 258233            string expected = condition.Value;
 234
 258235            switch (condition.Condition)
 236            {
 237                case ProfileConditionType.EqualsAny:
 258238                    return expected.Split('|').Contains(currentValue, StringComparison.OrdinalIgnoreCase);
 239                case ProfileConditionType.Equals:
 0240                    return string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
 241                case ProfileConditionType.NotEquals:
 0242                    return !string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
 243                default:
 0244                    throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 245            }
 246        }
 247
 248        private static bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue)
 249        {
 652250            if (!currentValue.HasValue)
 251            {
 252                // If the value is unknown, it satisfies if not marked as required
 177253                return !condition.IsRequired;
 254            }
 255
 475256            if (bool.TryParse(condition.Value, out var expected))
 257            {
 475258                switch (condition.Condition)
 259                {
 260                    case ProfileConditionType.Equals:
 280261                        return currentValue.Value == expected;
 262                    case ProfileConditionType.NotEquals:
 195263                        return currentValue.Value != expected;
 264                    default:
 0265                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 266                }
 267            }
 268
 0269            return false;
 270        }
 271
 272        private static bool IsConditionSatisfied(ProfileCondition condition, double? currentValue)
 273        {
 229274            if (!currentValue.HasValue)
 275            {
 276                // If the value is unknown, it satisfies if not marked as required
 0277                return !condition.IsRequired;
 278            }
 279
 229280            var conditionType = condition.Condition;
 229281            if (condition.Condition == ProfileConditionType.EqualsAny)
 282            {
 0283                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 284                {
 0285                    if (double.TryParse(singleConditionString, NumberStyles.Float | NumberStyles.AllowThousands, Culture
 0286                        && conditionValue.Equals(currentValue))
 287                    {
 0288                        return true;
 289                    }
 290                }
 291
 0292                return false;
 293            }
 294
 229295            if (double.TryParse(condition.Value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.Invariant
 296            {
 297                switch (conditionType)
 298                {
 299                    case ProfileConditionType.Equals:
 0300                        return currentValue.Value.Equals(expected);
 301                    case ProfileConditionType.GreaterThanEqual:
 0302                        return currentValue.Value >= expected;
 303                    case ProfileConditionType.LessThanEqual:
 229304                        return currentValue.Value <= expected;
 305                    case ProfileConditionType.NotEquals:
 0306                        return !currentValue.Value.Equals(expected);
 307                    default:
 0308                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 309                }
 310            }
 311
 0312            return false;
 313        }
 314
 315        private static bool IsConditionSatisfied(ProfileCondition condition, TransportStreamTimestamp? timestamp)
 316        {
 0317            if (!timestamp.HasValue)
 318            {
 319                // If the value is unknown, it satisfies if not marked as required
 0320                return !condition.IsRequired;
 321            }
 322
 0323            var expected = (TransportStreamTimestamp)Enum.Parse(typeof(TransportStreamTimestamp), condition.Value, true)
 324
 0325            switch (condition.Condition)
 326            {
 327                case ProfileConditionType.Equals:
 0328                    return timestamp == expected;
 329                case ProfileConditionType.NotEquals:
 0330                    return timestamp != expected;
 331                default:
 0332                    throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 333            }
 334        }
 335
 336        private static bool IsConditionSatisfied(ProfileCondition condition, VideoRangeType? currentValue)
 337        {
 166338            if (!currentValue.HasValue || currentValue.Equals(VideoRangeType.Unknown))
 339            {
 340                // If the value is unknown, it satisfies if not marked as required
 0341                return !condition.IsRequired;
 342            }
 343
 166344            var conditionType = condition.Condition;
 166345            if (conditionType == ProfileConditionType.EqualsAny)
 346            {
 694347                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 348                {
 254349                    if (Enum.TryParse(singleConditionString, true, out VideoRangeType conditionValue)
 254350                        && conditionValue.Equals(currentValue))
 351                    {
 146352                        return true;
 353                    }
 354                }
 355
 20356                return false;
 357            }
 358
 0359            if (Enum.TryParse(condition.Value, true, out VideoRangeType expected))
 360            {
 0361                return conditionType switch
 0362                {
 0363                    ProfileConditionType.Equals => currentValue.Value == expected,
 0364                    ProfileConditionType.NotEquals => currentValue.Value != expected,
 0365                    _ => throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition)
 0366                };
 367            }
 368
 0369            return false;
 370        }
 371    }
 372}

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.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>)