mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-08 16:58:50 +01:00
Merge remote-tracking branch 'upstream/master' into search-rebased
This commit is contained in:
@@ -287,5 +287,5 @@ public class ServerConfiguration : BaseApplicationConfiguration
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether old authorization methods are allowed.
|
||||
/// </summary>
|
||||
public bool EnableLegacyAuthorization { get; set; }
|
||||
public bool EnableLegacyAuthorization { get; set; } = true;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace MediaBrowser.Model.Dlna
|
||||
AudioSampleRate = 22,
|
||||
AudioBitDepth = 23,
|
||||
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 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>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CA1815
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
|
||||
@@ -800,5 +800,7 @@ namespace MediaBrowser.Model.Dto
|
||||
/// </summary>
|
||||
/// <value>The current program.</value>
|
||||
public BaseItemDto CurrentProgram { get; set; }
|
||||
|
||||
public string OriginalLanguage { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,6 +260,8 @@ namespace MediaBrowser.Model.Entities
|
||||
|
||||
public string LocalizedLanguage { get; set; }
|
||||
|
||||
public string LocalizedOriginal { get; set; }
|
||||
|
||||
public string DisplayTitle
|
||||
{
|
||||
get
|
||||
@@ -267,161 +269,166 @@ namespace MediaBrowser.Model.Entities
|
||||
switch (Type)
|
||||
{
|
||||
case MediaStreamType.Audio:
|
||||
{
|
||||
var attributes = new List<string>();
|
||||
{
|
||||
var attributes = new List<string>();
|
||||
|
||||
// Do not display the language code in display titles if unset or set to a special code. Show it in all other cases (possibly expanded).
|
||||
if (!string.IsNullOrEmpty(Language) && !_specialCodes.Contains(Language, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Use pre-resolved localized language name, falling back to raw language code.
|
||||
attributes.Add(StringHelper.FirstToUpper(LocalizedLanguage ?? Language));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Profile) && !string.Equals(Profile, "lc", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
attributes.Add(Profile);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(Codec))
|
||||
{
|
||||
attributes.Add(AudioCodec.GetFriendlyName(Codec));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(ChannelLayout))
|
||||
{
|
||||
attributes.Add(StringHelper.FirstToUpper(ChannelLayout));
|
||||
}
|
||||
else if (Channels.HasValue)
|
||||
{
|
||||
attributes.Add(Channels.Value.ToString(CultureInfo.InvariantCulture) + " ch");
|
||||
}
|
||||
|
||||
if (IsDefault)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedDefault) ? "Default" : LocalizedDefault);
|
||||
}
|
||||
|
||||
if (IsExternal)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedExternal) ? "External" : LocalizedExternal);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
var result = new StringBuilder(Title);
|
||||
foreach (var tag in attributes)
|
||||
// Do not display the language code in display titles if unset or set to a special code. Show it in all other cases (possibly expanded).
|
||||
if (!string.IsNullOrEmpty(Language) && !_specialCodes.Contains(Language, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Keep Tags that are not already in Title.
|
||||
if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Append(" - ").Append(tag);
|
||||
}
|
||||
// Use pre-resolved localized language name, falling back to raw language code.
|
||||
attributes.Add(StringHelper.FirstToUpper(LocalizedLanguage ?? Language));
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Profile) && !string.Equals(Profile, "lc", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
attributes.Add(Profile);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(Codec))
|
||||
{
|
||||
attributes.Add(AudioCodec.GetFriendlyName(Codec));
|
||||
}
|
||||
|
||||
return string.Join(" - ", attributes);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(ChannelLayout))
|
||||
{
|
||||
attributes.Add(StringHelper.FirstToUpper(ChannelLayout));
|
||||
}
|
||||
else if (Channels.HasValue)
|
||||
{
|
||||
attributes.Add(Channels.Value.ToString(CultureInfo.InvariantCulture) + " ch");
|
||||
}
|
||||
|
||||
if (IsDefault)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedDefault) ? "Default" : LocalizedDefault);
|
||||
}
|
||||
|
||||
if (IsExternal)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedExternal) ? "External" : LocalizedExternal);
|
||||
}
|
||||
|
||||
if (IsOriginal)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedOriginal) ? "Original" : LocalizedOriginal);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
var result = new StringBuilder(Title);
|
||||
foreach (var tag in attributes)
|
||||
{
|
||||
// Keep Tags that are not already in Title.
|
||||
if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Append(" - ").Append(tag);
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
return string.Join(" - ", attributes);
|
||||
}
|
||||
|
||||
case MediaStreamType.Video:
|
||||
{
|
||||
var attributes = new List<string>();
|
||||
|
||||
var resolutionText = GetResolutionText();
|
||||
|
||||
if (!string.IsNullOrEmpty(resolutionText))
|
||||
{
|
||||
attributes.Add(resolutionText);
|
||||
}
|
||||
var attributes = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(Codec))
|
||||
{
|
||||
attributes.Add(Codec.ToUpperInvariant());
|
||||
}
|
||||
var resolutionText = GetResolutionText();
|
||||
|
||||
if (VideoDoViTitle is not null)
|
||||
{
|
||||
attributes.Add(VideoDoViTitle);
|
||||
}
|
||||
else if (VideoRange != VideoRange.Unknown)
|
||||
{
|
||||
attributes.Add(VideoRange.ToString());
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
var result = new StringBuilder(Title);
|
||||
foreach (var tag in attributes)
|
||||
if (!string.IsNullOrEmpty(resolutionText))
|
||||
{
|
||||
// Keep Tags that are not already in Title.
|
||||
if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Append(" - ").Append(tag);
|
||||
}
|
||||
attributes.Add(resolutionText);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
if (!string.IsNullOrEmpty(Codec))
|
||||
{
|
||||
attributes.Add(Codec.ToUpperInvariant());
|
||||
}
|
||||
|
||||
return string.Join(' ', attributes);
|
||||
}
|
||||
if (VideoDoViTitle is not null)
|
||||
{
|
||||
attributes.Add(VideoDoViTitle);
|
||||
}
|
||||
else if (VideoRange != VideoRange.Unknown)
|
||||
{
|
||||
attributes.Add(VideoRange.ToString());
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
var result = new StringBuilder(Title);
|
||||
foreach (var tag in attributes)
|
||||
{
|
||||
// Keep Tags that are not already in Title.
|
||||
if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Append(" - ").Append(tag);
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
return string.Join(' ', attributes);
|
||||
}
|
||||
|
||||
case MediaStreamType.Subtitle:
|
||||
{
|
||||
var attributes = new List<string>();
|
||||
{
|
||||
var attributes = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(Language))
|
||||
{
|
||||
// Use pre-resolved localized language name, falling back to raw language code.
|
||||
attributes.Add(StringHelper.FirstToUpper(LocalizedLanguage ?? Language));
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedUndefined) ? "Und" : LocalizedUndefined);
|
||||
}
|
||||
|
||||
if (IsHearingImpaired == true)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedHearingImpaired) ? "Hearing Impaired" : LocalizedHearingImpaired);
|
||||
}
|
||||
|
||||
if (IsDefault)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedDefault) ? "Default" : LocalizedDefault);
|
||||
}
|
||||
|
||||
if (IsForced)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedForced) ? "Forced" : LocalizedForced);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Codec))
|
||||
{
|
||||
attributes.Add(Codec.ToUpperInvariant());
|
||||
}
|
||||
|
||||
if (IsExternal)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedExternal) ? "External" : LocalizedExternal);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
var result = new StringBuilder(Title);
|
||||
foreach (var tag in attributes)
|
||||
if (!string.IsNullOrEmpty(Language))
|
||||
{
|
||||
// Keep Tags that are not already in Title.
|
||||
if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Append(" - ").Append(tag);
|
||||
}
|
||||
// Use pre-resolved localized language name, falling back to raw language code.
|
||||
attributes.Add(StringHelper.FirstToUpper(LocalizedLanguage ?? Language));
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedUndefined) ? "Und" : LocalizedUndefined);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
if (IsHearingImpaired == true)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedHearingImpaired) ? "Hearing Impaired" : LocalizedHearingImpaired);
|
||||
}
|
||||
|
||||
return string.Join(" - ", attributes);
|
||||
}
|
||||
if (IsDefault)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedDefault) ? "Default" : LocalizedDefault);
|
||||
}
|
||||
|
||||
if (IsForced)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedForced) ? "Forced" : LocalizedForced);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Codec))
|
||||
{
|
||||
attributes.Add(Codec.ToUpperInvariant());
|
||||
}
|
||||
|
||||
if (IsExternal)
|
||||
{
|
||||
attributes.Add(string.IsNullOrEmpty(LocalizedExternal) ? "External" : LocalizedExternal);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Title))
|
||||
{
|
||||
var result = new StringBuilder(Title);
|
||||
foreach (var tag in attributes)
|
||||
{
|
||||
// Keep Tags that are not already in Title.
|
||||
if (!Title.Contains(tag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Append(" - ").Append(tag);
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
return string.Join(" - ", attributes);
|
||||
}
|
||||
|
||||
default:
|
||||
return null;
|
||||
@@ -499,6 +506,12 @@ namespace MediaBrowser.Model.Entities
|
||||
/// <value><c>true</c> if this instance is for the hearing impaired; otherwise, <c>false</c>.</value>
|
||||
public bool IsHearingImpaired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is original.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if this instance is original; otherwise, <c>false</c>.</value>
|
||||
public bool IsOriginal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height.
|
||||
/// </summary>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Model</PackageId>
|
||||
<VersionPrefix>10.12.0</VersionPrefix>
|
||||
<VersionPrefix>12.0.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user