< Summary - Jellyfin

Information
Class: MediaBrowser.Model.Dlna.ConditionProcessor
Assembly: MediaBrowser.Model
File(s): /srv/git/jellyfin/MediaBrowser.Model/Dlna/ConditionProcessor.cs
Line coverage
41%
Covered lines: 47
Uncovered lines: 67
Coverable lines: 114
Total lines: 389
Line coverage: 41.2%
Branch coverage
35%
Covered branches: 46
Total branches: 131
Branch coverage: 35.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 2/13/2026 - 12:11:21 AM Line coverage: 39.8% (45/113) Branch coverage: 33.8% (44/130) Total lines: 3855/11/2026 - 12:15:59 AM Line coverage: 41.2% (47/114) Branch coverage: 35.1% (46/131) Total lines: 389 2/13/2026 - 12:11:21 AM Line coverage: 39.8% (45/113) Branch coverage: 33.8% (44/130) Total lines: 3855/11/2026 - 12:15:59 AM Line coverage: 41.2% (47/114) Branch coverage: 35.1% (46/131) Total lines: 389

Coverage delta

Coverage delta 2 -2

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
IsVideoConditionSatisfied(...)48.14%672761.9%
IsImageConditionSatisfied(...)0%2040%
IsAudioConditionSatisfied(...)0%110100%
IsVideoAudioConditionSatisfied(...)33.33%471237.5%
IsConditionSatisfied(...)35.29%681743.75%
IsConditionSatisfied(...)25%16850%
IsConditionSatisfied(...)75%9875%
IsConditionSatisfied(...)23.52%1111731.25%
IsConditionSatisfied(...)0%4260%
IsConditionSatisfied(...)50%1032245%

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        /// <param name="videoRotation">The video rotation angle, usually 0 or +-90/180.</param>
 37        /// <returns><b>True</b> if the condition is satisfied.</returns>
 38        public static bool IsVideoConditionSatisfied(
 39            ProfileCondition condition,
 40            int? width,
 41            int? height,
 42            int? videoBitDepth,
 43            int? videoBitrate,
 44            string? videoProfile,
 45            VideoRangeType? videoRangeType,
 46            double? videoLevel,
 47            float? videoFramerate,
 48            int? packetLength,
 49            TransportStreamTimestamp? timestamp,
 50            bool? isAnamorphic,
 51            bool? isInterlaced,
 52            int? refFrames,
 53            int numStreams,
 54            int? numVideoStreams,
 55            int? numAudioStreams,
 56            string? videoCodecTag,
 57            bool? isAvc,
 58            int? videoRotation)
 59        {
 134860            switch (condition.Property)
 61            {
 62                case ProfileConditionValue.IsInterlaced:
 16863                    return IsConditionSatisfied(condition, isInterlaced);
 64                case ProfileConditionValue.IsAnamorphic:
 23865                    return IsConditionSatisfied(condition, isAnamorphic);
 66                case ProfileConditionValue.IsAvc:
 067                    return IsConditionSatisfied(condition, isAvc);
 68                case ProfileConditionValue.VideoFramerate:
 1969                    return IsConditionSatisfied(condition, videoFramerate);
 70                case ProfileConditionValue.VideoLevel:
 25271                    return IsConditionSatisfied(condition, videoLevel);
 72                case ProfileConditionValue.VideoProfile:
 26073                    return IsConditionSatisfied(condition, videoProfile);
 74                case ProfileConditionValue.VideoRangeType:
 24075                    return IsConditionSatisfied(condition, videoRangeType);
 76                case ProfileConditionValue.VideoCodecTag:
 1977                    return IsConditionSatisfied(condition, videoCodecTag);
 78                case ProfileConditionValue.PacketLength:
 079                    return IsConditionSatisfied(condition, packetLength);
 80                case ProfileConditionValue.VideoBitDepth:
 081                    return IsConditionSatisfied(condition, videoBitDepth);
 82                case ProfileConditionValue.VideoBitrate:
 6883                    return IsConditionSatisfied(condition, videoBitrate);
 84                case ProfileConditionValue.Height:
 085                    return IsConditionSatisfied(condition, height);
 86                case ProfileConditionValue.Width:
 1887                    return IsConditionSatisfied(condition, width);
 88                case ProfileConditionValue.RefFrames:
 789                    return IsConditionSatisfied(condition, refFrames);
 90                case ProfileConditionValue.NumStreams:
 5891                    return IsConditionSatisfied(condition, numStreams);
 92                case ProfileConditionValue.NumAudioStreams:
 093                    return IsConditionSatisfied(condition, numAudioStreams);
 94                case ProfileConditionValue.NumVideoStreams:
 095                    return IsConditionSatisfied(condition, numVideoStreams);
 96                case ProfileConditionValue.VideoTimestamp:
 097                    return IsConditionSatisfied(condition, timestamp);
 98                case ProfileConditionValue.VideoRotation:
 199                    return IsConditionSatisfied(condition, videoRotation);
 100                default:
 0101                    return true;
 102            }
 103        }
 104
 105        /// <summary>
 106        /// Checks if a image condition is satisfied.
 107        /// </summary>
 108        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 109        /// <param name="width">The width.</param>
 110        /// <param name="height">The height.</param>
 111        /// <returns><b>True</b> if the condition is satisfied.</returns>
 112        public static bool IsImageConditionSatisfied(ProfileCondition condition, int? width, int? height)
 113        {
 0114            switch (condition.Property)
 115            {
 116                case ProfileConditionValue.Height:
 0117                    return IsConditionSatisfied(condition, height);
 118                case ProfileConditionValue.Width:
 0119                    return IsConditionSatisfied(condition, width);
 120                default:
 0121                    throw new ArgumentException("Unexpected condition on image file: " + condition.Property);
 122            }
 123        }
 124
 125        /// <summary>
 126        /// Checks if an audio condition is satisfied.
 127        /// </summary>
 128        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 129        /// <param name="audioChannels">The channel count.</param>
 130        /// <param name="audioBitrate">The bitrate.</param>
 131        /// <param name="audioSampleRate">The sample rate.</param>
 132        /// <param name="audioBitDepth">The bit depth.</param>
 133        /// <returns><b>True</b> if the condition is satisfied.</returns>
 134        public static bool IsAudioConditionSatisfied(ProfileCondition condition, int? audioChannels, int? audioBitrate, 
 135        {
 0136            switch (condition.Property)
 137            {
 138                case ProfileConditionValue.AudioBitrate:
 0139                    return IsConditionSatisfied(condition, audioBitrate);
 140                case ProfileConditionValue.AudioChannels:
 0141                    return IsConditionSatisfied(condition, audioChannels);
 142                case ProfileConditionValue.AudioSampleRate:
 0143                    return IsConditionSatisfied(condition, audioSampleRate);
 144                case ProfileConditionValue.AudioBitDepth:
 0145                    return IsConditionSatisfied(condition, audioBitDepth);
 146                default:
 0147                    throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
 148            }
 149        }
 150
 151        /// <summary>
 152        /// Checks if an audio condition is satisfied for a video.
 153        /// </summary>
 154        /// <param name="condition">The <see cref="ProfileCondition"/>.</param>
 155        /// <param name="audioChannels">The channel count.</param>
 156        /// <param name="audioBitrate">The bitrate.</param>
 157        /// <param name="audioSampleRate">The sample rate.</param>
 158        /// <param name="audioBitDepth">The bit depth.</param>
 159        /// <param name="audioProfile">The profile.</param>
 160        /// <param name="isSecondaryTrack">A value indicating whether the audio is a secondary track.</param>
 161        /// <returns><b>True</b> if the condition is satisfied.</returns>
 162        public static bool IsVideoAudioConditionSatisfied(
 163            ProfileCondition condition,
 164            int? audioChannels,
 165            int? audioBitrate,
 166            int? audioSampleRate,
 167            int? audioBitDepth,
 168            string? audioProfile,
 169            bool? isSecondaryTrack)
 170        {
 983171            switch (condition.Property)
 172            {
 173                case ProfileConditionValue.AudioProfile:
 0174                    return IsConditionSatisfied(condition, audioProfile);
 175                case ProfileConditionValue.AudioBitrate:
 0176                    return IsConditionSatisfied(condition, audioBitrate);
 177                case ProfileConditionValue.AudioChannels:
 195178                    return IsConditionSatisfied(condition, audioChannels);
 179                case ProfileConditionValue.IsSecondaryAudio:
 788180                    return IsConditionSatisfied(condition, isSecondaryTrack);
 181                case ProfileConditionValue.AudioSampleRate:
 0182                    return IsConditionSatisfied(condition, audioSampleRate);
 183                case ProfileConditionValue.AudioBitDepth:
 0184                    return IsConditionSatisfied(condition, audioBitDepth);
 185                default:
 0186                    throw new ArgumentException("Unexpected condition on audio file: " + condition.Property);
 187            }
 188        }
 189
 190        private static bool IsConditionSatisfied(ProfileCondition condition, int? currentValue)
 191        {
 347192            if (!currentValue.HasValue)
 193            {
 194                // If the value is unknown, it satisfies if not marked as required
 0195                return !condition.IsRequired;
 196            }
 197
 347198            var conditionType = condition.Condition;
 347199            if (condition.Condition == ProfileConditionType.EqualsAny)
 200            {
 0201                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 202                {
 0203                    if (int.TryParse(singleConditionString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int 
 0204                        && conditionValue.Equals(currentValue))
 205                    {
 0206                        return true;
 207                    }
 208                }
 209
 0210                return false;
 211            }
 212
 347213            if (int.TryParse(condition.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var expected))
 214            {
 215                switch (conditionType)
 216                {
 217                    case ProfileConditionType.Equals:
 1218                        return currentValue.Value.Equals(expected);
 219                    case ProfileConditionType.GreaterThanEqual:
 18220                        return currentValue.Value >= expected;
 221                    case ProfileConditionType.LessThanEqual:
 328222                        return currentValue.Value <= expected;
 223                    case ProfileConditionType.NotEquals:
 0224                        return !currentValue.Value.Equals(expected);
 225                    default:
 0226                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 227                }
 228            }
 229
 0230            return false;
 231        }
 232
 233        private static bool IsConditionSatisfied(ProfileCondition condition, string? currentValue)
 234        {
 279235            if (string.IsNullOrEmpty(currentValue))
 236            {
 237                // If the value is unknown, it satisfies if not marked as required
 0238                return !condition.IsRequired;
 239            }
 240
 279241            string expected = condition.Value;
 242
 279243            switch (condition.Condition)
 244            {
 245                case ProfileConditionType.EqualsAny:
 279246                    return expected.Split('|').Contains(currentValue, StringComparison.OrdinalIgnoreCase);
 247                case ProfileConditionType.Equals:
 0248                    return string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
 249                case ProfileConditionType.NotEquals:
 0250                    return !string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
 251                default:
 0252                    throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 253            }
 254        }
 255
 256        private static bool IsConditionSatisfied(ProfileCondition condition, bool? currentValue)
 257        {
 1194258            if (!currentValue.HasValue)
 259            {
 260                // If the value is unknown, it satisfies if not marked as required
 185261                return !condition.IsRequired;
 262            }
 263
 1009264            if (bool.TryParse(condition.Value, out var expected))
 265            {
 1009266                switch (condition.Condition)
 267                {
 268                    case ProfileConditionType.Equals:
 788269                        return currentValue.Value == expected;
 270                    case ProfileConditionType.NotEquals:
 221271                        return currentValue.Value != expected;
 272                    default:
 0273                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 274                }
 275            }
 276
 0277            return false;
 278        }
 279
 280        private static bool IsConditionSatisfied(ProfileCondition condition, double? currentValue)
 281        {
 271282            if (!currentValue.HasValue)
 283            {
 284                // If the value is unknown, it satisfies if not marked as required
 0285                return !condition.IsRequired;
 286            }
 287
 271288            var conditionType = condition.Condition;
 271289            if (condition.Condition == ProfileConditionType.EqualsAny)
 290            {
 0291                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 292                {
 0293                    if (double.TryParse(singleConditionString, NumberStyles.Float | NumberStyles.AllowThousands, Culture
 0294                        && conditionValue.Equals(currentValue))
 295                    {
 0296                        return true;
 297                    }
 298                }
 299
 0300                return false;
 301            }
 302
 271303            if (double.TryParse(condition.Value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.Invariant
 304            {
 305                switch (conditionType)
 306                {
 307                    case ProfileConditionType.Equals:
 0308                        return currentValue.Value.Equals(expected);
 309                    case ProfileConditionType.GreaterThanEqual:
 0310                        return currentValue.Value >= expected;
 311                    case ProfileConditionType.LessThanEqual:
 271312                        return currentValue.Value <= expected;
 313                    case ProfileConditionType.NotEquals:
 0314                        return !currentValue.Value.Equals(expected);
 315                    default:
 0316                        throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 317                }
 318            }
 319
 0320            return false;
 321        }
 322
 323        private static bool IsConditionSatisfied(ProfileCondition condition, TransportStreamTimestamp? timestamp)
 324        {
 0325            if (!timestamp.HasValue)
 326            {
 327                // If the value is unknown, it satisfies if not marked as required
 0328                return !condition.IsRequired;
 329            }
 330
 0331            var expected = Enum.Parse<TransportStreamTimestamp>(condition.Value, true);
 332
 0333            switch (condition.Condition)
 334            {
 335                case ProfileConditionType.Equals:
 0336                    return timestamp == expected;
 337                case ProfileConditionType.NotEquals:
 0338                    return timestamp != expected;
 339                default:
 0340                    throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition);
 341            }
 342        }
 343
 344        private static bool IsConditionSatisfied(ProfileCondition condition, VideoRangeType? currentValue)
 345        {
 240346            if (!currentValue.HasValue || currentValue.Equals(VideoRangeType.Unknown))
 347            {
 348                // If the value is unknown, it satisfies if not marked as required
 0349                return !condition.IsRequired;
 350            }
 351
 352            // Special case: HDR10 also satisfies if the video is HDR10Plus
 240353            if (currentValue.Value == VideoRangeType.HDR10Plus)
 354            {
 0355                if (IsConditionSatisfied(condition, VideoRangeType.HDR10))
 356                {
 0357                    return true;
 358                }
 359            }
 360
 240361            var conditionType = condition.Condition;
 240362            if (conditionType == ProfileConditionType.EqualsAny)
 363            {
 1108364                foreach (var singleConditionString in condition.Value.AsSpan().Split('|'))
 365                {
 420366                    if (Enum.TryParse(singleConditionString, true, out VideoRangeType conditionValue)
 420367                        && conditionValue.Equals(currentValue))
 368                    {
 212369                        return true;
 370                    }
 371                }
 372
 28373                return false;
 374            }
 375
 0376            if (Enum.TryParse(condition.Value, true, out VideoRangeType expected))
 377            {
 0378                return conditionType switch
 0379                {
 0380                    ProfileConditionType.Equals => currentValue.Value == expected,
 0381                    ProfileConditionType.NotEquals => currentValue.Value != expected,
 0382                    _ => throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition)
 0383                };
 384            }
 385
 0386            return false;
 387        }
 388    }
 389}

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>,System.Nullable`1<System.Int32>)
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>)