1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "image_format_convert.h"
17 #ifdef EXT_PIXEL
18 #include "pixel_yuv_ext.h"
19 #endif
20
21 #include <map>
22 #include <memory>
23 #include "hilog/log.h"
24 #include "image_format_convert_ext_utils.h"
25 #include "image_log.h"
26 #include "image_source.h"
27 #include "log_tags.h"
28 #include "media_errors.h"
29 #include "pixel_yuv.h"
30 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
31 #include "v1_0/buffer_handle_meta_key_type.h"
32 #include "v1_0/cm_color_space.h"
33 #include "v1_0/hdr_static_metadata.h"
34 #include "surface_buffer.h"
35 #endif
36 #include "vpe_utils.h"
37 #include "image_utils.h"
38
39 namespace {
40 constexpr uint8_t NUM_0 = 0;
41 constexpr uint8_t NUM_1 = 1;
42 constexpr uint8_t NUM_2 = 2;
43 constexpr uint8_t NUM_3 = 3;
44 constexpr uint8_t NUM_4 = 4;
45 constexpr uint8_t NUM_8 = 8;
46 constexpr uint8_t PLANE_Y = 0;
47 constexpr uint8_t PLANE_U = 1;
48 constexpr uint8_t PLANE_V = 2;
49 constexpr uint32_t BYTES_PER_PIXEL_RGB565 = 2;
50 constexpr uint32_t BYTES_PER_PIXEL_RGB = 3;
51 constexpr uint32_t BYTES_PER_PIXEL_RGBA = 4;
52 constexpr uint32_t BYTES_PER_PIXEL_BGRA = 4;
53 constexpr uint32_t STRIDES_PER_PLANE = 8;
54 }
55
56 #undef LOG_DOMAIN
57 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
58
59 #undef LOG_TAG
60 #define LOG_TAG "ImageFormatConvert"
61
62 namespace OHOS {
63 namespace Media {
64 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
65 using namespace HDI::Display::Graphic::Common::V1_0;
66 #endif
67
__anon6e213fcc0202() 68 static const std::map<std::pair<PixelFormat, PixelFormat>, ConvertFunction> g_cvtFuncMap = []() {
69 #ifndef EXT_PIXEL
70 static const std::map<std::pair<PixelFormat, PixelFormat>, ConvertFunction> cvtFuncMap = {
71 {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV21), ImageFormatConvertUtils::RGB565ToNV21},
72 {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV12), ImageFormatConvertUtils::RGB565ToNV12},
73 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV21), ImageFormatConvertUtils::RGBAToNV21},
74 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV12), ImageFormatConvertUtils::RGBAToNV12},
75 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV21), ImageFormatConvertUtils::BGRAToNV21},
76 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV12), ImageFormatConvertUtils::BGRAToNV12},
77 {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV21), ImageFormatConvertUtils::RGBToNV21},
78 {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV12), ImageFormatConvertUtils::RGBToNV12},
79 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV21), ImageFormatConvertUtils::RGBAF16ToNV21},
80 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV12), ImageFormatConvertUtils::RGBAF16ToNV12},
81 {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGB565ToNV12P010},
82 {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGB565ToNV21P010},
83 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBAToNV12P010},
84 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBAToNV21P010},
85 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::BGRAToNV12P010},
86 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::BGRAToNV21P010},
87 {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBToNV12P010},
88 {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBToNV21P010},
89 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBAF16ToNV12P010},
90 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBAF16ToNV21P010},
91 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV12), ImageFormatConvertUtils::RGBA1010102ToNV12},
92 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV21), ImageFormatConvertUtils::RGBA1010102ToNV21},
93 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCBCR_P010),
94 ImageFormatConvertUtils::RGBA1010102ToNV12P010},
95 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCRCB_P010),
96 ImageFormatConvertUtils::RGBA1010102ToNV21P010},
97 };
98 #else
99 static const std::map<std::pair<PixelFormat, PixelFormat>, ConvertFunction> cvtFuncMap = {
100 {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV21), ImageFormatConvertExtUtils::RGB565ToNV21},
101 {std::make_pair(PixelFormat::RGB_565, PixelFormat::NV12), ImageFormatConvertExtUtils::RGB565ToNV12},
102 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV21), ImageFormatConvertExtUtils::RGBAToNV21},
103 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::NV12), ImageFormatConvertExtUtils::RGBAToNV12},
104 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV21), ImageFormatConvertExtUtils::BGRAToNV21},
105 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::NV12), ImageFormatConvertExtUtils::BGRAToNV12},
106 {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV21), ImageFormatConvertUtils::RGBToNV21},
107 {std::make_pair(PixelFormat::RGB_888, PixelFormat::NV12), ImageFormatConvertUtils::RGBToNV12},
108 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV21), ImageFormatConvertUtils::RGBAF16ToNV21},
109 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::NV12), ImageFormatConvertUtils::RGBAF16ToNV12},
110 {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::RGB565ToNV12P010},
111 {std::make_pair(PixelFormat::RGB_565, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::RGB565ToNV21P010},
112 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::RGBAToNV12P010},
113 {std::make_pair(PixelFormat::RGBA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::RGBAToNV21P010},
114 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::BGRAToNV12P010},
115 {std::make_pair(PixelFormat::BGRA_8888, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::BGRAToNV21P010},
116 {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::RGBToNV12P010},
117 {std::make_pair(PixelFormat::RGB_888, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::RGBToNV21P010},
118 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV12), ImageFormatConvertExtUtils::RGBA1010102ToNV12},
119 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::NV21), ImageFormatConvertExtUtils::RGBA1010102ToNV21},
120 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCBCR_P010),
121 ImageFormatConvertUtils::RGBA1010102ToNV12P010},
122 {std::make_pair(PixelFormat::RGBA_1010102, PixelFormat::YCRCB_P010),
123 ImageFormatConvertUtils::RGBA1010102ToNV21P010},
124 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::RGBAF16ToNV12P010},
125 {std::make_pair(PixelFormat::RGBA_F16, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::RGBAF16ToNV21P010},
126 };
127 #endif
128 return cvtFuncMap;
129 }();
130
__anon6e213fcc0302() 131 static const std::map<std::pair<PixelFormat, PixelFormat>, YUVConvertFunction> g_yuvCvtFuncMap = []() {
132 #ifndef EXT_PIXEL
133 std::map<std::pair<PixelFormat, PixelFormat>, YUVConvertFunction> yuvCvtFuncMap = {
134 {std::make_pair(PixelFormat::NV12, PixelFormat::NV21), ImageFormatConvertUtils::NV12ToNV21},
135 {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_888), ImageFormatConvertUtils::NV12ToRGB},
136 {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_565), ImageFormatConvertUtils::NV12ToRGB565},
137 {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12ToRGBAF16},
138 {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV12ToRGBA},
139 {std::make_pair(PixelFormat::NV12, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV12ToBGRA},
140 {std::make_pair(PixelFormat::NV21, PixelFormat::NV12), ImageFormatConvertUtils::NV21ToNV12},
141 {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_888), ImageFormatConvertUtils::NV21ToRGB},
142 {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_565), ImageFormatConvertUtils::NV21ToRGB565},
143 {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21ToRGBAF16},
144 {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV21ToRGBA},
145 {std::make_pair(PixelFormat::NV21, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV21ToBGRA},
146 {std::make_pair(PixelFormat::NV12, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::NV12ToNV12P010},
147 {std::make_pair(PixelFormat::NV12, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::NV12ToNV21P010},
148 {std::make_pair(PixelFormat::NV21, PixelFormat::YCBCR_P010), ImageFormatConvertUtils::NV21ToNV12P010},
149 {std::make_pair(PixelFormat::NV21, PixelFormat::YCRCB_P010), ImageFormatConvertUtils::NV21ToNV21P010},
150 {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_1010102), ImageFormatConvertUtils::NV12ToRGBA1010102},
151 {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_1010102), ImageFormatConvertUtils::NV21ToRGBA1010102},
152 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV12), ImageFormatConvertUtils::NV12P010ToNV12},
153 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV21), ImageFormatConvertUtils::NV12P010ToNV21},
154 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::YCRCB_P010),
155 ImageFormatConvertUtils::NV12P010ToNV21P010},
156 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_565), ImageFormatConvertUtils::NV12P010ToRGB565},
157 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV12P010ToRGBA8888},
158 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV12P010ToBGRA8888},
159 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_888), ImageFormatConvertUtils::NV12P010ToRGB888},
160 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12P010ToRGBAF16},
161 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV12), ImageFormatConvertUtils::NV21P010ToNV12},
162 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV21), ImageFormatConvertUtils::NV21P010ToNV21},
163 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::YCBCR_P010),
164 ImageFormatConvertUtils::NV21P010ToNV12P010},
165 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_1010102),
166 ImageFormatConvertUtils::NV12P010ToRGBA1010102},
167 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_565), ImageFormatConvertUtils::NV21P010ToRGB565},
168 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_8888), ImageFormatConvertUtils::NV21P010ToRGBA8888},
169 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::BGRA_8888), ImageFormatConvertUtils::NV21P010ToBGRA8888},
170 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_888), ImageFormatConvertUtils::NV21P010ToRGB888},
171 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21P010ToRGBAF16},
172 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_1010102),
173 ImageFormatConvertUtils::NV21P010ToRGBA1010102},
174 };
175 #else
176 std::map<std::pair<PixelFormat, PixelFormat>, YUVConvertFunction> yuvCvtFuncMap = {
177 {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV21ToRGB},
178 {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_8888), ImageFormatConvertExtUtils::NV21ToRGBA},
179 {std::make_pair(PixelFormat::NV21, PixelFormat::BGRA_8888), ImageFormatConvertExtUtils::NV21ToBGRA},
180 {std::make_pair(PixelFormat::NV21, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV21ToRGB565},
181 {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV12ToRGB565},
182 {std::make_pair(PixelFormat::NV21, PixelFormat::NV12), ImageFormatConvertUtils::NV21ToNV12},
183 {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21ToRGBAF16},
184 {std::make_pair(PixelFormat::NV12, PixelFormat::NV21), ImageFormatConvertUtils::NV12ToNV21},
185 {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12ToRGBAF16},
186 {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_8888), ImageFormatConvertExtUtils::NV12ToRGBA},
187 {std::make_pair(PixelFormat::NV12, PixelFormat::BGRA_8888), ImageFormatConvertExtUtils::NV12ToBGRA},
188 {std::make_pair(PixelFormat::NV12, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV12ToRGB},
189 {std::make_pair(PixelFormat::NV12, PixelFormat::RGBA_1010102), ImageFormatConvertExtUtils::NV12ToRGBA1010102},
190 {std::make_pair(PixelFormat::NV21, PixelFormat::RGBA_1010102), ImageFormatConvertExtUtils::NV21ToRGBA1010102},
191 {std::make_pair(PixelFormat::NV12, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::NV12ToNV12P010},
192 {std::make_pair(PixelFormat::NV12, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::NV12ToNV21P010},
193 {std::make_pair(PixelFormat::NV21, PixelFormat::YCBCR_P010), ImageFormatConvertExtUtils::NV21ToNV12P010},
194 {std::make_pair(PixelFormat::NV21, PixelFormat::YCRCB_P010), ImageFormatConvertExtUtils::NV21ToNV21P010},
195 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV12), ImageFormatConvertExtUtils::NV12P010ToNV12},
196 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::NV21), ImageFormatConvertExtUtils::NV12P010ToNV21},
197 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::YCRCB_P010),
198 ImageFormatConvertUtils::NV12P010ToNV21P010},
199 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV12P010ToRGB565},
200 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_8888),
201 ImageFormatConvertExtUtils::NV12P010ToRGBA8888},
202 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::BGRA_8888),
203 ImageFormatConvertExtUtils::NV12P010ToBGRA8888},
204 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV12P010ToRGB888},
205 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV12P010ToRGBAF16},
206 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV12), ImageFormatConvertExtUtils::NV21P010ToNV12},
207 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::NV21), ImageFormatConvertExtUtils::NV21P010ToNV21},
208 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::YCBCR_P010),
209 ImageFormatConvertUtils::NV21P010ToNV12P010},
210 {std::make_pair(PixelFormat::YCBCR_P010, PixelFormat::RGBA_1010102),
211 ImageFormatConvertExtUtils::NV12P010ToRGBA1010102},
212 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_565), ImageFormatConvertExtUtils::NV21P010ToRGB565},
213 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_8888),
214 ImageFormatConvertExtUtils::NV21P010ToRGBA8888},
215 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::BGRA_8888),
216 ImageFormatConvertExtUtils::NV21P010ToBGRA8888},
217 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGB_888), ImageFormatConvertExtUtils::NV21P010ToRGB888},
218 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_F16), ImageFormatConvertUtils::NV21P010ToRGBAF16},
219 {std::make_pair(PixelFormat::YCRCB_P010, PixelFormat::RGBA_1010102),
220 ImageFormatConvertExtUtils::NV21P010ToRGBA1010102},
221 };
222 #endif
223 return yuvCvtFuncMap;
224 }();
225
226 static const std::set<std::pair<PixelFormat, PixelFormat>> conversions = {
227 {PixelFormat::NV12, PixelFormat::RGBA_1010102},
228 {PixelFormat::NV21, PixelFormat::RGBA_1010102},
229 {PixelFormat::RGB_565, PixelFormat::YCBCR_P010},
230 {PixelFormat::RGBA_8888, PixelFormat::YCBCR_P010},
231 {PixelFormat::BGRA_8888, PixelFormat::YCBCR_P010},
232 {PixelFormat::RGB_888, PixelFormat::YCBCR_P010},
233 {PixelFormat::RGBA_F16, PixelFormat::YCBCR_P010},
234 {PixelFormat::RGB_565, PixelFormat::YCRCB_P010},
235 {PixelFormat::RGBA_8888, PixelFormat::YCRCB_P010},
236 {PixelFormat::BGRA_8888, PixelFormat::YCRCB_P010},
237 {PixelFormat::RGB_888, PixelFormat::YCRCB_P010},
238 {PixelFormat::RGBA_F16, PixelFormat::YCRCB_P010}
239 };
240
CalcRGBStride(PixelFormat format,uint32_t width,uint32_t & stride)241 static void CalcRGBStride(PixelFormat format, uint32_t width, uint32_t &stride)
242 {
243 switch (format) {
244 case PixelFormat::RGB_565:
245 stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGB565);
246 break;
247 case PixelFormat::RGBA_8888:
248 stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGBA);
249 break;
250 case PixelFormat::BGRA_8888:
251 stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_BGRA);
252 break;
253 case PixelFormat::RGB_888:
254 stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGB);
255 break;
256 case PixelFormat::RGBA_F16:
257 stride = static_cast<uint32_t>(width * STRIDES_PER_PLANE);
258 break;
259 default:
260 stride = static_cast<uint32_t>(width * BYTES_PER_PIXEL_RGBA);
261 }
262 }
263
IsYUVConvert(PixelFormat srcFormat)264 static bool IsYUVConvert(PixelFormat srcFormat)
265 {
266 bool ret = srcFormat == PixelFormat::NV21 || srcFormat == PixelFormat::NV12 ||
267 srcFormat == PixelFormat::YCBCR_P010 || srcFormat == PixelFormat::YCRCB_P010;
268 return ret;
269 }
270
YUVConvert(const OHOS::Media::ConvertDataInfo & srcDataInfo,OHOS::Media::DestConvertInfo & destInfo)271 uint32_t ImageFormatConvert::YUVConvert(const OHOS::Media::ConvertDataInfo &srcDataInfo,
272 OHOS::Media::DestConvertInfo &destInfo)
273 {
274 YUVConvertFunction yuvConvertFunction = YUVGetConvertFuncByFormat(srcDataInfo.pixelFormat, destInfo.format);
275 CHECK_ERROR_RETURN_RET_LOG(yuvConvertFunction == nullptr, ERR_IMAGE_INVALID_PARAMETER,
276 "YUVConvert get convert function by format failed!");
277 YUVDataInfo yuvDataInfo = srcDataInfo.yuvDataInfo;
278 int32_t width = srcDataInfo.imageSize.width;
279 int32_t height = srcDataInfo.imageSize.height;
280 if (destInfo.width == 0 || destInfo.height == 0) {
281 destInfo.width = static_cast<uint32_t>(width);
282 destInfo.height = static_cast<uint32_t>(height);
283 }
284 if (yuvDataInfo.yWidth == 0 || yuvDataInfo.yHeight == 0 || yuvDataInfo.uvWidth == 0 || yuvDataInfo.uvHeight == 0) {
285 yuvDataInfo.yWidth = static_cast<uint32_t>(width);
286 yuvDataInfo.yHeight = static_cast<uint32_t>(height);
287 yuvDataInfo.uvWidth = static_cast<uint32_t>((width + 1) / NUM_2);
288 yuvDataInfo.uvHeight = static_cast<uint32_t>((height + 1) / NUM_2);
289 }
290 YUVStrideInfo dstStrides;
291 auto m = CreateMemory(destInfo.format, destInfo.allocType, {destInfo.width, destInfo.height}, dstStrides);
292 CHECK_ERROR_RETURN_RET_LOG(m == nullptr, ERR_IMAGE_INVALID_PARAMETER, "YUVConvert create memory failed!");
293 destInfo.context = m->extend.data;
294 destInfo.yStride = dstStrides.yStride;
295 destInfo.uvStride = dstStrides.uvStride;
296 destInfo.yOffset = dstStrides.yOffset;
297 destInfo.uvOffset = dstStrides.uvOffset;
298 destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
299 destInfo.bufferSize = GetBufferSizeByFormat(destInfo.format, {destInfo.width, destInfo.height});
300
301 if (!yuvConvertFunction(srcDataInfo.buffer, yuvDataInfo, destInfo, srcDataInfo.colorSpace)) {
302 IMAGE_LOGE("YUVConvert format convert failed!");
303 m->Release();
304 return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
305 }
306 return SUCCESS;
307 }
308
RGBConvert(const OHOS::Media::ConvertDataInfo & srcDataInfo,OHOS::Media::DestConvertInfo & destInfo)309 uint32_t ImageFormatConvert::RGBConvert(const OHOS::Media::ConvertDataInfo &srcDataInfo,
310 OHOS::Media::DestConvertInfo &destInfo)
311 {
312 ConvertFunction cvtFunc = GetConvertFuncByFormat(srcDataInfo.pixelFormat, destInfo.format);
313 CHECK_ERROR_RETURN_RET_LOG(cvtFunc == nullptr, ERR_IMAGE_INVALID_PARAMETER,
314 "RGBConvert get convert function by format failed!");
315 YUVStrideInfo dstStrides;
316 auto m = CreateMemory(destInfo.format, destInfo.allocType, {destInfo.width, destInfo.height}, dstStrides);
317 CHECK_ERROR_RETURN_RET_LOG(m == nullptr, ERR_IMAGE_INVALID_PARAMETER, "RGBConvert create memory failed!");
318 destInfo.context = m->extend.data;
319 destInfo.yStride = dstStrides.yStride;
320 destInfo.uvStride = dstStrides.uvStride;
321 destInfo.yOffset = dstStrides.yOffset;
322 destInfo.uvOffset = dstStrides.uvOffset;
323 destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
324 destInfo.bufferSize = GetBufferSizeByFormat(destInfo.format, {destInfo.width, destInfo.height});
325 uint32_t srcStride = 0;
326 CalcRGBStride(srcDataInfo.pixelFormat, srcDataInfo.imageSize.width, srcStride);
327 RGBDataInfo rgbDataInfo = {srcDataInfo.imageSize.width, srcDataInfo.imageSize.height, srcStride};
328 if (!cvtFunc(srcDataInfo.buffer, rgbDataInfo, destInfo, srcDataInfo.colorSpace)) {
329 IMAGE_LOGE("RGBConvert format convert failed!");
330 m->Release();
331 return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
332 }
333 return SUCCESS;
334 }
335
ConvertImageFormat(const ConvertDataInfo & srcDataInfo,DestConvertInfo & destInfo)336 uint32_t ImageFormatConvert::ConvertImageFormat(const ConvertDataInfo &srcDataInfo, DestConvertInfo &destInfo)
337 {
338 if (!CheckConvertDataInfo(srcDataInfo)) {
339 IMAGE_LOGE("source convert data info is invalid");
340 return ERR_IMAGE_INVALID_PARAMETER;
341 }
342 if (!IsSupport(destInfo.format)) {
343 IMAGE_LOGE("destination format is not support or invalid");
344 return ERR_IMAGE_INVALID_PARAMETER;
345 }
346 if (IsYUVConvert(srcDataInfo.pixelFormat)) {
347 return YUVConvert(srcDataInfo, destInfo);
348 }
349 return RGBConvert(srcDataInfo, destInfo);
350 }
351
ConvertImageFormat(std::shared_ptr<PixelMap> & srcPiexlMap,PixelFormat destFormat)352 uint32_t ImageFormatConvert::ConvertImageFormat(std::shared_ptr<PixelMap> &srcPiexlMap, PixelFormat destFormat)
353 {
354 if (srcPiexlMap == nullptr) {
355 IMAGE_LOGE("source pixel map is null");
356 return ERR_IMAGE_INVALID_PARAMETER;
357 }
358 if (!IsSupport(destFormat)) {
359 IMAGE_LOGE("destination format not support");
360 return ERR_MEDIA_FORMAT_UNSUPPORT;
361 }
362 PixelFormat srcFormat = srcPiexlMap->GetPixelFormat();
363 if (IsYUVConvert(srcFormat)) {
364 uint32_t ret = 0;
365 ret = YUVConvertImageFormatOption(srcPiexlMap, srcFormat, destFormat);
366 if (ret != SUCCESS) {
367 IMAGE_LOGE("convert yuv format failed!");
368 }
369 return ret;
370 }
371 if (srcPiexlMap->IsAstc()) {
372 uint32_t ret = 0;
373 std::unique_ptr<PixelMap> resultPixelMap = PixelMap::ConvertFromAstc(srcPiexlMap.get(), ret,
374 destFormat);
375 srcPiexlMap = std::move(resultPixelMap);
376 if (ret != SUCCESS) {
377 IMAGE_LOGE("convert astc format failed!");
378 }
379 return ret;
380 }
381 uint32_t ret = RGBConvertImageFormatOption(srcPiexlMap, srcFormat, destFormat);
382 if (ret != SUCCESS) {
383 IMAGE_LOGE("convert rgb format failed!");
384 return ret;
385 }
386 ImageUtils::DumpPixelMapIfDumpEnabled(*srcPiexlMap, __func__);
387 return SUCCESS;
388 }
389
IsValidSize(const Size & size)390 bool ImageFormatConvert::IsValidSize(const Size &size)
391 {
392 return size.width > 0 && size.height > 0;
393 }
394
CheckConvertDataInfo(const ConvertDataInfo & convertDataInfo)395 bool ImageFormatConvert::CheckConvertDataInfo(const ConvertDataInfo &convertDataInfo)
396 {
397 if (convertDataInfo.buffer == nullptr) {
398 IMAGE_LOGE("buffer is null");
399 return false;
400 }
401
402 if (!IsSupport(convertDataInfo.pixelFormat)) {
403 IMAGE_LOGE("format is not support or invalid");
404 return false;
405 }
406
407 if (!IsValidSize(convertDataInfo.imageSize)) {
408 IMAGE_LOGE("image size is invalid");
409 return false;
410 }
411
412 if (GetBufferSizeByFormat(convertDataInfo.pixelFormat, convertDataInfo.imageSize) != convertDataInfo.bufferSize) {
413 IMAGE_LOGE("buffer size is wrong");
414 return false;
415 }
416
417 return true;
418 }
419
GetBufferSizeByFormat(PixelFormat format,const Size & size)420 size_t ImageFormatConvert::GetBufferSizeByFormat(PixelFormat format, const Size &size)
421 {
422 switch (format) {
423 case PixelFormat::RGB_565:{
424 return size.width * size.height * NUM_2;
425 }
426 case PixelFormat::RGB_888:{
427 return size.width * size.height * NUM_3;
428 }
429 case PixelFormat::ARGB_8888:
430 case PixelFormat::RGBA_8888:
431 case PixelFormat::BGRA_8888:
432 case PixelFormat::RGBA_1010102:{
433 return size.width * size.height * NUM_4;
434 }
435 case PixelFormat::RGBA_F16:{
436 return (((size.width + NUM_1) / NUM_2) * NUM_2) * size.height * NUM_8;
437 }
438 case PixelFormat::NV21:
439 case PixelFormat::NV12:{
440 return size.width * size.height + ((size.width + NUM_1) / NUM_2) *
441 ((size.height + NUM_1) / NUM_2) * NUM_2;
442 }
443 case PixelFormat::YCBCR_P010:
444 case PixelFormat::YCRCB_P010: {
445 return (size.width * size.height + ((size.width + NUM_1) / NUM_2) *
446 ((size.height + NUM_1) / NUM_2) * NUM_2) * NUM_2;
447 }
448 default:{
449 return NUM_0;
450 }
451 }
452 }
453
GetConvertFuncByFormat(PixelFormat srcFormat,PixelFormat destFormat)454 ConvertFunction ImageFormatConvert::GetConvertFuncByFormat(PixelFormat srcFormat, PixelFormat destFormat)
455 {
456 auto iter = g_cvtFuncMap.find(std::make_pair(srcFormat, destFormat));
457 if (iter == g_cvtFuncMap.end()) {
458 IMAGE_LOGE("current format is not supported or format is wrong");
459 return nullptr;
460 }
461 return iter->second;
462 }
463
YUVGetConvertFuncByFormat(PixelFormat srcFormat,PixelFormat destFormat)464 YUVConvertFunction ImageFormatConvert::YUVGetConvertFuncByFormat(PixelFormat srcFormat, PixelFormat destFormat)
465 {
466 auto iter = g_yuvCvtFuncMap.find(std::make_pair(srcFormat, destFormat));
467 if (iter == g_yuvCvtFuncMap.end()) {
468 IMAGE_LOGE("current format is not supported or format is wrong");
469 return nullptr;
470 }
471 return iter->second;
472 }
473
IsSupport(PixelFormat format)474 bool ImageFormatConvert::IsSupport(PixelFormat format)
475 {
476 switch (format) {
477 case PixelFormat::ARGB_8888:
478 case PixelFormat::RGB_565:
479 case PixelFormat::RGBA_8888:
480 case PixelFormat::BGRA_8888:
481 case PixelFormat::RGB_888:
482 case PixelFormat::RGBA_F16:
483 case PixelFormat::RGBA_1010102:
484 case PixelFormat::YCBCR_P010:
485 case PixelFormat::YCRCB_P010:
486 case PixelFormat::NV21:
487 case PixelFormat::NV12:{
488 return true;
489 }
490 default:{
491 return false;
492 }
493 }
494 }
495
496 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
GetYUVStrideInfo(int32_t pixelFmt,OH_NativeBuffer_Planes * planes,YUVStrideInfo & dstStrides)497 static void GetYUVStrideInfo(int32_t pixelFmt, OH_NativeBuffer_Planes *planes, YUVStrideInfo &dstStrides)
498 {
499 if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_420_SP) {
500 auto yStride = planes->planes[PLANE_Y].columnStride;
501 auto uvStride = planes->planes[PLANE_U].columnStride;
502 auto yOffset = planes->planes[PLANE_Y].offset;
503 auto uvOffset = planes->planes[PLANE_U].offset;
504 dstStrides = {yStride, uvStride, yOffset, uvOffset};
505 } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_420_SP) {
506 auto yStride = planes->planes[PLANE_Y].columnStride;
507 auto uvStride = planes->planes[PLANE_V].columnStride;
508 auto yOffset = planes->planes[PLANE_Y].offset;
509 auto uvOffset = planes->planes[PLANE_V].offset;
510 dstStrides = {yStride, uvStride, yOffset, uvOffset};
511 } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCBCR_P010) {
512 auto yStride = planes->planes[PLANE_Y].columnStride / 2;
513 auto uvStride = planes->planes[PLANE_U].columnStride / 2;
514 auto yOffset = planes->planes[PLANE_Y].offset / 2;
515 auto uvOffset = planes->planes[PLANE_U].offset / 2;
516 dstStrides = {yStride, uvStride, yOffset, uvOffset};
517 } else if (pixelFmt == GRAPHIC_PIXEL_FMT_YCRCB_P010) {
518 auto yStride = planes->planes[PLANE_Y].columnStride / 2;
519 auto uvStride = planes->planes[PLANE_V].columnStride / 2;
520 auto yOffset = planes->planes[PLANE_Y].offset / 2;
521 auto uvOffset = planes->planes[PLANE_V].offset / 2;
522 dstStrides = {yStride, uvStride, yOffset, uvOffset};
523 }
524 }
525 #endif
526
CreateMemory(PixelFormat pixelFormat,AllocatorType allocatorType,Size size,YUVStrideInfo & strides,uint64_t usage)527 std::unique_ptr<AbsMemory> ImageFormatConvert::CreateMemory(PixelFormat pixelFormat, AllocatorType allocatorType,
528 Size size, YUVStrideInfo &strides, uint64_t usage)
529 {
530 if (size.width == 0 || size.height == 0 || pixelFormat == PixelFormat::UNKNOWN) {
531 IMAGE_LOGE("CreateMemory err ERR_IMAGE_INVALID_PARAMETER!");
532 return nullptr;
533 }
534 uint32_t pictureSize = GetBufferSizeByFormat(pixelFormat, size);
535 if (IsYUVConvert(pixelFormat)) {
536 strides = {size.width, (size.width + 1) / NUM_2 * NUM_2, 0, size.width * size.height};
537 } else {
538 uint32_t stride = 0;
539 CalcRGBStride(pixelFormat, size.width, stride);
540 strides = {stride, 0, 0, 0};
541 }
542 MemoryData memoryData = {nullptr, pictureSize, "PixelConvert", size, pixelFormat};
543 memoryData.usage = usage;
544 auto m = MemoryManager::CreateMemory(allocatorType, memoryData);
545 CHECK_ERROR_RETURN_RET_LOG(m == nullptr, m, "CreateMemory failed");
546 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
547 if (allocatorType != AllocatorType::DMA_ALLOC) {
548 return m;
549 }
550 CHECK_ERROR_RETURN_RET_LOG(m->extend.data == nullptr, m, "CreateMemory get surfacebuffer failed");
551 auto sb = reinterpret_cast<SurfaceBuffer*>(m->extend.data);
552 OH_NativeBuffer_Planes *planes = nullptr;
553 GSError retVal = sb->GetPlanesInfo(reinterpret_cast<void**>(&planes));
554 auto stride = sb->GetStride();
555 strides = {stride, 0, 0, 0};
556 if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
557 IMAGE_LOGE("CreateMemory Get planesInfo failed, retVal:%{public}d", retVal);
558 } else if (planes->planeCount >= NUM_2) {
559 int32_t pixelFmt = sb->GetFormat();
560 GetYUVStrideInfo(pixelFmt, planes, strides);
561 }
562 #endif
563 return m;
564 }
565
RGBConvertImageFormatOption(std::shared_ptr<PixelMap> & srcPiexlMap,const PixelFormat & srcFormat,PixelFormat destFormat)566 uint32_t ImageFormatConvert::RGBConvertImageFormatOption(std::shared_ptr<PixelMap> &srcPiexlMap,
567 const PixelFormat &srcFormat, PixelFormat destFormat)
568 {
569 ConvertFunction cvtFunc = GetConvertFuncByFormat(srcFormat, destFormat);
570 if (cvtFunc == nullptr) {
571 IMAGE_LOGE("get convert function by format failed!");
572 return ERR_IMAGE_INVALID_PARAMETER;
573 }
574 const_uint8_buffer_type srcBuffer = srcPiexlMap->GetPixels();
575 ImageInfo imageInfo;
576 srcPiexlMap->GetImageInfo(imageInfo);
577
578 int32_t width = imageInfo.size.width;
579 int32_t height = imageInfo.size.height;
580 YUVStrideInfo dstStrides;
581 auto allocType = srcPiexlMap->GetAllocatorType();
582 auto m = CreateMemory(destFormat, allocType, imageInfo.size, dstStrides, srcPiexlMap->GetNoPaddingUsage());
583 if (m == nullptr) {
584 IMAGE_LOGE("CreateMemory failed");
585 return ERR_IMAGE_INVALID_PARAMETER;
586 }
587 int32_t stride = srcPiexlMap->GetRowStride();
588 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
589 if (allocType == AllocatorType::DMA_ALLOC) {
590 auto sb = reinterpret_cast<SurfaceBuffer*>(srcPiexlMap->GetFd());
591 stride = sb->GetStride();
592 sptr<SurfaceBuffer> sourceSurfaceBuffer(sb);
593 sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(m->extend.data));
594 VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
595 }
596 #endif
597 RGBDataInfo rgbDataInfo = {width, height, static_cast<uint32_t>(stride)};
598 DestConvertInfo destInfo = {width, height, destFormat, allocType};
599 destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
600 destInfo.bufferSize = GetBufferSizeByFormat(destFormat, {destInfo.width, destInfo.height});
601 destInfo.yStride = dstStrides.yStride;
602 destInfo.uvStride = dstStrides.uvStride;
603 destInfo.yOffset = dstStrides.yOffset;
604 destInfo.uvOffset = dstStrides.uvOffset;
605 if (!cvtFunc(srcBuffer, rgbDataInfo, destInfo, srcPiexlMap->GetColorSpace())) {
606 IMAGE_LOGE("format convert failed!");
607 m->Release();
608 return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
609 }
610 auto ret = MakeDestPixelMap(srcPiexlMap, imageInfo, destInfo, m->extend.data);
611 if (ret == ERR_IMAGE_PIXELMAP_CREATE_FAILED) {
612 m->Release();
613 }
614 return ret;
615 }
616
RGBConvertImageFormatOptionUnique(std::unique_ptr<PixelMap> & srcPiexlMap,const PixelFormat & srcFormat,PixelFormat destFormat)617 uint32_t ImageFormatConvert::RGBConvertImageFormatOptionUnique(
618 std::unique_ptr<PixelMap> &srcPiexlMap, const PixelFormat &srcFormat, PixelFormat destFormat)
619 {
620 ConvertFunction cvtFunc = GetConvertFuncByFormat(srcFormat, destFormat);
621 bool cond = cvtFunc == nullptr;
622 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "get convert function by format failed!");
623 const_uint8_buffer_type srcBuffer = srcPiexlMap->GetPixels();
624 ImageInfo imageInfo;
625 srcPiexlMap->GetImageInfo(imageInfo);
626
627 int32_t width = imageInfo.size.width;
628 int32_t height = imageInfo.size.height;
629 YUVStrideInfo dstStrides;
630 auto allocType = srcPiexlMap->GetAllocatorType();
631 auto memory = CreateMemory(destFormat, allocType, imageInfo.size, dstStrides, srcPiexlMap->GetNoPaddingUsage());
632 cond = memory == nullptr;
633 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "CreateMemory failed");
634 int32_t stride = srcPiexlMap->GetRowStride();
635 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
636 if (allocType == AllocatorType::DMA_ALLOC) {
637 auto sb = reinterpret_cast<SurfaceBuffer*>(srcPiexlMap->GetFd());
638 stride = sb->GetStride();
639 sptr<SurfaceBuffer> sourceSurfaceBuffer(sb);
640 sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(memory->extend.data));
641 VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
642 }
643 #endif
644 RGBDataInfo rgbDataInfo = {width, height, static_cast<uint32_t>(stride)};
645 DestConvertInfo destInfo = {width, height, destFormat, allocType};
646 destInfo.buffer = reinterpret_cast<uint8_t *>(memory->data.data);
647 destInfo.bufferSize = GetBufferSizeByFormat(destFormat, {destInfo.width, destInfo.height});
648 destInfo.yStride = dstStrides.yStride;
649 destInfo.uvStride = dstStrides.uvStride;
650 destInfo.yOffset = dstStrides.yOffset;
651 destInfo.uvOffset = dstStrides.uvOffset;
652 if (!cvtFunc(srcBuffer, rgbDataInfo, destInfo, srcPiexlMap->GetColorSpace())) {
653 IMAGE_LOGE("format convert failed!");
654 memory->Release();
655 return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
656 }
657 auto ret = MakeDestPixelMapUnique(srcPiexlMap, imageInfo, destInfo, memory->extend.data);
658 if (ret == ERR_IMAGE_PIXELMAP_CREATE_FAILED) {
659 memory->Release();
660 }
661 return ret;
662 }
663
SetConvertImageMetaData(std::unique_ptr<PixelMap> & srcPixelMap,std::unique_ptr<PixelMap> & dstPixelMap)664 bool ImageFormatConvert::SetConvertImageMetaData(std::unique_ptr<PixelMap> &srcPixelMap,
665 std::unique_ptr<PixelMap> &dstPixelMap)
666 {
667 CHECK_ERROR_RETURN_RET(srcPixelMap == nullptr || dstPixelMap == nullptr, false);
668 auto HdrMetadata = srcPixelMap->GetHdrMetadata();
669 if (HdrMetadata != nullptr) {
670 dstPixelMap->SetHdrMetadata(HdrMetadata);
671 }
672 auto exifData = srcPixelMap->GetExifMetadata();
673 if (exifData != nullptr) {
674 dstPixelMap->SetExifMetadata(exifData);
675 }
676 return true;
677 }
678
SetConvertImageMetaData(std::shared_ptr<PixelMap> & srcPixelMap,std::unique_ptr<PixelMap> & dstPixelMap)679 bool ImageFormatConvert::SetConvertImageMetaData(std::shared_ptr<PixelMap> &srcPixelMap,
680 std::unique_ptr<PixelMap> &dstPixelMap)
681 {
682 if (srcPixelMap == nullptr || dstPixelMap == nullptr) {
683 return false;
684 }
685 auto HdrMetadata = srcPixelMap->GetHdrMetadata();
686 if (HdrMetadata != nullptr) {
687 dstPixelMap->SetHdrMetadata(HdrMetadata);
688 }
689 auto exifData = srcPixelMap->GetExifMetadata();
690 if (exifData != nullptr) {
691 dstPixelMap->SetExifMetadata(exifData);
692 }
693 return true;
694 }
695
GetAllocatorType(std::shared_ptr<PixelMap> & srcPiexlMap,PixelFormat destFormat)696 static AllocatorType GetAllocatorType(std::shared_ptr<PixelMap> &srcPiexlMap, PixelFormat destFormat)
697 {
698 auto allocType = srcPiexlMap->GetAllocatorType();
699 if (destFormat == PixelFormat::RGB_888 || destFormat == PixelFormat::RGB_565 ||
700 destFormat == PixelFormat::RGBA_F16) {
701 allocType = AllocatorType::SHARE_MEM_ALLOC;
702 }
703 return allocType;
704 }
705
YUVConvertImageFormatOption(std::shared_ptr<PixelMap> & srcPiexlMap,const PixelFormat & srcFormat,PixelFormat destFormat)706 uint32_t ImageFormatConvert::YUVConvertImageFormatOption(std::shared_ptr<PixelMap> &srcPiexlMap,
707 const PixelFormat &srcFormat, PixelFormat destFormat)
708 {
709 YUVConvertFunction yuvCvtFunc = YUVGetConvertFuncByFormat(srcFormat, destFormat);
710 if (yuvCvtFunc == nullptr) {
711 return ERR_IMAGE_INVALID_PARAMETER;
712 }
713 const_uint8_buffer_type data = srcPiexlMap->GetPixels();
714 YUVDataInfo yDInfo;
715 srcPiexlMap->GetImageYUVInfo(yDInfo);
716 ImageInfo imageInfo;
717 srcPiexlMap->GetImageInfo(imageInfo);
718 if ((srcFormat == PixelFormat::NV21 || srcFormat == PixelFormat::YCBCR_P010 ||
719 srcFormat == PixelFormat::YCRCB_P010) &&
720 (yDInfo.yWidth == 0 || yDInfo.yHeight == 0 || yDInfo.uvWidth == 0 || yDInfo.uvHeight == 0)) {
721 yDInfo.yWidth = static_cast<uint32_t>(imageInfo.size.width);
722 yDInfo.yHeight = static_cast<uint32_t>(imageInfo.size.height);
723 yDInfo.uvWidth = static_cast<uint32_t>((imageInfo.size.width + 1) / NUM_2);
724 yDInfo.uvHeight = static_cast<uint32_t>((imageInfo.size.height + 1) / NUM_2);
725 }
726 YUVStrideInfo dstStrides;
727 auto allocType = GetAllocatorType(srcPiexlMap, destFormat);
728 DestConvertInfo destInfo = {imageInfo.size.width, imageInfo.size.height, destFormat, allocType};
729 auto m = CreateMemory(destFormat, allocType, imageInfo.size, dstStrides,
730 srcPiexlMap->GetNoPaddingUsage());
731 if (m == nullptr) {
732 return ERR_IMAGE_INVALID_PARAMETER;
733 }
734 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
735 if (allocType == AllocatorType::DMA_ALLOC) {
736 sptr<SurfaceBuffer> sourceSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(srcPiexlMap->GetFd()));
737 sptr<SurfaceBuffer> dstSurfaceBuffer(reinterpret_cast<SurfaceBuffer*>(m->extend.data));
738 VpeUtils::CopySurfaceBufferInfo(sourceSurfaceBuffer, dstSurfaceBuffer);
739 }
740 #endif
741 destInfo.buffer = reinterpret_cast<uint8_t *>(m->data.data);
742 destInfo.bufferSize = GetBufferSizeByFormat(destFormat, {destInfo.width, destInfo.height});
743 destInfo.yStride = dstStrides.yStride;
744 destInfo.uvStride = dstStrides.uvStride;
745 destInfo.yOffset = dstStrides.yOffset;
746 destInfo.uvOffset = dstStrides.uvOffset;
747 if (!yuvCvtFunc(data, yDInfo, destInfo, srcPiexlMap->GetColorSpace())) {
748 m->Release();
749 return IMAGE_RESULT_FORMAT_CONVERT_FAILED;
750 }
751 auto ret = MakeDestPixelMap(srcPiexlMap, imageInfo, destInfo, m->extend.data);
752 if (ret == ERR_IMAGE_PIXELMAP_CREATE_FAILED) {
753 m->Release();
754 }
755 return ret;
756 }
757
NeedProtectionConversion(const PixelFormat inputFormat,const PixelFormat outputFormat)758 bool NeedProtectionConversion(const PixelFormat inputFormat, const PixelFormat outputFormat)
759 {
760 if (conversions.find({inputFormat, outputFormat}) != conversions.end()) {
761 return true;
762 }
763 return false;
764 }
765
SetImageInfo(ImageInfo & srcImageinfo,DestConvertInfo & destInfo)766 ImageInfo SetImageInfo(ImageInfo &srcImageinfo, DestConvertInfo &destInfo)
767 {
768 ImageInfo info;
769 info.alphaType = srcImageinfo.alphaType;
770 info.baseDensity = srcImageinfo.baseDensity;
771 info.colorSpace = srcImageinfo.colorSpace;
772 info.pixelFormat = destInfo.format;
773 info.size = {destInfo.width, destInfo.height};
774 return info;
775 }
776
MakeDestPixelMap(std::shared_ptr<PixelMap> & destPixelMap,ImageInfo & srcImageinfo,DestConvertInfo & destInfo,void * context)777 uint32_t ImageFormatConvert::MakeDestPixelMap(std::shared_ptr<PixelMap> &destPixelMap, ImageInfo &srcImageinfo,
778 DestConvertInfo &destInfo, void *context)
779 {
780 if (srcImageinfo.size.width == 0 || srcImageinfo.size.height == 0 || destInfo.width == 0
781 || destInfo.height == 0 || destInfo.format == PixelFormat::UNKNOWN) {
782 return ERR_IMAGE_INVALID_PARAMETER;
783 }
784 ImageInfo info = SetImageInfo(srcImageinfo, destInfo);
785 auto allcatorType = destInfo.allocType;
786 std::unique_ptr<PixelMap> pixelMap;
787 if (info.pixelFormat == PixelFormat::NV21 || info.pixelFormat == PixelFormat::NV12 ||
788 info.pixelFormat == PixelFormat::YCBCR_P010 || info.pixelFormat == PixelFormat::YCRCB_P010) {
789 #ifdef EXT_PIXEL
790 pixelMap = std::make_unique<PixelYuvExt>();
791 #else
792 pixelMap = std::make_unique<PixelYuv>();
793 #endif
794 CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
795 if (allcatorType != AllocatorType::DMA_ALLOC) {
796 pixelMap->AssignYuvDataOnType(info.pixelFormat, info.size.width, info.size.height);
797 } else {
798 YUVStrideInfo strides = {destInfo.yStride, destInfo.uvStride, destInfo.yOffset, destInfo.uvOffset};
799 pixelMap->UpdateYUVDataInfo(info.pixelFormat, info.size.width, info.size.height, strides);
800 }
801 } else {
802 pixelMap = std::make_unique<PixelMap>();
803 CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
804 }
805 pixelMap->SetPixelsAddr(destInfo.buffer, context, destInfo.bufferSize, allcatorType, nullptr);
806 auto ret = pixelMap->SetImageInfo(info, true);
807 bool isSetMetaData = SetConvertImageMetaData(destPixelMap, pixelMap);
808 CHECK_ERROR_RETURN_RET_LOG(ret != SUCCESS || isSetMetaData == false, ret, "set imageInfo failed");
809 #ifdef IMAGE_COLORSPACE_FLAG
810 if (NeedProtectionConversion(srcImageinfo.pixelFormat, info.pixelFormat)) {
811 pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(ColorManager::ColorSpaceName::BT2020_HLG));
812 } else {
813 pixelMap->InnerSetColorSpace(destPixelMap->InnerGetGrColorSpace());
814 }
815 #endif
816 destPixelMap = std::move(pixelMap);
817 return SUCCESS;
818 }
819
MakeDestPixelMapUnique(std::unique_ptr<PixelMap> & destPixelMap,ImageInfo & srcImageinfo,DestConvertInfo & destInfo,void * context)820 uint32_t ImageFormatConvert::MakeDestPixelMapUnique(std::unique_ptr<PixelMap> &destPixelMap, ImageInfo &srcImageinfo,
821 DestConvertInfo &destInfo, void *context)
822 {
823 bool cond = srcImageinfo.size.width == 0 || srcImageinfo.size.height == 0 || destInfo.width == 0 ||
824 destInfo.height == 0 || destInfo.format == PixelFormat::UNKNOWN;
825 CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_INVALID_PARAMETER);
826 ImageInfo info = SetImageInfo(srcImageinfo, destInfo);
827 auto allcatorType = destInfo.allocType;
828 std::unique_ptr<PixelMap> pixelMap;
829 if (info.pixelFormat == PixelFormat::NV21 || info.pixelFormat == PixelFormat::NV12 ||
830 info.pixelFormat == PixelFormat::YCBCR_P010 || info.pixelFormat == PixelFormat::YCRCB_P010) {
831 #ifdef EXT_PIXEL
832 pixelMap = std::make_unique<PixelYuvExt>();
833 #else
834 pixelMap = std::make_unique<PixelYuv>();
835 #endif
836 CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
837 if (allcatorType != AllocatorType::DMA_ALLOC) {
838 pixelMap->AssignYuvDataOnType(info.pixelFormat, info.size.width, info.size.height);
839 } else {
840 YUVStrideInfo strides = {destInfo.yStride, destInfo.uvStride, destInfo.yOffset, destInfo.uvOffset};
841 pixelMap->UpdateYUVDataInfo(info.pixelFormat, info.size.width, info.size.height, strides);
842 }
843 } else {
844 pixelMap = std::make_unique<PixelMap>();
845 CHECK_ERROR_RETURN_RET(pixelMap == nullptr, ERR_IMAGE_PIXELMAP_CREATE_FAILED);
846 }
847 pixelMap->SetPixelsAddr(destInfo.buffer, context, destInfo.bufferSize, allcatorType, nullptr);
848 auto ret = pixelMap->SetImageInfo(info, true);
849 bool isSetMetaData = SetConvertImageMetaData(destPixelMap, pixelMap);
850 cond = ret != SUCCESS || isSetMetaData == false;
851 CHECK_ERROR_RETURN_RET_LOG(cond, ret, "set imageInfo failed");
852 #ifdef IMAGE_COLORSPACE_FLAG
853 if (NeedProtectionConversion(srcImageinfo.pixelFormat, info.pixelFormat)) {
854 pixelMap->InnerSetColorSpace(OHOS::ColorManager::ColorSpace(ColorManager::ColorSpaceName::BT2020_HLG));
855 } else {
856 pixelMap->InnerSetColorSpace(destPixelMap->InnerGetGrColorSpace());
857 }
858 #endif
859 destPixelMap = std::move(pixelMap);
860 return SUCCESS;
861 }
862 } // namespace Media
863 } // namespace OHOS