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 "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 decodeOptions.isAppUseAllocator = true;
113 pixelMap_ = imageSource->CreatePixelMap(decodeOptions, errorCode);
114 if (errorCode != Media::SUCCESS) {
115 WVLOG_E("[HeifSupport] CreatePixelMap failed, errorCode %{public}d", errorCode);
116 return false;
117 }
118
119 return true;
120 }
121
GetFd()122 int32_t OhosImageDecoderAdapterImpl::GetFd()
123 {
124 if (!pixelMap_) {
125 WVLOG_E("[HeifSupport] OhosImageDecoderAdapterImpl::GetFd. PixelMap is null.");
126 return -1;
127 }
128 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
129 return surfaceBuffer->GetFileDescriptor();
130 }
131 WVLOG_E(
132 "[HeifSupport] OhosImageDecoderAdapterImpl::GetFd. Fail to get surface buffer.");
133
134 return -1;
135 }
136
GetStride()137 int32_t OhosImageDecoderAdapterImpl::GetStride()
138 {
139 if (!pixelMap_) {
140 WVLOG_E(
141 "[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. PixelMap is null.");
142 return 0;
143 }
144 if (pixelMap_->GetAllocatorType() == Media::AllocatorType::SHARE_MEM_ALLOC) {
145 WVLOG_D("[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. share mem get row stride.");
146 return pixelMap_->GetRowStride();
147 }
148 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
149 // Pixmap row stride is suface buffer stride as We only support DMA_ALLOC now.
150 return surfaceBuffer->GetStride();
151 }
152 WVLOG_E(
153 "[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. Fail to get surface buffer.");
154
155 return 0;
156 }
157
GetOffset()158 int32_t OhosImageDecoderAdapterImpl::GetOffset()
159 {
160 if (!pixelMap_) {
161 WVLOG_E(
162 "[HeifSupport] OhosImageDecoderAdapterImpl::GetOffset. PixelMap is null.");
163 return 0;
164 }
165 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
166 OH_NativeBuffer_Planes* native_buffer_planes_;
167 surfaceBuffer->GetPlanesInfo((void**)&native_buffer_planes_);
168 if (!native_buffer_planes_) {
169 WVLOG_E(
170 "[HeifSupport] OhosImageDecoderAdapterImpl::GetOffset. Fail to get native buffer Planes.");
171 return 0;
172 }
173 return native_buffer_planes_->planes[0].offset;
174 }
175 WVLOG_E(
176 "[HeifSupport] OhosImageDecoderAdapterImpl::GetStride. Fail to get surface buffer.");
177
178 return 0;
179 }
180
GetSize()181 uint64_t OhosImageDecoderAdapterImpl::GetSize()
182 {
183 if (!pixelMap_) {
184 WVLOG_E(
185 "[HeifSupport] OhosImageDecoderAdapterImpl::GetSize. PixelMap is null.");
186 return 0;
187 }
188 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
189 return surfaceBuffer->GetSize();
190 }
191 WVLOG_E(
192 "[HeifSupport] OhosImageDecoderAdapterImpl::GetSize. Fail to get surface buffer.");
193
194 return 0;
195 }
196
GetNativeWindowBuffer()197 void* OhosImageDecoderAdapterImpl::GetNativeWindowBuffer()
198 {
199 if (!pixelMap_) {
200 WVLOG_E(
201 "[HeifSupport] OhosImageDecoderAdapterImpl::GetNativeWindowBuffer. PixelMap is null.");
202 return nullptr;
203 }
204
205 if (!nativeWindowBuffer_) {
206 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
207 nativeWindowBuffer_ =
208 CreateNativeWindowBufferFromSurfaceBuffer(&surfaceBuffer);
209 }
210 }
211 return static_cast<void*>(nativeWindowBuffer_);
212 }
213
214 // Used for NV12
GetPlanesCount()215 int32_t OhosImageDecoderAdapterImpl::GetPlanesCount()
216 {
217 if (!pixelMap_) {
218 WVLOG_E(
219 "[HeifSupport] OhosImageDecoderAdapterImpl::GetPlanesCount. PixelMap is null.");
220 return 0;
221 }
222
223 if (auto* surfaceBuffer = SurfaceBufferFromPixelMap(pixelMap_.get())) {
224 OH_NativeBuffer_Planes* nativeBufferPlanes;
225 surfaceBuffer->GetPlanesInfo((void**)&nativeBufferPlanes);
226 if (!nativeBufferPlanes) {
227 WVLOG_E(
228 "[HeifSupport] OhosImageDecoderAdapterImpl::GetPlanesCount. Fail to get native buffer Planes.");
229 return 0;
230 }
231 return nativeBufferPlanes->planeCount;
232 }
233 WVLOG_E(
234 "[HeifSupport] OhosImageDecoderAdapterImpl::GetPlanesCount. Fail to get surface buffer.");
235
236 return 0;
237 }
238
ReleasePixelMap()239 void OhosImageDecoderAdapterImpl::ReleasePixelMap()
240 {
241 WVLOG_I("[HeifSupport] OhosImageDecoderAdapterImpl release pixelmap and native window buffer.");
242 if (pixelMap_) {
243 pixelMap_.reset();
244 pixelMap_ = nullptr;
245 }
246 if (nativeWindowBuffer_) {
247 DestroyNativeWindowBuffer(nativeWindowBuffer_);
248 nativeWindowBuffer_ = nullptr;
249 }
250 }
251
GetDecodeData()252 void* OhosImageDecoderAdapterImpl::GetDecodeData()
253 {
254 if (!pixelMap_) {
255 WVLOG_E("[HeifSupport] OhosImageDecoderAdapterImpl::GetDecodeData. PixelMap is null.");
256 return nullptr;
257 }
258 return pixelMap_->GetWritablePixels();
259 }
260
261 } // namespace NWeb
262 } // namespace OHOS
263