1 /* 2 * Copyright 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 #ifndef VIDEO_CAPABILITIES_H_ 18 19 #define VIDEO_CAPABILITIES_H_ 20 21 #include <media/CodecCapabilitiesUtils.h> 22 #include <media/stagefright/foundation/AMessage.h> 23 24 #include <utils/StrongPointer.h> 25 26 namespace android { 27 28 struct VideoCapabilities { 29 struct PerformancePoint { 30 /** 31 * Maximum number of macroblocks in the frame. 32 * 33 * Video frames are conceptually divided into 16-by-16 pixel blocks called macroblocks. 34 * Most coding standards operate on these 16-by-16 pixel blocks; thus, codec performance 35 * is characterized using such blocks. 36 * 37 * Test API 38 */ 39 int32_t getMaxMacroBlocks() const; 40 41 /** 42 * Return the width. 43 * 44 * For internal use only. 45 */ 46 int32_t getWidth() const; 47 48 /** 49 * Return the height. 50 * 51 * For internal use only. 52 */ 53 int32_t getHeight() const; 54 55 /** 56 * Maximum frame rate in frames per second. 57 * 58 * Test API 59 */ 60 int32_t getMaxFrameRate() const; 61 62 /** 63 * Maximum number of macroblocks processed per second. 64 * 65 * Test API 66 */ 67 int64_t getMaxMacroBlockRate() const; 68 69 /** 70 * Return the block size. 71 * 72 * For internal use only. 73 */ 74 VideoSize getBlockSize() const; 75 76 /** 77 * convert to a debug string 78 * 79 * Be careful about the serializable compatibility across API revisions. 80 */ 81 std::string toString() const; 82 83 /** 84 * Create a detailed performance point with custom max frame rate and macroblock size. 85 * 86 * @param width frame width in pixels 87 * @param height frame height in pixels 88 * @param frameRate frames per second for frame width and height 89 * @param maxFrameRate maximum frames per second for any frame size 90 * @param blockSize block size for codec implementation. Must be powers of two in both 91 * width and height. 92 * 93 * Test API 94 */ 95 PerformancePoint(int32_t width, int32_t height, int32_t frameRate, int32_t maxFrameRate, 96 VideoSize blockSize); 97 98 /** 99 * Create a detailed performance point with custom max frame rate and macroblock size. 100 * 101 * @param width frame width in pixels 102 * @param height frame height in pixels 103 * @param maxFrameRate maximum frames per second for any frame size 104 * @param maxMacroBlockRate maximum number of macroblocks processed per second. 105 * @param blockSize block size for codec implementation. Must be powers of two in both 106 * width and height. 107 * 108 * Test API 109 */ 110 PerformancePoint(VideoSize blockSize, int32_t width, int32_t height, int maxFrameRate, 111 int64_t maxMacroBlockRate); 112 113 /** 114 * Convert a performance point to a larger blocksize. 115 * 116 * @param pp performance point. NonNull 117 * @param blockSize block size for codec implementation. NonNull. 118 * 119 * Test API 120 */ 121 PerformancePoint(const PerformancePoint &pp, VideoSize newBlockSize); 122 123 /** 124 * Create a performance point for a given frame size and frame rate. 125 * 126 * @param width width of the frame in pixels 127 * @param height height of the frame in pixels 128 * @param frameRate frame rate in frames per second 129 */ 130 PerformancePoint(int32_t width, int32_t height, int32_t frameRate); 131 132 /** 133 * Checks whether the performance point covers a media format. 134 * 135 * @param format Stream format considered 136 * 137 * @return {@code true} if the performance point covers the format. 138 */ 139 bool covers(const sp<AMessage> &format) const; 140 141 /** 142 * Checks whether the performance point covers another performance point. Use this 143 * method to determine if a performance point advertised by a codec covers the 144 * performance point required. This method can also be used for loose ordering as this 145 * method is transitive. 146 * 147 * @param other other performance point considered 148 * 149 * @return {@code true} if the performance point covers the other. 150 */ 151 bool covers(const PerformancePoint &other) const; 152 153 /** 154 * Check if two PerformancePoint instances are equal. 155 * 156 * @param other other PerformancePoint instance for comparison. 157 * 158 * @return true if two PerformancePoint are equal. 159 */ 160 bool equals(const PerformancePoint &other) const; 161 162 private: 163 VideoSize mBlockSize; // codec block size in macroblocks 164 int32_t mWidth; // width in macroblocks 165 int32_t mHeight; // height in macroblocks 166 int32_t mMaxFrameRate; // max frames per second 167 int64_t mMaxMacroBlockRate; // max macro block rate 168 169 void init(int32_t width, int32_t height, int32_t frameRate, int32_t maxFrameRate, 170 VideoSize blockSize); 171 172 /** Saturates a 64 bit integer value to a 32 bit integer */ 173 int32_t saturateInt64ToInt32(int64_t value) const; 174 175 /** This method may overflow */ 176 int32_t align(int32_t value, int32_t alignment) const; 177 178 /** @return NonNull */ 179 VideoSize getCommonBlockSize(const PerformancePoint &other) const; 180 }; 181 182 /** 183 * Find the equivalent VP9 profile level. 184 * 185 * Not a public API to developers. 186 */ 187 static int32_t EquivalentVP9Level(const sp<AMessage> &format); 188 189 /** 190 * Returns the range of supported bitrates in bits/second. 191 */ 192 const Range<int32_t>& getBitrateRange() const; 193 194 /** 195 * Returns the range of supported video widths. 196 * 32-bit processes will not support resolutions larger than 4096x4096 due to 197 * the limited address space. 198 */ 199 const Range<int32_t>& getSupportedWidths() const; 200 201 /** 202 * Returns the range of supported video heights. 203 * 32-bit processes will not support resolutions larger than 4096x4096 due to 204 * the limited address space. 205 */ 206 const Range<int32_t>& getSupportedHeights() const; 207 208 /** 209 * Returns the alignment requirement for video width (in pixels). 210 * 211 * This is a power-of-2 value that video width must be a 212 * multiple of. 213 */ 214 int32_t getWidthAlignment() const; 215 216 /** 217 * Returns the alignment requirement for video height (in pixels). 218 * 219 * This is a power-of-2 value that video height must be a 220 * multiple of. 221 */ 222 int32_t getHeightAlignment() const; 223 224 /** 225 * Return the upper limit on the smaller dimension of width or height. 226 * 227 * Some codecs have a limit on the smaller dimension, whether it be 228 * the width or the height. E.g. a codec may only be able to handle 229 * up to 1920x1080 both in landscape and portrait mode (1080x1920). 230 * In this case the maximum width and height are both 1920, but the 231 * smaller dimension limit will be 1080. For other codecs, this is 232 * {@code Math.min(getSupportedWidths().getUpper(), 233 * getSupportedHeights().getUpper())}. 234 */ 235 int32_t getSmallerDimensionUpperLimit() const; 236 237 /** 238 * Returns the range of supported frame rates. 239 * 240 * This is not a performance indicator. Rather, it expresses the 241 * limits specified in the coding standard, based on the complexities 242 * of encoding material for later playback at a certain frame rate, 243 * or the decoding of such material in non-realtime. 244 */ 245 const Range<int32_t>& getSupportedFrameRates() const; 246 247 /** 248 * Returns the range of supported video widths for a video height. 249 * @param height the height of the video 250 */ 251 std::optional<Range<int32_t>> getSupportedWidthsFor(int32_t height) const; 252 253 /** 254 * Returns the range of supported video heights for a video width 255 * @param width the width of the video 256 */ 257 std::optional<Range<int32_t>> getSupportedHeightsFor(int32_t width) const; 258 259 /** 260 * Returns the range of supported video frame rates for a video size. 261 * 262 * This is not a performance indicator. Rather, it expresses the limits specified in 263 * the coding standard, based on the complexities of encoding material of a given 264 * size for later playback at a certain frame rate, or the decoding of such material 265 * in non-realtime. 266 267 * @param width the width of the video 268 * @param height the height of the video 269 */ 270 std::optional<Range<double>> getSupportedFrameRatesFor(int32_t width, int32_t height) const; 271 272 /** 273 * Returns the range of achievable video frame rates for a video size. 274 * May return {@code null}, if the codec did not publish any measurement 275 * data. 276 * <p> 277 * This is a performance estimate provided by the device manufacturer based on statistical 278 * sampling of full-speed decoding and encoding measurements in various configurations 279 * of common video sizes supported by the codec. As such it should only be used to 280 * compare individual codecs on the device. The value is not suitable for comparing 281 * different devices or even different android releases for the same device. 282 * <p> 283 * <em>On {@link android.os.Build.VERSION_CODES#M} release</em> the returned range 284 * corresponds to the fastest frame rates achieved in the tested configurations. As 285 * such, it should not be used to gauge guaranteed or even average codec performance 286 * on the device. 287 * <p> 288 * <em>On {@link android.os.Build.VERSION_CODES#N} release</em> the returned range 289 * corresponds closer to sustained performance <em>in tested configurations</em>. 290 * One can expect to achieve sustained performance higher than the lower limit more than 291 * 50% of the time, and higher than half of the lower limit at least 90% of the time 292 * <em>in tested configurations</em>. 293 * Conversely, one can expect performance lower than twice the upper limit at least 294 * 90% of the time. 295 * <p class=note> 296 * Tested configurations use a single active codec. For use cases where multiple 297 * codecs are active, applications can expect lower and in most cases significantly lower 298 * performance. 299 * <p class=note> 300 * The returned range value is interpolated from the nearest frame size(s) tested. 301 * Codec performance is severely impacted by other activity on the device as well 302 * as environmental factors (such as battery level, temperature or power source), and can 303 * vary significantly even in a steady environment. 304 * <p class=note> 305 * Use this method in cases where only codec performance matters, e.g. to evaluate if 306 * a codec has any chance of meeting a performance target. Codecs are listed 307 * in {@link MediaCodecList} in the preferred order as defined by the device 308 * manufacturer. As such, applications should use the first suitable codec in the 309 * list to achieve the best balance between power use and performance. 310 * 311 * @param width the width of the video 312 * @param height the height of the video 313 */ 314 std::optional<Range<double>> getAchievableFrameRatesFor(int32_t width, int32_t height) const; 315 316 /** 317 * Returns the supported performance points. May return {@code null} if the codec did not 318 * publish any performance point information (e.g. the vendor codecs have not been updated 319 * to the latest android release). May return an empty list if the codec published that 320 * if does not guarantee any performance points. 321 * <p> 322 * This is a performance guarantee provided by the device manufacturer for hardware codecs 323 * based on hardware capabilities of the device. 324 * <p> 325 * The returned list is sorted first by decreasing number of pixels, then by decreasing 326 * width, and finally by decreasing frame rate. 327 * Performance points assume a single active codec. For use cases where multiple 328 * codecs are active, should use that highest pixel count, and add the frame rates of 329 * each individual codec. 330 * <p class=note> 331 * 32-bit processes will not support resolutions larger than 4096x4096 due to 332 * the limited address space, but performance points will be presented as is. 333 * In other words, even though a component publishes a performance point for 334 * a resolution higher than 4096x4096, it does not mean that the resolution is supported 335 * for 32-bit processes. 336 */ 337 const std::vector<PerformancePoint>& getSupportedPerformancePoints() const; 338 339 /** 340 * Returns whether a given video size ({@code width} and 341 * {@code height}) and {@code frameRate} combination is supported. 342 */ 343 bool areSizeAndRateSupported(int32_t width, int32_t height, double frameRate) const; 344 345 /** 346 * Returns whether a given video size ({@code width} and 347 * {@code height}) is supported. 348 */ 349 bool isSizeSupported(int32_t width, int32_t height) const; 350 351 /** 352 * Returns if a media format is supported. 353 * 354 * Not exposed to public 355 */ 356 bool supportsFormat(const sp<AMessage> &format) const; 357 358 /** 359 * Create VideoCapabilities. 360 */ 361 static std::shared_ptr<VideoCapabilities> Create(std::string mediaType, 362 std::vector<ProfileLevel> profLevs, const sp<AMessage> &format); 363 364 /** 365 * Get the block size. 366 * 367 * Not a public API to developers 368 */ 369 VideoSize getBlockSize() const; 370 371 /** 372 * Get the block count range. 373 * 374 * Not a public API to developers 375 */ 376 const Range<int32_t>& getBlockCountRange() const; 377 378 /** 379 * Get the blocks per second range. 380 * 381 * Not a public API to developers 382 */ 383 const Range<int64_t>& getBlocksPerSecondRange() const; 384 385 /** 386 * Get the aspect ratio range. 387 * 388 * Not a public API to developers 389 */ 390 Range<Rational> getAspectRatioRange(bool blocks) const; 391 392 private: 393 std::string mMediaType; 394 std::vector<ProfileLevel> mProfileLevels; 395 int mError; 396 397 Range<int32_t> mBitrateRange; 398 Range<int32_t> mHeightRange; 399 Range<int32_t> mWidthRange; 400 Range<int32_t> mBlockCountRange; 401 Range<int32_t> mHorizontalBlockRange; 402 Range<int32_t> mVerticalBlockRange; 403 Range<Rational> mAspectRatioRange; 404 Range<Rational> mBlockAspectRatioRange; 405 Range<int64_t> mBlocksPerSecondRange; 406 std::map<VideoSize, Range<int64_t>, VideoSizeCompare> mMeasuredFrameRates; 407 std::vector<PerformancePoint> mPerformancePoints; 408 Range<int32_t> mFrameRateRange; 409 410 int32_t mBlockWidth; 411 int32_t mBlockHeight; 412 int32_t mWidthAlignment; 413 int32_t mHeightAlignment; 414 int mSmallerDimensionUpperLimit; 415 416 bool mAllowMbOverride; // allow XML to override calculated limits 417 418 int32_t getBlockCount(int32_t width, int32_t height) const; 419 std::optional<VideoSize> findClosestSize(int32_t width, int32_t height) const; 420 std::optional<Range<double>> estimateFrameRatesFor(int32_t width, int32_t height) const; 421 bool supports(std::optional<int32_t> width, std::optional<int32_t> height, 422 std::optional<double> rate) const; 423 /* no public constructor */ VideoCapabilitiesVideoCapabilities424 VideoCapabilities() {} 425 void init(std::string mediaType, std::vector<ProfileLevel> profLevs, 426 const sp<AMessage> &format); 427 void initWithPlatformLimits(); 428 std::vector<PerformancePoint> getPerformancePoints(const sp<AMessage> &format) const; 429 std::map<VideoSize, Range<int64_t>, VideoSizeCompare> 430 getMeasuredFrameRates(const sp<AMessage> &format) const; 431 432 static std::optional<std::pair<Range<int32_t>, Range<int32_t>>> ParseWidthHeightRanges( 433 const std::string &str); 434 void parseFromInfo(const sp<AMessage> &format); 435 void applyBlockLimits(int32_t blockWidth, int32_t blockHeight, 436 Range<int32_t> counts, Range<int64_t> rates, Range<Rational> ratios); 437 void applyAlignment(int32_t widthAlignment, int32_t heightAlignment); 438 void updateLimits(); 439 void applyMacroBlockLimits( 440 int32_t maxHorizontalBlocks, int32_t maxVerticalBlocks, 441 int32_t maxBlocks, int64_t maxBlocksPerSecond, 442 int32_t blockWidth, int32_t blockHeight, 443 int32_t widthAlignment, int32_t heightAlignment); 444 void applyMacroBlockLimits( 445 int32_t minHorizontalBlocks, int32_t minVerticalBlocks, 446 int32_t maxHorizontalBlocks, int32_t maxVerticalBlocks, 447 int32_t maxBlocks, int64_t maxBlocksPerSecond, 448 int32_t blockWidth, int32_t blockHeight, 449 int32_t widthAlignment, int32_t heightAlignment); 450 void applyLevelLimits(); 451 452 friend struct CodecCapabilities; 453 }; 454 455 } // namespace android 456 457 #endif // VIDEO_CAPABILITIES_H_