mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-13 08:37:07 +00:00
Add videoRotation profile condition
Signed-off-by: nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
parent
4dd19b990b
commit
5cb6ac521a
4 changed files with 48 additions and 5 deletions
|
|
@ -33,6 +33,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
/// <param name="numAudioStreams">The number of audio streams.</param>
|
/// <param name="numAudioStreams">The number of audio streams.</param>
|
||||||
/// <param name="videoCodecTag">The video codec tag.</param>
|
/// <param name="videoCodecTag">The video codec tag.</param>
|
||||||
/// <param name="isAvc">A value indicating whether the video is AVC.</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>
|
/// <returns><b>True</b> if the condition is satisfied.</returns>
|
||||||
public static bool IsVideoConditionSatisfied(
|
public static bool IsVideoConditionSatisfied(
|
||||||
ProfileCondition condition,
|
ProfileCondition condition,
|
||||||
|
|
@ -53,7 +54,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
int? numVideoStreams,
|
int? numVideoStreams,
|
||||||
int? numAudioStreams,
|
int? numAudioStreams,
|
||||||
string? videoCodecTag,
|
string? videoCodecTag,
|
||||||
bool? isAvc)
|
bool? isAvc,
|
||||||
|
int? videoRotation)
|
||||||
{
|
{
|
||||||
switch (condition.Property)
|
switch (condition.Property)
|
||||||
{
|
{
|
||||||
|
|
@ -93,6 +95,8 @@ namespace MediaBrowser.Model.Dlna
|
||||||
return IsConditionSatisfied(condition, numVideoStreams);
|
return IsConditionSatisfied(condition, numVideoStreams);
|
||||||
case ProfileConditionValue.VideoTimestamp:
|
case ProfileConditionValue.VideoTimestamp:
|
||||||
return IsConditionSatisfied(condition, timestamp);
|
return IsConditionSatisfied(condition, timestamp);
|
||||||
|
case ProfileConditionValue.VideoRotation:
|
||||||
|
return IsConditionSatisfied(condition, videoRotation);
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
AudioSampleRate = 22,
|
AudioSampleRate = 22,
|
||||||
AudioBitDepth = 23,
|
AudioBitDepth = 23,
|
||||||
VideoRangeType = 24,
|
VideoRangeType = 24,
|
||||||
NumStreams = 25
|
NumStreams = 25,
|
||||||
|
VideoRotation = 26
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
internal const TranscodeReason ContainerReasons = TranscodeReason.ContainerNotSupported | TranscodeReason.ContainerBitrateExceedsLimit;
|
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 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 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 VideoReasons = TranscodeReason.VideoCodecNotSupported | VideoCodecReasons;
|
||||||
internal const TranscodeReason DirectStreamReasons = AudioReasons | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoCodecTagNotSupported;
|
internal const TranscodeReason DirectStreamReasons = AudioReasons | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoCodecTagNotSupported;
|
||||||
|
|
||||||
|
|
@ -380,6 +380,9 @@ namespace MediaBrowser.Model.Dlna
|
||||||
case ProfileConditionValue.VideoRangeType:
|
case ProfileConditionValue.VideoRangeType:
|
||||||
return TranscodeReason.VideoRangeTypeNotSupported;
|
return TranscodeReason.VideoRangeTypeNotSupported;
|
||||||
|
|
||||||
|
case ProfileConditionValue.VideoRotation:
|
||||||
|
return TranscodeReason.VideoRotationNotSupported;
|
||||||
|
|
||||||
case ProfileConditionValue.VideoTimestamp:
|
case ProfileConditionValue.VideoTimestamp:
|
||||||
// TODO
|
// TODO
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -1040,6 +1043,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||||
string? videoCodecTag = videoStream?.CodecTag;
|
string? videoCodecTag = videoStream?.CodecTag;
|
||||||
bool? isAvc = videoStream?.IsAVC;
|
bool? isAvc = videoStream?.IsAVC;
|
||||||
|
int? videoRotation = videoStream?.Rotation;
|
||||||
|
|
||||||
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp;
|
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : item.Timestamp;
|
||||||
int? packetLength = videoStream?.PacketLength;
|
int? packetLength = videoStream?.PacketLength;
|
||||||
|
|
@ -1054,7 +1058,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
var appliedVideoConditions = options.Profile.CodecProfiles
|
var appliedVideoConditions = options.Profile.CodecProfiles
|
||||||
.Where(i => i.Type == CodecType.Video &&
|
.Where(i => i.Type == CodecType.Video &&
|
||||||
i.ContainsAnyCodec(playlistItem.VideoCodecs, container, useSubContainer) &&
|
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 codec profiles for backward compatibility - first codec profile has higher priority
|
||||||
.Reverse();
|
.Reverse();
|
||||||
foreach (var condition in appliedVideoConditions)
|
foreach (var condition in appliedVideoConditions)
|
||||||
|
|
@ -2059,6 +2063,38 @@ namespace MediaBrowser.Model.Dlna
|
||||||
break;
|
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:
|
case ProfileConditionValue.Height:
|
||||||
{
|
{
|
||||||
if (!enableNonQualifiedConditions)
|
if (!enableNonQualifiedConditions)
|
||||||
|
|
@ -2281,6 +2317,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
bool? isInterlaced = videoStream?.IsInterlaced;
|
bool? isInterlaced = videoStream?.IsInterlaced;
|
||||||
string? videoCodecTag = videoStream?.CodecTag;
|
string? videoCodecTag = videoStream?.CodecTag;
|
||||||
bool? isAvc = videoStream?.IsAVC;
|
bool? isAvc = videoStream?.IsAVC;
|
||||||
|
int? videoRotation = videoStream?.Rotation;
|
||||||
|
|
||||||
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
|
TransportStreamTimestamp? timestamp = videoStream is null ? TransportStreamTimestamp.None : mediaSource.Timestamp;
|
||||||
int? packetLength = videoStream?.PacketLength;
|
int? packetLength = videoStream?.PacketLength;
|
||||||
|
|
@ -2290,7 +2327,7 @@ namespace MediaBrowser.Model.Dlna
|
||||||
int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio);
|
int? numAudioStreams = mediaSource.GetStreamCount(MediaStreamType.Audio);
|
||||||
int? numVideoStreams = mediaSource.GetStreamCount(MediaStreamType.Video);
|
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>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ namespace MediaBrowser.Model.Session
|
||||||
VideoResolutionNotSupported = 1 << 8,
|
VideoResolutionNotSupported = 1 << 8,
|
||||||
VideoBitDepthNotSupported = 1 << 9,
|
VideoBitDepthNotSupported = 1 << 9,
|
||||||
VideoFramerateNotSupported = 1 << 10,
|
VideoFramerateNotSupported = 1 << 10,
|
||||||
|
VideoRotationNotSupported = 1 << 27,
|
||||||
RefFramesNotSupported = 1 << 11,
|
RefFramesNotSupported = 1 << 11,
|
||||||
AnamorphicVideoNotSupported = 1 << 12,
|
AnamorphicVideoNotSupported = 1 << 12,
|
||||||
InterlacedVideoNotSupported = 1 << 13,
|
InterlacedVideoNotSupported = 1 << 13,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue