• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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