• 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 "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