blob: 01bb24e4bcb5eb32579ea1c1107f84ab7815183c [file] [log] [blame]
Songyue Han130053e2024-04-25 22:04:38 +00001/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "CodecCapabilitiesUtils"
Songyue Han4ed0abd2024-06-29 00:26:54 +000019
20#include <android-base/properties.h>
Songyue Han130053e2024-04-25 22:04:38 +000021#include <utils/Log.h>
22
23#include <algorithm>
24#include <cmath>
Songyue Han4ed0abd2024-06-29 00:26:54 +000025#include <cstdlib>
Songyue Han130053e2024-04-25 22:04:38 +000026#include <string>
27#include <vector>
28
29#include <media/CodecCapabilitiesUtils.h>
Songyue Han4ed0abd2024-06-29 00:26:54 +000030#include <media/stagefright/foundation/ADebug.h>
Songyue Han130053e2024-04-25 22:04:38 +000031#include <media/stagefright/foundation/AUtils.h>
32
33namespace android {
34
Songyue Han4ed0abd2024-06-29 00:26:54 +000035// VideoSize
36
37VideoSize::VideoSize(int32_t width, int32_t height) : mWidth(width), mHeight(height) {}
38
39VideoSize::VideoSize() : mWidth(0), mHeight(0) {}
40
41int32_t VideoSize::getWidth() const { return mWidth; }
42
43int32_t VideoSize::getHeight() const { return mHeight; }
44
45bool VideoSize::equals(VideoSize other) const {
46 return mWidth == other.mWidth && mHeight == other.mHeight;
47}
48
49bool VideoSize::empty() const {
50 return mWidth <= 0 || mHeight <= 0;
51}
52
53std::string VideoSize::toString() const {
54 return std::to_string(mWidth) + "x" + std::to_string(mHeight);
55}
56
57std::optional<VideoSize> VideoSize::ParseSize(std::string str) {
58 if (str.empty()) {
59 return std::nullopt;
60 }
61
62 std::regex regex("([0-9]+)([*x])([0-9]+)");
63 std::smatch match;
64 if (std::regex_match(str, match, regex)) {
65 long int w = strtol(match[1].str().c_str(), NULL, 10);
66 long int h = strtol(match[3].str().c_str(), NULL, 10);
67 return std::make_optional(VideoSize(w, h));
68 } else {
69 ALOGW("could not parse size %s", str.c_str());
70 return std::nullopt;
71 }
72}
73
74std::optional<std::pair<VideoSize, VideoSize>> VideoSize::ParseSizeRange(const std::string str) {
75 size_t ix = str.find_first_of('-');
76 if (ix != std::string::npos) {
77 std::optional<VideoSize> lowerOpt = VideoSize::ParseSize(str.substr(0, ix));
78 std::optional<VideoSize> upperOpt = VideoSize::ParseSize(str.substr(ix + 1));
79 if (!lowerOpt || !upperOpt) {
80 return std::nullopt;
81 }
82 return std::make_optional(
83 std::pair<VideoSize, VideoSize>(lowerOpt.value(), upperOpt.value()));
84 } else {
85 std::optional<VideoSize> opt = VideoSize::ParseSize(str);
86 if (!opt) {
87 return std::nullopt;
88 }
89 return std::make_optional(std::pair<VideoSize, VideoSize>(opt.value(), opt.value()));
90 }
91}
92
93Range<int32_t> VideoSize::GetAllowedDimensionRange() {
94#ifdef __LP64__
95 return Range<int32_t>(1, 32768);
96#else
97 int32_t value = base::GetIntProperty("media.resolution.limit.32bit", (int32_t)4096);
98 return Range<int32_t>(1, value);
99#endif
100}
101
102// Rational
103
104std::optional<Rational> Rational::Parse(std::string str) {
105 if (str.compare("NaN") == 0) {
106 return std::make_optional(NaN);
107 } else if (str.compare("Infinity") == 0) {
108 return std::make_optional(POSITIVE_INFINITY);
109 } else if (str.compare("-Infinity") == 0) {
110 return std::make_optional(NEGATIVE_INFINITY);
111 }
112
113 std::regex regex("([0-9]+)([:/])([0-9]+)");
114 std::smatch match;
115 if (std::regex_match(str, match, regex)) {
116 long int numerator = strtol(match[1].str().c_str(), NULL, 10);
117 long int denominator = strtol(match[3].str().c_str(), NULL, 10);
118 return std::make_optional(Rational(numerator, denominator));
119 } else {
120 ALOGW("could not parse string: %s to Rational", str.c_str());
121 return std::nullopt;
122 }
123}
124
125Rational Rational::scale(int32_t num, int32_t den) {
126 int32_t common = std::gcd(num, den);
127 num /= common;
128 den /= common;
129 return Rational(
130 (int32_t)(mNumerator * (double)num), // saturate to int
131 (int32_t)(mDenominator * (double)den)); // saturate to int
132}
133
134Range<Rational> Rational::ScaleRange(Range<Rational> range, int32_t num, int32_t den) {
135 if (num == den) {
136 return range;
137 }
138 return Range(
139 range.lower().scale(num, den),
140 range.upper().scale(num, den));
141}
142
143std::optional<Range<Rational>> Rational::ParseRange(const std::string str) {
144 size_t ix = str.find_first_of('-');
145 if (ix != std::string::npos) {
146 std::optional<Rational> lower = Parse(str.substr(0, ix));
147 std::optional<Rational> upper = Parse(str.substr(ix + 1));
148 if (!lower || !upper) {
149 return std::nullopt;
150 }
151 return std::make_optional<Range<Rational>>(lower.value(), upper.value());
152 } else {
153 std::optional<Rational> value = Parse(str);
154 if (!value) {
155 return std::nullopt;
156 }
157 return std::make_optional<Range<Rational>>(value.value(), value.value());
158 }
159}
Songyue Han73d6d112024-06-05 17:39:06 +0000160
Songyue Han130053e2024-04-25 22:04:38 +0000161} // namespace android