1 /*
2  * Copyright 2018, 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 "Codec2BufferUtils"
19 #define ATRACE_TAG  ATRACE_TAG_VIDEO
20 #include <utils/Log.h>
21 
22 #include <android/hardware_buffer.h>
23 #include <android-base/properties.h>
24 #include <cutils/properties.h>
25 #include <media/hardware/HardwareAPI.h>
26 #include <system/graphics.h>
27 
28 #include <C2Debug.h>
29 
30 #include "Codec2CommonUtils.h"
31 
32 namespace android {
33 
34 
isAtLeast(int version,const std::string codeName)35 static bool isAtLeast(int version, const std::string codeName) {
36     static std::once_flag sCheckOnce;
37     static std::string sDeviceCodeName;
38     static int sDeviceApiLevel;
39     std::call_once(sCheckOnce, [&](){
40         sDeviceCodeName = base::GetProperty("ro.build.version.codename", "");
41         sDeviceApiLevel = android_get_device_api_level();
42     });
43     return sDeviceApiLevel >= version || sDeviceCodeName == codeName;
44 }
45 
isAtLeastT()46 bool isAtLeastT() {
47     return isAtLeast(__ANDROID_API_T__, "Tiramisu");
48 }
49 
isAtLeastU()50 bool isAtLeastU() {
51     return isAtLeast(__ANDROID_API_U__, "UpsideDownCake");
52 }
53 
isAtLeastV()54 bool isAtLeastV() {
55     return isAtLeast(__ANDROID_API_V__, "VanillaIceCream");
56 }
57 
isP010Allowed()58 static bool isP010Allowed() {
59     // The Vendor API level which is min(ro.product.first_api_level, ro.board.[first_]api_level).
60     // This is the api level to which VSR requirement the device conform.
61     static const int32_t kVendorApiLevel =
62         base::GetIntProperty<int32_t>("ro.vendor.api_level", 0);
63 
64     return kVendorApiLevel >= __ANDROID_API_T__;
65 }
66 
isHalPixelFormatSupported(AHardwareBuffer_Format format)67 bool isHalPixelFormatSupported(AHardwareBuffer_Format format) {
68     // HAL_PIXEL_FORMAT_YCBCR_P010 requirement was added in T VSR, although it could have been
69     // supported prior to this.
70     //
71     // Unfortunately, we cannot detect if P010 is properly supported using AHardwareBuffer
72     // API alone. For now limit P010 to devices that launched with Android T or known to conform
73     // to Android T VSR (as opposed to simply limiting to a T vendor image).
74     if (format == (AHardwareBuffer_Format)HAL_PIXEL_FORMAT_YCBCR_P010 &&
75             !isP010Allowed()) {
76         return false;
77     }
78 
79     // Default scenario --- the consumer is display or GPU
80     const AHardwareBuffer_Desc consumableForDisplayOrGpu = {
81             .width = 320,
82             .height = 240,
83             .format = format,
84             .layers = 1,
85             .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
86                      AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
87                      AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
88                      AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY,
89             .stride = 0,
90             .rfu0 = 0,
91             .rfu1 = 0,
92     };
93 
94     // The consumer is a HW encoder
95     const AHardwareBuffer_Desc consumableForHwEncoder = {
96             .width = 320,
97             .height = 240,
98             .format = format,
99             .layers = 1,
100             .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
101                      AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
102                      AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
103                      AHARDWAREBUFFER_USAGE_VIDEO_ENCODE,
104             .stride = 0,
105             .rfu0 = 0,
106             .rfu1 = 0,
107     };
108 
109     // The consumer is a SW encoder
110     const AHardwareBuffer_Desc consumableForSwEncoder = {
111             .width = 320,
112             .height = 240,
113             .format = format,
114             .layers = 1,
115             .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
116                      AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
117                      AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
118                      AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY,
119             .stride = 0,
120             .rfu0 = 0,
121             .rfu1 = 0,
122     };
123     // Some devices running versions prior to Android U aren't guaranteed to advertise support
124     // for some color formats when the consumer is an encoder. Hence limit these checks to
125     // Android U and beyond.
126     if (isAtLeastU()) {
127         return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu)
128                 && AHardwareBuffer_isSupported(&consumableForHwEncoder)
129                 && AHardwareBuffer_isSupported(&consumableForSwEncoder);
130     } else {
131         return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu);
132     }
133 }
134 
135 }  // namespace android
136