1 /*
2  * Copyright (C) 2009 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 COLOR_CONVERTER_H_
18 
19 #define COLOR_CONVERTER_H_
20 
21 #include <sys/types.h>
22 
23 #include <stdint.h>
24 #include <utils/Errors.h>
25 
26 #include <optional>
27 
28 #include <OMX_Video.h>
29 #include <media/hardware/VideoAPI.h>
30 
31 namespace android {
32 
33 struct ColorConverter {
34     ColorConverter(OMX_COLOR_FORMATTYPE from, OMX_COLOR_FORMATTYPE to);
35     ~ColorConverter();
36 
37     bool isValid() const;
38 
39     bool isDstRGB() const;
40 
41     void setSrcMediaImage2(MediaImage2 img);
42 
43     void setSrcColorSpace(uint32_t standard, uint32_t range, uint32_t transfer);
44 
45     status_t convert(
46             const void *srcBits,
47             size_t srcWidth, size_t srcHeight, size_t srcStride,
48             size_t srcCropLeft, size_t srcCropTop,
49             size_t srcCropRight, size_t srcCropBottom,
50             void *dstBits,
51             size_t dstWidth, size_t dstHeight, size_t dstStride,
52             size_t dstCropLeft, size_t dstCropTop,
53             size_t dstCropRight, size_t dstCropBottom);
54 
55     struct Coeffs; // matrix coefficients
56 
57     struct ColorSpace {
58         uint32_t mStandard;
59         uint32_t mRange;
60         uint32_t mTransfer;
61 
62         bool isLimitedRange() const;
63         // libyuv helper methods
64         //   BT.2020 limited Range
65         bool isBt2020() const;
66         // BT.2020 full range
67         bool isBtV2020() const;
68         // 709 limited range
69         bool isH709() const;
70         // 709 full range
71         bool isF709() const;
72         // 601 limited range
73         bool isI601() const;
74         // 601 full range
75         // also called "JPEG" in libyuv
76         bool isJ601() const;
77     };
78 
79 private:
80 
81     typedef enum : uint8_t {
82         ImageLayoutUnknown = 0x0,
83         ImageLayout420SemiPlanar = 0x1,
84         ImageLayout420Planar = 0x2
85     } Layout_t;
86 
87     typedef enum : uint8_t {
88         ImageSamplingUnknown = 0x0,
89         ImageSamplingYUV420 = 0x1,
90     } Sampling_t;
91 
92     //this is the actual usable bit
93     typedef enum : uint8_t {
94         ImageBitDepthInvalid = 0x0,
95         ImageBitDepth8 = 0x1,
96         ImageBitDepth10 = 0x2,
97         ImageBitDepth12 = 0x3,
98         ImageBitDepth16 = 0x4
99     } BitDepth_t;
100 
101     struct BitmapParams;
102 
103 
104     class Image {
105     public:
106         Image(const MediaImage2& img);
~ImageColorConverter107         virtual ~Image() {}
108 
getMediaImage2ColorConverter109         const MediaImage2 getMediaImage2() const {
110             return mImage;
111         }
112 
getLayoutColorConverter113         Layout_t getLayout() const {
114             return mLayout;
115         }
getSamplingColorConverter116         Sampling_t getSampling() const {
117             return mSampling;
118         }
getBitDepthColorConverter119         BitDepth_t getBitDepth() const {
120             return mBitDepth;
121         }
122 
123         // Returns the plane offset for this image
124         // after accounting for the src Crop offsets
125         status_t getYUVPlaneOffsetAndStride(
126                 const BitmapParams &src,
127                 uint32_t *y_offset,
128                 uint32_t *u_offset,
129                 uint32_t *v_offset,
130                 size_t *y_stride,
131                 size_t *u_stride,
132                 size_t *v_stride
133                 ) const;
134 
135         bool isNV21() const;
136 
137     private:
138         MediaImage2 mImage;
139         Layout_t mLayout;
140         Sampling_t mSampling;
141         BitDepth_t mBitDepth;
142     };
143 
144     struct BitmapParams {
145         BitmapParams(
146                 void *bits,
147                 size_t width, size_t height, size_t stride,
148                 size_t cropLeft, size_t cropTop,
149                 size_t cropRight, size_t cropBottom,
150                 OMX_COLOR_FORMATTYPE colorFromat);
151 
152         size_t cropWidth() const;
153         size_t cropHeight() const;
154 
155         bool isValid() const;
156 
157         void *mBits;
158         OMX_COLOR_FORMATTYPE mColorFormat;
159         size_t mWidth, mHeight;
160         size_t mCropLeft, mCropTop, mCropRight, mCropBottom;
161         size_t mBpp, mStride;
162     };
163 
164     OMX_COLOR_FORMATTYPE mSrcFormat, mDstFormat;
165     std::optional<Image> mSrcImage;
166     ColorSpace mSrcColorSpace;
167     uint8_t *mClip;
168     uint16_t *mClip10Bit;
169 
170     uint8_t *initClip();
171     uint16_t *initClip10Bit();
172 
173     // resolve YUVFormat from YUV420Flexible
174     bool isValidForMediaImage2() const;
175 
176     // get plane offsets from Formats
177     status_t getSrcYUVPlaneOffsetAndStride(
178             const BitmapParams &src,
179             uint32_t *y_offset,
180             uint32_t *u_offset,
181             uint32_t *v_offset,
182             size_t *y_stride,
183             size_t *u_stride,
184             size_t *v_stride) const;
185 
186     status_t convertYUVMediaImage(
187         const BitmapParams &src, const BitmapParams &dst);
188 
189     // returns the YUV2RGB matrix coefficients according to the color aspects and bit depth
190     const struct Coeffs *getMatrix() const;
191 
192     status_t convertCbYCrY(
193             const BitmapParams &src, const BitmapParams &dst);
194 
195     // status_t convertYUV420Planar(
196     //        const BitmapParams &src, const BitmapParams &dst);
197 
198     status_t convertYUV420PlanarUseLibYUV(
199             const BitmapParams &src, const BitmapParams &dst);
200 
201     status_t convertYUV420SemiPlanarUseLibYUV(
202             const BitmapParams &src, const BitmapParams &dst);
203 
204     status_t convertYUV420Planar16(
205             const BitmapParams &src, const BitmapParams &dst);
206 
207     status_t convertYUV420Planar16ToY410(
208             const BitmapParams &src, const BitmapParams &dst);
209 
210     status_t convertYUV420Planar16ToRGB(
211             const BitmapParams &src, const BitmapParams &dst);
212 
213     status_t convertYUVP010(
214                 const BitmapParams &src, const BitmapParams &dst);
215 
216     status_t convertYUVP010ToRGBA1010102(
217                 const BitmapParams &src, const BitmapParams &dst);
218 
219     ColorConverter(const ColorConverter &);
220 
221     ColorConverter &operator=(const ColorConverter &);
222 };
223 
224 }  // namespace android
225 
226 #endif  // COLOR_CONVERTER_H_
227