xref: /aosp_15_r20/frameworks/av/media/libmedia/include/media/VideoCapabilities.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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_