|
836 | 836 | "Type": "Video", |
837 | 837 | "Codec": "h264,avc", |
838 | 838 | "Conditions": [ |
839 | | - { |
840 | | - "Condition": "NotEquals", |
841 | | - "Property": "IsAnamorphic", |
842 | | - "Value": "true", |
843 | | - "IsRequired": false |
844 | | - }, |
845 | 839 | { |
846 | 840 | "Condition": "EqualsAny", |
847 | 841 | "Property": "VideoProfile", |
|
869 | 863 | "IsRequired": false |
870 | 864 | }) |
871 | 865 |
|
| 866 | + anamorphicCondition = getAnamorphicCondition() |
| 867 | + if anamorphicCondition.count() > 0 |
| 868 | + h264ProfileArray.Conditions.push(anamorphicCondition) |
| 869 | + end if |
| 870 | + |
872 | 871 | ' set max resolution |
873 | 872 | h264ProfileArray.Conditions.Append(resolutionConditions) |
874 | 873 |
|
|
912 | 911 | mpeg2ProfileArray.Conditions.push(bitRateArray) |
913 | 912 | end if |
914 | 913 |
|
| 914 | + anamorphicCondition = getAnamorphicCondition() |
| 915 | + if anamorphicCondition.count() > 0 |
| 916 | + mpeg2ProfileArray.Conditions.push(anamorphicCondition) |
| 917 | + end if |
| 918 | + |
915 | 919 | codecProfiles.push(mpeg2ProfileArray) |
916 | 920 | end if |
917 | 921 |
|
|
933 | 937 | ' set max resolution |
934 | 938 | mpeg4ProfileArray.Conditions.Append(resolutionConditions) |
935 | 939 |
|
| 940 | + anamorphicCondition = getAnamorphicCondition() |
| 941 | + if anamorphicCondition.count() > 0 |
| 942 | + mpeg4ProfileArray.Conditions.push(anamorphicCondition) |
| 943 | + end if |
| 944 | + |
936 | 945 | codecProfiles.push(mpeg4ProfileArray) |
937 | 946 | end if |
938 | 947 |
|
|
983 | 992 | av1ProfileArray.Conditions.push(bitRateArray) |
984 | 993 | end if |
985 | 994 |
|
| 995 | + anamorphicCondition = getAnamorphicCondition() |
| 996 | + if anamorphicCondition.count() > 0 |
| 997 | + av1ProfileArray.Conditions.push(anamorphicCondition) |
| 998 | + end if |
| 999 | + |
986 | 1000 | codecProfiles.push(av1ProfileArray) |
987 | 1001 | end if |
988 | 1002 |
|
|
1006 | 1020 | "Type": "Video", |
1007 | 1021 | "Codec": "h265,hevc", |
1008 | 1022 | "Conditions": [ |
1009 | | - { |
1010 | | - "Condition": "NotEquals", |
1011 | | - "Property": "IsAnamorphic", |
1012 | | - "Value": "true", |
1013 | | - "IsRequired": false |
1014 | | - }, |
1015 | 1023 | { |
1016 | 1024 | "Condition": "EqualsAny", |
1017 | 1025 | "Property": "VideoProfile", |
|
1047 | 1055 | hevcProfileArray.Conditions.push(bitRateArray) |
1048 | 1056 | end if |
1049 | 1057 |
|
| 1058 | + anamorphicCondition = getAnamorphicCondition() |
| 1059 | + if anamorphicCondition.count() > 0 |
| 1060 | + hevcProfileArray.Conditions.push(anamorphicCondition) |
| 1061 | + end if |
| 1062 | + |
1050 | 1063 | codecProfiles.push(hevcProfileArray) |
1051 | 1064 | end if |
1052 | 1065 |
|
|
1085 | 1098 | vp9ProfileArray.Conditions.push(bitRateArray) |
1086 | 1099 | end if |
1087 | 1100 |
|
| 1101 | + anamorphicCondition = getAnamorphicCondition() |
| 1102 | + if anamorphicCondition.count() > 0 |
| 1103 | + vp9ProfileArray.Conditions.push(anamorphicCondition) |
| 1104 | + end if |
| 1105 | + |
1088 | 1106 | codecProfiles.push(vp9ProfileArray) |
1089 | 1107 | end if |
1090 | 1108 |
|
|
1107 | 1125 | ' set max resolution |
1108 | 1126 | vp8ProfileArray.Conditions.Append(resolutionConditions) |
1109 | 1127 |
|
| 1128 | + anamorphicCondition = getAnamorphicCondition() |
| 1129 | + if anamorphicCondition.count() > 0 |
| 1130 | + vp8ProfileArray.Conditions.push(anamorphicCondition) |
| 1131 | + end if |
| 1132 | + |
1110 | 1133 | codecProfiles.push(vp8ProfileArray) |
1111 | 1134 | end if |
1112 | 1135 |
|
|
1237 | 1260 | return {} |
1238 | 1261 | end function |
1239 | 1262 |
|
| 1263 | +' Returns an IsAnamorphic codec profile condition when the user has enabled |
| 1264 | +' forced transcoding of anamorphic video. Returns empty object when disabled. |
| 1265 | +' @return {object} - Condition AA or empty AA |
| 1266 | +function getAnamorphicCondition() as object |
| 1267 | + if m.global.user.settings.playbackForceTranscodeAnamorphic |
| 1268 | + return { |
| 1269 | + "Condition": "NotEquals", |
| 1270 | + "Property": "IsAnamorphic", |
| 1271 | + "Value": "true", |
| 1272 | + "IsRequired": false |
| 1273 | + } |
| 1274 | + end if |
| 1275 | + return {} |
| 1276 | +end function |
| 1277 | + |
| 1278 | +' Checks whether a video stream's resolution is within the h264 hardware |
| 1279 | +' decoding ceiling (1080p / 1920x1080). Returns true for non-h264 codecs |
| 1280 | +' since they have higher ceilings handled elsewhere. |
| 1281 | +' Handles Height/Width fields arriving as strings or integers, and defaults |
| 1282 | +' to 0 (within ceiling) when metadata is missing. |
| 1283 | +' @param videoStream {object} - MediaStream object with codec, Height, Width |
| 1284 | +' @return {boolean} - true if within ceiling or not h264, false if exceeds ceiling |
| 1285 | +function isWithinH264HardwareCeiling(videoStream as object) as boolean |
| 1286 | + if not isValid(videoStream) or not isValid(videoStream.codec) then return false |
| 1287 | + if videoStream.codec <> "h264" then return true |
| 1288 | + |
| 1289 | + sourceHeight = 0 |
| 1290 | + sourceWidth = 0 |
| 1291 | + |
| 1292 | + if isValid(videoStream.Height) |
| 1293 | + sourceHeight = videoStream.Height |
| 1294 | + if type(sourceHeight) = "roString" or type(sourceHeight) = "String" |
| 1295 | + sourceHeight = sourceHeight.toInt() |
| 1296 | + end if |
| 1297 | + end if |
| 1298 | + |
| 1299 | + if isValid(videoStream.Width) |
| 1300 | + sourceWidth = videoStream.Width |
| 1301 | + if type(sourceWidth) = "roString" or type(sourceWidth) = "String" |
| 1302 | + sourceWidth = sourceWidth.toInt() |
| 1303 | + end if |
| 1304 | + end if |
| 1305 | + |
| 1306 | + return sourceHeight <= 1080 and sourceWidth <= 1920 |
| 1307 | +end function |
| 1308 | + |
1240 | 1309 | function getResolutionConditions(isRequired = false as boolean) as object |
1241 | 1310 | userMaxHeight = m.global.user.settings.playbackResolutionMax |
1242 | 1311 | if userMaxHeight = invalid or userMaxHeight = "" then userMaxHeight = "auto" |
|
0 commit comments