update prefered codecs and maxAudioChannel logic

This commit is contained in:
Charles Ewert 2023-06-06 00:24:54 -04:00
parent adc769c625
commit 9c6201b25e

View File

@ -52,47 +52,63 @@ function getDeviceProfile() as object
playAv1 = m.global.session.user.settings["playback.av1"] playAv1 = m.global.session.user.settings["playback.av1"]
di = CreateObject("roDeviceInfo") di = CreateObject("roDeviceInfo")
transContainers = ["mp4", "hls", "mkv", "ism", "dash", "ts"] ' TRANSCODING
supportedVideoCodecs = {} ' use strings to preserve order
supportedAudioCodecs = {} mp4AudioCodecs = "aac"
addH264Profile = false mp4VideoCodecs = "h264"
addHevcProfile = false tsAudioCodecs = "aac"
addMpeg2Profile = false tsVideoCodecs = "h264"
addAv1Profile = false ' profileSupport["mp4"]["hevc"]["profile name"]["profile level"]
addVp9Profile = false profileSupport = {
mp4: {},
ts: {}
}
maxAudioChannels = "2"
di = CreateObject("roDeviceInfo") ' does the users setup support surround sound?
maxAudioChannels = "2" ' jellyfin expects this as a string
' in order of preference from left to right
' aac will be highest priority unless surroundSoundCodec <> "aac"
audioCodecs = ["mp3", "vorbis", "opus", "flac", "alac", "ac4", "pcm", "wma", "wmapro"]
surroundSoundCodecs = ["aac", "eac3", "ac3", "vorbis", "dts"]
surroundSoundCodec = invalid
if di.GetAudioOutputChannel() = "5.1 surround" if di.GetAudioOutputChannel() = "5.1 surround"
maxAudioChannels = "6" maxAudioChannels = "6"
eightChannelCodecs = ["ac3", "eac3", "dts"] for each codec in surroundSoundCodecs
for each eightChannelCodec in eightChannelCodecs if di.CanDecodeAudio({ Codec: codec, ChCnt: 6 }).Result
if di.CanDecodeAudio({ Codec: eightChannelCodec, ChCnt: 8 }).Result surroundSoundCodec = codec
if di.CanDecodeAudio({ Codec: codec, ChCnt: 8 }).Result
maxAudioChannels = "8" maxAudioChannels = "8"
end if
exit for exit for
end if end if
end for end for
end if end if
' AVC / h264 ' VIDEO CODECS
'
' AVC / h264 / MPEG4 AVC
h264Profiles = ["main", "high"] h264Profiles = ["main", "high"]
h264Levels = ["4.1", "4.2"] h264Levels = ["4.1", "4.2"]
for each container in profileSupport
for each container in transContainers
for each profile in h264Profiles for each profile in h264Profiles
for each level in h264Levels for each level in h264Levels
if di.CanDecodeVideo({ Codec: "h264", Container: container, Profile: profile, Level: level }).Result if di.CanDecodeVideo({ Codec: "h264", Container: container, Profile: profile, Level: level }).Result
addH264Profile = true profileSupport[container] = updateProfileArray(profileSupport[container], "h264", profile, level)
if supportedVideoCodecs[container] = invalid
supportedVideoCodecs[container] = {}
end if end if
if supportedVideoCodecs[container]["h264"] = invalid if di.CanDecodeVideo({ Codec: "mpeg4 avc", Container: container, Profile: profile, Level: level }).Result
supportedVideoCodecs[container]["h264"] = {} profileSupport[container] = updateProfileArray(profileSupport[container], "mpeg4 avc", profile, level)
if container = "mp4"
' check for codec string before adding it
if mp4VideoCodecs.Instr(0, ",mpeg4 avc") = -1
mp4VideoCodecs = mp4VideoCodecs + ",mpeg4 avc"
end if
else if container = "ts"
' check for codec string before adding it
if tsVideoCodecs.Instr(0, ",mpeg4 avc") = -1
tsVideoCodecs = tsVideoCodecs + ",mpeg4 avc"
end if end if
if supportedVideoCodecs[container]["h264"][profile] = invalid
supportedVideoCodecs[container]["h264"][profile] = []
end if end if
supportedVideoCodecs[container]["h264"][profile].push(level)
end if end if
end for end for
end for end for
@ -101,53 +117,80 @@ function getDeviceProfile() as object
' HEVC / h265 ' HEVC / h265
hevcProfiles = ["main", "main 10"] hevcProfiles = ["main", "main 10"]
hevcLevels = ["4.1", "5.0", "5.1"] hevcLevels = ["4.1", "5.0", "5.1"]
addHevc = false
for each container in transContainers for each container in profileSupport
for each profile in hevcProfiles for each profile in hevcProfiles
for each level in hevcLevels for each level in hevcLevels
if di.CanDecodeVideo({ Codec: "hevc", Container: container, Profile: profile, Level: level }).Result if di.CanDecodeVideo({ Codec: "hevc", Container: container, Profile: profile, Level: level }).Result
addHevcProfile = true addHevc = true
' hevc codec string profileSupport[container] = updateProfileArray(profileSupport[container], "hevc", profile, level)
if supportedVideoCodecs[container] = invalid profileSupport[container] = updateProfileArray(profileSupport[container], "h265", profile, level)
supportedVideoCodecs[container] = {} if container = "mp4"
' check for codec string before adding it
if mp4VideoCodecs.Instr(0, "h265,") = -1
mp4VideoCodecs = "h265," + mp4VideoCodecs
end if end if
if supportedVideoCodecs[container]["hevc"] = invalid if mp4VideoCodecs.Instr(0, "hevc,") = -1
supportedVideoCodecs[container]["hevc"] = {} mp4VideoCodecs = "hevc," + mp4VideoCodecs
end if end if
if supportedVideoCodecs[container]["hevc"][profile] = invalid else if container = "ts"
supportedVideoCodecs[container]["hevc"][profile] = [] ' check for codec string before adding it
if tsVideoCodecs.Instr(0, "h265,") = -1
tsVideoCodecs = "h265," + tsVideoCodecs
end if end if
supportedVideoCodecs[container]["hevc"][profile].push(level) if tsVideoCodecs.Instr(0, "hevc,") = -1
' h265 codec string tsVideoCodecs = "hevc," + tsVideoCodecs
if supportedVideoCodecs[container] = invalid
supportedVideoCodecs[container] = {}
end if end if
if supportedVideoCodecs[container]["h265"] = invalid
supportedVideoCodecs[container]["h265"] = {}
end if end if
if supportedVideoCodecs[container]["h265"][profile] = invalid
supportedVideoCodecs[container]["h265"][profile] = []
end if
supportedVideoCodecs[container]["h265"][profile].push(level)
end if end if
end for end for
end for end for
end for end for
' VP9
vp9Profiles = ["profile 0", "profile 2"]
addVp9 = false
for each container in profileSupport
for each profile in vp9Profiles
if di.CanDecodeAudio({ Codec: "vp9", Container: container, Profile: profile }).Result
addVp9 = true
profileSupport[container] = updateProfileArray(profileSupport[container], "vp9", profile)
if container = "mp4"
' check for codec string before adding it
if mp4VideoCodecs.Instr(0, ",vp9") = -1
mp4VideoCodecs = mp4VideoCodecs + ",vp9"
end if
else if container = "ts"
' check for codec string before adding it
if tsVideoCodecs.Instr(0, ",vp9") = -1
tsVideoCodecs = tsVideoCodecs + ",vp9"
end if
end if
end if
end for
end for
' MPEG2 ' MPEG2
mpeg2Levels = ["main", "high"] mpeg2Profiles = ["main", "high"]
addMpeg2 = false
if playMpeg2 if playMpeg2
for each container in transContainers for each container in profileSupport
for each level in mpeg2Levels for each profile in mpeg2Profiles
if di.CanDecodeVideo({ Codec: "mpeg2", Container: container, Level: level }).Result if di.CanDecodeVideo({ Codec: "mpeg2", Container: container, Profile: profile }).Result
addMpeg2Profile = true addMpeg2 = true
if supportedVideoCodecs[container] = invalid profileSupport[container] = updateProfileArray(profileSupport[container], "mpeg2", profile)
supportedVideoCodecs[container] = {} if container = "mp4"
' check for codec string before adding it
if mp4VideoCodecs.Instr(0, ",mpeg2video") = -1
mp4VideoCodecs = mp4VideoCodecs + ",mpeg2video"
end if
else if container = "ts"
' check for codec string before adding it
if tsVideoCodecs.Instr(0, ",mpeg2video") = -1
tsVideoCodecs = tsVideoCodecs + ",mpeg2video"
end if end if
if supportedVideoCodecs[container]["mpeg2video"] = invalid
supportedVideoCodecs[container]["mpeg2video"] = []
end if end if
supportedVideoCodecs[container]["mpeg2video"].push(level)
end if end if
end for end for
end for end for
@ -156,153 +199,72 @@ function getDeviceProfile() as object
' AV1 ' AV1
av1Profiles = ["main", "main 10"] av1Profiles = ["main", "main 10"]
av1Levels = ["4.1", "5.0", "5.1"] av1Levels = ["4.1", "5.0", "5.1"]
addAv1 = false
if playAv1 if playAv1
for each container in transContainers for each container in profileSupport
for each profile in av1Profiles for each profile in av1Profiles
for each level in av1Levels for each level in av1Levels
if di.CanDecodeVideo({ Codec: "av1", Container: container, Profile: profile, Level: level }).Result if di.CanDecodeVideo({ Codec: "av1", Container: container, Profile: profile, Level: level }).Result
addAv1Profile = true addAv1 = true
' av1 codec string profileSupport[container] = updateProfileArray(profileSupport[container], "av1", profile, level)
if supportedVideoCodecs[container] = invalid if container = "mp4"
supportedVideoCodecs[container] = {} ' check for codec string before adding it
if mp4VideoCodecs.Instr(0, ",av1") = -1
mp4VideoCodecs = mp4VideoCodecs + ",av1"
end if end if
if supportedVideoCodecs[container]["av1"] = invalid else if container = "ts"
supportedVideoCodecs[container]["av1"] = {} ' check for codec string before adding it
if tsVideoCodecs.Instr(0, ",av1") = -1
tsVideoCodecs = tsVideoCodecs + ",av1"
end if end if
if supportedVideoCodecs[container]["av1"][profile] = invalid
supportedVideoCodecs[container]["av1"][profile] = []
end if end if
supportedVideoCodecs[container]["av1"][profile].push(level)
end if end if
end for end for
end for end for
end for end for
end if end if
' VP9 ' AUDIO CODECS
vp9Profiles = ["profile 0", "profile 2"] for each container in profileSupport
for each codec in audioCodecs
for each container in transContainers if di.CanDecodeAudio({ Codec: codec, Container: container }).result
for each profile in vp9Profiles if container = "mp4"
if di.CanDecodeVideo({ Codec: "vp9", Container: container, Profile: profile }).Result ' check for codec string before adding it
addVp9Profile = true if mp4VideoCodecs.Instr(0, "," + codec) = -1
' vp9 codec string mp4AudioCodecs = mp4AudioCodecs + "," + codec
if supportedVideoCodecs[container] = invalid end if
supportedVideoCodecs[container] = {} else if container = "ts"
' check for codec string before adding it
if tsAudioCodecs.Instr(0, "," + codec) = -1
tsAudioCodecs = tsAudioCodecs + "," + codec
end if end if
if supportedVideoCodecs[container]["vp9"] = invalid
supportedVideoCodecs[container]["vp9"] = []
end if end if
supportedVideoCodecs[container]["vp9"].push(profile)
end if end if
end for end for
end for end for
' eac3 ' HDR SUPPORT
for each container in transContainers h264VideoRangeTypes = "SDR"
if di.CanDecodeAudio({ Codec: "eac3", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("eac3")
end if
end for
' ac3
for each container in transContainers
if di.CanDecodeAudio({ Codec: "ac3", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("ac3")
end if
end for
' dts
for each container in transContainers
if di.CanDecodeAudio({ Codec: "dts", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("dts")
end if
end for
' opus
for each container in transContainers
if di.CanDecodeAudio({ Codec: "opus", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("opus")
end if
end for
' flac
for each container in transContainers
if di.CanDecodeAudio({ Codec: "flac", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("flac")
end if
end for
' vorbis
for each container in transContainers
if di.CanDecodeAudio({ Codec: "vorbis", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("vorbis")
end if
end for
' aac
for each container in transContainers
if di.CanDecodeAudio({ Codec: "aac", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("aac")
end if
end for
' mp3
for each container in transContainers
if di.CanDecodeAudio({ Codec: "mp3", Container: container }).result
if supportedAudioCodecs[container] = invalid
supportedAudioCodecs[container] = []
end if
supportedAudioCodecs[container].push("mp3")
end if
end for
hevcVideoRangeTypes = "SDR" hevcVideoRangeTypes = "SDR"
vp9VideoRangeTypes = "SDR" vp9VideoRangeTypes = "SDR"
av1VideoRangeTypes = "SDR" av1VideoRangeTypes = "SDR"
dp = di.GetDisplayProperties() dp = di.GetDisplayProperties()
if dp.Hdr10 ' or dp.Hdr10Plus? if dp.Hdr10
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10" hevcVideoRangeTypes = hevcVideoRangeTypes + "|HDR10"
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10" vp9VideoRangeTypes = vp9VideoRangeTypes + "|HDR10"
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10" av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10"
end if end if
if dp.Hdr10Plus
av1VideoRangeTypes = av1VideoRangeTypes + "|HDR10+"
end if
if dp.HLG if dp.HLG
hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG" hevcVideoRangeTypes = hevcVideoRangeTypes + "|HLG"
vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG" vp9VideoRangeTypes = vp9VideoRangeTypes + "|HLG"
av1VideoRangeTypes = av1VideoRangeTypes + "|HLG" av1VideoRangeTypes = av1VideoRangeTypes + "|HLG"
end if end if
if dp.DolbyVision if dp.DolbyVision
h264VideoRangeTypes = hevcVideoRangeTypes + "|DOVI"
hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI" hevcVideoRangeTypes = hevcVideoRangeTypes + "|DOVI"
'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI 'vp9VideoRangeTypes = vp9VideoRangeTypes + ",DOVI" no evidence that vp9 can hold DOVI
av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI" av1VideoRangeTypes = av1VideoRangeTypes + "|DOVI"
@ -318,18 +280,18 @@ function getDeviceProfile() as object
"TranscodingProfiles": [], "TranscodingProfiles": [],
"ContainerProfiles": [], "ContainerProfiles": [],
"CodecProfiles": [ "CodecProfiles": [
{ ' {
"Type": "VideoAudio", ' "Type": "VideoAudio",
"Codec": DirectPlayProfile[1].AudioCodec, ' Use supported MKV Audio list ' "Codec": DirectPlayProfile[1].AudioCodec, ' Use supported MKV Audio list
"Conditions": [ ' "Conditions": [
{ ' {
"Condition": "LessThanEqual", ' "Condition": "LessThanEqual",
"Property": "AudioChannels", ' "Property": "AudioChannels",
"Value": maxAudioChannels, ' "Value": maxAudioChannels,
"IsRequired": false ' "IsRequired": false
} ' }
] ' ]
} ' }
], ],
"SubtitleProfiles": [ "SubtitleProfiles": [
{ {
@ -352,92 +314,127 @@ function getDeviceProfile() as object
} }
' build TranscodingProfiles ' build TranscodingProfiles
' create an audio profile for each audio codec supported by the mp4 container '
for each supportedMp4AudioCodec in supportedAudioCodecs["mp4"] for each audioCodec in mp4AudioCodecs.split(",")
' streaming streamingArray = {
deviceProfile.TranscodingProfiles.push({ "Container": audioCodec,
"Container": supportedMp4AudioCodec,
"Type": "Audio", "Type": "Audio",
"AudioCodec": supportedMp4AudioCodec, "AudioCodec": audioCodec,
"Context": "Streaming", "Context": "Streaming",
"Protocol": "http", "Protocol": "http",
"MaxAudioChannels": maxAudioChannels "MaxAudioChannels": maxAudioChannels
}) }
' static staticArray = {
deviceProfile.TranscodingProfiles.push({ "Container": audioCodec,
"Container": supportedMp4AudioCodec,
"Type": "Audio", "Type": "Audio",
"AudioCodec": supportedMp4AudioCodec, "AudioCodec": audioCodec,
"Context": "Static", "Context": "Static",
"Protocol": "http", "Protocol": "http",
"MaxAudioChannels": maxAudioChannels "MaxAudioChannels": maxAudioChannels
})
end for
' create a video profile for each container in transContainers
for each container in transContainers
audioCodecs = []
videoCodecs = []
for each codec in supportedAudioCodecs[container]
audioCodecs.push(codec)
end for
for each codec in supportedVideoCodecs[container]
videoCodecs.push(codec)
end for
containerArray = {
"Container": container,
"Context": "Static",
"Type": "Video",
"AudioCodec": audioCodecs.join(","),
"VideoCodec": videoCodecs.join(","),
"MaxAudioChannels": maxAudioChannels
} }
if container = "ts" ' use ts container for aac
containerArray["Context"] = "Streaming" if audioCodec = "aac"
containerArray["Protocol"] = "hls" if di.CanDecodeAudio({ Codec: audioCodec, Container: "ts", ChCnt: maxAudioChannels.trim().ToInt() }).result
containerArray["MinSegments"] = "1" streamingArray["Container"] = "ts"
containerArray["BreakOnNonKeyFrames"] = true staticArray["Container"] = "ts"
else if container = "mp4"
containerArray["Context"] = "Static" deviceProfile.TranscodingProfiles.push(streamingArray)
containerArray["Protocol"] = "http" deviceProfile.TranscodingProfiles.push(staticArray)
end if
else
' use audioCodec as container for everything else
if di.CanDecodeAudio({ Codec: audioCodec, Container: audioCodec, ChCnt: maxAudioChannels.trim().ToInt() }).result
deviceProfile.TranscodingProfiles.push(streamingArray)
deviceProfile.TranscodingProfiles.push(staticArray)
end if
end if end if
deviceProfile.TranscodingProfiles.push(containerArray)
end for end for
' build CodecProfiles
if addH264Profile tsArray = {
' determine highest level supported "Container": "ts",
h264HighestLevel = 4.2 "Context": "Streaming",
h264HighestLevelSupported = 0.0 "Protocol": "hls",
for each container in transContainers "Type": "Video",
for each profile in hevcProfiles "AudioCodec": tsAudioCodecs,
for each level in supportedVideoCodecs[container]["h264"][profile] "VideoCodec": tsVideoCodecs,
"MaxAudioChannels": maxAudioChannels,
"MinSegments": 1,
"BreakOnNonKeyFrames": false
}
mp4Array = {
"Container": "mp4",
"Context": "Streaming",
"Protocol": "hls",
"Type": "Video",
"AudioCodec": mp4AudioCodecs,
"VideoCodec": mp4VideoCodecs,
"MaxAudioChannels": maxAudioChannels,
"MinSegments": 1,
"BreakOnNonKeyFrames": false
}
' surround sound
' move preferred surround sound codec to front of string
if maxAudioChannels.ToInt() > 2
' search codec strings for our preferred codec
tsCodecStringPosition = tsArray.AudioCodec.Instr(0, "," + surroundSoundCodec)
mp4CodecStringPosition = mp4Array.AudioCodec.Instr(0, "," + surroundSoundCodec)
if tsCodecStringPosition <> -1
' ts supports our prefered codec
' remove codec from string
tsArray.AudioCodec.Replace("," + surroundSoundCodec, "")
' put codec in front of string
tsArray.AudioCodec = surroundSoundCodec + "," + tsArray.AudioCodec
end if
if mp4CodecStringPosition <> -1
' mp4 supports our prefered codec
' remove codec from string
mp4Array.AudioCodec.Replace("," + surroundSoundCodec, "")
' put codec in front of string
mp4Array.AudioCodec = surroundSoundCodec + "," + mp4Array.AudioCodec
end if
end if
deviceProfile.TranscodingProfiles.push(tsArray)
deviceProfile.TranscodingProfiles.push(mp4Array)
' Build CodecProfiles
'
' H264
h264Mp4LevelSupported = 0.0
h264TsLevelSupported = 0.0
h264AssProfiles = {}
h264LevelString = invalid
for each container in profileSupport
for each profile in profileSupport[container]["h264"]
h264AssProfiles.AddReplace(profile, true)
for each level in profileSupport[container]["h264"][profile]
levelFloat = level.ToFloat() levelFloat = level.ToFloat()
if levelFloat > h264HighestLevelSupported if container = "mp4"
h264HighestLevelSupported = levelFloat if levelFloat > h264Mp4LevelSupported
h264Mp4LevelSupported = levelFloat
end if end if
if h264HighestLevelSupported = h264HighestLevel then exit for else if container = "ts"
end for if levelFloat > h264TsLevelSupported
if h264HighestLevelSupported = h264HighestLevel then exit for h264TsLevelSupported = levelFloat
end for
if h264HighestLevelSupported = h264HighestLevel then exit for
end for
h264LevelString = "41"
if h264HighestLevelSupported = 4.2
h264LevelString = "42"
end if end if
videoProfiles = []
for each container in transContainers
if supportedVideoCodecs[container]["h264"] <> invalid
for each profile in supportedVideoCodecs[container]["h264"]
videoProfiles.push(profile)
end for
exit for
end if end if
end for end for
end for
end for
h264LevelString = h264Mp4LevelSupported
if h264TsLevelSupported > h264Mp4LevelSupported
h264LevelString = h264TsLevelSupported
end if
' convert to string
h264LevelString = h264LevelString.ToStr()
' remove decimals
h264LevelString = removeDecimals(h264LevelString)
codecProfileArray = { codecProfileArray = {
"Type": "Video", "Type": "Video",
@ -452,13 +449,13 @@ function getDeviceProfile() as object
{ {
"Condition": "EqualsAny", "Condition": "EqualsAny",
"Property": "VideoProfile", "Property": "VideoProfile",
"Value": videoProfiles.join("|"), "Value": h264AssProfiles.Keys().join("|"),
"IsRequired": false "IsRequired": false
}, },
{ {
"Condition": "EqualsAny", "Condition": "EqualsAny",
"Property": "VideoRangeType", "Property": "VideoRangeType",
"Value": "SDR", "Value": h264VideoRangeTypes,
"IsRequired": false "IsRequired": false
}, },
{ {
@ -474,19 +471,16 @@ function getDeviceProfile() as object
codecProfileArray.Conditions.push(bitRateArray) codecProfileArray.Conditions.push(bitRateArray)
end if end if
deviceProfile.CodecProfiles.push(codecProfileArray) deviceProfile.CodecProfiles.push(codecProfileArray)
end if
if addMpeg2Profile ' MPEG2
if addMpeg2
mpeg2Levels = [] mpeg2Levels = []
for each container in transContainers for each container in profileSupport
if supportedVideoCodecs[container] <> invalid for each level in profileSupport[container]["mpeg2"]
if supportedVideoCodecs[container]["mpeg2"] <> invalid if mpeg2Levels[level] = invalid
for each level in supportedVideoCodecs[container]["mpeg2"]
mpeg2Levels.push(level) mpeg2Levels.push(level)
end if
end for end for
if mpeg2Levels.count() > 0 then exit for
end if
end if
end for end for
codecProfileArray = { codecProfileArray = {
@ -508,33 +502,35 @@ function getDeviceProfile() as object
deviceProfile.CodecProfiles.push(codecProfileArray) deviceProfile.CodecProfiles.push(codecProfileArray)
end if end if
if addAv1Profile if addAv1
' determine highest level supported av1Mp4LevelSupported = 0.0
av1HighestLevel = 5.1 av1TsLevelSupported = 0.0
av1HighestLevelSupported = 0.0 av1AssProfiles = []
for each container in transContainers av1HighestLevel = 0.0
for each profile in hevcProfiles for each container in profileSupport
for each level in supportedVideoCodecs[container]["av1"][profile] for each profile in profileSupport[container]["av1"]
av1AssProfiles.AddReplace(profile, true)
for each level in profileSupport[container]["av1"][profile]
levelFloat = level.ToFloat() levelFloat = level.ToFloat()
if levelFloat > av1HighestLevelSupported if container = "mp4"
av1HighestLevelSupported = levelFloat if levelFloat > av1Mp4LevelSupported
av1Mp4LevelSupported = levelFloat
end if
else if container = "ts"
if levelFloat > av1TsLevelSupported
av1TsLevelSupported = levelFloat
end if
end if end if
if av1HighestLevelSupported = av1HighestLevel then exit for
end for end for
if av1HighestLevelSupported = av1HighestLevel then exit for
end for end for
if av1HighestLevelSupported = av1HighestLevel then exit for
end for end for
videoProfiles = [] av1HighestLevel = av1Mp4LevelSupported
for each container in transContainers if av1TsLevelSupported > av1Mp4LevelSupported
if supportedVideoCodecs[container]["av1"] <> invalid av1HighestLevel = av1TsLevelSupported
for each profile in supportedVideoCodecs[container]["av1"]
videoProfiles.push(profile)
end for
exit for
end if end if
end for
codecProfileArray = { codecProfileArray = {
"Type": "Video", "Type": "Video",
@ -543,7 +539,7 @@ function getDeviceProfile() as object
{ {
"Condition": "EqualsAny", "Condition": "EqualsAny",
"Property": "VideoProfile", "Property": "VideoProfile",
"Value": videoProfiles.join("|"), "Value": av1AssProfiles.Keys().join("|"),
"IsRequired": false "IsRequired": false
}, },
{ {
@ -555,7 +551,7 @@ function getDeviceProfile() as object
{ {
"Condition": "LessThanEqual", "Condition": "LessThanEqual",
"Property": "VideoLevel", "Property": "VideoLevel",
"Value": (120 * av1HighestLevelSupported).ToStr(), "Value": (120 * av1HighestLevel).ToStr(),
"IsRequired": false "IsRequired": false
} }
] ]
@ -567,39 +563,39 @@ function getDeviceProfile() as object
deviceProfile.CodecProfiles.push(codecProfileArray) deviceProfile.CodecProfiles.push(codecProfileArray)
end if end if
if addHevcProfile if addHevc
' determine highest level supported hevcMp4LevelSupported = 0.0
hevcHighestLevel = 5.1 hevcTsLevelSupported = 0.0
hevcHighestLevelSupported = 0.0 hevcAssProfiles = {}
for each container in transContainers hevcHighestLevel = 0.0
for each profile in hevcProfiles for each container in profileSupport
for each level in supportedVideoCodecs[container]["hevc"][profile] for each profile in profileSupport[container]["hevc"]
hevcAssProfiles.AddReplace(profile, true)
for each level in profileSupport[container]["hevc"][profile]
levelFloat = level.ToFloat() levelFloat = level.ToFloat()
if levelFloat > hevcHighestLevelSupported if container = "mp4"
hevcHighestLevelSupported = levelFloat if levelFloat > hevcMp4LevelSupported
hevcMp4LevelSupported = levelFloat
end if
else if container = "ts"
if levelFloat > hevcTsLevelSupported
hevcTsLevelSupported = levelFloat
end if
end if end if
if hevcHighestLevelSupported = hevcHighestLevel then exit for
end for end for
if hevcHighestLevelSupported = hevcHighestLevel then exit for
end for end for
if hevcHighestLevelSupported = hevcHighestLevel then exit for
end for end for
hevcHighestLevel = hevcMp4LevelSupported
if hevcTsLevelSupported > hevcMp4LevelSupported
hevcHighestLevel = hevcTsLevelSupported
end if
hevcLevelString = "120" hevcLevelString = "120"
if hevcHighestLevelSupported = 5.1 if hevcHighestLevel = 5.1
hevcLevelString = "153" hevcLevelString = "153"
end if end if
videoProfiles = []
for each container in transContainers
if supportedVideoCodecs[container]["hevc"] <> invalid
for each profile in supportedVideoCodecs[container]["hevc"]
videoProfiles.push(profile)
end for
exit for
end if
end for
codecProfileArray = { codecProfileArray = {
"Type": "Video", "Type": "Video",
"Codec": "hevc", "Codec": "hevc",
@ -613,7 +609,7 @@ function getDeviceProfile() as object
{ {
"Condition": "EqualsAny", "Condition": "EqualsAny",
"Property": "VideoProfile", "Property": "VideoProfile",
"Value": videoProfiles.join("|"), "Value": profileSupport["ts"]["hevc"].Keys().join("|"),
"IsRequired": false "IsRequired": false
}, },
{ {
@ -630,6 +626,7 @@ function getDeviceProfile() as object
} }
] ]
} }
bitRateArray = GetBitRateLimit("h265") bitRateArray = GetBitRateLimit("h265")
if bitRateArray.count() > 0 if bitRateArray.count() > 0
codecProfileArray.Conditions.push(bitRateArray) codecProfileArray.Conditions.push(bitRateArray)
@ -637,16 +634,15 @@ function getDeviceProfile() as object
deviceProfile.CodecProfiles.push(codecProfileArray) deviceProfile.CodecProfiles.push(codecProfileArray)
end if end if
if addVp9Profile if addVp9
videoProfiles = [] vp9Profiles = []
for each container in transContainers for each container in profileSupport
if supportedVideoCodecs[container]["vp9"] <> invalid for each profile in profileSupport[container]["vp9"]
for each profile in supportedVideoCodecs[container]["vp9"] if vp9Profiles[profile] = invalid
videoProfiles.push(profile) vp9Profiles.push(profile)
end for
exit for
end if end if
end for end for
end for
codecProfileArray = { codecProfileArray = {
"Type": "Video", "Type": "Video",
@ -654,8 +650,8 @@ function getDeviceProfile() as object
"Conditions": [ "Conditions": [
{ {
"Condition": "EqualsAny", "Condition": "EqualsAny",
"Property": "VideoProfile", "Property": "VideoLevel",
"Value": videoProfiles.join("|"), "Value": vp9Profiles.join("|"),
"IsRequired": false "IsRequired": false
}, },
{ {
@ -666,6 +662,7 @@ function getDeviceProfile() as object
} }
] ]
} }
bitRateArray = GetBitRateLimit("vp9") bitRateArray = GetBitRateLimit("vp9")
if bitRateArray.count() > 0 if bitRateArray.count() > 0
codecProfileArray.Conditions.push(bitRateArray) codecProfileArray.Conditions.push(bitRateArray)
@ -834,3 +831,35 @@ function GetBitRateLimit(codec as string) as object
end if end if
return {} return {}
end function end function
' Recieves and returns an assArray of supported profiles and levels for each video codec
function updateProfileArray(profileArray as object, videoCodec as string, videoProfile as string, profileLevel = "" as string) as object
' validate params
if profileArray = invalid then return {}
if videoCodec = "" or videoProfile = "" then return profileArray
if profileArray[videoCodec] = invalid
profileArray[videoCodec] = {}
end if
if profileArray[videoCodec][videoProfile] = invalid
profileArray[videoCodec][videoProfile] = {}
end if
' add profileLevel if a value was provided
if profileLevel <> ""
if profileArray[videoCodec][videoProfile][profileLevel] = invalid
profileArray[videoCodec][videoProfile].AddReplace(profileLevel, true)
end if
end if
' profileSupport[container][codec][profile][level]
return profileArray
end function
' Remove all decimals from a string
function removeDecimals(value as string) as string
r = CreateObject("roRegex", "\.", "")
value = r.ReplaceAll(value, "")
return value
end function