// // Copyright © 2025 Hardcore Engineering Inc. // // Licensed under the Eclipse Public License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. You may // obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // limitations under the License. // // Package resconv implements conversions to and from string representations of video resolutions. package resconv import ( "sort" "strconv" "strings" ) const defaultLevel = "360p" var prefixes = []struct { pixels int width int height int label string }{ {pixels: 640 * 360, width: 640, height: 360, label: "360p"}, {pixels: 1280 * 720, width: 720, height: 720, label: "480p"}, {pixels: 1920 * 1080, width: 1920, height: 1080, label: "720p"}, {pixels: 2560 * 1440, width: 2560, height: 1440, label: "1080p"}, {pixels: 3840 * 2160, width: 3840, height: 2160, label: "1440p"}, {pixels: 7680 * 4320, width: 7680, height: 4320, label: "2160p"}, } var bandwidthMap = map[string]int{ "360p": 500000, "480p": 2000000, "720p": 5000000, "1080p": 8000000, "1440p": 12000000, "2160p": 25000000, "4320p": 50000000, } var resolutions = map[string]string{ "360p": "640:360", "480p": "640:480", "720p": "1280:720", "1080p": "1920:1080", "1440p": "2560:1440", "2160p": "3840:2160", "4320p": "7680:4320", } // SubLevels returns sublevels for the resolution func SubLevels(resolution string) (res []string) { var height = Height(resolution) var idx = sort.Search(len(prefixes), func(i int) bool { return height < prefixes[i].height }) if idx < 2 { return res } idx-- idx = min(idx, 3) for idx >= 1 { res = append(res, prefixes[idx].label) idx-- if len(res) == 2 { break } } return res } // Resolution returns default resolution based on the level func Resolution(level string) string { if res, ok := resolutions[level]; ok { return res } return Resolution(defaultLevel) } // Level converts the resolution to short prefix func Level(resolution string) string { var height = Height(resolution) idx := sort.Search(len(prefixes), func(i int) bool { return height < prefixes[i].height }) if idx == len(prefixes) { return "4320p" } return prefixes[idx].label } // Height returns height for the resolution func Height(resolution string) int { var parts = strings.Split(resolution, ":") var h = 240 if len(parts) > 1 { var _h, _ = strconv.Atoi(parts[1]) h = max(h, _h) } return h } // Pixels returns amount of pixels for the resolution func Pixels(resolution string) int { var parts = strings.Split(resolution, ":") var w, h = 320, 240 if len(parts) > 1 { var _w, _ = strconv.Atoi(parts[0]) var _h, _ = strconv.Atoi(parts[1]) w = max(w, _w) h = max(h, _h) } return w * h } // Bandwidth returns default bandwidth for the resolution func Bandwidth(resolution string) int { if v, ok := bandwidthMap[resolution]; ok { return v } return bandwidthMap[defaultLevel] }