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