diff options
| author | nyanmisaka <nst799610810@gmail.com> | 2026-05-08 15:36:01 +0800 |
|---|---|---|
| committer | nyanmisaka <nst799610810@gmail.com> | 2026-05-09 15:20:29 +0800 |
| commit | 5cb6ac521a213ab13cef5e28ffa07e43dd073913 (patch) | |
| tree | 41f3770e94858d7a9828e482dd033c909ec81cc2 /MediaBrowser.Model | |
| parent | 4dd19b990ba953d9b16d1cbd0a575ceed7374445 (diff) | |
Add videoRotation profile condition
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
Diffstat (limited to 'MediaBrowser.Model')
| -rw-r--r-- | MediaBrowser.Model/Dlna/ConditionProcessor.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/ProfileConditionValue.cs | 3 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamBuilder.cs | 43 | ||||
| -rw-r--r-- | MediaBrowser.Model/Session/TranscodeReason.cs | 1 |
4 files changed, 48 insertions, 5 deletions
diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs index 79ee683a2d..a6018f369d 100644 --- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs +++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs @@ -33,6 +33,7 @@ namespace MediaBrowser.Model.Dlna /// <param name="numAudioStreams">The number of audio streams.</param> /// <param name="videoCodecTag">The video codec tag.</param> /// <param name="isAvc">A value indicating whether the video is AVC.</param> + /// <param name="videoRotation">The video rotation angle, usually 0 or +-90/180.</param> /// <returns><b>True</b> if the condition is satisfied.</returns> public static bool IsVideoConditionSatisfied( ProfileCondition condition, @@ -53,7 +54,8 @@ namespace MediaBrowser.Model.Dlna int? numVideoStreams, int? numAudioStreams, string? videoCodecTag, - bool? isAvc) + bool? isAvc, + int? videoRotation) { switch (condition.Property) { @@ -93,6 +95,8 @@ namespace MediaBrowser.Model.Dlna return IsConditionSatisfied(condition, numVideoStreams); case ProfileConditionValue.VideoTimestamp: return IsConditionSatisfied(condition, timestamp); + case ProfileConditionValue.VideoRotation: + return IsConditionSatisfied(condition, videoRotation); default: return true; } diff --git a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs index b66a15840b..c6171c7ab2 100644 --- a/MediaBrowser.Model/Dlna/ProfileConditionValue.cs +++ b/MediaBrowser.Model/Dlna/ProfileConditionValue.cs @@ -28,6 +28,7 @@ namespace MediaBrowser.Model.Dlna AudioSampleRate = 22, AudioBitDepth = 23, VideoRangeType = 24, - NumStreams = 25 + NumStreams = 25, + VideoRotation = 26 } } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index c9697c685c..44697837ca 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -22,7 +22,7 @@ namespace MediaBrowser.Model.Dlna internal const TranscodeReason ContainerReasons = TranscodeReason.ContainerNotSupported | TranscodeReason.ContainerBitrateExceedsLimit; internal const TranscodeReason AudioCodecReasons = TranscodeReason.AudioBitrateNotSupported | TranscodeReason.AudioChannelsNotSupported | TranscodeReason.AudioProfileNotSupported | TranscodeReason.AudioSampleRateNotSupported | TranscodeReason.SecondaryAudioNotSupported | TranscodeReason.AudioBitDepthNotSupported | TranscodeReason.AudioIsExternal; internal const TranscodeReason AudioReasons = TranscodeReason.AudioCodecNotSupported | AudioCodecReasons; - internal const TranscodeReason VideoCodecReasons = TranscodeReason.VideoResolutionNotSupported | TranscodeReason.AnamorphicVideoNotSupported | TranscodeReason.InterlacedVideoNotSupported | TranscodeReason.VideoBitDepthNotSupported | TranscodeReason.VideoBitrateNotSupported | TranscodeReason.VideoFramerateNotSupported | TranscodeReason.VideoLevelNotSupported | TranscodeReason.RefFramesNotSupported | TranscodeReason.VideoRangeTypeNotSupported | TranscodeReason.VideoProfileNotSupported; + internal const TranscodeReason VideoCodecReasons = TranscodeReason.VideoResolutionNotSupported | TranscodeReason.AnamorphicVideoNotSupported | TranscodeReason.InterlacedVideoNotSupported | TranscodeReason.VideoBitDepthNotSupported | TranscodeReason.VideoBitrateNotSupported | TranscodeReason.VideoFramerateNotSupported | TranscodeReason.VideoLevelNotSupported | TranscodeReason.RefFramesNotSupported | TranscodeReason.VideoRangeTypeNotSupported | TranscodeReason.VideoProfileNotSupported | TranscodeReason.VideoRotationNotSupported; internal const TranscodeReason VideoReasons = TranscodeReason.VideoCodecNotSupported | VideoCodecReasons; internal const TranscodeReason DirectStreamReasons = AudioReasons | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoCodecTagNotSupported; @@ -380,6 +380,9 @@ namespace MediaBrowser.Model.Dlna case ProfileConditionValue.VideoRangeType: return TranscodeReason.VideoRangeTypeNotSupported; + case ProfileConditionValue.VideoRotation: + return TranscodeReason.VideoRotationNotSupported; + case ProfileConditionValue.VideoTimestamp: // TODO return 0; @@ -1040,6 +1043,7 @@ namespace MediaBrowser.Model.Dlna bool? isInterlaced = videoStream?.IsInterlaced; string? videoCodecTag = videoStream?.CodecTag; bool? isAvc = videoStream?.IsAVC; + int? videoRotation = videoStream?.Rotation; TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp; int? packetLength = videoStream?.PacketLength; @@ -1054,7 +1058,7 @@ namespace MediaBrowser.Model.Dlna var appliedVideoConditions = options.Profile.CodecProfiles .Where(i => i.Type == CodecType.Video && i.ContainsAnyCodec(playlistItem.VideoCodecs, container, useSubContainer) && - i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numStreams, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))) + i.ApplyConditions.All(applyCondition => ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numStreams, numVideoStreams, numAudioStreams, videoCodecTag, isAvc, videoRotation))) // Reverse codec profiles for backward compatibility - first codec profile has higher priority .Reverse(); foreach (var condition in appliedVideoConditions) @@ -2059,6 +2063,38 @@ namespace MediaBrowser.Model.Dlna break; } + case ProfileConditionValue.VideoRotation: + { + if (string.IsNullOrEmpty(qualifier)) + { + continue; + } + + // change from split by | to comma + // strip spaces to avoid having to encode + var values = value + .Split('|', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + if (condition.Condition == ProfileConditionType.Equals) + { + item.SetOption(qualifier, "rotation", string.Join(',', values)); + } + else if (condition.Condition == ProfileConditionType.EqualsAny) + { + var currentValue = item.GetOption(qualifier, "rotation"); + if (!string.IsNullOrEmpty(currentValue) && values.Any(v => string.Equals(v, currentValue, StringComparison.OrdinalIgnoreCase))) + { + item.SetOption(qualifier, "rotation", currentValue); + } + else + { + item.SetOption(qualifier, "rotation", string.Join(',', values)); + } + } + + break; + } + case ProfileConditionValue.Height: { if (!enableNonQualifiedConditions) @@ -2281,6 +2317,7 @@ namespace MediaBrowser.Model.Dlna bool? isInterlaced = videoStream?.IsInterlaced; string? videoCodecTag = videoStream?.CodecTag; bool? isAvc = videoStream?.IsAVC; + int? videoRotation = videoStream?.Rotation; TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : mediaSource.Timestamp; int? packetLength = videoStream?.PacketLength; @@ -2290,7 +2327,7 @@ namespace MediaBrowser.Model.Dlna int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio); int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video); - return conditions.Where(applyCondition => !ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numStreams, numVideoStreams, numAudioStreams, videoCodecTag, isAvc)); + return conditions.Where(applyCondition => !ConditionProcessor.IsVideoConditionSatisfied(applyCondition, width, height, bitDepth, videoBitrate, videoProfile, videoRangeType, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numStreams, numVideoStreams, numAudioStreams, videoCodecTag, isAvc, videoRotation)); } /// <summary> diff --git a/MediaBrowser.Model/Session/TranscodeReason.cs b/MediaBrowser.Model/Session/TranscodeReason.cs index 902bab9a6e..4ea60f115a 100644 --- a/MediaBrowser.Model/Session/TranscodeReason.cs +++ b/MediaBrowser.Model/Session/TranscodeReason.cs @@ -24,6 +24,7 @@ namespace MediaBrowser.Model.Session VideoResolutionNotSupported = 1 << 8, VideoBitDepthNotSupported = 1 << 9, VideoFramerateNotSupported = 1 << 10, + VideoRotationNotSupported = 1 << 27, RefFramesNotSupported = 1 << 11, AnamorphicVideoNotSupported = 1 << 12, InterlacedVideoNotSupported = 1 << 13, |
