1 /*
2 * Copyright (c) 2023 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 "ohos_image_decoder_adapter_impl.h"
17
18 #include "foundation/graphic/graphic_surface/interfaces/inner_api/surface/window.h"
19 #include "image_source.h"
20 #include "media_errors.h"
21 #include "nweb_log.h"
22 #include "pixel_map.h"
23
24 namespace OHOS {
25 namespace NWeb {
26
27 namespace {
28
ParseRawData(const uint8_t * data,uint32_t size,Media::ImageInfo & imageInfo)29 std::unique_ptr<Media::ImageSource> ParseRawData(const uint8_t* data,
30 uint32_t size,
31 Media::ImageInfo& imageInfo)
32 {
33 uint32_t errorCode = 0;
34 Media::SourceOptions sourceOptions;
35 auto imageSource = Media::ImageSource::CreateImageSource(
36 data, size, sourceOptions, errorCode);
37 if (imageSource == nullptr || errorCode != Media::SUCCESS) {
38 WVLOG_E("[HeifSupport] ParseRawData failed, errorCode %{public}d", errorCode);
39 return nullptr;
40 }
41
42 auto ret = imageSource->GetImageInfo(imageInfo);
43 if (ret != Media::SUCCESS) {
44 WVLOG_E(
45 "[HeifSupport] ParseRawData GetImageInfo failed, errorCode %{public}d", ret);
46 return nullptr;
47 }
48 return imageSource;
49 }
50
SurfaceBufferFromPixelMap(Media::PixelMap * pixelMap)51 SurfaceBuffer* SurfaceBufferFromPixelMap(Media::PixelMap* pixelMap)
52 {
53 if (pixelMap && pixelMap->GetFd()) {
54 return reinterpret_cast<SurfaceBuffer*>(pixelMap->GetFd());
55 }
56 return nullptr;
57 }
58
59 }; // namespace
60
61 OhosImageDecoderAdapterImpl::OhosImageDecoderAdapterImpl() = default;
62
~OhosImageDecoderAdapterImpl()63 OhosImageDecoderAdapterImpl::~OhosImageDecoderAdapterImpl()
64 {
65 ReleasePixelMap();
66 }
67
ParseImageInfo(const uint8_t * data,uint32_t size)68 bool OhosImageDecoderAdapterImpl::ParseImageInfo(const uint8_t* data, uint32_t size)
69 {
70 return ParseRawData(data, size, imageInfo_) != nullptr;
71 }
72
GetEncodedFormat()73 std::string OhosImageDecoderAdapterImpl::GetEncodedFormat()
74 {
75 return imageInfo_.encodedFormat;
76 }
77
GetImageWidth()78 int32_t OhosImageDecoderAdapterImpl::GetImageWidth()
79 {
80 return imageInfo_.size.width;
81 }
82
GetImageHeight()83 int32_t OhosImageDecoderAdapterImpl::GetImageHeight()
84 {
85 return imageInfo_.size.height;
86 }
87
DecodeToPixelMap(const uint8_t * data,uint32_t size)88 bool OhosImageDecoderAdapterImpl::DecodeToPixelMap(const uint8_t* data, uint32_t size)
89 {
90 return Decode(data, size, AllocatorType::kDmaAlloc, false);
91 }
92
Decode(const uint8_t * data,uint32_t size,AllocatorType type,bool useYuv)93 bool OhosImageDecoderAdapterImpl::Decode(const uint8_t* data,
94 uint32_t size,
95 AllocatorType type,
96 bool useYuv)
97 {
98 // Manage lifecycle of pixelmap and native window buffer with map next.
99 WVLOG_I("[HeifSupport] OhosImageDecoderAdapterImpl DecodeToPixelMap.");
100 auto imageSource = ParseRawData(data, size, imageInfo_);
101 if (imageSource == nullptr) {
102 WVLOG_E(
103 "[HeifSupport] OhosImageDecoderAdapterImpl::DecodeToPixelMap, fail to get image source.");
104 return false;
105 }
106
107 uint32_t errorCode = 0;
108 Media::DecodeOptions decodeOptions;
109 decodeOptions.desiredPixelFormat =
110 useYuv ? Media::PixelFormat::NV12 : Media::PixelFormat::RGBA_8888;
111 decodeOptions.allocatorType = static_cast<Media::AllocatorType>(type);
112 pixelMap_ = imageSource->CreatePixelMap(decodeOptions, errorCode);
113 if (errorCode != Media::SUCCESS) {
114 WVLOG_E("[HeifSupport] CreatePixelMap failed, errorCode %{public}d", errorCode);
115 return false;
116 }
117
118 return true;
119 }
120
GetFd()121 int32_t OhosImageDecoderAdapterImpl::GetFd()
122 {
123 if (!pixelMap_) {
124 WVLOG_E("[HeifSupport] OhosImageDecoderAdapterImpl::GetFd. PixelMap is null.");
125 return -1;
126 }
127 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
128 return surfaceBuffer->GetFileDescriptor();
129 }
130 WVLOG_E(
131 "[HeifSupport] OhosImageDecoderAdapterImpl::GetFd. Fail to get surface buffer.");
132
133 return -1;
134 }
135
GetStride()136 int32_t OhosImageDecoderAdapterImpl::GetStride()
137 {
138 if (!pixelMap_) {
139 WVLOG_E(
140 "[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. PixelMap is null.");
141 return 0;
142 }
143 if (pixelMap_->GetAllocatorType() == Media::AllocatorType::SHARE_MEM_ALLOC) {
144 WVLOG_D("[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. share mem get row stride.");
145 return pixelMap_->GetRowStride();
146 }
147 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
148 // Pixmap row stride is suface buffer stride as We only support DMA_ALLOC now.
149 return surfaceBuffer->GetStride();
150 }
151 WVLOG_E(
152 "[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. Fail to get surface buffer.");
153
154 return 0;
155 }
156
GetOffset()157 int32_t OhosImageDecoderAdapterImpl::GetOffset()
158 {
159 if (!pixelMap_) {
160 WVLOG_E(
161 "[HeifSupport] OhosImageDecoderAdapterImpl::GetOffset. PixelMap is null.");
162 return 0;
163 }
164 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
165 OH_NativeBuffer_Planes* native_buffer_planes_;
166 surfaceBuffer->GetPlanesInfo((void**)&native_buffer_planes_);
167 if (!native_buffer_planes_) {
168 WVLOG_E(
169 "[HeifSupport] OhosImageDecoderAdapterImpl::GetOffset. Fail to get native buffer Planes.");
170 return 0;
171 }
172 return native_buffer_planes_->planes[0].offset;
173 }
174 WVLOG_E(
175 "[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. Fail to get surface buffer.");
176
177 return 0;
178 }
179
GetSize()180 uint64_t OhosImageDecoderAdapterImpl::GetSize()
181 {
182 if (!pixelMap_) {
183 WVLOG_E(
184 "[HeifSupport] OhosImageDecoderAdapterImpl::GetSize. PixelMap is null.");
185 return 0;
186 }
187 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
188 return surfaceBuffer->GetSize();
189 }
190 WVLOG_E(
191 "[HeifSupport] OhosImageDecoderAdapterImpl::GetSize. Fail to get surface buffer.");
192
193 return 0;
194 }
195
GetNativeWindowBuffer()196 void* OhosImageDecoderAdapterImpl::GetNativeWindowBuffer()
197 {
198 if (!pixelMap_) {
199 WVLOG_E(
200 "[HeifSupport] OhosImageDecoderAdapterImpl::GetNativeWindowBuffer. PixelMap is null.");
201 return nullptr;
202 }
203
204 if (!nativeWindowBuffer_) {
205 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
206 nativeWindowBuffer_ =
207 CreateNativeWindowBufferFromSurfaceBuffer(&surfaceBuffer);
208 }
209 }
210 return static_cast<void*>(nativeWindowBuffer_);
211 }
212
213 // Used for NV12
GetPlanesCount()214 int32_t OhosImageDecoderAdapterImpl::GetPlanesCount()
215 {
216 if (!pixelMap_) {
217 WVLOG_E(
218 "[HeifSupport] OhosImageDecoderAdapterImpl::GetPlanesCount. PixelMap is null.");
219 return 0;
220 }
221
222 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
223 OH_NativeBuffer_Planes* nativeBufferPlanes;
224 surfaceBuffer->GetPlanesInfo((void**)&nativeBufferPlanes);
225 if (!nativeBufferPlanes) {
226 WVLOG_E(
227 "[HeifSupport] OhosImageDecoderAdapterImpl::GetPlanesCount. Fail to get native buffer Planes.");
228 return 0;
229 }
230 return nativeBufferPlanes->planeCount;
231 }
232 WVLOG_E(
233 "[HeifSupport] OhosImageDecoderAdapterImpl::GetPlanesCount. Fail to get surface buffer.");
234
235 return 0;
236 }
237
ReleasePixelMap()238 void OhosImageDecoderAdapterImpl::ReleasePixelMap()
239 {
240 WVLOG_I("[HeifSupport] OhosImageDecoderAdapterImpl release pixelmap and native window buffer.");
241 if (pixelMap_) {
242 pixelMap_.reset();
243 pixelMap_ = nullptr;
244 }
245 if (nativeWindowBuffer_) {
246 DestroyNativeWindowBuffer(nativeWindowBuffer_);
247 nativeWindowBuffer_ = nullptr;
248 }
249 }
250
GetDecodeData()251 void* OhosImageDecoderAdapterImpl::GetDecodeData()
252 {
253 if (!pixelMap_) {
254 WVLOG_E("[HeifSupport] OhosImageDecoderAdapterImpl::GetDecodeData. PixelMap is null.");
255 return nullptr;
256 }
257 return pixelMap_->GetWritablePixels();
258 }
259
260 } // namespace NWeb
261 } // namespace OHOS
262