Files
huly-platform/foundations/stream/internal/pkg/resconv/resconv.go
T
Denis Bykhov 6e77cbb762 Add 'foundations/stream/' from commit 'b7b6930b0992ae48f08d37745d5e6e5e26517337'
git-subtree-dir: foundations/stream
git-subtree-mainline: 328a7dc269
git-subtree-split: b7b6930b09
2025-11-26 23:06:55 +05:00

140 lines
3.2 KiB
Go

//
// 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]
}