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