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